xref: /openbsd-src/regress/lib/libcrypto/asn1/asn1basic.c (revision 45ae274f3da4eedddbe59146c8e01785831fb0b8)
1 /* $OpenBSD: asn1basic.c,v 1.14 2023/08/15 19:14:42 tb Exp $ */
2 /*
3  * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <openssl/asn1.h>
19 #include <openssl/err.h>
20 
21 #include <err.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "asn1_local.h"
26 
27 static void
28 hexdump(const unsigned char *buf, size_t len)
29 {
30 	size_t i;
31 
32 	for (i = 1; i <= len; i++)
33 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
34 
35 	fprintf(stderr, "\n");
36 }
37 
38 static int
39 asn1_compare_bytes(const char *label, const unsigned char *d1, int len1,
40     const unsigned char *d2, int len2)
41 {
42 	if (len1 != len2) {
43 		fprintf(stderr, "FAIL: %s - byte lengths differ "
44 		    "(%d != %d)\n", label, len1, len2);
45 		fprintf(stderr, "Got:\n");
46 		hexdump(d1, len1);
47 		fprintf(stderr, "Want:\n");
48 		hexdump(d2, len2);
49 		return 0;
50 	}
51 	if (memcmp(d1, d2, len1) != 0) {
52 		fprintf(stderr, "FAIL: %s - bytes differ\n", label);
53 		fprintf(stderr, "Got:\n");
54 		hexdump(d1, len1);
55 		fprintf(stderr, "Want:\n");
56 		hexdump(d2, len2);
57 		return 0;
58 	}
59 	return 1;
60 }
61 
62 const uint8_t asn1_bit_string_primitive[] = {
63 	0x03, 0x07,
64 	0x04, 0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0,
65 };
66 
67 static int
68 asn1_bit_string_test(void)
69 {
70 	uint8_t bs[] = {0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0};
71 	ASN1_BIT_STRING *abs;
72 	uint8_t *p = NULL, *pp;
73 	const uint8_t *q;
74 	int bit, i, len;
75 	int failed = 1;
76 
77 	if ((abs = ASN1_BIT_STRING_new()) == NULL) {
78 		fprintf(stderr, "FAIL: ASN1_BIT_STRING_new() == NULL\n");
79 		goto failed;
80 	}
81 	if (!ASN1_BIT_STRING_set(abs, bs, sizeof(bs))) {
82 		fprintf(stderr, "FAIL: failed to set bit string\n");
83 		goto failed;
84 	}
85 
86 	if ((len = i2d_ASN1_BIT_STRING(abs, NULL)) < 0) {
87 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING with NULL\n");
88 		goto failed;
89 	}
90 	if ((p = malloc(len)) == NULL)
91 		errx(1, "malloc");
92 	memset(p, 0xbd, len);
93 	pp = p;
94 	if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) {
95 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
96 		goto failed;
97 	}
98 	if (!asn1_compare_bytes("BIT_STRING", p, len, asn1_bit_string_primitive,
99 	    sizeof(asn1_bit_string_primitive)))
100 		goto failed;
101 	if (pp != p + len) {
102 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING pp = %p, want %p\n",
103 		    pp, p + len);
104 		goto failed;
105 	}
106 
107 	/* Test primitive decoding. */
108 	q = p;
109 	if (d2i_ASN1_BIT_STRING(&abs, &q, len) == NULL) {
110 		fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING primitive\n");
111 		goto failed;
112 	}
113 	if (!asn1_compare_bytes("BIT_STRING primitive data", abs->data, abs->length,
114 	    bs, sizeof(bs)))
115 		goto failed;
116 	if (q != p + len) {
117 		fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING q = %p, want %p\n",
118 		    q, p + len);
119 		goto failed;
120 	}
121 
122 	/* Test ASN1_BIT_STRING_get_bit(). */
123 	for (i = 0; i < ((int)sizeof(bs) * 8); i++) {
124 		bit = (bs[i / 8] >> (7 - i % 8)) & 1;
125 
126 		if (ASN1_BIT_STRING_get_bit(abs, i) != bit) {
127 			fprintf(stderr, "FAIL: ASN1_BIT_STRING_get_bit(_, %d) "
128 			    "= %d, want %d\n", i,
129 			    ASN1_BIT_STRING_get_bit(abs, i), bit);
130 			goto failed;
131 		}
132 	}
133 
134 	/* Test ASN1_BIT_STRING_set_bit(). */
135 	for (i = 0; i < ((int)sizeof(bs) * 8); i++) {
136 		if (!ASN1_BIT_STRING_set_bit(abs, i, 1)) {
137 			fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit 1\n");
138 			goto failed;
139 		}
140 	}
141 	for (i = ((int)sizeof(bs) * 8) - 1; i >= 0; i--) {
142 		bit = (bs[i / 8] >> (7 - i % 8)) & 1;
143 		if (bit == 1)
144 			continue;
145 		if (!ASN1_BIT_STRING_set_bit(abs, i, 0)) {
146 			fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit\n");
147 			goto failed;
148 		}
149 	}
150 
151 	if ((i2d_ASN1_BIT_STRING(abs, NULL)) != len) {
152 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
153 		goto failed;
154 	}
155 
156 	memset(p, 0xbd, len);
157 	pp = p;
158 	if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) {
159 		fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n");
160 		goto failed;
161 	}
162 
163 	if (!asn1_compare_bytes("BIT_STRING set", p, len, asn1_bit_string_primitive,
164 	    sizeof(asn1_bit_string_primitive)))
165 		goto failed;
166 
167 	failed = 0;
168 
169  failed:
170 	ASN1_BIT_STRING_free(abs);
171 	free(p);
172 
173 	return failed;
174 }
175 
176 const uint8_t asn1_boolean_false[] = {
177 	0x01, 0x01, 0x00,
178 };
179 const uint8_t asn1_boolean_true[] = {
180 	0x01, 0x01, 0x01,
181 };
182 
183 static int
184 asn1_boolean_test(void)
185 {
186 	uint8_t *p = NULL, *pp;
187 	const uint8_t *q;
188 	int len;
189 	int failed = 1;
190 
191 	if ((len = i2d_ASN1_BOOLEAN(0, NULL)) < 0) {
192 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false with NULL\n");
193 		goto failed;
194 	}
195 	if ((p = malloc(len)) == NULL)
196 		errx(1, "calloc");
197 	memset(p, 0xbd, len);
198 	pp = p;
199 	if ((i2d_ASN1_BOOLEAN(0, &pp)) != len) {
200 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false\n");
201 		goto failed;
202 	}
203 	if (pp != p + len) {
204 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n",
205 		    pp, p + len);
206 		goto failed;
207 	}
208 
209 	if (!asn1_compare_bytes("BOOLEAN false", p, len, asn1_boolean_false,
210 	    sizeof(asn1_boolean_false)))
211 		goto failed;
212 
213 	q = p;
214 	if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 0) {
215 		fprintf(stderr, "FAIL: BOOLEAN false did not decode to 0\n");
216 		goto failed;
217 	}
218 	if (q != p + len) {
219 		fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n",
220 		    q, p + len);
221 		goto failed;
222 	}
223 
224 	free(p);
225 	p = NULL;
226 
227 	if ((len = i2d_ASN1_BOOLEAN(1, NULL)) < 0) {
228 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true with NULL\n");
229 		goto failed;
230 	}
231 	if ((p = calloc(1, len)) == NULL)
232 		errx(1, "calloc");
233 	pp = p;
234 	if ((i2d_ASN1_BOOLEAN(1, &pp)) != len) {
235 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true\n");
236 		goto failed;
237 	}
238 	if (pp != p + len) {
239 		fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n",
240 		    pp, p + len);
241 		goto failed;
242 	}
243 
244 	if (!asn1_compare_bytes("BOOLEAN true", p, len, asn1_boolean_true,
245 	    sizeof(asn1_boolean_true)))
246 		goto failed;
247 
248 	q = p;
249 	if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 1) {
250 		fprintf(stderr, "FAIL: BOOLEAN true did not decode to 1\n");
251 		goto failed;
252 	}
253 	if (q != p + len) {
254 		fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n",
255 		    q, p + len);
256 		goto failed;
257 	}
258 
259 	failed = 0;
260 
261  failed:
262 	free(p);
263 
264 	return failed;
265 }
266 
267 struct asn1_integer_test {
268 	long value;
269 	uint8_t content[64];
270 	size_t content_len;
271 	int content_neg;
272 	uint8_t der[64];
273 	size_t der_len;
274 	int want_error;
275 };
276 
277 struct asn1_integer_test asn1_integer_tests[] = {
278 	{
279 		.value = 0,
280 		.content = {0x00},
281 		.content_len = 1,
282 		.der = {0x02, 0x01, 0x00},
283 		.der_len = 3,
284 	},
285 	{
286 		.value = 1,
287 		.content = {0x01},
288 		.content_len = 1,
289 		.der = {0x02, 0x01, 0x01},
290 		.der_len = 3,
291 	},
292 	{
293 		.value = -1,
294 		.content = {0x01},
295 		.content_len = 1,
296 		.content_neg = 1,
297 		.der = {0x02, 0x01, 0xff},
298 		.der_len = 3,
299 	},
300 	{
301 		.value = 127,
302 		.content = {0x7f},
303 		.content_len = 1,
304 		.der = {0x02, 0x01, 0x7f},
305 		.der_len = 3,
306 	},
307 	{
308 		.value = -127,
309 		.content = {0x7f},
310 		.content_len = 1,
311 		.content_neg = 1,
312 		.der = {0x02, 0x01, 0x81},
313 		.der_len = 3,
314 	},
315 	{
316 		.value = 128,
317 		.content = {0x80},
318 		.content_len = 1,
319 		.der = {0x02, 0x02, 0x00, 0x80},
320 		.der_len = 4,
321 	},
322 	{
323 		.value = -128,
324 		.content = {0x80},
325 		.content_len = 1,
326 		.content_neg = 1,
327 		.der = {0x02, 0x01, 0x80},
328 		.der_len = 3,
329 	},
330 	{
331 		/* 2^64 */
332 		.content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
333 		.content_len = 9,
334 		.der = {0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
335 		.der_len = 11,
336 	},
337 	{
338 		/* -2^64 */
339 		.content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
340 		.content_len = 9,
341 		.content_neg = 1,
342 		.der = {0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
343 		.der_len = 11,
344 	},
345 	{
346 		/* Invalid length. */
347 		.der = {0x02, 0x00},
348 		.der_len = 2,
349 		.want_error = 1,
350 	},
351 	{
352 		/* Invalid padding. */
353 		.der = {0x02, 0x09, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
354 		.der_len = 11,
355 		.want_error = 1,
356 	},
357 	{
358 		/* Invalid padding. */
359 		.der = {0x02, 0x09, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
360 		.der_len = 11,
361 		.want_error = 1,
362 	},
363 	{
364 		/* Invalid encoding (constructed with definite length). */
365 		.der = {0x22, 0x03, 0x02, 0x01, 0x01},
366 		.der_len = 5,
367 		.want_error = 1,
368 	},
369 	{
370 		/* Invalid encoding (constructed with indefinite length). */
371 		.der = {0x22, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00},
372 		.der_len = 7,
373 		.want_error = 1,
374 	},
375 };
376 
377 #define N_ASN1_INTEGER_TESTS \
378     (sizeof(asn1_integer_tests) / sizeof(*asn1_integer_tests))
379 
380 static int
381 asn1_integer_set_test(struct asn1_integer_test *ait)
382 {
383 	ASN1_INTEGER *aint = NULL;
384 	uint8_t *p = NULL, *pp;
385 	int len;
386 	int failed = 1;
387 
388 	if ((aint = ASN1_INTEGER_new()) == NULL) {
389 		fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
390 		goto failed;
391 	}
392 	if (!ASN1_INTEGER_set(aint, ait->value)) {
393 		fprintf(stderr, "FAIL: ASN1_INTEGER_(%ld) failed\n",
394 		    ait->value);
395 		goto failed;
396 	}
397 	if (ait->value != 0 &&
398 	    !asn1_compare_bytes("INTEGER set", aint->data, aint->length,
399 	    ait->content, ait->content_len))
400 		goto failed;
401 	if (ait->content_neg && aint->type != V_ASN1_NEG_INTEGER) {
402 		fprintf(stderr, "FAIL: Not V_ASN1_NEG_INTEGER\n");
403 		goto failed;
404 	}
405 	if (ASN1_INTEGER_get(aint) != ait->value) {
406 		fprintf(stderr, "FAIL: ASN1_INTEGER_get() = %ld, want %ld\n",
407 		    ASN1_INTEGER_get(aint), ait->value);
408 		goto failed;
409 	}
410 	if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
411 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
412 		goto failed;
413 	}
414 	if ((p = malloc(len)) == NULL)
415 		errx(1, "malloc");
416 	memset(p, 0xbd, len);
417 	pp = p;
418 	if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
419 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
420 		goto failed;
421 	}
422 	if (!asn1_compare_bytes("INTEGER set", p, len, ait->der,
423 	    ait->der_len))
424 		goto failed;
425 
426 	failed = 0;
427 
428  failed:
429 	ASN1_INTEGER_free(aint);
430 	free(p);
431 
432 	return failed;
433 }
434 
435 static int
436 asn1_integer_content_test(struct asn1_integer_test *ait)
437 {
438 	ASN1_INTEGER *aint = NULL;
439 	uint8_t *p = NULL, *pp;
440 	int len;
441 	int failed = 1;
442 
443 	if ((aint = ASN1_INTEGER_new()) == NULL) {
444 		fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
445 		goto failed;
446 	}
447 	if ((aint->data = malloc(ait->content_len)) == NULL)
448 		errx(1, "malloc");
449 	memcpy(aint->data, ait->content, ait->content_len);
450 	aint->length = ait->content_len;
451 	if (ait->content_neg)
452 		aint->type = V_ASN1_NEG_INTEGER;
453 
454 	if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
455 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
456 		goto failed;
457 	}
458 	if ((p = malloc(len)) == NULL)
459 		errx(1, "malloc");
460 	memset(p, 0xbd, len);
461 	pp = p;
462 	if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
463 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
464 		goto failed;
465 	}
466 	if (!asn1_compare_bytes("INTEGER content", p, len, ait->der,
467 	    ait->der_len))
468 		goto failed;
469 	if (pp != p + len) {
470 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER pp = %p, want %p\n",
471 		    pp, p + len);
472 		goto failed;
473 	}
474 
475 	failed = 0;
476 
477  failed:
478 	ASN1_INTEGER_free(aint);
479 	free(p);
480 
481 	return failed;
482 }
483 
484 static int
485 asn1_integer_decode_test(struct asn1_integer_test *ait)
486 {
487 	ASN1_INTEGER *aint = NULL;
488 	const uint8_t *q;
489 	int failed = 1;
490 
491 	q = ait->der;
492 	if (d2i_ASN1_INTEGER(&aint, &q, ait->der_len) != NULL) {
493 		if (ait->want_error != 0) {
494 			fprintf(stderr, "FAIL: INTEGER decoded when it should "
495 			    "have failed\n");
496 			goto failed;
497 		}
498 		if (!asn1_compare_bytes("INTEGER content", aint->data,
499 		    aint->length, ait->content, ait->content_len))
500 			goto failed;
501 		if (q != ait->der + ait->der_len) {
502 			fprintf(stderr, "FAIL: d2i_ASN1_INTEGER q = %p, want %p\n",
503 			    q, ait->der + ait->der_len);
504 			goto failed;
505 		}
506 	} else if (ait->want_error == 0) {
507 		fprintf(stderr, "FAIL: INTEGER failed to decode\n");
508 		ERR_print_errors_fp(stderr);
509 		goto failed;
510 	}
511 
512 	failed = 0;
513 
514  failed:
515 	ASN1_INTEGER_free(aint);
516 
517 	return failed;
518 }
519 
520 static int
521 asn1_integer_set_val_test(void)
522 {
523 	ASN1_INTEGER *aint = NULL;
524 	uint64_t uval;
525 	int64_t val;
526 	int failed = 1;
527 
528 	if ((aint = ASN1_INTEGER_new()) == NULL) {
529 		fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
530 		goto failed;
531 	}
532 
533 	if (!ASN1_INTEGER_set_uint64(aint, 0)) {
534 		fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with "
535 		    "0\n");
536 		goto failed;
537 	}
538 	if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
539 		fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
540 		    "0\n");
541 		goto failed;
542 	}
543 	if (uval != 0) {
544 		fprintf(stderr, "FAIL: uval != 0\n");
545 		goto failed;
546 	}
547 
548 	if (!ASN1_INTEGER_set_uint64(aint, UINT64_MAX)) {
549 		fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with "
550 		    "UINT64_MAX\n");
551 		goto failed;
552 	}
553 	if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
554 		fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
555 		    "UINT64_MAX\n");
556 		goto failed;
557 	}
558 	if (uval != UINT64_MAX) {
559 		fprintf(stderr, "FAIL: uval != UINT64_MAX\n");
560 		goto failed;
561 	}
562 	if (ASN1_INTEGER_get_int64(&val, aint)) {
563 		fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() succeeded "
564 		    "with UINT64_MAX\n");
565 		goto failed;
566 	}
567 
568 	if (!ASN1_INTEGER_set_int64(aint, INT64_MIN)) {
569 		fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with "
570 		    "INT64_MIN\n");
571 		goto failed;
572 	}
573 	if (!ASN1_INTEGER_get_int64(&val, aint)) {
574 		fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
575 		    "INT64_MIN\n");
576 		goto failed;
577 	}
578 	if (val != INT64_MIN) {
579 		fprintf(stderr, "FAIL: val != INT64_MIN\n");
580 		goto failed;
581 	}
582 	if (ASN1_INTEGER_get_uint64(&uval, aint)) {
583 		fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() succeeded "
584 		    "with INT64_MIN\n");
585 		goto failed;
586 	}
587 
588 	if (!ASN1_INTEGER_set_int64(aint, INT64_MAX)) {
589 		fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with "
590 		    "INT64_MAX\n");
591 		goto failed;
592 	}
593 	if (!ASN1_INTEGER_get_int64(&val, aint)) {
594 		fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
595 		    "INT64_MAX\n");
596 		goto failed;
597 	}
598 	if (val != INT64_MAX) {
599 		fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with "
600 		    "INT64_MAX\n");
601 		goto failed;
602 	}
603 	if (!ASN1_INTEGER_get_uint64(&uval, aint)) {
604 		fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with "
605 		    "INT64_MAX\n");
606 		goto failed;
607 	}
608 	if (uval != INT64_MAX) {
609 		fprintf(stderr, "FAIL: uval != INT64_MAX\n");
610 		goto failed;
611 	}
612 
613 	failed = 0;
614 
615  failed:
616 	ASN1_INTEGER_free(aint);
617 
618 	return failed;
619 }
620 
621 static int
622 asn1_integer_cmp_test(void)
623 {
624 	ASN1_INTEGER *a = NULL, *b = NULL;
625 	int failed = 1;
626 
627 	if ((a = ASN1_INTEGER_new()) == NULL)
628 		goto failed;
629 	if ((b = ASN1_INTEGER_new()) == NULL)
630 		goto failed;
631 
632 	if (ASN1_INTEGER_cmp(a, b) != 0) {
633 		fprintf(stderr, "FAIL: INTEGER 0 == 0");
634 		goto failed;
635 	}
636 
637 	if (!ASN1_INTEGER_set(b, 1)) {
638 		fprintf(stderr, "FAIL: failed to set INTEGER");
639 		goto failed;
640 	}
641 	if (ASN1_INTEGER_cmp(a, b) >= 0) {
642 		fprintf(stderr, "FAIL: INTEGER 0 < 1");
643 		goto failed;
644 	}
645 	if (ASN1_INTEGER_cmp(b, a) <= 0) {
646 		fprintf(stderr, "FAIL: INTEGER 1 > 0");
647 		goto failed;
648 	}
649 
650 	if (!ASN1_INTEGER_set(b, -1)) {
651 		fprintf(stderr, "FAIL: failed to set INTEGER");
652 		goto failed;
653 	}
654 	if (ASN1_INTEGER_cmp(a, b) <= 0) {
655 		fprintf(stderr, "FAIL: INTEGER 0 > -1");
656 		goto failed;
657 	}
658 	if (ASN1_INTEGER_cmp(b, a) >= 0) {
659 		fprintf(stderr, "FAIL: INTEGER -1 < 0");
660 		goto failed;
661 	}
662 
663 	if (!ASN1_INTEGER_set(a, 1)) {
664 		fprintf(stderr, "FAIL: failed to set INTEGER");
665 		goto failed;
666 	}
667 	if (ASN1_INTEGER_cmp(a, b) <= 0) {
668 		fprintf(stderr, "FAIL: INTEGER 1 > -1");
669 		goto failed;
670 	}
671 	if (ASN1_INTEGER_cmp(b, a) >= 0) {
672 		fprintf(stderr, "FAIL: INTEGER -1 < 1");
673 		goto failed;
674 	}
675 
676 	if (!ASN1_INTEGER_set(b, 1)) {
677 		fprintf(stderr, "FAIL: failed to set INTEGER");
678 		goto failed;
679 	}
680 	if (ASN1_INTEGER_cmp(a, b) != 0) {
681 		fprintf(stderr, "FAIL: INTEGER 1 == 1");
682 		goto failed;
683 	}
684 
685 	failed = 0;
686 
687  failed:
688 	ASN1_INTEGER_free(a);
689 	ASN1_INTEGER_free(b);
690 
691 	return failed;
692 }
693 
694 static int
695 asn1_integer_null_data_test(void)
696 {
697 	const uint8_t der[] = {0x02, 0x01, 0x00};
698 	ASN1_INTEGER *aint = NULL;
699 	uint8_t *p = NULL, *pp;
700 	int len;
701 	int failed = 0;
702 
703 	if ((aint = ASN1_INTEGER_new()) == NULL) {
704 		fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n");
705 		goto failed;
706 	}
707 	if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) {
708 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
709 		goto failed;
710 	}
711 	if ((p = calloc(1, len)) == NULL)
712 		errx(1, "calloc");
713 	pp = p;
714 	if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) {
715 		fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n");
716 		goto failed;
717 	}
718 	if (!asn1_compare_bytes("INTEGER NULL data", p, len, der, sizeof(der)))
719 		goto failed;
720 
721 	failed = 0;
722 
723  failed:
724 	ASN1_INTEGER_free(aint);
725 	free(p);
726 
727 	return failed;
728 }
729 
730 static int
731 asn1_integer_test(void)
732 {
733 	struct asn1_integer_test *ait;
734 	int failed = 0;
735 	size_t i;
736 
737 	for (i = 0; i < N_ASN1_INTEGER_TESTS; i++) {
738 		ait = &asn1_integer_tests[i];
739 		if (ait->content_len > 0 && ait->content_len <= 4)
740 			failed |= asn1_integer_set_test(ait);
741 		if (ait->content_len > 0)
742 			failed |= asn1_integer_content_test(ait);
743 		failed |= asn1_integer_decode_test(ait);
744 	}
745 
746 	failed |= asn1_integer_cmp_test();
747 	failed |= asn1_integer_null_data_test();
748 	failed |= asn1_integer_set_val_test();
749 
750 	return failed;
751 }
752 
753 static const struct asn1_string_new_test {
754 	const char *name;
755 	ASN1_STRING *(*new)(void);
756 	void (*free)(ASN1_STRING *);
757 	int type;
758 	long flags;
759 } asn1_string_new_tests[] = {
760 	{
761 		.name = "ASN1_STRING",
762 		.new = ASN1_STRING_new,
763 		.free = ASN1_STRING_free,
764 		.type = V_ASN1_OCTET_STRING,
765 	},
766 	{
767 		.name = "ASN1_OCTET_STRING",
768 		.new = ASN1_OCTET_STRING_new,
769 		.free = ASN1_OCTET_STRING_free,
770 		.type = V_ASN1_OCTET_STRING,
771 	},
772 	{
773 		.name = "ASN1_BIT_STRING",
774 		.new = ASN1_BIT_STRING_new,
775 		.free = ASN1_BIT_STRING_free,
776 		.type = V_ASN1_BIT_STRING,
777 	},
778 	{
779 		.name = "ASN1_INTEGER",
780 		.new = ASN1_INTEGER_new,
781 		.free = ASN1_INTEGER_free,
782 		.type = V_ASN1_INTEGER,
783 	},
784 	{
785 		.name = "ASN1_ENUMERATED",
786 		.new = ASN1_ENUMERATED_new,
787 		.free = ASN1_ENUMERATED_free,
788 		.type = V_ASN1_ENUMERATED,
789 	},
790 	{
791 		.name = "ASN1_UTF8STRING",
792 		.new = ASN1_UTF8STRING_new,
793 		.free = ASN1_UTF8STRING_free,
794 		.type = V_ASN1_UTF8STRING,
795 	},
796 	{
797 		.name = "ASN1_IA5STRING",
798 		.new = ASN1_IA5STRING_new,
799 		.free = ASN1_IA5STRING_free,
800 		.type = V_ASN1_IA5STRING,
801 	},
802 	{
803 		.name = "ASN1_UNIVERSALSTRING",
804 		.new = ASN1_UNIVERSALSTRING_new,
805 		.free = ASN1_UNIVERSALSTRING_free,
806 		.type = V_ASN1_UNIVERSALSTRING,
807 	},
808 	{
809 		.name = "ASN1_BMPSTRING",
810 		.new = ASN1_BMPSTRING_new,
811 		.free = ASN1_BMPSTRING_free,
812 		.type = V_ASN1_BMPSTRING,
813 	},
814 	{
815 		.name = "ASN1_GENERALSTRING",
816 		.new = ASN1_GENERALSTRING_new,
817 		.free = ASN1_GENERALSTRING_free,
818 		.type = V_ASN1_GENERALSTRING,
819 	},
820 	{
821 		.name = "ASN1_T61STRING",
822 		.new = ASN1_T61STRING_new,
823 		.free = ASN1_T61STRING_free,
824 		.type = V_ASN1_T61STRING,
825 	},
826 	{
827 		.name = "ASN1_VISIBLESTRING",
828 		.new = ASN1_VISIBLESTRING_new,
829 		.free = ASN1_VISIBLESTRING_free,
830 		.type = V_ASN1_VISIBLESTRING,
831 	},
832 	{
833 		.name = "ASN1_PRINTABLESTRING",
834 		.new = ASN1_PRINTABLESTRING_new,
835 		.free = ASN1_PRINTABLESTRING_free,
836 		.type = V_ASN1_PRINTABLESTRING,
837 	},
838 	{
839 		.name = "ASN1_PRINTABLE",
840 		.new = ASN1_PRINTABLE_new,
841 		.free = ASN1_PRINTABLE_free,
842 		.type = V_ASN1_UNDEF,
843 		.flags = ASN1_STRING_FLAG_MSTRING,
844 	},
845 	{
846 		.name = "DIRECTORYSTRING",
847 		.new = DIRECTORYSTRING_new,
848 		.free = DIRECTORYSTRING_free,
849 		.type = V_ASN1_UNDEF,
850 		.flags = ASN1_STRING_FLAG_MSTRING,
851 	},
852 	{
853 		.name = "DISPLAYTEXT",
854 		.new = DISPLAYTEXT_new,
855 		.free = DISPLAYTEXT_free,
856 		.type = V_ASN1_UNDEF,
857 		.flags = ASN1_STRING_FLAG_MSTRING,
858 	},
859 	{
860 		.name = "ASN1_GENERALIZEDTIME",
861 		.new = ASN1_GENERALIZEDTIME_new,
862 		.free = ASN1_GENERALIZEDTIME_free,
863 		.type = V_ASN1_GENERALIZEDTIME,
864 	},
865 	{
866 		.name = "ASN1_UTCTIME",
867 		.new = ASN1_UTCTIME_new,
868 		.free = ASN1_UTCTIME_free,
869 		.type = V_ASN1_UTCTIME,
870 	},
871 	{
872 		.name = "ASN1_TIME",
873 		.new = ASN1_TIME_new,
874 		.free = ASN1_TIME_free,
875 		.type = V_ASN1_UNDEF,
876 		.flags = ASN1_STRING_FLAG_MSTRING,
877 	},
878 };
879 
880 #define N_ASN1_STRING_NEW_TESTS \
881     (sizeof(asn1_string_new_tests) / sizeof(asn1_string_new_tests[0]))
882 
883 static int
884 asn1_string_new_test(void)
885 {
886 	size_t i;
887 	ASN1_STRING *astr = NULL;
888 	int failed = 1;
889 
890 	for (i = 0; i < N_ASN1_STRING_NEW_TESTS; i++) {
891 		const struct asn1_string_new_test *asnt = &asn1_string_new_tests[i];
892 
893 		if ((astr = asnt->new()) == NULL) {
894 			fprintf(stderr, "%s_new() failed\n", asnt->name);
895 			goto err;
896 		}
897 		if (ASN1_STRING_type(astr) != asnt->type) {
898 			fprintf(stderr, "%s type: want %d, got %d\n",
899 			    asnt->name, asnt->type, ASN1_STRING_type(astr));
900 			goto err;
901 		}
902 		if (ASN1_STRING_data(astr) != NULL) {
903 			fprintf(stderr, "%s data != NULL\n", asnt->name);
904 			goto err;
905 		}
906 		if (ASN1_STRING_get0_data(astr) != NULL) {
907 			fprintf(stderr, "%s data != NULL\n", asnt->name);
908 			goto err;
909 		}
910 		if (ASN1_STRING_length(astr) != 0) {
911 			fprintf(stderr, "%s length %d != 0\n", asnt->name,
912 			    ASN1_STRING_length(astr));
913 			goto err;
914 		}
915 		ASN1_STRING_length_set(astr, 20);
916 		if (ASN1_STRING_length(astr) != 20) {
917 			fprintf(stderr, "%s length %d != 20\n", asnt->name,
918 			    ASN1_STRING_length(astr));
919 			goto err;
920 		}
921 		astr->flags |= ASN1_STRING_FLAG_NDEF;
922 		if (astr->flags != (asnt->flags | ASN1_STRING_FLAG_NDEF)) {
923 			fprintf(stderr, "%s flags: %lx\n", asnt->name,
924 			    astr->flags);
925 			goto err;
926 		}
927 		/* ASN1_STRING_set0() clears ASN1_STRING_FLAG_NDEF. */
928 		ASN1_STRING_set0(astr, NULL, 0);
929 		if (astr->flags != asnt->flags) {
930 			fprintf(stderr, "%s flags: %lx != %lx\n", asnt->name,
931 			    astr->flags, asnt->flags);
932 			goto err;
933 		}
934 		asnt->free(astr);
935 		astr = NULL;
936 
937 		if ((astr = ASN1_STRING_type_new(asnt->type)) == NULL) {
938 			fprintf(stderr, "ASN1_STRING_type_new(%s) failed\n",
939 			    asnt->name);
940 			goto err;
941 		}
942 		if (ASN1_STRING_type(astr) != asnt->type) {
943 			fprintf(stderr, "%s type: want %d, got %d\n",
944 			    asnt->name, asnt->type, ASN1_STRING_type(astr));
945 			goto err;
946 		}
947 		if (ASN1_STRING_data(astr) != NULL) {
948 			fprintf(stderr, "%s data != NULL\n", asnt->name);
949 			goto err;
950 		}
951 		/* ASN1_STRING_type_new() does not set flags. */
952 		if (astr->flags != 0) {
953 			fprintf(stderr, "%s flags %lx\n", asnt->name,
954 			    astr->flags);
955 			goto err;
956 		}
957 		asnt->free(astr);
958 		astr = NULL;
959 
960 	}
961 
962 	failed = 0;
963 
964  err:
965 	ASN1_STRING_free(astr);
966 
967 	return failed;
968 }
969 
970 static int
971 asn1_string_test(void)
972 {
973 	int failed = 0;
974 
975 	failed |= asn1_string_new_test();
976 
977 	return failed;
978 }
979 
980 int
981 main(int argc, char **argv)
982 {
983 	int failed = 0;
984 
985 	failed |= asn1_bit_string_test();
986 	failed |= asn1_boolean_test();
987 	failed |= asn1_integer_test();
988 	failed |= asn1_string_test();
989 
990 	return (failed);
991 }
992