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