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