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