1/* 2 * Copyright (c) 1999 - 2007 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "der_locl.h" 37#include <err.h> 38#include <roken.h> 39 40#include <asn1-common.h> 41#include <asn1_err.h> 42#include <der.h> 43 44#include "check-common.h" 45 46RCSID("$Id$"); 47 48static int 49cmp_integer (void *a, void *b) 50{ 51 int *ia = (int *)a; 52 int *ib = (int *)b; 53 54 return *ib - *ia; 55} 56 57static int 58test_integer (void) 59{ 60 struct test_case tests[] = { 61 {NULL, 1, "\x00"}, 62 {NULL, 1, "\x7f"}, 63 {NULL, 2, "\x00\x80"}, 64 {NULL, 2, "\x01\x00"}, 65 {NULL, 1, "\x80"}, 66 {NULL, 2, "\xff\x7f"}, 67 {NULL, 1, "\xff"}, 68 {NULL, 2, "\xff\x01"}, 69 {NULL, 2, "\x00\xff"}, 70 {NULL, 4, "\x7f\xff\xff\xff"} 71 }; 72 73 int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255, 74 0x7fffffff}; 75 int i, ret; 76 int ntests = sizeof(tests) / sizeof(*tests); 77 78 for (i = 0; i < ntests; ++i) { 79 tests[i].val = &values[i]; 80 if (asprintf (&tests[i].name, "integer %d", values[i]) < 0) 81 errx(1, "malloc"); 82 if (tests[i].name == NULL) 83 errx(1, "malloc"); 84 } 85 86 ret = generic_test (tests, ntests, sizeof(int), 87 (generic_encode)der_put_integer, 88 (generic_length) der_length_integer, 89 (generic_decode)der_get_integer, 90 (generic_free)NULL, 91 cmp_integer, 92 NULL); 93 94 for (i = 0; i < ntests; ++i) 95 free (tests[i].name); 96 return ret; 97} 98 99static int 100test_one_int(int val) 101{ 102 int ret, dval; 103 unsigned char *buf; 104 size_t len_len, len; 105 106 len = _heim_len_int(val); 107 108 buf = emalloc(len + 2); 109 110 buf[0] = '\xff'; 111 buf[len + 1] = '\xff'; 112 memset(buf + 1, 0, len); 113 114 ret = der_put_integer(buf + 1 + len - 1, len, &val, &len_len); 115 if (ret) { 116 printf("integer %d encode failed %d\n", val, ret); 117 return 1; 118 } 119 if (len != len_len) { 120 printf("integer %d encode fail with %d len %lu, result len %lu\n", 121 val, ret, (unsigned long)len, (unsigned long)len_len); 122 return 1; 123 } 124 125 ret = der_get_integer(buf + 1, len, &dval, &len_len); 126 if (ret) { 127 printf("integer %d decode failed %d\n", val, ret); 128 return 1; 129 } 130 if (len != len_len) { 131 printf("integer %d decoded diffrent len %lu != %lu", 132 val, (unsigned long)len, (unsigned long)len_len); 133 return 1; 134 } 135 if (val != dval) { 136 printf("decode decoded to diffrent value %d != %d", 137 val, dval); 138 return 1; 139 } 140 141 if (buf[0] != (unsigned char)'\xff') { 142 printf("precanary dead %d\n", val); 143 return 1; 144 } 145 if (buf[len + 1] != (unsigned char)'\xff') { 146 printf("postecanary dead %d\n", val); 147 return 1; 148 } 149 free(buf); 150 return 0; 151} 152 153static int 154test_integer_more (void) 155{ 156 int n1, n2, n3, n4, n5, n6; 157 size_t i; 158 159 n2 = 0; 160 for (i = 0; i < (sizeof(int) * 8); i++) { 161 n1 = 0x01 << i; 162 n2 = n2 | n1; 163 n3 = ~n1; 164 n4 = ~n2; 165 n5 = (-1) & ~(0x3f << i); 166 n6 = (-1) & ~(0x7f << i); 167 168 test_one_int(n1); 169 test_one_int(n2); 170 test_one_int(n3); 171 test_one_int(n4); 172 test_one_int(n5); 173 test_one_int(n6); 174 } 175 return 0; 176} 177 178static int 179cmp_unsigned (void *a, void *b) 180{ 181 return *(unsigned int*)b - *(unsigned int*)a; 182} 183 184static int 185test_unsigned (void) 186{ 187 struct test_case tests[] = { 188 {NULL, 1, "\x00"}, 189 {NULL, 1, "\x7f"}, 190 {NULL, 2, "\x00\x80"}, 191 {NULL, 2, "\x01\x00"}, 192 {NULL, 2, "\x02\x00"}, 193 {NULL, 3, "\x00\x80\x00"}, 194 {NULL, 5, "\x00\x80\x00\x00\x00"}, 195 {NULL, 4, "\x7f\xff\xff\xff"} 196 }; 197 198 unsigned int values[] = {0, 127, 128, 256, 512, 32768, 199 0x80000000, 0x7fffffff}; 200 int i, ret; 201 int ntests = sizeof(tests) / sizeof(*tests); 202 203 for (i = 0; i < ntests; ++i) { 204 tests[i].val = &values[i]; 205 if (asprintf (&tests[i].name, "unsigned %u", values[i]) < 0) 206 errx(1, "malloc"); 207 if (tests[i].name == NULL) 208 errx(1, "malloc"); 209 } 210 211 ret = generic_test (tests, ntests, sizeof(int), 212 (generic_encode)der_put_unsigned, 213 (generic_length)der_length_unsigned, 214 (generic_decode)der_get_unsigned, 215 (generic_free)NULL, 216 cmp_unsigned, 217 NULL); 218 for (i = 0; i < ntests; ++i) 219 free (tests[i].name); 220 return ret; 221} 222 223static int 224cmp_octet_string (void *a, void *b) 225{ 226 return der_heim_octet_string_cmp(a, b); 227} 228 229static int 230test_octet_string (void) 231{ 232 heim_octet_string s1 = {8, "\x01\x23\x45\x67\x89\xab\xcd\xef"}; 233 234 struct test_case tests[] = { 235 {NULL, 8, "\x01\x23\x45\x67\x89\xab\xcd\xef"} 236 }; 237 int ntests = sizeof(tests) / sizeof(*tests); 238 int ret; 239 240 tests[0].val = &s1; 241 if (asprintf (&tests[0].name, "a octet string") < 0) 242 errx(1, "malloc"); 243 if (tests[0].name == NULL) 244 errx(1, "malloc"); 245 246 ret = generic_test (tests, ntests, sizeof(heim_octet_string), 247 (generic_encode)der_put_octet_string, 248 (generic_length)der_length_octet_string, 249 (generic_decode)der_get_octet_string, 250 (generic_free)der_free_octet_string, 251 cmp_octet_string, 252 NULL); 253 free(tests[0].name); 254 return ret; 255} 256 257static int 258cmp_bmp_string (void *a, void *b) 259{ 260 heim_bmp_string *oa = (heim_bmp_string *)a; 261 heim_bmp_string *ob = (heim_bmp_string *)b; 262 263 return der_heim_bmp_string_cmp(oa, ob); 264} 265 266static uint16_t bmp_d1[] = { 32 }; 267static uint16_t bmp_d2[] = { 32, 32 }; 268 269static int 270test_bmp_string (void) 271{ 272 heim_bmp_string s1 = { 1, bmp_d1 }; 273 heim_bmp_string s2 = { 2, bmp_d2 }; 274 275 struct test_case tests[] = { 276 {NULL, 2, "\x00\x20"}, 277 {NULL, 4, "\x00\x20\x00\x20"} 278 }; 279 int ntests = sizeof(tests) / sizeof(*tests); 280 int ret; 281 282 tests[0].val = &s1; 283 if (asprintf (&tests[0].name, "a bmp string") < 0) 284 errx(1, "malloc"); 285 if (tests[0].name == NULL) 286 errx(1, "malloc"); 287 tests[1].val = &s2; 288 if (asprintf (&tests[1].name, "second bmp string") < 0) 289 errx(1, "malloc"); 290 if (tests[1].name == NULL) 291 errx(1, "malloc"); 292 293 ret = generic_test (tests, ntests, sizeof(heim_bmp_string), 294 (generic_encode)der_put_bmp_string, 295 (generic_length)der_length_bmp_string, 296 (generic_decode)der_get_bmp_string, 297 (generic_free)der_free_bmp_string, 298 cmp_bmp_string, 299 NULL); 300 free(tests[0].name); 301 free(tests[1].name); 302 return ret; 303} 304 305static int 306cmp_universal_string (void *a, void *b) 307{ 308 heim_universal_string *oa = (heim_universal_string *)a; 309 heim_universal_string *ob = (heim_universal_string *)b; 310 311 return der_heim_universal_string_cmp(oa, ob); 312} 313 314static uint32_t universal_d1[] = { 32 }; 315static uint32_t universal_d2[] = { 32, 32 }; 316 317static int 318test_universal_string (void) 319{ 320 heim_universal_string s1 = { 1, universal_d1 }; 321 heim_universal_string s2 = { 2, universal_d2 }; 322 323 struct test_case tests[] = { 324 {NULL, 4, "\x00\x00\x00\x20"}, 325 {NULL, 8, "\x00\x00\x00\x20\x00\x00\x00\x20"} 326 }; 327 int ntests = sizeof(tests) / sizeof(*tests); 328 int ret; 329 330 tests[0].val = &s1; 331 if (asprintf (&tests[0].name, "a universal string") < 0) 332 errx(1, "malloc"); 333 if (tests[0].name == NULL) 334 errx(1, "malloc"); 335 tests[1].val = &s2; 336 if (asprintf (&tests[1].name, "second universal string") < 0) 337 errx(1, "malloc"); 338 if (tests[1].name == NULL) 339 errx(1, "malloc"); 340 341 ret = generic_test (tests, ntests, sizeof(heim_universal_string), 342 (generic_encode)der_put_universal_string, 343 (generic_length)der_length_universal_string, 344 (generic_decode)der_get_universal_string, 345 (generic_free)der_free_universal_string, 346 cmp_universal_string, 347 NULL); 348 free(tests[0].name); 349 free(tests[1].name); 350 return ret; 351} 352 353static int 354cmp_general_string (void *a, void *b) 355{ 356 char **sa = (char **)a; 357 char **sb = (char **)b; 358 359 return strcmp (*sa, *sb); 360} 361 362static int 363test_general_string (void) 364{ 365 char *s1 = "Test User 1"; 366 367 struct test_case tests[] = { 368 {NULL, 11, "\x54\x65\x73\x74\x20\x55\x73\x65\x72\x20\x31"} 369 }; 370 int ret, ntests = sizeof(tests) / sizeof(*tests); 371 372 tests[0].val = &s1; 373 if (asprintf (&tests[0].name, "the string \"%s\"", s1) < 0) 374 errx(1, "malloc"); 375 if (tests[0].name == NULL) 376 errx(1, "malloc"); 377 378 ret = generic_test (tests, ntests, sizeof(unsigned char *), 379 (generic_encode)der_put_general_string, 380 (generic_length)der_length_general_string, 381 (generic_decode)der_get_general_string, 382 (generic_free)der_free_general_string, 383 cmp_general_string, 384 NULL); 385 free(tests[0].name); 386 return ret; 387} 388 389static int 390cmp_generalized_time (void *a, void *b) 391{ 392 time_t *ta = (time_t *)a; 393 time_t *tb = (time_t *)b; 394 395 return (int)(*tb - *ta); 396} 397 398static int 399test_generalized_time (void) 400{ 401 struct test_case tests[] = { 402 {NULL, 15, "19700101000000Z"}, 403 {NULL, 15, "19851106210627Z"} 404 }; 405 time_t values[] = {0, 500159187}; 406 int i, ret; 407 int ntests = sizeof(tests) / sizeof(*tests); 408 409 for (i = 0; i < ntests; ++i) { 410 tests[i].val = &values[i]; 411 if (asprintf (&tests[i].name, "time %d", (int)values[i]) < 0) 412 errx(1, "malloc"); 413 if (tests[i].name == NULL) 414 errx(1, "malloc"); 415 } 416 417 ret = generic_test (tests, ntests, sizeof(time_t), 418 (generic_encode)der_put_generalized_time, 419 (generic_length)der_length_generalized_time, 420 (generic_decode)der_get_generalized_time, 421 (generic_free)NULL, 422 cmp_generalized_time, 423 NULL); 424 for (i = 0; i < ntests; ++i) 425 free(tests[i].name); 426 return ret; 427} 428 429static int 430test_cmp_oid (void *a, void *b) 431{ 432 return der_heim_oid_cmp((heim_oid *)a, (heim_oid *)b); 433} 434 435static unsigned oid_comp1[] = { 1, 1, 1 }; 436static unsigned oid_comp2[] = { 1, 1 }; 437static unsigned oid_comp3[] = { 6, 15, 1 }; 438static unsigned oid_comp4[] = { 6, 15 }; 439 440static int 441test_oid (void) 442{ 443 struct test_case tests[] = { 444 {NULL, 2, "\x29\x01"}, 445 {NULL, 1, "\x29"}, 446 {NULL, 2, "\xff\x01"}, 447 {NULL, 1, "\xff"} 448 }; 449 heim_oid values[] = { 450 { 3, oid_comp1 }, 451 { 2, oid_comp2 }, 452 { 3, oid_comp3 }, 453 { 2, oid_comp4 } 454 }; 455 int i, ret; 456 int ntests = sizeof(tests) / sizeof(*tests); 457 458 for (i = 0; i < ntests; ++i) { 459 tests[i].val = &values[i]; 460 if (asprintf (&tests[i].name, "oid %d", i) < 0) 461 errx(1, "malloc"); 462 if (tests[i].name == NULL) 463 errx(1, "malloc"); 464 } 465 466 ret = generic_test (tests, ntests, sizeof(heim_oid), 467 (generic_encode)der_put_oid, 468 (generic_length)der_length_oid, 469 (generic_decode)der_get_oid, 470 (generic_free)der_free_oid, 471 test_cmp_oid, 472 NULL); 473 for (i = 0; i < ntests; ++i) 474 free(tests[i].name); 475 return ret; 476} 477 478static int 479test_cmp_bit_string (void *a, void *b) 480{ 481 return der_heim_bit_string_cmp((heim_bit_string *)a, (heim_bit_string *)b); 482} 483 484static int 485test_bit_string (void) 486{ 487 struct test_case tests[] = { 488 {NULL, 1, "\x00"} 489 }; 490 heim_bit_string values[] = { 491 { 0, "" } 492 }; 493 int i, ret; 494 int ntests = sizeof(tests) / sizeof(*tests); 495 496 for (i = 0; i < ntests; ++i) { 497 tests[i].val = &values[i]; 498 if (asprintf (&tests[i].name, "bit_string %d", i) < 0) 499 errx(1, "malloc"); 500 if (tests[i].name == NULL) 501 errx(1, "malloc"); 502 } 503 504 ret = generic_test (tests, ntests, sizeof(heim_bit_string), 505 (generic_encode)der_put_bit_string, 506 (generic_length)der_length_bit_string, 507 (generic_decode)der_get_bit_string, 508 (generic_free)der_free_bit_string, 509 test_cmp_bit_string, 510 NULL); 511 for (i = 0; i < ntests; ++i) 512 free(tests[i].name); 513 return ret; 514} 515 516static int 517test_cmp_heim_integer (void *a, void *b) 518{ 519 return der_heim_integer_cmp((heim_integer *)a, (heim_integer *)b); 520} 521 522static int 523test_heim_integer (void) 524{ 525 struct test_case tests[] = { 526 {NULL, 2, "\xfe\x01"}, 527 {NULL, 2, "\xef\x01"}, 528 {NULL, 3, "\xff\x00\xff"}, 529 {NULL, 3, "\xff\x01\x00"}, 530 {NULL, 1, "\x00"}, 531 {NULL, 1, "\x01"}, 532 {NULL, 2, "\x00\x80"} 533 }; 534 535 heim_integer values[] = { 536 { 2, "\x01\xff", 1 }, 537 { 2, "\x10\xff", 1 }, 538 { 2, "\xff\x01", 1 }, 539 { 2, "\xff\x00", 1 }, 540 { 0, "", 0 }, 541 { 1, "\x01", 0 }, 542 { 1, "\x80", 0 } 543 }; 544 int i, ret; 545 int ntests = sizeof(tests) / sizeof(tests[0]); 546 size_t size; 547 heim_integer i2; 548 549 for (i = 0; i < ntests; ++i) { 550 tests[i].val = &values[i]; 551 if (asprintf (&tests[i].name, "heim_integer %d", i) < 0) 552 errx(1, "malloc"); 553 if (tests[i].name == NULL) 554 errx(1, "malloc"); 555 } 556 557 ret = generic_test (tests, ntests, sizeof(heim_integer), 558 (generic_encode)der_put_heim_integer, 559 (generic_length)der_length_heim_integer, 560 (generic_decode)der_get_heim_integer, 561 (generic_free)der_free_heim_integer, 562 test_cmp_heim_integer, 563 NULL); 564 for (i = 0; i < ntests; ++i) 565 free (tests[i].name); 566 if (ret) 567 return ret; 568 569 /* test zero length integer (BER format) */ 570 ret = der_get_heim_integer(NULL, 0, &i2, &size); 571 if (ret) 572 errx(1, "der_get_heim_integer"); 573 if (i2.length != 0) 574 errx(1, "der_get_heim_integer wrong length"); 575 der_free_heim_integer(&i2); 576 577 return 0; 578} 579 580static int 581test_cmp_boolean (void *a, void *b) 582{ 583 return !!*(int *)a != !!*(int *)b; 584} 585 586static int 587test_boolean (void) 588{ 589 struct test_case tests[] = { 590 {NULL, 1, "\xff"}, 591 {NULL, 1, "\x00"} 592 }; 593 594 int values[] = { 1, 0 }; 595 int i, ret; 596 int ntests = sizeof(tests) / sizeof(tests[0]); 597 size_t size; 598 heim_integer i2; 599 600 for (i = 0; i < ntests; ++i) { 601 tests[i].val = &values[i]; 602 if (asprintf (&tests[i].name, "heim_boolean %d", i) < 0) 603 errx(1, "malloc"); 604 if (tests[i].name == NULL) 605 errx(1, "malloc"); 606 } 607 608 ret = generic_test (tests, ntests, sizeof(int), 609 (generic_encode)der_put_boolean, 610 (generic_length)der_length_boolean, 611 (generic_decode)der_get_boolean, 612 (generic_free)NULL, 613 test_cmp_boolean, 614 NULL); 615 for (i = 0; i < ntests; ++i) 616 free (tests[i].name); 617 if (ret) 618 return ret; 619 620 /* test zero length integer (BER format) */ 621 ret = der_get_heim_integer(NULL, 0, &i2, &size); 622 if (ret) 623 errx(1, "der_get_heim_integer"); 624 if (i2.length != 0) 625 errx(1, "der_get_heim_integer wrong length"); 626 der_free_heim_integer(&i2); 627 628 return 0; 629} 630 631static int 632check_fail_unsigned(void) 633{ 634 struct test_case tests[] = { 635 {NULL, sizeof(unsigned) + 1, 636 "\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" } 637 }; 638 int ntests = sizeof(tests) / sizeof(*tests); 639 640 return generic_decode_fail(tests, ntests, sizeof(unsigned), 641 (generic_decode)der_get_unsigned); 642} 643 644static int 645check_fail_integer(void) 646{ 647 struct test_case tests[] = { 648 {NULL, sizeof(int) + 1, 649 "\x01\x01\x01\x01\x01\x01\x01\x01\x01", "data overrun" } 650 }; 651 int ntests = sizeof(tests) / sizeof(*tests); 652 653 return generic_decode_fail(tests, ntests, sizeof(int), 654 (generic_decode)der_get_integer); 655} 656 657static int 658check_fail_length(void) 659{ 660 struct test_case tests[] = { 661 {NULL, 0, "", "empty input data"}, 662 {NULL, 1, "\x82", "internal length overrun" } 663 }; 664 int ntests = sizeof(tests) / sizeof(*tests); 665 666 return generic_decode_fail(tests, ntests, sizeof(size_t), 667 (generic_decode)der_get_length); 668} 669 670static int 671check_fail_boolean(void) 672{ 673 struct test_case tests[] = { 674 {NULL, 0, "", "empty input data"} 675 }; 676 int ntests = sizeof(tests) / sizeof(*tests); 677 678 return generic_decode_fail(tests, ntests, sizeof(int), 679 (generic_decode)der_get_boolean); 680} 681 682static int 683check_fail_general_string(void) 684{ 685 struct test_case tests[] = { 686 { NULL, 3, "A\x00i", "NUL char in string"} 687 }; 688 int ntests = sizeof(tests) / sizeof(*tests); 689 690 return generic_decode_fail(tests, ntests, sizeof(heim_general_string), 691 (generic_decode)der_get_general_string); 692} 693 694static int 695check_fail_bmp_string(void) 696{ 697 struct test_case tests[] = { 698 {NULL, 1, "\x00", "odd (1) length bmpstring"}, 699 {NULL, 3, "\x00\x00\x00", "odd (3) length bmpstring"} 700 }; 701 int ntests = sizeof(tests) / sizeof(*tests); 702 703 return generic_decode_fail(tests, ntests, sizeof(heim_bmp_string), 704 (generic_decode)der_get_bmp_string); 705} 706 707static int 708check_fail_universal_string(void) 709{ 710 struct test_case tests[] = { 711 {NULL, 1, "\x00", "x & 3 == 1 universal string"}, 712 {NULL, 2, "\x00\x00", "x & 3 == 2 universal string"}, 713 {NULL, 3, "\x00\x00\x00", "x & 3 == 3 universal string"}, 714 {NULL, 5, "\x00\x00\x00\x00\x00", "x & 3 == 1 universal string"}, 715 {NULL, 6, "\x00\x00\x00\x00\x00\x00", "x & 3 == 2 universal string"}, 716 {NULL, 7, "\x00\x00\x00\x00\x00\x00\x00", "x & 3 == 3 universal string"} 717 }; 718 int ntests = sizeof(tests) / sizeof(*tests); 719 720 return generic_decode_fail(tests, ntests, sizeof(heim_universal_string), 721 (generic_decode)der_get_universal_string); 722} 723 724static int 725check_fail_heim_integer(void) 726{ 727#if 0 728 struct test_case tests[] = { 729 }; 730 int ntests = sizeof(tests) / sizeof(*tests); 731 732 return generic_decode_fail(tests, ntests, sizeof(heim_integer), 733 (generic_decode)der_get_heim_integer); 734#else 735 return 0; 736#endif 737} 738 739static int 740check_fail_generalized_time(void) 741{ 742 struct test_case tests[] = { 743 {NULL, 1, "\x00", "no time"} 744 }; 745 int ntests = sizeof(tests) / sizeof(*tests); 746 747 return generic_decode_fail(tests, ntests, sizeof(time_t), 748 (generic_decode)der_get_generalized_time); 749} 750 751static int 752check_fail_oid(void) 753{ 754 struct test_case tests[] = { 755 {NULL, 0, "", "empty input data"}, 756 {NULL, 2, "\x00\x80", "last byte continuation" }, 757 {NULL, 11, "\x00\x81\x80\x80\x80\x80\x80\x80\x80\x80\x00", 758 "oid element overflow" } 759 }; 760 int ntests = sizeof(tests) / sizeof(*tests); 761 762 return generic_decode_fail(tests, ntests, sizeof(heim_oid), 763 (generic_decode)der_get_oid); 764} 765 766static int 767check_fail_bitstring(void) 768{ 769 struct test_case tests[] = { 770 {NULL, 0, "", "empty input data"}, 771 {NULL, 1, "\x08", "larger then 8 bits trailer"}, 772 {NULL, 1, "\x01", "to few bytes for bits"}, 773 {NULL, -2, "\x00", "length overrun"}, 774 {NULL, -1, "", "length to short"} 775 }; 776 int ntests = sizeof(tests) / sizeof(*tests); 777 778 return generic_decode_fail(tests, ntests, sizeof(heim_bit_string), 779 (generic_decode)der_get_bit_string); 780} 781 782static int 783check_heim_integer_same(const char *p, const char *norm_p, heim_integer *i) 784{ 785 heim_integer i2; 786 char *str; 787 int ret; 788 789 ret = der_print_hex_heim_integer(i, &str); 790 if (ret) 791 errx(1, "der_print_hex_heim_integer: %d", ret); 792 793 if (strcmp(str, norm_p) != 0) 794 errx(1, "der_print_hex_heim_integer: %s != %s", str, p); 795 796 ret = der_parse_hex_heim_integer(str, &i2); 797 if (ret) 798 errx(1, "der_parse_hex_heim_integer: %d", ret); 799 800 if (der_heim_integer_cmp(i, &i2) != 0) 801 errx(1, "der_heim_integer_cmp: p %s", p); 802 803 der_free_heim_integer(&i2); 804 free(str); 805 806 ret = der_parse_hex_heim_integer(p, &i2); 807 if (ret) 808 errx(1, "der_parse_hex_heim_integer: %d", ret); 809 810 if (der_heim_integer_cmp(i, &i2) != 0) 811 errx(1, "der_heim_integer_cmp: norm"); 812 813 der_free_heim_integer(&i2); 814 815 return 0; 816} 817 818static int 819test_heim_int_format(void) 820{ 821 heim_integer i = { 1, "\x10", 0 }; 822 heim_integer i2 = { 1, "\x10", 1 }; 823 heim_integer i3 = { 1, "\01", 0 }; 824 char *p = 825 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" 826 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" 827 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" 828 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" 829 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" 830 "FFFFFFFF" "FFFFFFFF"; 831 heim_integer bni = { 832 128, 833 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC9\x0F\xDA\xA2" 834 "\x21\x68\xC2\x34\xC4\xC6\x62\x8B\x80\xDC\x1C\xD1" 835 "\x29\x02\x4E\x08\x8A\x67\xCC\x74\x02\x0B\xBE\xA6" 836 "\x3B\x13\x9B\x22\x51\x4A\x08\x79\x8E\x34\x04\xDD" 837 "\xEF\x95\x19\xB3\xCD\x3A\x43\x1B\x30\x2B\x0A\x6D" 838 "\xF2\x5F\x14\x37\x4F\xE1\x35\x6D\x6D\x51\xC2\x45" 839 "\xE4\x85\xB5\x76\x62\x5E\x7E\xC6\xF4\x4C\x42\xE9" 840 "\xA6\x37\xED\x6B\x0B\xFF\x5C\xB6\xF4\x06\xB7\xED" 841 "\xEE\x38\x6B\xFB\x5A\x89\x9F\xA5\xAE\x9F\x24\x11" 842 "\x7C\x4B\x1F\xE6\x49\x28\x66\x51\xEC\xE6\x53\x81" 843 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 844 0 845 }; 846 heim_integer f; 847 int ret = 0; 848 849 ret += check_heim_integer_same(p, p, &bni); 850 ret += check_heim_integer_same("10", "10", &i); 851 ret += check_heim_integer_same("00000010", "10", &i); 852 ret += check_heim_integer_same("-10", "-10", &i2); 853 ret += check_heim_integer_same("-00000010", "-10", &i2); 854 ret += check_heim_integer_same("01", "01", &i3); 855 ret += check_heim_integer_same("1", "01", &i3); 856 857 { 858 int r; 859 r = der_parse_hex_heim_integer("-", &f); 860 if (r == 0) { 861 der_free_heim_integer(&f); 862 ret++; 863 } 864 /* used to cause UMR */ 865 r = der_parse_hex_heim_integer("00", &f); 866 if (r == 0) 867 der_free_heim_integer(&f); 868 else 869 ret++; 870 } 871 872 return ret; 873} 874 875static int 876test_heim_oid_format_same(const char *str, const heim_oid *oid) 877{ 878 int ret; 879 char *p; 880 heim_oid o2; 881 882 ret = der_print_heim_oid(oid, ' ', &p); 883 if (ret) { 884 printf("fail to print oid: %s\n", str); 885 return 1; 886 } 887 ret = strcmp(p, str); 888 if (ret) { 889 printf("oid %s != formated oid %s\n", str, p); 890 free(p); 891 return ret; 892 } 893 894 ret = der_parse_heim_oid(p, " ", &o2); 895 if (ret) { 896 printf("failed to parse %s\n", p); 897 free(p); 898 return ret; 899 } 900 free(p); 901 ret = der_heim_oid_cmp(&o2, oid); 902 der_free_oid(&o2); 903 904 return ret; 905} 906 907static unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 }; 908 909static int 910test_heim_oid_format(void) 911{ 912 heim_oid sha1 = { 6, sha1_oid_tree }; 913 int ret = 0; 914 915 ret += test_heim_oid_format_same("1 3 14 3 2 26", &sha1); 916 917 return ret; 918} 919 920static int 921check_trailing_nul(void) 922{ 923 int ret; 924 size_t i; 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", (int)i); 949 continue; 950 } 951 if (ret) 952 errx(1, "NULL check %d der_get_general_string failed", (int)i); 953 if (foo[i].size != size) 954 errx(1, "NUL check i = %d size failed", (int)i); 955 if (strcmp(foo[i].s, s) != 0) 956 errx(1, "NUL check i = %d content failed", (int)i); 957 free(s); 958 } 959 return 0; 960} 961 962static int 963test_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 1027static int 1028corner_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 1042static int 1043corner_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 ret; 1055 Der_class cl; 1056 Der_type ty; 1057 unsigned int tag; 1058 size_t size, i; 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 1074struct 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 } 1100#undef el 1101}; 1102 1103static void 1104asn1rand(uint8_t *rand, size_t len) 1105{ 1106 while (len) { 1107 *rand++ = arc4random(); 1108 len--; 1109 } 1110} 1111 1112static int 1113check_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 1172int 1173main(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