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