xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/asn1/check-der.c (revision afab4e300d3a9fb07dd8c80daf53d0feb3345706)
1 /*	$NetBSD: check-der.c,v 1.3 2023/06/19 21:41:42 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1999 - 2007 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  *
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * 3. Neither the name of the Institute nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 #include "der_locl.h"
39 #include <err.h>
40 #include <krb5/roken.h>
41 
42 #include <krb5/asn1-common.h>
43 #include <krb5/asn1_err.h>
44 #include <krb5/der.h>
45 
46 #include "check-common.h"
47 
48 __RCSID("$NetBSD: check-der.c,v 1.3 2023/06/19 21:41:42 christos Exp $");
49 
50 static int
cmp_integer(void * a,void * b)51 cmp_integer (void *a, void *b)
52 {
53     int *ia = (int *)a;
54     int *ib = (int *)b;
55 
56     return *ib - *ia;
57 }
58 
59 static int
test_integer(void)60 test_integer (void)
61 {
62     struct test_case tests[] = {
63 	{NULL, 1, "\x00", 		NULL },
64 	{NULL, 1, "\x7f", 		NULL },
65 	{NULL, 2, "\x00\x80", 		NULL },
66 	{NULL, 2, "\x01\x00", 		NULL },
67 	{NULL, 1, "\x80", 		NULL },
68 	{NULL, 2, "\xff\x7f", 		NULL },
69 	{NULL, 1, "\xff", 		NULL },
70 	{NULL, 2, "\xff\x01", 		NULL },
71 	{NULL, 2, "\x00\xff", 		NULL },
72 	{NULL, 2, "\xfe\x01", 		NULL },
73 	{NULL, 4, "\x7f\xff\xff\xff", 	NULL }
74     };
75 
76     int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255,
77 		    -511, 0x7fffffff};
78     int i, ret;
79     int ntests = sizeof(tests) / sizeof(*tests);
80 
81     for (i = 0; i < ntests; ++i) {
82 	tests[i].val = &values[i];
83 	if (asprintf (&tests[i].name, "integer %d", values[i]) < 0)
84 	    errx(1, "malloc");
85 	if (tests[i].name == NULL)
86 	    errx(1, "malloc");
87     }
88 
89     ret = generic_test (tests, ntests, sizeof(int),
90 			(generic_encode)der_put_integer,
91 			(generic_length) der_length_integer,
92 			(generic_decode)der_get_integer,
93 			(generic_free)NULL,
94 			cmp_integer,
95 			NULL);
96 
97     for (i = 0; i < ntests; ++i)
98 	free (tests[i].name);
99     return ret;
100 }
101 
102 static int
test_one_int(int val)103 test_one_int(int val)
104 {
105     int ret, dval;
106     unsigned char *buf;
107     size_t len_len, len;
108 
109     len = _heim_len_int(val);
110 
111     buf = emalloc(len + 2);
112 
113     buf[0] = '\xff';
114     buf[len + 1] = '\xff';
115     memset(buf + 1, 0, len);
116 
117     ret = der_put_integer(buf + 1 + len - 1, len, &val, &len_len);
118     if (ret) {
119 	printf("integer %d encode failed %d\n", val, ret);
120 	return 1;
121     }
122     if (len != len_len) {
123 	printf("integer %d encode fail with %d len %lu, result len %lu\n",
124 	       val, ret, (unsigned long)len, (unsigned long)len_len);
125 	return 1;
126     }
127 
128     ret = der_get_integer(buf + 1, len, &dval, &len_len);
129     if (ret) {
130 	printf("integer %d decode failed %d\n", val, ret);
131 	return 1;
132     }
133     if (len != len_len) {
134 	printf("integer %d decoded diffrent len %lu != %lu",
135 	       val, (unsigned long)len, (unsigned long)len_len);
136 	return 1;
137     }
138     if (val != dval) {
139 	printf("decode decoded to diffrent value %d != %d",
140 	       val, dval);
141 	return 1;
142     }
143 
144     if (buf[0] != (unsigned char)'\xff') {
145 	printf("precanary dead %d\n", val);
146 	return 1;
147     }
148     if (buf[len + 1] != (unsigned char)'\xff') {
149 	printf("postecanary dead %d\n", val);
150 	return 1;
151     }
152     free(buf);
153     return 0;
154 }
155 
156 static int
test_integer_more(void)157 test_integer_more (void)
158 {
159     int64_t i, n1, n2, n3, n4, n5, n6;
160 
161     n2 = 0;
162     for (i = 0; i < (sizeof(int) * 8); i++) {
163 	n1 = 0x01LL << i;
164 	n2 = n2 | n1;
165 	n3 = ~n1;
166 	n4 = ~n2;
167 	n5 = (-1LL) & ~(0x3fLL << i);
168 	n6 = (-1LL) & ~(0x7fLL << i);
169 
170 	test_one_int(n1);
171 	test_one_int(n2);
172 	test_one_int(n3);
173 	test_one_int(n4);
174 	test_one_int(n5);
175 	test_one_int(n6);
176     }
177     return 0;
178 }
179 
180 static int
cmp_unsigned(void * a,void * b)181 cmp_unsigned (void *a, void *b)
182 {
183     return *(unsigned int*)b - *(unsigned int*)a;
184 }
185 
186 static int
test_unsigned(void)187 test_unsigned (void)
188 {
189     struct test_case tests[] = {
190 	{NULL, 1, "\x00", 			NULL },
191 	{NULL, 1, "\x7f", 			NULL },
192 	{NULL, 2, "\x00\x80", 			NULL },
193 	{NULL, 2, "\x01\x00", 			NULL },
194 	{NULL, 2, "\x02\x00", 			NULL },
195 	{NULL, 3, "\x00\x80\x00", 		NULL },
196 	{NULL, 5, "\x00\x80\x00\x00\x00",	NULL },
197 	{NULL, 4, "\x7f\xff\xff\xff", 		NULL }
198     };
199 
200     unsigned int values[] = {0, 127, 128, 256, 512, 32768,
201 			     0x80000000, 0x7fffffff};
202     int i, ret;
203     int ntests = sizeof(tests) / sizeof(*tests);
204 
205     for (i = 0; i < ntests; ++i) {
206 	tests[i].val = &values[i];
207 	if (asprintf (&tests[i].name, "unsigned %u", values[i]) < 0)
208 	    errx(1, "malloc");
209 	if (tests[i].name == NULL)
210 	    errx(1, "malloc");
211     }
212 
213     ret = generic_test (tests, ntests, sizeof(int),
214 			(generic_encode)der_put_unsigned,
215 			(generic_length)der_length_unsigned,
216 			(generic_decode)der_get_unsigned,
217 			(generic_free)NULL,
218 			cmp_unsigned,
219 			NULL);
220     for (i = 0; i < ntests; ++i)
221 	free (tests[i].name);
222     return ret;
223 }
224 
225 static int
cmp_octet_string(void * a,void * b)226 cmp_octet_string (void *a, void *b)
227 {
228     return der_heim_octet_string_cmp(a, b);
229 }
230 
231 static int
test_octet_string(void)232 test_octet_string (void)
233 {
234     heim_octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"};
235 
236     struct test_case tests[] = {
237 	{NULL, 8, "\x01\x23\x45\x67\x89\xab\xcd\xef", NULL }
238     };
239     int ntests = sizeof(tests) / sizeof(*tests);
240     int ret;
241 
242     tests[0].val = &s1;
243     if (asprintf (&tests[0].name, "a octet string") < 0)
244 	errx(1, "malloc");
245     if (tests[0].name == NULL)
246 	errx(1, "malloc");
247 
248     ret = generic_test (tests, ntests, sizeof(heim_octet_string),
249 			(generic_encode)der_put_octet_string,
250 			(generic_length)der_length_octet_string,
251 			(generic_decode)der_get_octet_string,
252 			(generic_free)der_free_octet_string,
253 			cmp_octet_string,
254 			NULL);
255     free(tests[0].name);
256     return ret;
257 }
258 
259 static int
cmp_bmp_string(void * a,void * b)260 cmp_bmp_string (void *a, void *b)
261 {
262     heim_bmp_string *oa = (heim_bmp_string *)a;
263     heim_bmp_string *ob = (heim_bmp_string *)b;
264 
265     return der_heim_bmp_string_cmp(oa, ob);
266 }
267 
268 static uint16_t bmp_d1[] = { 32 };
269 static uint16_t bmp_d2[] = { 32, 32 };
270 
271 static int
test_bmp_string(void)272 test_bmp_string (void)
273 {
274     heim_bmp_string s1 = { 1, bmp_d1 };
275     heim_bmp_string s2 = { 2, bmp_d2 };
276 
277     struct test_case tests[] = {
278 	{NULL, 2, "\x00\x20", 		NULL },
279 	{NULL, 4, "\x00\x20\x00\x20", 	NULL }
280     };
281     int ntests = sizeof(tests) / sizeof(*tests);
282     int ret;
283 
284     tests[0].val = &s1;
285     if (asprintf (&tests[0].name, "a bmp string") < 0)
286 	errx(1, "malloc");
287     if (tests[0].name == NULL)
288 	errx(1, "malloc");
289     tests[1].val = &s2;
290     if (asprintf (&tests[1].name, "second bmp string") < 0)
291 	errx(1, "malloc");
292     if (tests[1].name == NULL)
293 	errx(1, "malloc");
294 
295     ret = generic_test (tests, ntests, sizeof(heim_bmp_string),
296 			(generic_encode)der_put_bmp_string,
297 			(generic_length)der_length_bmp_string,
298 			(generic_decode)der_get_bmp_string,
299 			(generic_free)der_free_bmp_string,
300 			cmp_bmp_string,
301 			NULL);
302     free(tests[0].name);
303     free(tests[1].name);
304     return ret;
305 }
306 
307 static int
cmp_universal_string(void * a,void * b)308 cmp_universal_string (void *a, void *b)
309 {
310     heim_universal_string *oa = (heim_universal_string *)a;
311     heim_universal_string *ob = (heim_universal_string *)b;
312 
313     return der_heim_universal_string_cmp(oa, ob);
314 }
315 
316 static uint32_t universal_d1[] = { 32 };
317 static uint32_t universal_d2[] = { 32, 32 };
318 
319 static int
test_universal_string(void)320 test_universal_string (void)
321 {
322     heim_universal_string s1 = { 1, universal_d1 };
323     heim_universal_string s2 = { 2, universal_d2 };
324 
325     struct test_case tests[] = {
326 	{NULL, 4, "\x00\x00\x00\x20", 			NULL },
327 	{NULL, 8, "\x00\x00\x00\x20\x00\x00\x00\x20", 	NULL }
328     };
329     int ntests = sizeof(tests) / sizeof(*tests);
330     int ret;
331 
332     tests[0].val = &s1;
333     if (asprintf (&tests[0].name, "a universal string") < 0)
334 	errx(1, "malloc");
335     if (tests[0].name == NULL)
336 	errx(1, "malloc");
337     tests[1].val = &s2;
338     if (asprintf (&tests[1].name, "second universal string") < 0)
339 	errx(1, "malloc");
340     if (tests[1].name == NULL)
341 	errx(1, "malloc");
342 
343     ret = generic_test (tests, ntests, sizeof(heim_universal_string),
344 			(generic_encode)der_put_universal_string,
345 			(generic_length)der_length_universal_string,
346 			(generic_decode)der_get_universal_string,
347 			(generic_free)der_free_universal_string,
348 			cmp_universal_string,
349 			NULL);
350     free(tests[0].name);
351     free(tests[1].name);
352     return ret;
353 }
354 
355 static int
cmp_general_string(void * a,void * b)356 cmp_general_string (void *a, void *b)
357 {
358     char **sa = (char **)a;
359     char **sb = (char **)b;
360 
361     return strcmp (*sa, *sb);
362 }
363 
364 static int
test_general_string(void)365 test_general_string (void)
366 {
367     char *s1 = "Test User 1";
368 
369     struct test_case tests[] = {
370 	{NULL, 11, "\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31", NULL }
371     };
372     int ret, ntests = sizeof(tests) / sizeof(*tests);
373 
374     tests[0].val = &s1;
375     if (asprintf (&tests[0].name, "the string \"%s\"", s1) < 0)
376 	errx(1, "malloc");
377     if (tests[0].name == NULL)
378 	errx(1, "malloc");
379 
380     ret = generic_test (tests, ntests, sizeof(unsigned char *),
381 			(generic_encode)der_put_general_string,
382 			(generic_length)der_length_general_string,
383 			(generic_decode)der_get_general_string,
384 			(generic_free)der_free_general_string,
385 			cmp_general_string,
386 			NULL);
387     free(tests[0].name);
388     return ret;
389 }
390 
391 static int
cmp_generalized_time(void * a,void * b)392 cmp_generalized_time (void *a, void *b)
393 {
394     time_t *ta = (time_t *)a;
395     time_t *tb = (time_t *)b;
396 
397     return (int)(*tb - *ta);
398 }
399 
400 static int
test_generalized_time(void)401 test_generalized_time (void)
402 {
403     struct test_case tests[] = {
404 	{NULL, 15, "19700101000000Z", 		NULL },
405 	{NULL, 15, "19851106210627Z", 		NULL }
406     };
407     time_t values[] = {0, 500159187};
408     int i, ret;
409     int ntests = sizeof(tests) / sizeof(*tests);
410 
411     for (i = 0; i < ntests; ++i) {
412 	tests[i].val = &values[i];
413 	if (asprintf (&tests[i].name, "time %d", (int)values[i]) < 0)
414 	    errx(1, "malloc");
415 	if (tests[i].name == NULL)
416 	    errx(1, "malloc");
417     }
418 
419     ret = generic_test (tests, ntests, sizeof(time_t),
420 			(generic_encode)der_put_generalized_time,
421 			(generic_length)der_length_generalized_time,
422 			(generic_decode)der_get_generalized_time,
423 			(generic_free)NULL,
424 			cmp_generalized_time,
425 			NULL);
426     for (i = 0; i < ntests; ++i)
427 	free(tests[i].name);
428     return ret;
429 }
430 
431 static int
test_cmp_oid(void * a,void * b)432 test_cmp_oid (void *a, void *b)
433 {
434     return der_heim_oid_cmp((heim_oid *)a, (heim_oid *)b);
435 }
436 
437 static unsigned oid_comp1[] = { 1, 1, 1 };
438 static unsigned oid_comp2[] = { 1, 1 };
439 static unsigned oid_comp3[] = { 6, 15, 1 };
440 static unsigned oid_comp4[] = { 6, 15 };
441 
442 static int
test_oid(void)443 test_oid (void)
444 {
445     struct test_case tests[] = {
446 	{NULL, 2, "\x29\x01", 		NULL },
447 	{NULL, 1, "\x29", 		NULL },
448 	{NULL, 2, "\xff\x01", 		NULL },
449 	{NULL, 1, "\xff", 		NULL }
450     };
451     heim_oid values[] = {
452 	{ 3, oid_comp1 },
453 	{ 2, oid_comp2 },
454 	{ 3, oid_comp3 },
455 	{ 2, oid_comp4 }
456     };
457     int i, ret;
458     int ntests = sizeof(tests) / sizeof(*tests);
459 
460     for (i = 0; i < ntests; ++i) {
461 	tests[i].val = &values[i];
462 	if (asprintf (&tests[i].name, "oid %d", i) < 0)
463 	    errx(1, "malloc");
464 	if (tests[i].name == NULL)
465 	    errx(1, "malloc");
466     }
467 
468     ret = generic_test (tests, ntests, sizeof(heim_oid),
469 			(generic_encode)der_put_oid,
470 			(generic_length)der_length_oid,
471 			(generic_decode)der_get_oid,
472 			(generic_free)der_free_oid,
473 			test_cmp_oid,
474 			NULL);
475     for (i = 0; i < ntests; ++i)
476 	free(tests[i].name);
477     return ret;
478 }
479 
480 static int
test_cmp_bit_string(void * a,void * b)481 test_cmp_bit_string (void *a, void *b)
482 {
483     return der_heim_bit_string_cmp((heim_bit_string *)a, (heim_bit_string *)b);
484 }
485 
486 static int
test_bit_string(void)487 test_bit_string (void)
488 {
489     struct test_case tests[] = {
490 	{NULL, 1, "\x00", 		NULL }
491     };
492     heim_bit_string values[] = {
493 	{ 0, "" }
494     };
495     int i, ret;
496     int ntests = sizeof(tests) / sizeof(*tests);
497 
498     for (i = 0; i < ntests; ++i) {
499 	tests[i].val = &values[i];
500 	if (asprintf (&tests[i].name, "bit_string %d", i) < 0)
501 	    errx(1, "malloc");
502 	if (tests[i].name == NULL)
503 	    errx(1, "malloc");
504     }
505 
506     ret = generic_test (tests, ntests, sizeof(heim_bit_string),
507 			(generic_encode)der_put_bit_string,
508 			(generic_length)der_length_bit_string,
509 			(generic_decode)der_get_bit_string,
510 			(generic_free)der_free_bit_string,
511 			test_cmp_bit_string,
512 			NULL);
513     for (i = 0; i < ntests; ++i)
514 	free(tests[i].name);
515     return ret;
516 }
517 
518 static int
test_cmp_heim_integer(void * a,void * b)519 test_cmp_heim_integer (void *a, void *b)
520 {
521     return der_heim_integer_cmp((heim_integer *)a, (heim_integer *)b);
522 }
523 
524 static int
test_heim_integer(void)525 test_heim_integer (void)
526 {
527     struct test_case tests[] = {
528 	{NULL, 1, "\xff", 		NULL },
529 	{NULL, 2, "\xff\x01", 		NULL },
530 	{NULL, 2, "\xfe\x01", 		NULL },
531 	{NULL, 2, "\xef\x01", 		NULL },
532 	{NULL, 3, "\xff\x00\xff", 	NULL },
533 	{NULL, 3, "\xff\x01\x00", 	NULL },
534 	{NULL, 1, "\x00", 		NULL },
535 	{NULL, 1, "\x01", 		NULL },
536 	{NULL, 2, "\x00\x80", 		NULL },
537     };
538 
539     heim_integer values[] = {
540 	{ 1, "\x01", 1 },
541 	{ 1, "\xff", 1 },
542 	{ 2, "\x01\xff", 1 },
543 	{ 2, "\x10\xff", 1 },
544 	{ 2, "\xff\x01", 1 },
545 	{ 2, "\xff\x00", 1 },
546 	{ 0, "", 0 },
547 	{ 1, "\x01", 0 },
548 	{ 1, "\x80", 0 },
549     };
550     int i, ret;
551     int ntests = sizeof(tests) / sizeof(tests[0]);
552     size_t size;
553     heim_integer i2;
554 
555     for (i = 0; i < ntests; ++i) {
556 	tests[i].val = &values[i];
557 	if (asprintf (&tests[i].name, "heim_integer %d", i) < 0)
558 	    errx(1, "malloc");
559 	if (tests[i].name == NULL)
560 	    errx(1, "malloc");
561     }
562 
563     ret = generic_test (tests, ntests, sizeof(heim_integer),
564 			(generic_encode)der_put_heim_integer,
565 			(generic_length)der_length_heim_integer,
566 			(generic_decode)der_get_heim_integer,
567 			(generic_free)der_free_heim_integer,
568 			test_cmp_heim_integer,
569 			NULL);
570     for (i = 0; i < ntests; ++i)
571 	free (tests[i].name);
572     if (ret)
573 	return ret;
574 
575     /* test zero length integer (BER format) */
576     ret = der_get_heim_integer(NULL, 0, &i2, &size);
577     if (ret)
578 	errx(1, "der_get_heim_integer");
579     if (i2.length != 0)
580 	errx(1, "der_get_heim_integer wrong length");
581     der_free_heim_integer(&i2);
582 
583     return 0;
584 }
585 
586 static int
test_cmp_boolean(void * a,void * b)587 test_cmp_boolean (void *a, void *b)
588 {
589     return !!*(int *)a != !!*(int *)b;
590 }
591 
592 static int
test_boolean(void)593 test_boolean (void)
594 {
595     struct test_case tests[] = {
596 	{NULL, 1, "\xff", 		NULL },
597 	{NULL, 1, "\x00", 		NULL }
598     };
599 
600     int values[] = { 1, 0 };
601     int i, ret;
602     int ntests = sizeof(tests) / sizeof(tests[0]);
603     size_t size;
604     heim_integer i2;
605 
606     for (i = 0; i < ntests; ++i) {
607 	tests[i].val = &values[i];
608 	if (asprintf (&tests[i].name, "heim_boolean %d", i) < 0)
609 	    errx(1, "malloc");
610 	if (tests[i].name == NULL)
611 	    errx(1, "malloc");
612     }
613 
614     ret = generic_test (tests, ntests, sizeof(int),
615 			(generic_encode)der_put_boolean,
616 			(generic_length)der_length_boolean,
617 			(generic_decode)der_get_boolean,
618 			(generic_free)NULL,
619 			test_cmp_boolean,
620 			NULL);
621     for (i = 0; i < ntests; ++i)
622 	free (tests[i].name);
623     if (ret)
624 	return ret;
625 
626     /* test zero length integer (BER format) */
627     ret = der_get_heim_integer(NULL, 0, &i2, &size);
628     if (ret)
629 	errx(1, "der_get_heim_integer");
630     if (i2.length != 0)
631 	errx(1, "der_get_heim_integer wrong length");
632     der_free_heim_integer(&i2);
633 
634     return 0;
635 }
636 
637 static int
check_fail_unsigned(void)638 check_fail_unsigned(void)
639 {
640     struct test_case tests[] = {
641 	{NULL, sizeof(unsigned) + 1,
642 	 "\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
643     };
644     int ntests = sizeof(tests) / sizeof(*tests);
645 
646     return generic_decode_fail(tests, ntests, sizeof(unsigned),
647 			       (generic_decode)der_get_unsigned);
648 }
649 
650 static int
check_fail_integer(void)651 check_fail_integer(void)
652 {
653     struct test_case tests[] = {
654 	{NULL, sizeof(int) + 1,
655 	 "\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
656     };
657     int ntests = sizeof(tests) / sizeof(*tests);
658 
659     return generic_decode_fail(tests, ntests, sizeof(int),
660 			       (generic_decode)der_get_integer);
661 }
662 
663 static int
check_fail_length(void)664 check_fail_length(void)
665 {
666     struct test_case tests[] = {
667 	{NULL, 0, "", "empty input data"},
668 	{NULL, 1, "\x82", "internal length overrun" }
669     };
670     int ntests = sizeof(tests) / sizeof(*tests);
671 
672     return generic_decode_fail(tests, ntests, sizeof(size_t),
673 			       (generic_decode)der_get_length);
674 }
675 
676 static int
check_fail_boolean(void)677 check_fail_boolean(void)
678 {
679     struct test_case tests[] = {
680 	{NULL, 0, "", "empty input data"}
681     };
682     int ntests = sizeof(tests) / sizeof(*tests);
683 
684     return generic_decode_fail(tests, ntests, sizeof(int),
685 			       (generic_decode)der_get_boolean);
686 }
687 
688 static int
check_fail_general_string(void)689 check_fail_general_string(void)
690 {
691     struct test_case tests[] = {
692 	{ NULL, 3, "A\x00i", "NUL char in string"}
693     };
694     int ntests = sizeof(tests) / sizeof(*tests);
695 
696     return generic_decode_fail(tests, ntests, sizeof(heim_general_string),
697 			       (generic_decode)der_get_general_string);
698 }
699 
700 static int
check_fail_bmp_string(void)701 check_fail_bmp_string(void)
702 {
703     struct test_case tests[] = {
704 	{NULL, 1, "\x00", "odd (1) length bmpstring"},
705 	{NULL, 3, "\x00\x00\x00", "odd (3) length bmpstring"}
706     };
707     int ntests = sizeof(tests) / sizeof(*tests);
708 
709     return generic_decode_fail(tests, ntests, sizeof(heim_bmp_string),
710 			       (generic_decode)der_get_bmp_string);
711 }
712 
713 static int
check_fail_universal_string(void)714 check_fail_universal_string(void)
715 {
716     struct test_case tests[] = {
717 	{NULL, 1, "\x00", "x & 3 == 1 universal string"},
718 	{NULL, 2, "\x00\x00", "x & 3 == 2 universal string"},
719 	{NULL, 3, "\x00\x00\x00", "x & 3 == 3 universal string"},
720 	{NULL, 5, "\x00\x00\x00\x00\x00", "x & 3 == 1 universal string"},
721 	{NULL, 6, "\x00\x00\x00\x00\x00\x00", "x & 3 == 2 universal string"},
722 	{NULL, 7, "\x00\x00\x00\x00\x00\x00\x00", "x & 3 == 3 universal string"}
723     };
724     int ntests = sizeof(tests) / sizeof(*tests);
725 
726     return generic_decode_fail(tests, ntests, sizeof(heim_universal_string),
727 			       (generic_decode)der_get_universal_string);
728 }
729 
730 static int
check_fail_heim_integer(void)731 check_fail_heim_integer(void)
732 {
733 #if 0
734     struct test_case tests[] = {
735     };
736     int ntests = sizeof(tests) / sizeof(*tests);
737 
738     return generic_decode_fail(tests, ntests, sizeof(heim_integer),
739 			       (generic_decode)der_get_heim_integer);
740 #else
741     return 0;
742 #endif
743 }
744 
745 static int
check_fail_generalized_time(void)746 check_fail_generalized_time(void)
747 {
748     struct test_case tests[] = {
749 	{NULL, 1, "\x00", "no time"}
750     };
751     int ntests = sizeof(tests) / sizeof(*tests);
752 
753     return generic_decode_fail(tests, ntests, sizeof(time_t),
754 			       (generic_decode)der_get_generalized_time);
755 }
756 
757 static int
check_fail_oid(void)758 check_fail_oid(void)
759 {
760     struct test_case tests[] = {
761 	{NULL, 0, "", "empty input data"},
762 	{NULL, 2, "\x00\x80", "last byte continuation" },
763 	{NULL, 11, "\x00\x81\x80\x80\x80\x80\x80\x80\x80\x80\x00",
764 	"oid element overflow" }
765     };
766     int ntests = sizeof(tests) / sizeof(*tests);
767 
768     return generic_decode_fail(tests, ntests, sizeof(heim_oid),
769 			       (generic_decode)der_get_oid);
770 }
771 
772 static int
check_fail_bitstring(void)773 check_fail_bitstring(void)
774 {
775     struct test_case tests[] = {
776 	{NULL, 0, "", "empty input data"},
777 	{NULL, 1, "\x08", "larger then 8 bits trailer"},
778 	{NULL, 1, "\x01", "to few bytes for bits"},
779 	{NULL, -2, "\x00", "length overrun"},
780 	{NULL, -1, "", "length to short"}
781     };
782     int ntests = sizeof(tests) / sizeof(*tests);
783 
784     return generic_decode_fail(tests, ntests, sizeof(heim_bit_string),
785 			       (generic_decode)der_get_bit_string);
786 }
787 
788 static int
check_heim_integer_same(const char * p,const char * norm_p,heim_integer * i)789 check_heim_integer_same(const char *p, const char *norm_p, heim_integer *i)
790 {
791     heim_integer i2;
792     char *str;
793     int ret;
794 
795     ret = der_print_hex_heim_integer(i, &str);
796     if (ret)
797 	errx(1, "der_print_hex_heim_integer: %d", ret);
798 
799     if (strcmp(str, norm_p) != 0)
800 	errx(1, "der_print_hex_heim_integer: %s != %s", str, p);
801 
802     ret = der_parse_hex_heim_integer(str, &i2);
803     if (ret)
804 	errx(1, "der_parse_hex_heim_integer: %d", ret);
805 
806     if (der_heim_integer_cmp(i, &i2) != 0)
807 	errx(1, "der_heim_integer_cmp: p %s", p);
808 
809     der_free_heim_integer(&i2);
810     free(str);
811 
812     ret = der_parse_hex_heim_integer(p, &i2);
813     if (ret)
814 	errx(1, "der_parse_hex_heim_integer: %d", ret);
815 
816     if (der_heim_integer_cmp(i, &i2) != 0)
817 	errx(1, "der_heim_integer_cmp: norm");
818 
819     der_free_heim_integer(&i2);
820 
821     return 0;
822 }
823 
824 static int
test_heim_int_format(void)825 test_heim_int_format(void)
826 {
827     heim_integer i = { 1, "\x10", 0 };
828     heim_integer i2 = { 1, "\x10", 1 };
829     heim_integer i3 = { 1, "\01", 0 };
830     char *p =
831 	"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
832 	"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
833 	"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
834 	"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
835 	"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
836 	"FFFFFFFF" "FFFFFFFF";
837     heim_integer bni = {
838 	128,
839 	"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC9\x0F\xDA\xA2"
840 	"\x21\x68\xC2\x34\xC4\xC6\x62\x8B\x80\xDC\x1C\xD1"
841 	"\x29\x02\x4E\x08\x8A\x67\xCC\x74\x02\x0B\xBE\xA6"
842 	"\x3B\x13\x9B\x22\x51\x4A\x08\x79\x8E\x34\x04\xDD"
843 	"\xEF\x95\x19\xB3\xCD\x3A\x43\x1B\x30\x2B\x0A\x6D"
844 	"\xF2\x5F\x14\x37\x4F\xE1\x35\x6D\x6D\x51\xC2\x45"
845 	"\xE4\x85\xB5\x76\x62\x5E\x7E\xC6\xF4\x4C\x42\xE9"
846 	"\xA6\x37\xED\x6B\x0B\xFF\x5C\xB6\xF4\x06\xB7\xED"
847 	"\xEE\x38\x6B\xFB\x5A\x89\x9F\xA5\xAE\x9F\x24\x11"
848 	"\x7C\x4B\x1F\xE6\x49\x28\x66\x51\xEC\xE6\x53\x81"
849 	"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
850 	0
851     };
852     heim_integer f;
853     int ret = 0;
854 
855     ret += check_heim_integer_same(p, p, &bni);
856     ret += check_heim_integer_same("10", "10", &i);
857     ret += check_heim_integer_same("00000010", "10", &i);
858     ret += check_heim_integer_same("-10", "-10", &i2);
859     ret += check_heim_integer_same("-00000010", "-10", &i2);
860     ret += check_heim_integer_same("01", "01", &i3);
861     ret += check_heim_integer_same("1", "01", &i3);
862 
863     {
864 	int r;
865 	r = der_parse_hex_heim_integer("-", &f);
866 	if (r == 0) {
867 	    der_free_heim_integer(&f);
868 	    ret++;
869 	}
870 	/* used to cause UMR */
871 	r = der_parse_hex_heim_integer("00", &f);
872 	if (r == 0)
873 	    der_free_heim_integer(&f);
874 	else
875 	    ret++;
876     }
877 
878     return ret;
879 }
880 
881 static int
test_heim_oid_format_same(const char * str,const heim_oid * oid)882 test_heim_oid_format_same(const char *str, const heim_oid *oid)
883 {
884     int ret;
885     char *p;
886     heim_oid o2;
887 
888     ret = der_print_heim_oid(oid, ' ', &p);
889     if (ret) {
890 	printf("fail to print oid: %s\n", str);
891 	return 1;
892     }
893     ret = strcmp(p, str);
894     if (ret) {
895 	printf("oid %s != formated oid %s\n", str, p);
896 	free(p);
897 	return ret;
898     }
899 
900     ret = der_parse_heim_oid(p, " ", &o2);
901     if (ret) {
902 	printf("failed to parse %s\n", p);
903 	free(p);
904 	return ret;
905     }
906     free(p);
907     ret = der_heim_oid_cmp(&o2, oid);
908     der_free_oid(&o2);
909 
910     return ret;
911 }
912 
913 static unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
914 
915 static int
test_heim_oid_format(void)916 test_heim_oid_format(void)
917 {
918     heim_oid sha1 = { 6, sha1_oid_tree };
919     int ret = 0;
920 
921     ret += test_heim_oid_format_same("1 3 14 3 2 26", &sha1);
922 
923     return ret;
924 }
925 
926 static int
check_trailing_nul(void)927 check_trailing_nul(void)
928 {
929     int i, ret;
930     struct {
931 	int fail;
932 	const unsigned char *p;
933 	size_t len;
934 	const char *s;
935 	size_t size;
936     } foo[] = {
937 	{ 1, (const unsigned char *)"foo\x00o", 5, NULL, 0 },
938 	{ 1, (const unsigned char *)"\x00o", 2, NULL, 0 },
939 	{ 0, (const unsigned char *)"\x00\x00\x00\x00\x00", 5, "", 5 },
940 	{ 0, (const unsigned char *)"\x00", 1, "", 1 },
941 	{ 0, (const unsigned char *)"", 0, "", 0 },
942 	{ 0, (const unsigned char *)"foo\x00\x00", 5, "foo", 5 },
943 	{ 0, (const unsigned char *)"foo\0", 4, "foo", 4 },
944 	{ 0, (const unsigned char *)"foo", 3, "foo", 3 }
945     };
946 
947     for (i = 0; i < sizeof(foo)/sizeof(foo[0]); i++) {
948 	char *s;
949 	size_t size;
950 	ret = der_get_general_string(foo[i].p, foo[i].len, &s, &size);
951 	if (foo[i].fail) {
952 	    if (ret == 0)
953 		errx(1, "check %d NULL didn't fail", i);
954 	    continue;
955 	}
956 	if (ret)
957 	    errx(1, "NULL check %d der_get_general_string failed", i);
958 	if (foo[i].size != size)
959 	    errx(1, "NUL check i = %d size failed", i);
960 	if (strcmp(foo[i].s, s) != 0)
961 	    errx(1, "NUL check i = %d content failed", i);
962 	free(s);
963     }
964     return 0;
965 }
966 
967 static int
test_misc_cmp(void)968 test_misc_cmp(void)
969 {
970     int ret;
971 
972     /* diffrent lengths are diffrent */
973     {
974 	const heim_octet_string os1 = { 1, "a" } , os2 = { 0, NULL };
975 	ret = der_heim_octet_string_cmp(&os1, &os2);
976 	if (ret == 0)
977 	    return 1;
978     }
979     /* diffrent data are diffrent */
980     {
981 	const heim_octet_string os1 = { 1, "a" } , os2 = { 1, "b" };
982 	ret = der_heim_octet_string_cmp(&os1, &os2);
983 	if (ret == 0)
984 	    return 1;
985     }
986     /* diffrent lengths are diffrent */
987     {
988 	const heim_bit_string bs1 = { 8, "a" } , bs2 = { 7, "a" };
989 	ret = der_heim_bit_string_cmp(&bs1, &bs2);
990 	if (ret == 0)
991 	    return 1;
992     }
993     /* diffrent data are diffrent */
994     {
995 	const heim_bit_string bs1 = { 7, "\x0f" } , bs2 = { 7, "\x02" };
996 	ret = der_heim_bit_string_cmp(&bs1, &bs2);
997 	if (ret == 0)
998 	    return 1;
999     }
1000     /* diffrent lengths are diffrent */
1001     {
1002 	uint16_t data = 1;
1003 	heim_bmp_string bs1 = { 1, NULL } , bs2 = { 0, NULL };
1004 	bs1.data = &data;
1005 	ret = der_heim_bmp_string_cmp(&bs1, &bs2);
1006 	if (ret == 0)
1007 	    return 1;
1008     }
1009     /* diffrent lengths are diffrent */
1010     {
1011 	uint32_t data;
1012 	heim_universal_string us1 = { 1, NULL } , us2 = { 0, NULL };
1013 	us1.data = &data;
1014 	ret = der_heim_universal_string_cmp(&us1, &us2);
1015 	if (ret == 0)
1016 	    return 1;
1017     }
1018     /* same */
1019     {
1020 	uint32_t data = (uint32_t)'a';
1021 	heim_universal_string us1 = { 1, NULL } , us2 = { 1, NULL };
1022 	us1.data = &data;
1023 	us2.data = &data;
1024 	ret = der_heim_universal_string_cmp(&us1, &us2);
1025 	if (ret != 0)
1026 	    return 1;
1027     }
1028 
1029     return 0;
1030 }
1031 
1032 static int
corner_generalized_time(void)1033 corner_generalized_time(void)
1034 {
1035     const char *str = "760520140000Z";
1036     size_t size;
1037     time_t t;
1038     int ret;
1039 
1040     ret = der_get_generalized_time((const unsigned char*)str, strlen(str),
1041 				   &t, &size);
1042     if (ret)
1043 	return 1;
1044     return 0;
1045 }
1046 
1047 static int
corner_tag(void)1048 corner_tag(void)
1049 {
1050     struct {
1051 	int ok;
1052 	const char *ptr;
1053 	size_t len;
1054     } tests[] = {
1055 	{ 1, "\x00", 1 },
1056 	{ 0, "\xff", 1 },
1057 	{ 0, "\xff\xff\xff\xff\xff\xff\xff\xff", 8 }
1058     };
1059     int i, ret;
1060     Der_class cl;
1061     Der_type ty;
1062     unsigned int tag;
1063     size_t size;
1064 
1065     for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
1066 	ret = der_get_tag((const unsigned char*)tests[i].ptr,
1067 			  tests[i].len, &cl, &ty, &tag, &size);
1068 	if (ret) {
1069 	    if (tests[i].ok)
1070 		errx(1, "failed while shouldn't");
1071 	} else {
1072 	    if (!tests[i].ok)
1073 		errx(1, "passed while shouldn't");
1074 	}
1075     }
1076     return 0;
1077 }
1078 
1079 struct randomcheck {
1080     asn1_type_decode decoder;
1081     asn1_type_release release;
1082     size_t typesize;
1083     size_t inputsize;
1084 } randomcheck[] = {
1085 #define el(name, type, maxlen) {			\
1086 	(asn1_type_decode)der_get_##name,		\
1087 	(asn1_type_release)der_free_##name,		\
1088 	sizeof(type), 					\
1089 	maxlen						\
1090     }
1091     el(integer, int, 6),
1092     el(heim_integer, heim_integer, 12),
1093     el(integer, int, 6),
1094     el(unsigned, unsigned, 6),
1095     el(general_string, heim_general_string, 12),
1096     el(octet_string, heim_octet_string, 12),
1097     { (asn1_type_decode)der_get_octet_string_ber,
1098       (asn1_type_release)der_free_octet_string,
1099       sizeof(heim_octet_string), 20 },
1100     el(generalized_time, time_t, 20),
1101     el(utctime, time_t, 20),
1102     el(bit_string, heim_bit_string, 10),
1103     el(oid, heim_oid, 10),
1104     { NULL, NULL, 0, 0 }
1105 #undef el
1106 };
1107 
1108 static void
asn1rand(uint8_t * randbytes,size_t len)1109 asn1rand(uint8_t *randbytes, size_t len)
1110 {
1111     while (len) {
1112 	*randbytes++ = rk_random();
1113 	len--;
1114     }
1115 }
1116 
1117 static int
check_random(void)1118 check_random(void)
1119 {
1120     struct randomcheck *r = randomcheck;
1121     uint8_t *input;
1122     void *type;
1123     size_t size, insize;
1124     int ret;
1125 
1126     while (r->decoder) {
1127 	type = emalloc(r->typesize);
1128 	memset(type, 0, r->typesize);
1129 
1130 	input = emalloc(r->inputsize);
1131 
1132 	/* try all zero first */
1133 	memset(input, 0, r->inputsize);
1134 
1135 	ret = r->decoder(input, r->inputsize, type, &size);
1136 	if (ret)
1137 	    r->release(type);
1138 
1139 	/* try all one first */
1140 	memset(input, 0xff, r->inputsize);
1141 	ret = r->decoder(input, r->inputsize, type, &size);
1142 	if (ret)
1143 	    r->release(type);
1144 
1145 	/* try 0x41 too */
1146 	memset(input, 0x41, r->inputsize);
1147 	ret = r->decoder(input, r->inputsize, type, &size);
1148 	if (ret)
1149 	    r->release(type);
1150 
1151 	/* random */
1152 	asn1rand(input, r->inputsize);
1153 	ret = r->decoder(input, r->inputsize, type, &size);
1154 	if (ret)
1155 	    r->release(type);
1156 
1157 	/* let make buffer smaller */
1158 	insize = r->inputsize;
1159 	do {
1160 	    insize--;
1161 	    asn1rand(input, insize);
1162 
1163 	    ret = r->decoder(input, insize, type, &size);
1164 	    if (ret == 0)
1165 		r->release(type);
1166 	} while(insize > 0);
1167 
1168 	free(type);
1169 
1170 	r++;
1171     }
1172     return 0;
1173 }
1174 
1175 
1176 
1177 int
main(int argc,char ** argv)1178 main(int argc, char **argv)
1179 {
1180     int ret = 0;
1181 
1182     ret += test_integer ();
1183     ret += test_integer_more();
1184     ret += test_unsigned ();
1185     ret += test_octet_string ();
1186     ret += test_bmp_string ();
1187     ret += test_universal_string ();
1188     ret += test_general_string ();
1189     ret += test_generalized_time ();
1190     ret += test_oid ();
1191     ret += test_bit_string();
1192     ret += test_heim_integer();
1193     ret += test_boolean();
1194 
1195     ret += check_fail_unsigned();
1196     ret += check_fail_integer();
1197     ret += check_fail_length();
1198     ret += check_fail_boolean();
1199     ret += check_fail_general_string();
1200     ret += check_fail_bmp_string();
1201     ret += check_fail_universal_string();
1202     ret += check_fail_heim_integer();
1203     ret += check_fail_generalized_time();
1204     ret += check_fail_oid();
1205     ret += check_fail_bitstring();
1206     ret += test_heim_int_format();
1207     ret += test_heim_oid_format();
1208     ret += check_trailing_nul();
1209     ret += test_misc_cmp();
1210     ret += corner_generalized_time();
1211     ret += corner_tag();
1212     ret += check_random();
1213 
1214     return ret;
1215 }
1216