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