xref: /openbsd-src/regress/lib/libcrypto/asn1/asn1basic.c (revision 9badb9ad8932c12f4ece484255eb2703a2518c17)
1*9badb9adSjsing /* $OpenBSD: asn1basic.c,v 1.7 2022/06/25 13:57:17 jsing Exp $ */
2725e2e31Sjsing /*
3725e2e31Sjsing  * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org>
4725e2e31Sjsing  *
5725e2e31Sjsing  * Permission to use, copy, modify, and distribute this software for any
6725e2e31Sjsing  * purpose with or without fee is hereby granted, provided that the above
7725e2e31Sjsing  * copyright notice and this permission notice appear in all copies.
8725e2e31Sjsing  *
9725e2e31Sjsing  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10725e2e31Sjsing  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11725e2e31Sjsing  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12725e2e31Sjsing  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13725e2e31Sjsing  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14725e2e31Sjsing  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15725e2e31Sjsing  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16725e2e31Sjsing  */
17725e2e31Sjsing 
18725e2e31Sjsing #include <openssl/asn1.h>
19725e2e31Sjsing 
20725e2e31Sjsing #include <err.h>
21725e2e31Sjsing #include <stdio.h>
22725e2e31Sjsing #include <string.h>
23725e2e31Sjsing 
249773c5c8Stb #include "asn1_locl.h"
259773c5c8Stb 
26725e2e31Sjsing static void
27725e2e31Sjsing hexdump(const unsigned char *buf, size_t len)
28725e2e31Sjsing {
29725e2e31Sjsing 	size_t i;
30725e2e31Sjsing 
31725e2e31Sjsing 	for (i = 1; i <= len; i++)
32725e2e31Sjsing 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
33725e2e31Sjsing 
34725e2e31Sjsing 	fprintf(stderr, "\n");
35725e2e31Sjsing }
36725e2e31Sjsing 
37725e2e31Sjsing static int
38725e2e31Sjsing asn1_compare_bytes(const char *label, const unsigned char *d1, int len1,
39725e2e31Sjsing     const unsigned char *d2, int len2)
40725e2e31Sjsing {
41725e2e31Sjsing 	if (len1 != len2) {
42725e2e31Sjsing 		fprintf(stderr, "FAIL: %s - byte lengths differ "
43725e2e31Sjsing 		    "(%i != %i)\n", label, len1, len2);
4430fc8fe5Sjsing 		fprintf(stderr, "Got:\n");
4530fc8fe5Sjsing 		hexdump(d1, len1);
4630fc8fe5Sjsing 		fprintf(stderr, "Want:\n");
4730fc8fe5Sjsing 		hexdump(d2, len2);
48725e2e31Sjsing 		return 0;
49725e2e31Sjsing 	}
50725e2e31Sjsing 	if (memcmp(d1, d2, len1) != 0) {
51725e2e31Sjsing 		fprintf(stderr, "FAIL: %s - bytes differ\n", label);
52725e2e31Sjsing 		fprintf(stderr, "Got:\n");
53725e2e31Sjsing 		hexdump(d1, len1);
54725e2e31Sjsing 		fprintf(stderr, "Want:\n");
55725e2e31Sjsing 		hexdump(d2, len2);
56725e2e31Sjsing 		return 0;
57725e2e31Sjsing 	}
58725e2e31Sjsing 	return 1;
59725e2e31Sjsing }
60725e2e31Sjsing 
6130fc8fe5Sjsing const uint8_t asn1_bit_string_primitive[] = {
6230fc8fe5Sjsing 	0x03, 0x07,
6330fc8fe5Sjsing 	0x04, 0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0,
6430fc8fe5Sjsing };
6530fc8fe5Sjsing 
6630fc8fe5Sjsing static int
6730fc8fe5Sjsing asn1_bit_string_test(void)
6830fc8fe5Sjsing {
6930fc8fe5Sjsing 	uint8_t bs[] = {0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0};
7030fc8fe5Sjsing 	ASN1_BIT_STRING *abs;
7130fc8fe5Sjsing 	uint8_t *p = NULL, *pp;
7230fc8fe5Sjsing 	const uint8_t *q;
7330fc8fe5Sjsing 	int bit, i, len;
7430fc8fe5Sjsing 	int failed = 1;
7530fc8fe5Sjsing 
7630fc8fe5Sjsing 	if ((abs = ASN1_BIT_STRING_new()) == NULL) {
7730fc8fe5Sjsing 		fprintf(stderr, "FAIL: ASN1_BIT_STRING_new() == NULL\n");
7830fc8fe5Sjsing 		goto failed;
7930fc8fe5Sjsing 	}
8030fc8fe5Sjsing 	if (!ASN1_BIT_STRING_set(abs, bs, sizeof(bs))) {
8130fc8fe5Sjsing 		fprintf(stderr, "FAIL: failed to set bit string\n");
8230fc8fe5Sjsing 		goto failed;
8330fc8fe5Sjsing 	}
8430fc8fe5Sjsing 
8530fc8fe5Sjsing 	if ((len = i2d_ASN1_BIT_STRING(abs, NULL)) < 0) {
8630fc8fe5Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING with NULL\n");
8730fc8fe5Sjsing 		goto failed;
8830fc8fe5Sjsing 	}
8930fc8fe5Sjsing 	if ((p = malloc(len)) == NULL)
9030fc8fe5Sjsing 		errx(1, "malloc");
9130fc8fe5Sjsing 	memset(p, 0xbd, len);
9230fc8fe5Sjsing 	pp = p;
9330fc8fe5Sjsing 	if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) {
9430fc8fe5Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
9530fc8fe5Sjsing 		goto failed;
9630fc8fe5Sjsing 	}
9730fc8fe5Sjsing 
9830fc8fe5Sjsing 	if (!asn1_compare_bytes("BIT_STRING", p, len, asn1_bit_string_primitive,
9930fc8fe5Sjsing 	    sizeof(asn1_bit_string_primitive)))
10030fc8fe5Sjsing 		goto failed;
10130fc8fe5Sjsing 
10230fc8fe5Sjsing 	/* Test primitive decoding. */
10330fc8fe5Sjsing 	q = p;
10430fc8fe5Sjsing 	if (d2i_ASN1_BIT_STRING(&abs, &q, len) == NULL) {
10530fc8fe5Sjsing 		fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING primitive\n");
10630fc8fe5Sjsing 		goto failed;
10730fc8fe5Sjsing 	}
10830fc8fe5Sjsing 	if (!asn1_compare_bytes("BIT_STRING primitive data", abs->data, abs->length,
10930fc8fe5Sjsing 	    bs, sizeof(bs)))
11030fc8fe5Sjsing 		goto failed;
11130fc8fe5Sjsing 
11230fc8fe5Sjsing 	/* Test ASN1_BIT_STRING_get_bit(). */
11330fc8fe5Sjsing 	for (i = 0; i < ((int)sizeof(bs) * 8); i++) {
11430fc8fe5Sjsing 		bit = (bs[i / 8] >> (7 - i % 8)) & 1;
11530fc8fe5Sjsing 
11630fc8fe5Sjsing 		if (ASN1_BIT_STRING_get_bit(abs, i) != bit) {
11730fc8fe5Sjsing 			fprintf(stderr, "FAIL: ASN1_BIT_STRING_get_bit(_, %d) "
11830fc8fe5Sjsing 			    "= %d, want %d\n", i,
11930fc8fe5Sjsing 			    ASN1_BIT_STRING_get_bit(abs, i), bit);
12030fc8fe5Sjsing 			goto failed;
12130fc8fe5Sjsing 		}
12230fc8fe5Sjsing 	}
12330fc8fe5Sjsing 
12430fc8fe5Sjsing 	/* Test ASN1_BIT_STRING_set_bit(). */
12530fc8fe5Sjsing 	for (i = 0; i < ((int)sizeof(bs) * 8); i++) {
12630fc8fe5Sjsing 		if (!ASN1_BIT_STRING_set_bit(abs, i, 1)) {
12730fc8fe5Sjsing 			fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit 1\n");
12830fc8fe5Sjsing 			goto failed;
12930fc8fe5Sjsing 		}
13030fc8fe5Sjsing 	}
13130fc8fe5Sjsing 	for (i = ((int)sizeof(bs) * 8) - 1; i >= 0; i--) {
13230fc8fe5Sjsing 		bit = (bs[i / 8] >> (7 - i % 8)) & 1;
13330fc8fe5Sjsing 		if (bit == 1)
13430fc8fe5Sjsing 			continue;
13530fc8fe5Sjsing 		if (!ASN1_BIT_STRING_set_bit(abs, i, 0)) {
13630fc8fe5Sjsing 			fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit\n");
13730fc8fe5Sjsing 			goto failed;
13830fc8fe5Sjsing 		}
13930fc8fe5Sjsing 	}
14030fc8fe5Sjsing 
14130fc8fe5Sjsing 	if ((i2d_ASN1_BIT_STRING(abs, NULL)) != len) {
14230fc8fe5Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
14330fc8fe5Sjsing 		goto failed;
14430fc8fe5Sjsing 	}
14530fc8fe5Sjsing 
14630fc8fe5Sjsing 	memset(p, 0xbd, len);
14730fc8fe5Sjsing 	pp = p;
14830fc8fe5Sjsing 	if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) {
14930fc8fe5Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
15030fc8fe5Sjsing 		goto failed;
15130fc8fe5Sjsing 	}
15230fc8fe5Sjsing 
15330fc8fe5Sjsing 	if (!asn1_compare_bytes("BIT_STRING set", p, len, asn1_bit_string_primitive,
15430fc8fe5Sjsing 	    sizeof(asn1_bit_string_primitive)))
15530fc8fe5Sjsing 		goto failed;
15630fc8fe5Sjsing 
15730fc8fe5Sjsing 	failed = 0;
15830fc8fe5Sjsing 
15930fc8fe5Sjsing  failed:
16030fc8fe5Sjsing 	ASN1_BIT_STRING_free(abs);
16130fc8fe5Sjsing 	free(p);
16230fc8fe5Sjsing 
16330fc8fe5Sjsing 	return failed;
16430fc8fe5Sjsing }
16530fc8fe5Sjsing 
166725e2e31Sjsing const uint8_t asn1_boolean_false[] = {
167725e2e31Sjsing 	0x01, 0x01, 0x00,
168725e2e31Sjsing };
169725e2e31Sjsing const uint8_t asn1_boolean_true[] = {
170725e2e31Sjsing 	0x01, 0x01, 0x01,
171725e2e31Sjsing };
172725e2e31Sjsing 
173725e2e31Sjsing static int
174725e2e31Sjsing asn1_boolean_test(void)
175725e2e31Sjsing {
176725e2e31Sjsing 	uint8_t *p = NULL, *pp;
177725e2e31Sjsing 	const uint8_t *q;
178725e2e31Sjsing 	int len;
179725e2e31Sjsing 	int failed = 1;
180725e2e31Sjsing 
181725e2e31Sjsing 	if ((len = i2d_ASN1_BOOLEAN(0, NULL)) < 0) {
182725e2e31Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false with NULL\n");
183725e2e31Sjsing 		goto failed;
184725e2e31Sjsing 	}
18530fc8fe5Sjsing 	if ((p = malloc(len)) == NULL)
186725e2e31Sjsing 		errx(1, "calloc");
18730fc8fe5Sjsing 	memset(p, 0xbd, len);
188725e2e31Sjsing 	pp = p;
189725e2e31Sjsing 	if ((i2d_ASN1_BOOLEAN(0, &pp)) != len) {
190725e2e31Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false\n");
191725e2e31Sjsing 		goto failed;
192725e2e31Sjsing 	}
193725e2e31Sjsing 
194725e2e31Sjsing 	if (!asn1_compare_bytes("BOOLEAN false", p, len, asn1_boolean_false,
195725e2e31Sjsing 	    sizeof(asn1_boolean_false)))
196725e2e31Sjsing 		goto failed;
197725e2e31Sjsing 
198725e2e31Sjsing 	q = p;
199725e2e31Sjsing 	if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 0) {
200725e2e31Sjsing 		fprintf(stderr, "FAIL: BOOLEAN false did not decode to 0\n");
201725e2e31Sjsing 		goto failed;
202725e2e31Sjsing 	}
203725e2e31Sjsing 
204725e2e31Sjsing 	free(p);
205725e2e31Sjsing 	p = NULL;
206725e2e31Sjsing 
207725e2e31Sjsing 	if ((len = i2d_ASN1_BOOLEAN(1, NULL)) < 0) {
208725e2e31Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true with NULL\n");
209725e2e31Sjsing 		goto failed;
210725e2e31Sjsing 	}
211725e2e31Sjsing 	if ((p = calloc(1, len)) == NULL)
212725e2e31Sjsing 		errx(1, "calloc");
213725e2e31Sjsing 	pp = p;
214725e2e31Sjsing 	if ((i2d_ASN1_BOOLEAN(1, &pp)) != len) {
215725e2e31Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true\n");
216725e2e31Sjsing 		goto failed;
217725e2e31Sjsing 	}
218725e2e31Sjsing 
219725e2e31Sjsing 	if (!asn1_compare_bytes("BOOLEAN true", p, len, asn1_boolean_true,
220725e2e31Sjsing 	    sizeof(asn1_boolean_true)))
221725e2e31Sjsing 		goto failed;
222725e2e31Sjsing 
223725e2e31Sjsing 	q = p;
224725e2e31Sjsing 	if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 1) {
22572ad5686Stb 		fprintf(stderr, "FAIL: BOOLEAN true did not decode to 1\n");
226725e2e31Sjsing 		goto failed;
227725e2e31Sjsing 	}
228725e2e31Sjsing 
229725e2e31Sjsing 	failed = 0;
230725e2e31Sjsing 
231725e2e31Sjsing  failed:
232725e2e31Sjsing 	free(p);
233725e2e31Sjsing 
234725e2e31Sjsing 	return failed;
235725e2e31Sjsing }
236725e2e31Sjsing 
23751b91989Sjsing struct asn1_integer_test {
23851b91989Sjsing 	long value;
23951b91989Sjsing 	uint8_t content[64];
24051b91989Sjsing 	size_t content_len;
24151b91989Sjsing 	int content_neg;
24251b91989Sjsing 	uint8_t der[64];
24351b91989Sjsing 	size_t der_len;
24451b91989Sjsing 	int want_error;
24551b91989Sjsing };
24651b91989Sjsing 
24751b91989Sjsing struct asn1_integer_test asn1_integer_tests[] = {
24851b91989Sjsing 	{
24951b91989Sjsing 		.value = 0,
25051b91989Sjsing 		.content = {0x00},
25151b91989Sjsing 		.content_len = 1,
25251b91989Sjsing 		.der = {0x02, 0x01, 0x00},
25351b91989Sjsing 		.der_len = 3,
25451b91989Sjsing 	},
25551b91989Sjsing 	{
25651b91989Sjsing 		.value = 1,
25751b91989Sjsing 		.content = {0x01},
25851b91989Sjsing 		.content_len = 1,
25951b91989Sjsing 		.der = {0x02, 0x01, 0x01},
26051b91989Sjsing 		.der_len = 3,
26151b91989Sjsing 	},
26251b91989Sjsing 	{
26351b91989Sjsing 		.value = -1,
26451b91989Sjsing 		.content = {0x01},
26551b91989Sjsing 		.content_len = 1,
26651b91989Sjsing 		.content_neg = 1,
26751b91989Sjsing 		.der = {0x02, 0x01, 0xff},
26851b91989Sjsing 		.der_len = 3,
26951b91989Sjsing 	},
27051b91989Sjsing 	{
27151b91989Sjsing 		.value = 127,
27251b91989Sjsing 		.content = {0x7f},
27351b91989Sjsing 		.content_len = 1,
27451b91989Sjsing 		.der = {0x02, 0x01, 0x7f},
27551b91989Sjsing 		.der_len = 3,
27651b91989Sjsing 	},
27751b91989Sjsing 	{
27851b91989Sjsing 		.value = -127,
27951b91989Sjsing 		.content = {0x7f},
28051b91989Sjsing 		.content_len = 1,
28151b91989Sjsing 		.content_neg = 1,
28251b91989Sjsing 		.der = {0x02, 0x01, 0x81},
28351b91989Sjsing 		.der_len = 3,
28451b91989Sjsing 	},
28551b91989Sjsing 	{
28651b91989Sjsing 		.value = 128,
28751b91989Sjsing 		.content = {0x80},
28851b91989Sjsing 		.content_len = 1,
28951b91989Sjsing 		.der = {0x02, 0x02, 0x00, 0x80},
29051b91989Sjsing 		.der_len = 4,
29151b91989Sjsing 	},
29251b91989Sjsing 	{
29351b91989Sjsing 		.value = -128,
29451b91989Sjsing 		.content = {0x80},
29551b91989Sjsing 		.content_len = 1,
29651b91989Sjsing 		.content_neg = 1,
29751b91989Sjsing 		.der = {0x02, 0x01, 0x80},
29851b91989Sjsing 		.der_len = 3,
29951b91989Sjsing 	},
30051b91989Sjsing 	{
30151b91989Sjsing 		/* 2^64 */
30251b91989Sjsing 		.content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
30351b91989Sjsing 		.content_len = 9,
30451b91989Sjsing 		.der = {0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
30551b91989Sjsing 		.der_len = 11,
30651b91989Sjsing 	},
30751b91989Sjsing 	{
30851b91989Sjsing 		/* -2^64 */
30951b91989Sjsing 		.content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
31051b91989Sjsing 		.content_len = 9,
31151b91989Sjsing 		.content_neg = 1,
31251b91989Sjsing 		.der = {0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
31351b91989Sjsing 		.der_len = 11,
31451b91989Sjsing 	},
31551b91989Sjsing 	{
31651b91989Sjsing 		/* Invalid length. */
31751b91989Sjsing 		.der = {0x02, 0x00},
31851b91989Sjsing 		.der_len = 2,
31951b91989Sjsing 		.want_error = 1,
32051b91989Sjsing 	},
32151b91989Sjsing 	{
32251b91989Sjsing 		/* Invalid padding. */
32351b91989Sjsing 		.der = {0x02, 0x09, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
32451b91989Sjsing 		.der_len = 11,
32551b91989Sjsing 		.want_error = 1,
32651b91989Sjsing 	},
32751b91989Sjsing 	{
32851b91989Sjsing 		/* Invalid padding. */
32951b91989Sjsing 		.der = {0x02, 0x09, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
33051b91989Sjsing 		.der_len = 11,
33151b91989Sjsing 		.want_error = 1,
33251b91989Sjsing 	},
33351b91989Sjsing };
33451b91989Sjsing 
33551b91989Sjsing #define N_ASN1_INTEGER_TESTS \
33651b91989Sjsing     (sizeof(asn1_integer_tests) / sizeof(*asn1_integer_tests))
33751b91989Sjsing 
33851b91989Sjsing static int
33951b91989Sjsing asn1_integer_set_test(struct asn1_integer_test *ait)
34051b91989Sjsing {
34151b91989Sjsing 	ASN1_INTEGER *aint = NULL;
34251b91989Sjsing 	uint8_t *p = NULL, *pp;
34351b91989Sjsing 	int len;
34451b91989Sjsing 	int failed = 1;
34551b91989Sjsing 
34651b91989Sjsing 	if ((aint = ASN1_INTEGER_new()) == NULL) {
34751b91989Sjsing 		fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
34851b91989Sjsing 		goto failed;
34951b91989Sjsing 	}
35051b91989Sjsing 	if (!ASN1_INTEGER_set(aint, ait->value)) {
35151b91989Sjsing 		fprintf(stderr, "FAIL: ASN1_INTEGER_(%ld) failed\n",
35251b91989Sjsing 		    ait->value);
35351b91989Sjsing 		goto failed;
35451b91989Sjsing 	}
35551b91989Sjsing 	if (ait->value != 0 &&
35651b91989Sjsing 	    !asn1_compare_bytes("INTEGER set", aint->data, aint->length,
35751b91989Sjsing 	    ait->content, ait->content_len))
35851b91989Sjsing 		goto failed;
35951b91989Sjsing 	if (ait->content_neg && aint->type != V_ASN1_NEG_INTEGER) {
36051b91989Sjsing 		fprintf(stderr, "FAIL: Not V_ASN1_NEG_INTEGER\n");
36151b91989Sjsing 		goto failed;
36251b91989Sjsing 	}
36351b91989Sjsing 	if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
36451b91989Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
36551b91989Sjsing 		goto failed;
36651b91989Sjsing 	}
36751b91989Sjsing 	if ((p = malloc(len)) == NULL)
36851b91989Sjsing 		errx(1, "malloc");
36951b91989Sjsing 	memset(p, 0xbd, len);
37051b91989Sjsing 	pp = p;
37151b91989Sjsing 	if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
37251b91989Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
37351b91989Sjsing 		goto failed;
37451b91989Sjsing 	}
37551b91989Sjsing 	if (!asn1_compare_bytes("INTEGER set", p, len, ait->der,
37651b91989Sjsing 	    ait->der_len))
37751b91989Sjsing 		goto failed;
37851b91989Sjsing 
37951b91989Sjsing 	failed = 0;
38051b91989Sjsing 
38151b91989Sjsing  failed:
38251b91989Sjsing 	ASN1_INTEGER_free(aint);
38351b91989Sjsing 	free(p);
38451b91989Sjsing 
38551b91989Sjsing 	return failed;
38651b91989Sjsing }
38751b91989Sjsing 
38851b91989Sjsing static int
38951b91989Sjsing asn1_integer_content_test(struct asn1_integer_test *ait)
39051b91989Sjsing {
39151b91989Sjsing 	ASN1_INTEGER *aint = NULL;
39251b91989Sjsing 	uint8_t *p = NULL, *pp;
39351b91989Sjsing 	int len;
39451b91989Sjsing 	int failed = 1;
39551b91989Sjsing 
39651b91989Sjsing 	if ((aint = ASN1_INTEGER_new()) == NULL) {
39751b91989Sjsing 		fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
39851b91989Sjsing 		goto failed;
39951b91989Sjsing 	}
40051b91989Sjsing 	if ((aint->data = malloc(ait->content_len)) == NULL)
40151b91989Sjsing 		errx(1, "malloc");
40251b91989Sjsing 	memcpy(aint->data, ait->content, ait->content_len);
40351b91989Sjsing 	aint->length = ait->content_len;
40451b91989Sjsing 	if (ait->content_neg)
40551b91989Sjsing 		aint->type = V_ASN1_NEG_INTEGER;
40651b91989Sjsing 
40751b91989Sjsing 	if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
40851b91989Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
40951b91989Sjsing 		goto failed;
41051b91989Sjsing 	}
41151b91989Sjsing 	if ((p = malloc(len)) == NULL)
41251b91989Sjsing 		errx(1, "malloc");
41351b91989Sjsing 	memset(p, 0xbd, len);
41451b91989Sjsing 	pp = p;
41551b91989Sjsing 	if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
41651b91989Sjsing 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
41751b91989Sjsing 		goto failed;
41851b91989Sjsing 	}
41951b91989Sjsing 	if (!asn1_compare_bytes("INTEGER content", p, len, ait->der,
42051b91989Sjsing 	    ait->der_len))
42151b91989Sjsing 		goto failed;
42251b91989Sjsing 
42351b91989Sjsing 	failed = 0;
42451b91989Sjsing 
42551b91989Sjsing  failed:
42651b91989Sjsing 	ASN1_INTEGER_free(aint);
42751b91989Sjsing 	free(p);
42851b91989Sjsing 
42951b91989Sjsing 	return failed;
43051b91989Sjsing }
43151b91989Sjsing 
43251b91989Sjsing static int
43351b91989Sjsing asn1_integer_decode_test(struct asn1_integer_test *ait)
43451b91989Sjsing {
43551b91989Sjsing 	ASN1_INTEGER *aint = NULL;
43651b91989Sjsing 	const uint8_t *q;
43751b91989Sjsing 	int failed = 1;
43851b91989Sjsing 
43951b91989Sjsing 	q = ait->der;
44051b91989Sjsing 	if (d2i_ASN1_INTEGER(&aint, &q, ait->der_len) != NULL) {
44151b91989Sjsing 		if (ait->want_error != 0) {
44251b91989Sjsing 			fprintf(stderr, "FAIL: INTEGER decoded when it should "
44351b91989Sjsing 			    "have failed\n");
44451b91989Sjsing 			goto failed;
44551b91989Sjsing 		}
44651b91989Sjsing 		if (!asn1_compare_bytes("INTEGER content", aint->data,
44751b91989Sjsing 		    aint->length, ait->content, ait->content_len))
44851b91989Sjsing 			goto failed;
44951b91989Sjsing 	} else if (ait->want_error == 0) {
45051b91989Sjsing 		fprintf(stderr, "FAIL: INTEGER failed to decode\n");
45151b91989Sjsing 		goto failed;
45251b91989Sjsing 	}
45351b91989Sjsing 
45451b91989Sjsing 	failed = 0;
45551b91989Sjsing 
45651b91989Sjsing  failed:
45751b91989Sjsing 	ASN1_INTEGER_free(aint);
45851b91989Sjsing 
45951b91989Sjsing 	return failed;
46051b91989Sjsing }
46151b91989Sjsing 
46251b91989Sjsing static int
463*9badb9adSjsing asn1_integer_cmp_test(void)
464*9badb9adSjsing {
465*9badb9adSjsing 	ASN1_INTEGER *a = NULL, *b = NULL;
466*9badb9adSjsing 	int failed = 1;
467*9badb9adSjsing 
468*9badb9adSjsing 	if ((a = ASN1_INTEGER_new()) == NULL)
469*9badb9adSjsing 		goto failed;
470*9badb9adSjsing 	if ((b = ASN1_INTEGER_new()) == NULL)
471*9badb9adSjsing 		goto failed;
472*9badb9adSjsing 
473*9badb9adSjsing 	if (ASN1_INTEGER_cmp(a, b) != 0) {
474*9badb9adSjsing 		fprintf(stderr, "FAIL: INTEGER 0 == 0");
475*9badb9adSjsing 		goto failed;
476*9badb9adSjsing 	}
477*9badb9adSjsing 
478*9badb9adSjsing 	if (!ASN1_INTEGER_set(b, 1)) {
479*9badb9adSjsing 		fprintf(stderr, "FAIL: failed to set INTEGER");
480*9badb9adSjsing 		goto failed;
481*9badb9adSjsing 	}
482*9badb9adSjsing 	if (ASN1_INTEGER_cmp(a, b) >= 0) {
483*9badb9adSjsing 		fprintf(stderr, "FAIL: INTEGER 0 < 1");
484*9badb9adSjsing 		goto failed;
485*9badb9adSjsing 	}
486*9badb9adSjsing 	if (ASN1_INTEGER_cmp(b, a) <= 0) {
487*9badb9adSjsing 		fprintf(stderr, "FAIL: INTEGER 1 > 0");
488*9badb9adSjsing 		goto failed;
489*9badb9adSjsing 	}
490*9badb9adSjsing 
491*9badb9adSjsing 	if (!ASN1_INTEGER_set(b, -1)) {
492*9badb9adSjsing 		fprintf(stderr, "FAIL: failed to set INTEGER");
493*9badb9adSjsing 		goto failed;
494*9badb9adSjsing 	}
495*9badb9adSjsing 	if (ASN1_INTEGER_cmp(a, b) <= 0) {
496*9badb9adSjsing 		fprintf(stderr, "FAIL: INTEGER 0 > -1");
497*9badb9adSjsing 		goto failed;
498*9badb9adSjsing 	}
499*9badb9adSjsing 	if (ASN1_INTEGER_cmp(b, a) >= 0) {
500*9badb9adSjsing 		fprintf(stderr, "FAIL: INTEGER -1 < 0");
501*9badb9adSjsing 		goto failed;
502*9badb9adSjsing 	}
503*9badb9adSjsing 
504*9badb9adSjsing 	if (!ASN1_INTEGER_set(a, 1)) {
505*9badb9adSjsing 		fprintf(stderr, "FAIL: failed to set INTEGER");
506*9badb9adSjsing 		goto failed;
507*9badb9adSjsing 	}
508*9badb9adSjsing 	if (ASN1_INTEGER_cmp(a, b) <= 0) {
509*9badb9adSjsing 		fprintf(stderr, "FAIL: INTEGER 1 > -1");
510*9badb9adSjsing 		goto failed;
511*9badb9adSjsing 	}
512*9badb9adSjsing 	if (ASN1_INTEGER_cmp(b, a) >= 0) {
513*9badb9adSjsing 		fprintf(stderr, "FAIL: INTEGER -1 < 1");
514*9badb9adSjsing 		goto failed;
515*9badb9adSjsing 	}
516*9badb9adSjsing 
517*9badb9adSjsing 	if (!ASN1_INTEGER_set(b, 1)) {
518*9badb9adSjsing 		fprintf(stderr, "FAIL: failed to set INTEGER");
519*9badb9adSjsing 		goto failed;
520*9badb9adSjsing 	}
521*9badb9adSjsing 	if (ASN1_INTEGER_cmp(a, b) != 0) {
522*9badb9adSjsing 		fprintf(stderr, "FAIL: INTEGER 1 == 1");
523*9badb9adSjsing 		goto failed;
524*9badb9adSjsing 	}
525*9badb9adSjsing 
526*9badb9adSjsing 	failed = 0;
527*9badb9adSjsing 
528*9badb9adSjsing  failed:
529*9badb9adSjsing 	ASN1_INTEGER_free(a);
530*9badb9adSjsing 	ASN1_INTEGER_free(b);
531*9badb9adSjsing 
532*9badb9adSjsing 	return failed;
533*9badb9adSjsing }
534*9badb9adSjsing 
535*9badb9adSjsing static int
53651b91989Sjsing asn1_integer_test(void)
53751b91989Sjsing {
53851b91989Sjsing 	struct asn1_integer_test *ait;
53951b91989Sjsing 	int failed = 0;
54051b91989Sjsing 	size_t i;
54151b91989Sjsing 
54251b91989Sjsing 	for (i = 0; i < N_ASN1_INTEGER_TESTS; i++) {
54351b91989Sjsing 		ait = &asn1_integer_tests[i];
54451b91989Sjsing 		if (ait->content_len > 0 && ait->content_len <= 4)
54551b91989Sjsing 			failed |= asn1_integer_set_test(ait);
54651b91989Sjsing 		if (ait->content_len > 0)
54751b91989Sjsing 			failed |= asn1_integer_content_test(ait);
54851b91989Sjsing 		failed |= asn1_integer_decode_test(ait);
54951b91989Sjsing 	}
55051b91989Sjsing 
551*9badb9adSjsing 	failed |= asn1_integer_cmp_test();
552*9badb9adSjsing 
55351b91989Sjsing 	return failed;
55451b91989Sjsing }
55551b91989Sjsing 
556725e2e31Sjsing int
557725e2e31Sjsing main(int argc, char **argv)
558725e2e31Sjsing {
559725e2e31Sjsing 	int failed = 0;
560725e2e31Sjsing 
56130fc8fe5Sjsing 	failed |= asn1_bit_string_test();
562725e2e31Sjsing 	failed |= asn1_boolean_test();
56351b91989Sjsing 	failed |= asn1_integer_test();
564725e2e31Sjsing 
565725e2e31Sjsing 	return (failed);
566725e2e31Sjsing }
567