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