1 /* $OpenBSD: asn1basic.c,v 1.15 2023/08/15 21:05:44 tb Exp $ */ 2 /* 3 * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org> 4 * Copyright (c) 2023 Theo Buehler <tb@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 <openssl/asn1.h> 20 #include <openssl/err.h> 21 22 #include <err.h> 23 #include <stdio.h> 24 #include <string.h> 25 26 #include "asn1_local.h" 27 28 static void 29 hexdump(const unsigned char *buf, size_t len) 30 { 31 size_t i; 32 33 for (i = 1; i <= len; i++) 34 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); 35 36 fprintf(stderr, "\n"); 37 } 38 39 static int 40 asn1_compare_bytes(const char *label, const unsigned char *d1, int len1, 41 const unsigned char *d2, int len2) 42 { 43 if (len1 != len2) { 44 fprintf(stderr, "FAIL: %s - byte lengths differ " 45 "(%d != %d)\n", label, len1, len2); 46 fprintf(stderr, "Got:\n"); 47 hexdump(d1, len1); 48 fprintf(stderr, "Want:\n"); 49 hexdump(d2, len2); 50 return 0; 51 } 52 if (memcmp(d1, d2, len1) != 0) { 53 fprintf(stderr, "FAIL: %s - bytes differ\n", label); 54 fprintf(stderr, "Got:\n"); 55 hexdump(d1, len1); 56 fprintf(stderr, "Want:\n"); 57 hexdump(d2, len2); 58 return 0; 59 } 60 return 1; 61 } 62 63 const uint8_t asn1_bit_string_primitive[] = { 64 0x03, 0x07, 65 0x04, 0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0, 66 }; 67 68 static int 69 asn1_bit_string_test(void) 70 { 71 uint8_t bs[] = {0x0a, 0x3b, 0x5f, 0x29, 0x1c, 0xd0}; 72 ASN1_BIT_STRING *abs; 73 uint8_t *p = NULL, *pp; 74 const uint8_t *q; 75 int bit, i, len; 76 int failed = 1; 77 78 if ((abs = ASN1_BIT_STRING_new()) == NULL) { 79 fprintf(stderr, "FAIL: ASN1_BIT_STRING_new() == NULL\n"); 80 goto failed; 81 } 82 if (!ASN1_BIT_STRING_set(abs, bs, sizeof(bs))) { 83 fprintf(stderr, "FAIL: failed to set bit string\n"); 84 goto failed; 85 } 86 87 if ((len = i2d_ASN1_BIT_STRING(abs, NULL)) < 0) { 88 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING with NULL\n"); 89 goto failed; 90 } 91 if ((p = malloc(len)) == NULL) 92 errx(1, "malloc"); 93 memset(p, 0xbd, len); 94 pp = p; 95 if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) { 96 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); 97 goto failed; 98 } 99 if (!asn1_compare_bytes("BIT_STRING", p, len, asn1_bit_string_primitive, 100 sizeof(asn1_bit_string_primitive))) 101 goto failed; 102 if (pp != p + len) { 103 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING pp = %p, want %p\n", 104 pp, p + len); 105 goto failed; 106 } 107 108 /* Test primitive decoding. */ 109 q = p; 110 if (d2i_ASN1_BIT_STRING(&abs, &q, len) == NULL) { 111 fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING primitive\n"); 112 goto failed; 113 } 114 if (!asn1_compare_bytes("BIT_STRING primitive data", abs->data, abs->length, 115 bs, sizeof(bs))) 116 goto failed; 117 if (q != p + len) { 118 fprintf(stderr, "FAIL: d2i_ASN1_BIT_STRING q = %p, want %p\n", 119 q, p + len); 120 goto failed; 121 } 122 123 /* Test ASN1_BIT_STRING_get_bit(). */ 124 for (i = 0; i < ((int)sizeof(bs) * 8); i++) { 125 bit = (bs[i / 8] >> (7 - i % 8)) & 1; 126 127 if (ASN1_BIT_STRING_get_bit(abs, i) != bit) { 128 fprintf(stderr, "FAIL: ASN1_BIT_STRING_get_bit(_, %d) " 129 "= %d, want %d\n", i, 130 ASN1_BIT_STRING_get_bit(abs, i), bit); 131 goto failed; 132 } 133 } 134 135 /* Test ASN1_BIT_STRING_set_bit(). */ 136 for (i = 0; i < ((int)sizeof(bs) * 8); i++) { 137 if (!ASN1_BIT_STRING_set_bit(abs, i, 1)) { 138 fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit 1\n"); 139 goto failed; 140 } 141 } 142 for (i = ((int)sizeof(bs) * 8) - 1; i >= 0; i--) { 143 bit = (bs[i / 8] >> (7 - i % 8)) & 1; 144 if (bit == 1) 145 continue; 146 if (!ASN1_BIT_STRING_set_bit(abs, i, 0)) { 147 fprintf(stderr, "FAIL: ASN1_BIT_STRING_set_bit\n"); 148 goto failed; 149 } 150 } 151 152 if ((i2d_ASN1_BIT_STRING(abs, NULL)) != len) { 153 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); 154 goto failed; 155 } 156 157 memset(p, 0xbd, len); 158 pp = p; 159 if ((i2d_ASN1_BIT_STRING(abs, &pp)) != len) { 160 fprintf(stderr, "FAIL: i2d_ASN1_BIT_STRING\n"); 161 goto failed; 162 } 163 164 if (!asn1_compare_bytes("BIT_STRING set", p, len, asn1_bit_string_primitive, 165 sizeof(asn1_bit_string_primitive))) 166 goto failed; 167 168 failed = 0; 169 170 failed: 171 ASN1_BIT_STRING_free(abs); 172 free(p); 173 174 return failed; 175 } 176 177 const uint8_t asn1_boolean_false[] = { 178 0x01, 0x01, 0x00, 179 }; 180 const uint8_t asn1_boolean_true[] = { 181 0x01, 0x01, 0x01, 182 }; 183 184 static int 185 asn1_boolean_test(void) 186 { 187 uint8_t *p = NULL, *pp; 188 const uint8_t *q; 189 int len; 190 int failed = 1; 191 192 if ((len = i2d_ASN1_BOOLEAN(0, NULL)) < 0) { 193 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false with NULL\n"); 194 goto failed; 195 } 196 if ((p = malloc(len)) == NULL) 197 errx(1, "calloc"); 198 memset(p, 0xbd, len); 199 pp = p; 200 if ((i2d_ASN1_BOOLEAN(0, &pp)) != len) { 201 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN false\n"); 202 goto failed; 203 } 204 if (pp != p + len) { 205 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n", 206 pp, p + len); 207 goto failed; 208 } 209 210 if (!asn1_compare_bytes("BOOLEAN false", p, len, asn1_boolean_false, 211 sizeof(asn1_boolean_false))) 212 goto failed; 213 214 q = p; 215 if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 0) { 216 fprintf(stderr, "FAIL: BOOLEAN false did not decode to 0\n"); 217 goto failed; 218 } 219 if (q != p + len) { 220 fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n", 221 q, p + len); 222 goto failed; 223 } 224 225 free(p); 226 p = NULL; 227 228 if ((len = i2d_ASN1_BOOLEAN(1, NULL)) < 0) { 229 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true with NULL\n"); 230 goto failed; 231 } 232 if ((p = calloc(1, len)) == NULL) 233 errx(1, "calloc"); 234 pp = p; 235 if ((i2d_ASN1_BOOLEAN(1, &pp)) != len) { 236 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN true\n"); 237 goto failed; 238 } 239 if (pp != p + len) { 240 fprintf(stderr, "FAIL: i2d_ASN1_BOOLEAN pp = %p, want %p\n", 241 pp, p + len); 242 goto failed; 243 } 244 245 if (!asn1_compare_bytes("BOOLEAN true", p, len, asn1_boolean_true, 246 sizeof(asn1_boolean_true))) 247 goto failed; 248 249 q = p; 250 if (d2i_ASN1_BOOLEAN(NULL, &q, len) != 1) { 251 fprintf(stderr, "FAIL: BOOLEAN true did not decode to 1\n"); 252 goto failed; 253 } 254 if (q != p + len) { 255 fprintf(stderr, "FAIL: d2i_ASN1_BOOLEAN q = %p, want %p\n", 256 q, p + len); 257 goto failed; 258 } 259 260 failed = 0; 261 262 failed: 263 free(p); 264 265 return failed; 266 } 267 268 struct asn1_integer_test { 269 long value; 270 uint8_t content[64]; 271 size_t content_len; 272 int content_neg; 273 uint8_t der[64]; 274 size_t der_len; 275 int want_error; 276 }; 277 278 struct asn1_integer_test asn1_integer_tests[] = { 279 { 280 .value = 0, 281 .content = {0x00}, 282 .content_len = 1, 283 .der = {0x02, 0x01, 0x00}, 284 .der_len = 3, 285 }, 286 { 287 .value = 1, 288 .content = {0x01}, 289 .content_len = 1, 290 .der = {0x02, 0x01, 0x01}, 291 .der_len = 3, 292 }, 293 { 294 .value = -1, 295 .content = {0x01}, 296 .content_len = 1, 297 .content_neg = 1, 298 .der = {0x02, 0x01, 0xff}, 299 .der_len = 3, 300 }, 301 { 302 .value = 127, 303 .content = {0x7f}, 304 .content_len = 1, 305 .der = {0x02, 0x01, 0x7f}, 306 .der_len = 3, 307 }, 308 { 309 .value = -127, 310 .content = {0x7f}, 311 .content_len = 1, 312 .content_neg = 1, 313 .der = {0x02, 0x01, 0x81}, 314 .der_len = 3, 315 }, 316 { 317 .value = 128, 318 .content = {0x80}, 319 .content_len = 1, 320 .der = {0x02, 0x02, 0x00, 0x80}, 321 .der_len = 4, 322 }, 323 { 324 .value = -128, 325 .content = {0x80}, 326 .content_len = 1, 327 .content_neg = 1, 328 .der = {0x02, 0x01, 0x80}, 329 .der_len = 3, 330 }, 331 { 332 /* 2^64 */ 333 .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 334 .content_len = 9, 335 .der = {0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 336 .der_len = 11, 337 }, 338 { 339 /* -2^64 */ 340 .content = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 341 .content_len = 9, 342 .content_neg = 1, 343 .der = {0x02, 0x09, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 344 .der_len = 11, 345 }, 346 { 347 /* Invalid length. */ 348 .der = {0x02, 0x00}, 349 .der_len = 2, 350 .want_error = 1, 351 }, 352 { 353 /* Invalid padding. */ 354 .der = {0x02, 0x09, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 355 .der_len = 11, 356 .want_error = 1, 357 }, 358 { 359 /* Invalid padding. */ 360 .der = {0x02, 0x09, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 361 .der_len = 11, 362 .want_error = 1, 363 }, 364 { 365 /* Invalid encoding (constructed with definite length). */ 366 .der = {0x22, 0x03, 0x02, 0x01, 0x01}, 367 .der_len = 5, 368 .want_error = 1, 369 }, 370 { 371 /* Invalid encoding (constructed with indefinite length). */ 372 .der = {0x22, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00}, 373 .der_len = 7, 374 .want_error = 1, 375 }, 376 }; 377 378 #define N_ASN1_INTEGER_TESTS \ 379 (sizeof(asn1_integer_tests) / sizeof(*asn1_integer_tests)) 380 381 static int 382 asn1_integer_set_test(struct asn1_integer_test *ait) 383 { 384 ASN1_INTEGER *aint = NULL; 385 uint8_t *p = NULL, *pp; 386 int len; 387 int failed = 1; 388 389 if ((aint = ASN1_INTEGER_new()) == NULL) { 390 fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); 391 goto failed; 392 } 393 if (!ASN1_INTEGER_set(aint, ait->value)) { 394 fprintf(stderr, "FAIL: ASN1_INTEGER_(%ld) failed\n", 395 ait->value); 396 goto failed; 397 } 398 if (ait->value != 0 && 399 !asn1_compare_bytes("INTEGER set", aint->data, aint->length, 400 ait->content, ait->content_len)) 401 goto failed; 402 if (ait->content_neg && aint->type != V_ASN1_NEG_INTEGER) { 403 fprintf(stderr, "FAIL: Not V_ASN1_NEG_INTEGER\n"); 404 goto failed; 405 } 406 if (ASN1_INTEGER_get(aint) != ait->value) { 407 fprintf(stderr, "FAIL: ASN1_INTEGER_get() = %ld, want %ld\n", 408 ASN1_INTEGER_get(aint), ait->value); 409 goto failed; 410 } 411 if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) { 412 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 413 goto failed; 414 } 415 if ((p = malloc(len)) == NULL) 416 errx(1, "malloc"); 417 memset(p, 0xbd, len); 418 pp = p; 419 if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) { 420 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 421 goto failed; 422 } 423 if (!asn1_compare_bytes("INTEGER set", p, len, ait->der, 424 ait->der_len)) 425 goto failed; 426 427 failed = 0; 428 429 failed: 430 ASN1_INTEGER_free(aint); 431 free(p); 432 433 return failed; 434 } 435 436 static int 437 asn1_integer_content_test(struct asn1_integer_test *ait) 438 { 439 ASN1_INTEGER *aint = NULL; 440 uint8_t *p = NULL, *pp; 441 int len; 442 int failed = 1; 443 444 if ((aint = ASN1_INTEGER_new()) == NULL) { 445 fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); 446 goto failed; 447 } 448 if ((aint->data = malloc(ait->content_len)) == NULL) 449 errx(1, "malloc"); 450 memcpy(aint->data, ait->content, ait->content_len); 451 aint->length = ait->content_len; 452 if (ait->content_neg) 453 aint->type = V_ASN1_NEG_INTEGER; 454 455 if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) { 456 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 457 goto failed; 458 } 459 if ((p = malloc(len)) == NULL) 460 errx(1, "malloc"); 461 memset(p, 0xbd, len); 462 pp = p; 463 if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) { 464 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 465 goto failed; 466 } 467 if (!asn1_compare_bytes("INTEGER content", p, len, ait->der, 468 ait->der_len)) 469 goto failed; 470 if (pp != p + len) { 471 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER pp = %p, want %p\n", 472 pp, p + len); 473 goto failed; 474 } 475 476 failed = 0; 477 478 failed: 479 ASN1_INTEGER_free(aint); 480 free(p); 481 482 return failed; 483 } 484 485 static int 486 asn1_integer_decode_test(struct asn1_integer_test *ait) 487 { 488 ASN1_INTEGER *aint = NULL; 489 const uint8_t *q; 490 int failed = 1; 491 492 q = ait->der; 493 if (d2i_ASN1_INTEGER(&aint, &q, ait->der_len) != NULL) { 494 if (ait->want_error != 0) { 495 fprintf(stderr, "FAIL: INTEGER decoded when it should " 496 "have failed\n"); 497 goto failed; 498 } 499 if (!asn1_compare_bytes("INTEGER content", aint->data, 500 aint->length, ait->content, ait->content_len)) 501 goto failed; 502 if (q != ait->der + ait->der_len) { 503 fprintf(stderr, "FAIL: d2i_ASN1_INTEGER q = %p, want %p\n", 504 q, ait->der + ait->der_len); 505 goto failed; 506 } 507 } else if (ait->want_error == 0) { 508 fprintf(stderr, "FAIL: INTEGER failed to decode\n"); 509 ERR_print_errors_fp(stderr); 510 goto failed; 511 } 512 513 failed = 0; 514 515 failed: 516 ASN1_INTEGER_free(aint); 517 518 return failed; 519 } 520 521 static int 522 asn1_integer_set_val_test(void) 523 { 524 ASN1_INTEGER *aint = NULL; 525 uint64_t uval; 526 int64_t val; 527 int failed = 1; 528 529 if ((aint = ASN1_INTEGER_new()) == NULL) { 530 fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); 531 goto failed; 532 } 533 534 if (!ASN1_INTEGER_set_uint64(aint, 0)) { 535 fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with " 536 "0\n"); 537 goto failed; 538 } 539 if (!ASN1_INTEGER_get_uint64(&uval, aint)) { 540 fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with " 541 "0\n"); 542 goto failed; 543 } 544 if (uval != 0) { 545 fprintf(stderr, "FAIL: uval != 0\n"); 546 goto failed; 547 } 548 549 if (!ASN1_INTEGER_set_uint64(aint, UINT64_MAX)) { 550 fprintf(stderr, "FAIL: ASN_INTEGER_set_uint64() failed with " 551 "UINT64_MAX\n"); 552 goto failed; 553 } 554 if (!ASN1_INTEGER_get_uint64(&uval, aint)) { 555 fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with " 556 "UINT64_MAX\n"); 557 goto failed; 558 } 559 if (uval != UINT64_MAX) { 560 fprintf(stderr, "FAIL: uval != UINT64_MAX\n"); 561 goto failed; 562 } 563 if (ASN1_INTEGER_get_int64(&val, aint)) { 564 fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() succeeded " 565 "with UINT64_MAX\n"); 566 goto failed; 567 } 568 569 if (!ASN1_INTEGER_set_int64(aint, INT64_MIN)) { 570 fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with " 571 "INT64_MIN\n"); 572 goto failed; 573 } 574 if (!ASN1_INTEGER_get_int64(&val, aint)) { 575 fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with " 576 "INT64_MIN\n"); 577 goto failed; 578 } 579 if (val != INT64_MIN) { 580 fprintf(stderr, "FAIL: val != INT64_MIN\n"); 581 goto failed; 582 } 583 if (ASN1_INTEGER_get_uint64(&uval, aint)) { 584 fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() succeeded " 585 "with INT64_MIN\n"); 586 goto failed; 587 } 588 589 if (!ASN1_INTEGER_set_int64(aint, INT64_MAX)) { 590 fprintf(stderr, "FAIL: ASN_INTEGER_set_int64() failed with " 591 "INT64_MAX\n"); 592 goto failed; 593 } 594 if (!ASN1_INTEGER_get_int64(&val, aint)) { 595 fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with " 596 "INT64_MAX\n"); 597 goto failed; 598 } 599 if (val != INT64_MAX) { 600 fprintf(stderr, "FAIL: ASN_INTEGER_get_int64() failed with " 601 "INT64_MAX\n"); 602 goto failed; 603 } 604 if (!ASN1_INTEGER_get_uint64(&uval, aint)) { 605 fprintf(stderr, "FAIL: ASN_INTEGER_get_uint64() failed with " 606 "INT64_MAX\n"); 607 goto failed; 608 } 609 if (uval != INT64_MAX) { 610 fprintf(stderr, "FAIL: uval != INT64_MAX\n"); 611 goto failed; 612 } 613 614 failed = 0; 615 616 failed: 617 ASN1_INTEGER_free(aint); 618 619 return failed; 620 } 621 622 static int 623 asn1_integer_cmp_test(void) 624 { 625 ASN1_INTEGER *a = NULL, *b = NULL; 626 int failed = 1; 627 628 if ((a = ASN1_INTEGER_new()) == NULL) 629 goto failed; 630 if ((b = ASN1_INTEGER_new()) == NULL) 631 goto failed; 632 633 if (ASN1_INTEGER_cmp(a, b) != 0) { 634 fprintf(stderr, "FAIL: INTEGER 0 == 0"); 635 goto failed; 636 } 637 638 if (!ASN1_INTEGER_set(b, 1)) { 639 fprintf(stderr, "FAIL: failed to set INTEGER"); 640 goto failed; 641 } 642 if (ASN1_INTEGER_cmp(a, b) >= 0) { 643 fprintf(stderr, "FAIL: INTEGER 0 < 1"); 644 goto failed; 645 } 646 if (ASN1_INTEGER_cmp(b, a) <= 0) { 647 fprintf(stderr, "FAIL: INTEGER 1 > 0"); 648 goto failed; 649 } 650 651 if (!ASN1_INTEGER_set(b, -1)) { 652 fprintf(stderr, "FAIL: failed to set INTEGER"); 653 goto failed; 654 } 655 if (ASN1_INTEGER_cmp(a, b) <= 0) { 656 fprintf(stderr, "FAIL: INTEGER 0 > -1"); 657 goto failed; 658 } 659 if (ASN1_INTEGER_cmp(b, a) >= 0) { 660 fprintf(stderr, "FAIL: INTEGER -1 < 0"); 661 goto failed; 662 } 663 664 if (!ASN1_INTEGER_set(a, 1)) { 665 fprintf(stderr, "FAIL: failed to set INTEGER"); 666 goto failed; 667 } 668 if (ASN1_INTEGER_cmp(a, b) <= 0) { 669 fprintf(stderr, "FAIL: INTEGER 1 > -1"); 670 goto failed; 671 } 672 if (ASN1_INTEGER_cmp(b, a) >= 0) { 673 fprintf(stderr, "FAIL: INTEGER -1 < 1"); 674 goto failed; 675 } 676 677 if (!ASN1_INTEGER_set(b, 1)) { 678 fprintf(stderr, "FAIL: failed to set INTEGER"); 679 goto failed; 680 } 681 if (ASN1_INTEGER_cmp(a, b) != 0) { 682 fprintf(stderr, "FAIL: INTEGER 1 == 1"); 683 goto failed; 684 } 685 686 failed = 0; 687 688 failed: 689 ASN1_INTEGER_free(a); 690 ASN1_INTEGER_free(b); 691 692 return failed; 693 } 694 695 static int 696 asn1_integer_null_data_test(void) 697 { 698 const uint8_t der[] = {0x02, 0x01, 0x00}; 699 ASN1_INTEGER *aint = NULL; 700 uint8_t *p = NULL, *pp; 701 int len; 702 int failed = 0; 703 704 if ((aint = ASN1_INTEGER_new()) == NULL) { 705 fprintf(stderr, "FAIL: ASN1_INTEGER_new() == NULL\n"); 706 goto failed; 707 } 708 if ((len = i2d_ASN1_INTEGER(aint, NULL)) < 0) { 709 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 710 goto failed; 711 } 712 if ((p = calloc(1, len)) == NULL) 713 errx(1, "calloc"); 714 pp = p; 715 if ((len = i2d_ASN1_INTEGER(aint, &pp)) < 0) { 716 fprintf(stderr, "FAIL: i2d_ASN1_INTEGER() failed\n"); 717 goto failed; 718 } 719 if (!asn1_compare_bytes("INTEGER NULL data", p, len, der, sizeof(der))) 720 goto failed; 721 722 failed = 0; 723 724 failed: 725 ASN1_INTEGER_free(aint); 726 free(p); 727 728 return failed; 729 } 730 731 static int 732 asn1_integer_test(void) 733 { 734 struct asn1_integer_test *ait; 735 int failed = 0; 736 size_t i; 737 738 for (i = 0; i < N_ASN1_INTEGER_TESTS; i++) { 739 ait = &asn1_integer_tests[i]; 740 if (ait->content_len > 0 && ait->content_len <= 4) 741 failed |= asn1_integer_set_test(ait); 742 if (ait->content_len > 0) 743 failed |= asn1_integer_content_test(ait); 744 failed |= asn1_integer_decode_test(ait); 745 } 746 747 failed |= asn1_integer_cmp_test(); 748 failed |= asn1_integer_null_data_test(); 749 failed |= asn1_integer_set_val_test(); 750 751 return failed; 752 } 753 754 static const struct asn1_string_new_test { 755 const char *name; 756 ASN1_STRING *(*new)(void); 757 void (*free)(ASN1_STRING *); 758 int type; 759 long flags; 760 } asn1_string_new_tests[] = { 761 { 762 .name = "ASN1_STRING", 763 .new = ASN1_STRING_new, 764 .free = ASN1_STRING_free, 765 .type = V_ASN1_OCTET_STRING, 766 }, 767 { 768 .name = "ASN1_OCTET_STRING", 769 .new = ASN1_OCTET_STRING_new, 770 .free = ASN1_OCTET_STRING_free, 771 .type = V_ASN1_OCTET_STRING, 772 }, 773 { 774 .name = "ASN1_BIT_STRING", 775 .new = ASN1_BIT_STRING_new, 776 .free = ASN1_BIT_STRING_free, 777 .type = V_ASN1_BIT_STRING, 778 }, 779 { 780 .name = "ASN1_INTEGER", 781 .new = ASN1_INTEGER_new, 782 .free = ASN1_INTEGER_free, 783 .type = V_ASN1_INTEGER, 784 }, 785 { 786 .name = "ASN1_ENUMERATED", 787 .new = ASN1_ENUMERATED_new, 788 .free = ASN1_ENUMERATED_free, 789 .type = V_ASN1_ENUMERATED, 790 }, 791 { 792 .name = "ASN1_UTF8STRING", 793 .new = ASN1_UTF8STRING_new, 794 .free = ASN1_UTF8STRING_free, 795 .type = V_ASN1_UTF8STRING, 796 }, 797 { 798 .name = "ASN1_IA5STRING", 799 .new = ASN1_IA5STRING_new, 800 .free = ASN1_IA5STRING_free, 801 .type = V_ASN1_IA5STRING, 802 }, 803 { 804 .name = "ASN1_UNIVERSALSTRING", 805 .new = ASN1_UNIVERSALSTRING_new, 806 .free = ASN1_UNIVERSALSTRING_free, 807 .type = V_ASN1_UNIVERSALSTRING, 808 }, 809 { 810 .name = "ASN1_BMPSTRING", 811 .new = ASN1_BMPSTRING_new, 812 .free = ASN1_BMPSTRING_free, 813 .type = V_ASN1_BMPSTRING, 814 }, 815 { 816 .name = "ASN1_GENERALSTRING", 817 .new = ASN1_GENERALSTRING_new, 818 .free = ASN1_GENERALSTRING_free, 819 .type = V_ASN1_GENERALSTRING, 820 }, 821 { 822 .name = "ASN1_T61STRING", 823 .new = ASN1_T61STRING_new, 824 .free = ASN1_T61STRING_free, 825 .type = V_ASN1_T61STRING, 826 }, 827 { 828 .name = "ASN1_VISIBLESTRING", 829 .new = ASN1_VISIBLESTRING_new, 830 .free = ASN1_VISIBLESTRING_free, 831 .type = V_ASN1_VISIBLESTRING, 832 }, 833 { 834 .name = "ASN1_PRINTABLESTRING", 835 .new = ASN1_PRINTABLESTRING_new, 836 .free = ASN1_PRINTABLESTRING_free, 837 .type = V_ASN1_PRINTABLESTRING, 838 }, 839 { 840 .name = "ASN1_PRINTABLE", 841 .new = ASN1_PRINTABLE_new, 842 .free = ASN1_PRINTABLE_free, 843 .type = V_ASN1_UNDEF, 844 .flags = ASN1_STRING_FLAG_MSTRING, 845 }, 846 { 847 .name = "DIRECTORYSTRING", 848 .new = DIRECTORYSTRING_new, 849 .free = DIRECTORYSTRING_free, 850 .type = V_ASN1_UNDEF, 851 .flags = ASN1_STRING_FLAG_MSTRING, 852 }, 853 { 854 .name = "DISPLAYTEXT", 855 .new = DISPLAYTEXT_new, 856 .free = DISPLAYTEXT_free, 857 .type = V_ASN1_UNDEF, 858 .flags = ASN1_STRING_FLAG_MSTRING, 859 }, 860 { 861 .name = "ASN1_GENERALIZEDTIME", 862 .new = ASN1_GENERALIZEDTIME_new, 863 .free = ASN1_GENERALIZEDTIME_free, 864 .type = V_ASN1_GENERALIZEDTIME, 865 }, 866 { 867 .name = "ASN1_UTCTIME", 868 .new = ASN1_UTCTIME_new, 869 .free = ASN1_UTCTIME_free, 870 .type = V_ASN1_UTCTIME, 871 }, 872 { 873 .name = "ASN1_TIME", 874 .new = ASN1_TIME_new, 875 .free = ASN1_TIME_free, 876 .type = V_ASN1_UNDEF, 877 .flags = ASN1_STRING_FLAG_MSTRING, 878 }, 879 }; 880 881 #define N_ASN1_STRING_NEW_TESTS \ 882 (sizeof(asn1_string_new_tests) / sizeof(asn1_string_new_tests[0])) 883 884 static int 885 asn1_string_new_test(void) 886 { 887 size_t i; 888 ASN1_STRING *astr = NULL; 889 int failed = 1; 890 891 for (i = 0; i < N_ASN1_STRING_NEW_TESTS; i++) { 892 const struct asn1_string_new_test *asnt = &asn1_string_new_tests[i]; 893 894 if ((astr = asnt->new()) == NULL) { 895 fprintf(stderr, "%s_new() failed\n", asnt->name); 896 goto err; 897 } 898 if (ASN1_STRING_type(astr) != asnt->type) { 899 fprintf(stderr, "%s type: want %d, got %d\n", 900 asnt->name, asnt->type, ASN1_STRING_type(astr)); 901 goto err; 902 } 903 if (ASN1_STRING_data(astr) != NULL) { 904 fprintf(stderr, "%s data != NULL\n", asnt->name); 905 goto err; 906 } 907 if (ASN1_STRING_get0_data(astr) != NULL) { 908 fprintf(stderr, "%s data != NULL\n", asnt->name); 909 goto err; 910 } 911 if (ASN1_STRING_length(astr) != 0) { 912 fprintf(stderr, "%s length %d != 0\n", asnt->name, 913 ASN1_STRING_length(astr)); 914 goto err; 915 } 916 ASN1_STRING_length_set(astr, 20); 917 if (ASN1_STRING_length(astr) != 20) { 918 fprintf(stderr, "%s length %d != 20\n", asnt->name, 919 ASN1_STRING_length(astr)); 920 goto err; 921 } 922 astr->flags |= ASN1_STRING_FLAG_NDEF; 923 if (astr->flags != (asnt->flags | ASN1_STRING_FLAG_NDEF)) { 924 fprintf(stderr, "%s flags: %lx\n", asnt->name, 925 astr->flags); 926 goto err; 927 } 928 /* ASN1_STRING_set0() clears ASN1_STRING_FLAG_NDEF. */ 929 ASN1_STRING_set0(astr, NULL, 0); 930 if (astr->flags != asnt->flags) { 931 fprintf(stderr, "%s flags: %lx != %lx\n", asnt->name, 932 astr->flags, asnt->flags); 933 goto err; 934 } 935 asnt->free(astr); 936 astr = NULL; 937 938 if ((astr = ASN1_STRING_type_new(asnt->type)) == NULL) { 939 fprintf(stderr, "ASN1_STRING_type_new(%s) failed\n", 940 asnt->name); 941 goto err; 942 } 943 if (ASN1_STRING_type(astr) != asnt->type) { 944 fprintf(stderr, "%s type: want %d, got %d\n", 945 asnt->name, asnt->type, ASN1_STRING_type(astr)); 946 goto err; 947 } 948 if (ASN1_STRING_data(astr) != NULL) { 949 fprintf(stderr, "%s data != NULL\n", asnt->name); 950 goto err; 951 } 952 /* ASN1_STRING_type_new() does not set flags. */ 953 if (astr->flags != 0) { 954 fprintf(stderr, "%s flags %lx\n", asnt->name, 955 astr->flags); 956 goto err; 957 } 958 asnt->free(astr); 959 astr = NULL; 960 961 } 962 963 failed = 0; 964 965 err: 966 ASN1_STRING_free(astr); 967 968 return failed; 969 } 970 971 static char *comparison_str = "mystring"; 972 973 static int 974 asn1_string_cmp_test(void) 975 { 976 ASN1_STRING *a = NULL, *b = NULL; 977 int got, want; 978 int failed = 1; 979 980 if ((got = ASN1_STRING_cmp(NULL, NULL)) != -1) { 981 fprintf(stderr, "ASN1_STRING_cmp(NULL, NULL): %d != -1\n", got); 982 goto err; 983 } 984 985 if ((a = ASN1_STRING_new()) == NULL) { 986 fprintf(stderr, "a = ASN1_STRING_new() failed\n"); 987 goto err; 988 } 989 if ((b = ASN1_STRING_type_new(V_ASN1_UTF8STRING)) == NULL) { 990 fprintf(stderr, "b = ASN1_STRING_type_new() failed\n"); 991 goto err; 992 } 993 994 if ((got = ASN1_STRING_cmp(a, NULL)) != -1) { 995 fprintf(stderr, "ASN1_STRING_cmp(a, NULL): %d != -1\n", got); 996 goto err; 997 } 998 if ((got = ASN1_STRING_cmp(NULL, a)) != -1) { 999 fprintf(stderr, "ASN1_STRING_cmp(NULL, a): %d != -1\n", got); 1000 goto err; 1001 } 1002 1003 if (ASN1_STRING_cmp(a, b) >= 0) { 1004 fprintf(stderr, "V_ASN1_OCTET_STRING >= V_ASN1_UTF8STRING\n"); 1005 goto err; 1006 } 1007 want = V_ASN1_UTF8STRING - V_ASN1_OCTET_STRING; 1008 if ((got = ASN1_STRING_cmp(b, a)) != want) { 1009 fprintf(stderr, "comparison of octet with utf8 string:" 1010 "want %d, got %d\n", want, got); 1011 goto err; 1012 } 1013 1014 ASN1_STRING_set0(a, comparison_str, strlen(comparison_str)); 1015 ASN1_STRING_set0(b, comparison_str, strlen(comparison_str)); 1016 1017 /* Ensure any data set on a or b isn't freed/zeroed. */ 1018 a->flags |= ASN1_STRING_FLAG_NDEF; 1019 b->flags |= ASN1_STRING_FLAG_NDEF; 1020 1021 if ((got = ASN1_STRING_cmp(b, a)) != want) { 1022 fprintf(stderr, "comparison of octet with utf8 string:" 1023 "want %d, got %d\n", want, got); 1024 goto err; 1025 } 1026 1027 b->type = V_ASN1_OCTET_STRING; 1028 1029 if ((got = ASN1_STRING_cmp(a, b)) != 0) { 1030 fprintf(stderr, "same string on both. want 0, got %d\n", got); 1031 goto err; 1032 } 1033 1034 if (!ASN1_STRING_set(b, "myString", -1)) { 1035 fprintf(stderr, "ASN1_STRING_set(b) failed\n"); 1036 goto err; 1037 } 1038 1039 if ((got = ASN1_STRING_cmp(a, b)) <= 0) { 1040 fprintf(stderr, "capitalized letter compares larger: got %d\n", 1041 got); 1042 goto err; 1043 } 1044 if ((got = ASN1_STRING_cmp(b, a)) >= 0) { 1045 fprintf(stderr, "capitalized letter is larger 2: %d\n", got); 1046 goto err; 1047 } 1048 1049 ASN1_STRING_length_set(b, 2); 1050 1051 want = strlen(comparison_str) - 2; 1052 1053 if ((got = ASN1_STRING_cmp(a, b)) != want) { 1054 fprintf(stderr, "comparison of a with truncated b: " 1055 "want %d, got %d\n", want, got); 1056 goto err; 1057 } 1058 1059 want = -want; 1060 1061 if ((got = ASN1_STRING_cmp(b, a)) != want) { 1062 fprintf(stderr, "comparison of truncated b with a: " 1063 "want %d, got %d\n", want, got); 1064 goto err; 1065 } 1066 1067 ASN1_STRING_length_set(a, 2); 1068 1069 if ((got = ASN1_STRING_cmp(a, b)) != 0) { 1070 fprintf(stderr, "both truncated compared to %d\n", got); 1071 goto err; 1072 } 1073 1074 ASN1_STRING_length_set(a, strlen(comparison_str)); 1075 1076 ASN1_STRING_set0(b, NULL, 0); 1077 1078 want = strlen(comparison_str); 1079 if ((got = ASN1_STRING_cmp(a, b)) != want) { 1080 fprintf(stderr, "comparison of a with zeroed b: " 1081 "want %d, got %d\n", want, got); 1082 goto err; 1083 } 1084 1085 ASN1_STRING_set0(b, "", 0); 1086 b->flags |= ASN1_STRING_FLAG_NDEF; 1087 1088 if ((got = ASN1_STRING_cmp(a, b)) != want) { 1089 fprintf(stderr, "comparison of a with zero-length b: " 1090 "want %d, got %d\n", want, got); 1091 goto err; 1092 } 1093 1094 ASN1_STRING_set0(a, NULL, 0); 1095 if ((got = ASN1_STRING_cmp(a, b)) != 0) { 1096 fprintf(stderr, "comparison of zeroed a with zero-length b: " 1097 "want 0, got %d\n", got); 1098 goto err; 1099 } 1100 if ((got = ASN1_STRING_cmp(b, a)) != 0) { 1101 fprintf(stderr, "comparison of zero-length b with zeroed a: " 1102 "want 0, got %d\n", got); 1103 goto err; 1104 } 1105 1106 failed = 0; 1107 1108 err: 1109 ASN1_STRING_free(a); 1110 ASN1_STRING_free(b); 1111 1112 return failed; 1113 } 1114 1115 static int 1116 asn1_string_test(void) 1117 { 1118 int failed = 0; 1119 1120 failed |= asn1_string_new_test(); 1121 failed |= asn1_string_cmp_test(); 1122 1123 return failed; 1124 } 1125 1126 int 1127 main(int argc, char **argv) 1128 { 1129 int failed = 0; 1130 1131 failed |= asn1_bit_string_test(); 1132 failed |= asn1_boolean_test(); 1133 failed |= asn1_integer_test(); 1134 failed |= asn1_string_test(); 1135 1136 return (failed); 1137 } 1138