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