1 /* $OpenBSD: ber_test_int_i.c,v 1.6 2019/10/24 12:39:26 tb Exp $ 2 */ 3 /* 4 * Copyright (c) Rob Pierce <rob@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 21 #include <ber.h> 22 #include <errno.h> 23 #include <stdio.h> 24 #include <string.h> 25 26 #define SUCCEED 0 27 #define FAIL 1 28 29 struct test_vector { 30 int fail; /* 1 means test is expected to fail */ 31 char title[128]; 32 size_t input_length; 33 long long value; 34 unsigned char input[1024]; 35 size_t expect_length; 36 unsigned char expect[1024]; 37 }; 38 39 struct test_vector test_vectors[] = { 40 { 41 SUCCEED, 42 "integer (-9223372036854775807)", 43 10, 44 -9223372036854775807, 45 { 46 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 47 0x00, 0x01 48 }, 49 10, 50 { 51 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 52 0x00, 0x01 53 }, 54 }, 55 { 56 SUCCEED, 57 "integer (-9223372036854775806)", 58 10, 59 -9223372036854775806, 60 { 61 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 62 0x00, 0x02 63 }, 64 10, 65 { 66 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 67 0x00, 0x02 68 }, 69 }, 70 { 71 FAIL, 72 "integer (-2147483650) (expected failure)", 73 10, 74 -2147483650, 75 { 76 0x02, 0x08, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 77 0xff, 0xfe 78 }, 79 7, 80 { 81 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xfe 82 }, 83 }, 84 { 85 SUCCEED, 86 "integer (-2147483650)", 87 7, 88 -2147483650, 89 { 90 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xfe 91 }, 92 7, 93 { 94 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xfe 95 }, 96 }, 97 { 98 SUCCEED, 99 "integer (-2147483649)", 100 7, 101 -2147483649, 102 { 103 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xff 104 }, 105 7, 106 { 107 0x02, 0x05, 0xff, 0x7f, 0xff, 0xff, 0xff 108 }, 109 }, 110 { 111 FAIL, 112 "integer (-2147483648) (expected failure)", 113 8, 114 -2147483648, 115 { 116 0x02, 0x06, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 117 }, 118 6, 119 { 120 0x02, 0x04, 0x80, 0x00, 0x00, 0x00 121 }, 122 }, 123 { 124 SUCCEED, 125 "integer (-2147483648)", 126 6, 127 -2147483648, 128 { 129 0x02, 0x04, 0x80, 0x00, 0x00, 0x00 130 }, 131 6, 132 { 133 0x02, 0x04, 0x80, 0x00, 0x00, 0x00 134 }, 135 }, 136 { 137 SUCCEED, 138 "integer (-1073741824)", 139 6, 140 -1073741824, 141 { 142 0x02, 0x04, 0xc0, 0x00, 0x00, 0x00 143 }, 144 6, 145 { 146 0x02, 0x04, 0xc0, 0x00, 0x00, 0x00 147 }, 148 }, 149 { 150 SUCCEED, 151 "integer (-536870912)", 152 6, 153 -536870912, 154 { 155 0x02, 0x04, 0xe0, 0x00, 0x00, 0x00 156 }, 157 6, 158 { 159 0x02, 0x04, 0xe0, 0x00, 0x00, 0x00 160 }, 161 }, 162 { 163 SUCCEED, 164 "integer (-268435456)", 165 6, 166 -268435456, 167 { 168 0x02, 0x04, 0xf0, 0x00, 0x00, 0x00 169 }, 170 6, 171 { 172 0x02, 0x04, 0xf0, 0x00, 0x00, 0x00 173 }, 174 }, 175 { 176 SUCCEED, 177 "integer (-1342177728)", 178 6, 179 -1342177728, 180 { 181 0x02, 0x04, 0xaf, 0xff, 0xfe, 0x40 182 }, 183 6, 184 { 185 0x02, 0x04, 0xaf, 0xff, 0xfe, 0x40 186 }, 187 }, 188 { 189 SUCCEED, 190 "integer (-67108865)", 191 6, 192 -67108865, 193 { 194 0x02, 0x04, 0xfb, 0xff, 0xff, 0xff 195 }, 196 6, 197 { 198 0x02, 0x04, 0xfb, 0xff, 0xff, 0xff 199 }, 200 }, 201 { 202 SUCCEED, 203 "integer (-67108864)", 204 6, 205 -67108864, 206 { 207 0x02, 0x04, 0xfc, 0x00, 0x00, 0x00 208 }, 209 6, 210 { 211 0x02, 0x04, 0xfc, 0x00, 0x00, 0x00 212 }, 213 }, 214 { 215 SUCCEED, 216 "integer (-67108863)", 217 6, 218 -67108863, 219 { 220 0x02, 0x04, 0xfc, 0x00, 0x00, 0x01 221 }, 222 6, 223 { 224 0x02, 0x04, 0xfc, 0x00, 0x00, 0x01 225 }, 226 }, 227 { 228 SUCCEED, 229 "integer (-3554432)", 230 5, 231 -3554432, 232 { 233 0x02, 0x03, 0xc9, 0xc3, 0x80 234 }, 235 5, 236 { 237 0x02, 0x03, 0xc9, 0xc3, 0x80 238 }, 239 }, 240 { 241 SUCCEED, 242 "integer (-65535)", 243 5, 244 -65535, 245 { 246 0x02, 0x03, 0xff, 0x00, 0x01, 247 }, 248 5, 249 { 250 0x02, 0x03, 0xff, 0x00, 0x01, 251 }, 252 }, 253 { 254 SUCCEED, 255 "integer (-32769)", 256 5, 257 -32769, 258 { 259 0x02, 0x03, 0xff, 0x7f, 0xff 260 }, 261 5, 262 { 263 0x02, 0x03, 0xff, 0x7f, 0xff 264 }, 265 }, 266 { 267 SUCCEED, 268 "integer (-32768)", 269 4, 270 -32768, 271 { 272 0x02, 0x02, 0x80, 0x00 273 }, 274 4, 275 { 276 0x02, 0x02, 0x80, 0x00 277 }, 278 }, 279 { 280 SUCCEED, 281 "integer (-128)", 282 3, 283 -128, 284 { 285 0x02, 0x01, 0x80 286 }, 287 3, 288 { 289 0x02, 0x01, 0x80 290 }, 291 }, 292 { 293 SUCCEED, 294 "integer (-1)", 295 3, 296 -1, 297 { 298 0x02, 0x01, 0xff 299 }, 300 3, 301 { 302 0x02, 0x01, 0xff 303 }, 304 }, 305 { 306 SUCCEED, 307 "integer (0)", 308 3, 309 0, 310 { 311 0x02, 0x01, 0x00 312 }, 313 3, 314 { 315 0x02, 0x01, 0x00 316 }, 317 }, 318 { 319 SUCCEED, 320 "integer (127)", 321 3, 322 127, 323 { 324 0x02, 0x01, 0x7f 325 }, 326 3, 327 { 328 0x02, 0x01, 0x7f 329 }, 330 }, 331 { 332 SUCCEED, 333 "integer (128)", 334 4, 335 128, 336 { 337 0x02, 0x02, 0x00, 0x80 338 }, 339 4, 340 { 341 0x02, 0x02, 0x00, 0x80 342 }, 343 }, 344 { 345 SUCCEED, 346 "integer (32767)", 347 4, 348 32767, 349 { 350 0x02, 0x02, 0x7f, 0xff 351 }, 352 4, 353 { 354 0x02, 0x02, 0x7f, 0xff 355 }, 356 }, 357 { 358 SUCCEED, 359 "integer (32768)", 360 5, 361 32768, 362 { 363 0x02, 0x03, 0x00, 0x80, 0x00 364 }, 365 5, 366 { 367 0x02, 0x03, 0x00, 0x80, 0x00 368 }, 369 }, 370 { 371 SUCCEED, 372 "integer (65535)", 373 5, 374 65535, 375 { 376 0x02, 0x03, 0x00, 0xff, 0xff 377 }, 378 5, 379 { 380 0x02, 0x03, 0x00, 0xff, 0xff 381 }, 382 }, 383 { 384 SUCCEED, 385 "integer (65536)", 386 5, 387 65536, 388 { 389 0x02, 0x03, 0x01, 0x00, 0x00 390 }, 391 5, 392 { 393 0x02, 0x03, 0x01, 0x00, 0x00 394 }, 395 }, 396 { 397 SUCCEED, 398 "integer (2147483647)", 399 6, 400 2147483647, 401 { 402 0x02, 0x04, 0x7f, 0xff, 0xff, 0xff 403 }, 404 6, 405 { 406 0x02, 0x04, 0x7f, 0xff, 0xff, 0xff 407 }, 408 }, 409 { 410 SUCCEED, 411 "integer (2147483648)", 412 7, 413 2147483648, 414 { 415 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00 416 }, 417 7, 418 { 419 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00 420 }, 421 }, 422 { 423 SUCCEED, 424 "integer (2147483649)", 425 7, 426 2147483649, 427 { 428 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x01 429 }, 430 7, 431 { 432 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x01 433 }, 434 }, 435 { 436 SUCCEED, 437 "integer (4294967295)", 438 7, 439 4294967295, 440 { 441 0x02, 0x05, 0x00, 0xff, 0xff, 0xff, 0xff 442 }, 443 7, 444 { 445 0x02, 0x05, 0x00, 0xff, 0xff, 0xff, 0xff 446 }, 447 }, 448 { 449 SUCCEED, 450 "integer (4294967296)", 451 7, 452 4294967296, 453 { 454 0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 455 }, 456 7, 457 { 458 0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 459 }, 460 }, 461 { 462 SUCCEED, 463 "integer (4294967297)", 464 7, 465 4294967297, 466 { 467 0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x01 468 }, 469 7, 470 { 471 0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x01 472 }, 473 }, 474 { 475 SUCCEED, 476 "integer (9223372036854775806)", 477 10, 478 9223372036854775806, 479 { 480 0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 481 0xff, 0xfe 482 }, 483 10, 484 { 485 0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 486 0xff, 0xfe 487 }, 488 }, 489 { 490 SUCCEED, 491 "integer (9223372036854775807)", 492 10, 493 9223372036854775807, 494 { 495 0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 496 0xff, 0xff 497 }, 498 10, 499 { 500 0x02, 0x08, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 501 0xff, 0xff 502 }, 503 }, 504 }; 505 506 static void 507 hexdump(const unsigned char *buf, size_t len) 508 { 509 size_t i; 510 511 for (i = 1; i < len; i++) 512 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "": "\n"); 513 514 fprintf(stderr, " 0x%02hhx", buf[i - 1]); 515 fprintf(stderr, "\n"); 516 } 517 518 static int 519 test_read_elements(int i) 520 { 521 int pos, b; 522 char *string; 523 void *p = NULL; 524 ssize_t len = 0; 525 struct ber_element *elm = NULL, *ptr = NULL; 526 struct ber ber; 527 long long val; 528 void *bstring = NULL; 529 struct ber_oid oid; 530 struct ber_octetstring ostring; 531 532 bzero(&ber, sizeof(ber)); 533 ober_set_readbuf(&ber, test_vectors[i].input, 534 test_vectors[i].input_length); 535 536 elm = ober_read_elements(&ber, elm); 537 if (elm != NULL && test_vectors[i].fail == FAIL) { 538 printf("unexpectedly passed ober_read_elements\n"); 539 return 1; 540 } else if (elm == NULL && test_vectors[i].fail != FAIL) { 541 printf("unexpectedly failed ober_read_elements\n"); 542 return 1; 543 } else if (elm == NULL && test_vectors[i].fail == FAIL) 544 return 0; 545 546 pos = ober_getpos(elm); 547 if (pos != 2) { 548 printf("unexpected element position within " 549 "byte stream (%d)\n", pos); 550 return 1; 551 } 552 553 switch (elm->be_encoding) { 554 case BER_TYPE_INTEGER: 555 if (ober_get_integer(elm, &val) == -1) { 556 printf("failed (int) encoding check\n"); 557 return 1; 558 } 559 if (val != test_vectors[i].value) { 560 printf("(ober_get_integer) got %lld, expected %lld\n", 561 val, test_vectors[i].value); 562 return 1; 563 } 564 if (ober_scanf_elements(elm, "i", &val) == -1) { 565 printf("(ober_scanf_elements) failed (int)" 566 " ober_scanf_elements (i)\n"); 567 return 1; 568 } 569 if (val != test_vectors[i].value) { 570 printf("got %lld, expected %lld\n", val, 571 test_vectors[i].value); 572 return 1; 573 } 574 break; 575 default: 576 printf("failed with unexpected encoding (%ud)\n", 577 elm->be_encoding); 578 return 1; 579 } 580 581 len = ober_calc_len(elm); 582 if (len != test_vectors[i].expect_length) { 583 printf("failed to calculate length\n"); 584 printf("was %zd want %zu\n", len, 585 test_vectors[i].expect_length); 586 return 1; 587 } 588 589 ber.br_wbuf = NULL; 590 len = ober_write_elements(&ber, elm); 591 if (len != test_vectors[i].expect_length) { 592 printf("failed length check (was %zd want " 593 "%zd)\n", len, test_vectors[i].expect_length); 594 return 1; 595 } 596 597 if (memcmp(ber.br_wbuf, test_vectors[i].expect, 598 test_vectors[i].expect_length) != 0) { 599 printf("failed byte stream compare\n"); 600 printf("Got:\n"); 601 hexdump(ber.br_wbuf, len); 602 printf("Expected:\n"); 603 hexdump(test_vectors[i].expect, test_vectors[i].expect_length); 604 return 1; 605 } 606 ober_free(&ber); 607 608 ober_free_elements(elm); 609 610 return 0; 611 } 612 613 static int 614 test_printf_elements(int i) 615 { 616 int pos, b; 617 char *string; 618 void *p = NULL; 619 ssize_t len = 0; 620 struct ber_element *elm = NULL, *ptr = NULL; 621 struct ber ber; 622 long long val; 623 void *bstring = NULL; 624 struct ber_oid oid; 625 struct ber_octetstring ostring; 626 627 bzero(&ber, sizeof(ber)); 628 ober_set_readbuf(&ber, test_vectors[i].input, 629 test_vectors[i].input_length); 630 631 elm = ober_printf_elements(elm, "i", test_vectors[i].value); 632 if (elm == NULL) { 633 printf("unexpectedly failed ober_printf_elements\n"); 634 return 1; 635 } 636 637 switch (elm->be_encoding) { 638 case BER_TYPE_INTEGER: 639 if (ober_get_integer(elm, &val) == -1) { 640 printf("failed (int) encoding check\n"); 641 return 1; 642 } 643 if (val != test_vectors[i].value) { 644 printf("(ober_get_integer) got %lld, expected %lld\n", 645 val, test_vectors[i].value); 646 return 1; 647 } 648 if (ober_scanf_elements(elm, "i", &val) == -1) { 649 printf("(ober_scanf_elements) failed (int)" 650 " ober_scanf_elements (i)\n"); 651 return 1; 652 } 653 if (val != test_vectors[i].value) { 654 printf("got %lld, expected %lld\n", val, 655 test_vectors[i].value); 656 return 1; 657 } 658 break; 659 default: 660 printf("failed with unexpected encoding (%ud)\n", 661 elm->be_encoding); 662 return 1; 663 } 664 665 len = ober_calc_len(elm); 666 if (len != test_vectors[i].expect_length) { 667 printf("failed to calculate length\n"); 668 printf("was %zd want %zu\n", len, 669 test_vectors[i].expect_length); 670 return 1; 671 } 672 673 ber.br_wbuf = NULL; 674 len = ober_write_elements(&ber, elm); 675 if (len != test_vectors[i].expect_length) { 676 printf("failed length check (was %zd want " 677 "%zd)\n", len, test_vectors[i].expect_length); 678 return 1; 679 } 680 681 if (memcmp(ber.br_wbuf, test_vectors[i].expect, 682 test_vectors[i].expect_length) != 0) { 683 printf("failed byte stream compare\n"); 684 printf("Got:\n"); 685 hexdump(ber.br_wbuf, len); 686 printf("Expected:\n"); 687 hexdump(test_vectors[i].expect, test_vectors[i].expect_length); 688 return 1; 689 } 690 ober_free(&ber); 691 692 ober_free_elements(elm); 693 694 return 0; 695 } 696 697 int 698 main(void) 699 { 700 extern char *__progname; 701 702 ssize_t len = 0; 703 int i, ret = 0; 704 705 /* 706 * drive test vectors for ber byte stream input validation, etc. 707 */ 708 printf("= = = = = test_read_elements\n"); 709 for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) { 710 if (test_read_elements(i) != 0) { 711 printf("FAILED: %s\n", test_vectors[i].title); 712 ret = 1; 713 } else 714 printf("SUCCESS: %s\n", test_vectors[i].title); 715 } 716 717 printf("= = = = = test_printf_elements\n"); 718 for (i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); i++) { 719 /* 720 * skip test cases known to fail under ober_read_elements as 721 * they are not applicable to ober_printf_elements 722 */ 723 if (test_vectors[i].fail) 724 continue; 725 if (test_printf_elements(i) != 0) { 726 printf("FAILED: %s\n", test_vectors[i].title); 727 ret = 1; 728 } else 729 printf("SUCCESS: %s\n", test_vectors[i].title); 730 } 731 732 if (ret != 0) { 733 printf("FAILED: %s\n", __progname); 734 return 1; 735 } 736 737 return 0; 738 } 739