]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/heimdal/lib/asn1/check-der.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / heimdal / lib / asn1 / check-der.c
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 }