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
cmp_integer(void * a,void * b)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
test_integer(void)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
test_one_int(int val)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
test_integer_more(void)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
cmp_unsigned(void * a,void * b)178 cmp_unsigned (void *a, void *b)
179 {
180 return *(unsigned int*)b - *(unsigned int*)a;
181 }
182
183 static int
test_unsigned(void)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
cmp_octet_string(void * a,void * b)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
test_octet_string(void)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
cmp_bmp_string(void * a,void * b)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
test_bmp_string(void)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
cmp_universal_string(void * a,void * b)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
test_universal_string(void)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
cmp_general_string(void * a,void * b)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
test_general_string(void)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
cmp_generalized_time(void * a,void * b)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
test_generalized_time(void)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
test_cmp_oid(void * a,void * b)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
test_oid(void)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
test_cmp_bit_string(void * a,void * b)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
test_bit_string(void)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
test_cmp_heim_integer(void * a,void * b)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
test_heim_integer(void)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
test_cmp_boolean(void * a,void * b)586 test_cmp_boolean (void *a, void *b)
587 {
588 return !!*(int *)a != !!*(int *)b;
589 }
590
591 static int
test_boolean(void)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
check_fail_unsigned(void)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
check_fail_integer(void)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
check_fail_length(void)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
check_fail_boolean(void)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
check_fail_general_string(void)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
check_fail_bmp_string(void)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
check_fail_universal_string(void)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
check_fail_heim_integer(void)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
check_fail_generalized_time(void)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
check_fail_oid(void)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
check_fail_bitstring(void)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
check_heim_integer_same(const char * p,const char * norm_p,heim_integer * i)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
test_heim_int_format(void)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
test_heim_oid_format_same(const char * str,const heim_oid * oid)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
test_heim_oid_format(void)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
check_trailing_nul(void)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
test_misc_cmp(void)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
corner_generalized_time(void)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
corner_tag(void)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
main(int argc,char ** argv)1079 main(int argc, char **argv)
1080 {
1081 int ret = 0;
1082
1083 ret += test_integer ();
1084 ret += test_integer_more();
1085 ret += test_unsigned ();
1086 ret += test_octet_string ();
1087 ret += test_bmp_string ();
1088 ret += test_universal_string ();
1089 ret += test_general_string ();
1090 ret += test_generalized_time ();
1091 ret += test_oid ();
1092 ret += test_bit_string();
1093 ret += test_heim_integer();
1094 ret += test_boolean();
1095
1096 ret += check_fail_unsigned();
1097 ret += check_fail_integer();
1098 ret += check_fail_length();
1099 ret += check_fail_boolean();
1100 ret += check_fail_general_string();
1101 ret += check_fail_bmp_string();
1102 ret += check_fail_universal_string();
1103 ret += check_fail_heim_integer();
1104 ret += check_fail_generalized_time();
1105 ret += check_fail_oid();
1106 ret += check_fail_bitstring();
1107 ret += test_heim_int_format();
1108 ret += test_heim_oid_format();
1109 ret += check_trailing_nul();
1110 ret += test_misc_cmp();
1111 ret += corner_generalized_time();
1112 ret += corner_tag();
1113
1114 return ret;
1115 }
1116