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