155682Smarkm/*
2233294Sstas * Copyright (c) 1999 - 2007 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
555682Smarkm *
6233294Sstas * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
755682Smarkm *
8233294Sstas * Redistribution and use in source and binary forms, with or without
9233294Sstas * modification, are permitted provided that the following conditions
10233294Sstas * are met:
1155682Smarkm *
12233294Sstas * 1. Redistributions of source code must retain the above copyright
13233294Sstas *    notice, this list of conditions and the following disclaimer.
1455682Smarkm *
15233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
16233294Sstas *    notice, this list of conditions and the following disclaimer in the
17233294Sstas *    documentation and/or other materials provided with the distribution.
1855682Smarkm *
19233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
20233294Sstas *    may be used to endorse or promote products derived from this software
21233294Sstas *    without specific prior written permission.
22233294Sstas *
23233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33233294Sstas * SUCH DAMAGE.
3455682Smarkm */
3555682Smarkm
36178825Sdfr#include "der_locl.h"
3755682Smarkm#include <err.h>
3855682Smarkm#include <roken.h>
3955682Smarkm
40102644Snectar#include <asn1-common.h>
41102644Snectar#include <asn1_err.h>
42102644Snectar#include <der.h>
4355682Smarkm
44120945Snectar#include "check-common.h"
4555682Smarkm
46233294SstasRCSID("$Id$");
4755682Smarkm
4855682Smarkmstatic int
4955682Smarkmcmp_integer (void *a, void *b)
5055682Smarkm{
5155682Smarkm    int *ia = (int *)a;
5255682Smarkm    int *ib = (int *)b;
5355682Smarkm
5455682Smarkm    return *ib - *ia;
5555682Smarkm}
5655682Smarkm
5755682Smarkmstatic int
5855682Smarkmtest_integer (void)
5955682Smarkm{
6055682Smarkm    struct test_case tests[] = {
61178825Sdfr	{NULL, 1, "\x00"},
62178825Sdfr	{NULL, 1, "\x7f"},
63178825Sdfr	{NULL, 2, "\x00\x80"},
64178825Sdfr	{NULL, 2, "\x01\x00"},
65178825Sdfr	{NULL, 1, "\x80"},
66178825Sdfr	{NULL, 2, "\xff\x7f"},
67178825Sdfr	{NULL, 1, "\xff"},
68178825Sdfr	{NULL, 2, "\xff\x01"},
69178825Sdfr	{NULL, 2, "\x00\xff"},
70178825Sdfr	{NULL, 4, "\x7f\xff\xff\xff"}
7155682Smarkm    };
7255682Smarkm
7355682Smarkm    int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255,
74178825Sdfr		    0x7fffffff};
75178825Sdfr    int i, ret;
7655682Smarkm    int ntests = sizeof(tests) / sizeof(*tests);
7755682Smarkm
7855682Smarkm    for (i = 0; i < ntests; ++i) {
7955682Smarkm	tests[i].val = &values[i];
80233294Sstas	if (asprintf (&tests[i].name, "integer %d", values[i]) < 0)
81233294Sstas	    errx(1, "malloc");
82178825Sdfr	if (tests[i].name == NULL)
83178825Sdfr	    errx(1, "malloc");
8455682Smarkm    }
8555682Smarkm
86178825Sdfr    ret = generic_test (tests, ntests, sizeof(int),
87178825Sdfr			(generic_encode)der_put_integer,
88233294Sstas			(generic_length) der_length_integer,
89233294Sstas			(generic_decode)der_get_integer,
90233294Sstas			(generic_free)NULL,
91233294Sstas			cmp_integer,
92233294Sstas			NULL);
93178825Sdfr
94178825Sdfr    for (i = 0; i < ntests; ++i)
95178825Sdfr	free (tests[i].name);
96178825Sdfr    return ret;
9755682Smarkm}
9855682Smarkm
9955682Smarkmstatic int
100178825Sdfrtest_one_int(int val)
101178825Sdfr{
102178825Sdfr    int ret, dval;
103178825Sdfr    unsigned char *buf;
104178825Sdfr    size_t len_len, len;
105178825Sdfr
106178825Sdfr    len = _heim_len_int(val);
107178825Sdfr
108178825Sdfr    buf = emalloc(len + 2);
109178825Sdfr
110178825Sdfr    buf[0] = '\xff';
111178825Sdfr    buf[len + 1] = '\xff';
112178825Sdfr    memset(buf + 1, 0, len);
113178825Sdfr
114178825Sdfr    ret = der_put_integer(buf + 1 + len - 1, len, &val, &len_len);
115178825Sdfr    if (ret) {
116178825Sdfr	printf("integer %d encode failed %d\n", val, ret);
117178825Sdfr	return 1;
118178825Sdfr    }
119178825Sdfr    if (len != len_len) {
120178825Sdfr	printf("integer %d encode fail with %d len %lu, result len %lu\n",
121178825Sdfr	       val, ret, (unsigned long)len, (unsigned long)len_len);
122178825Sdfr	return 1;
123178825Sdfr    }
124178825Sdfr
125178825Sdfr    ret = der_get_integer(buf + 1, len, &dval, &len_len);
126178825Sdfr    if (ret) {
127178825Sdfr	printf("integer %d decode failed %d\n", val, ret);
128178825Sdfr	return 1;
129178825Sdfr    }
130178825Sdfr    if (len != len_len) {
131178825Sdfr	printf("integer %d decoded diffrent len %lu != %lu",
132178825Sdfr	       val, (unsigned long)len, (unsigned long)len_len);
133178825Sdfr	return 1;
134178825Sdfr    }
135178825Sdfr    if (val != dval) {
136178825Sdfr	printf("decode decoded to diffrent value %d != %d",
137178825Sdfr	       val, dval);
138178825Sdfr	return 1;
139178825Sdfr    }
140178825Sdfr
141178825Sdfr    if (buf[0] != (unsigned char)'\xff') {
142178825Sdfr	printf("precanary dead %d\n", val);
143178825Sdfr	return 1;
144178825Sdfr    }
145178825Sdfr    if (buf[len + 1] != (unsigned char)'\xff') {
146178825Sdfr	printf("postecanary dead %d\n", val);
147178825Sdfr	return 1;
148178825Sdfr    }
149178825Sdfr    free(buf);
150178825Sdfr    return 0;
151178825Sdfr}
152178825Sdfr
153178825Sdfrstatic int
154178825Sdfrtest_integer_more (void)
155178825Sdfr{
156178825Sdfr    int i, n1, n2, n3, n4, n5, n6;
157178825Sdfr
158178825Sdfr    n2 = 0;
159178825Sdfr    for (i = 0; i < (sizeof(int) * 8); i++) {
160178825Sdfr	n1 = 0x01 << i;
161178825Sdfr	n2 = n2 | n1;
162178825Sdfr	n3 = ~n1;
163178825Sdfr	n4 = ~n2;
164178825Sdfr	n5 = (-1) & ~(0x3f << i);
165178825Sdfr	n6 = (-1) & ~(0x7f << i);
166178825Sdfr
167178825Sdfr	test_one_int(n1);
168178825Sdfr	test_one_int(n2);
169178825Sdfr	test_one_int(n3);
170178825Sdfr	test_one_int(n4);
171178825Sdfr	test_one_int(n5);
172178825Sdfr	test_one_int(n6);
173178825Sdfr    }
174178825Sdfr    return 0;
175178825Sdfr}
176178825Sdfr
177178825Sdfrstatic int
178178825Sdfrcmp_unsigned (void *a, void *b)
179178825Sdfr{
180178825Sdfr    return *(unsigned int*)b - *(unsigned int*)a;
181178825Sdfr}
182178825Sdfr
183178825Sdfrstatic int
184178825Sdfrtest_unsigned (void)
185178825Sdfr{
186178825Sdfr    struct test_case tests[] = {
187178825Sdfr	{NULL, 1, "\x00"},
188178825Sdfr	{NULL, 1, "\x7f"},
189178825Sdfr	{NULL, 2, "\x00\x80"},
190178825Sdfr	{NULL, 2, "\x01\x00"},
191178825Sdfr	{NULL, 2, "\x02\x00"},
192178825Sdfr	{NULL, 3, "\x00\x80\x00"},
193178825Sdfr	{NULL, 5, "\x00\x80\x00\x00\x00"},
194178825Sdfr	{NULL, 4, "\x7f\xff\xff\xff"}
195178825Sdfr    };
196178825Sdfr
197233294Sstas    unsigned int values[] = {0, 127, 128, 256, 512, 32768,
198178825Sdfr			     0x80000000, 0x7fffffff};
199178825Sdfr    int i, ret;
200178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
201178825Sdfr
202178825Sdfr    for (i = 0; i < ntests; ++i) {
203178825Sdfr	tests[i].val = &values[i];
204233294Sstas	if (asprintf (&tests[i].name, "unsigned %u", values[i]) < 0)
205233294Sstas	    errx(1, "malloc");
206178825Sdfr	if (tests[i].name == NULL)
207178825Sdfr	    errx(1, "malloc");
208178825Sdfr    }
209178825Sdfr
210178825Sdfr    ret = generic_test (tests, ntests, sizeof(int),
211178825Sdfr			(generic_encode)der_put_unsigned,
212178825Sdfr			(generic_length)der_length_unsigned,
213178825Sdfr			(generic_decode)der_get_unsigned,
214178825Sdfr			(generic_free)NULL,
215233294Sstas			cmp_unsigned,
216233294Sstas			NULL);
217233294Sstas    for (i = 0; i < ntests; ++i)
218178825Sdfr	free (tests[i].name);
219178825Sdfr    return ret;
220178825Sdfr}
221178825Sdfr
222178825Sdfrstatic int
22355682Smarkmcmp_octet_string (void *a, void *b)
22455682Smarkm{
225178825Sdfr    heim_octet_string *oa = (heim_octet_string *)a;
226178825Sdfr    heim_octet_string *ob = (heim_octet_string *)b;
22755682Smarkm
22855682Smarkm    if (oa->length != ob->length)
22955682Smarkm	return ob->length - oa->length;
23055682Smarkm
23155682Smarkm    return (memcmp (oa->data, ob->data, oa->length));
23255682Smarkm}
23355682Smarkm
23455682Smarkmstatic int
23555682Smarkmtest_octet_string (void)
23655682Smarkm{
237178825Sdfr    heim_octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"};
23855682Smarkm
23955682Smarkm    struct test_case tests[] = {
240178825Sdfr	{NULL, 8, "\x01\x23\x45\x67\x89\xab\xcd\xef"}
24155682Smarkm    };
24255682Smarkm    int ntests = sizeof(tests) / sizeof(*tests);
243178825Sdfr    int ret;
24455682Smarkm
24555682Smarkm    tests[0].val = &s1;
246233294Sstas    if (asprintf (&tests[0].name, "a octet string") < 0)
247233294Sstas	errx(1, "malloc");
248178825Sdfr    if (tests[0].name == NULL)
249178825Sdfr	errx(1, "malloc");
25055682Smarkm
251178825Sdfr    ret = generic_test (tests, ntests, sizeof(heim_octet_string),
252178825Sdfr			(generic_encode)der_put_octet_string,
253178825Sdfr			(generic_length)der_length_octet_string,
254178825Sdfr			(generic_decode)der_get_octet_string,
255178825Sdfr			(generic_free)der_free_octet_string,
256233294Sstas			cmp_octet_string,
257233294Sstas			NULL);
258178825Sdfr    free(tests[0].name);
259178825Sdfr    return ret;
26055682Smarkm}
26155682Smarkm
26255682Smarkmstatic int
263178825Sdfrcmp_bmp_string (void *a, void *b)
264178825Sdfr{
265178825Sdfr    heim_bmp_string *oa = (heim_bmp_string *)a;
266178825Sdfr    heim_bmp_string *ob = (heim_bmp_string *)b;
267178825Sdfr
268178825Sdfr    return der_heim_bmp_string_cmp(oa, ob);
269178825Sdfr}
270178825Sdfr
271178825Sdfrstatic uint16_t bmp_d1[] = { 32 };
272178825Sdfrstatic uint16_t bmp_d2[] = { 32, 32 };
273178825Sdfr
274178825Sdfrstatic int
275178825Sdfrtest_bmp_string (void)
276178825Sdfr{
277178825Sdfr    heim_bmp_string s1 = { 1, bmp_d1 };
278178825Sdfr    heim_bmp_string s2 = { 2, bmp_d2 };
279178825Sdfr
280178825Sdfr    struct test_case tests[] = {
281178825Sdfr	{NULL, 2, "\x00\x20"},
282178825Sdfr	{NULL, 4, "\x00\x20\x00\x20"}
283178825Sdfr    };
284178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
285178825Sdfr    int ret;
286178825Sdfr
287178825Sdfr    tests[0].val = &s1;
288233294Sstas    if (asprintf (&tests[0].name, "a bmp string") < 0)
289233294Sstas	errx(1, "malloc");
290178825Sdfr    if (tests[0].name == NULL)
291178825Sdfr	errx(1, "malloc");
292178825Sdfr    tests[1].val = &s2;
293233294Sstas    if (asprintf (&tests[1].name, "second bmp string") < 0)
294233294Sstas	errx(1, "malloc");
295178825Sdfr    if (tests[1].name == NULL)
296178825Sdfr	errx(1, "malloc");
297178825Sdfr
298178825Sdfr    ret = generic_test (tests, ntests, sizeof(heim_bmp_string),
299178825Sdfr			(generic_encode)der_put_bmp_string,
300178825Sdfr			(generic_length)der_length_bmp_string,
301178825Sdfr			(generic_decode)der_get_bmp_string,
302178825Sdfr			(generic_free)der_free_bmp_string,
303233294Sstas			cmp_bmp_string,
304233294Sstas			NULL);
305178825Sdfr    free(tests[0].name);
306178825Sdfr    free(tests[1].name);
307178825Sdfr    return ret;
308178825Sdfr}
309178825Sdfr
310178825Sdfrstatic int
311178825Sdfrcmp_universal_string (void *a, void *b)
312178825Sdfr{
313178825Sdfr    heim_universal_string *oa = (heim_universal_string *)a;
314178825Sdfr    heim_universal_string *ob = (heim_universal_string *)b;
315178825Sdfr
316178825Sdfr    return der_heim_universal_string_cmp(oa, ob);
317178825Sdfr}
318178825Sdfr
319178825Sdfrstatic uint32_t universal_d1[] = { 32 };
320178825Sdfrstatic uint32_t universal_d2[] = { 32, 32 };
321178825Sdfr
322178825Sdfrstatic int
323178825Sdfrtest_universal_string (void)
324178825Sdfr{
325178825Sdfr    heim_universal_string s1 = { 1, universal_d1 };
326178825Sdfr    heim_universal_string s2 = { 2, universal_d2 };
327178825Sdfr
328178825Sdfr    struct test_case tests[] = {
329178825Sdfr	{NULL, 4, "\x00\x00\x00\x20"},
330178825Sdfr	{NULL, 8, "\x00\x00\x00\x20\x00\x00\x00\x20"}
331178825Sdfr    };
332178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
333178825Sdfr    int ret;
334178825Sdfr
335178825Sdfr    tests[0].val = &s1;
336233294Sstas    if (asprintf (&tests[0].name, "a universal string") < 0)
337233294Sstas	errx(1, "malloc");
338178825Sdfr    if (tests[0].name == NULL)
339178825Sdfr	errx(1, "malloc");
340178825Sdfr    tests[1].val = &s2;
341233294Sstas    if (asprintf (&tests[1].name, "second universal string") < 0)
342233294Sstas	errx(1, "malloc");
343178825Sdfr    if (tests[1].name == NULL)
344178825Sdfr	errx(1, "malloc");
345178825Sdfr
346178825Sdfr    ret = generic_test (tests, ntests, sizeof(heim_universal_string),
347178825Sdfr			(generic_encode)der_put_universal_string,
348178825Sdfr			(generic_length)der_length_universal_string,
349178825Sdfr			(generic_decode)der_get_universal_string,
350178825Sdfr			(generic_free)der_free_universal_string,
351233294Sstas			cmp_universal_string,
352233294Sstas			NULL);
353178825Sdfr    free(tests[0].name);
354178825Sdfr    free(tests[1].name);
355178825Sdfr    return ret;
356178825Sdfr}
357178825Sdfr
358178825Sdfrstatic int
35955682Smarkmcmp_general_string (void *a, void *b)
36055682Smarkm{
361178825Sdfr    char **sa = (char **)a;
362178825Sdfr    char **sb = (char **)b;
36355682Smarkm
36455682Smarkm    return strcmp (*sa, *sb);
36555682Smarkm}
36655682Smarkm
36755682Smarkmstatic int
36855682Smarkmtest_general_string (void)
36955682Smarkm{
370178825Sdfr    char *s1 = "Test User 1";
37155682Smarkm
37255682Smarkm    struct test_case tests[] = {
373178825Sdfr	{NULL, 11, "\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31"}
37455682Smarkm    };
375178825Sdfr    int ret, ntests = sizeof(tests) / sizeof(*tests);
37655682Smarkm
37755682Smarkm    tests[0].val = &s1;
378233294Sstas    if (asprintf (&tests[0].name, "the string \"%s\"", s1) < 0)
379233294Sstas	errx(1, "malloc");
380178825Sdfr    if (tests[0].name == NULL)
381178825Sdfr	errx(1, "malloc");
38255682Smarkm
383178825Sdfr    ret = generic_test (tests, ntests, sizeof(unsigned char *),
384178825Sdfr			(generic_encode)der_put_general_string,
385178825Sdfr			(generic_length)der_length_general_string,
386178825Sdfr			(generic_decode)der_get_general_string,
387178825Sdfr			(generic_free)der_free_general_string,
388233294Sstas			cmp_general_string,
389233294Sstas			NULL);
390178825Sdfr    free(tests[0].name);
391178825Sdfr    return ret;
39255682Smarkm}
39355682Smarkm
39455682Smarkmstatic int
39555682Smarkmcmp_generalized_time (void *a, void *b)
39655682Smarkm{
39755682Smarkm    time_t *ta = (time_t *)a;
39855682Smarkm    time_t *tb = (time_t *)b;
39955682Smarkm
40055682Smarkm    return *tb - *ta;
40155682Smarkm}
40255682Smarkm
40355682Smarkmstatic int
40455682Smarkmtest_generalized_time (void)
40555682Smarkm{
40655682Smarkm    struct test_case tests[] = {
407178825Sdfr	{NULL, 15, "19700101000000Z"},
408178825Sdfr	{NULL, 15, "19851106210627Z"}
40955682Smarkm    };
41055682Smarkm    time_t values[] = {0, 500159187};
411178825Sdfr    int i, ret;
41255682Smarkm    int ntests = sizeof(tests) / sizeof(*tests);
41355682Smarkm
41455682Smarkm    for (i = 0; i < ntests; ++i) {
41555682Smarkm	tests[i].val = &values[i];
416233294Sstas	if (asprintf (&tests[i].name, "time %d", (int)values[i]) < 0)
417233294Sstas	    errx(1, "malloc");
418178825Sdfr	if (tests[i].name == NULL)
419178825Sdfr	    errx(1, "malloc");
42055682Smarkm    }
42155682Smarkm
422178825Sdfr    ret = generic_test (tests, ntests, sizeof(time_t),
423178825Sdfr			(generic_encode)der_put_generalized_time,
424178825Sdfr			(generic_length)der_length_generalized_time,
425178825Sdfr			(generic_decode)der_get_generalized_time,
426178825Sdfr			(generic_free)NULL,
427233294Sstas			cmp_generalized_time,
428233294Sstas			NULL);
429178825Sdfr    for (i = 0; i < ntests; ++i)
430178825Sdfr	free(tests[i].name);
431178825Sdfr    return ret;
43255682Smarkm}
43355682Smarkm
434178825Sdfrstatic int
435178825Sdfrtest_cmp_oid (void *a, void *b)
436178825Sdfr{
437178825Sdfr    return der_heim_oid_cmp((heim_oid *)a, (heim_oid *)b);
438178825Sdfr}
439178825Sdfr
440178825Sdfrstatic unsigned oid_comp1[] = { 1, 1, 1 };
441178825Sdfrstatic unsigned oid_comp2[] = { 1, 1 };
442178825Sdfrstatic unsigned oid_comp3[] = { 6, 15, 1 };
443178825Sdfrstatic unsigned oid_comp4[] = { 6, 15 };
444178825Sdfr
445178825Sdfrstatic int
446178825Sdfrtest_oid (void)
447178825Sdfr{
448178825Sdfr    struct test_case tests[] = {
449178825Sdfr	{NULL, 2, "\x29\x01"},
450178825Sdfr	{NULL, 1, "\x29"},
451178825Sdfr	{NULL, 2, "\xff\x01"},
452178825Sdfr	{NULL, 1, "\xff"}
453178825Sdfr    };
454178825Sdfr    heim_oid values[] = {
455178825Sdfr	{ 3, oid_comp1 },
456178825Sdfr	{ 2, oid_comp2 },
457178825Sdfr	{ 3, oid_comp3 },
458178825Sdfr	{ 2, oid_comp4 }
459178825Sdfr    };
460178825Sdfr    int i, ret;
461178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
462178825Sdfr
463178825Sdfr    for (i = 0; i < ntests; ++i) {
464178825Sdfr	tests[i].val = &values[i];
465233294Sstas	if (asprintf (&tests[i].name, "oid %d", i) < 0)
466233294Sstas	    errx(1, "malloc");
467178825Sdfr	if (tests[i].name == NULL)
468178825Sdfr	    errx(1, "malloc");
469178825Sdfr    }
470178825Sdfr
471178825Sdfr    ret = generic_test (tests, ntests, sizeof(heim_oid),
472178825Sdfr			(generic_encode)der_put_oid,
473178825Sdfr			(generic_length)der_length_oid,
474178825Sdfr			(generic_decode)der_get_oid,
475178825Sdfr			(generic_free)der_free_oid,
476233294Sstas			test_cmp_oid,
477233294Sstas			NULL);
478178825Sdfr    for (i = 0; i < ntests; ++i)
479178825Sdfr	free(tests[i].name);
480178825Sdfr    return ret;
481178825Sdfr}
482178825Sdfr
483178825Sdfrstatic int
484178825Sdfrtest_cmp_bit_string (void *a, void *b)
485178825Sdfr{
486178825Sdfr    return der_heim_bit_string_cmp((heim_bit_string *)a, (heim_bit_string *)b);
487178825Sdfr}
488178825Sdfr
489178825Sdfrstatic int
490178825Sdfrtest_bit_string (void)
491178825Sdfr{
492178825Sdfr    struct test_case tests[] = {
493178825Sdfr	{NULL, 1, "\x00"}
494178825Sdfr    };
495178825Sdfr    heim_bit_string values[] = {
496178825Sdfr	{ 0, "" }
497178825Sdfr    };
498178825Sdfr    int i, ret;
499178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
500178825Sdfr
501178825Sdfr    for (i = 0; i < ntests; ++i) {
502178825Sdfr	tests[i].val = &values[i];
503233294Sstas	if (asprintf (&tests[i].name, "bit_string %d", i) < 0)
504233294Sstas	    errx(1, "malloc");
505178825Sdfr	if (tests[i].name == NULL)
506178825Sdfr	    errx(1, "malloc");
507178825Sdfr    }
508178825Sdfr
509178825Sdfr    ret = generic_test (tests, ntests, sizeof(heim_bit_string),
510178825Sdfr			(generic_encode)der_put_bit_string,
511178825Sdfr			(generic_length)der_length_bit_string,
512178825Sdfr			(generic_decode)der_get_bit_string,
513178825Sdfr			(generic_free)der_free_bit_string,
514233294Sstas			test_cmp_bit_string,
515233294Sstas			NULL);
516178825Sdfr    for (i = 0; i < ntests; ++i)
517178825Sdfr	free(tests[i].name);
518178825Sdfr    return ret;
519178825Sdfr}
520178825Sdfr
521178825Sdfrstatic int
522178825Sdfrtest_cmp_heim_integer (void *a, void *b)
523178825Sdfr{
524178825Sdfr    return der_heim_integer_cmp((heim_integer *)a, (heim_integer *)b);
525178825Sdfr}
526178825Sdfr
527178825Sdfrstatic int
528178825Sdfrtest_heim_integer (void)
529178825Sdfr{
530178825Sdfr    struct test_case tests[] = {
531178825Sdfr	{NULL, 2, "\xfe\x01"},
532178825Sdfr	{NULL, 2, "\xef\x01"},
533178825Sdfr	{NULL, 3, "\xff\x00\xff"},
534178825Sdfr	{NULL, 3, "\xff\x01\x00"},
535178825Sdfr	{NULL, 1, "\x00"},
536178825Sdfr	{NULL, 1, "\x01"},
537178825Sdfr	{NULL, 2, "\x00\x80"}
538178825Sdfr    };
539178825Sdfr
540178825Sdfr    heim_integer values[] = {
541178825Sdfr	{ 2, "\x01\xff", 1 },
542178825Sdfr	{ 2, "\x10\xff", 1 },
543178825Sdfr	{ 2, "\xff\x01", 1 },
544178825Sdfr	{ 2, "\xff\x00", 1 },
545178825Sdfr	{ 0, "", 0 },
546178825Sdfr	{ 1, "\x01", 0 },
547178825Sdfr	{ 1, "\x80", 0 }
548178825Sdfr    };
549178825Sdfr    int i, ret;
550178825Sdfr    int ntests = sizeof(tests) / sizeof(tests[0]);
551178825Sdfr    size_t size;
552178825Sdfr    heim_integer i2;
553178825Sdfr
554178825Sdfr    for (i = 0; i < ntests; ++i) {
555178825Sdfr	tests[i].val = &values[i];
556233294Sstas	if (asprintf (&tests[i].name, "heim_integer %d", i) < 0)
557233294Sstas	    errx(1, "malloc");
558178825Sdfr	if (tests[i].name == NULL)
559178825Sdfr	    errx(1, "malloc");
560178825Sdfr    }
561178825Sdfr
562178825Sdfr    ret = generic_test (tests, ntests, sizeof(heim_integer),
563178825Sdfr			(generic_encode)der_put_heim_integer,
564178825Sdfr			(generic_length)der_length_heim_integer,
565178825Sdfr			(generic_decode)der_get_heim_integer,
566178825Sdfr			(generic_free)der_free_heim_integer,
567233294Sstas			test_cmp_heim_integer,
568233294Sstas			NULL);
569233294Sstas    for (i = 0; i < ntests; ++i)
570178825Sdfr	free (tests[i].name);
571178825Sdfr    if (ret)
572178825Sdfr	return ret;
573178825Sdfr
574178825Sdfr    /* test zero length integer (BER format) */
575178825Sdfr    ret = der_get_heim_integer(NULL, 0, &i2, &size);
576178825Sdfr    if (ret)
577178825Sdfr	errx(1, "der_get_heim_integer");
578178825Sdfr    if (i2.length != 0)
579178825Sdfr	errx(1, "der_get_heim_integer wrong length");
580178825Sdfr    der_free_heim_integer(&i2);
581178825Sdfr
582178825Sdfr    return 0;
583178825Sdfr}
584178825Sdfr
585178825Sdfrstatic int
586178825Sdfrtest_cmp_boolean (void *a, void *b)
587178825Sdfr{
588178825Sdfr    return !!*(int *)a != !!*(int *)b;
589178825Sdfr}
590178825Sdfr
591178825Sdfrstatic int
592178825Sdfrtest_boolean (void)
593178825Sdfr{
594178825Sdfr    struct test_case tests[] = {
595178825Sdfr	{NULL, 1, "\xff"},
596178825Sdfr	{NULL, 1, "\x00"}
597178825Sdfr    };
598178825Sdfr
599178825Sdfr    int values[] = { 1, 0 };
600178825Sdfr    int i, ret;
601178825Sdfr    int ntests = sizeof(tests) / sizeof(tests[0]);
602178825Sdfr    size_t size;
603178825Sdfr    heim_integer i2;
604178825Sdfr
605178825Sdfr    for (i = 0; i < ntests; ++i) {
606178825Sdfr	tests[i].val = &values[i];
607233294Sstas	if (asprintf (&tests[i].name, "heim_boolean %d", i) < 0)
608233294Sstas	    errx(1, "malloc");
609178825Sdfr	if (tests[i].name == NULL)
610178825Sdfr	    errx(1, "malloc");
611178825Sdfr    }
612178825Sdfr
613178825Sdfr    ret = generic_test (tests, ntests, sizeof(int),
614178825Sdfr			(generic_encode)der_put_boolean,
615178825Sdfr			(generic_length)der_length_boolean,
616178825Sdfr			(generic_decode)der_get_boolean,
617178825Sdfr			(generic_free)NULL,
618233294Sstas			test_cmp_boolean,
619233294Sstas			NULL);
620233294Sstas    for (i = 0; i < ntests; ++i)
621178825Sdfr	free (tests[i].name);
622178825Sdfr    if (ret)
623178825Sdfr	return ret;
624178825Sdfr
625178825Sdfr    /* test zero length integer (BER format) */
626178825Sdfr    ret = der_get_heim_integer(NULL, 0, &i2, &size);
627178825Sdfr    if (ret)
628178825Sdfr	errx(1, "der_get_heim_integer");
629178825Sdfr    if (i2.length != 0)
630178825Sdfr	errx(1, "der_get_heim_integer wrong length");
631178825Sdfr    der_free_heim_integer(&i2);
632178825Sdfr
633178825Sdfr    return 0;
634178825Sdfr}
635178825Sdfr
636178825Sdfrstatic int
637178825Sdfrcheck_fail_unsigned(void)
638178825Sdfr{
639178825Sdfr    struct test_case tests[] = {
640178825Sdfr	{NULL, sizeof(unsigned) + 1,
641178825Sdfr	 "\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
642178825Sdfr    };
643178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
644178825Sdfr
645178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(unsigned),
646178825Sdfr			       (generic_decode)der_get_unsigned);
647178825Sdfr}
648178825Sdfr
649178825Sdfrstatic int
650178825Sdfrcheck_fail_integer(void)
651178825Sdfr{
652178825Sdfr    struct test_case tests[] = {
653178825Sdfr	{NULL, sizeof(int) + 1,
654178825Sdfr	 "\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" }
655178825Sdfr    };
656178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
657178825Sdfr
658178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(int),
659178825Sdfr			       (generic_decode)der_get_integer);
660178825Sdfr}
661178825Sdfr
662178825Sdfrstatic int
663178825Sdfrcheck_fail_length(void)
664178825Sdfr{
665178825Sdfr    struct test_case tests[] = {
666178825Sdfr	{NULL, 0, "", "empty input data"},
667178825Sdfr	{NULL, 1, "\x82", "internal length overrun" }
668178825Sdfr    };
669178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
670178825Sdfr
671178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(size_t),
672178825Sdfr			       (generic_decode)der_get_length);
673178825Sdfr}
674178825Sdfr
675178825Sdfrstatic int
676178825Sdfrcheck_fail_boolean(void)
677178825Sdfr{
678178825Sdfr    struct test_case tests[] = {
679178825Sdfr	{NULL, 0, "", "empty input data"}
680178825Sdfr    };
681178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
682178825Sdfr
683178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(int),
684178825Sdfr			       (generic_decode)der_get_boolean);
685178825Sdfr}
686178825Sdfr
687178825Sdfrstatic int
688178825Sdfrcheck_fail_general_string(void)
689178825Sdfr{
690178825Sdfr    struct test_case tests[] = {
691178825Sdfr	{ NULL, 3, "A\x00i", "NUL char in string"}
692178825Sdfr    };
693178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
694178825Sdfr
695178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(heim_general_string),
696178825Sdfr			       (generic_decode)der_get_general_string);
697178825Sdfr}
698178825Sdfr
699178825Sdfrstatic int
700178825Sdfrcheck_fail_bmp_string(void)
701178825Sdfr{
702178825Sdfr    struct test_case tests[] = {
703178825Sdfr	{NULL, 1, "\x00", "odd (1) length bmpstring"},
704178825Sdfr	{NULL, 3, "\x00\x00\x00", "odd (3) length bmpstring"}
705178825Sdfr    };
706178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
707178825Sdfr
708178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(heim_bmp_string),
709178825Sdfr			       (generic_decode)der_get_bmp_string);
710178825Sdfr}
711178825Sdfr
712178825Sdfrstatic int
713178825Sdfrcheck_fail_universal_string(void)
714178825Sdfr{
715178825Sdfr    struct test_case tests[] = {
716178825Sdfr	{NULL, 1, "\x00", "x & 3 == 1 universal string"},
717178825Sdfr	{NULL, 2, "\x00\x00", "x & 3 == 2 universal string"},
718178825Sdfr	{NULL, 3, "\x00\x00\x00", "x & 3 == 3 universal string"},
719178825Sdfr	{NULL, 5, "\x00\x00\x00\x00\x00", "x & 3 == 1 universal string"},
720178825Sdfr	{NULL, 6, "\x00\x00\x00\x00\x00\x00", "x & 3 == 2 universal string"},
721178825Sdfr	{NULL, 7, "\x00\x00\x00\x00\x00\x00\x00", "x & 3 == 3 universal string"}
722178825Sdfr    };
723178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
724178825Sdfr
725178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(heim_universal_string),
726178825Sdfr			       (generic_decode)der_get_universal_string);
727178825Sdfr}
728178825Sdfr
729178825Sdfrstatic int
730178825Sdfrcheck_fail_heim_integer(void)
731178825Sdfr{
732178825Sdfr#if 0
733178825Sdfr    struct test_case tests[] = {
734178825Sdfr    };
735178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
736178825Sdfr
737178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(heim_integer),
738178825Sdfr			       (generic_decode)der_get_heim_integer);
739178825Sdfr#else
740178825Sdfr    return 0;
741178825Sdfr#endif
742178825Sdfr}
743178825Sdfr
744178825Sdfrstatic int
745178825Sdfrcheck_fail_generalized_time(void)
746178825Sdfr{
747178825Sdfr    struct test_case tests[] = {
748178825Sdfr	{NULL, 1, "\x00", "no time"}
749178825Sdfr    };
750178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
751178825Sdfr
752178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(time_t),
753178825Sdfr			       (generic_decode)der_get_generalized_time);
754178825Sdfr}
755178825Sdfr
756178825Sdfrstatic int
757178825Sdfrcheck_fail_oid(void)
758178825Sdfr{
759178825Sdfr    struct test_case tests[] = {
760178825Sdfr	{NULL, 0, "", "empty input data"},
761178825Sdfr	{NULL, 2, "\x00\x80", "last byte continuation" },
762233294Sstas	{NULL, 11, "\x00\x81\x80\x80\x80\x80\x80\x80\x80\x80\x00",
763178825Sdfr	"oid element overflow" }
764178825Sdfr    };
765178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
766178825Sdfr
767178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(heim_oid),
768178825Sdfr			       (generic_decode)der_get_oid);
769178825Sdfr}
770178825Sdfr
771178825Sdfrstatic int
772178825Sdfrcheck_fail_bitstring(void)
773178825Sdfr{
774178825Sdfr    struct test_case tests[] = {
775178825Sdfr	{NULL, 0, "", "empty input data"},
776178825Sdfr	{NULL, 1, "\x08", "larger then 8 bits trailer"},
777178825Sdfr	{NULL, 1, "\x01", "to few bytes for bits"},
778178825Sdfr	{NULL, -2, "\x00", "length overrun"},
779178825Sdfr	{NULL, -1, "", "length to short"}
780178825Sdfr    };
781178825Sdfr    int ntests = sizeof(tests) / sizeof(*tests);
782178825Sdfr
783178825Sdfr    return generic_decode_fail(tests, ntests, sizeof(heim_bit_string),
784178825Sdfr			       (generic_decode)der_get_bit_string);
785178825Sdfr}
786178825Sdfr
787178825Sdfrstatic int
788178825Sdfrcheck_heim_integer_same(const char *p, const char *norm_p, heim_integer *i)
789178825Sdfr{
790178825Sdfr    heim_integer i2;
791178825Sdfr    char *str;
792178825Sdfr    int ret;
793178825Sdfr
794178825Sdfr    ret = der_print_hex_heim_integer(i, &str);
795178825Sdfr    if (ret)
796178825Sdfr	errx(1, "der_print_hex_heim_integer: %d", ret);
797178825Sdfr
798178825Sdfr    if (strcmp(str, norm_p) != 0)
799178825Sdfr	errx(1, "der_print_hex_heim_integer: %s != %s", str, p);
800178825Sdfr
801178825Sdfr    ret = der_parse_hex_heim_integer(str, &i2);
802178825Sdfr    if (ret)
803178825Sdfr	errx(1, "der_parse_hex_heim_integer: %d", ret);
804178825Sdfr
805178825Sdfr    if (der_heim_integer_cmp(i, &i2) != 0)
806178825Sdfr	errx(1, "der_heim_integer_cmp: p %s", p);
807178825Sdfr
808178825Sdfr    der_free_heim_integer(&i2);
809178825Sdfr    free(str);
810178825Sdfr
811178825Sdfr    ret = der_parse_hex_heim_integer(p, &i2);
812178825Sdfr    if (ret)
813178825Sdfr	errx(1, "der_parse_hex_heim_integer: %d", ret);
814178825Sdfr
815178825Sdfr    if (der_heim_integer_cmp(i, &i2) != 0)
816178825Sdfr	errx(1, "der_heim_integer_cmp: norm");
817178825Sdfr
818178825Sdfr    der_free_heim_integer(&i2);
819178825Sdfr
820178825Sdfr    return 0;
821178825Sdfr}
822178825Sdfr
823178825Sdfrstatic int
824178825Sdfrtest_heim_int_format(void)
825178825Sdfr{
826178825Sdfr    heim_integer i = { 1, "\x10", 0 };
827178825Sdfr    heim_integer i2 = { 1, "\x10", 1 };
828178825Sdfr    heim_integer i3 = { 1, "\01", 0 };
829178825Sdfr    char *p =
830178825Sdfr	"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
831178825Sdfr	"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
832178825Sdfr	"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
833178825Sdfr	"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
834178825Sdfr	"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
835178825Sdfr	"FFFFFFFF" "FFFFFFFF";
836178825Sdfr    heim_integer bni = {
837233294Sstas	128,
838178825Sdfr	"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC9\x0F\xDA\xA2"
839178825Sdfr	"\x21\x68\xC2\x34\xC4\xC6\x62\x8B\x80\xDC\x1C\xD1"
840178825Sdfr	"\x29\x02\x4E\x08\x8A\x67\xCC\x74\x02\x0B\xBE\xA6"
841178825Sdfr	"\x3B\x13\x9B\x22\x51\x4A\x08\x79\x8E\x34\x04\xDD"
842178825Sdfr	"\xEF\x95\x19\xB3\xCD\x3A\x43\x1B\x30\x2B\x0A\x6D"
843178825Sdfr	"\xF2\x5F\x14\x37\x4F\xE1\x35\x6D\x6D\x51\xC2\x45"
844178825Sdfr	"\xE4\x85\xB5\x76\x62\x5E\x7E\xC6\xF4\x4C\x42\xE9"
845178825Sdfr	"\xA6\x37\xED\x6B\x0B\xFF\x5C\xB6\xF4\x06\xB7\xED"
846178825Sdfr	"\xEE\x38\x6B\xFB\x5A\x89\x9F\xA5\xAE\x9F\x24\x11"
847178825Sdfr	"\x7C\x4B\x1F\xE6\x49\x28\x66\x51\xEC\xE6\x53\x81"
848178825Sdfr	"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
849178825Sdfr	0
850178825Sdfr    };
851178825Sdfr    heim_integer f;
852178825Sdfr    int ret = 0;
853178825Sdfr
854178825Sdfr    ret += check_heim_integer_same(p, p, &bni);
855178825Sdfr    ret += check_heim_integer_same("10", "10", &i);
856178825Sdfr    ret += check_heim_integer_same("00000010", "10", &i);
857178825Sdfr    ret += check_heim_integer_same("-10", "-10", &i2);
858178825Sdfr    ret += check_heim_integer_same("-00000010", "-10", &i2);
859178825Sdfr    ret += check_heim_integer_same("01", "01", &i3);
860178825Sdfr    ret += check_heim_integer_same("1", "01", &i3);
861178825Sdfr
862178825Sdfr    {
863178825Sdfr	int r;
864178825Sdfr	r = der_parse_hex_heim_integer("-", &f);
865178825Sdfr	if (r == 0) {
866178825Sdfr	    der_free_heim_integer(&f);
867178825Sdfr	    ret++;
868178825Sdfr	}
869178825Sdfr	/* used to cause UMR */
870178825Sdfr	r = der_parse_hex_heim_integer("00", &f);
871178825Sdfr	if (r == 0)
872178825Sdfr	    der_free_heim_integer(&f);
873178825Sdfr	else
874178825Sdfr	    ret++;
875178825Sdfr    }
876178825Sdfr
877178825Sdfr    return ret;
878178825Sdfr}
879178825Sdfr
880178825Sdfrstatic int
881178825Sdfrtest_heim_oid_format_same(const char *str, const heim_oid *oid)
882178825Sdfr{
883178825Sdfr    int ret;
884178825Sdfr    char *p;
885178825Sdfr    heim_oid o2;
886178825Sdfr
887178825Sdfr    ret = der_print_heim_oid(oid, ' ', &p);
888178825Sdfr    if (ret) {
889178825Sdfr	printf("fail to print oid: %s\n", str);
890178825Sdfr	return 1;
891178825Sdfr    }
892178825Sdfr    ret = strcmp(p, str);
893178825Sdfr    if (ret) {
894178825Sdfr	printf("oid %s != formated oid %s\n", str, p);
895178825Sdfr	free(p);
896178825Sdfr	return ret;
897178825Sdfr    }
898178825Sdfr
899178825Sdfr    ret = der_parse_heim_oid(p, " ", &o2);
900178825Sdfr    if (ret) {
901178825Sdfr	printf("failed to parse %s\n", p);
902178825Sdfr	free(p);
903178825Sdfr	return ret;
904178825Sdfr    }
905178825Sdfr    free(p);
906178825Sdfr    ret = der_heim_oid_cmp(&o2, oid);
907178825Sdfr    der_free_oid(&o2);
908178825Sdfr
909178825Sdfr    return ret;
910178825Sdfr}
911178825Sdfr
912178825Sdfrstatic unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
913178825Sdfr
914178825Sdfrstatic int
915178825Sdfrtest_heim_oid_format(void)
916178825Sdfr{
917178825Sdfr    heim_oid sha1 = { 6, sha1_oid_tree };
918178825Sdfr    int ret = 0;
919178825Sdfr
920178825Sdfr    ret += test_heim_oid_format_same("1 3 14 3 2 26", &sha1);
921178825Sdfr
922178825Sdfr    return ret;
923178825Sdfr}
924178825Sdfr
925178825Sdfrstatic int
926178825Sdfrcheck_trailing_nul(void)
927178825Sdfr{
928178825Sdfr    int i, ret;
929178825Sdfr    struct {
930178825Sdfr	int fail;
931178825Sdfr	const unsigned char *p;
932178825Sdfr	size_t len;
933178825Sdfr	const char *s;
934178825Sdfr	size_t size;
935178825Sdfr    } foo[] = {
936178825Sdfr	{ 1, (const unsigned char *)"foo\x00o", 5, NULL, 0 },
937178825Sdfr	{ 1, (const unsigned char *)"\x00o", 2, NULL, 0 },
938178825Sdfr	{ 0, (const unsigned char *)"\x00\x00\x00\x00\x00", 5, "", 5 },
939178825Sdfr	{ 0, (const unsigned char *)"\x00", 1, "", 1 },
940178825Sdfr	{ 0, (const unsigned char *)"", 0, "", 0 },
941178825Sdfr	{ 0, (const unsigned char *)"foo\x00\x00", 5, "foo", 5 },
942178825Sdfr	{ 0, (const unsigned char *)"foo\0", 4, "foo", 4 },
943178825Sdfr	{ 0, (const unsigned char *)"foo", 3, "foo", 3 }
944178825Sdfr    };
945233294Sstas
946178825Sdfr    for (i = 0; i < sizeof(foo)/sizeof(foo[0]); i++) {
947178825Sdfr	char *s;
948178825Sdfr	size_t size;
949178825Sdfr	ret = der_get_general_string(foo[i].p, foo[i].len, &s, &size);
950178825Sdfr	if (foo[i].fail) {
951178825Sdfr	    if (ret == 0)
952178825Sdfr		errx(1, "check %d NULL didn't fail", i);
953178825Sdfr	    continue;
954178825Sdfr	}
955178825Sdfr	if (ret)
956178825Sdfr	    errx(1, "NULL check %d der_get_general_string failed", i);
957178825Sdfr	if (foo[i].size != size)
958178825Sdfr	    errx(1, "NUL check i = %d size failed", i);
959178825Sdfr	if (strcmp(foo[i].s, s) != 0)
960178825Sdfr	    errx(1, "NUL check i = %d content failed", i);
961178825Sdfr	free(s);
962178825Sdfr    }
963178825Sdfr    return 0;
964178825Sdfr}
965178825Sdfr
966178825Sdfrstatic int
967178825Sdfrtest_misc_cmp(void)
968178825Sdfr{
969178825Sdfr    int ret;
970178825Sdfr
971178825Sdfr    /* diffrent lengths are diffrent */
972178825Sdfr    {
973178825Sdfr	const heim_octet_string os1 = { 1, "a" } , os2 = { 0, NULL };
974178825Sdfr	ret = der_heim_octet_string_cmp(&os1, &os2);
975178825Sdfr	if (ret == 0)
976178825Sdfr	    return 1;
977178825Sdfr    }
978178825Sdfr    /* diffrent data are diffrent */
979178825Sdfr    {
980178825Sdfr	const heim_octet_string os1 = { 1, "a" } , os2 = { 1, "b" };
981178825Sdfr	ret = der_heim_octet_string_cmp(&os1, &os2);
982178825Sdfr	if (ret == 0)
983178825Sdfr	    return 1;
984178825Sdfr    }
985178825Sdfr    /* diffrent lengths are diffrent */
986178825Sdfr    {
987178825Sdfr	const heim_bit_string bs1 = { 8, "a" } , bs2 = { 7, "a" };
988178825Sdfr	ret = der_heim_bit_string_cmp(&bs1, &bs2);
989178825Sdfr	if (ret == 0)
990178825Sdfr	    return 1;
991178825Sdfr    }
992178825Sdfr    /* diffrent data are diffrent */
993178825Sdfr    {
994178825Sdfr	const heim_bit_string bs1 = { 7, "\x0f" } , bs2 = { 7, "\x02" };
995178825Sdfr	ret = der_heim_bit_string_cmp(&bs1, &bs2);
996178825Sdfr	if (ret == 0)
997178825Sdfr	    return 1;
998178825Sdfr    }
999178825Sdfr    /* diffrent lengths are diffrent */
1000178825Sdfr    {
1001178825Sdfr	uint16_t data = 1;
1002178825Sdfr	heim_bmp_string bs1 = { 1, NULL } , bs2 = { 0, NULL };
1003178825Sdfr	bs1.data = &data;
1004178825Sdfr	ret = der_heim_bmp_string_cmp(&bs1, &bs2);
1005178825Sdfr	if (ret == 0)
1006178825Sdfr	    return 1;
1007178825Sdfr    }
1008178825Sdfr    /* diffrent lengths are diffrent */
1009178825Sdfr    {
1010178825Sdfr	uint32_t data;
1011178825Sdfr	heim_universal_string us1 = { 1, NULL } , us2 = { 0, NULL };
1012178825Sdfr	us1.data = &data;
1013178825Sdfr	ret = der_heim_universal_string_cmp(&us1, &us2);
1014178825Sdfr	if (ret == 0)
1015178825Sdfr	    return 1;
1016178825Sdfr    }
1017178825Sdfr    /* same */
1018178825Sdfr    {
1019178825Sdfr	uint32_t data = (uint32_t)'a';
1020178825Sdfr	heim_universal_string us1 = { 1, NULL } , us2 = { 1, NULL };
1021178825Sdfr	us1.data = &data;
1022178825Sdfr	us2.data = &data;
1023178825Sdfr	ret = der_heim_universal_string_cmp(&us1, &us2);
1024178825Sdfr	if (ret != 0)
1025178825Sdfr	    return 1;
1026178825Sdfr    }
1027178825Sdfr
1028178825Sdfr    return 0;
1029178825Sdfr}
1030178825Sdfr
1031178825Sdfrstatic int
1032178825Sdfrcorner_generalized_time(void)
1033178825Sdfr{
1034178825Sdfr    const char *str = "760520140000Z";
1035178825Sdfr    size_t size;
1036178825Sdfr    time_t t;
1037178825Sdfr    int ret;
1038178825Sdfr
1039178825Sdfr    ret = der_get_generalized_time((const unsigned char*)str, strlen(str),
1040178825Sdfr				   &t, &size);
1041178825Sdfr    if (ret)
1042178825Sdfr	return 1;
1043178825Sdfr    return 0;
1044178825Sdfr}
1045178825Sdfr
1046178825Sdfrstatic int
1047178825Sdfrcorner_tag(void)
1048178825Sdfr{
1049178825Sdfr    struct {
1050178825Sdfr	int ok;
1051178825Sdfr	const char *ptr;
1052178825Sdfr	size_t len;
1053233294Sstas    } tests[] = {
1054178825Sdfr	{ 1, "\x00", 1 },
1055178825Sdfr	{ 0, "\xff", 1 },
1056178825Sdfr	{ 0, "\xff\xff\xff\xff\xff\xff\xff\xff", 8 }
1057178825Sdfr    };
1058178825Sdfr    int i, ret;
1059178825Sdfr    Der_class cl;
1060178825Sdfr    Der_type ty;
1061178825Sdfr    unsigned int tag;
1062178825Sdfr    size_t size;
1063178825Sdfr
1064178825Sdfr    for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
1065233294Sstas	ret = der_get_tag((const unsigned char*)tests[i].ptr,
1066178825Sdfr			  tests[i].len, &cl, &ty, &tag, &size);
1067178825Sdfr	if (ret) {
1068178825Sdfr	    if (tests[i].ok)
1069178825Sdfr		errx(1, "failed while shouldn't");
1070178825Sdfr	} else {
1071178825Sdfr	    if (!tests[i].ok)
1072178825Sdfr		errx(1, "passed while shouldn't");
1073178825Sdfr	}
1074178825Sdfr    }
1075178825Sdfr    return 0;
1076178825Sdfr}
1077178825Sdfr
107855682Smarkmint
107955682Smarkmmain(int argc, char **argv)
108055682Smarkm{
108155682Smarkm    int ret = 0;
108255682Smarkm
108355682Smarkm    ret += test_integer ();
1084178825Sdfr    ret += test_integer_more();
1085178825Sdfr    ret += test_unsigned ();
108655682Smarkm    ret += test_octet_string ();
1087178825Sdfr    ret += test_bmp_string ();
1088178825Sdfr    ret += test_universal_string ();
108955682Smarkm    ret += test_general_string ();
109055682Smarkm    ret += test_generalized_time ();
1091178825Sdfr    ret += test_oid ();
1092178825Sdfr    ret += test_bit_string();
1093178825Sdfr    ret += test_heim_integer();
1094178825Sdfr    ret += test_boolean();
109555682Smarkm
1096178825Sdfr    ret += check_fail_unsigned();
1097178825Sdfr    ret += check_fail_integer();
1098178825Sdfr    ret += check_fail_length();
1099178825Sdfr    ret += check_fail_boolean();
1100178825Sdfr    ret += check_fail_general_string();
1101178825Sdfr    ret += check_fail_bmp_string();
1102178825Sdfr    ret += check_fail_universal_string();
1103178825Sdfr    ret += check_fail_heim_integer();
1104178825Sdfr    ret += check_fail_generalized_time();
1105178825Sdfr    ret += check_fail_oid();
1106178825Sdfr    ret += check_fail_bitstring();
1107178825Sdfr    ret += test_heim_int_format();
1108178825Sdfr    ret += test_heim_oid_format();
1109178825Sdfr    ret += check_trailing_nul();
1110178825Sdfr    ret += test_misc_cmp();
1111178825Sdfr    ret += corner_generalized_time();
1112178825Sdfr    ret += corner_tag();
1113178825Sdfr
111455682Smarkm    return ret;
111555682Smarkm}
1116