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