]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - crypto/heimdal/lib/asn1/check-der.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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  * 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 }