1/*
2 * Copyright (c) 1999 - 2005 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 <config.h>
37#include <stdio.h>
38#include <string.h>
39#include <err.h>
40#include <roken.h>
41
42#include <asn1-common.h>
43#include <asn1_err.h>
44#include <der.h>
45#include <krb5_asn1.h>
46#include <heim_asn1.h>
47#include <rfc2459_asn1.h>
48#include <test_asn1.h>
49#include <cms_asn1.h>
50
51#include "check-common.h"
52
53static char *lha_principal[] = { "lha" };
54static char *lharoot_princ[] = { "lha", "root" };
55static char *datan_princ[] = { "host", "nutcracker.e.kth.se" };
56static char *nada_tgt_principal[] = { "krbtgt", "NADA.KTH.SE" };
57
58
59#define IF_OPT_COMPARE(ac,bc,e) \
60	if (((ac)->e == NULL && (bc)->e != NULL) || (((ac)->e != NULL && (bc)->e == NULL))) return 1; if ((ab)->e)
61#define COMPARE_OPT_STRING(ac,bc,e) \
62	do { if (strcmp(*(ac)->e, *(bc)->e) != 0) return 1; } while(0)
63#define COMPARE_OPT_OCTECT_STRING(ac,bc,e) \
64	do { if ((ac)->e->length != (bc)->e->length || memcmp((ac)->e->data, (bc)->e->data, (ac)->e->length) != 0) return 1; } while(0)
65#define COMPARE_STRING(ac,bc,e) \
66	do { if (strcmp((ac)->e, (bc)->e) != 0) return 1; } while(0)
67#define COMPARE_INTEGER(ac,bc,e) \
68	do { if ((ac)->e != (bc)->e) return 1; } while(0)
69#define COMPARE_OPT_INTEGER(ac,bc,e) \
70	do { if (*(ac)->e != *(bc)->e) return 1; } while(0)
71#define COMPARE_MEM(ac,bc,e,len) \
72	do { if (memcmp((ac)->e, (bc)->e,len) != 0) return 1; } while(0)
73
74static int
75cmp_principal (void *a, void *b)
76{
77    Principal *pa = a;
78    Principal *pb = b;
79    unsigned i;
80
81    COMPARE_STRING(pa,pb,realm);
82    COMPARE_INTEGER(pa,pb,name.name_type);
83    COMPARE_INTEGER(pa,pb,name.name_string.len);
84
85    for (i = 0; i < pa->name.name_string.len; i++)
86	COMPARE_STRING(pa,pb,name.name_string.val[i]);
87
88    return 0;
89}
90
91static int
92test_principal (void)
93{
94
95    struct test_case tests[] = {
96	{ NULL, 29,
97	  "\x30\x1b\xa0\x10\x30\x0e\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b"
98	  "\x03\x6c\x68\x61\xa1\x07\x1b\x05\x53\x55\x2e\x53\x45"
99	},
100	{ NULL, 35,
101	  "\x30\x21\xa0\x16\x30\x14\xa0\x03\x02\x01\x01\xa1\x0d\x30\x0b\x1b"
102	  "\x03\x6c\x68\x61\x1b\x04\x72\x6f\x6f\x74\xa1\x07\x1b\x05\x53\x55"
103	  "\x2e\x53\x45"
104	},
105	{ NULL, 54,
106	  "\x30\x34\xa0\x26\x30\x24\xa0\x03\x02\x01\x03\xa1\x1d\x30\x1b\x1b"
107	  "\x04\x68\x6f\x73\x74\x1b\x13\x6e\x75\x74\x63\x72\x61\x63\x6b\x65"
108	  "\x72\x2e\x65\x2e\x6b\x74\x68\x2e\x73\x65\xa1\x0a\x1b\x08\x45\x2e"
109	  "\x4b\x54\x48\x2e\x53\x45"
110	}
111    };
112
113
114    Principal values[] = {
115	{ { KRB5_NT_PRINCIPAL, { 1, lha_principal } },  "SU.SE" },
116	{ { KRB5_NT_PRINCIPAL, { 2, lharoot_princ } },  "SU.SE" },
117	{ { KRB5_NT_SRV_HST, { 2, datan_princ } },  "E.KTH.SE" }
118    };
119    int i, ret;
120    int ntests = sizeof(tests) / sizeof(*tests);
121
122    for (i = 0; i < ntests; ++i) {
123	tests[i].val = &values[i];
124	if (asprintf (&tests[i].name, "Principal %d", i) < 0)
125	    errx(1, "malloc");
126	if (tests[i].name == NULL)
127	    errx(1, "malloc");
128    }
129
130    ret = generic_test (tests, ntests, sizeof(Principal),
131			(generic_encode)encode_Principal,
132			(generic_length)length_Principal,
133			(generic_decode)decode_Principal,
134			(generic_free)free_Principal,
135			cmp_principal,
136			NULL);
137    for (i = 0; i < ntests; ++i)
138	free (tests[i].name);
139
140    return ret;
141}
142
143static int
144cmp_authenticator (void *a, void *b)
145{
146    Authenticator *aa = a;
147    Authenticator *ab = b;
148    unsigned i;
149
150    COMPARE_INTEGER(aa,ab,authenticator_vno);
151    COMPARE_STRING(aa,ab,crealm);
152
153    COMPARE_INTEGER(aa,ab,cname.name_type);
154    COMPARE_INTEGER(aa,ab,cname.name_string.len);
155
156    for (i = 0; i < aa->cname.name_string.len; i++)
157	COMPARE_STRING(aa,ab,cname.name_string.val[i]);
158
159    return 0;
160}
161
162static int
163test_authenticator (void)
164{
165    struct test_case tests[] = {
166	{ NULL, 63,
167	  "\x62\x3d\x30\x3b\xa0\x03\x02\x01\x05\xa1\x0a\x1b\x08"
168	  "\x45\x2e\x4b\x54\x48\x2e\x53\x45\xa2\x10\x30\x0e\xa0"
169	  "\x03\x02\x01\x01\xa1\x07\x30\x05\x1b\x03\x6c\x68\x61"
170	  "\xa4\x03\x02\x01\x0a\xa5\x11\x18\x0f\x31\x39\x37\x30"
171	  "\x30\x31\x30\x31\x30\x30\x30\x31\x33\x39\x5a"
172	},
173	{ NULL, 67,
174	  "\x62\x41\x30\x3f\xa0\x03\x02\x01\x05\xa1\x07\x1b\x05"
175	  "\x53\x55\x2e\x53\x45\xa2\x16\x30\x14\xa0\x03\x02\x01"
176	  "\x01\xa1\x0d\x30\x0b\x1b\x03\x6c\x68\x61\x1b\x04\x72"
177	  "\x6f\x6f\x74\xa4\x04\x02\x02\x01\x24\xa5\x11\x18\x0f"
178	  "\x31\x39\x37\x30\x30\x31\x30\x31\x30\x30\x31\x36\x33"
179	  "\x39\x5a"
180	}
181    };
182
183    Authenticator values[] = {
184	{ 5, "E.KTH.SE", { KRB5_NT_PRINCIPAL, { 1, lha_principal } },
185	  NULL, 10, 99, NULL, NULL, NULL },
186	{ 5, "SU.SE", { KRB5_NT_PRINCIPAL, { 2, lharoot_princ } },
187	  NULL, 292, 999, NULL, NULL, NULL }
188    };
189    int i, ret;
190    int ntests = sizeof(tests) / sizeof(*tests);
191
192    for (i = 0; i < ntests; ++i) {
193	tests[i].val = &values[i];
194	if (asprintf (&tests[i].name, "Authenticator %d", i) < 0)
195	    errx(1, "malloc");
196	if (tests[i].name == NULL)
197	    errx(1, "malloc");
198    }
199
200    ret = generic_test (tests, ntests, sizeof(Authenticator),
201			(generic_encode)encode_Authenticator,
202			(generic_length)length_Authenticator,
203			(generic_decode)decode_Authenticator,
204			(generic_free)free_Authenticator,
205			cmp_authenticator,
206			(generic_copy)copy_Authenticator);
207    for (i = 0; i < ntests; ++i)
208	free(tests[i].name);
209
210    return ret;
211}
212
213static int
214cmp_KRB_ERROR (void *a, void *b)
215{
216    KRB_ERROR *aa = a;
217    KRB_ERROR *ab = b;
218    unsigned i;
219
220    COMPARE_INTEGER(aa,ab,pvno);
221    COMPARE_INTEGER(aa,ab,msg_type);
222
223    IF_OPT_COMPARE(aa,ab,ctime) {
224	COMPARE_INTEGER(aa,ab,ctime);
225    }
226    IF_OPT_COMPARE(aa,ab,cusec) {
227	COMPARE_INTEGER(aa,ab,cusec);
228    }
229    COMPARE_INTEGER(aa,ab,stime);
230    COMPARE_INTEGER(aa,ab,susec);
231    COMPARE_INTEGER(aa,ab,error_code);
232
233    IF_OPT_COMPARE(aa,ab,crealm) {
234	COMPARE_OPT_STRING(aa,ab,crealm);
235    }
236#if 0
237    IF_OPT_COMPARE(aa,ab,cname) {
238	COMPARE_OPT_STRING(aa,ab,cname);
239    }
240#endif
241    COMPARE_STRING(aa,ab,realm);
242
243    COMPARE_INTEGER(aa,ab,sname.name_string.len);
244    for (i = 0; i < aa->sname.name_string.len; i++)
245	COMPARE_STRING(aa,ab,sname.name_string.val[i]);
246
247    IF_OPT_COMPARE(aa,ab,e_text) {
248	COMPARE_OPT_STRING(aa,ab,e_text);
249    }
250    IF_OPT_COMPARE(aa,ab,e_data) {
251	/* COMPARE_OPT_OCTECT_STRING(aa,ab,e_data); */
252    }
253
254    return 0;
255}
256
257static int
258test_krb_error (void)
259{
260    struct test_case tests[] = {
261	{ NULL, 127,
262	  "\x7e\x7d\x30\x7b\xa0\x03\x02\x01\x05\xa1\x03\x02\x01\x1e\xa4\x11"
263	  "\x18\x0f\x32\x30\x30\x33\x31\x31\x32\x34\x30\x30\x31\x31\x31\x39"
264	  "\x5a\xa5\x05\x02\x03\x04\xed\xa5\xa6\x03\x02\x01\x1f\xa7\x0d\x1b"
265	  "\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45\xa8\x10\x30\x0e"
266	  "\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b\x03\x6c\x68\x61\xa9\x0d"
267	  "\x1b\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45\xaa\x20\x30"
268	  "\x1e\xa0\x03\x02\x01\x01\xa1\x17\x30\x15\x1b\x06\x6b\x72\x62\x74"
269	  "\x67\x74\x1b\x0b\x4e\x41\x44\x41\x2e\x4b\x54\x48\x2e\x53\x45",
270	  "KRB-ERROR Test 1"
271	}
272    };
273    int ntests = sizeof(tests) / sizeof(*tests);
274    KRB_ERROR e1;
275    PrincipalName lhaprincipalname = { 1, { 1, lha_principal } };
276    PrincipalName tgtprincipalname = { 1, { 2, nada_tgt_principal } };
277    char *realm = "NADA.KTH.SE";
278
279    e1.pvno = 5;
280    e1.msg_type = 30;
281    e1.ctime = NULL;
282    e1.cusec = NULL;
283    e1.stime = 1069632679;
284    e1.susec = 322981;
285    e1.error_code = 31;
286    e1.crealm = &realm;
287    e1.cname = &lhaprincipalname;
288    e1.realm = "NADA.KTH.SE";
289    e1.sname = tgtprincipalname;
290    e1.e_text = NULL;
291    e1.e_data = NULL;
292
293    tests[0].val = &e1;
294
295    return generic_test (tests, ntests, sizeof(KRB_ERROR),
296			 (generic_encode)encode_KRB_ERROR,
297			 (generic_length)length_KRB_ERROR,
298			 (generic_decode)decode_KRB_ERROR,
299			 (generic_free)free_KRB_ERROR,
300			 cmp_KRB_ERROR,
301			 (generic_copy)copy_KRB_ERROR);
302}
303
304static int
305cmp_Name (void *a, void *b)
306{
307    Name *aa = a;
308    Name *ab = b;
309
310    COMPARE_INTEGER(aa,ab,element);
311
312    return 0;
313}
314
315static int
316test_Name (void)
317{
318    struct test_case tests[] = {
319	{ NULL, 35,
320	  "\x30\x21\x31\x1f\x30\x0b\x06\x03\x55\x04\x03\x13\x04\x4c\x6f\x76"
321	  "\x65\x30\x10\x06\x03\x55\x04\x07\x13\x09\x53\x54\x4f\x43\x4b\x48"
322	  "\x4f\x4c\x4d",
323	  "Name CN=Love+L=STOCKHOLM"
324	},
325	{ NULL, 35,
326	  "\x30\x21\x31\x1f\x30\x0b\x06\x03\x55\x04\x03\x13\x04\x4c\x6f\x76"
327	  "\x65\x30\x10\x06\x03\x55\x04\x07\x13\x09\x53\x54\x4f\x43\x4b\x48"
328	  "\x4f\x4c\x4d",
329	  "Name L=STOCKHOLM+CN=Love"
330	}
331    };
332
333    int ntests = sizeof(tests) / sizeof(*tests);
334    Name n1, n2;
335    RelativeDistinguishedName rdn1[1];
336    RelativeDistinguishedName rdn2[1];
337    AttributeTypeAndValue atv1[2];
338    AttributeTypeAndValue atv2[2];
339    unsigned cmp_CN[] = { 2, 5, 4, 3 };
340    unsigned cmp_L[] = { 2, 5, 4, 7 };
341
342    /* n1 */
343    n1.element = choice_Name_rdnSequence;
344    n1.u.rdnSequence.val = rdn1;
345    n1.u.rdnSequence.len = sizeof(rdn1)/sizeof(rdn1[0]);
346    rdn1[0].val = atv1;
347    rdn1[0].len = sizeof(atv1)/sizeof(atv1[0]);
348
349    atv1[0].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
350    atv1[0].type.components = cmp_CN;
351    atv1[0].value.element = choice_DirectoryString_printableString;
352    atv1[0].value.u.printableString.data = "Love";
353    atv1[0].value.u.printableString.length = 4;
354
355    atv1[1].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
356    atv1[1].type.components = cmp_L;
357    atv1[1].value.element = choice_DirectoryString_printableString;
358    atv1[1].value.u.printableString.data = "STOCKHOLM";
359    atv1[1].value.u.printableString.length = 9;
360
361    /* n2 */
362    n2.element = choice_Name_rdnSequence;
363    n2.u.rdnSequence.val = rdn2;
364    n2.u.rdnSequence.len = sizeof(rdn2)/sizeof(rdn2[0]);
365    rdn2[0].val = atv2;
366    rdn2[0].len = sizeof(atv2)/sizeof(atv2[0]);
367
368    atv2[0].type.length = sizeof(cmp_L)/sizeof(cmp_L[0]);
369    atv2[0].type.components = cmp_L;
370    atv2[0].value.element = choice_DirectoryString_printableString;
371    atv2[0].value.u.printableString.data = "STOCKHOLM";
372    atv2[0].value.u.printableString.length = 9;
373
374    atv2[1].type.length = sizeof(cmp_CN)/sizeof(cmp_CN[0]);
375    atv2[1].type.components = cmp_CN;
376    atv2[1].value.element = choice_DirectoryString_printableString;
377    atv2[1].value.u.printableString.data = "Love";
378    atv2[1].value.u.printableString.length = 4;
379
380    /* */
381    tests[0].val = &n1;
382    tests[1].val = &n2;
383
384    return generic_test (tests, ntests, sizeof(Name),
385			 (generic_encode)encode_Name,
386			 (generic_length)length_Name,
387			 (generic_decode)decode_Name,
388			 (generic_free)free_Name,
389			 cmp_Name,
390			 (generic_copy)copy_Name);
391}
392
393static int
394cmp_KeyUsage (void *a, void *b)
395{
396    KeyUsage *aa = a;
397    KeyUsage *ab = b;
398
399    return KeyUsage2int(*aa) != KeyUsage2int(*ab);
400}
401
402static int
403test_bit_string (void)
404{
405    struct test_case tests[] = {
406	{ NULL, 4,
407	  "\x03\x02\x07\x80",
408	  "bitstring 1"
409	},
410	{ NULL, 4,
411	  "\x03\x02\x05\xa0",
412	  "bitstring 2"
413	},
414	{ NULL, 5,
415	  "\x03\x03\x07\x00\x80",
416	  "bitstring 3"
417	},
418	{ NULL, 3,
419	  "\x03\x01\x00",
420	  "bitstring 4"
421	}
422    };
423
424    int ntests = sizeof(tests) / sizeof(*tests);
425    KeyUsage ku1, ku2, ku3, ku4;
426
427    memset(&ku1, 0, sizeof(ku1));
428    ku1.digitalSignature = 1;
429    tests[0].val = &ku1;
430
431    memset(&ku2, 0, sizeof(ku2));
432    ku2.digitalSignature = 1;
433    ku2.keyEncipherment = 1;
434    tests[1].val = &ku2;
435
436    memset(&ku3, 0, sizeof(ku3));
437    ku3.decipherOnly = 1;
438    tests[2].val = &ku3;
439
440    memset(&ku4, 0, sizeof(ku4));
441    tests[3].val = &ku4;
442
443
444    return generic_test (tests, ntests, sizeof(KeyUsage),
445			 (generic_encode)encode_KeyUsage,
446			 (generic_length)length_KeyUsage,
447			 (generic_decode)decode_KeyUsage,
448			 (generic_free)free_KeyUsage,
449			 cmp_KeyUsage,
450			 (generic_copy)copy_KeyUsage);
451}
452
453static int
454cmp_TicketFlags (void *a, void *b)
455{
456    TicketFlags *aa = a;
457    TicketFlags *ab = b;
458
459    return TicketFlags2int(*aa) != TicketFlags2int(*ab);
460}
461
462static int
463test_bit_string_rfc1510 (void)
464{
465    struct test_case tests[] = {
466	{ NULL, 7,
467	  "\x03\x05\x00\x80\x00\x00\x00",
468	  "TF bitstring 1"
469	},
470	{ NULL, 7,
471	  "\x03\x05\x00\x40\x20\x00\x00",
472	  "TF bitstring 2"
473	},
474	{ NULL, 7,
475	  "\x03\x05\x00\x00\x20\x00\x00",
476	  "TF bitstring 3"
477	},
478	{ NULL, 7,
479	  "\x03\x05\x00\x00\x00\x00\x00",
480	  "TF bitstring 4"
481	}
482    };
483
484    int ntests = sizeof(tests) / sizeof(*tests);
485    TicketFlags tf1, tf2, tf3, tf4;
486
487    memset(&tf1, 0, sizeof(tf1));
488    tf1.reserved = 1;
489    tests[0].val = &tf1;
490
491    memset(&tf2, 0, sizeof(tf2));
492    tf2.forwardable = 1;
493    tf2.pre_authent = 1;
494    tests[1].val = &tf2;
495
496    memset(&tf3, 0, sizeof(tf3));
497    tf3.pre_authent = 1;
498    tests[2].val = &tf3;
499
500    memset(&tf4, 0, sizeof(tf4));
501    tests[3].val = &tf4;
502
503
504    return generic_test (tests, ntests, sizeof(TicketFlags),
505			 (generic_encode)encode_TicketFlags,
506			 (generic_length)length_TicketFlags,
507			 (generic_decode)decode_TicketFlags,
508			 (generic_free)free_TicketFlags,
509			 cmp_TicketFlags,
510			 (generic_copy)copy_TicketFlags);
511}
512
513static int
514cmp_KerberosTime (void *a, void *b)
515{
516    KerberosTime *aa = a;
517    KerberosTime *ab = b;
518
519    return *aa != *ab;
520}
521
522static int
523test_time (void)
524{
525    struct test_case tests[] = {
526	{ NULL,  17,
527	  "\x18\x0f\x31\x39\x37\x30\x30\x31\x30\x31\x30\x31\x31\x38\x33\x31"
528	  "\x5a",
529	  "time 1" },
530	{ NULL,  17,
531	  "\x18\x0f\x32\x30\x30\x39\x30\x35\x32\x34\x30\x32\x30\x32\x34\x30"
532	  "\x5a"
533	  "time 2" }
534    };
535
536    int ntests = sizeof(tests) / sizeof(*tests);
537    KerberosTime times[] = {
538	4711,
539	1243130560
540    };
541
542    tests[0].val = &times[0];
543    tests[1].val = &times[1];
544
545    return generic_test (tests, ntests, sizeof(KerberosTime),
546			 (generic_encode)encode_KerberosTime,
547			 (generic_length)length_KerberosTime,
548			 (generic_decode)decode_KerberosTime,
549			 (generic_free)free_KerberosTime,
550			 cmp_KerberosTime,
551			 (generic_copy)copy_KerberosTime);
552}
553
554struct {
555    const char *cert;
556    size_t len;
557} certs[] = {
558    {
559	"\x30\x82\x02\x6c\x30\x82\x01\xd5\xa0\x03\x02\x01\x02\x02\x09\x00"
560	"\x99\x32\xde\x61\x0e\x40\x19\x8a\x30\x0d\x06\x09\x2a\x86\x48\x86"
561	"\xf7\x0d\x01\x01\x05\x05\x00\x30\x2a\x31\x1b\x30\x19\x06\x03\x55"
562	"\x04\x03\x0c\x12\x68\x78\x35\x30\x39\x20\x54\x65\x73\x74\x20\x52"
563	"\x6f\x6f\x74\x20\x43\x41\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
564	"\x02\x53\x45\x30\x1e\x17\x0d\x30\x39\x30\x34\x32\x36\x32\x30\x32"
565	"\x39\x34\x30\x5a\x17\x0d\x31\x39\x30\x34\x32\x34\x32\x30\x32\x39"
566	"\x34\x30\x5a\x30\x2a\x31\x1b\x30\x19\x06\x03\x55\x04\x03\x0c\x12"
567	"\x68\x78\x35\x30\x39\x20\x54\x65\x73\x74\x20\x52\x6f\x6f\x74\x20"
568	"\x43\x41\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x53\x45\x30"
569	"\x81\x9f\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05"
570	"\x00\x03\x81\x8d\x00\x30\x81\x89\x02\x81\x81\x00\xb9\xd3\x1b\x67"
571	"\x1c\xf7\x5e\x26\x81\x3b\x82\xff\x03\xa4\x43\xb5\xb2\x63\x0b\x89"
572	"\x58\x43\xfe\x3d\xe0\x38\x7d\x93\x74\xbb\xad\x21\xa4\x29\xd9\x34"
573	"\x79\xf3\x1c\x8c\x5a\xd6\xb0\xd7\x19\xea\xcc\xaf\xe0\xa8\x40\x02"
574	"\x1d\x91\xf1\xac\x36\xb0\xfb\x08\xbd\xcc\x9a\xe1\xb7\x6e\xee\x0a"
575	"\x69\xbf\x6d\x2b\xee\x20\x82\x61\x06\xf2\x18\xcc\x89\x11\x64\x7e"
576	"\xb2\xff\x47\xd1\x3b\x52\x73\xeb\x5a\xc0\x03\xa6\x4b\xc7\x40\x7e"
577	"\xbc\xe1\x0e\x65\x44\x3f\x40\x8b\x02\x82\x54\x04\xd9\xcc\x2c\x67"
578	"\x01\xb6\x16\x82\xd8\x33\x53\x17\xd7\xde\x8d\x5d\x02\x03\x01\x00"
579	"\x01\xa3\x81\x99\x30\x81\x96\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16"
580	"\x04\x14\x6e\x48\x13\xdc\xbf\x8b\x95\x4c\x13\xf3\x1f\x97\x30\xdd"
581	"\x27\x96\x59\x9b\x0e\x68\x30\x5a\x06\x03\x55\x1d\x23\x04\x53\x30"
582	"\x51\x80\x14\x6e\x48\x13\xdc\xbf\x8b\x95\x4c\x13\xf3\x1f\x97\x30"
583	"\xdd\x27\x96\x59\x9b\x0e\x68\xa1\x2e\xa4\x2c\x30\x2a\x31\x1b\x30"
584	"\x19\x06\x03\x55\x04\x03\x0c\x12\x68\x78\x35\x30\x39\x20\x54\x65"
585	"\x73\x74\x20\x52\x6f\x6f\x74\x20\x43\x41\x31\x0b\x30\x09\x06\x03"
586	"\x55\x04\x06\x13\x02\x53\x45\x82\x09\x00\x99\x32\xde\x61\x0e\x40"
587	"\x19\x8a\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff"
588	"\x30\x0b\x06\x03\x55\x1d\x0f\x04\x04\x03\x02\x01\xe6\x30\x0d\x06"
589	"\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x03\x81\x81\x00"
590	"\x52\x9b\xe4\x0e\xee\xc2\x5d\xb7\xf1\xba\x47\xe3\xfe\xaf\x3d\x51"
591	"\x10\xfd\xe8\x0d\x14\x58\x05\x36\xa7\xeb\xd8\x05\xe5\x27\x6f\x51"
592	"\xb8\xec\x90\xd9\x03\xe1\xbc\x9c\x93\x38\x21\x5c\xaf\x4e\x6c\x7b"
593	"\x6c\x65\xa9\x92\xcd\x94\xef\xa8\xae\x90\x12\x14\x78\x2d\xa3\x15"
594	"\xaa\x42\xf1\xd9\x44\x64\x2c\x3c\xc0\xbd\x3a\x48\xd8\x80\x45\x8b"
595	"\xd1\x79\x82\xe0\x0f\xdf\x08\x3c\x60\x21\x6f\x31\x47\x98\xae\x2f"
596	"\xcb\xb1\xa1\xb9\xc1\xa3\x71\x5e\x4a\xc2\x67\xdf\x66\x0a\x51\xb5"
597	"\xad\x60\x05\xdb\x02\xd4\x1a\xd2\xb9\x4e\x01\x08\x2b\xc3\x57\xaf",
598	624 },
599    {
600	"\x30\x82\x02\x54\x30\x82\x01\xbd\xa0\x03\x02\x01\x02\x02\x01\x08"
601	"\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x30"
602	"\x2a\x31\x1b\x30\x19\x06\x03\x55\x04\x03\x0c\x12\x68\x78\x35\x30"
603	"\x39\x20\x54\x65\x73\x74\x20\x52\x6f\x6f\x74\x20\x43\x41\x31\x0b"
604	"\x30\x09\x06\x03\x55\x04\x06\x13\x02\x53\x45\x30\x1e\x17\x0d\x30"
605	"\x39\x30\x34\x32\x36\x32\x30\x32\x39\x34\x30\x5a\x17\x0d\x31\x39"
606	"\x30\x34\x32\x34\x32\x30\x32\x39\x34\x30\x5a\x30\x1b\x31\x0b\x30"
607	"\x09\x06\x03\x55\x04\x06\x13\x02\x53\x45\x31\x0c\x30\x0a\x06\x03"
608	"\x55\x04\x03\x0c\x03\x6b\x64\x63\x30\x81\x9f\x30\x0d\x06\x09\x2a"
609	"\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00\x30\x81"
610	"\x89\x02\x81\x81\x00\xd2\x41\x7a\xf8\x4b\x55\xb2\xaf\x11\xf9\x43"
611	"\x9b\x43\x81\x09\x3b\x9a\x94\xcf\x00\xf4\x85\x75\x92\xd7\x2a\xa5"
612	"\x11\xf1\xa8\x50\x6e\xc6\x84\x74\x24\x17\xda\x84\xc8\x03\x37\xb2"
613	"\x20\xf3\xba\xb5\x59\x36\x21\x4d\xab\x70\xe2\xc3\x09\x93\x68\x14"
614	"\x12\x79\xc5\xbb\x9e\x1b\x4a\xf0\xc6\x24\x59\x25\xc3\x1c\xa8\x70"
615	"\x66\x5b\x3e\x41\x8e\xe3\x25\x71\x9a\x94\xa0\x5b\x46\x91\x6f\xdd"
616	"\x58\x14\xec\x89\xe5\x8c\x96\xc5\x38\x60\xe4\xab\xf2\x75\xee\x6e"
617	"\x62\xfc\xe1\xbd\x03\x47\xff\xc4\xbe\x0f\xca\x70\x73\xe3\x74\x58"
618	"\x3a\x2f\x04\x2d\x39\x02\x03\x01\x00\x01\xa3\x81\x98\x30\x81\x95"
619	"\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55"
620	"\x1d\x0f\x04\x04\x03\x02\x05\xe0\x30\x12\x06\x03\x55\x1d\x25\x04"
621	"\x0b\x30\x09\x06\x07\x2b\x06\x01\x05\x02\x03\x05\x30\x1d\x06\x03"
622	"\x55\x1d\x0e\x04\x16\x04\x14\x3a\xd3\x73\xff\xab\xdb\x7d\x8d\xc6"
623	"\x3a\xa2\x26\x3e\xae\x78\x95\x80\xc9\xe6\x31\x30\x48\x06\x03\x55"
624	"\x1d\x11\x04\x41\x30\x3f\xa0\x3d\x06\x06\x2b\x06\x01\x05\x02\x02"
625	"\xa0\x33\x30\x31\xa0\x0d\x1b\x0b\x54\x45\x53\x54\x2e\x48\x35\x4c"
626	"\x2e\x53\x45\xa1\x20\x30\x1e\xa0\x03\x02\x01\x01\xa1\x17\x30\x15"
627	"\x1b\x06\x6b\x72\x62\x74\x67\x74\x1b\x0b\x54\x45\x53\x54\x2e\x48"
628	"\x35\x4c\x2e\x53\x45\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01"
629	"\x01\x05\x05\x00\x03\x81\x81\x00\x83\xf4\x14\xa7\x6e\x59\xff\x80"
630	"\x64\xe7\xfa\xcf\x13\x80\x86\xe1\xed\x02\x38\xad\x96\x72\x25\xe5"
631	"\x06\x7a\x9a\xbc\x24\x74\xa9\x75\x55\xb2\x49\x80\x69\x45\x95\x4a"
632	"\x4c\x76\xa9\xe3\x4e\x49\xd3\xc2\x69\x5a\x95\x03\xeb\xba\x72\x23"
633	"\x9c\xfd\x3d\x8b\xc6\x07\x82\x3b\xf4\xf3\xef\x6c\x2e\x9e\x0b\xac"
634	"\x9e\x6c\xbb\x37\x4a\xa1\x9e\x73\xd1\xdc\x97\x61\xba\xfc\xd3\x49"
635	"\xa6\xc2\x4c\x55\x2e\x06\x37\x76\xb5\xef\x57\xe7\x57\x58\x8a\x71"
636	"\x63\xf3\xeb\xe7\x55\x68\x0d\xf6\x46\x4c\xfb\xf9\x43\xbb\x0c\x92"
637	"\x4f\x4e\x22\x7b\x63\xe8\x4f\x9c",
638	600
639    }
640};
641
642static int
643test_cert(void)
644{
645    Certificate c, c2;
646    size_t size;
647    size_t i;
648    int ret;
649
650    for (i = 0; i < sizeof(certs)/sizeof(certs[0]); i++) {
651
652	ret = decode_Certificate((unsigned char *)certs[i].cert,
653				 certs[i].len, &c, &size);
654	if (ret)
655	    return ret;
656
657	ret = copy_Certificate(&c, &c2);
658	free_Certificate(&c);
659	if (ret)
660	    return ret;
661
662	free_Certificate(&c2);
663    }
664
665    return 0;
666}
667
668struct {
669    const char *sd;
670    size_t len;
671} signeddata[] = {
672    {
673	"\x30\x80\x02\x01\x03\x31\x0b\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a"
674	"\x05\x00\x30\x80\x06\x07\x2b\x06\x01\x05\x02\x03\x03\xa0\x80\x24"
675	"\x80\x04\x50\x30\x4e\xa0\x2b\x30\x29\xa0\x03\x02\x01\x12\xa1\x22"
676	"\x04\x20\x78\xf4\x86\x31\xc6\xc2\xc9\xcb\xef\x0c\xd7\x3a\x2a\xcd"
677	"\x8c\x13\x34\x83\xb1\x5c\xa8\xbe\xbf\x2f\xea\xd2\xbb\xd8\x8c\x18"
678	"\x47\x01\xa1\x1f\x30\x1d\xa0\x03\x02\x01\x0c\xa1\x16\x04\x14\xa6"
679	"\x2c\x52\xb2\x80\x98\x30\x40\xbc\x5f\xb0\x77\x2d\x8a\xd7\xa1\xda"
680	"\x3c\xc5\x62\x00\x00\x00\x00\x00\x00\xa0\x82\x02\x09\x30\x82\x02"
681	"\x05\x30\x82\x01\x6e\xa0\x03\x02\x01\x02\x02\x04\x49\x75\x57\xbf"
682	"\x30\x0b\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x30\x3b\x31"
683	"\x1f\x30\x1d\x06\x03\x55\x04\x03\x0c\x16\x63\x6f\x6d\x2e\x61\x70"
684	"\x70\x6c\x65\x2e\x6b\x65\x72\x62\x65\x72\x6f\x73\x2e\x6b\x64\x63"
685	"\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x53\x79\x73\x74\x65"
686	"\x6d\x20\x49\x64\x65\x6e\x74\x69\x74\x79\x30\x1e\x17\x0d\x30\x39"
687	"\x31\x32\x30\x34\x30\x30\x32\x30\x32\x34\x5a\x17\x0d\x32\x39\x31"
688	"\x31\x32\x39\x30\x30\x32\x30\x32\x34\x5a\x30\x3b\x31\x1f\x30\x1d"
689	"\x06\x03\x55\x04\x03\x0c\x16\x63\x6f\x6d\x2e\x61\x70\x70\x6c\x65"
690	"\x2e\x6b\x65\x72\x62\x65\x72\x6f\x73\x2e\x6b\x64\x63\x31\x18\x30"
691	"\x16\x06\x03\x55\x04\x0a\x0c\x0f\x53\x79\x73\x74\x65\x6d\x20\x49"
692	"\x64\x65\x6e\x74\x69\x74\x79\x30\x81\x9f\x30\x0d\x06\x09\x2a\x86"
693	"\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00\x30\x81\x89"
694	"\x02\x81\x81\x00\xb2\xc5\x4b\x34\xe3\x93\x99\xbb\xaa\xd1\x70\x62"
695	"\x6c\x9c\xcc\xa6\xbc\x47\xc3\x23\xff\x15\xb9\x11\x27\x0a\xf8\x55"
696	"\x4c\xb2\x43\x34\x75\xad\x55\xbb\xb9\x8a\xd0\x25\x64\xa4\x8c\x82"
697	"\x74\x5d\x89\x52\xe2\x76\x75\x08\x67\xb5\x9c\x9c\x69\x86\x0c\x6d"
698	"\x79\xf7\xa0\xbe\x42\x8f\x90\x46\x0c\x18\xf4\x7a\x56\x17\xa4\x65"
699	"\x00\x3a\x5e\x3e\xbf\xbc\xf5\xe2\x2c\x26\x03\x52\xdd\xd4\x85\x3f"
700	"\x03\xd7\x0c\x45\x7f\xff\xdd\x1e\x70\x6c\x9f\xb0\x8c\xd0\x33\xad"
701	"\x92\x54\x17\x9d\x88\x89\x1a\xee\xef\xf7\x96\x3e\x68\xc3\xd1\x60"
702	"\x47\x86\x80\x5d\x02\x03\x01\x00\x01\xa3\x18\x30\x16\x30\x14\x06"
703	"\x03\x55\x1d\x25\x04\x0d\x30\x0b\x06\x09\x2a\x86\x48\x86\xf7\x63"
704	"\x64\x04\x04\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05"
705	"\x05\x00\x03\x81\x81\x00\x9b\xbb\xaa\x63\x66\xd8\x70\x84\x3e\xf6"
706	"\xa1\x3b\xf3\xe6\xd7\x3d\xfc\x4f\xc9\x45\xaa\x31\x43\x8d\xb5\x72"
707	"\xe4\x34\x95\x7b\x6e\x5f\xe5\xc8\x5e\xaf\x12\x08\x6d\xd7\x25\x76"
708	"\x40\xd5\xdc\x83\x7f\x2f\x74\xd1\x63\xc0\x7c\x26\x4d\x53\x10\xe7"
709	"\xfa\xcc\xf2\x60\x41\x63\xdf\x56\xd6\xd9\xc0\xb4\xd0\x73\x99\x54"
710	"\x40\xad\x90\x79\x2d\xd2\x5e\xcb\x13\x22\x2b\xd0\x76\xef\x8a\x48"
711	"\xfd\xb2\x6e\xca\x04\x4e\x91\x3f\xb4\x63\xad\x22\x3a\xf7\x20\x9c"
712	"\x4c\x0e\x47\x78\xe5\x2a\x85\x0e\x90\x7a\xce\x46\xe6\x15\x02\xb0"
713	"\x83\xe7\xac\xfa\x92\xf8\x31\x81\xe8\x30\x81\xe5\x02\x01\x01\x30"
714	"\x43\x30\x3b\x31\x1f\x30\x1d\x06\x03\x55\x04\x03\x0c\x16\x63\x6f"
715	"\x6d\x2e\x61\x70\x70\x6c\x65\x2e\x6b\x65\x72\x62\x65\x72\x6f\x73"
716	"\x2e\x6b\x64\x63\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x53"
717	"\x79\x73\x74\x65\x6d\x20\x49\x64\x65\x6e\x74\x69\x74\x79\x02\x04"
718	"\x49\x75\x57\xbf\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x30"
719	"\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x04\x81"
720	"\x80\x50\x2c\x69\xe1\xd2\xc4\xd1\xcc\xdc\xe0\xe9\x8a\x6b\x6a\x97"
721	"\x1b\xb4\xe0\xa8\x20\xbe\x09\x6d\xe1\x55\x5f\x07\x70\x94\x2e\x14"
722	"\xed\x4e\xb1\x69\x75\x40\xbb\x99\x87\xed\x23\x50\x27\x5f\xaa\xc4"
723	"\x84\x60\x06\xfe\x45\xfd\x7e\x1b\x18\xe0\x0b\x77\x35\x2a\xb2\xf2"
724	"\xe0\x88\x31\xad\x82\x31\x4a\xbc\x6d\x71\x62\xe6\x4d\x33\xb4\x09"
725	"\x6e\x3f\x14\x12\xf2\x89\x29\x31\x84\x60\x2b\xa8\x2d\xe6\xca\x2f"
726	"\x03\x3d\xd4\x69\x89\xb3\x98\xfd\xac\x63\x14\xaf\x6a\x52\x2a\xac"
727	"\xe3\x8e\xfa\x21\x41\x8f\xcc\x04\x2d\x52\xee\x49\x54\x0d\x58\x51"
728	"\x77\x00\x00",
729	883
730    }
731};
732
733static int
734test_SignedData(void)
735{
736    SignedData sd;
737    size_t size, i;
738    int ret;
739
740    for (i = 0; i < sizeof(signeddata) / sizeof(signeddata[0]); i++) {
741
742	ret = decode_SignedData((unsigned char *)signeddata[i].sd,
743				signeddata[i].len, &sd, &size);
744	if (ret)
745	    return ret;
746
747	free_SignedData(&sd);
748    }
749
750    return 0;
751}
752
753
754static int
755cmp_TESTLargeTag (void *a, void *b)
756{
757    TESTLargeTag *aa = a;
758    TESTLargeTag *ab = b;
759
760    COMPARE_INTEGER(aa,ab,foo);
761    COMPARE_INTEGER(aa,ab,bar);
762    return 0;
763}
764
765static int
766test_large_tag (void)
767{
768    struct test_case tests[] = {
769	{ NULL,  15,  "\x30\x0d\xbf\x7f\x03\x02\x01\x01\xbf\x81\x00\x03\x02\x01\x02", "large tag 1" }
770    };
771
772    int ntests = sizeof(tests) / sizeof(*tests);
773    TESTLargeTag lt1;
774
775    memset(&lt1, 0, sizeof(lt1));
776    lt1.foo = 1;
777    lt1.bar = 2;
778
779    tests[0].val = &lt1;
780
781    return generic_test (tests, ntests, sizeof(TESTLargeTag),
782			 (generic_encode)encode_TESTLargeTag,
783			 (generic_length)length_TESTLargeTag,
784			 (generic_decode)decode_TESTLargeTag,
785			 (generic_free)free_TESTLargeTag,
786			 cmp_TESTLargeTag,
787			 (generic_copy)copy_TESTLargeTag);
788}
789
790struct test_data {
791    int ok;
792    size_t len;
793    size_t expected_len;
794    void *data;
795};
796
797static int
798check_tag_length(void)
799{
800    struct test_data td[] = {
801	{ 1, 3, 3, "\x02\x01\x00"},
802	{ 1, 3, 3, "\x02\x01\x7f"},
803	{ 1, 4, 4, "\x02\x02\x00\x80"},
804	{ 1, 4, 4, "\x02\x02\x01\x00"},
805	{ 1, 4, 4, "\x02\x02\x02\x00"},
806	{ 0, 3, 0, "\x02\x02\x00"},
807	{ 0, 3, 0, "\x02\x7f\x7f"},
808	{ 0, 4, 0, "\x02\x03\x00\x80"},
809	{ 0, 4, 0, "\x02\x7f\x01\x00"},
810	{ 0, 5, 0, "\x02\xff\x7f\x02\x00"}
811    };
812    size_t sz;
813    TESTuint32 values[] = {0, 127, 128, 256, 512,
814			 0, 127, 128, 256, 512 };
815    TESTuint32 u;
816    int ret, failed = 0;
817    void *buf;
818    size_t i;
819
820    for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) {
821	struct map_page *page;
822
823	buf = map_alloc(OVERRUN, td[i].data, td[i].len, &page);
824
825	ret = decode_TESTuint32(buf, td[i].len, &u, &sz);
826	if (ret) {
827	    if (td[i].ok) {
828		printf("failed with tag len test %d\n", (int)i);
829		failed = 1;
830	    }
831	} else {
832	    if (td[i].ok == 0) {
833		printf("failed with success for tag len test %d\n", (int)i);
834		failed = 1;
835	    }
836	    if (td[i].expected_len != sz) {
837		printf("wrong expected size for tag test %d\n", (int)i);
838		failed = 1;
839	    }
840	    if (values[i] != u) {
841		printf("wrong value for tag test %d\n", (int)i);
842		failed = 1;
843	    }
844	}
845	map_free(page, "test", "decode");
846    }
847    return failed;
848}
849
850static int
851cmp_TESTChoice (void *a, void *b)
852{
853    return 0;
854}
855
856static int
857test_choice (void)
858{
859    struct test_case tests[] = {
860	{ NULL,  5,  "\xa1\x03\x02\x01\x01", "large choice 1" },
861	{ NULL,  5,  "\xa2\x03\x02\x01\x02", "large choice 2" }
862    };
863
864    int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
865    TESTChoice1 c1;
866    TESTChoice1 c2_1;
867    TESTChoice2 c2_2;
868
869    memset(&c1, 0, sizeof(c1));
870    c1.element = choice_TESTChoice1_i1;
871    c1.u.i1 = 1;
872    tests[0].val = &c1;
873
874    memset(&c2_1, 0, sizeof(c2_1));
875    c2_1.element = choice_TESTChoice1_i2;
876    c2_1.u.i2 = 2;
877    tests[1].val = &c2_1;
878
879    ret += generic_test (tests, ntests, sizeof(TESTChoice1),
880			 (generic_encode)encode_TESTChoice1,
881			 (generic_length)length_TESTChoice1,
882			 (generic_decode)decode_TESTChoice1,
883			 (generic_free)free_TESTChoice1,
884			 cmp_TESTChoice,
885			 (generic_copy)copy_TESTChoice1);
886
887    memset(&c2_2, 0, sizeof(c2_2));
888    c2_2.element = choice_TESTChoice2_asn1_ellipsis;
889    c2_2.u.asn1_ellipsis.data = "\xa2\x03\x02\x01\x02";
890    c2_2.u.asn1_ellipsis.length = 5;
891    tests[1].val = &c2_2;
892
893    ret += generic_test (tests, ntests, sizeof(TESTChoice2),
894			 (generic_encode)encode_TESTChoice2,
895			 (generic_length)length_TESTChoice2,
896			 (generic_decode)decode_TESTChoice2,
897			 (generic_free)free_TESTChoice2,
898			 cmp_TESTChoice,
899			 (generic_copy)copy_TESTChoice2);
900
901    return ret;
902}
903
904static int
905cmp_TESTImplicit (void *a, void *b)
906{
907    TESTImplicit *aa = a;
908    TESTImplicit *ab = b;
909
910    COMPARE_INTEGER(aa,ab,ti1);
911    COMPARE_INTEGER(aa,ab,ti2.foo);
912    COMPARE_INTEGER(aa,ab,ti3);
913    return 0;
914}
915
916/*
917UNIV CONS Sequence 14
918  CONTEXT PRIM 0 1 00
919  CONTEXT CONS 1 6
920    CONTEXT CONS 127 3
921      UNIV PRIM Integer 1 02
922  CONTEXT PRIM 2 1 03
923*/
924
925static int
926test_implicit (void)
927{
928    struct test_case tests[] = {
929	{ NULL,  18,
930	  "\x30\x10\x80\x01\x00\xa1\x06\xbf"
931	  "\x7f\x03\x02\x01\x02\xa2\x03\x84\x01\x03",
932	  "implicit 1" }
933    };
934
935    int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
936    TESTImplicit c0;
937
938    memset(&c0, 0, sizeof(c0));
939    c0.ti1 = 0;
940    c0.ti2.foo = 2;
941    c0.ti3 = 3;
942    tests[0].val = &c0;
943
944    ret += generic_test (tests, ntests, sizeof(TESTImplicit),
945			 (generic_encode)encode_TESTImplicit,
946			 (generic_length)length_TESTImplicit,
947			 (generic_decode)decode_TESTImplicit,
948			 (generic_free)free_TESTImplicit,
949			 cmp_TESTImplicit,
950			 (generic_copy)copy_TESTImplicit);
951
952#ifdef IMPLICIT_TAGGING_WORKS
953    ret += generic_test (tests, ntests, sizeof(TESTImplicit2),
954			 (generic_encode)encode_TESTImplicit2,
955			 (generic_length)length_TESTImplicit2,
956			 (generic_decode)decode_TESTImplicit2,
957			 (generic_free)free_TESTImplicit2,
958			 cmp_TESTImplicit,
959			 NULL);
960
961#endif /* IMPLICIT_TAGGING_WORKS */
962    return ret;
963}
964
965static int
966cmp_TESTAlloc (void *a, void *b)
967{
968    TESTAlloc *aa = a;
969    TESTAlloc *ab = b;
970
971    IF_OPT_COMPARE(aa,ab,tagless) {
972	COMPARE_INTEGER(aa,ab,tagless->ai);
973    }
974
975    COMPARE_INTEGER(aa,ab,three);
976
977    IF_OPT_COMPARE(aa,ab,tagless2) {
978	COMPARE_OPT_OCTECT_STRING(aa, ab, tagless2);
979    }
980
981    return 0;
982}
983
984/*
985UNIV CONS Sequence 12
986  UNIV CONS Sequence 5
987    CONTEXT CONS 0 3
988      UNIV PRIM Integer 1 01
989  CONTEXT CONS 1 3
990    UNIV PRIM Integer 1 03
991
992UNIV CONS Sequence 5
993  CONTEXT CONS 1 3
994    UNIV PRIM Integer 1 03
995
996UNIV CONS Sequence 8
997  CONTEXT CONS 1 3
998    UNIV PRIM Integer 1 04
999  UNIV PRIM Integer 1 05
1000
1001*/
1002
1003static int
1004test_taglessalloc (void)
1005{
1006    struct test_case tests[] = {
1007	{ NULL,  14,
1008	  "\x30\x0c\x30\x05\xa0\x03\x02\x01\x01\xa1\x03\x02\x01\x03",
1009	  "alloc 1" },
1010	{ NULL,  7,
1011	  "\x30\x05\xa1\x03\x02\x01\x03",
1012	  "alloc 2" },
1013	{ NULL,  10,
1014	  "\x30\x08\xa1\x03\x02\x01\x04\x02\x01\x05",
1015	  "alloc 3" }
1016    };
1017
1018    int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
1019    TESTAlloc c1, c2, c3;
1020    heim_any any3;
1021
1022    memset(&c1, 0, sizeof(c1));
1023    c1.tagless = ecalloc(1, sizeof(*c1.tagless));
1024    c1.tagless->ai = 1;
1025    c1.three = 3;
1026    tests[0].val = &c1;
1027
1028    memset(&c2, 0, sizeof(c2));
1029    c2.tagless = NULL;
1030    c2.three = 3;
1031    tests[1].val = &c2;
1032
1033    memset(&c3, 0, sizeof(c3));
1034    c3.tagless = NULL;
1035    c3.three = 4;
1036    c3.tagless2 = &any3;
1037    any3.data = "\x02\x01\x05";
1038    any3.length = 3;
1039    tests[2].val = &c3;
1040
1041    ret += generic_test (tests, ntests, sizeof(TESTAlloc),
1042			 (generic_encode)encode_TESTAlloc,
1043			 (generic_length)length_TESTAlloc,
1044			 (generic_decode)decode_TESTAlloc,
1045			 (generic_free)free_TESTAlloc,
1046			 cmp_TESTAlloc,
1047			 (generic_copy)copy_TESTAlloc);
1048
1049    free(c1.tagless);
1050
1051    return ret;
1052}
1053
1054static int
1055cmp_TESTOptional (void *a, void *b)
1056{
1057    TESTOptional *aa = a;
1058    TESTOptional *ab = b;
1059
1060    IF_OPT_COMPARE(aa,ab,zero) {
1061	COMPARE_OPT_INTEGER(aa,ab,zero);
1062    }
1063    IF_OPT_COMPARE(aa,ab,one) {
1064	COMPARE_OPT_INTEGER(aa,ab,one);
1065    }
1066    return 0;
1067}
1068
1069/*
1070UNIV CONS Sequence 5
1071  CONTEXT CONS 0 3
1072    UNIV PRIM Integer 1 00
1073
1074UNIV CONS Sequence 5
1075  CONTEXT CONS 1 3
1076    UNIV PRIM Integer 1 03
1077
1078UNIV CONS Sequence 10
1079  CONTEXT CONS 0 3
1080    UNIV PRIM Integer 1 00
1081  CONTEXT CONS 1 3
1082    UNIV PRIM Integer 1 01
1083
1084*/
1085
1086static int
1087test_optional (void)
1088{
1089    struct test_case tests[] = {
1090	{ NULL,  2,
1091	  "\x30\x00",
1092	  "optional 0" },
1093	{ NULL,  7,
1094	  "\x30\x05\xa0\x03\x02\x01\x00",
1095	  "optional 1" },
1096	{ NULL,  7,
1097	  "\x30\x05\xa1\x03\x02\x01\x01",
1098	  "optional 2" },
1099	{ NULL,  12,
1100	  "\x30\x0a\xa0\x03\x02\x01\x00\xa1\x03\x02\x01\x01",
1101	  "optional 3" }
1102    };
1103
1104    int ret = 0, ntests = sizeof(tests) / sizeof(*tests);
1105    TESTOptional c0, c1, c2, c3;
1106    int zero = 0;
1107    int one = 1;
1108
1109    c0.zero = NULL;
1110    c0.one = NULL;
1111    tests[0].val = &c0;
1112
1113    c1.zero = &zero;
1114    c1.one = NULL;
1115    tests[1].val = &c1;
1116
1117    c2.zero = NULL;
1118    c2.one = &one;
1119    tests[2].val = &c2;
1120
1121    c3.zero = &zero;
1122    c3.one = &one;
1123    tests[3].val = &c3;
1124
1125    ret += generic_test (tests, ntests, sizeof(TESTOptional),
1126			 (generic_encode)encode_TESTOptional,
1127			 (generic_length)length_TESTOptional,
1128			 (generic_decode)decode_TESTOptional,
1129			 (generic_free)free_TESTOptional,
1130			 cmp_TESTOptional,
1131			 (generic_copy)copy_TESTOptional);
1132
1133    return ret;
1134}
1135
1136static int
1137check_fail_largetag(void)
1138{
1139    struct test_case tests[] = {
1140	{NULL, 14, "\x30\x0c\xbf\x87\xff\xff\xff\xff\xff\x7f\x03\x02\x01\x01",
1141	 "tag overflow"},
1142	{NULL, 0, "", "empty buffer"},
1143	{NULL, 7, "\x30\x05\xa1\x03\x02\x02\x01",
1144	 "one too short" },
1145	{NULL, 7, "\x30\x04\xa1\x03\x02\x02\x01"
1146	 "two too short" },
1147	{NULL, 7, "\x30\x03\xa1\x03\x02\x02\x01",
1148	 "three too short" },
1149	{NULL, 7, "\x30\x02\xa1\x03\x02\x02\x01",
1150	 "four too short" },
1151	{NULL, 7, "\x30\x01\xa1\x03\x02\x02\x01",
1152	 "five too short" },
1153	{NULL, 7, "\x30\x00\xa1\x03\x02\x02\x01",
1154	 "six too short" },
1155	{NULL, 7, "\x30\x05\xa1\x04\x02\x02\x01",
1156	 "inner one too long" },
1157	{NULL, 7, "\x30\x00\xa1\x02\x02\x02\x01",
1158	 "inner one too short" },
1159	{NULL, 8, "\x30\x05\xbf\x7f\x03\x02\x02\x01",
1160	 "inner one too short"},
1161	{NULL, 8, "\x30\x06\xbf\x64\x03\x02\x01\x01",
1162	 "wrong tag"},
1163	{NULL, 10, "\x30\x08\xbf\x9a\x9b\x38\x03\x02\x01\x01",
1164	 "still wrong tag"}
1165    };
1166    int ntests = sizeof(tests) / sizeof(*tests);
1167
1168    return generic_decode_fail(tests, ntests, sizeof(TESTLargeTag),
1169			       (generic_decode)decode_TESTLargeTag);
1170}
1171
1172
1173static int
1174check_fail_sequence(void)
1175{
1176    struct test_case tests[] = {
1177	{NULL, 0, "", "empty buffer"},
1178	{NULL, 24,
1179	 "\x30\x16\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01\x01"
1180	 "\x02\x01\x01\xa2\x03\x02\x01\x01"
1181	 "missing one byte from the end, internal length ok"},
1182	{NULL, 25,
1183	 "\x30\x18\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01\x01"
1184	 "\x02\x01\x01\xa2\x03\x02\x01\x01",
1185	 "inner length one byte too long"},
1186	{NULL, 24,
1187	 "\x30\x17\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\xbf\x7f\x03\x02\x01"
1188	 "\x01\x02\x01\x01\xa2\x03\x02\x01\x01",
1189	 "correct buffer but missing one too short"}
1190    };
1191    int ntests = sizeof(tests) / sizeof(*tests);
1192
1193    return generic_decode_fail(tests, ntests, sizeof(TESTSeq),
1194			       (generic_decode)decode_TESTSeq);
1195}
1196
1197static int
1198check_fail_choice(void)
1199{
1200    struct test_case tests[] = {
1201	{NULL, 6,
1202	 "\xa1\x02\x02\x01\x01",
1203	 "choice one too short"},
1204	{NULL, 6,
1205	 "\xa1\x03\x02\x02\x01",
1206	 "choice one too short inner"}
1207    };
1208    int ntests = sizeof(tests) / sizeof(*tests);
1209
1210    return generic_decode_fail(tests, ntests, sizeof(TESTChoice1),
1211			       (generic_decode)decode_TESTChoice1);
1212}
1213
1214static int
1215check_fail_Ticket(void)
1216{
1217    char buf[100];
1218    size_t i;
1219    int ret;
1220    struct test_case test;
1221    Ticket ticket;
1222
1223    for (i = 0; i < sizeof(buf); i++) {
1224	memset(buf, 0, sizeof(buf));
1225	memset(&ticket, 0, sizeof(ticket));
1226	test.val = &ticket;
1227	test.byte_len = i;
1228	test.bytes = buf;
1229	test.name = "zero life";
1230	ret = generic_decode_fail(&test, 1, sizeof(Ticket),
1231				  (generic_decode)decode_Ticket);
1232	if (ret)
1233	    return ret;
1234    }
1235    return 0;
1236}
1237
1238static int
1239check_seq(void)
1240{
1241    TESTSeqOf seq;
1242    TESTInteger i;
1243    int ret;
1244
1245    seq.val = NULL;
1246    seq.len = 0;
1247
1248    ret = add_TESTSeqOf(&seq, &i);
1249    if (ret) { printf("failed adding\n"); goto out; }
1250    ret = add_TESTSeqOf(&seq, &i);
1251    if (ret) { printf("failed adding\n"); goto out; }
1252    ret = add_TESTSeqOf(&seq, &i);
1253    if (ret) { printf("failed adding\n"); goto out; }
1254    ret = add_TESTSeqOf(&seq, &i);
1255    if (ret) { printf("failed adding\n"); goto out; }
1256
1257    ret = remove_TESTSeqOf(&seq, seq.len - 1);
1258    if (ret) { printf("failed removing\n"); goto out; }
1259    ret = remove_TESTSeqOf(&seq, 2);
1260    if (ret) { printf("failed removing\n"); goto out; }
1261    ret = remove_TESTSeqOf(&seq, 0);
1262    if (ret) { printf("failed removing\n"); goto out; }
1263    ret = remove_TESTSeqOf(&seq, 0);
1264    if (ret) { printf("failed removing\n"); goto out; }
1265    ret = remove_TESTSeqOf(&seq, 0);
1266    if (ret == 0) {
1267	printf("can remove from empty list");
1268	return 1;
1269    }
1270
1271    if (seq.len != 0) {
1272	printf("seq not empty!");
1273	return 1;
1274    }
1275    free_TESTSeqOf(&seq);
1276    ret = 0;
1277
1278out:
1279
1280    return ret;
1281}
1282
1283#define test_seq_of(type, ok, ptr)					\
1284{									\
1285    heim_octet_string os;						\
1286    size_t size;							\
1287    type decode;							\
1288    ASN1_MALLOC_ENCODE(type, os.data, os.length, ptr, &size, ret);	\
1289    if (ret)								\
1290	return ret;							\
1291    if (os.length != size)						\
1292	abort();							\
1293    ret = decode_##type(os.data, os.length, &decode, &size);		\
1294    free(os.data);							\
1295    if (ret) {								\
1296	if (ok)								\
1297	    return 1;							\
1298    } else {								\
1299	free_##type(&decode);						\
1300	if (!ok)							\
1301	    return 1;							\
1302	if (size != 0)							\
1303            return 1;							\
1304    }									\
1305    return 0;								\
1306}
1307
1308static int
1309check_seq_of_size(void)
1310{
1311#if 0 /* template */
1312    TESTInteger integers[4] = { 1, 2, 3, 4 };
1313    int ret;
1314
1315    {
1316	TESTSeqSizeOf1 ssof1f1 = { 1, integers };
1317	TESTSeqSizeOf1 ssof1ok1 = { 2, integers };
1318	TESTSeqSizeOf1 ssof1f2 = { 3, integers };
1319
1320	test_seq_of(TESTSeqSizeOf1, 0, &ssof1f1);
1321	test_seq_of(TESTSeqSizeOf1, 1, &ssof1ok1);
1322	test_seq_of(TESTSeqSizeOf1, 0, &ssof1f2);
1323    }
1324    {
1325	TESTSeqSizeOf2 ssof2f1 = { 0, NULL };
1326	TESTSeqSizeOf2 ssof2ok1 = { 1, integers };
1327	TESTSeqSizeOf2 ssof2ok2 = { 2, integers };
1328	TESTSeqSizeOf2 ssof2f2 = { 3, integers };
1329
1330	test_seq_of(TESTSeqSizeOf2, 0, &ssof2f1);
1331	test_seq_of(TESTSeqSizeOf2, 1, &ssof2ok1);
1332	test_seq_of(TESTSeqSizeOf2, 1, &ssof2ok2);
1333	test_seq_of(TESTSeqSizeOf2, 0, &ssof2f2);
1334    }
1335    {
1336	TESTSeqSizeOf3 ssof3f1 = { 0, NULL };
1337	TESTSeqSizeOf3 ssof3ok1 = { 1, integers };
1338	TESTSeqSizeOf3 ssof3ok2 = { 2, integers };
1339
1340	test_seq_of(TESTSeqSizeOf3, 0, &ssof3f1);
1341	test_seq_of(TESTSeqSizeOf3, 1, &ssof3ok1);
1342	test_seq_of(TESTSeqSizeOf3, 1, &ssof3ok2);
1343    }
1344    {
1345	TESTSeqSizeOf4 ssof4ok1 = { 0, NULL };
1346	TESTSeqSizeOf4 ssof4ok2 = { 1, integers };
1347	TESTSeqSizeOf4 ssof4ok3 = { 2, integers };
1348	TESTSeqSizeOf4 ssof4f1  = { 3, integers };
1349
1350	test_seq_of(TESTSeqSizeOf4, 1, &ssof4ok1);
1351	test_seq_of(TESTSeqSizeOf4, 1, &ssof4ok2);
1352	test_seq_of(TESTSeqSizeOf4, 1, &ssof4ok3);
1353	test_seq_of(TESTSeqSizeOf4, 0, &ssof4f1);
1354   }
1355#endif
1356    return 0;
1357}
1358
1359static int
1360check_TESTMechTypeList(void)
1361{
1362    TESTMechTypeList tl;
1363    unsigned oid1[] =  { 1, 2, 840, 48018, 1, 2, 2};
1364    unsigned oid2[] =  { 1, 2, 840, 113554, 1, 2, 2};
1365    unsigned oid3[] =   { 1, 3, 6, 1, 4, 1, 311, 2, 2, 30};
1366    unsigned oid4[] =   { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10};
1367    TESTMechType array[] = {{ 7, oid1 },
1368                            { 7, oid2 },
1369                            { 10, oid3 },
1370                            { 10, oid4 }};
1371    size_t size = 0, len;
1372    void *ptr;
1373    int ret;
1374
1375    tl.len = 4;
1376    tl.val = array;
1377
1378    ASN1_MALLOC_ENCODE(TESTMechTypeList, ptr, len, &tl, &size, ret);
1379    if (ret)
1380	errx(1, "TESTMechTypeList: %d", ret);
1381    if (len != size)
1382	abort();
1383    return 0;
1384}
1385
1386static unsigned char token[] = {
1387  0x30, 0x81, 0xb1, 0xa0, 0x03, 0x0a, 0x05, 0x00, 0xa2, 0x81, 0xa9, 0x04,
1388  0x81, 0xa6, 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00,
1389  0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x18, 0x00,
1390  0x18, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x48, 0x00,
1391  0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x0c, 0x00,
1392  0x0c, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1393  0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x05, 0x01, 0x28, 0x0a, 0x00, 0x00,
1394  0x00, 0x0f, 0x54, 0x00, 0x45, 0x00, 0x53, 0x00, 0x54, 0x00, 0x44, 0x00,
1395  0x4f, 0x00, 0x4d, 0x00, 0x41, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x73, 0x00,
1396  0x6d, 0x00, 0x62, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
1397  0x54, 0x00, 0x45, 0x00, 0x53, 0x00, 0x54, 0x00, 0x50, 0x00, 0x43, 0x00,
1398  0x73, 0x8c, 0x0f, 0xb0, 0xd4, 0xc1, 0xab, 0x7f, 0xe6, 0xeb, 0xb9, 0xc4,
1399  0x04, 0xfb, 0x3d, 0xda, 0x5d, 0x76, 0x55, 0x5f, 0x3c, 0x75, 0xcc, 0xf9,
1400  0xd5, 0x4a, 0x55, 0xc7, 0x0f, 0x2e, 0x03, 0xaf, 0xcf, 0x66, 0x1e, 0xc0,
1401  0x52, 0x70, 0x89, 0xaa, 0x99, 0xa2, 0x9b, 0xa5, 0x91, 0x26, 0x61, 0x94
1402};
1403static size_t token_len = 180;
1404
1405static int
1406check_negToken(void)
1407{
1408    TESTNegotiationToken tl;
1409    TESTNegTokenResp tr;
1410    size_t size;
1411    int ret;
1412
1413    ret = decode_TESTNegotiationToken(token, token_len, &tl, &size);
1414    if (ret)
1415	;
1416    else if (token_len != size)
1417	errx(1, "token contains extra data");
1418
1419    ret = decode_TESTNegTokenResp(token, token_len, &tr, &size);
1420    if (ret)
1421	;
1422    else if (token_len != size)
1423	errx(1, "token contains extra data");
1424
1425    return 0;
1426}
1427
1428int
1429main(int argc, char **argv)
1430{
1431    int ret = 0;
1432
1433    ret += test_principal ();
1434    ret += test_authenticator();
1435    ret += test_krb_error();
1436    ret += test_Name();
1437    ret += test_bit_string();
1438    ret += test_bit_string_rfc1510();
1439    ret += test_time();
1440    ret += test_cert();
1441
1442    ret += check_tag_length();
1443    ret += test_large_tag();
1444    ret += test_choice();
1445
1446    ret += test_implicit();
1447    ret += test_taglessalloc();
1448    ret += test_optional();
1449
1450    ret += check_fail_largetag();
1451    ret += check_fail_sequence();
1452    ret += check_fail_choice();
1453    ret += check_fail_Ticket();
1454
1455    ret += check_seq();
1456    ret += check_seq_of_size();
1457    ret += test_SignedData();
1458
1459    ret += check_TESTMechTypeList();
1460    ret += check_negToken();
1461
1462
1463    return ret;
1464}
1465