1 /* $OpenBSD: rfc3779.c,v 1.10 2023/12/13 07:19:37 tb Exp $ */ 2 /* 3 * Copyright (c) 2021 Theo Buehler <tb@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <stdio.h> 19 #include <string.h> 20 21 #include <openssl/asn1.h> 22 #include <openssl/asn1t.h> 23 #include <openssl/x509v3.h> 24 25 #define RAW_ADDRESS_SIZE 16 26 27 static void 28 hexdump(const unsigned char *buf, size_t len) 29 { 30 size_t i; 31 32 for (i = 1; i <= len; i++) 33 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); 34 35 if (len % 8) 36 fprintf(stderr, "\n"); 37 } 38 39 static void 40 report_hexdump(const char *func, const char *description, const char *msg, 41 const unsigned char *want, size_t want_len, 42 const unsigned char *got, size_t got_len) 43 { 44 fprintf(stderr, "%s: \"%s\" %s\nwant:\n", func, description, msg); 45 hexdump(want, want_len); 46 fprintf(stderr, "got:\n"); 47 hexdump(got, got_len); 48 } 49 50 static int 51 afi_size(int afi) 52 { 53 switch (afi) { 54 case IANA_AFI_IPV4: 55 return 4; 56 case IANA_AFI_IPV6: 57 return 16; 58 } 59 return 0; 60 } 61 62 struct IPAddressOrRange_test { 63 const char *description; 64 const uint8_t der[32]; 65 size_t der_len; 66 unsigned afi; 67 const uint8_t min[RAW_ADDRESS_SIZE]; 68 const uint8_t max[RAW_ADDRESS_SIZE]; 69 }; 70 71 const struct IPAddressOrRange_test IPAddressOrRange_test_data[] = { 72 /* Examples from RFC 3779, section 2.1.1 */ 73 { 74 .description = "address 10.5.0.4", 75 .der = { 76 0x03, 0x05, 0x00, 0x0a, 0x05, 0x00, 0x04, 77 }, 78 .der_len = 7, 79 .afi = IANA_AFI_IPV4, 80 .min = { 81 0x0a, 0x05, 0x00, 0x04, 82 }, 83 .max = { 84 0x0a, 0x05, 0x00, 0x04, 85 } 86 }, 87 { 88 .description = "prefix 10.5.0/23", 89 .der = { 90 0x03, 0x04, 0x01, 0x0a, 0x05, 0x00, 91 }, 92 .der_len = 6, 93 .afi = IANA_AFI_IPV4, 94 .min = { 95 0x0a, 0x05, 0x00, 0x00, 96 }, 97 .max = { 98 0x0a, 0x05, 0x01, 0xff, 99 } 100 }, 101 { 102 .description = "address 2001:0:200:3::1", 103 .der = { 104 0x03, 0x11, 0x00, 0x20, 0x01, 0x00, 0x00, 0x02, 105 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 106 0x00, 0x00, 0x01, 107 }, 108 .der_len = 19, 109 .afi = IANA_AFI_IPV6, 110 .min = { 111 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 113 }, 114 .max = { 115 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 117 }, 118 }, 119 { 120 .description = "prefix 2001:0:200/39", 121 .der = { 122 0x03, 0x06, 0x01, 0x20, 0x01, 0x00, 0x00, 0x02, 123 }, 124 .der_len = 8, 125 .afi = IANA_AFI_IPV6, 126 .min = { 127 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 129 }, 130 .max = { 131 0x20, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 133 }, 134 }, 135 136 /* Examples from RFC 3779, Section 2.1.2 */ 137 { 138 .description = "prefix 10.5.0/23 as a range", 139 .der = { 140 /* Sequence */ 141 0x30, 0x0b, 142 /* 10.5.0.0 */ 143 0x03, 0x03, 0x00, 0x0a, 0x05, 144 /* 10.5.1.255 */ 145 0x03, 0x04, 0x01, 0x0a, 0x05, 0x00, 146 }, 147 .der_len = 13, 148 .afi = IANA_AFI_IPV4, 149 .min = { 150 0x0a, 0x05, 0x00, 0x00, 151 }, 152 .max = { 153 0x0a, 0x05, 0x01, 0xff, 154 } 155 }, 156 { 157 .description = "prefix 2001:0:200/39 as a range", 158 .der = { 159 /* Sequence */ 160 0x30, 0x10, 161 /* 2001:0:200:: */ 162 0x03, 0x06, 0x01, 0x20, 0x01, 0x00, 0x00, 0x02, 163 /* 2001:0:3ff:ffff:ffff:ffff:ffff:ffff */ 164 0x03, 0x06, 0x02, 0x20, 0x01, 0x00, 0x00, 0x00, 165 }, 166 .der_len = 18, 167 .afi = IANA_AFI_IPV6, 168 .min = { 169 0x20, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 171 }, 172 .max = { 173 0x20, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 174 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 175 } 176 }, 177 { 178 .description = "prefix 0/0", 179 .der = { 180 0x03, 0x01, 0x00, 181 }, 182 .der_len = 3, 183 .afi = IANA_AFI_IPV4, 184 .min = { 185 0x00, 0x00, 0x00, 0x00, 186 }, 187 .max = { 188 0xff, 0xff, 0xff, 0xff, 189 } 190 }, 191 { 192 .description = "prefix 10.64/12", 193 .der = { 194 0x03, 0x03, 0x04, 0x0a, 0x40, 195 }, 196 .der_len = 5, 197 .afi = IANA_AFI_IPV4, 198 .min = { 199 0x0a, 0x40, 0x00, 0x00, 200 }, 201 .max = { 202 0x0a, 0x4f, 0xff, 0xff, 203 }, 204 }, 205 { 206 .description = "prefix 10.64/20", 207 .der = { 208 0x03, 0x04, 0x04, 0x0a, 0x40, 0x00, 209 }, 210 .der_len = 6, 211 .afi = IANA_AFI_IPV4, 212 .min = { 213 0x0a, 0x40, 0x00, 0x00, 214 }, 215 .max = { 216 0x0a, 0x40, 0x0f, 0xff, 217 }, 218 }, 219 }; 220 221 const size_t N_IPADDRESSORRANGE_TESTS = 222 sizeof(IPAddressOrRange_test_data) / sizeof(IPAddressOrRange_test_data[0]); 223 224 static int 225 test_IPAddressOrRange(const struct IPAddressOrRange_test *test) 226 { 227 IPAddressOrRange *aor; 228 const unsigned char *p; 229 unsigned char min[RAW_ADDRESS_SIZE] = {0}, max[RAW_ADDRESS_SIZE] = {0}; 230 unsigned char *out = NULL; 231 int out_len; 232 int afi_len; 233 int memcmp_failed = 0; 234 int failed = 1; 235 236 /* 237 * First, decode DER from the test case. 238 */ 239 240 p = &test->der[0]; 241 if ((aor = d2i_IPAddressOrRange(NULL, &p, test->der_len)) == NULL) { 242 fprintf(stderr, "%s: \"%s\" d2i_IPAddressOrRange failed\n", 243 __func__, test->description); 244 goto err; 245 } 246 247 /* 248 * Now extract minimum and maximum from the parsed range. 249 */ 250 251 afi_len = afi_size(test->afi); 252 253 if (X509v3_addr_get_range(aor, test->afi, min, max, sizeof min) != 254 afi_len) { 255 fprintf(stderr, "%s: \"%s\" X509v3_addr_get_range failed\n", 256 __func__, test->description); 257 goto err; 258 } 259 260 /* 261 * Check that min and max match expectations. 262 */ 263 264 if (memcmp(min, test->min, afi_len) != 0) { 265 memcmp_failed |= 1; 266 report_hexdump(__func__, test->description, "memcmp min failed", 267 test->min, afi_len, min, afi_len); 268 } 269 if (memcmp(max, test->max, afi_len) != 0) { 270 memcmp_failed |= 1; 271 report_hexdump(__func__, test->description, "memcmp max failed", 272 test->max, afi_len, max, afi_len); 273 } 274 if (memcmp_failed) 275 goto err; 276 277 /* 278 * Now turn the parsed IPAddressOrRange back into DER and check that 279 * it matches the DER in the test case. 280 */ 281 282 out = NULL; 283 if ((out_len = i2d_IPAddressOrRange(aor, &out)) <= 0) { 284 fprintf(stderr, "%s: \"%s\" i2d_IPAddressOrRange failed\n", 285 __func__, test->description); 286 goto err; 287 } 288 289 memcmp_failed = (size_t)out_len != test->der_len; 290 if (!memcmp_failed) 291 memcmp_failed = memcmp(test->der, out, out_len); 292 293 if (memcmp_failed) { 294 report_hexdump(__func__, test->description, "memcmp DER failed", 295 test->der, test->der_len, out, out_len); 296 goto err; 297 } 298 299 failed = 0; 300 err: 301 IPAddressOrRange_free(aor); 302 free(out); 303 304 return failed; 305 } 306 307 static int 308 run_IPAddressOrRange_tests(void) 309 { 310 size_t i; 311 int failed = 0; 312 313 for (i = 0; i < N_IPADDRESSORRANGE_TESTS; i++) 314 failed |= 315 test_IPAddressOrRange(&IPAddressOrRange_test_data[i]); 316 317 return failed; 318 } 319 320 /* 321 * XXX: These should really be part of the public API... 322 */ 323 static IPAddrBlocks *IPAddrBlocks_new(void); 324 static void IPAddrBlocks_free(IPAddrBlocks *addr); 325 static IPAddrBlocks *d2i_IPAddrBlocks(IPAddrBlocks **addrs, 326 const unsigned char **in, long len); 327 static int i2d_IPAddrBlocks(IPAddrBlocks *addrs, unsigned char **out); 328 329 static IPAddrBlocks * 330 IPAddrBlocks_new(void) 331 { 332 IPAddrBlocks *addrs; 333 334 /* 335 * XXX The comparison function IPAddressFamily_cmp() isn't public. 336 * Start with the default and exploit a side effect of the lovely API 337 * which helpfully sets the correct function in a few places. Let's 338 * use the cheapest and easiest to reach one. 339 */ 340 if ((addrs = sk_IPAddressFamily_new_null()) == NULL) 341 return NULL; 342 if (!X509v3_addr_canonize(addrs)) { 343 IPAddrBlocks_free(addrs); 344 return NULL; 345 } 346 347 return addrs; 348 } 349 350 static void 351 IPAddrBlocks_free(IPAddrBlocks *addr) 352 { 353 sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); 354 } 355 356 /* 357 * We want {d2i,i2d}_IPAddrBlocks() to play with the DER of the extension. 358 * These don't exist, so we have to implement them ourselves. IPAddrBlocks_it 359 * isn't public, so we need to fetch it from the library. We cache it in a 360 * static variable to avoid the cost of a binary search through all supported 361 * extensions on each call. 362 */ 363 364 static ASN1_ITEM_EXP * 365 get_IPAddrBlocks_it(void) 366 { 367 static ASN1_ITEM_EXP *my_IPAddrBlocks_it; 368 const X509V3_EXT_METHOD *v3_addr; 369 370 if (my_IPAddrBlocks_it != NULL) 371 return my_IPAddrBlocks_it; 372 373 if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL) { 374 fprintf(stderr, "could not get v3_addr\n"); 375 return NULL; 376 } 377 378 my_IPAddrBlocks_it = v3_addr->it; 379 380 return my_IPAddrBlocks_it; 381 } 382 383 static IPAddrBlocks * 384 d2i_IPAddrBlocks(IPAddrBlocks **addrs, const unsigned char **in, long len) 385 { 386 ASN1_ITEM_EXP *my_IPAddrBlocks_it; 387 388 if ((my_IPAddrBlocks_it = get_IPAddrBlocks_it()) == NULL) 389 return NULL; 390 391 return (IPAddrBlocks *)ASN1_item_d2i((ASN1_VALUE **)addrs, in, len, 392 my_IPAddrBlocks_it); 393 } 394 395 static int 396 i2d_IPAddrBlocks(IPAddrBlocks *addrs, unsigned char **out) 397 { 398 ASN1_ITEM_EXP *my_IPAddrBlocks_it; 399 400 if ((my_IPAddrBlocks_it = get_IPAddrBlocks_it()) == NULL) 401 return -1; 402 403 return ASN1_item_i2d((ASN1_VALUE *)addrs, out, my_IPAddrBlocks_it); 404 } 405 406 struct ipv4_prefix { 407 unsigned char addr[4]; 408 size_t addr_len; 409 size_t prefix_len; 410 }; 411 412 struct ipv4_range { 413 unsigned char min[4]; 414 unsigned char max[4]; 415 }; 416 417 union ipv4_choice { 418 struct ipv4_prefix prefix; 419 struct ipv4_range range; 420 }; 421 422 struct ipv6_prefix { 423 unsigned char addr[16]; 424 size_t addr_len; 425 size_t prefix_len; 426 }; 427 428 struct ipv6_range { 429 unsigned char min[16]; 430 unsigned char max[16]; 431 }; 432 433 union ipv6_choice { 434 struct ipv6_prefix prefix; 435 struct ipv6_range range; 436 }; 437 438 enum choice_type { 439 choice_prefix, 440 choice_range, 441 choice_inherit, 442 choice_last, 443 }; 444 445 union ip { 446 union ipv4_choice ipv4; 447 union ipv6_choice ipv6; 448 }; 449 450 enum safi { 451 safi_none, 452 safi_unicast, 453 safi_multicast, 454 }; 455 456 struct ip_addr_block { 457 unsigned int afi; 458 enum safi safi; 459 enum choice_type type; 460 union ip addr; 461 }; 462 463 struct build_addr_block_test_data { 464 char *description; 465 struct ip_addr_block addrs[16]; 466 char der[128]; 467 size_t der_len; 468 int is_canonical; 469 int inherits; 470 unsigned int afis[4]; 471 int afi_len; 472 }; 473 474 const struct build_addr_block_test_data build_addr_block_tests[] = { 475 { 476 .description = "RFC 3779, Appendix B, example 1", 477 .addrs = { 478 { 479 .afi = IANA_AFI_IPV4, 480 .safi = safi_unicast, 481 .type = choice_prefix, 482 .addr.ipv4.prefix = { 483 .addr = { 484 10, 0, 32, 485 }, 486 .addr_len = 3, 487 .prefix_len = 20, 488 }, 489 }, 490 { 491 .afi = IANA_AFI_IPV4, 492 .safi = safi_unicast, 493 .type = choice_prefix, 494 .addr.ipv4.prefix = { 495 .addr = { 496 10, 0, 64, 497 }, 498 .addr_len = 3, 499 .prefix_len = 24, 500 }, 501 }, 502 { 503 .afi = IANA_AFI_IPV4, 504 .safi = safi_unicast, 505 .type = choice_prefix, 506 .addr.ipv4.prefix = { 507 .addr = { 508 10, 1, 509 }, 510 .addr_len = 2, 511 .prefix_len = 16, 512 }, 513 }, 514 { 515 .afi = IANA_AFI_IPV4, 516 .safi = safi_unicast, 517 .type = choice_prefix, 518 .addr.ipv4.prefix = { 519 .addr = { 520 10, 2, 48, 521 }, 522 .addr_len = 3, 523 .prefix_len = 20, 524 }, 525 }, 526 { 527 .afi = IANA_AFI_IPV4, 528 .safi = safi_unicast, 529 .type = choice_prefix, 530 .addr.ipv4.prefix = { 531 .addr = { 532 10, 2, 64, 533 }, 534 .addr_len = 3, 535 .prefix_len = 24, 536 }, 537 }, 538 { 539 .afi = IANA_AFI_IPV4, 540 .safi = safi_unicast, 541 .type = choice_prefix, 542 .addr.ipv4.prefix = { 543 .addr = { 544 10, 3, 545 }, 546 .addr_len = 2, 547 .prefix_len = 16, 548 }, 549 }, 550 { 551 .afi = IANA_AFI_IPV6, 552 .safi = safi_none, 553 .type = choice_inherit, 554 }, 555 { 556 .type = choice_last, 557 }, 558 }, 559 .der = { 560 0x30, 0x35, 0x30, 0x2b, 0x04, 0x03, 0x00, 0x01, 561 0x01, 0x30, 0x24, 0x03, 0x04, 0x04, 0x0a, 0x00, 562 0x20, 0x03, 0x04, 0x00, 0x0a, 0x00, 0x40, 0x03, 563 0x03, 0x00, 0x0a, 0x01, 0x30, 0x0c, 0x03, 0x04, 564 0x04, 0x0a, 0x02, 0x30, 0x03, 0x04, 0x00, 0x0a, 565 0x02, 0x40, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x30, 566 0x06, 0x04, 0x02, 0x00, 0x02, 0x05, 0x00, 567 }, 568 .der_len = 55, 569 .is_canonical = 0, 570 .inherits = 1, 571 .afis = { 572 IANA_AFI_IPV4, IANA_AFI_IPV6, 573 }, 574 .afi_len = 2, 575 }, 576 { 577 .description = "RFC 3779, Appendix B, example 1 canonical", 578 .addrs = { 579 { 580 .afi = IANA_AFI_IPV4, 581 .safi = safi_unicast, 582 .type = choice_prefix, 583 .addr.ipv4.prefix = { 584 .addr = { 585 10, 0, 32, 586 }, 587 .addr_len = 3, 588 .prefix_len = 20, 589 }, 590 }, 591 { 592 .afi = IANA_AFI_IPV4, 593 .safi = safi_unicast, 594 .type = choice_prefix, 595 .addr.ipv4.prefix = { 596 .addr = { 597 10, 0, 64, 598 }, 599 .addr_len = 3, 600 .prefix_len = 24, 601 }, 602 }, 603 { 604 .afi = IANA_AFI_IPV4, 605 .safi = safi_unicast, 606 .type = choice_prefix, 607 .addr.ipv4.prefix = { 608 .addr = { 609 10, 1, 610 }, 611 .addr_len = 2, 612 .prefix_len = 16, 613 }, 614 }, 615 { 616 .afi = IANA_AFI_IPV4, 617 .safi = safi_unicast, 618 .type = choice_range, 619 .addr.ipv4.range = { 620 .min = { 621 10, 2, 48, 00, 622 }, 623 .max = { 624 10, 2, 64, 255, 625 }, 626 }, 627 }, 628 { 629 .afi = IANA_AFI_IPV4, 630 .safi = safi_unicast, 631 .type = choice_prefix, 632 .addr.ipv4.prefix = { 633 .addr = { 634 10, 3, 635 }, 636 .addr_len = 2, 637 .prefix_len = 16, 638 }, 639 }, 640 { 641 .afi = IANA_AFI_IPV6, 642 .safi = safi_none, 643 .type = choice_inherit, 644 }, 645 { 646 .type = choice_last, 647 }, 648 }, 649 .der = { 650 0x30, 0x35, 0x30, 0x2b, 0x04, 0x03, 0x00, 0x01, 651 0x01, 0x30, 0x24, 0x03, 0x04, 0x04, 0x0a, 0x00, 652 0x20, 0x03, 0x04, 0x00, 0x0a, 0x00, 0x40, 0x03, 653 0x03, 0x00, 0x0a, 0x01, 0x30, 0x0c, 0x03, 0x04, 654 0x04, 0x0a, 0x02, 0x30, 0x03, 0x04, 0x00, 0x0a, 655 0x02, 0x40, 0x03, 0x03, 0x00, 0x0a, 0x03, 0x30, 656 0x06, 0x04, 0x02, 0x00, 0x02, 0x05, 0x00, 657 }, 658 .der_len = 55, 659 .is_canonical = 1, 660 .inherits = 1, 661 .afis = { 662 IANA_AFI_IPV4, IANA_AFI_IPV6, 663 }, 664 .afi_len = 2, 665 }, 666 { 667 .description = "RFC 3779, Appendix B, example 2", 668 .addrs = { 669 { 670 .afi = IANA_AFI_IPV6, 671 .safi = safi_none, 672 .type = choice_prefix, 673 .addr.ipv6.prefix = { 674 .addr = { 675 0x20, 0x01, 0x00, 0x00, 676 0x00, 0x02, 677 }, 678 .addr_len = 6, 679 .prefix_len = 48, 680 }, 681 }, 682 { 683 .afi = IANA_AFI_IPV4, 684 .safi = safi_unicast, 685 .type = choice_prefix, 686 .addr.ipv4.prefix = { 687 .addr = { 688 10, 689 }, 690 .addr_len = 1, 691 .prefix_len = 8, 692 }, 693 }, 694 { 695 .afi = IANA_AFI_IPV4, 696 .safi = safi_unicast, 697 .type = choice_prefix, 698 .addr.ipv4.prefix = { 699 .addr = { 700 172, 16, 701 }, 702 .addr_len = 2, 703 .prefix_len = 12, 704 }, 705 }, 706 { 707 .afi = IANA_AFI_IPV4, 708 .safi = safi_multicast, 709 .type = choice_inherit, 710 }, 711 { 712 .type = choice_last, 713 }, 714 }, 715 .der = { 716 0x30, 0x2c, 0x30, 0x10, 0x04, 0x03, 0x00, 0x01, 717 0x01, 0x30, 0x09, 0x03, 0x02, 0x00, 0x0a, 0x03, 718 0x03, 0x04, 0xac, 0x10, 0x30, 0x07, 0x04, 0x03, 719 0x00, 0x01, 0x02, 0x05, 0x00, 0x30, 0x0f, 0x04, 720 0x02, 0x00, 0x02, 0x30, 0x09, 0x03, 0x07, 0x00, 721 0x20, 0x01, 0x00, 0x00, 0x00, 0x02, 722 }, 723 .der_len = 46, 724 .is_canonical = 0, 725 .inherits = 1, 726 .afis = { 727 IANA_AFI_IPV4, IANA_AFI_IPV4, 728 }, 729 .afi_len = 2, 730 }, 731 { 732 .description = "Range should be prefix 127/8", 733 .addrs = { 734 { 735 .afi = IANA_AFI_IPV4, 736 .safi = safi_none, 737 .type = choice_range, 738 .addr.ipv4.range = { 739 .min = { 740 127, 0, 0, 0, 741 }, 742 .max = { 743 127, 255, 255, 255, 744 }, 745 }, 746 }, 747 { 748 .type = choice_last, 749 }, 750 }, 751 .der = { 752 0x30, 0x0c, 0x30, 0x0a, 0x04, 0x02, 0x00, 0x01, 753 0x30, 0x04, 0x03, 0x02, 0x00, 0x7f, 754 }, 755 .der_len = 14, 756 .is_canonical = 1, 757 .inherits = 0, 758 .afis = { 759 IANA_AFI_IPV4, 760 }, 761 .afi_len = 1, 762 }, 763 }; 764 765 const size_t N_BUILD_ADDR_BLOCK_TESTS = 766 sizeof(build_addr_block_tests) / sizeof(build_addr_block_tests[0]); 767 768 static unsigned int * 769 addr_block_get_safi(const struct ip_addr_block *addr) 770 { 771 static unsigned int safi; 772 773 switch (addr->safi) { 774 case safi_none: 775 return NULL; 776 case safi_unicast: 777 safi = 1; 778 break; 779 case safi_multicast: 780 safi = 2; 781 break; 782 } 783 784 return &safi; 785 } 786 787 static int 788 addr_block_add_ipv4_addr(IPAddrBlocks *block, enum choice_type type, 789 const union ipv4_choice *ipv4, unsigned int *safi) 790 { 791 unsigned char addr[RAW_ADDRESS_SIZE] = {0}; 792 unsigned char min[RAW_ADDRESS_SIZE]; 793 unsigned char max[RAW_ADDRESS_SIZE]; 794 795 switch (type) { 796 case choice_prefix: 797 memcpy(addr, ipv4->prefix.addr, ipv4->prefix.addr_len); 798 return X509v3_addr_add_prefix(block, IANA_AFI_IPV4, safi, 799 addr, ipv4->prefix.prefix_len); 800 case choice_range: 801 memcpy(min, ipv4->range.min, sizeof(ipv4->range.min)); 802 memcpy(max, ipv4->range.max, sizeof(ipv4->range.max)); 803 return X509v3_addr_add_range(block, IANA_AFI_IPV4, safi, 804 min, max); 805 case choice_inherit: 806 return X509v3_addr_add_inherit(block, IANA_AFI_IPV4, safi); 807 case choice_last: 808 default: 809 return 0; 810 } 811 } 812 813 static int 814 addr_block_add_ipv6_addr(IPAddrBlocks *block, enum choice_type type, 815 const union ipv6_choice *ipv6, unsigned int *safi) 816 { 817 unsigned char addr[RAW_ADDRESS_SIZE] = {0}; 818 unsigned char min[RAW_ADDRESS_SIZE]; 819 unsigned char max[RAW_ADDRESS_SIZE]; 820 821 switch (type) { 822 case choice_prefix: 823 memcpy(addr, ipv6->prefix.addr, ipv6->prefix.addr_len); 824 return X509v3_addr_add_prefix(block, IANA_AFI_IPV6, safi, 825 addr, ipv6->prefix.prefix_len); 826 case choice_range: 827 memcpy(min, ipv6->range.min, sizeof(ipv6->range.min)); 828 memcpy(max, ipv6->range.max, sizeof(ipv6->range.max)); 829 return X509v3_addr_add_range(block, IANA_AFI_IPV6, safi, 830 min, max); 831 case choice_inherit: 832 return X509v3_addr_add_inherit(block, IANA_AFI_IPV6, safi); 833 case choice_last: 834 default: 835 return 0; 836 } 837 } 838 839 static int 840 addr_block_add_addrs(IPAddrBlocks *block, const struct ip_addr_block addrs[]) 841 { 842 const struct ip_addr_block *addr; 843 unsigned int *safi; 844 845 for (addr = &addrs[0]; addr->type != choice_last; addr++) { 846 safi = addr_block_get_safi(addr); 847 switch (addr->afi) { 848 case IANA_AFI_IPV4: 849 if (!addr_block_add_ipv4_addr(block, addr->type, 850 &addr->addr.ipv4, safi)) 851 return 0; 852 break; 853 case IANA_AFI_IPV6: 854 if (!addr_block_add_ipv6_addr(block, addr->type, 855 &addr->addr.ipv6, safi)) 856 return 0; 857 break; 858 default: 859 fprintf(stderr, "%s: corrupt test data", __func__); 860 exit(1); 861 } 862 } 863 864 return 1; 865 } 866 867 static int 868 build_addr_block_test(const struct build_addr_block_test_data *test) 869 { 870 IPAddrBlocks *addrs = NULL, *parsed = NULL; 871 const unsigned char *p; 872 unsigned char *out = NULL; 873 int out_len; 874 int i; 875 int memcmp_failed = 1; 876 int failed = 1; 877 878 if ((addrs = IPAddrBlocks_new()) == NULL) 879 goto err; 880 881 if (!addr_block_add_addrs(addrs, test->addrs)) 882 goto err; 883 884 if (X509v3_addr_is_canonical(addrs) != test->is_canonical) { 885 fprintf(stderr, "%s: \"%s\" X509v3_addr_is_canonical not %d\n", 886 __func__, test->description, test->is_canonical); 887 goto err; 888 } 889 890 if (!X509v3_addr_canonize(addrs)) { 891 fprintf(stderr, "%s: \"%s\" failed to canonize\n", 892 __func__, test->description); 893 goto err; 894 } 895 896 if (!X509v3_addr_is_canonical(addrs)) { 897 fprintf(stderr, "%s: \"%s\" canonization wasn't canonical\n", 898 __func__, test->description); 899 goto err; 900 } 901 902 if ((out_len = i2d_IPAddrBlocks(addrs, &out)) <= 0) { 903 fprintf(stderr, "%s: \"%s\" i2d_IPAddrBlocks failed\n", 904 __func__, test->description); 905 goto err; 906 } 907 908 memcmp_failed = (size_t)out_len != test->der_len; 909 if (!memcmp_failed) 910 memcmp_failed = memcmp(out, test->der, test->der_len); 911 if (memcmp_failed) { 912 report_hexdump(__func__, test->description, "memcmp DER failed", 913 test->der, test->der_len, out, out_len); 914 goto err; 915 } 916 917 if (X509v3_addr_inherits(addrs) != test->inherits) { 918 fprintf(stderr, "%s: \"%s\" X509v3_addr_inherits not %d\n", 919 __func__, test->description, test->inherits); 920 goto err; 921 } 922 923 for (i = 0; i < sk_IPAddressFamily_num(addrs) && i < test->afi_len; i++) { 924 IPAddressFamily *family; 925 unsigned int afi; 926 927 family = sk_IPAddressFamily_value(addrs, i); 928 929 if ((afi = X509v3_addr_get_afi(family)) == 0) { 930 fprintf(stderr, "%s: \"%s\" X509v3_addr_get_afi" 931 " failed\n", __func__, test->description); 932 goto err; 933 } 934 if (test->afis[i] != afi){ 935 fprintf(stderr, "%s: \"%s\" afi[%d] mismatch. " 936 "want: %u, got: %u\n", __func__, 937 test->description, i, test->afis[i], afi); 938 goto err; 939 } 940 } 941 if (i != test->afi_len) { 942 fprintf(stderr, "%s: \"%s\" checked %d afis, expected %d\n", 943 __func__, test->description, i, test->afi_len); 944 goto err; 945 } 946 947 p = test->der; 948 if ((parsed = d2i_IPAddrBlocks(NULL, &p, test->der_len)) == NULL) { 949 fprintf(stderr, "%s: \"%s\" d2i_IPAddrBlocks failed\n", 950 __func__, test->description); 951 goto err; 952 } 953 if (!X509v3_addr_is_canonical(parsed)) { 954 fprintf(stderr, "%s: \"%s\" parsed AddrBlocks isn't canonical\n", 955 __func__, test->description); 956 goto err; 957 } 958 /* Can't compare IPAddrBlocks with inheritance. */ 959 if (!X509v3_addr_inherits(addrs) && !X509v3_addr_inherits(parsed)) { 960 if (!X509v3_addr_subset(addrs, parsed)) { 961 fprintf(stderr, "%s: \"%s\" addrs not subset of parsed\n", 962 __func__, test->description); 963 } 964 if (!X509v3_addr_subset(parsed, addrs)) { 965 fprintf(stderr, "%s: \"%s\" parsed not subset of addrs\n", 966 __func__, test->description); 967 } 968 } 969 970 failed = 0; 971 972 err: 973 IPAddrBlocks_free(addrs); 974 IPAddrBlocks_free(parsed); 975 free(out); 976 977 return failed; 978 } 979 980 static int 981 run_IPAddrBlock_tests(void) 982 { 983 size_t i; 984 int failed = 0; 985 986 for (i = 0; i < N_BUILD_ADDR_BLOCK_TESTS; i++) 987 failed |= build_addr_block_test(&build_addr_block_tests[i]); 988 989 return failed; 990 } 991 992 struct asid_or_range { 993 int type; 994 int inherit; 995 const unsigned char *min; 996 const unsigned char *max; 997 }; 998 999 struct ASIdentifiers_build_test { 1000 const char *description; 1001 int should_build; 1002 int inherits; 1003 int canonical; 1004 int should_canonize; 1005 struct asid_or_range delegations[8]; 1006 const unsigned char der[128]; 1007 size_t der_len; 1008 }; 1009 1010 /* Sentinel value used for marking the end of the delegations table. */ 1011 #define V3_ASID_END -1 1012 1013 const struct ASIdentifiers_build_test ASIdentifiers_build_data[] = { 1014 { 1015 .description = "RFC 3779, Appendix C", 1016 .should_build = 1, 1017 .inherits = 1, 1018 .canonical = 1, 1019 .delegations = { 1020 { 1021 .type = V3_ASID_ASNUM, 1022 .inherit = 0, 1023 .min = "135", 1024 .max = NULL, 1025 }, 1026 { 1027 .type = V3_ASID_ASNUM, 1028 .inherit = 0, 1029 .min = "3000", 1030 .max = "3999", 1031 }, 1032 { 1033 .type = V3_ASID_ASNUM, 1034 .inherit = 0, 1035 .min = "5001", 1036 .max = NULL, 1037 }, 1038 { 1039 .type = V3_ASID_RDI, 1040 .inherit = 1, 1041 .min = NULL, 1042 .max = NULL, 1043 }, 1044 { 1045 .type = V3_ASID_END, 1046 }, 1047 }, 1048 .der = { 1049 0x30, 0x1a, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02, 1050 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, 1051 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89, 1052 0xa1, 0x02, 0x05, 0x00, 1053 }, 1054 .der_len = 28, 1055 }, 1056 { 1057 .description = "RFC 3779, Appendix C without rdi", 1058 .should_build = 1, 1059 .inherits = 0, 1060 .canonical = 1, 1061 .delegations = { 1062 { 1063 .type = V3_ASID_ASNUM, 1064 .inherit = 0, 1065 .min = "135", 1066 .max = NULL, 1067 }, 1068 { 1069 .type = V3_ASID_ASNUM, 1070 .inherit = 0, 1071 .min = "3000", 1072 .max = "3999", 1073 }, 1074 { 1075 .type = V3_ASID_ASNUM, 1076 .inherit = 0, 1077 .min = "5001", 1078 .max = NULL, 1079 }, 1080 { 1081 .type = V3_ASID_END, 1082 }, 1083 }, 1084 .der = { 1085 0x30, 0x16, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02, 1086 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, 1087 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89, 1088 }, 1089 .der_len = 24, 1090 }, 1091 { 1092 .description = "RFC 3779, Appendix C variant", 1093 .should_build = 1, 1094 .inherits = 0, 1095 .canonical = 1, 1096 .delegations = { 1097 { 1098 .type = V3_ASID_ASNUM, 1099 .inherit = 0, 1100 .min = "135", 1101 .max = NULL, 1102 }, 1103 { 1104 .type = V3_ASID_ASNUM, 1105 .inherit = 0, 1106 .min = "3000", 1107 .max = "3999", 1108 }, 1109 { 1110 .type = V3_ASID_ASNUM, 1111 .inherit = 0, 1112 .min = "5001", 1113 .max = NULL, 1114 }, 1115 { 1116 .type = V3_ASID_RDI, 1117 .inherit = 0, 1118 .min = "135", 1119 .max = NULL, 1120 }, 1121 { 1122 .type = V3_ASID_RDI, 1123 .inherit = 0, 1124 .min = "3000", 1125 .max = "3999", 1126 }, 1127 { 1128 .type = V3_ASID_RDI, 1129 .inherit = 0, 1130 .min = "5001", 1131 .max = NULL, 1132 }, 1133 { 1134 .type = V3_ASID_END, 1135 }, 1136 }, 1137 .der = { 1138 0x30, 0x2c, 0xa0, 0x14, 0x30, 0x12, 0x02, 0x02, 1139 0x00, 0x87, 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, 1140 0x02, 0x02, 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89, 1141 0xa1, 0x14, 0x30, 0x12, 0x02, 0x02, 0x00, 0x87, 1142 0x30, 0x08, 0x02, 0x02, 0x0b, 0xb8, 0x02, 0x02, 1143 0x0f, 0x9f, 0x02, 0x02, 0x13, 0x89, 1144 }, 1145 .der_len = 46, 1146 }, 1147 { 1148 .description = "inherit only", 1149 .should_build = 1, 1150 .inherits = 1, 1151 .canonical = 1, 1152 .delegations = { 1153 { 1154 .type = V3_ASID_ASNUM, 1155 .inherit = 1, 1156 }, 1157 { 1158 .type = V3_ASID_RDI, 1159 .inherit = 1, 1160 }, 1161 { 1162 .type = V3_ASID_END, 1163 }, 1164 }, 1165 .der = { 1166 0x30, 0x08, 0xa0, 0x02, 0x05, 0x00, 0xa1, 0x02, 1167 0x05, 0x00, 1168 }, 1169 .der_len = 10, 1170 }, 1171 { 1172 .description = "adjacent unsorted ranges are merged", 1173 .should_build = 1, 1174 .inherits = 0, 1175 .canonical = 0, 1176 .should_canonize = 1, 1177 .delegations = { 1178 { 1179 .type = V3_ASID_RDI, 1180 .inherit = 0, 1181 .min = "27", 1182 .max = NULL, 1183 }, 1184 { 1185 .type = V3_ASID_RDI, 1186 .inherit = 0, 1187 .min = "28", 1188 .max = "57", 1189 }, 1190 { 1191 .type = V3_ASID_RDI, 1192 .inherit = 0, 1193 .min = "66", 1194 .max = "68", 1195 }, 1196 { 1197 .type = V3_ASID_RDI, 1198 .inherit = 0, 1199 .min = "58", 1200 .max = "63", 1201 }, 1202 { 1203 .type = V3_ASID_RDI, 1204 .inherit = 0, 1205 .min = "64", 1206 .max = NULL, 1207 }, 1208 { 1209 .type = V3_ASID_END, 1210 }, 1211 }, 1212 .der = { 1213 0x30, 0x14, 0xa1, 0x12, 0x30, 0x10, 0x30, 0x06, 1214 0x02, 0x01, 0x1b, 0x02, 0x01, 0x40, 0x30, 0x06, 1215 0x02, 0x01, 0x42, 0x02, 0x01, 0x44, 1216 }, 1217 .der_len = 22, 1218 }, 1219 { 1220 .description = "range of length 0", 1221 .should_build = 1, 1222 .inherits = 1, 1223 .canonical = 1, 1224 .should_canonize = 1, 1225 .delegations = { 1226 { 1227 .type = V3_ASID_RDI, 1228 .inherit = 0, 1229 .min = "27", 1230 .max = "27", 1231 }, 1232 { 1233 .type = V3_ASID_ASNUM, 1234 .inherit = 1, 1235 }, 1236 { 1237 .type = V3_ASID_END, 1238 }, 1239 }, 1240 .der = { 1241 0x30, 0x10, 0xa0, 0x02, 0x05, 0x00, 0xa1, 0x0a, 1242 0x30, 0x08, 0x30, 0x06, 0x02, 0x01, 0x1b, 0x02, 1243 0x01, 0x1b, 1244 }, 1245 .der_len = 18, 1246 }, 1247 { 1248 .description = "reversed range doesn't canonize", 1249 .should_build = 1, 1250 .inherits = 0, 1251 .canonical = 0, 1252 .should_canonize = 0, 1253 .delegations = { 1254 { 1255 .type = V3_ASID_ASNUM, 1256 .inherit = 0, 1257 .min = "57", 1258 .max = "42", 1259 }, 1260 { 1261 .type = V3_ASID_END, 1262 }, 1263 }, 1264 }, 1265 { 1266 .description = "overlapping ranges don't canonize", 1267 .should_build = 1, 1268 .inherits = 0, 1269 .canonical = 0, 1270 .should_canonize = 0, 1271 .delegations = { 1272 { 1273 .type = V3_ASID_ASNUM, 1274 .inherit = 0, 1275 .min = "42", 1276 .max = "57", 1277 }, 1278 { 1279 .type = V3_ASID_ASNUM, 1280 .inherit = 0, 1281 .min = "57", 1282 .max = "60", 1283 }, 1284 { 1285 .type = V3_ASID_END, 1286 }, 1287 }, 1288 }, 1289 { 1290 .description = "reversed interior range doesn't canonize", 1291 .should_build = 1, 1292 .inherits = 0, 1293 .canonical = 0, 1294 .should_canonize = 0, 1295 .delegations = { 1296 { 1297 .type = V3_ASID_ASNUM, 1298 .inherit = 0, 1299 .min = "1", 1300 .max = "2", 1301 }, 1302 { 1303 .type = V3_ASID_ASNUM, 1304 .inherit = 0, 1305 .min = "57", 1306 .max = "42", 1307 }, 1308 { 1309 .type = V3_ASID_ASNUM, 1310 .inherit = 0, 1311 .min = "65523", 1312 .max = "65535", 1313 }, 1314 { 1315 .type = V3_ASID_END, 1316 }, 1317 }, 1318 }, 1319 { 1320 .description = "can't inherit and add AS ids", 1321 .should_build = 0, 1322 .inherits = 0, 1323 .canonical = 0, 1324 .should_canonize = 0, 1325 .delegations = { 1326 { 1327 .type = V3_ASID_ASNUM, 1328 .inherit = 0, 1329 .min = "1", 1330 .max = "2", 1331 }, 1332 { 1333 .type = V3_ASID_ASNUM, 1334 .inherit = 1, 1335 }, 1336 { 1337 .type = V3_ASID_END, 1338 }, 1339 }, 1340 }, 1341 { 1342 .description = "can't inherit and add rdis", 1343 .should_build = 0, 1344 .inherits = 0, 1345 .canonical = 0, 1346 .should_canonize = 0, 1347 .delegations = { 1348 { 1349 .type = V3_ASID_RDI, 1350 .inherit = 0, 1351 .min = "1", 1352 .max = "2", 1353 }, 1354 { 1355 .type = V3_ASID_RDI, 1356 .inherit = 1, 1357 }, 1358 { 1359 .type = V3_ASID_END, 1360 }, 1361 }, 1362 }, 1363 }; 1364 1365 const size_t N_ASIDENTIFIERS_BUILD_TESTS = 1366 sizeof(ASIdentifiers_build_data) / sizeof(ASIdentifiers_build_data[0]); 1367 1368 static int 1369 add_as_delegation(ASIdentifiers *asid, const struct asid_or_range *delegation) 1370 { 1371 ASN1_INTEGER *min = NULL, *max = NULL; 1372 int ret = 0; 1373 1374 if (delegation->inherit) 1375 return X509v3_asid_add_inherit(asid, delegation->type); 1376 1377 if ((min = s2i_ASN1_INTEGER(NULL, delegation->min)) == NULL) 1378 goto err; 1379 1380 if (delegation->max != NULL) { 1381 if ((max = s2i_ASN1_INTEGER(NULL, delegation->max)) == NULL) 1382 goto err; 1383 } 1384 1385 if (!X509v3_asid_add_id_or_range(asid, delegation->type, min, max)) 1386 goto err; 1387 min = NULL; 1388 max = NULL; 1389 1390 ret = 1; 1391 1392 err: 1393 ASN1_INTEGER_free(min); 1394 ASN1_INTEGER_free(max); 1395 1396 return ret; 1397 } 1398 1399 static ASIdentifiers * 1400 build_asid(const struct asid_or_range delegations[]) 1401 { 1402 ASIdentifiers *asid = NULL; 1403 const struct asid_or_range *delegation; 1404 1405 if ((asid = ASIdentifiers_new()) == NULL) 1406 goto err; 1407 1408 for (delegation = &delegations[0]; delegation->type != V3_ASID_END; 1409 delegation++) { 1410 if (!add_as_delegation(asid, delegation)) 1411 goto err; 1412 } 1413 1414 return asid; 1415 1416 err: 1417 ASIdentifiers_free(asid); 1418 return NULL; 1419 } 1420 1421 static int 1422 build_asid_test(const struct ASIdentifiers_build_test *test) 1423 { 1424 ASIdentifiers *asid = NULL; 1425 unsigned char *out = NULL; 1426 int out_len; 1427 int memcmp_failed = 1; 1428 int failed = 1; 1429 1430 if ((asid = build_asid(test->delegations)) == NULL) { 1431 if (!test->should_build) { 1432 failed = 0; 1433 return failed; 1434 } 1435 fprintf(stderr, "%s: \"%s\" failed to build\n", __func__, 1436 test->description); 1437 return failed; 1438 } 1439 1440 if (!test->canonical) { 1441 if (X509v3_asid_is_canonical(asid)) { 1442 fprintf(stderr, "%s: \"%s\" shouldn't be canonical\n", 1443 __func__, test->description); 1444 goto err; 1445 } 1446 if (X509v3_asid_canonize(asid) != test->should_canonize) { 1447 fprintf(stderr, "%s: \"%s\" failed to canonize\n", 1448 __func__, test->description); 1449 goto err; 1450 } 1451 if (!test->should_canonize) { 1452 failed = 0; 1453 goto err; 1454 } 1455 } 1456 1457 /* 1458 * Verify that asid is in canonical form before converting it to DER. 1459 */ 1460 if (!X509v3_asid_is_canonical(asid)) { 1461 fprintf(stderr, "%s: asid is not canonical\n", __func__); 1462 goto err; 1463 } 1464 1465 /* 1466 * Convert asid to DER and check that it matches expectations 1467 */ 1468 out = NULL; 1469 if ((out_len = i2d_ASIdentifiers(asid, &out)) <= 0) { 1470 fprintf(stderr, "%s: \"%s\" i2d_ASIdentifiers failed\n", 1471 __func__, test->description); 1472 goto err; 1473 } 1474 1475 1476 memcmp_failed = (size_t)out_len != test->der_len; 1477 if (!memcmp_failed) 1478 memcmp_failed = memcmp(out, test->der, test->der_len); 1479 if (memcmp_failed) { 1480 report_hexdump(__func__, test->description, "memcmp DER failed", 1481 test->der, test->der_len, out, out_len); 1482 goto err; 1483 } 1484 1485 /* 1486 * Verify that asid inherits as expected 1487 */ 1488 if (X509v3_asid_inherits(asid) != test->inherits) { 1489 fprintf(stderr, "%s: \"%s\" unexpected asid inherit %d\n", 1490 __func__, test->description, test->inherits); 1491 goto err; 1492 } 1493 1494 failed = 0; 1495 1496 err: 1497 free(out); 1498 ASIdentifiers_free(asid); 1499 1500 return failed; 1501 } 1502 1503 static int 1504 run_ASIdentifiers_build_test(void) 1505 { 1506 size_t i; 1507 int failed = 0; 1508 1509 for (i = 0; i < N_ASIDENTIFIERS_BUILD_TESTS; i++) 1510 failed |= build_asid_test(&ASIdentifiers_build_data[i]); 1511 1512 return failed; 1513 } 1514 1515 struct ASIdentifiers_subset_test { 1516 const char *description; 1517 struct asid_or_range delegationsA[8]; 1518 struct asid_or_range delegationsB[8]; 1519 int is_subset; 1520 int is_subset_if_canonized; 1521 }; 1522 1523 const struct ASIdentifiers_subset_test ASIdentifiers_subset_data[] = { 1524 { 1525 .description = "simple subset relation", 1526 .delegationsA = { 1527 { 1528 .type = V3_ASID_ASNUM, 1529 .inherit = 0, 1530 .min = "2", 1531 .max = "4", 1532 }, 1533 { 1534 .type = V3_ASID_RDI, 1535 .inherit = 0, 1536 .min = "2", 1537 .max = NULL, 1538 }, 1539 { 1540 .type = V3_ASID_END, 1541 }, 1542 }, 1543 .delegationsB = { 1544 { 1545 .type = V3_ASID_ASNUM, 1546 .inherit = 0, 1547 .min = "1", 1548 .max = "5", 1549 }, 1550 { 1551 .type = V3_ASID_RDI, 1552 .inherit = 0, 1553 .min = "1", 1554 .max = "5", 1555 }, 1556 { 1557 .type = V3_ASID_END, 1558 }, 1559 }, 1560 .is_subset = 1, 1561 .is_subset_if_canonized = 1, 1562 }, 1563 { 1564 .description = "only asnums", 1565 .delegationsA = { 1566 { 1567 .type = V3_ASID_ASNUM, 1568 .inherit = 0, 1569 .min = "2", 1570 .max = "4", 1571 }, 1572 { 1573 .type = V3_ASID_END, 1574 }, 1575 }, 1576 .delegationsB = { 1577 { 1578 .type = V3_ASID_ASNUM, 1579 .inherit = 0, 1580 .min = "1", 1581 .max = "5", 1582 }, 1583 { 1584 .type = V3_ASID_END, 1585 }, 1586 }, 1587 .is_subset = 1, 1588 .is_subset_if_canonized = 1, 1589 }, 1590 { 1591 .description = "only rdis", 1592 .delegationsA = { 1593 { 1594 .type = V3_ASID_RDI, 1595 .inherit = 0, 1596 .min = "2", 1597 .max = NULL, 1598 }, 1599 { 1600 .type = V3_ASID_END, 1601 }, 1602 }, 1603 .delegationsB = { 1604 { 1605 .type = V3_ASID_RDI, 1606 .inherit = 0, 1607 .min = "1", 1608 .max = "5", 1609 }, 1610 { 1611 .type = V3_ASID_END, 1612 }, 1613 }, 1614 .is_subset = 1, 1615 .is_subset_if_canonized = 1, 1616 }, 1617 { 1618 .description = "child only has asnums, parent only has rdis", 1619 .delegationsA = { 1620 { 1621 .type = V3_ASID_ASNUM, 1622 .inherit = 0, 1623 .min = "2", 1624 .max = "4", 1625 }, 1626 { 1627 .type = V3_ASID_END, 1628 }, 1629 }, 1630 .delegationsB = { 1631 { 1632 .type = V3_ASID_RDI, 1633 .inherit = 0, 1634 .min = "1", 1635 .max = "5", 1636 }, 1637 { 1638 .type = V3_ASID_END, 1639 }, 1640 }, 1641 .is_subset = 0, 1642 .is_subset_if_canonized = 0, 1643 }, 1644 { 1645 .description = "child only has rdis, parent only has asnums", 1646 .delegationsA = { 1647 { 1648 .type = V3_ASID_RDI, 1649 .inherit = 0, 1650 .min = "2", 1651 .max = "4", 1652 }, 1653 { 1654 .type = V3_ASID_END, 1655 }, 1656 }, 1657 .delegationsB = { 1658 { 1659 .type = V3_ASID_ASNUM, 1660 .inherit = 0, 1661 .min = "1", 1662 .max = "5", 1663 }, 1664 { 1665 .type = V3_ASID_END, 1666 }, 1667 }, 1668 .is_subset = 0, 1669 .is_subset_if_canonized = 0, 1670 }, 1671 { 1672 .description = "child only has rdis, parent has both", 1673 .delegationsA = { 1674 { 1675 .type = V3_ASID_RDI, 1676 .inherit = 0, 1677 .min = "2", 1678 .max = "4", 1679 }, 1680 { 1681 .type = V3_ASID_END, 1682 }, 1683 }, 1684 .delegationsB = { 1685 { 1686 .type = V3_ASID_ASNUM, 1687 .inherit = 0, 1688 .min = "1", 1689 .max = "5", 1690 }, 1691 { 1692 .type = V3_ASID_RDI, 1693 .inherit = 0, 1694 .min = "1", 1695 .max = "5", 1696 }, 1697 { 1698 .type = V3_ASID_END, 1699 }, 1700 }, 1701 .is_subset = 1, 1702 .is_subset_if_canonized = 1, 1703 }, 1704 { 1705 .description = "subset relation only after canonization", 1706 .delegationsA = { 1707 { 1708 .type = V3_ASID_ASNUM, 1709 .inherit = 0, 1710 .min = "2", 1711 .max = NULL, 1712 }, 1713 { 1714 .type = V3_ASID_ASNUM, 1715 .inherit = 0, 1716 .min = "3", 1717 .max = "4", 1718 }, 1719 { 1720 .type = V3_ASID_RDI, 1721 .inherit = 0, 1722 .min = "2", 1723 .max = NULL, 1724 }, 1725 { 1726 .type = V3_ASID_END, 1727 }, 1728 }, 1729 .delegationsB = { 1730 { 1731 .type = V3_ASID_ASNUM, 1732 .inherit = 0, 1733 .min = "1", 1734 .max = "3", 1735 }, 1736 { 1737 .type = V3_ASID_ASNUM, 1738 .inherit = 0, 1739 .min = "4", 1740 .max = "5", 1741 }, 1742 { 1743 .type = V3_ASID_RDI, 1744 .inherit = 0, 1745 .min = "1", 1746 .max = "5", 1747 }, 1748 { 1749 .type = V3_ASID_END, 1750 }, 1751 }, 1752 .is_subset = 0, 1753 .is_subset_if_canonized = 1, 1754 }, 1755 { 1756 .description = "no subset if A inherits", 1757 .delegationsA = { 1758 { 1759 .type = V3_ASID_ASNUM, 1760 .inherit = 0, 1761 .min = "2", 1762 .max = NULL, 1763 }, 1764 { 1765 .type = V3_ASID_ASNUM, 1766 .inherit = 0, 1767 .min = "3", 1768 .max = "4", 1769 }, 1770 { 1771 .type = V3_ASID_RDI, 1772 .inherit = 1, 1773 }, 1774 { 1775 .type = V3_ASID_END, 1776 }, 1777 }, 1778 .delegationsB = { 1779 { 1780 .type = V3_ASID_ASNUM, 1781 .inherit = 0, 1782 .min = "1", 1783 .max = "3", 1784 }, 1785 { 1786 .type = V3_ASID_ASNUM, 1787 .inherit = 0, 1788 .min = "4", 1789 .max = "5", 1790 }, 1791 { 1792 .type = V3_ASID_RDI, 1793 .inherit = 0, 1794 .min = "1", 1795 .max = "5", 1796 }, 1797 { 1798 .type = V3_ASID_END, 1799 }, 1800 }, 1801 .is_subset = 0, 1802 .is_subset_if_canonized = 0, 1803 }, 1804 { 1805 .description = "no subset if B inherits", 1806 .delegationsA = { 1807 { 1808 .type = V3_ASID_ASNUM, 1809 .inherit = 0, 1810 .min = "2", 1811 .max = NULL, 1812 }, 1813 { 1814 .type = V3_ASID_ASNUM, 1815 .inherit = 0, 1816 .min = "3", 1817 .max = "4", 1818 }, 1819 { 1820 .type = V3_ASID_RDI, 1821 .inherit = 0, 1822 .min = "5", 1823 .max = NULL, 1824 }, 1825 { 1826 .type = V3_ASID_END, 1827 }, 1828 }, 1829 .delegationsB = { 1830 { 1831 .type = V3_ASID_ASNUM, 1832 .inherit = 0, 1833 .min = "1", 1834 .max = "3", 1835 }, 1836 { 1837 .type = V3_ASID_ASNUM, 1838 .inherit = 0, 1839 .min = "4", 1840 .max = "5", 1841 }, 1842 { 1843 .type = V3_ASID_RDI, 1844 .inherit = 1, 1845 }, 1846 { 1847 .type = V3_ASID_END, 1848 }, 1849 }, 1850 .is_subset = 0, 1851 .is_subset_if_canonized = 0, 1852 }, 1853 { 1854 .description = "no subset if both inherit", 1855 .delegationsA = { 1856 { 1857 .type = V3_ASID_ASNUM, 1858 .inherit = 0, 1859 .min = "2", 1860 .max = NULL, 1861 }, 1862 { 1863 .type = V3_ASID_ASNUM, 1864 .inherit = 0, 1865 .min = "3", 1866 .max = "4", 1867 }, 1868 { 1869 .type = V3_ASID_RDI, 1870 .inherit = 1, 1871 }, 1872 { 1873 .type = V3_ASID_END, 1874 }, 1875 }, 1876 .delegationsB = { 1877 { 1878 .type = V3_ASID_ASNUM, 1879 .inherit = 0, 1880 .min = "1", 1881 .max = "3", 1882 }, 1883 { 1884 .type = V3_ASID_ASNUM, 1885 .inherit = 0, 1886 .min = "4", 1887 .max = "5", 1888 }, 1889 { 1890 .type = V3_ASID_RDI, 1891 .inherit = 1, 1892 }, 1893 { 1894 .type = V3_ASID_END, 1895 }, 1896 }, 1897 .is_subset = 0, 1898 .is_subset_if_canonized = 0, 1899 }, 1900 }; 1901 1902 const size_t N_ASIDENTIFIERS_SUBSET_TESTS = 1903 sizeof(ASIdentifiers_subset_data) / sizeof(ASIdentifiers_subset_data[0]); 1904 1905 static int 1906 asid_subset_test(const struct ASIdentifiers_subset_test *test) 1907 { 1908 ASIdentifiers *asidA = NULL, *asidB = NULL; 1909 int failed = 0; 1910 1911 if ((asidA = build_asid(test->delegationsA)) == NULL) 1912 goto err; 1913 if ((asidB = build_asid(test->delegationsB)) == NULL) 1914 goto err; 1915 1916 if (X509v3_asid_subset(asidA, asidB) != test->is_subset) { 1917 fprintf(stderr, "%s: \"%s\" X509v3_asid_subset failed\n", 1918 __func__, test->description); 1919 failed = 1; 1920 } 1921 1922 if (!test->is_subset) { 1923 if (!X509v3_asid_canonize(asidA)) 1924 goto err; 1925 if (!X509v3_asid_canonize(asidB)) 1926 goto err; 1927 if (X509v3_asid_subset(asidA, asidB) != 1928 test->is_subset_if_canonized) { 1929 fprintf(stderr, "%s: \"%s\" canonized subset failed\n", 1930 __func__, test->description); 1931 failed = 1; 1932 } 1933 } 1934 1935 err: 1936 ASIdentifiers_free(asidA); 1937 ASIdentifiers_free(asidB); 1938 1939 return failed; 1940 } 1941 1942 static int 1943 run_ASIdentifiers_subset_test(void) 1944 { 1945 size_t i; 1946 int failed = 0; 1947 1948 for (i = 0; i < N_ASIDENTIFIERS_SUBSET_TESTS; i++) 1949 failed |= asid_subset_test(&ASIdentifiers_subset_data[i]); 1950 1951 return failed; 1952 } 1953 1954 int 1955 main(void) 1956 { 1957 int failed = 0; 1958 1959 failed |= run_IPAddressOrRange_tests(); 1960 failed |= run_IPAddrBlock_tests(); 1961 failed |= run_ASIdentifiers_build_test(); 1962 failed |= run_ASIdentifiers_subset_test(); 1963 1964 return failed; 1965 } 1966