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