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