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