1 /* $OpenBSD: x509_asid.c,v 1.41 2023/11/11 09:35:21 tb Exp $ */ 2 /* 3 * Contributed to the OpenSSL Project by the American Registry for 4 * Internet Numbers ("ARIN"). 5 */ 6 /* ==================================================================== 7 * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This product includes cryptographic software written by Eric Young 55 * (eay@cryptsoft.com). This product includes software written by Tim 56 * Hudson (tjh@cryptsoft.com). 57 */ 58 59 /* 60 * Implementation of RFC 3779 section 3.2. 61 */ 62 63 #include <stdio.h> 64 #include <stdlib.h> 65 #include <string.h> 66 67 #include <openssl/asn1.h> 68 #include <openssl/asn1t.h> 69 #include <openssl/bn.h> 70 #include <openssl/conf.h> 71 #include <openssl/err.h> 72 #include <openssl/x509.h> 73 #include <openssl/x509v3.h> 74 75 #include "x509_local.h" 76 77 #ifndef OPENSSL_NO_RFC3779 78 79 static const ASN1_TEMPLATE ASRange_seq_tt[] = { 80 { 81 .flags = 0, 82 .tag = 0, 83 .offset = offsetof(ASRange, min), 84 .field_name = "min", 85 .item = &ASN1_INTEGER_it, 86 }, 87 { 88 .flags = 0, 89 .tag = 0, 90 .offset = offsetof(ASRange, max), 91 .field_name = "max", 92 .item = &ASN1_INTEGER_it, 93 }, 94 }; 95 96 const ASN1_ITEM ASRange_it = { 97 .itype = ASN1_ITYPE_SEQUENCE, 98 .utype = V_ASN1_SEQUENCE, 99 .templates = ASRange_seq_tt, 100 .tcount = sizeof(ASRange_seq_tt) / sizeof(ASN1_TEMPLATE), 101 .funcs = NULL, 102 .size = sizeof(ASRange), 103 .sname = "ASRange", 104 }; 105 106 static const ASN1_TEMPLATE ASIdOrRange_ch_tt[] = { 107 { 108 .flags = 0, 109 .tag = 0, 110 .offset = offsetof(ASIdOrRange, u.id), 111 .field_name = "u.id", 112 .item = &ASN1_INTEGER_it, 113 }, 114 { 115 .flags = 0, 116 .tag = 0, 117 .offset = offsetof(ASIdOrRange, u.range), 118 .field_name = "u.range", 119 .item = &ASRange_it, 120 }, 121 }; 122 123 const ASN1_ITEM ASIdOrRange_it = { 124 .itype = ASN1_ITYPE_CHOICE, 125 .utype = offsetof(ASIdOrRange, type), 126 .templates = ASIdOrRange_ch_tt, 127 .tcount = sizeof(ASIdOrRange_ch_tt) / sizeof(ASN1_TEMPLATE), 128 .funcs = NULL, 129 .size = sizeof(ASIdOrRange), 130 .sname = "ASIdOrRange", 131 }; 132 133 static const ASN1_TEMPLATE ASIdentifierChoice_ch_tt[] = { 134 { 135 .flags = 0, 136 .tag = 0, 137 .offset = offsetof(ASIdentifierChoice, u.inherit), 138 .field_name = "u.inherit", 139 .item = &ASN1_NULL_it, 140 }, 141 { 142 .flags = ASN1_TFLG_SEQUENCE_OF, 143 .tag = 0, 144 .offset = offsetof(ASIdentifierChoice, u.asIdsOrRanges), 145 .field_name = "u.asIdsOrRanges", 146 .item = &ASIdOrRange_it, 147 }, 148 }; 149 150 const ASN1_ITEM ASIdentifierChoice_it = { 151 .itype = ASN1_ITYPE_CHOICE, 152 .utype = offsetof(ASIdentifierChoice, type), 153 .templates = ASIdentifierChoice_ch_tt, 154 .tcount = sizeof(ASIdentifierChoice_ch_tt) / sizeof(ASN1_TEMPLATE), 155 .funcs = NULL, 156 .size = sizeof(ASIdentifierChoice), 157 .sname = "ASIdentifierChoice", 158 }; 159 160 static const ASN1_TEMPLATE ASIdentifiers_seq_tt[] = { 161 { 162 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, 163 .tag = 0, 164 .offset = offsetof(ASIdentifiers, asnum), 165 .field_name = "asnum", 166 .item = &ASIdentifierChoice_it, 167 }, 168 { 169 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, 170 .tag = 1, 171 .offset = offsetof(ASIdentifiers, rdi), 172 .field_name = "rdi", 173 .item = &ASIdentifierChoice_it, 174 }, 175 }; 176 177 const ASN1_ITEM ASIdentifiers_it = { 178 .itype = ASN1_ITYPE_SEQUENCE, 179 .utype = V_ASN1_SEQUENCE, 180 .templates = ASIdentifiers_seq_tt, 181 .tcount = sizeof(ASIdentifiers_seq_tt) / sizeof(ASN1_TEMPLATE), 182 .funcs = NULL, 183 .size = sizeof(ASIdentifiers), 184 .sname = "ASIdentifiers", 185 }; 186 187 ASRange * 188 d2i_ASRange(ASRange **a, const unsigned char **in, long len) 189 { 190 return (ASRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 191 &ASRange_it); 192 } 193 LCRYPTO_ALIAS(d2i_ASRange); 194 195 int 196 i2d_ASRange(ASRange *a, unsigned char **out) 197 { 198 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASRange_it); 199 } 200 LCRYPTO_ALIAS(i2d_ASRange); 201 202 ASRange * 203 ASRange_new(void) 204 { 205 return (ASRange *)ASN1_item_new(&ASRange_it); 206 } 207 LCRYPTO_ALIAS(ASRange_new); 208 209 void 210 ASRange_free(ASRange *a) 211 { 212 ASN1_item_free((ASN1_VALUE *)a, &ASRange_it); 213 } 214 LCRYPTO_ALIAS(ASRange_free); 215 216 ASIdOrRange * 217 d2i_ASIdOrRange(ASIdOrRange **a, const unsigned char **in, long len) 218 { 219 return (ASIdOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 220 &ASIdOrRange_it); 221 } 222 LCRYPTO_ALIAS(d2i_ASIdOrRange); 223 224 int 225 i2d_ASIdOrRange(ASIdOrRange *a, unsigned char **out) 226 { 227 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdOrRange_it); 228 } 229 LCRYPTO_ALIAS(i2d_ASIdOrRange); 230 231 ASIdOrRange * 232 ASIdOrRange_new(void) 233 { 234 return (ASIdOrRange *)ASN1_item_new(&ASIdOrRange_it); 235 } 236 LCRYPTO_ALIAS(ASIdOrRange_new); 237 238 void 239 ASIdOrRange_free(ASIdOrRange *a) 240 { 241 ASN1_item_free((ASN1_VALUE *)a, &ASIdOrRange_it); 242 } 243 LCRYPTO_ALIAS(ASIdOrRange_free); 244 245 ASIdentifierChoice * 246 d2i_ASIdentifierChoice(ASIdentifierChoice **a, const unsigned char **in, 247 long len) 248 { 249 return (ASIdentifierChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 250 &ASIdentifierChoice_it); 251 } 252 LCRYPTO_ALIAS(d2i_ASIdentifierChoice); 253 254 int 255 i2d_ASIdentifierChoice(ASIdentifierChoice *a, unsigned char **out) 256 { 257 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifierChoice_it); 258 } 259 LCRYPTO_ALIAS(i2d_ASIdentifierChoice); 260 261 ASIdentifierChoice * 262 ASIdentifierChoice_new(void) 263 { 264 return (ASIdentifierChoice *)ASN1_item_new(&ASIdentifierChoice_it); 265 } 266 LCRYPTO_ALIAS(ASIdentifierChoice_new); 267 268 void 269 ASIdentifierChoice_free(ASIdentifierChoice *a) 270 { 271 ASN1_item_free((ASN1_VALUE *)a, &ASIdentifierChoice_it); 272 } 273 LCRYPTO_ALIAS(ASIdentifierChoice_free); 274 275 ASIdentifiers * 276 d2i_ASIdentifiers(ASIdentifiers **a, const unsigned char **in, long len) 277 { 278 return (ASIdentifiers *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 279 &ASIdentifiers_it); 280 } 281 LCRYPTO_ALIAS(d2i_ASIdentifiers); 282 283 int 284 i2d_ASIdentifiers(ASIdentifiers *a, unsigned char **out) 285 { 286 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifiers_it); 287 } 288 LCRYPTO_ALIAS(i2d_ASIdentifiers); 289 290 ASIdentifiers * 291 ASIdentifiers_new(void) 292 { 293 return (ASIdentifiers *)ASN1_item_new(&ASIdentifiers_it); 294 } 295 LCRYPTO_ALIAS(ASIdentifiers_new); 296 297 void 298 ASIdentifiers_free(ASIdentifiers *a) 299 { 300 ASN1_item_free((ASN1_VALUE *)a, &ASIdentifiers_it); 301 } 302 LCRYPTO_ALIAS(ASIdentifiers_free); 303 304 /* 305 * i2r method for an ASIdentifierChoice. 306 */ 307 static int 308 i2r_ASIdentifierChoice(BIO *out, ASIdentifierChoice *choice, int indent, 309 const char *msg) 310 { 311 int i; 312 char *s; 313 if (choice == NULL) 314 return 1; 315 BIO_printf(out, "%*s%s:\n", indent, "", msg); 316 switch (choice->type) { 317 case ASIdentifierChoice_inherit: 318 BIO_printf(out, "%*sinherit\n", indent + 2, ""); 319 break; 320 case ASIdentifierChoice_asIdsOrRanges: 321 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); 322 i++) { 323 ASIdOrRange *aor = 324 sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 325 switch (aor->type) { 326 case ASIdOrRange_id: 327 if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == 328 NULL) 329 return 0; 330 BIO_printf(out, "%*s%s\n", indent + 2, "", s); 331 free(s); 332 break; 333 case ASIdOrRange_range: 334 if ((s = i2s_ASN1_INTEGER(NULL, 335 aor->u.range->min)) == NULL) 336 return 0; 337 BIO_printf(out, "%*s%s-", indent + 2, "", s); 338 free(s); 339 if ((s = i2s_ASN1_INTEGER(NULL, 340 aor->u.range->max)) == NULL) 341 return 0; 342 BIO_printf(out, "%s\n", s); 343 free(s); 344 break; 345 default: 346 return 0; 347 } 348 } 349 break; 350 default: 351 return 0; 352 } 353 return 1; 354 } 355 356 /* 357 * i2r method for an ASIdentifier extension. 358 */ 359 static int 360 i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, void *ext, BIO *out, 361 int indent) 362 { 363 ASIdentifiers *asid = ext; 364 return (i2r_ASIdentifierChoice(out, asid->asnum, indent, 365 "Autonomous System Numbers") && 366 i2r_ASIdentifierChoice(out, asid->rdi, indent, 367 "Routing Domain Identifiers")); 368 } 369 370 /* 371 * Sort comparison function for a sequence of ASIdOrRange elements. 372 */ 373 static int 374 ASIdOrRange_cmp(const ASIdOrRange *const *a_, const ASIdOrRange *const *b_) 375 { 376 const ASIdOrRange *a = *a_, *b = *b_; 377 378 /* XXX: these asserts need to be replaced */ 379 OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || 380 (a->type == ASIdOrRange_range && a->u.range != NULL && 381 a->u.range->min != NULL && a->u.range->max != NULL)); 382 383 OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || 384 (b->type == ASIdOrRange_range && b->u.range != NULL && 385 b->u.range->min != NULL && b->u.range->max != NULL)); 386 387 if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) 388 return ASN1_INTEGER_cmp(a->u.id, b->u.id); 389 390 if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { 391 int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); 392 return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, 393 b->u.range->max); 394 } 395 396 if (a->type == ASIdOrRange_id) 397 return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); 398 else 399 return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); 400 } 401 402 /* 403 * Add an inherit element. 404 */ 405 int 406 X509v3_asid_add_inherit(ASIdentifiers *asid, int which) 407 { 408 ASIdentifierChoice **choice; 409 ASIdentifierChoice *aic = NULL; 410 int ret = 0; 411 412 if (asid == NULL) 413 goto err; 414 415 switch (which) { 416 case V3_ASID_ASNUM: 417 choice = &asid->asnum; 418 break; 419 case V3_ASID_RDI: 420 choice = &asid->rdi; 421 break; 422 default: 423 goto err; 424 } 425 426 if (*choice != NULL) { 427 if ((*choice)->type != ASIdentifierChoice_inherit) 428 goto err; 429 } else { 430 if ((aic = ASIdentifierChoice_new()) == NULL) 431 goto err; 432 if ((aic->u.inherit = ASN1_NULL_new()) == NULL) 433 goto err; 434 aic->type = ASIdentifierChoice_inherit; 435 436 *choice = aic; 437 aic = NULL; 438 } 439 440 ret = 1; 441 442 err: 443 ASIdentifierChoice_free(aic); 444 445 return ret; 446 } 447 LCRYPTO_ALIAS(X509v3_asid_add_inherit); 448 449 static int 450 ASIdOrRanges_add_id_or_range(ASIdOrRanges *aors, ASN1_INTEGER *min, 451 ASN1_INTEGER *max) 452 { 453 ASIdOrRange *aor = NULL; 454 ASRange *asr = NULL; 455 int ret = 0; 456 457 /* Preallocate since we must not fail after sk_ASIdOrRange_push(). */ 458 if (max != NULL) { 459 if ((asr = ASRange_new()) == NULL) 460 goto err; 461 } 462 463 if ((aor = ASIdOrRange_new()) == NULL) 464 goto err; 465 if (sk_ASIdOrRange_push(aors, aor) <= 0) 466 goto err; 467 468 if (max == NULL) { 469 aor->type = ASIdOrRange_id; 470 aor->u.id = min; 471 } else { 472 ASN1_INTEGER_free(asr->min); 473 asr->min = min; 474 ASN1_INTEGER_free(asr->max); 475 asr->max = max; 476 477 aor->type = ASIdOrRange_range; 478 aor->u.range = asr; 479 asr = NULL; 480 } 481 482 aor = NULL; 483 484 ret = 1; 485 486 err: 487 ASIdOrRange_free(aor); 488 ASRange_free(asr); 489 490 return ret; 491 } 492 493 /* 494 * Add an ID or range to an ASIdentifierChoice. 495 */ 496 int 497 X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, ASN1_INTEGER *min, 498 ASN1_INTEGER *max) 499 { 500 ASIdentifierChoice **choice; 501 ASIdentifierChoice *aic = NULL, *new_aic = NULL; 502 int ret = 0; 503 504 if (asid == NULL) 505 goto err; 506 507 switch (which) { 508 case V3_ASID_ASNUM: 509 choice = &asid->asnum; 510 break; 511 case V3_ASID_RDI: 512 choice = &asid->rdi; 513 break; 514 default: 515 goto err; 516 } 517 518 if ((aic = *choice) != NULL) { 519 if (aic->type != ASIdentifierChoice_asIdsOrRanges) 520 goto err; 521 } else { 522 if ((aic = new_aic = ASIdentifierChoice_new()) == NULL) 523 goto err; 524 aic->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); 525 if (aic->u.asIdsOrRanges == NULL) 526 goto err; 527 aic->type = ASIdentifierChoice_asIdsOrRanges; 528 } 529 530 if (!ASIdOrRanges_add_id_or_range(aic->u.asIdsOrRanges, min, max)) 531 goto err; 532 533 *choice = aic; 534 aic = new_aic = NULL; 535 536 ret = 1; 537 538 err: 539 ASIdentifierChoice_free(new_aic); 540 541 return ret; 542 } 543 LCRYPTO_ALIAS(X509v3_asid_add_id_or_range); 544 545 /* 546 * Extract min and max values from an ASIdOrRange. 547 */ 548 static int 549 extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max) 550 { 551 switch (aor->type) { 552 case ASIdOrRange_id: 553 *min = aor->u.id; 554 *max = aor->u.id; 555 return 1; 556 case ASIdOrRange_range: 557 *min = aor->u.range->min; 558 *max = aor->u.range->max; 559 return 1; 560 } 561 562 return 0; 563 } 564 565 /* 566 * Check whether an ASIdentifierChoice is in canonical form. 567 */ 568 static int 569 ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) 570 { 571 ASN1_INTEGER *a_max_plus_one = NULL; 572 ASN1_INTEGER *orig; 573 BIGNUM *bn = NULL; 574 int i, ret = 0; 575 576 /* 577 * Empty element or inheritance is canonical. 578 */ 579 if (choice == NULL || choice->type == ASIdentifierChoice_inherit) 580 return 1; 581 582 /* 583 * If not a list, or if empty list, it's broken. 584 */ 585 if (choice->type != ASIdentifierChoice_asIdsOrRanges || 586 sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) 587 return 0; 588 589 /* 590 * It's a list, check it. 591 */ 592 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { 593 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 594 i); 595 ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 596 i + 1); 597 ASN1_INTEGER *a_min = NULL, 598 *a_max = NULL, 599 *b_min = NULL, 600 *b_max = 601 NULL; 602 603 if (!extract_min_max(a, &a_min, &a_max) || 604 !extract_min_max(b, &b_min, &b_max)) 605 goto done; 606 607 /* 608 * Punt misordered list, overlapping start, or inverted range. 609 */ 610 if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || 611 ASN1_INTEGER_cmp(a_min, a_max) > 0 || 612 ASN1_INTEGER_cmp(b_min, b_max) > 0) 613 goto done; 614 615 /* 616 * Calculate a_max + 1 to check for adjacency. 617 */ 618 if ((bn == NULL && (bn = BN_new()) == NULL) || 619 ASN1_INTEGER_to_BN(a_max, bn) == NULL || 620 !BN_add_word(bn, 1)) { 621 X509V3error(ERR_R_MALLOC_FAILURE); 622 goto done; 623 } 624 625 if ((a_max_plus_one = 626 BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { 627 a_max_plus_one = orig; 628 X509V3error(ERR_R_MALLOC_FAILURE); 629 goto done; 630 } 631 632 /* 633 * Punt if adjacent or overlapping. 634 */ 635 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) 636 goto done; 637 } 638 639 /* 640 * Check for inverted range. 641 */ 642 i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; 643 { 644 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 645 i); 646 ASN1_INTEGER *a_min, *a_max; 647 if (a != NULL && a->type == ASIdOrRange_range) { 648 if (!extract_min_max(a, &a_min, &a_max) || 649 ASN1_INTEGER_cmp(a_min, a_max) > 0) 650 goto done; 651 } 652 } 653 654 ret = 1; 655 656 done: 657 ASN1_INTEGER_free(a_max_plus_one); 658 BN_free(bn); 659 return ret; 660 } 661 662 /* 663 * Check whether an ASIdentifier extension is in canonical form. 664 */ 665 int 666 X509v3_asid_is_canonical(ASIdentifiers *asid) 667 { 668 return (asid == NULL || 669 (ASIdentifierChoice_is_canonical(asid->asnum) && 670 ASIdentifierChoice_is_canonical(asid->rdi))); 671 } 672 LCRYPTO_ALIAS(X509v3_asid_is_canonical); 673 674 /* 675 * Whack an ASIdentifierChoice into canonical form. 676 */ 677 static int 678 ASIdentifierChoice_canonize(ASIdentifierChoice *choice) 679 { 680 ASN1_INTEGER *a_max_plus_one = NULL; 681 ASN1_INTEGER *orig; 682 BIGNUM *bn = NULL; 683 int i, ret = 0; 684 685 /* 686 * Nothing to do for empty element or inheritance. 687 */ 688 if (choice == NULL || choice->type == ASIdentifierChoice_inherit) 689 return 1; 690 691 /* 692 * If not a list, or if empty list, it's broken. 693 */ 694 if (choice->type != ASIdentifierChoice_asIdsOrRanges || 695 sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { 696 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 697 return 0; 698 } 699 700 /* 701 * We have a non-empty list. Sort it. 702 */ 703 sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); 704 705 /* 706 * Now check for errors and suboptimal encoding, rejecting the 707 * former and fixing the latter. 708 */ 709 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { 710 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 711 i); 712 ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 713 i + 1); 714 ASN1_INTEGER *a_min = NULL, 715 *a_max = NULL, 716 *b_min = NULL, 717 *b_max = 718 NULL; 719 720 if (!extract_min_max(a, &a_min, &a_max) || 721 !extract_min_max(b, &b_min, &b_max)) 722 goto done; 723 724 /* 725 * Make sure we're properly sorted (paranoia). 726 */ 727 if (ASN1_INTEGER_cmp(a_min, b_min) > 0) 728 goto done; 729 730 /* 731 * Punt inverted ranges. 732 */ 733 if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || 734 ASN1_INTEGER_cmp(b_min, b_max) > 0) 735 goto done; 736 737 /* 738 * Check for overlaps. 739 */ 740 if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { 741 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 742 goto done; 743 } 744 745 /* 746 * Calculate a_max + 1 to check for adjacency. 747 */ 748 if ((bn == NULL && (bn = BN_new()) == NULL) || 749 ASN1_INTEGER_to_BN(a_max, bn) == NULL || 750 !BN_add_word(bn, 1)) { 751 X509V3error(ERR_R_MALLOC_FAILURE); 752 goto done; 753 } 754 755 if ((a_max_plus_one = 756 BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { 757 a_max_plus_one = orig; 758 X509V3error(ERR_R_MALLOC_FAILURE); 759 goto done; 760 } 761 762 /* 763 * If a and b are adjacent, merge them. 764 */ 765 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { 766 ASRange *r; 767 switch (a->type) { 768 case ASIdOrRange_id: 769 if ((r = calloc(1, sizeof(*r))) == NULL) { 770 X509V3error(ERR_R_MALLOC_FAILURE); 771 goto done; 772 } 773 r->min = a_min; 774 r->max = b_max; 775 a->type = ASIdOrRange_range; 776 a->u.range = r; 777 break; 778 case ASIdOrRange_range: 779 ASN1_INTEGER_free(a->u.range->max); 780 a->u.range->max = b_max; 781 break; 782 } 783 switch (b->type) { 784 case ASIdOrRange_id: 785 b->u.id = NULL; 786 break; 787 case ASIdOrRange_range: 788 b->u.range->max = NULL; 789 break; 790 } 791 ASIdOrRange_free(b); 792 (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, 793 i + 1); 794 i--; 795 continue; 796 } 797 } 798 799 /* 800 * Check for final inverted range. 801 */ 802 i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; 803 { 804 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 805 i); 806 ASN1_INTEGER *a_min, *a_max; 807 if (a != NULL && a->type == ASIdOrRange_range) { 808 if (!extract_min_max(a, &a_min, &a_max) || 809 ASN1_INTEGER_cmp(a_min, a_max) > 0) 810 goto done; 811 } 812 } 813 814 /* Paranoia */ 815 if (!ASIdentifierChoice_is_canonical(choice)) 816 goto done; 817 818 ret = 1; 819 820 done: 821 ASN1_INTEGER_free(a_max_plus_one); 822 BN_free(bn); 823 return ret; 824 } 825 826 /* 827 * Whack an ASIdentifier extension into canonical form. 828 */ 829 int 830 X509v3_asid_canonize(ASIdentifiers *asid) 831 { 832 if (asid == NULL) 833 return 1; 834 835 if (!ASIdentifierChoice_canonize(asid->asnum)) 836 return 0; 837 838 return ASIdentifierChoice_canonize(asid->rdi); 839 } 840 LCRYPTO_ALIAS(X509v3_asid_canonize); 841 842 /* 843 * v2i method for an ASIdentifier extension. 844 */ 845 static void * 846 v2i_ASIdentifiers(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, 847 STACK_OF(CONF_VALUE)*values) 848 { 849 ASN1_INTEGER *min = NULL, *max = NULL; 850 ASIdentifiers *asid = NULL; 851 int i; 852 853 if ((asid = ASIdentifiers_new()) == NULL) { 854 X509V3error(ERR_R_MALLOC_FAILURE); 855 return NULL; 856 } 857 858 for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 859 CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 860 int i1 = 0, i2 = 0, i3 = 0, is_range = 0, which = 0; 861 862 /* 863 * Figure out whether this is an AS or an RDI. 864 */ 865 if (!name_cmp(val->name, "AS")) { 866 which = V3_ASID_ASNUM; 867 } else if (!name_cmp(val->name, "RDI")) { 868 which = V3_ASID_RDI; 869 } else { 870 X509V3error(X509V3_R_EXTENSION_NAME_ERROR); 871 X509V3_conf_err(val); 872 goto err; 873 } 874 875 /* 876 * Handle inheritance. 877 */ 878 if (strcmp(val->value, "inherit") == 0) { 879 if (X509v3_asid_add_inherit(asid, which)) 880 continue; 881 X509V3error(X509V3_R_INVALID_INHERITANCE); 882 X509V3_conf_err(val); 883 goto err; 884 } 885 886 /* 887 * Number, range, or mistake, pick it apart and figure out which 888 */ 889 i1 = strspn(val->value, "0123456789"); 890 if (val->value[i1] == '\0') { 891 is_range = 0; 892 } else { 893 is_range = 1; 894 i2 = i1 + strspn(val->value + i1, " \t"); 895 if (val->value[i2] != '-') { 896 X509V3error(X509V3_R_INVALID_ASNUMBER); 897 X509V3_conf_err(val); 898 goto err; 899 } 900 i2++; 901 i2 = i2 + strspn(val->value + i2, " \t"); 902 i3 = i2 + strspn(val->value + i2, "0123456789"); 903 if (val->value[i3] != '\0') { 904 X509V3error(X509V3_R_INVALID_ASRANGE); 905 X509V3_conf_err(val); 906 goto err; 907 } 908 } 909 910 /* 911 * Syntax is ok, read and add it. 912 */ 913 if (!is_range) { 914 if (!X509V3_get_value_int(val, &min)) { 915 X509V3error(ERR_R_MALLOC_FAILURE); 916 goto err; 917 } 918 } else { 919 char *s = strdup(val->value); 920 if (s == NULL) { 921 X509V3error(ERR_R_MALLOC_FAILURE); 922 goto err; 923 } 924 s[i1] = '\0'; 925 min = s2i_ASN1_INTEGER(NULL, s); 926 max = s2i_ASN1_INTEGER(NULL, s + i2); 927 free(s); 928 if (min == NULL || max == NULL) { 929 X509V3error(ERR_R_MALLOC_FAILURE); 930 goto err; 931 } 932 if (ASN1_INTEGER_cmp(min, max) > 0) { 933 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 934 goto err; 935 } 936 } 937 if (!X509v3_asid_add_id_or_range(asid, which, min, max)) { 938 X509V3error(ERR_R_MALLOC_FAILURE); 939 goto err; 940 } 941 min = max = NULL; 942 } 943 944 /* 945 * Canonize the result, then we're done. 946 */ 947 if (!X509v3_asid_canonize(asid)) 948 goto err; 949 return asid; 950 951 err: 952 ASIdentifiers_free(asid); 953 ASN1_INTEGER_free(min); 954 ASN1_INTEGER_free(max); 955 return NULL; 956 } 957 958 /* 959 * OpenSSL dispatch. 960 */ 961 const X509V3_EXT_METHOD v3_asid = { 962 .ext_nid = NID_sbgp_autonomousSysNum, 963 .ext_flags = 0, 964 .it = &ASIdentifiers_it, 965 .ext_new = NULL, 966 .ext_free = NULL, 967 .d2i = NULL, 968 .i2d = NULL, 969 .i2s = NULL, 970 .s2i = NULL, 971 .i2v = NULL, 972 .v2i = v2i_ASIdentifiers, 973 .i2r = i2r_ASIdentifiers, 974 .r2i = NULL, 975 .usr_data = NULL, 976 }; 977 978 /* 979 * Figure out whether extension uses inheritance. 980 */ 981 int 982 X509v3_asid_inherits(ASIdentifiers *asid) 983 { 984 if (asid == NULL) 985 return 0; 986 987 if (asid->asnum != NULL) { 988 if (asid->asnum->type == ASIdentifierChoice_inherit) 989 return 1; 990 } 991 992 if (asid->rdi != NULL) { 993 if (asid->rdi->type == ASIdentifierChoice_inherit) 994 return 1; 995 } 996 997 return 0; 998 } 999 LCRYPTO_ALIAS(X509v3_asid_inherits); 1000 1001 /* 1002 * Figure out whether parent contains child. 1003 */ 1004 static int 1005 asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) 1006 { 1007 ASN1_INTEGER *p_min = NULL, *p_max = NULL, *c_min = NULL, *c_max = NULL; 1008 int p, c; 1009 1010 if (child == NULL || parent == child) 1011 return 1; 1012 1013 if (parent == NULL) 1014 return 0; 1015 1016 p = 0; 1017 for (c = 0; c < sk_ASIdOrRange_num(child); c++) { 1018 if (!extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, 1019 &c_max)) 1020 return 0; 1021 for (;; p++) { 1022 if (p >= sk_ASIdOrRange_num(parent)) 1023 return 0; 1024 if (!extract_min_max(sk_ASIdOrRange_value(parent, p), 1025 &p_min, &p_max)) 1026 return 0; 1027 if (ASN1_INTEGER_cmp(p_max, c_max) < 0) 1028 continue; 1029 if (ASN1_INTEGER_cmp(p_min, c_min) > 0) 1030 return 0; 1031 break; 1032 } 1033 } 1034 1035 return 1; 1036 } 1037 1038 /* 1039 * Test whether child is a subset of parent. 1040 */ 1041 int 1042 X509v3_asid_subset(ASIdentifiers *child, ASIdentifiers *parent) 1043 { 1044 if (child == NULL || child == parent) 1045 return 1; 1046 1047 if (parent == NULL) 1048 return 0; 1049 1050 if (X509v3_asid_inherits(child) || X509v3_asid_inherits(parent)) 1051 return 0; 1052 1053 if (child->asnum != NULL) { 1054 if (parent->asnum == NULL) 1055 return 0; 1056 1057 if (!asid_contains(parent->asnum->u.asIdsOrRanges, 1058 child->asnum->u.asIdsOrRanges)) 1059 return 0; 1060 } 1061 1062 if (child->rdi != NULL) { 1063 if (parent->rdi == NULL) 1064 return 0; 1065 1066 if (!asid_contains(parent->rdi->u.asIdsOrRanges, 1067 child->rdi->u.asIdsOrRanges)) 1068 return 0; 1069 } 1070 1071 return 1; 1072 } 1073 LCRYPTO_ALIAS(X509v3_asid_subset); 1074 1075 /* 1076 * Validation error handling via callback. 1077 */ 1078 #define validation_err(_err_) \ 1079 do { \ 1080 if (ctx != NULL) { \ 1081 ctx->error = _err_; \ 1082 ctx->error_depth = i; \ 1083 ctx->current_cert = x; \ 1084 ret = ctx->verify_cb(0, ctx); \ 1085 } else { \ 1086 ret = 0; \ 1087 } \ 1088 if (!ret) \ 1089 goto done; \ 1090 } while (0) 1091 1092 /* 1093 * Core code for RFC 3779 3.3 path validation. 1094 */ 1095 static int 1096 asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, 1097 ASIdentifiers *ext) 1098 { 1099 ASIdOrRanges *child_as = NULL, *child_rdi = NULL; 1100 int i, ret = 1, inherit_as = 0, inherit_rdi = 0; 1101 X509 *x; 1102 1103 /* We need a non-empty chain to test against. */ 1104 if (sk_X509_num(chain) <= 0) 1105 goto err; 1106 /* We need either a store ctx or an extension to work with. */ 1107 if (ctx == NULL && ext == NULL) 1108 goto err; 1109 /* If there is a store ctx, it needs a verify_cb. */ 1110 if (ctx != NULL && ctx->verify_cb == NULL) 1111 goto err; 1112 1113 /* 1114 * Figure out where to start. If we don't have an extension to check, 1115 * (either extracted from the leaf or passed by the caller), we're done. 1116 * Otherwise, check canonical form and set up for walking up the chain. 1117 */ 1118 if (ext != NULL) { 1119 i = -1; 1120 x = NULL; 1121 if (!X509v3_asid_is_canonical(ext)) 1122 validation_err(X509_V_ERR_INVALID_EXTENSION); 1123 } else { 1124 i = 0; 1125 x = sk_X509_value(chain, i); 1126 if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) 1127 goto done; 1128 if ((ext = x->rfc3779_asid) == NULL) 1129 goto done; 1130 } 1131 if (ext->asnum != NULL) { 1132 switch (ext->asnum->type) { 1133 case ASIdentifierChoice_inherit: 1134 inherit_as = 1; 1135 break; 1136 case ASIdentifierChoice_asIdsOrRanges: 1137 child_as = ext->asnum->u.asIdsOrRanges; 1138 break; 1139 } 1140 } 1141 if (ext->rdi != NULL) { 1142 switch (ext->rdi->type) { 1143 case ASIdentifierChoice_inherit: 1144 inherit_rdi = 1; 1145 break; 1146 case ASIdentifierChoice_asIdsOrRanges: 1147 child_rdi = ext->rdi->u.asIdsOrRanges; 1148 break; 1149 } 1150 } 1151 1152 /* 1153 * Now walk up the chain. Extensions must be in canonical form, no 1154 * cert may list resources that its parent doesn't list. 1155 */ 1156 for (i++; i < sk_X509_num(chain); i++) { 1157 x = sk_X509_value(chain, i); 1158 1159 if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) 1160 validation_err(X509_V_ERR_INVALID_EXTENSION); 1161 if (x->rfc3779_asid == NULL) { 1162 if (child_as != NULL || child_rdi != NULL) 1163 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1164 continue; 1165 } 1166 if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { 1167 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1168 child_as = NULL; 1169 inherit_as = 0; 1170 } 1171 if (x->rfc3779_asid->asnum != NULL && 1172 x->rfc3779_asid->asnum->type == 1173 ASIdentifierChoice_asIdsOrRanges) { 1174 if (inherit_as || 1175 asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, 1176 child_as)) { 1177 child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; 1178 inherit_as = 0; 1179 } else { 1180 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1181 } 1182 } 1183 if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { 1184 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1185 child_rdi = NULL; 1186 inherit_rdi = 0; 1187 } 1188 if (x->rfc3779_asid->rdi != NULL && 1189 x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { 1190 if (inherit_rdi || 1191 asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, 1192 child_rdi)) { 1193 child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; 1194 inherit_rdi = 0; 1195 } else { 1196 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1197 } 1198 } 1199 } 1200 1201 /* 1202 * Trust anchor can't inherit. 1203 */ 1204 1205 if (x == NULL) 1206 goto err; 1207 1208 if (x->rfc3779_asid != NULL) { 1209 if (x->rfc3779_asid->asnum != NULL && 1210 x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) 1211 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1212 if (x->rfc3779_asid->rdi != NULL && 1213 x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) 1214 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1215 } 1216 1217 done: 1218 return ret; 1219 1220 err: 1221 if (ctx != NULL) 1222 ctx->error = X509_V_ERR_UNSPECIFIED; 1223 1224 return 0; 1225 } 1226 1227 #undef validation_err 1228 1229 /* 1230 * RFC 3779 3.3 path validation -- called from X509_verify_cert(). 1231 */ 1232 int 1233 X509v3_asid_validate_path(X509_STORE_CTX *ctx) 1234 { 1235 if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) { 1236 ctx->error = X509_V_ERR_UNSPECIFIED; 1237 return 0; 1238 } 1239 return asid_validate_path_internal(ctx, ctx->chain, NULL); 1240 } 1241 LCRYPTO_ALIAS(X509v3_asid_validate_path); 1242 1243 /* 1244 * RFC 3779 3.3 path validation of an extension. 1245 * Test whether chain covers extension. 1246 */ 1247 int 1248 X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext, 1249 int allow_inheritance) 1250 { 1251 if (ext == NULL) 1252 return 1; 1253 if (sk_X509_num(chain) <= 0) 1254 return 0; 1255 if (!allow_inheritance && X509v3_asid_inherits(ext)) 1256 return 0; 1257 return asid_validate_path_internal(NULL, chain, ext); 1258 } 1259 LCRYPTO_ALIAS(X509v3_asid_validate_resource_set); 1260 1261 #endif /* OPENSSL_NO_RFC3779 */ 1262