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