quel 64bit warnings, fixup implicit encoding for template, fix spelling
[heimdal.git] / lib / asn1 / check-der.c
blob7cff5b4201a12b9c5ae9645781656539145981f4
1 /*
2 * Copyright (c) 1999 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
36 #include "der_locl.h"
37 #include <err.h>
38 #include <roken.h>
40 #include <asn1-common.h>
41 #include <asn1_err.h>
42 #include <der.h>
44 #include "check-common.h"
46 RCSID("$Id$");
48 static int
49 cmp_integer (void *a, void *b)
51 int *ia = (int *)a;
52 int *ib = (int *)b;
54 return *ib - *ia;
57 static int
58 test_integer (void)
60 struct test_case tests[] = {
61 {NULL, 1, "\x00", NULL },
62 {NULL, 1, "\x7f", NULL },
63 {NULL, 2, "\x00\x80", NULL },
64 {NULL, 2, "\x01\x00", NULL },
65 {NULL, 1, "\x80", NULL },
66 {NULL, 2, "\xff\x7f", NULL },
67 {NULL, 1, "\xff", NULL },
68 {NULL, 2, "\xff\x01", NULL },
69 {NULL, 2, "\x00\xff", NULL },
70 {NULL, 4, "\x7f\xff\xff\xff", NULL }
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);
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");
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);
94 for (i = 0; i < ntests; ++i)
95 free (tests[i].name);
96 return ret;
99 static int
100 test_one_int(int val)
102 int ret, dval;
103 unsigned char *buf;
104 size_t len_len, len;
106 len = _heim_len_int(val);
108 buf = emalloc(len + 2);
110 buf[0] = '\xff';
111 buf[len + 1] = '\xff';
112 memset(buf + 1, 0, len);
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;
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;
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;
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;
135 if (val != dval) {
136 printf("decode decoded to diffrent value %d != %d",
137 val, dval);
138 return 1;
141 if (buf[0] != (unsigned char)'\xff') {
142 printf("precanary dead %d\n", val);
143 return 1;
145 if (buf[len + 1] != (unsigned char)'\xff') {
146 printf("postecanary dead %d\n", val);
147 return 1;
149 free(buf);
150 return 0;
153 static int
154 test_integer_more (void)
156 int i, n1, n2, n3, n4, n5, n6;
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);
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);
174 return 0;
177 static int
178 cmp_unsigned (void *a, void *b)
180 return *(unsigned int*)b - *(unsigned int*)a;
183 static int
184 test_unsigned (void)
186 struct test_case tests[] = {
187 {NULL, 1, "\x00", NULL },
188 {NULL, 1, "\x7f", NULL },
189 {NULL, 2, "\x00\x80", NULL },
190 {NULL, 2, "\x01\x00", NULL },
191 {NULL, 2, "\x02\x00", NULL },
192 {NULL, 3, "\x00\x80\x00", NULL },
193 {NULL, 5, "\x00\x80\x00\x00\x00", NULL },
194 {NULL, 4, "\x7f\xff\xff\xff", NULL }
197 unsigned int values[] = {0, 127, 128, 256, 512, 32768,
198 0x80000000, 0x7fffffff};
199 int i, ret;
200 int ntests = sizeof(tests) / sizeof(*tests);
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");
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;
222 static int
223 cmp_octet_string (void *a, void *b)
225 return der_heim_octet_string_cmp(a, b);
228 static int
229 test_octet_string (void)
231 heim_octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"};
233 struct test_case tests[] = {
234 {NULL, 8, "\x01\x23\x45\x67\x89\xab\xcd\xef", NULL }
236 int ntests = sizeof(tests) / sizeof(*tests);
237 int ret;
239 tests[0].val = &s1;
240 if (asprintf (&tests[0].name, "a octet string") < 0)
241 errx(1, "malloc");
242 if (tests[0].name == NULL)
243 errx(1, "malloc");
245 ret = generic_test (tests, ntests, sizeof(heim_octet_string),
246 (generic_encode)der_put_octet_string,
247 (generic_length)der_length_octet_string,
248 (generic_decode)der_get_octet_string,
249 (generic_free)der_free_octet_string,
250 cmp_octet_string,
251 NULL);
252 free(tests[0].name);
253 return ret;
256 static int
257 cmp_bmp_string (void *a, void *b)
259 heim_bmp_string *oa = (heim_bmp_string *)a;
260 heim_bmp_string *ob = (heim_bmp_string *)b;
262 return der_heim_bmp_string_cmp(oa, ob);
265 static uint16_t bmp_d1[] = { 32 };
266 static uint16_t bmp_d2[] = { 32, 32 };
268 static int
269 test_bmp_string (void)
271 heim_bmp_string s1 = { 1, bmp_d1 };
272 heim_bmp_string s2 = { 2, bmp_d2 };
274 struct test_case tests[] = {
275 {NULL, 2, "\x00\x20", NULL },
276 {NULL, 4, "\x00\x20\x00\x20", NULL }
278 int ntests = sizeof(tests) / sizeof(*tests);
279 int ret;
281 tests[0].val = &s1;
282 if (asprintf (&tests[0].name, "a bmp string") < 0)
283 errx(1, "malloc");
284 if (tests[0].name == NULL)
285 errx(1, "malloc");
286 tests[1].val = &s2;
287 if (asprintf (&tests[1].name, "second bmp string") < 0)
288 errx(1, "malloc");
289 if (tests[1].name == NULL)
290 errx(1, "malloc");
292 ret = generic_test (tests, ntests, sizeof(heim_bmp_string),
293 (generic_encode)der_put_bmp_string,
294 (generic_length)der_length_bmp_string,
295 (generic_decode)der_get_bmp_string,
296 (generic_free)der_free_bmp_string,
297 cmp_bmp_string,
298 NULL);
299 free(tests[0].name);
300 free(tests[1].name);
301 return ret;
304 static int
305 cmp_universal_string (void *a, void *b)
307 heim_universal_string *oa = (heim_universal_string *)a;
308 heim_universal_string *ob = (heim_universal_string *)b;
310 return der_heim_universal_string_cmp(oa, ob);
313 static uint32_t universal_d1[] = { 32 };
314 static uint32_t universal_d2[] = { 32, 32 };
316 static int
317 test_universal_string (void)
319 heim_universal_string s1 = { 1, universal_d1 };
320 heim_universal_string s2 = { 2, universal_d2 };
322 struct test_case tests[] = {
323 {NULL, 4, "\x00\x00\x00\x20", NULL },
324 {NULL, 8, "\x00\x00\x00\x20\x00\x00\x00\x20", NULL }
326 int ntests = sizeof(tests) / sizeof(*tests);
327 int ret;
329 tests[0].val = &s1;
330 if (asprintf (&tests[0].name, "a universal string") < 0)
331 errx(1, "malloc");
332 if (tests[0].name == NULL)
333 errx(1, "malloc");
334 tests[1].val = &s2;
335 if (asprintf (&tests[1].name, "second universal string") < 0)
336 errx(1, "malloc");
337 if (tests[1].name == NULL)
338 errx(1, "malloc");
340 ret = generic_test (tests, ntests, sizeof(heim_universal_string),
341 (generic_encode)der_put_universal_string,
342 (generic_length)der_length_universal_string,
343 (generic_decode)der_get_universal_string,
344 (generic_free)der_free_universal_string,
345 cmp_universal_string,
346 NULL);
347 free(tests[0].name);
348 free(tests[1].name);
349 return ret;
352 static int
353 cmp_general_string (void *a, void *b)
355 char **sa = (char **)a;
356 char **sb = (char **)b;
358 return strcmp (*sa, *sb);
361 static int
362 test_general_string (void)
364 char *s1 = "Test User 1";
366 struct test_case tests[] = {
367 {NULL, 11, "\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31", NULL }
369 int ret, ntests = sizeof(tests) / sizeof(*tests);
371 tests[0].val = &s1;
372 if (asprintf (&tests[0].name, "the string \"%s\"", s1) < 0)
373 errx(1, "malloc");
374 if (tests[0].name == NULL)
375 errx(1, "malloc");
377 ret = generic_test (tests, ntests, sizeof(unsigned char *),
378 (generic_encode)der_put_general_string,
379 (generic_length)der_length_general_string,
380 (generic_decode)der_get_general_string,
381 (generic_free)der_free_general_string,
382 cmp_general_string,
383 NULL);
384 free(tests[0].name);
385 return ret;
388 static int
389 cmp_generalized_time (void *a, void *b)
391 time_t *ta = (time_t *)a;
392 time_t *tb = (time_t *)b;
394 return (int)(*tb - *ta);
397 static int
398 test_generalized_time (void)
400 struct test_case tests[] = {
401 {NULL, 15, "19700101000000Z", NULL },
402 {NULL, 15, "19851106210627Z", NULL }
404 time_t values[] = {0, 500159187};
405 int i, ret;
406 int ntests = sizeof(tests) / sizeof(*tests);
408 for (i = 0; i < ntests; ++i) {
409 tests[i].val = &values[i];
410 if (asprintf (&tests[i].name, "time %d", (int)values[i]) < 0)
411 errx(1, "malloc");
412 if (tests[i].name == NULL)
413 errx(1, "malloc");
416 ret = generic_test (tests, ntests, sizeof(time_t),
417 (generic_encode)der_put_generalized_time,
418 (generic_length)der_length_generalized_time,
419 (generic_decode)der_get_generalized_time,
420 (generic_free)NULL,
421 cmp_generalized_time,
422 NULL);
423 for (i = 0; i < ntests; ++i)
424 free(tests[i].name);
425 return ret;
428 static int
429 test_cmp_oid (void *a, void *b)
431 return der_heim_oid_cmp((heim_oid *)a, (heim_oid *)b);
434 static unsigned oid_comp1[] = { 1, 1, 1 };
435 static unsigned oid_comp2[] = { 1, 1 };
436 static unsigned oid_comp3[] = { 6, 15, 1 };
437 static unsigned oid_comp4[] = { 6, 15 };
439 static int
440 test_oid (void)
442 struct test_case tests[] = {
443 {NULL, 2, "\x29\x01", NULL },
444 {NULL, 1, "\x29", NULL },
445 {NULL, 2, "\xff\x01", NULL },
446 {NULL, 1, "\xff", NULL }
448 heim_oid values[] = {
449 { 3, oid_comp1 },
450 { 2, oid_comp2 },
451 { 3, oid_comp3 },
452 { 2, oid_comp4 }
454 int i, ret;
455 int ntests = sizeof(tests) / sizeof(*tests);
457 for (i = 0; i < ntests; ++i) {
458 tests[i].val = &values[i];
459 if (asprintf (&tests[i].name, "oid %d", i) < 0)
460 errx(1, "malloc");
461 if (tests[i].name == NULL)
462 errx(1, "malloc");
465 ret = generic_test (tests, ntests, sizeof(heim_oid),
466 (generic_encode)der_put_oid,
467 (generic_length)der_length_oid,
468 (generic_decode)der_get_oid,
469 (generic_free)der_free_oid,
470 test_cmp_oid,
471 NULL);
472 for (i = 0; i < ntests; ++i)
473 free(tests[i].name);
474 return ret;
477 static int
478 test_cmp_bit_string (void *a, void *b)
480 return der_heim_bit_string_cmp((heim_bit_string *)a, (heim_bit_string *)b);
483 static int
484 test_bit_string (void)
486 struct test_case tests[] = {
487 {NULL, 1, "\x00", NULL }
489 heim_bit_string values[] = {
490 { 0, "" }
492 int i, ret;
493 int ntests = sizeof(tests) / sizeof(*tests);
495 for (i = 0; i < ntests; ++i) {
496 tests[i].val = &values[i];
497 if (asprintf (&tests[i].name, "bit_string %d", i) < 0)
498 errx(1, "malloc");
499 if (tests[i].name == NULL)
500 errx(1, "malloc");
503 ret = generic_test (tests, ntests, sizeof(heim_bit_string),
504 (generic_encode)der_put_bit_string,
505 (generic_length)der_length_bit_string,
506 (generic_decode)der_get_bit_string,
507 (generic_free)der_free_bit_string,
508 test_cmp_bit_string,
509 NULL);
510 for (i = 0; i < ntests; ++i)
511 free(tests[i].name);
512 return ret;
515 static int
516 test_cmp_heim_integer (void *a, void *b)
518 return der_heim_integer_cmp((heim_integer *)a, (heim_integer *)b);
521 static int
522 test_heim_integer (void)
524 struct test_case tests[] = {
525 {NULL, 2, "\xfe\x01", NULL },
526 {NULL, 2, "\xef\x01", NULL },
527 {NULL, 3, "\xff\x00\xff", NULL },
528 {NULL, 3, "\xff\x01\x00", NULL },
529 {NULL, 1, "\x00", NULL },
530 {NULL, 1, "\x01", NULL },
531 {NULL, 2, "\x00\x80", NULL }
534 heim_integer values[] = {
535 { 2, "\x01\xff", 1 },
536 { 2, "\x10\xff", 1 },
537 { 2, "\xff\x01", 1 },
538 { 2, "\xff\x00", 1 },
539 { 0, "", 0 },
540 { 1, "\x01", 0 },
541 { 1, "\x80", 0 }
543 int i, ret;
544 int ntests = sizeof(tests) / sizeof(tests[0]);
545 size_t size;
546 heim_integer i2;
548 for (i = 0; i < ntests; ++i) {
549 tests[i].val = &values[i];
550 if (asprintf (&tests[i].name, "heim_integer %d", i) < 0)
551 errx(1, "malloc");
552 if (tests[i].name == NULL)
553 errx(1, "malloc");
556 ret = generic_test (tests, ntests, sizeof(heim_integer),
557 (generic_encode)der_put_heim_integer,
558 (generic_length)der_length_heim_integer,
559 (generic_decode)der_get_heim_integer,
560 (generic_free)der_free_heim_integer,
561 test_cmp_heim_integer,
562 NULL);
563 for (i = 0; i < ntests; ++i)
564 free (tests[i].name);
565 if (ret)
566 return ret;
568 /* test zero length integer (BER format) */
569 ret = der_get_heim_integer(NULL, 0, &i2, &size);
570 if (ret)
571 errx(1, "der_get_heim_integer");
572 if (i2.length != 0)
573 errx(1, "der_get_heim_integer wrong length");
574 der_free_heim_integer(&i2);
576 return 0;
579 static int
580 test_cmp_boolean (void *a, void *b)
582 return !!*(int *)a != !!*(int *)b;
585 static int
586 test_boolean (void)
588 struct test_case tests[] = {
589 {NULL, 1, "\xff", NULL },
590 {NULL, 1, "\x00", NULL }
593 int values[] = { 1, 0 };
594 int i, ret;
595 int ntests = sizeof(tests) / sizeof(tests[0]);
596 size_t size;
597 heim_integer i2;
599 for (i = 0; i < ntests; ++i) {
600 tests[i].val = &values[i];
601 if (asprintf (&tests[i].name, "heim_boolean %d", i) < 0)
602 errx(1, "malloc");
603 if (tests[i].name == NULL)
604 errx(1, "malloc");
607 ret = generic_test (tests, ntests, sizeof(int),
608 (generic_encode)der_put_boolean,
609 (generic_length)der_length_boolean,
610 (generic_decode)der_get_boolean,
611 (generic_free)NULL,
612 test_cmp_boolean,
613 NULL);
614 for (i = 0; i < ntests; ++i)
615 free (tests[i].name);
616 if (ret)
617 return ret;
619 /* test zero length integer (BER format) */
620 ret = der_get_heim_integer(NULL, 0, &i2, &size);
621 if (ret)
622 errx(1, "der_get_heim_integer");
623 if (i2.length != 0)
624 errx(1, "der_get_heim_integer wrong length");
625 der_free_heim_integer(&i2);
627 return 0;
630 static int
631 check_fail_unsigned(void)
633 struct test_case tests[] = {
634 {NULL, sizeof(unsigned) + 1,
635 "\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
637 int ntests = sizeof(tests) / sizeof(*tests);
639 return generic_decode_fail(tests, ntests, sizeof(unsigned),
640 (generic_decode)der_get_unsigned);
643 static int
644 check_fail_integer(void)
646 struct test_case tests[] = {
647 {NULL, sizeof(int) + 1,
648 "\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
650 int ntests = sizeof(tests) / sizeof(*tests);
652 return generic_decode_fail(tests, ntests, sizeof(int),
653 (generic_decode)der_get_integer);
656 static int
657 check_fail_length(void)
659 struct test_case tests[] = {
660 {NULL, 0, "", "empty input data"},
661 {NULL, 1, "\x82", "internal length overrun" }
663 int ntests = sizeof(tests) / sizeof(*tests);
665 return generic_decode_fail(tests, ntests, sizeof(size_t),
666 (generic_decode)der_get_length);
669 static int
670 check_fail_boolean(void)
672 struct test_case tests[] = {
673 {NULL, 0, "", "empty input data"}
675 int ntests = sizeof(tests) / sizeof(*tests);
677 return generic_decode_fail(tests, ntests, sizeof(int),
678 (generic_decode)der_get_boolean);
681 static int
682 check_fail_general_string(void)
684 struct test_case tests[] = {
685 { NULL, 3, "A\x00i", "NUL char in string"}
687 int ntests = sizeof(tests) / sizeof(*tests);
689 return generic_decode_fail(tests, ntests, sizeof(heim_general_string),
690 (generic_decode)der_get_general_string);
693 static int
694 check_fail_bmp_string(void)
696 struct test_case tests[] = {
697 {NULL, 1, "\x00", "odd (1) length bmpstring"},
698 {NULL, 3, "\x00\x00\x00", "odd (3) length bmpstring"}
700 int ntests = sizeof(tests) / sizeof(*tests);
702 return generic_decode_fail(tests, ntests, sizeof(heim_bmp_string),
703 (generic_decode)der_get_bmp_string);
706 static int
707 check_fail_universal_string(void)
709 struct test_case tests[] = {
710 {NULL, 1, "\x00", "x & 3 == 1 universal string"},
711 {NULL, 2, "\x00\x00", "x & 3 == 2 universal string"},
712 {NULL, 3, "\x00\x00\x00", "x & 3 == 3 universal string"},
713 {NULL, 5, "\x00\x00\x00\x00\x00", "x & 3 == 1 universal string"},
714 {NULL, 6, "\x00\x00\x00\x00\x00\x00", "x & 3 == 2 universal string"},
715 {NULL, 7, "\x00\x00\x00\x00\x00\x00\x00", "x & 3 == 3 universal string"}
717 int ntests = sizeof(tests) / sizeof(*tests);
719 return generic_decode_fail(tests, ntests, sizeof(heim_universal_string),
720 (generic_decode)der_get_universal_string);
723 static int
724 check_fail_heim_integer(void)
726 #if 0
727 struct test_case tests[] = {
729 int ntests = sizeof(tests) / sizeof(*tests);
731 return generic_decode_fail(tests, ntests, sizeof(heim_integer),
732 (generic_decode)der_get_heim_integer);
733 #else
734 return 0;
735 #endif
738 static int
739 check_fail_generalized_time(void)
741 struct test_case tests[] = {
742 {NULL, 1, "\x00", "no time"}
744 int ntests = sizeof(tests) / sizeof(*tests);
746 return generic_decode_fail(tests, ntests, sizeof(time_t),
747 (generic_decode)der_get_generalized_time);
750 static int
751 check_fail_oid(void)
753 struct test_case tests[] = {
754 {NULL, 0, "", "empty input data"},
755 {NULL, 2, "\x00\x80", "last byte continuation" },
756 {NULL, 11, "\x00\x81\x80\x80\x80\x80\x80\x80\x80\x80\x00",
757 "oid element overflow" }
759 int ntests = sizeof(tests) / sizeof(*tests);
761 return generic_decode_fail(tests, ntests, sizeof(heim_oid),
762 (generic_decode)der_get_oid);
765 static int
766 check_fail_bitstring(void)
768 struct test_case tests[] = {
769 {NULL, 0, "", "empty input data"},
770 {NULL, 1, "\x08", "larger then 8 bits trailer"},
771 {NULL, 1, "\x01", "to few bytes for bits"},
772 {NULL, -2, "\x00", "length overrun"},
773 {NULL, -1, "", "length to short"}
775 int ntests = sizeof(tests) / sizeof(*tests);
777 return generic_decode_fail(tests, ntests, sizeof(heim_bit_string),
778 (generic_decode)der_get_bit_string);
781 static int
782 check_heim_integer_same(const char *p, const char *norm_p, heim_integer *i)
784 heim_integer i2;
785 char *str;
786 int ret;
788 ret = der_print_hex_heim_integer(i, &str);
789 if (ret)
790 errx(1, "der_print_hex_heim_integer: %d", ret);
792 if (strcmp(str, norm_p) != 0)
793 errx(1, "der_print_hex_heim_integer: %s != %s", str, p);
795 ret = der_parse_hex_heim_integer(str, &i2);
796 if (ret)
797 errx(1, "der_parse_hex_heim_integer: %d", ret);
799 if (der_heim_integer_cmp(i, &i2) != 0)
800 errx(1, "der_heim_integer_cmp: p %s", p);
802 der_free_heim_integer(&i2);
803 free(str);
805 ret = der_parse_hex_heim_integer(p, &i2);
806 if (ret)
807 errx(1, "der_parse_hex_heim_integer: %d", ret);
809 if (der_heim_integer_cmp(i, &i2) != 0)
810 errx(1, "der_heim_integer_cmp: norm");
812 der_free_heim_integer(&i2);
814 return 0;
817 static int
818 test_heim_int_format(void)
820 heim_integer i = { 1, "\x10", 0 };
821 heim_integer i2 = { 1, "\x10", 1 };
822 heim_integer i3 = { 1, "\01", 0 };
823 char *p =
824 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
825 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
826 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
827 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
828 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
829 "FFFFFFFF" "FFFFFFFF";
830 heim_integer bni = {
831 128,
832 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC9\x0F\xDA\xA2"
833 "\x21\x68\xC2\x34\xC4\xC6\x62\x8B\x80\xDC\x1C\xD1"
834 "\x29\x02\x4E\x08\x8A\x67\xCC\x74\x02\x0B\xBE\xA6"
835 "\x3B\x13\x9B\x22\x51\x4A\x08\x79\x8E\x34\x04\xDD"
836 "\xEF\x95\x19\xB3\xCD\x3A\x43\x1B\x30\x2B\x0A\x6D"
837 "\xF2\x5F\x14\x37\x4F\xE1\x35\x6D\x6D\x51\xC2\x45"
838 "\xE4\x85\xB5\x76\x62\x5E\x7E\xC6\xF4\x4C\x42\xE9"
839 "\xA6\x37\xED\x6B\x0B\xFF\x5C\xB6\xF4\x06\xB7\xED"
840 "\xEE\x38\x6B\xFB\x5A\x89\x9F\xA5\xAE\x9F\x24\x11"
841 "\x7C\x4B\x1F\xE6\x49\x28\x66\x51\xEC\xE6\x53\x81"
842 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
845 heim_integer f;
846 int ret = 0;
848 ret += check_heim_integer_same(p, p, &bni);
849 ret += check_heim_integer_same("10", "10", &i);
850 ret += check_heim_integer_same("00000010", "10", &i);
851 ret += check_heim_integer_same("-10", "-10", &i2);
852 ret += check_heim_integer_same("-00000010", "-10", &i2);
853 ret += check_heim_integer_same("01", "01", &i3);
854 ret += check_heim_integer_same("1", "01", &i3);
857 int r;
858 r = der_parse_hex_heim_integer("-", &f);
859 if (r == 0) {
860 der_free_heim_integer(&f);
861 ret++;
863 /* used to cause UMR */
864 r = der_parse_hex_heim_integer("00", &f);
865 if (r == 0)
866 der_free_heim_integer(&f);
867 else
868 ret++;
871 return ret;
874 static int
875 test_heim_oid_format_same(const char *str, const heim_oid *oid)
877 int ret;
878 char *p;
879 heim_oid o2;
881 ret = der_print_heim_oid(oid, ' ', &p);
882 if (ret) {
883 printf("fail to print oid: %s\n", str);
884 return 1;
886 ret = strcmp(p, str);
887 if (ret) {
888 printf("oid %s != formated oid %s\n", str, p);
889 free(p);
890 return ret;
893 ret = der_parse_heim_oid(p, " ", &o2);
894 if (ret) {
895 printf("failed to parse %s\n", p);
896 free(p);
897 return ret;
899 free(p);
900 ret = der_heim_oid_cmp(&o2, oid);
901 der_free_oid(&o2);
903 return ret;
906 static unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
908 static int
909 test_heim_oid_format(void)
911 heim_oid sha1 = { 6, sha1_oid_tree };
912 int ret = 0;
914 ret += test_heim_oid_format_same("1 3 14 3 2 26", &sha1);
916 return ret;
919 static int
920 check_trailing_nul(void)
922 int i, ret;
923 struct {
924 int fail;
925 const unsigned char *p;
926 size_t len;
927 const char *s;
928 size_t size;
929 } foo[] = {
930 { 1, (const unsigned char *)"foo\x00o", 5, NULL, 0 },
931 { 1, (const unsigned char *)"\x00o", 2, NULL, 0 },
932 { 0, (const unsigned char *)"\x00\x00\x00\x00\x00", 5, "", 5 },
933 { 0, (const unsigned char *)"\x00", 1, "", 1 },
934 { 0, (const unsigned char *)"", 0, "", 0 },
935 { 0, (const unsigned char *)"foo\x00\x00", 5, "foo", 5 },
936 { 0, (const unsigned char *)"foo\0", 4, "foo", 4 },
937 { 0, (const unsigned char *)"foo", 3, "foo", 3 }
940 for (i = 0; i < sizeof(foo)/sizeof(foo[0]); i++) {
941 char *s;
942 size_t size;
943 ret = der_get_general_string(foo[i].p, foo[i].len, &s, &size);
944 if (foo[i].fail) {
945 if (ret == 0)
946 errx(1, "check %d NULL didn't fail", i);
947 continue;
949 if (ret)
950 errx(1, "NULL check %d der_get_general_string failed", i);
951 if (foo[i].size != size)
952 errx(1, "NUL check i = %d size failed", i);
953 if (strcmp(foo[i].s, s) != 0)
954 errx(1, "NUL check i = %d content failed", i);
955 free(s);
957 return 0;
960 static int
961 test_misc_cmp(void)
963 int ret;
965 /* diffrent lengths are diffrent */
967 const heim_octet_string os1 = { 1, "a" } , os2 = { 0, NULL };
968 ret = der_heim_octet_string_cmp(&os1, &os2);
969 if (ret == 0)
970 return 1;
972 /* diffrent data are diffrent */
974 const heim_octet_string os1 = { 1, "a" } , os2 = { 1, "b" };
975 ret = der_heim_octet_string_cmp(&os1, &os2);
976 if (ret == 0)
977 return 1;
979 /* diffrent lengths are diffrent */
981 const heim_bit_string bs1 = { 8, "a" } , bs2 = { 7, "a" };
982 ret = der_heim_bit_string_cmp(&bs1, &bs2);
983 if (ret == 0)
984 return 1;
986 /* diffrent data are diffrent */
988 const heim_bit_string bs1 = { 7, "\x0f" } , bs2 = { 7, "\x02" };
989 ret = der_heim_bit_string_cmp(&bs1, &bs2);
990 if (ret == 0)
991 return 1;
993 /* diffrent lengths are diffrent */
995 uint16_t data = 1;
996 heim_bmp_string bs1 = { 1, NULL } , bs2 = { 0, NULL };
997 bs1.data = &data;
998 ret = der_heim_bmp_string_cmp(&bs1, &bs2);
999 if (ret == 0)
1000 return 1;
1002 /* diffrent lengths are diffrent */
1004 uint32_t data;
1005 heim_universal_string us1 = { 1, NULL } , us2 = { 0, NULL };
1006 us1.data = &data;
1007 ret = der_heim_universal_string_cmp(&us1, &us2);
1008 if (ret == 0)
1009 return 1;
1011 /* same */
1013 uint32_t data = (uint32_t)'a';
1014 heim_universal_string us1 = { 1, NULL } , us2 = { 1, NULL };
1015 us1.data = &data;
1016 us2.data = &data;
1017 ret = der_heim_universal_string_cmp(&us1, &us2);
1018 if (ret != 0)
1019 return 1;
1022 return 0;
1025 static int
1026 corner_generalized_time(void)
1028 const char *str = "760520140000Z";
1029 size_t size;
1030 time_t t;
1031 int ret;
1033 ret = der_get_generalized_time((const unsigned char*)str, strlen(str),
1034 &t, &size);
1035 if (ret)
1036 return 1;
1037 return 0;
1040 static int
1041 corner_tag(void)
1043 struct {
1044 int ok;
1045 const char *ptr;
1046 size_t len;
1047 } tests[] = {
1048 { 1, "\x00", 1 },
1049 { 0, "\xff", 1 },
1050 { 0, "\xff\xff\xff\xff\xff\xff\xff\xff", 8 }
1052 int i, ret;
1053 Der_class cl;
1054 Der_type ty;
1055 unsigned int tag;
1056 size_t size;
1058 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
1059 ret = der_get_tag((const unsigned char*)tests[i].ptr,
1060 tests[i].len, &cl, &ty, &tag, &size);
1061 if (ret) {
1062 if (tests[i].ok)
1063 errx(1, "failed while shouldn't");
1064 } else {
1065 if (!tests[i].ok)
1066 errx(1, "passed while shouldn't");
1069 return 0;
1072 struct randomcheck {
1073 asn1_type_decode decoder;
1074 asn1_type_release release;
1075 size_t typesize;
1076 size_t inputsize;
1077 } randomcheck[] = {
1078 #define el(name, type, maxlen) { \
1079 (asn1_type_decode)der_get_##name, \
1080 (asn1_type_release)der_free_##name, \
1081 sizeof(type), \
1082 maxlen \
1084 el(integer, int, 6),
1085 el(heim_integer, heim_integer, 12),
1086 el(integer, int, 6),
1087 el(unsigned, unsigned, 6),
1088 el(general_string, heim_general_string, 12),
1089 el(octet_string, heim_octet_string, 12),
1090 { (asn1_type_decode)der_get_octet_string_ber,
1091 (asn1_type_release)der_free_octet_string,
1092 sizeof(heim_octet_string), 20 },
1093 el(generalized_time, time_t, 20),
1094 el(utctime, time_t, 20),
1095 el(bit_string, heim_bit_string, 10),
1096 el(oid, heim_oid, 10),
1097 { NULL, NULL, 0, 0 }
1098 #undef el
1101 static void
1102 asn1rand(uint8_t *rand, size_t len)
1104 while (len) {
1105 *rand++ = arc4random();
1106 len--;
1110 static int
1111 check_random(void)
1113 struct randomcheck *r = randomcheck;
1114 uint8_t *input;
1115 void *type;
1116 size_t size, insize;
1117 int ret;
1119 while (r->decoder) {
1120 type = emalloc(r->typesize);
1121 memset(type, 0, r->typesize);
1123 input = emalloc(r->inputsize);
1125 /* try all zero first */
1126 memset(input, 0, r->inputsize);
1128 ret = r->decoder(input, r->inputsize, type, &size);
1129 if (ret)
1130 r->release(type);
1132 /* try all one first */
1133 memset(input, 0xff, r->inputsize);
1134 ret = r->decoder(input, r->inputsize, type, &size);
1135 if (ret)
1136 r->release(type);
1138 /* try 0x41 too */
1139 memset(input, 0x41, r->inputsize);
1140 ret = r->decoder(input, r->inputsize, type, &size);
1141 if (ret)
1142 r->release(type);
1144 /* random */
1145 asn1rand(input, r->inputsize);
1146 ret = r->decoder(input, r->inputsize, type, &size);
1147 if (ret)
1148 r->release(type);
1150 /* let make buffer smaller */
1151 insize = r->inputsize;
1152 do {
1153 insize--;
1154 asn1rand(input, insize);
1156 ret = r->decoder(input, insize, type, &size);
1157 if (ret == 0)
1158 r->release(type);
1159 } while(insize > 0);
1161 free(type);
1163 r++;
1165 return 0;
1171 main(int argc, char **argv)
1173 int ret = 0;
1175 ret += test_integer ();
1176 ret += test_integer_more();
1177 ret += test_unsigned ();
1178 ret += test_octet_string ();
1179 ret += test_bmp_string ();
1180 ret += test_universal_string ();
1181 ret += test_general_string ();
1182 ret += test_generalized_time ();
1183 ret += test_oid ();
1184 ret += test_bit_string();
1185 ret += test_heim_integer();
1186 ret += test_boolean();
1188 ret += check_fail_unsigned();
1189 ret += check_fail_integer();
1190 ret += check_fail_length();
1191 ret += check_fail_boolean();
1192 ret += check_fail_general_string();
1193 ret += check_fail_bmp_string();
1194 ret += check_fail_universal_string();
1195 ret += check_fail_heim_integer();
1196 ret += check_fail_generalized_time();
1197 ret += check_fail_oid();
1198 ret += check_fail_bitstring();
1199 ret += test_heim_int_format();
1200 ret += test_heim_oid_format();
1201 ret += check_trailing_nul();
1202 ret += test_misc_cmp();
1203 ret += corner_generalized_time();
1204 ret += corner_tag();
1205 ret += check_random();
1207 return ret;