xref: /openbsd-src/regress/lib/libcrypto/asn1/asn1basic.c (revision 9ea232b5eaf388983a2f2886d7918b2ea8495d2e)
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