1*9ea232b5Stb /* $OpenBSD: asn1basic.c,v 1.16 2024/02/04 13:07:02 tb Exp $ */
2725e2e31Sjsing /*
3725e2e31Sjsing * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org>
478b0b018Stb * Copyright (c) 2023 Theo Buehler <tb@openbsd.org>
5725e2e31Sjsing *
6725e2e31Sjsing * Permission to use, copy, modify, and distribute this software for any
7725e2e31Sjsing * purpose with or without fee is hereby granted, provided that the above
8725e2e31Sjsing * copyright notice and this permission notice appear in all copies.
9725e2e31Sjsing *
10725e2e31Sjsing * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11725e2e31Sjsing * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12725e2e31Sjsing * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13725e2e31Sjsing * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14725e2e31Sjsing * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15725e2e31Sjsing * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16725e2e31Sjsing * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17725e2e31Sjsing */
18725e2e31Sjsing
19725e2e31Sjsing #include <openssl/asn1.h>
203dd3802fSjsing #include <openssl/err.h>
21725e2e31Sjsing
22725e2e31Sjsing #include <err.h>
23725e2e31Sjsing #include <stdio.h>
24725e2e31Sjsing #include <string.h>
25725e2e31Sjsing
26c9675a23Stb #include "asn1_local.h"
279773c5c8Stb
28725e2e31Sjsing static void
hexdump(const unsigned char * buf,size_t len)29725e2e31Sjsing hexdump(const unsigned char *buf, size_t len)
30725e2e31Sjsing {
31725e2e31Sjsing size_t i;
32725e2e31Sjsing
33725e2e31Sjsing for (i = 1; i <= len; i++)
34725e2e31Sjsing fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
35725e2e31Sjsing
36725e2e31Sjsing fprintf(stderr, "\n");
37725e2e31Sjsing }
38725e2e31Sjsing
39725e2e31Sjsing static int
asn1_compare_bytes(const char * label,const unsigned char * d1,int len1,const unsigned char * d2,int len2)40725e2e31Sjsing asn1_compare_bytes(const char *label, const unsigned char *d1, int len1,
41725e2e31Sjsing const unsigned char *d2, int len2)
42725e2e31Sjsing {
43725e2e31Sjsing if (len1 != len2) {
44725e2e31Sjsing fprintf(stderr, "FAIL: %s - byte lengths differ "
457bb1a6cfStb "(%d != %d)\n", label, len1, len2);
4630fc8fe5Sjsing fprintf(stderr, "Got:\n");
4730fc8fe5Sjsing hexdump(d1, len1);
4830fc8fe5Sjsing fprintf(stderr, "Want:\n");
4930fc8fe5Sjsing hexdump(d2, len2);
50725e2e31Sjsing return 0;
51725e2e31Sjsing }
52725e2e31Sjsing if (memcmp(d1, d2, len1) != 0) {
53725e2e31Sjsing fprintf(stderr, "FAIL: %s - bytes differ\n", label);
54725e2e31Sjsing fprintf(stderr, "Got:\n");
55725e2e31Sjsing hexdump(d1, len1);
56725e2e31Sjsing fprintf(stderr, "Want:\n");
57725e2e31Sjsing hexdump(d2, len2);
58725e2e31Sjsing return 0;
59725e2e31Sjsing }
60725e2e31Sjsing return 1;
61725e2e31Sjsing }
62725e2e31Sjsing
6330fc8fe5Sjsing const uint8_t asn1_bit_string_primitive[] = {
6430fc8fe5Sjsing 0x03, 0x07,
6530fc8fe5Sjsing 0x04, 0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0,
6630fc8fe5Sjsing };
6730fc8fe5Sjsing
6830fc8fe5Sjsing static int
asn1_bit_string_test(void)6930fc8fe5Sjsing asn1_bit_string_test(void)
7030fc8fe5Sjsing {
7130fc8fe5Sjsing uint8_t bs[] = {0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0};
7230fc8fe5Sjsing ASN1_BIT_STRING *abs;
7330fc8fe5Sjsing uint8_t *p = NULL, *pp;
7430fc8fe5Sjsing const uint8_t *q;
7530fc8fe5Sjsing int bit, i, len;
7630fc8fe5Sjsing int failed = 1;
7730fc8fe5Sjsing
7830fc8fe5Sjsing if ((abs = ASN1_BIT_STRING_new()) == NULL) {
7930fc8fe5Sjsing fprintf(stderr, "FAIL: ASN1_BIT_STRING_new() == NULL\n");
8030fc8fe5Sjsing goto failed;
8130fc8fe5Sjsing }
8230fc8fe5Sjsing if (!ASN1_BIT_STRING_set(abs, bs, sizeof(bs))) {
8330fc8fe5Sjsing fprintf(stderr, "FAIL: failed to set bit string\n");
8430fc8fe5Sjsing goto failed;
8530fc8fe5Sjsing }
8630fc8fe5Sjsing
8730fc8fe5Sjsing if ((len = i2d_ASN1_BIT_STRING(abs, NULL)) < 0) {
8830fc8fe5Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING with NULL\n");
8930fc8fe5Sjsing goto failed;
9030fc8fe5Sjsing }
9130fc8fe5Sjsing if ((p = malloc(len)) == NULL)
9230fc8fe5Sjsing errx(1, "malloc");
9330fc8fe5Sjsing memset(p, 0xbd, len);
9430fc8fe5Sjsing pp = p;
9530fc8fe5Sjsing if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) {
9630fc8fe5Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
9730fc8fe5Sjsing goto failed;
9830fc8fe5Sjsing }
9930fc8fe5Sjsing if (!asn1_compare_bytes("BIT_STRING", p, len, asn1_bit_string_primitive,
10030fc8fe5Sjsing sizeof(asn1_bit_string_primitive)))
10130fc8fe5Sjsing goto failed;
102d95bd0c0Sjsing if (pp != p + len) {
103d95bd0c0Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING pp = %p, want %p\n",
104d95bd0c0Sjsing pp, p + len);
105d95bd0c0Sjsing goto failed;
106d95bd0c0Sjsing }
10730fc8fe5Sjsing
10830fc8fe5Sjsing /* Test primitive decoding. */
10930fc8fe5Sjsing q = p;
11030fc8fe5Sjsing if (d2i_ASN1_BIT_STRING(&abs, &q, len) == NULL) {
11130fc8fe5Sjsing fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING primitive\n");
11230fc8fe5Sjsing goto failed;
11330fc8fe5Sjsing }
11430fc8fe5Sjsing if (!asn1_compare_bytes("BIT_STRING primitive data", abs->data, abs->length,
11530fc8fe5Sjsing bs, sizeof(bs)))
11630fc8fe5Sjsing goto failed;
117d95bd0c0Sjsing if (q != p + len) {
118d95bd0c0Sjsing fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING q = %p, want %p\n",
119d95bd0c0Sjsing q, p + len);
120d95bd0c0Sjsing goto failed;
121d95bd0c0Sjsing }
12230fc8fe5Sjsing
12330fc8fe5Sjsing /* Test ASN1_BIT_STRING_get_bit(). */
12430fc8fe5Sjsing for (i = 0; i < ((int)sizeof(bs) * 8); i++) {
12530fc8fe5Sjsing bit = (bs[i / 8] >> (7 - i % 8)) & 1;
12630fc8fe5Sjsing
12730fc8fe5Sjsing if (ASN1_BIT_STRING_get_bit(abs, i) != bit) {
12830fc8fe5Sjsing fprintf(stderr, "FAIL: ASN1_BIT_STRING_get_bit(_, %d) "
12930fc8fe5Sjsing "= %d, want %d\n", i,
13030fc8fe5Sjsing ASN1_BIT_STRING_get_bit(abs, i), bit);
13130fc8fe5Sjsing goto failed;
13230fc8fe5Sjsing }
13330fc8fe5Sjsing }
13430fc8fe5Sjsing
13530fc8fe5Sjsing /* Test ASN1_BIT_STRING_set_bit(). */
13630fc8fe5Sjsing for (i = 0; i < ((int)sizeof(bs) * 8); i++) {
13730fc8fe5Sjsing if (!ASN1_BIT_STRING_set_bit(abs, i, 1)) {
13830fc8fe5Sjsing fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit 1\n");
13930fc8fe5Sjsing goto failed;
14030fc8fe5Sjsing }
14130fc8fe5Sjsing }
14230fc8fe5Sjsing for (i = ((int)sizeof(bs) * 8) - 1; i >= 0; i--) {
14330fc8fe5Sjsing bit = (bs[i / 8] >> (7 - i % 8)) & 1;
14430fc8fe5Sjsing if (bit == 1)
14530fc8fe5Sjsing continue;
14630fc8fe5Sjsing if (!ASN1_BIT_STRING_set_bit(abs, i, 0)) {
14730fc8fe5Sjsing fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit\n");
14830fc8fe5Sjsing goto failed;
14930fc8fe5Sjsing }
15030fc8fe5Sjsing }
15130fc8fe5Sjsing
15230fc8fe5Sjsing if ((i2d_ASN1_BIT_STRING(abs, NULL)) != len) {
15330fc8fe5Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
15430fc8fe5Sjsing goto failed;
15530fc8fe5Sjsing }
15630fc8fe5Sjsing
15730fc8fe5Sjsing memset(p, 0xbd, len);
15830fc8fe5Sjsing pp = p;
15930fc8fe5Sjsing if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) {
16030fc8fe5Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
16130fc8fe5Sjsing goto failed;
16230fc8fe5Sjsing }
16330fc8fe5Sjsing
16430fc8fe5Sjsing if (!asn1_compare_bytes("BIT_STRING set", p, len, asn1_bit_string_primitive,
16530fc8fe5Sjsing sizeof(asn1_bit_string_primitive)))
16630fc8fe5Sjsing goto failed;
16730fc8fe5Sjsing
16830fc8fe5Sjsing failed = 0;
16930fc8fe5Sjsing
17030fc8fe5Sjsing failed:
17130fc8fe5Sjsing ASN1_BIT_STRING_free(abs);
17230fc8fe5Sjsing free(p);
17330fc8fe5Sjsing
17430fc8fe5Sjsing return failed;
17530fc8fe5Sjsing }
17630fc8fe5Sjsing
177725e2e31Sjsing const uint8_t asn1_boolean_false[] = {
178725e2e31Sjsing 0x01, 0x01, 0x00,
179725e2e31Sjsing };
180725e2e31Sjsing const uint8_t asn1_boolean_true[] = {
181725e2e31Sjsing 0x01, 0x01, 0x01,
182725e2e31Sjsing };
183725e2e31Sjsing
184725e2e31Sjsing static int
asn1_boolean_test(void)185725e2e31Sjsing asn1_boolean_test(void)
186725e2e31Sjsing {
187725e2e31Sjsing uint8_t *p = NULL, *pp;
188725e2e31Sjsing const uint8_t *q;
189725e2e31Sjsing int len;
190725e2e31Sjsing int failed = 1;
191725e2e31Sjsing
192725e2e31Sjsing if ((len = i2d_ASN1_BOOLEAN(0, NULL)) < 0) {
193725e2e31Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false with NULL\n");
194725e2e31Sjsing goto failed;
195725e2e31Sjsing }
19630fc8fe5Sjsing if ((p = malloc(len)) == NULL)
197725e2e31Sjsing errx(1, "calloc");
19830fc8fe5Sjsing memset(p, 0xbd, len);
199725e2e31Sjsing pp = p;
200725e2e31Sjsing if ((i2d_ASN1_BOOLEAN(0, &pp)) != len) {
201725e2e31Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false\n");
202725e2e31Sjsing goto failed;
203725e2e31Sjsing }
204d95bd0c0Sjsing if (pp != p + len) {
205d95bd0c0Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n",
206d95bd0c0Sjsing pp, p + len);
207d95bd0c0Sjsing goto failed;
208d95bd0c0Sjsing }
209725e2e31Sjsing
210725e2e31Sjsing if (!asn1_compare_bytes("BOOLEAN false", p, len, asn1_boolean_false,
211725e2e31Sjsing sizeof(asn1_boolean_false)))
212725e2e31Sjsing goto failed;
213725e2e31Sjsing
214725e2e31Sjsing q = p;
215725e2e31Sjsing if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 0) {
216725e2e31Sjsing fprintf(stderr, "FAIL: BOOLEAN false did not decode to 0\n");
217725e2e31Sjsing goto failed;
218725e2e31Sjsing }
219d95bd0c0Sjsing if (q != p + len) {
220d95bd0c0Sjsing fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n",
221d95bd0c0Sjsing q, p + len);
222d95bd0c0Sjsing goto failed;
223d95bd0c0Sjsing }
224725e2e31Sjsing
225725e2e31Sjsing free(p);
226725e2e31Sjsing p = NULL;
227725e2e31Sjsing
228725e2e31Sjsing if ((len = i2d_ASN1_BOOLEAN(1, NULL)) < 0) {
229725e2e31Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true with NULL\n");
230725e2e31Sjsing goto failed;
231725e2e31Sjsing }
232725e2e31Sjsing if ((p = calloc(1, len)) == NULL)
233725e2e31Sjsing errx(1, "calloc");
234725e2e31Sjsing pp = p;
235725e2e31Sjsing if ((i2d_ASN1_BOOLEAN(1, &pp)) != len) {
236725e2e31Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true\n");
237725e2e31Sjsing goto failed;
238725e2e31Sjsing }
239d95bd0c0Sjsing if (pp != p + len) {
240d95bd0c0Sjsing fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n",
241d95bd0c0Sjsing pp, p + len);
242d95bd0c0Sjsing goto failed;
243d95bd0c0Sjsing }
244725e2e31Sjsing
245725e2e31Sjsing if (!asn1_compare_bytes("BOOLEAN true", p, len, asn1_boolean_true,
246725e2e31Sjsing sizeof(asn1_boolean_true)))
247725e2e31Sjsing goto failed;
248725e2e31Sjsing
249725e2e31Sjsing q = p;
250725e2e31Sjsing if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 1) {
25172ad5686Stb fprintf(stderr, "FAIL: BOOLEAN true did not decode to 1\n");
252725e2e31Sjsing goto failed;
253725e2e31Sjsing }
254d95bd0c0Sjsing if (q != p + len) {
255d95bd0c0Sjsing fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n",
256d95bd0c0Sjsing q, p + len);
257d95bd0c0Sjsing goto failed;
258d95bd0c0Sjsing }
259725e2e31Sjsing
260725e2e31Sjsing failed = 0;
261725e2e31Sjsing
262725e2e31Sjsing failed:
263725e2e31Sjsing free(p);
264725e2e31Sjsing
265725e2e31Sjsing return failed;
266725e2e31Sjsing }
267725e2e31Sjsing
26851b91989Sjsing struct asn1_integer_test {
26951b91989Sjsing long value;
27051b91989Sjsing uint8_t content[64];
27151b91989Sjsing size_t content_len;
27251b91989Sjsing int content_neg;
27351b91989Sjsing uint8_t der[64];
27451b91989Sjsing size_t der_len;
27551b91989Sjsing int want_error;
27651b91989Sjsing };
27751b91989Sjsing
27851b91989Sjsing struct asn1_integer_test asn1_integer_tests[] = {
27951b91989Sjsing {
28051b91989Sjsing .value = 0,
28151b91989Sjsing .content = {0x00},
28251b91989Sjsing .content_len = 1,
28351b91989Sjsing .der = {0x02, 0x01, 0x00},
28451b91989Sjsing .der_len = 3,
28551b91989Sjsing },
28651b91989Sjsing {
28751b91989Sjsing .value = 1,
28851b91989Sjsing .content = {0x01},
28951b91989Sjsing .content_len = 1,
29051b91989Sjsing .der = {0x02, 0x01, 0x01},
29151b91989Sjsing .der_len = 3,
29251b91989Sjsing },
29351b91989Sjsing {
29451b91989Sjsing .value = -1,
29551b91989Sjsing .content = {0x01},
29651b91989Sjsing .content_len = 1,
29751b91989Sjsing .content_neg = 1,
29851b91989Sjsing .der = {0x02, 0x01, 0xff},
29951b91989Sjsing .der_len = 3,
30051b91989Sjsing },
30151b91989Sjsing {
30251b91989Sjsing .value = 127,
30351b91989Sjsing .content = {0x7f},
30451b91989Sjsing .content_len = 1,
30551b91989Sjsing .der = {0x02, 0x01, 0x7f},
30651b91989Sjsing .der_len = 3,
30751b91989Sjsing },
30851b91989Sjsing {
30951b91989Sjsing .value = -127,
31051b91989Sjsing .content = {0x7f},
31151b91989Sjsing .content_len = 1,
31251b91989Sjsing .content_neg = 1,
31351b91989Sjsing .der = {0x02, 0x01, 0x81},
31451b91989Sjsing .der_len = 3,
31551b91989Sjsing },
31651b91989Sjsing {
31751b91989Sjsing .value = 128,
31851b91989Sjsing .content = {0x80},
31951b91989Sjsing .content_len = 1,
32051b91989Sjsing .der = {0x02, 0x02, 0x00, 0x80},
32151b91989Sjsing .der_len = 4,
32251b91989Sjsing },
32351b91989Sjsing {
32451b91989Sjsing .value = -128,
32551b91989Sjsing .content = {0x80},
32651b91989Sjsing .content_len = 1,
32751b91989Sjsing .content_neg = 1,
32851b91989Sjsing .der = {0x02, 0x01, 0x80},
32951b91989Sjsing .der_len = 3,
33051b91989Sjsing },
33151b91989Sjsing {
33251b91989Sjsing /* 2^64 */
33351b91989Sjsing .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
33451b91989Sjsing .content_len = 9,
33551b91989Sjsing .der = {0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
33651b91989Sjsing .der_len = 11,
33751b91989Sjsing },
33851b91989Sjsing {
33951b91989Sjsing /* -2^64 */
34051b91989Sjsing .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
34151b91989Sjsing .content_len = 9,
34251b91989Sjsing .content_neg = 1,
34351b91989Sjsing .der = {0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
34451b91989Sjsing .der_len = 11,
34551b91989Sjsing },
34651b91989Sjsing {
34751b91989Sjsing /* Invalid length. */
34851b91989Sjsing .der = {0x02, 0x00},
34951b91989Sjsing .der_len = 2,
35051b91989Sjsing .want_error = 1,
35151b91989Sjsing },
35251b91989Sjsing {
35351b91989Sjsing /* Invalid padding. */
35451b91989Sjsing .der = {0x02, 0x09, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
35551b91989Sjsing .der_len = 11,
35651b91989Sjsing .want_error = 1,
35751b91989Sjsing },
35851b91989Sjsing {
35951b91989Sjsing /* Invalid padding. */
36051b91989Sjsing .der = {0x02, 0x09, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
36151b91989Sjsing .der_len = 11,
36251b91989Sjsing .want_error = 1,
36351b91989Sjsing },
3643dd3802fSjsing {
3653dd3802fSjsing /* Invalid encoding (constructed with definite length). */
3663dd3802fSjsing .der = {0x22, 0x03, 0x02, 0x01, 0x01},
3673dd3802fSjsing .der_len = 5,
3683dd3802fSjsing .want_error = 1,
3693dd3802fSjsing },
3703dd3802fSjsing {
3713dd3802fSjsing /* Invalid encoding (constructed with indefinite length). */
3723dd3802fSjsing .der = {0x22, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00},
3733dd3802fSjsing .der_len = 7,
3743dd3802fSjsing .want_error = 1,
3753dd3802fSjsing },
37651b91989Sjsing };
37751b91989Sjsing
37851b91989Sjsing #define N_ASN1_INTEGER_TESTS \
37951b91989Sjsing (sizeof(asn1_integer_tests) / sizeof(*asn1_integer_tests))
38051b91989Sjsing
38151b91989Sjsing static int
asn1_integer_set_test(struct asn1_integer_test * ait)38251b91989Sjsing asn1_integer_set_test(struct asn1_integer_test *ait)
38351b91989Sjsing {
38451b91989Sjsing ASN1_INTEGER *aint = NULL;
38551b91989Sjsing uint8_t *p = NULL, *pp;
38651b91989Sjsing int len;
38751b91989Sjsing int failed = 1;
38851b91989Sjsing
38951b91989Sjsing if ((aint = ASN1_INTEGER_new()) == NULL) {
39051b91989Sjsing fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
39151b91989Sjsing goto failed;
39251b91989Sjsing }
39351b91989Sjsing if (!ASN1_INTEGER_set(aint, ait->value)) {
39451b91989Sjsing fprintf(stderr, "FAIL: ASN1_INTEGER_(%ld) failed\n",
39551b91989Sjsing ait->value);
39651b91989Sjsing goto failed;
39751b91989Sjsing }
39851b91989Sjsing if (ait->value != 0 &&
39951b91989Sjsing !asn1_compare_bytes("INTEGER set", aint->data, aint->length,
40051b91989Sjsing ait->content, ait->content_len))
40151b91989Sjsing goto failed;
40251b91989Sjsing if (ait->content_neg && aint->type != V_ASN1_NEG_INTEGER) {
40351b91989Sjsing fprintf(stderr, "FAIL: Not V_ASN1_NEG_INTEGER\n");
40451b91989Sjsing goto failed;
40551b91989Sjsing }
406d95bd0c0Sjsing if (ASN1_INTEGER_get(aint) != ait->value) {
407d95bd0c0Sjsing fprintf(stderr, "FAIL: ASN1_INTEGER_get() = %ld, want %ld\n",
408d95bd0c0Sjsing ASN1_INTEGER_get(aint), ait->value);
409d95bd0c0Sjsing goto failed;
410d95bd0c0Sjsing }
41151b91989Sjsing if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
41251b91989Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
41351b91989Sjsing goto failed;
41451b91989Sjsing }
41551b91989Sjsing if ((p = malloc(len)) == NULL)
41651b91989Sjsing errx(1, "malloc");
41751b91989Sjsing memset(p, 0xbd, len);
41851b91989Sjsing pp = p;
41951b91989Sjsing if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
42051b91989Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
42151b91989Sjsing goto failed;
42251b91989Sjsing }
42351b91989Sjsing if (!asn1_compare_bytes("INTEGER set", p, len, ait->der,
42451b91989Sjsing ait->der_len))
42551b91989Sjsing goto failed;
42651b91989Sjsing
42751b91989Sjsing failed = 0;
42851b91989Sjsing
42951b91989Sjsing failed:
43051b91989Sjsing ASN1_INTEGER_free(aint);
43151b91989Sjsing free(p);
43251b91989Sjsing
43351b91989Sjsing return failed;
43451b91989Sjsing }
43551b91989Sjsing
43651b91989Sjsing static int
asn1_integer_content_test(struct asn1_integer_test * ait)43751b91989Sjsing asn1_integer_content_test(struct asn1_integer_test *ait)
43851b91989Sjsing {
43951b91989Sjsing ASN1_INTEGER *aint = NULL;
44051b91989Sjsing uint8_t *p = NULL, *pp;
44151b91989Sjsing int len;
44251b91989Sjsing int failed = 1;
44351b91989Sjsing
44451b91989Sjsing if ((aint = ASN1_INTEGER_new()) == NULL) {
44551b91989Sjsing fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
44651b91989Sjsing goto failed;
44751b91989Sjsing }
44851b91989Sjsing if ((aint->data = malloc(ait->content_len)) == NULL)
44951b91989Sjsing errx(1, "malloc");
45051b91989Sjsing memcpy(aint->data, ait->content, ait->content_len);
45151b91989Sjsing aint->length = ait->content_len;
45251b91989Sjsing if (ait->content_neg)
45351b91989Sjsing aint->type = V_ASN1_NEG_INTEGER;
45451b91989Sjsing
45551b91989Sjsing if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
45651b91989Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
45751b91989Sjsing goto failed;
45851b91989Sjsing }
45951b91989Sjsing if ((p = malloc(len)) == NULL)
46051b91989Sjsing errx(1, "malloc");
46151b91989Sjsing memset(p, 0xbd, len);
46251b91989Sjsing pp = p;
46351b91989Sjsing if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
46451b91989Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
46551b91989Sjsing goto failed;
46651b91989Sjsing }
46751b91989Sjsing if (!asn1_compare_bytes("INTEGER content", p, len, ait->der,
46851b91989Sjsing ait->der_len))
46951b91989Sjsing goto failed;
470d95bd0c0Sjsing if (pp != p + len) {
471d95bd0c0Sjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER pp = %p, want %p\n",
472d95bd0c0Sjsing pp, p + len);
473d95bd0c0Sjsing goto failed;
474d95bd0c0Sjsing }
47551b91989Sjsing
47651b91989Sjsing failed = 0;
47751b91989Sjsing
47851b91989Sjsing failed:
47951b91989Sjsing ASN1_INTEGER_free(aint);
48051b91989Sjsing free(p);
48151b91989Sjsing
48251b91989Sjsing return failed;
48351b91989Sjsing }
48451b91989Sjsing
48551b91989Sjsing static int
asn1_integer_decode_test(struct asn1_integer_test * ait)48651b91989Sjsing asn1_integer_decode_test(struct asn1_integer_test *ait)
48751b91989Sjsing {
48851b91989Sjsing ASN1_INTEGER *aint = NULL;
48951b91989Sjsing const uint8_t *q;
49051b91989Sjsing int failed = 1;
49151b91989Sjsing
49251b91989Sjsing q = ait->der;
49351b91989Sjsing if (d2i_ASN1_INTEGER(&aint, &q, ait->der_len) != NULL) {
49451b91989Sjsing if (ait->want_error != 0) {
49551b91989Sjsing fprintf(stderr, "FAIL: INTEGER decoded when it should "
49651b91989Sjsing "have failed\n");
49751b91989Sjsing goto failed;
49851b91989Sjsing }
49951b91989Sjsing if (!asn1_compare_bytes("INTEGER content", aint->data,
50051b91989Sjsing aint->length, ait->content, ait->content_len))
50151b91989Sjsing goto failed;
502d95bd0c0Sjsing if (q != ait->der + ait->der_len) {
503d95bd0c0Sjsing fprintf(stderr, "FAIL: d2i_ASN1_INTEGER q = %p, want %p\n",
504d95bd0c0Sjsing q, ait->der + ait->der_len);
505d95bd0c0Sjsing goto failed;
506d95bd0c0Sjsing }
50751b91989Sjsing } else if (ait->want_error == 0) {
50851b91989Sjsing fprintf(stderr, "FAIL: INTEGER failed to decode\n");
5093dd3802fSjsing ERR_print_errors_fp(stderr);
51051b91989Sjsing goto failed;
51151b91989Sjsing }
51251b91989Sjsing
51351b91989Sjsing failed = 0;
51451b91989Sjsing
51551b91989Sjsing failed:
51651b91989Sjsing ASN1_INTEGER_free(aint);
51751b91989Sjsing
51851b91989Sjsing return failed;
51951b91989Sjsing }
52051b91989Sjsing
52151b91989Sjsing static int
asn1_integer_set_val_test(void)522888e0020Sjsing asn1_integer_set_val_test(void)
523888e0020Sjsing {
524888e0020Sjsing ASN1_INTEGER *aint = NULL;
525888e0020Sjsing uint64_t uval;
526888e0020Sjsing int64_t val;
527888e0020Sjsing int failed = 1;
528888e0020Sjsing
529888e0020Sjsing if ((aint = ASN1_INTEGER_new()) == NULL) {
530888e0020Sjsing fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
531888e0020Sjsing goto failed;
532888e0020Sjsing }
533888e0020Sjsing
534888e0020Sjsing if (!ASN1_INTEGER_set_uint64(aint, 0)) {
535888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with "
536888e0020Sjsing "0\n");
537888e0020Sjsing goto failed;
538888e0020Sjsing }
539888e0020Sjsing if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
540888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
541888e0020Sjsing "0\n");
542888e0020Sjsing goto failed;
543888e0020Sjsing }
544888e0020Sjsing if (uval != 0) {
545888e0020Sjsing fprintf(stderr, "FAIL: uval != 0\n");
546888e0020Sjsing goto failed;
547888e0020Sjsing }
548888e0020Sjsing
549888e0020Sjsing if (!ASN1_INTEGER_set_uint64(aint, UINT64_MAX)) {
550888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with "
551888e0020Sjsing "UINT64_MAX\n");
552888e0020Sjsing goto failed;
553888e0020Sjsing }
554888e0020Sjsing if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
555888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
556888e0020Sjsing "UINT64_MAX\n");
557888e0020Sjsing goto failed;
558888e0020Sjsing }
559888e0020Sjsing if (uval != UINT64_MAX) {
560888e0020Sjsing fprintf(stderr, "FAIL: uval != UINT64_MAX\n");
561888e0020Sjsing goto failed;
562888e0020Sjsing }
563888e0020Sjsing if (ASN1_INTEGER_get_int64(&val, aint)) {
564888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() succeeded "
565888e0020Sjsing "with UINT64_MAX\n");
566888e0020Sjsing goto failed;
567888e0020Sjsing }
568888e0020Sjsing
569888e0020Sjsing if (!ASN1_INTEGER_set_int64(aint, INT64_MIN)) {
570888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with "
571888e0020Sjsing "INT64_MIN\n");
572888e0020Sjsing goto failed;
573888e0020Sjsing }
574888e0020Sjsing if (!ASN1_INTEGER_get_int64(&val, aint)) {
575888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
576888e0020Sjsing "INT64_MIN\n");
577888e0020Sjsing goto failed;
578888e0020Sjsing }
579888e0020Sjsing if (val != INT64_MIN) {
580888e0020Sjsing fprintf(stderr, "FAIL: val != INT64_MIN\n");
581888e0020Sjsing goto failed;
582888e0020Sjsing }
583888e0020Sjsing if (ASN1_INTEGER_get_uint64(&uval, aint)) {
584888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() succeeded "
585888e0020Sjsing "with INT64_MIN\n");
586888e0020Sjsing goto failed;
587888e0020Sjsing }
588888e0020Sjsing
589888e0020Sjsing if (!ASN1_INTEGER_set_int64(aint, INT64_MAX)) {
590888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with "
591888e0020Sjsing "INT64_MAX\n");
592888e0020Sjsing goto failed;
593888e0020Sjsing }
594888e0020Sjsing if (!ASN1_INTEGER_get_int64(&val, aint)) {
595888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
596888e0020Sjsing "INT64_MAX\n");
597888e0020Sjsing goto failed;
598888e0020Sjsing }
599888e0020Sjsing if (val != INT64_MAX) {
600888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
601888e0020Sjsing "INT64_MAX\n");
602888e0020Sjsing goto failed;
603888e0020Sjsing }
604888e0020Sjsing if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
605888e0020Sjsing fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
606888e0020Sjsing "INT64_MAX\n");
607888e0020Sjsing goto failed;
608888e0020Sjsing }
609888e0020Sjsing if (uval != INT64_MAX) {
610888e0020Sjsing fprintf(stderr, "FAIL: uval != INT64_MAX\n");
611888e0020Sjsing goto failed;
612888e0020Sjsing }
613888e0020Sjsing
614888e0020Sjsing failed = 0;
615888e0020Sjsing
616888e0020Sjsing failed:
617888e0020Sjsing ASN1_INTEGER_free(aint);
618888e0020Sjsing
619888e0020Sjsing return failed;
620888e0020Sjsing }
621888e0020Sjsing
622888e0020Sjsing static int
asn1_integer_cmp_test(void)6239badb9adSjsing asn1_integer_cmp_test(void)
6249badb9adSjsing {
6259badb9adSjsing ASN1_INTEGER *a = NULL, *b = NULL;
6269badb9adSjsing int failed = 1;
6279badb9adSjsing
6289badb9adSjsing if ((a = ASN1_INTEGER_new()) == NULL)
6299badb9adSjsing goto failed;
6309badb9adSjsing if ((b = ASN1_INTEGER_new()) == NULL)
6319badb9adSjsing goto failed;
6329badb9adSjsing
6339badb9adSjsing if (ASN1_INTEGER_cmp(a, b) != 0) {
6349badb9adSjsing fprintf(stderr, "FAIL: INTEGER 0 == 0");
6359badb9adSjsing goto failed;
6369badb9adSjsing }
6379badb9adSjsing
6389badb9adSjsing if (!ASN1_INTEGER_set(b, 1)) {
6399badb9adSjsing fprintf(stderr, "FAIL: failed to set INTEGER");
6409badb9adSjsing goto failed;
6419badb9adSjsing }
6429badb9adSjsing if (ASN1_INTEGER_cmp(a, b) >= 0) {
6439badb9adSjsing fprintf(stderr, "FAIL: INTEGER 0 < 1");
6449badb9adSjsing goto failed;
6459badb9adSjsing }
6469badb9adSjsing if (ASN1_INTEGER_cmp(b, a) <= 0) {
6479badb9adSjsing fprintf(stderr, "FAIL: INTEGER 1 > 0");
6489badb9adSjsing goto failed;
6499badb9adSjsing }
6509badb9adSjsing
6519badb9adSjsing if (!ASN1_INTEGER_set(b, -1)) {
6529badb9adSjsing fprintf(stderr, "FAIL: failed to set INTEGER");
6539badb9adSjsing goto failed;
6549badb9adSjsing }
6559badb9adSjsing if (ASN1_INTEGER_cmp(a, b) <= 0) {
6569badb9adSjsing fprintf(stderr, "FAIL: INTEGER 0 > -1");
6579badb9adSjsing goto failed;
6589badb9adSjsing }
6599badb9adSjsing if (ASN1_INTEGER_cmp(b, a) >= 0) {
6609badb9adSjsing fprintf(stderr, "FAIL: INTEGER -1 < 0");
6619badb9adSjsing goto failed;
6629badb9adSjsing }
6639badb9adSjsing
6649badb9adSjsing if (!ASN1_INTEGER_set(a, 1)) {
6659badb9adSjsing fprintf(stderr, "FAIL: failed to set INTEGER");
6669badb9adSjsing goto failed;
6679badb9adSjsing }
6689badb9adSjsing if (ASN1_INTEGER_cmp(a, b) <= 0) {
6699badb9adSjsing fprintf(stderr, "FAIL: INTEGER 1 > -1");
6709badb9adSjsing goto failed;
6719badb9adSjsing }
6729badb9adSjsing if (ASN1_INTEGER_cmp(b, a) >= 0) {
6739badb9adSjsing fprintf(stderr, "FAIL: INTEGER -1 < 1");
6749badb9adSjsing goto failed;
6759badb9adSjsing }
6769badb9adSjsing
6779badb9adSjsing if (!ASN1_INTEGER_set(b, 1)) {
6789badb9adSjsing fprintf(stderr, "FAIL: failed to set INTEGER");
6799badb9adSjsing goto failed;
6809badb9adSjsing }
6819badb9adSjsing if (ASN1_INTEGER_cmp(a, b) != 0) {
6829badb9adSjsing fprintf(stderr, "FAIL: INTEGER 1 == 1");
6839badb9adSjsing goto failed;
6849badb9adSjsing }
6859badb9adSjsing
6869badb9adSjsing failed = 0;
6879badb9adSjsing
6889badb9adSjsing failed:
6899badb9adSjsing ASN1_INTEGER_free(a);
6909badb9adSjsing ASN1_INTEGER_free(b);
6919badb9adSjsing
6929badb9adSjsing return failed;
6939badb9adSjsing }
6949badb9adSjsing
6959badb9adSjsing static int
asn1_integer_null_data_test(void)696ed3e01bfSjsing asn1_integer_null_data_test(void)
697ed3e01bfSjsing {
698ed3e01bfSjsing const uint8_t der[] = {0x02, 0x01, 0x00};
699ed3e01bfSjsing ASN1_INTEGER *aint = NULL;
700ed3e01bfSjsing uint8_t *p = NULL, *pp;
701ed3e01bfSjsing int len;
702*9ea232b5Stb int failed = 1;
703ed3e01bfSjsing
704ed3e01bfSjsing if ((aint = ASN1_INTEGER_new()) == NULL) {
705ed3e01bfSjsing fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
706ed3e01bfSjsing goto failed;
707ed3e01bfSjsing }
708ed3e01bfSjsing if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
709ed3e01bfSjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
710ed3e01bfSjsing goto failed;
711ed3e01bfSjsing }
712ed3e01bfSjsing if ((p = calloc(1, len)) == NULL)
713ed3e01bfSjsing errx(1, "calloc");
714ed3e01bfSjsing pp = p;
715ed3e01bfSjsing if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
716ed3e01bfSjsing fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
717ed3e01bfSjsing goto failed;
718ed3e01bfSjsing }
719ed3e01bfSjsing if (!asn1_compare_bytes("INTEGER NULL data", p, len, der, sizeof(der)))
720ed3e01bfSjsing goto failed;
721ed3e01bfSjsing
722ed3e01bfSjsing failed = 0;
723ed3e01bfSjsing
724ed3e01bfSjsing failed:
725ed3e01bfSjsing ASN1_INTEGER_free(aint);
726ed3e01bfSjsing free(p);
727ed3e01bfSjsing
728ed3e01bfSjsing return failed;
729ed3e01bfSjsing }
730ed3e01bfSjsing
731ed3e01bfSjsing static int
asn1_integer_test(void)73251b91989Sjsing asn1_integer_test(void)
73351b91989Sjsing {
73451b91989Sjsing struct asn1_integer_test *ait;
73551b91989Sjsing int failed = 0;
73651b91989Sjsing size_t i;
73751b91989Sjsing
73851b91989Sjsing for (i = 0; i < N_ASN1_INTEGER_TESTS; i++) {
73951b91989Sjsing ait = &asn1_integer_tests[i];
74051b91989Sjsing if (ait->content_len > 0 && ait->content_len <= 4)
74151b91989Sjsing failed |= asn1_integer_set_test(ait);
74251b91989Sjsing if (ait->content_len > 0)
74351b91989Sjsing failed |= asn1_integer_content_test(ait);
74451b91989Sjsing failed |= asn1_integer_decode_test(ait);
74551b91989Sjsing }
74651b91989Sjsing
7479badb9adSjsing failed |= asn1_integer_cmp_test();
748ed3e01bfSjsing failed |= asn1_integer_null_data_test();
749888e0020Sjsing failed |= asn1_integer_set_val_test();
7509badb9adSjsing
75151b91989Sjsing return failed;
75251b91989Sjsing }
75351b91989Sjsing
75445ae274fStb static const struct asn1_string_new_test {
75545ae274fStb const char *name;
75645ae274fStb ASN1_STRING *(*new)(void);
75745ae274fStb void (*free)(ASN1_STRING *);
75845ae274fStb int type;
75945ae274fStb long flags;
76045ae274fStb } asn1_string_new_tests[] = {
76145ae274fStb {
76245ae274fStb .name = "ASN1_STRING",
76345ae274fStb .new = ASN1_STRING_new,
76445ae274fStb .free = ASN1_STRING_free,
76545ae274fStb .type = V_ASN1_OCTET_STRING,
76645ae274fStb },
76745ae274fStb {
76845ae274fStb .name = "ASN1_OCTET_STRING",
76945ae274fStb .new = ASN1_OCTET_STRING_new,
77045ae274fStb .free = ASN1_OCTET_STRING_free,
77145ae274fStb .type = V_ASN1_OCTET_STRING,
77245ae274fStb },
77345ae274fStb {
77445ae274fStb .name = "ASN1_BIT_STRING",
77545ae274fStb .new = ASN1_BIT_STRING_new,
77645ae274fStb .free = ASN1_BIT_STRING_free,
77745ae274fStb .type = V_ASN1_BIT_STRING,
77845ae274fStb },
77945ae274fStb {
78045ae274fStb .name = "ASN1_INTEGER",
78145ae274fStb .new = ASN1_INTEGER_new,
78245ae274fStb .free = ASN1_INTEGER_free,
78345ae274fStb .type = V_ASN1_INTEGER,
78445ae274fStb },
78545ae274fStb {
78645ae274fStb .name = "ASN1_ENUMERATED",
78745ae274fStb .new = ASN1_ENUMERATED_new,
78845ae274fStb .free = ASN1_ENUMERATED_free,
78945ae274fStb .type = V_ASN1_ENUMERATED,
79045ae274fStb },
79145ae274fStb {
79245ae274fStb .name = "ASN1_UTF8STRING",
79345ae274fStb .new = ASN1_UTF8STRING_new,
79445ae274fStb .free = ASN1_UTF8STRING_free,
79545ae274fStb .type = V_ASN1_UTF8STRING,
79645ae274fStb },
79745ae274fStb {
79845ae274fStb .name = "ASN1_IA5STRING",
79945ae274fStb .new = ASN1_IA5STRING_new,
80045ae274fStb .free = ASN1_IA5STRING_free,
80145ae274fStb .type = V_ASN1_IA5STRING,
80245ae274fStb },
80345ae274fStb {
80445ae274fStb .name = "ASN1_UNIVERSALSTRING",
80545ae274fStb .new = ASN1_UNIVERSALSTRING_new,
80645ae274fStb .free = ASN1_UNIVERSALSTRING_free,
80745ae274fStb .type = V_ASN1_UNIVERSALSTRING,
80845ae274fStb },
80945ae274fStb {
81045ae274fStb .name = "ASN1_BMPSTRING",
81145ae274fStb .new = ASN1_BMPSTRING_new,
81245ae274fStb .free = ASN1_BMPSTRING_free,
81345ae274fStb .type = V_ASN1_BMPSTRING,
81445ae274fStb },
81545ae274fStb {
81645ae274fStb .name = "ASN1_GENERALSTRING",
81745ae274fStb .new = ASN1_GENERALSTRING_new,
81845ae274fStb .free = ASN1_GENERALSTRING_free,
81945ae274fStb .type = V_ASN1_GENERALSTRING,
82045ae274fStb },
82145ae274fStb {
82245ae274fStb .name = "ASN1_T61STRING",
82345ae274fStb .new = ASN1_T61STRING_new,
82445ae274fStb .free = ASN1_T61STRING_free,
82545ae274fStb .type = V_ASN1_T61STRING,
82645ae274fStb },
82745ae274fStb {
82845ae274fStb .name = "ASN1_VISIBLESTRING",
82945ae274fStb .new = ASN1_VISIBLESTRING_new,
83045ae274fStb .free = ASN1_VISIBLESTRING_free,
83145ae274fStb .type = V_ASN1_VISIBLESTRING,
83245ae274fStb },
83345ae274fStb {
83445ae274fStb .name = "ASN1_PRINTABLESTRING",
83545ae274fStb .new = ASN1_PRINTABLESTRING_new,
83645ae274fStb .free = ASN1_PRINTABLESTRING_free,
83745ae274fStb .type = V_ASN1_PRINTABLESTRING,
83845ae274fStb },
83945ae274fStb {
84045ae274fStb .name = "ASN1_PRINTABLE",
84145ae274fStb .new = ASN1_PRINTABLE_new,
84245ae274fStb .free = ASN1_PRINTABLE_free,
84345ae274fStb .type = V_ASN1_UNDEF,
84445ae274fStb .flags = ASN1_STRING_FLAG_MSTRING,
84545ae274fStb },
84645ae274fStb {
84745ae274fStb .name = "DIRECTORYSTRING",
84845ae274fStb .new = DIRECTORYSTRING_new,
84945ae274fStb .free = DIRECTORYSTRING_free,
85045ae274fStb .type = V_ASN1_UNDEF,
85145ae274fStb .flags = ASN1_STRING_FLAG_MSTRING,
85245ae274fStb },
85345ae274fStb {
85445ae274fStb .name = "DISPLAYTEXT",
85545ae274fStb .new = DISPLAYTEXT_new,
85645ae274fStb .free = DISPLAYTEXT_free,
85745ae274fStb .type = V_ASN1_UNDEF,
85845ae274fStb .flags = ASN1_STRING_FLAG_MSTRING,
85945ae274fStb },
86045ae274fStb {
86145ae274fStb .name = "ASN1_GENERALIZEDTIME",
86245ae274fStb .new = ASN1_GENERALIZEDTIME_new,
86345ae274fStb .free = ASN1_GENERALIZEDTIME_free,
86445ae274fStb .type = V_ASN1_GENERALIZEDTIME,
86545ae274fStb },
86645ae274fStb {
86745ae274fStb .name = "ASN1_UTCTIME",
86845ae274fStb .new = ASN1_UTCTIME_new,
86945ae274fStb .free = ASN1_UTCTIME_free,
87045ae274fStb .type = V_ASN1_UTCTIME,
87145ae274fStb },
87245ae274fStb {
87345ae274fStb .name = "ASN1_TIME",
87445ae274fStb .new = ASN1_TIME_new,
87545ae274fStb .free = ASN1_TIME_free,
87645ae274fStb .type = V_ASN1_UNDEF,
87745ae274fStb .flags = ASN1_STRING_FLAG_MSTRING,
87845ae274fStb },
87945ae274fStb };
88045ae274fStb
88145ae274fStb #define N_ASN1_STRING_NEW_TESTS \
88245ae274fStb (sizeof(asn1_string_new_tests) / sizeof(asn1_string_new_tests[0]))
88345ae274fStb
88445ae274fStb static int
asn1_string_new_test(void)88545ae274fStb asn1_string_new_test(void)
88645ae274fStb {
88745ae274fStb size_t i;
88845ae274fStb ASN1_STRING *astr = NULL;
88945ae274fStb int failed = 1;
89045ae274fStb
89145ae274fStb for (i = 0; i < N_ASN1_STRING_NEW_TESTS; i++) {
89245ae274fStb const struct asn1_string_new_test *asnt = &asn1_string_new_tests[i];
89345ae274fStb
89445ae274fStb if ((astr = asnt->new()) == NULL) {
89545ae274fStb fprintf(stderr, "%s_new() failed\n", asnt->name);
89645ae274fStb goto err;
89745ae274fStb }
89845ae274fStb if (ASN1_STRING_type(astr) != asnt->type) {
89945ae274fStb fprintf(stderr, "%s type: want %d, got %d\n",
90045ae274fStb asnt->name, asnt->type, ASN1_STRING_type(astr));
90145ae274fStb goto err;
90245ae274fStb }
90345ae274fStb if (ASN1_STRING_data(astr) != NULL) {
90445ae274fStb fprintf(stderr, "%s data != NULL\n", asnt->name);
90545ae274fStb goto err;
90645ae274fStb }
90745ae274fStb if (ASN1_STRING_get0_data(astr) != NULL) {
90845ae274fStb fprintf(stderr, "%s data != NULL\n", asnt->name);
90945ae274fStb goto err;
91045ae274fStb }
91145ae274fStb if (ASN1_STRING_length(astr) != 0) {
91245ae274fStb fprintf(stderr, "%s length %d != 0\n", asnt->name,
91345ae274fStb ASN1_STRING_length(astr));
91445ae274fStb goto err;
91545ae274fStb }
91645ae274fStb ASN1_STRING_length_set(astr, 20);
91745ae274fStb if (ASN1_STRING_length(astr) != 20) {
91845ae274fStb fprintf(stderr, "%s length %d != 20\n", asnt->name,
91945ae274fStb ASN1_STRING_length(astr));
92045ae274fStb goto err;
92145ae274fStb }
92245ae274fStb astr->flags |= ASN1_STRING_FLAG_NDEF;
92345ae274fStb if (astr->flags != (asnt->flags | ASN1_STRING_FLAG_NDEF)) {
92445ae274fStb fprintf(stderr, "%s flags: %lx\n", asnt->name,
92545ae274fStb astr->flags);
92645ae274fStb goto err;
92745ae274fStb }
92845ae274fStb /* ASN1_STRING_set0() clears ASN1_STRING_FLAG_NDEF. */
92945ae274fStb ASN1_STRING_set0(astr, NULL, 0);
93045ae274fStb if (astr->flags != asnt->flags) {
93145ae274fStb fprintf(stderr, "%s flags: %lx != %lx\n", asnt->name,
93245ae274fStb astr->flags, asnt->flags);
93345ae274fStb goto err;
93445ae274fStb }
93545ae274fStb asnt->free(astr);
93645ae274fStb astr = NULL;
93745ae274fStb
93845ae274fStb if ((astr = ASN1_STRING_type_new(asnt->type)) == NULL) {
93945ae274fStb fprintf(stderr, "ASN1_STRING_type_new(%s) failed\n",
94045ae274fStb asnt->name);
94145ae274fStb goto err;
94245ae274fStb }
94345ae274fStb if (ASN1_STRING_type(astr) != asnt->type) {
94445ae274fStb fprintf(stderr, "%s type: want %d, got %d\n",
94545ae274fStb asnt->name, asnt->type, ASN1_STRING_type(astr));
94645ae274fStb goto err;
94745ae274fStb }
94845ae274fStb if (ASN1_STRING_data(astr) != NULL) {
94945ae274fStb fprintf(stderr, "%s data != NULL\n", asnt->name);
95045ae274fStb goto err;
95145ae274fStb }
95245ae274fStb /* ASN1_STRING_type_new() does not set flags. */
95345ae274fStb if (astr->flags != 0) {
95445ae274fStb fprintf(stderr, "%s flags %lx\n", asnt->name,
95545ae274fStb astr->flags);
95645ae274fStb goto err;
95745ae274fStb }
95845ae274fStb asnt->free(astr);
95945ae274fStb astr = NULL;
96045ae274fStb
96145ae274fStb }
96245ae274fStb
96345ae274fStb failed = 0;
96445ae274fStb
96545ae274fStb err:
96645ae274fStb ASN1_STRING_free(astr);
96745ae274fStb
96845ae274fStb return failed;
96945ae274fStb }
97045ae274fStb
97178b0b018Stb static char *comparison_str = "mystring";
97278b0b018Stb
97378b0b018Stb static int
asn1_string_cmp_test(void)97478b0b018Stb asn1_string_cmp_test(void)
97578b0b018Stb {
97678b0b018Stb ASN1_STRING *a = NULL, *b = NULL;
97778b0b018Stb int got, want;
97878b0b018Stb int failed = 1;
97978b0b018Stb
98078b0b018Stb if ((got = ASN1_STRING_cmp(NULL, NULL)) != -1) {
98178b0b018Stb fprintf(stderr, "ASN1_STRING_cmp(NULL, NULL): %d != -1\n", got);
98278b0b018Stb goto err;
98378b0b018Stb }
98478b0b018Stb
98578b0b018Stb if ((a = ASN1_STRING_new()) == NULL) {
98678b0b018Stb fprintf(stderr, "a = ASN1_STRING_new() failed\n");
98778b0b018Stb goto err;
98878b0b018Stb }
98978b0b018Stb if ((b = ASN1_STRING_type_new(V_ASN1_UTF8STRING)) == NULL) {
99078b0b018Stb fprintf(stderr, "b = ASN1_STRING_type_new() failed\n");
99178b0b018Stb goto err;
99278b0b018Stb }
99378b0b018Stb
99478b0b018Stb if ((got = ASN1_STRING_cmp(a, NULL)) != -1) {
99578b0b018Stb fprintf(stderr, "ASN1_STRING_cmp(a, NULL): %d != -1\n", got);
99678b0b018Stb goto err;
99778b0b018Stb }
99878b0b018Stb if ((got = ASN1_STRING_cmp(NULL, a)) != -1) {
99978b0b018Stb fprintf(stderr, "ASN1_STRING_cmp(NULL, a): %d != -1\n", got);
100078b0b018Stb goto err;
100178b0b018Stb }
100278b0b018Stb
100378b0b018Stb if (ASN1_STRING_cmp(a, b) >= 0) {
100478b0b018Stb fprintf(stderr, "V_ASN1_OCTET_STRING >= V_ASN1_UTF8STRING\n");
100578b0b018Stb goto err;
100678b0b018Stb }
100778b0b018Stb want = V_ASN1_UTF8STRING - V_ASN1_OCTET_STRING;
100878b0b018Stb if ((got = ASN1_STRING_cmp(b, a)) != want) {
100978b0b018Stb fprintf(stderr, "comparison of octet with utf8 string:"
101078b0b018Stb "want %d, got %d\n", want, got);
101178b0b018Stb goto err;
101278b0b018Stb }
101378b0b018Stb
101478b0b018Stb ASN1_STRING_set0(a, comparison_str, strlen(comparison_str));
101578b0b018Stb ASN1_STRING_set0(b, comparison_str, strlen(comparison_str));
101678b0b018Stb
101778b0b018Stb /* Ensure any data set on a or b isn't freed/zeroed. */
101878b0b018Stb a->flags |= ASN1_STRING_FLAG_NDEF;
101978b0b018Stb b->flags |= ASN1_STRING_FLAG_NDEF;
102078b0b018Stb
102178b0b018Stb if ((got = ASN1_STRING_cmp(b, a)) != want) {
102278b0b018Stb fprintf(stderr, "comparison of octet with utf8 string:"
102378b0b018Stb "want %d, got %d\n", want, got);
102478b0b018Stb goto err;
102578b0b018Stb }
102678b0b018Stb
102778b0b018Stb b->type = V_ASN1_OCTET_STRING;
102878b0b018Stb
102978b0b018Stb if ((got = ASN1_STRING_cmp(a, b)) != 0) {
103078b0b018Stb fprintf(stderr, "same string on both. want 0, got %d\n", got);
103178b0b018Stb goto err;
103278b0b018Stb }
103378b0b018Stb
103478b0b018Stb if (!ASN1_STRING_set(b, "myString", -1)) {
103578b0b018Stb fprintf(stderr, "ASN1_STRING_set(b) failed\n");
103678b0b018Stb goto err;
103778b0b018Stb }
103878b0b018Stb
103978b0b018Stb if ((got = ASN1_STRING_cmp(a, b)) <= 0) {
104078b0b018Stb fprintf(stderr, "capitalized letter compares larger: got %d\n",
104178b0b018Stb got);
104278b0b018Stb goto err;
104378b0b018Stb }
104478b0b018Stb if ((got = ASN1_STRING_cmp(b, a)) >= 0) {
104578b0b018Stb fprintf(stderr, "capitalized letter is larger 2: %d\n", got);
104678b0b018Stb goto err;
104778b0b018Stb }
104878b0b018Stb
104978b0b018Stb ASN1_STRING_length_set(b, 2);
105078b0b018Stb
105178b0b018Stb want = strlen(comparison_str) - 2;
105278b0b018Stb
105378b0b018Stb if ((got = ASN1_STRING_cmp(a, b)) != want) {
105478b0b018Stb fprintf(stderr, "comparison of a with truncated b: "
105578b0b018Stb "want %d, got %d\n", want, got);
105678b0b018Stb goto err;
105778b0b018Stb }
105878b0b018Stb
105978b0b018Stb want = -want;
106078b0b018Stb
106178b0b018Stb if ((got = ASN1_STRING_cmp(b, a)) != want) {
106278b0b018Stb fprintf(stderr, "comparison of truncated b with a: "
106378b0b018Stb "want %d, got %d\n", want, got);
106478b0b018Stb goto err;
106578b0b018Stb }
106678b0b018Stb
106778b0b018Stb ASN1_STRING_length_set(a, 2);
106878b0b018Stb
106978b0b018Stb if ((got = ASN1_STRING_cmp(a, b)) != 0) {
107078b0b018Stb fprintf(stderr, "both truncated compared to %d\n", got);
107178b0b018Stb goto err;
107278b0b018Stb }
107378b0b018Stb
107478b0b018Stb ASN1_STRING_length_set(a, strlen(comparison_str));
107578b0b018Stb
107678b0b018Stb ASN1_STRING_set0(b, NULL, 0);
107778b0b018Stb
107878b0b018Stb want = strlen(comparison_str);
107978b0b018Stb if ((got = ASN1_STRING_cmp(a, b)) != want) {
108078b0b018Stb fprintf(stderr, "comparison of a with zeroed b: "
108178b0b018Stb "want %d, got %d\n", want, got);
108278b0b018Stb goto err;
108378b0b018Stb }
108478b0b018Stb
108578b0b018Stb ASN1_STRING_set0(b, "", 0);
108678b0b018Stb b->flags |= ASN1_STRING_FLAG_NDEF;
108778b0b018Stb
108878b0b018Stb if ((got = ASN1_STRING_cmp(a, b)) != want) {
108978b0b018Stb fprintf(stderr, "comparison of a with zero-length b: "
109078b0b018Stb "want %d, got %d\n", want, got);
109178b0b018Stb goto err;
109278b0b018Stb }
109378b0b018Stb
109478b0b018Stb ASN1_STRING_set0(a, NULL, 0);
109578b0b018Stb if ((got = ASN1_STRING_cmp(a, b)) != 0) {
109678b0b018Stb fprintf(stderr, "comparison of zeroed a with zero-length b: "
109778b0b018Stb "want 0, got %d\n", got);
109878b0b018Stb goto err;
109978b0b018Stb }
110078b0b018Stb if ((got = ASN1_STRING_cmp(b, a)) != 0) {
110178b0b018Stb fprintf(stderr, "comparison of zero-length b with zeroed a: "
110278b0b018Stb "want 0, got %d\n", got);
110378b0b018Stb goto err;
110478b0b018Stb }
110578b0b018Stb
110678b0b018Stb failed = 0;
110778b0b018Stb
110878b0b018Stb err:
110978b0b018Stb ASN1_STRING_free(a);
111078b0b018Stb ASN1_STRING_free(b);
111178b0b018Stb
111278b0b018Stb return failed;
111378b0b018Stb }
111478b0b018Stb
111545ae274fStb static int
asn1_string_test(void)111645ae274fStb asn1_string_test(void)
111745ae274fStb {
111845ae274fStb int failed = 0;
111945ae274fStb
112045ae274fStb failed |= asn1_string_new_test();
112178b0b018Stb failed |= asn1_string_cmp_test();
112245ae274fStb
112345ae274fStb return failed;
112445ae274fStb }
112545ae274fStb
1126725e2e31Sjsing int
main(int argc,char ** argv)1127725e2e31Sjsing main(int argc, char **argv)
1128725e2e31Sjsing {
1129725e2e31Sjsing int failed = 0;
1130725e2e31Sjsing
113130fc8fe5Sjsing failed |= asn1_bit_string_test();
1132725e2e31Sjsing failed |= asn1_boolean_test();
113351b91989Sjsing failed |= asn1_integer_test();
113445ae274fStb failed |= asn1_string_test();
1135725e2e31Sjsing
1136725e2e31Sjsing return (failed);
1137725e2e31Sjsing }
1138