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