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