1 /* $OpenBSD: x509_asid.c,v 1.40 2023/04/19 12:30:09 jsg 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 if (asid == NULL) 410 return 0; 411 switch (which) { 412 case V3_ASID_ASNUM: 413 choice = &asid->asnum; 414 break; 415 case V3_ASID_RDI: 416 choice = &asid->rdi; 417 break; 418 default: 419 return 0; 420 } 421 if (*choice == NULL) { 422 if ((*choice = ASIdentifierChoice_new()) == NULL) 423 return 0; 424 if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) 425 return 0; 426 (*choice)->type = ASIdentifierChoice_inherit; 427 } 428 return (*choice)->type == ASIdentifierChoice_inherit; 429 } 430 LCRYPTO_ALIAS(X509v3_asid_add_inherit); 431 432 /* 433 * Add an ID or range to an ASIdentifierChoice. 434 */ 435 int 436 X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, ASN1_INTEGER *min, 437 ASN1_INTEGER *max) 438 { 439 ASIdentifierChoice **choice; 440 ASIdOrRange *aor; 441 if (asid == NULL) 442 return 0; 443 switch (which) { 444 case V3_ASID_ASNUM: 445 choice = &asid->asnum; 446 break; 447 case V3_ASID_RDI: 448 choice = &asid->rdi; 449 break; 450 default: 451 return 0; 452 } 453 if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) 454 return 0; 455 if (*choice == NULL) { 456 if ((*choice = ASIdentifierChoice_new()) == NULL) 457 return 0; 458 (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); 459 if ((*choice)->u.asIdsOrRanges == NULL) 460 return 0; 461 (*choice)->type = ASIdentifierChoice_asIdsOrRanges; 462 } 463 if ((aor = ASIdOrRange_new()) == NULL) 464 return 0; 465 if (max == NULL) { 466 aor->type = ASIdOrRange_id; 467 aor->u.id = min; 468 } else { 469 aor->type = ASIdOrRange_range; 470 if ((aor->u.range = ASRange_new()) == NULL) 471 goto err; 472 ASN1_INTEGER_free(aor->u.range->min); 473 aor->u.range->min = min; 474 ASN1_INTEGER_free(aor->u.range->max); 475 aor->u.range->max = max; 476 } 477 if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) 478 goto err; 479 return 1; 480 481 err: 482 ASIdOrRange_free(aor); 483 return 0; 484 } 485 LCRYPTO_ALIAS(X509v3_asid_add_id_or_range); 486 487 /* 488 * Extract min and max values from an ASIdOrRange. 489 */ 490 static int 491 extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max) 492 { 493 switch (aor->type) { 494 case ASIdOrRange_id: 495 *min = aor->u.id; 496 *max = aor->u.id; 497 return 1; 498 case ASIdOrRange_range: 499 *min = aor->u.range->min; 500 *max = aor->u.range->max; 501 return 1; 502 } 503 504 return 0; 505 } 506 507 /* 508 * Check whether an ASIdentifierChoice is in canonical form. 509 */ 510 static int 511 ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) 512 { 513 ASN1_INTEGER *a_max_plus_one = NULL; 514 ASN1_INTEGER *orig; 515 BIGNUM *bn = NULL; 516 int i, ret = 0; 517 518 /* 519 * Empty element or inheritance is canonical. 520 */ 521 if (choice == NULL || choice->type == ASIdentifierChoice_inherit) 522 return 1; 523 524 /* 525 * If not a list, or if empty list, it's broken. 526 */ 527 if (choice->type != ASIdentifierChoice_asIdsOrRanges || 528 sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) 529 return 0; 530 531 /* 532 * It's a list, check it. 533 */ 534 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { 535 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 536 i); 537 ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 538 i + 1); 539 ASN1_INTEGER *a_min = NULL, 540 *a_max = NULL, 541 *b_min = NULL, 542 *b_max = 543 NULL; 544 545 if (!extract_min_max(a, &a_min, &a_max) || 546 !extract_min_max(b, &b_min, &b_max)) 547 goto done; 548 549 /* 550 * Punt misordered list, overlapping start, or inverted range. 551 */ 552 if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || 553 ASN1_INTEGER_cmp(a_min, a_max) > 0 || 554 ASN1_INTEGER_cmp(b_min, b_max) > 0) 555 goto done; 556 557 /* 558 * Calculate a_max + 1 to check for adjacency. 559 */ 560 if ((bn == NULL && (bn = BN_new()) == NULL) || 561 ASN1_INTEGER_to_BN(a_max, bn) == NULL || 562 !BN_add_word(bn, 1)) { 563 X509V3error(ERR_R_MALLOC_FAILURE); 564 goto done; 565 } 566 567 if ((a_max_plus_one = 568 BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { 569 a_max_plus_one = orig; 570 X509V3error(ERR_R_MALLOC_FAILURE); 571 goto done; 572 } 573 574 /* 575 * Punt if adjacent or overlapping. 576 */ 577 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) 578 goto done; 579 } 580 581 /* 582 * Check for inverted range. 583 */ 584 i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; 585 { 586 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 587 i); 588 ASN1_INTEGER *a_min, *a_max; 589 if (a != NULL && a->type == ASIdOrRange_range) { 590 if (!extract_min_max(a, &a_min, &a_max) || 591 ASN1_INTEGER_cmp(a_min, a_max) > 0) 592 goto done; 593 } 594 } 595 596 ret = 1; 597 598 done: 599 ASN1_INTEGER_free(a_max_plus_one); 600 BN_free(bn); 601 return ret; 602 } 603 604 /* 605 * Check whether an ASIdentifier extension is in canonical form. 606 */ 607 int 608 X509v3_asid_is_canonical(ASIdentifiers *asid) 609 { 610 return (asid == NULL || 611 (ASIdentifierChoice_is_canonical(asid->asnum) && 612 ASIdentifierChoice_is_canonical(asid->rdi))); 613 } 614 LCRYPTO_ALIAS(X509v3_asid_is_canonical); 615 616 /* 617 * Whack an ASIdentifierChoice into canonical form. 618 */ 619 static int 620 ASIdentifierChoice_canonize(ASIdentifierChoice *choice) 621 { 622 ASN1_INTEGER *a_max_plus_one = NULL; 623 ASN1_INTEGER *orig; 624 BIGNUM *bn = NULL; 625 int i, ret = 0; 626 627 /* 628 * Nothing to do for empty element or inheritance. 629 */ 630 if (choice == NULL || choice->type == ASIdentifierChoice_inherit) 631 return 1; 632 633 /* 634 * If not a list, or if empty list, it's broken. 635 */ 636 if (choice->type != ASIdentifierChoice_asIdsOrRanges || 637 sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { 638 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 639 return 0; 640 } 641 642 /* 643 * We have a non-empty list. Sort it. 644 */ 645 sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); 646 647 /* 648 * Now check for errors and suboptimal encoding, rejecting the 649 * former and fixing the latter. 650 */ 651 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { 652 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 653 i); 654 ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 655 i + 1); 656 ASN1_INTEGER *a_min = NULL, 657 *a_max = NULL, 658 *b_min = NULL, 659 *b_max = 660 NULL; 661 662 if (!extract_min_max(a, &a_min, &a_max) || 663 !extract_min_max(b, &b_min, &b_max)) 664 goto done; 665 666 /* 667 * Make sure we're properly sorted (paranoia). 668 */ 669 if (ASN1_INTEGER_cmp(a_min, b_min) > 0) 670 goto done; 671 672 /* 673 * Punt inverted ranges. 674 */ 675 if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || 676 ASN1_INTEGER_cmp(b_min, b_max) > 0) 677 goto done; 678 679 /* 680 * Check for overlaps. 681 */ 682 if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { 683 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 684 goto done; 685 } 686 687 /* 688 * Calculate a_max + 1 to check for adjacency. 689 */ 690 if ((bn == NULL && (bn = BN_new()) == NULL) || 691 ASN1_INTEGER_to_BN(a_max, bn) == NULL || 692 !BN_add_word(bn, 1)) { 693 X509V3error(ERR_R_MALLOC_FAILURE); 694 goto done; 695 } 696 697 if ((a_max_plus_one = 698 BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) { 699 a_max_plus_one = orig; 700 X509V3error(ERR_R_MALLOC_FAILURE); 701 goto done; 702 } 703 704 /* 705 * If a and b are adjacent, merge them. 706 */ 707 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { 708 ASRange *r; 709 switch (a->type) { 710 case ASIdOrRange_id: 711 if ((r = calloc(1, sizeof(*r))) == NULL) { 712 X509V3error(ERR_R_MALLOC_FAILURE); 713 goto done; 714 } 715 r->min = a_min; 716 r->max = b_max; 717 a->type = ASIdOrRange_range; 718 a->u.range = r; 719 break; 720 case ASIdOrRange_range: 721 ASN1_INTEGER_free(a->u.range->max); 722 a->u.range->max = b_max; 723 break; 724 } 725 switch (b->type) { 726 case ASIdOrRange_id: 727 b->u.id = NULL; 728 break; 729 case ASIdOrRange_range: 730 b->u.range->max = NULL; 731 break; 732 } 733 ASIdOrRange_free(b); 734 (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, 735 i + 1); 736 i--; 737 continue; 738 } 739 } 740 741 /* 742 * Check for final inverted range. 743 */ 744 i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; 745 { 746 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, 747 i); 748 ASN1_INTEGER *a_min, *a_max; 749 if (a != NULL && a->type == ASIdOrRange_range) { 750 if (!extract_min_max(a, &a_min, &a_max) || 751 ASN1_INTEGER_cmp(a_min, a_max) > 0) 752 goto done; 753 } 754 } 755 756 /* Paranoia */ 757 if (!ASIdentifierChoice_is_canonical(choice)) 758 goto done; 759 760 ret = 1; 761 762 done: 763 ASN1_INTEGER_free(a_max_plus_one); 764 BN_free(bn); 765 return ret; 766 } 767 768 /* 769 * Whack an ASIdentifier extension into canonical form. 770 */ 771 int 772 X509v3_asid_canonize(ASIdentifiers *asid) 773 { 774 if (asid == NULL) 775 return 1; 776 777 if (!ASIdentifierChoice_canonize(asid->asnum)) 778 return 0; 779 780 return ASIdentifierChoice_canonize(asid->rdi); 781 } 782 LCRYPTO_ALIAS(X509v3_asid_canonize); 783 784 /* 785 * v2i method for an ASIdentifier extension. 786 */ 787 static void * 788 v2i_ASIdentifiers(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, 789 STACK_OF(CONF_VALUE)*values) 790 { 791 ASN1_INTEGER *min = NULL, *max = NULL; 792 ASIdentifiers *asid = NULL; 793 int i; 794 795 if ((asid = ASIdentifiers_new()) == NULL) { 796 X509V3error(ERR_R_MALLOC_FAILURE); 797 return NULL; 798 } 799 800 for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 801 CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 802 int i1 = 0, i2 = 0, i3 = 0, is_range = 0, which = 0; 803 804 /* 805 * Figure out whether this is an AS or an RDI. 806 */ 807 if (!name_cmp(val->name, "AS")) { 808 which = V3_ASID_ASNUM; 809 } else if (!name_cmp(val->name, "RDI")) { 810 which = V3_ASID_RDI; 811 } else { 812 X509V3error(X509V3_R_EXTENSION_NAME_ERROR); 813 X509V3_conf_err(val); 814 goto err; 815 } 816 817 /* 818 * Handle inheritance. 819 */ 820 if (strcmp(val->value, "inherit") == 0) { 821 if (X509v3_asid_add_inherit(asid, which)) 822 continue; 823 X509V3error(X509V3_R_INVALID_INHERITANCE); 824 X509V3_conf_err(val); 825 goto err; 826 } 827 828 /* 829 * Number, range, or mistake, pick it apart and figure out which 830 */ 831 i1 = strspn(val->value, "0123456789"); 832 if (val->value[i1] == '\0') { 833 is_range = 0; 834 } else { 835 is_range = 1; 836 i2 = i1 + strspn(val->value + i1, " \t"); 837 if (val->value[i2] != '-') { 838 X509V3error(X509V3_R_INVALID_ASNUMBER); 839 X509V3_conf_err(val); 840 goto err; 841 } 842 i2++; 843 i2 = i2 + strspn(val->value + i2, " \t"); 844 i3 = i2 + strspn(val->value + i2, "0123456789"); 845 if (val->value[i3] != '\0') { 846 X509V3error(X509V3_R_INVALID_ASRANGE); 847 X509V3_conf_err(val); 848 goto err; 849 } 850 } 851 852 /* 853 * Syntax is ok, read and add it. 854 */ 855 if (!is_range) { 856 if (!X509V3_get_value_int(val, &min)) { 857 X509V3error(ERR_R_MALLOC_FAILURE); 858 goto err; 859 } 860 } else { 861 char *s = strdup(val->value); 862 if (s == NULL) { 863 X509V3error(ERR_R_MALLOC_FAILURE); 864 goto err; 865 } 866 s[i1] = '\0'; 867 min = s2i_ASN1_INTEGER(NULL, s); 868 max = s2i_ASN1_INTEGER(NULL, s + i2); 869 free(s); 870 if (min == NULL || max == NULL) { 871 X509V3error(ERR_R_MALLOC_FAILURE); 872 goto err; 873 } 874 if (ASN1_INTEGER_cmp(min, max) > 0) { 875 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 876 goto err; 877 } 878 } 879 if (!X509v3_asid_add_id_or_range(asid, which, min, max)) { 880 X509V3error(ERR_R_MALLOC_FAILURE); 881 goto err; 882 } 883 min = max = NULL; 884 } 885 886 /* 887 * Canonize the result, then we're done. 888 */ 889 if (!X509v3_asid_canonize(asid)) 890 goto err; 891 return asid; 892 893 err: 894 ASIdentifiers_free(asid); 895 ASN1_INTEGER_free(min); 896 ASN1_INTEGER_free(max); 897 return NULL; 898 } 899 900 /* 901 * OpenSSL dispatch. 902 */ 903 const X509V3_EXT_METHOD v3_asid = { 904 .ext_nid = NID_sbgp_autonomousSysNum, 905 .ext_flags = 0, 906 .it = &ASIdentifiers_it, 907 .ext_new = NULL, 908 .ext_free = NULL, 909 .d2i = NULL, 910 .i2d = NULL, 911 .i2s = NULL, 912 .s2i = NULL, 913 .i2v = NULL, 914 .v2i = v2i_ASIdentifiers, 915 .i2r = i2r_ASIdentifiers, 916 .r2i = NULL, 917 .usr_data = NULL, 918 }; 919 920 /* 921 * Figure out whether extension uses inheritance. 922 */ 923 int 924 X509v3_asid_inherits(ASIdentifiers *asid) 925 { 926 if (asid == NULL) 927 return 0; 928 929 if (asid->asnum != NULL) { 930 if (asid->asnum->type == ASIdentifierChoice_inherit) 931 return 1; 932 } 933 934 if (asid->rdi != NULL) { 935 if (asid->rdi->type == ASIdentifierChoice_inherit) 936 return 1; 937 } 938 939 return 0; 940 } 941 LCRYPTO_ALIAS(X509v3_asid_inherits); 942 943 /* 944 * Figure out whether parent contains child. 945 */ 946 static int 947 asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) 948 { 949 ASN1_INTEGER *p_min = NULL, *p_max = NULL, *c_min = NULL, *c_max = NULL; 950 int p, c; 951 952 if (child == NULL || parent == child) 953 return 1; 954 955 if (parent == NULL) 956 return 0; 957 958 p = 0; 959 for (c = 0; c < sk_ASIdOrRange_num(child); c++) { 960 if (!extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, 961 &c_max)) 962 return 0; 963 for (;; p++) { 964 if (p >= sk_ASIdOrRange_num(parent)) 965 return 0; 966 if (!extract_min_max(sk_ASIdOrRange_value(parent, p), 967 &p_min, &p_max)) 968 return 0; 969 if (ASN1_INTEGER_cmp(p_max, c_max) < 0) 970 continue; 971 if (ASN1_INTEGER_cmp(p_min, c_min) > 0) 972 return 0; 973 break; 974 } 975 } 976 977 return 1; 978 } 979 980 /* 981 * Test whether child is a subset of parent. 982 */ 983 int 984 X509v3_asid_subset(ASIdentifiers *child, ASIdentifiers *parent) 985 { 986 if (child == NULL || child == parent) 987 return 1; 988 989 if (parent == NULL) 990 return 0; 991 992 if (X509v3_asid_inherits(child) || X509v3_asid_inherits(parent)) 993 return 0; 994 995 if (child->asnum != NULL) { 996 if (parent->asnum == NULL) 997 return 0; 998 999 if (!asid_contains(parent->asnum->u.asIdsOrRanges, 1000 child->asnum->u.asIdsOrRanges)) 1001 return 0; 1002 } 1003 1004 if (child->rdi != NULL) { 1005 if (parent->rdi == NULL) 1006 return 0; 1007 1008 if (!asid_contains(parent->rdi->u.asIdsOrRanges, 1009 child->rdi->u.asIdsOrRanges)) 1010 return 0; 1011 } 1012 1013 return 1; 1014 } 1015 LCRYPTO_ALIAS(X509v3_asid_subset); 1016 1017 /* 1018 * Validation error handling via callback. 1019 */ 1020 #define validation_err(_err_) \ 1021 do { \ 1022 if (ctx != NULL) { \ 1023 ctx->error = _err_; \ 1024 ctx->error_depth = i; \ 1025 ctx->current_cert = x; \ 1026 ret = ctx->verify_cb(0, ctx); \ 1027 } else { \ 1028 ret = 0; \ 1029 } \ 1030 if (!ret) \ 1031 goto done; \ 1032 } while (0) 1033 1034 /* 1035 * Core code for RFC 3779 3.3 path validation. 1036 */ 1037 static int 1038 asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, 1039 ASIdentifiers *ext) 1040 { 1041 ASIdOrRanges *child_as = NULL, *child_rdi = NULL; 1042 int i, ret = 1, inherit_as = 0, inherit_rdi = 0; 1043 X509 *x; 1044 1045 /* We need a non-empty chain to test against. */ 1046 if (sk_X509_num(chain) <= 0) 1047 goto err; 1048 /* We need either a store ctx or an extension to work with. */ 1049 if (ctx == NULL && ext == NULL) 1050 goto err; 1051 /* If there is a store ctx, it needs a verify_cb. */ 1052 if (ctx != NULL && ctx->verify_cb == NULL) 1053 goto err; 1054 1055 /* 1056 * Figure out where to start. If we don't have an extension to check, 1057 * (either extracted from the leaf or passed by the caller), we're done. 1058 * Otherwise, check canonical form and set up for walking up the chain. 1059 */ 1060 if (ext != NULL) { 1061 i = -1; 1062 x = NULL; 1063 if (!X509v3_asid_is_canonical(ext)) 1064 validation_err(X509_V_ERR_INVALID_EXTENSION); 1065 } else { 1066 i = 0; 1067 x = sk_X509_value(chain, i); 1068 if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) 1069 goto done; 1070 if ((ext = x->rfc3779_asid) == NULL) 1071 goto done; 1072 } 1073 if (ext->asnum != NULL) { 1074 switch (ext->asnum->type) { 1075 case ASIdentifierChoice_inherit: 1076 inherit_as = 1; 1077 break; 1078 case ASIdentifierChoice_asIdsOrRanges: 1079 child_as = ext->asnum->u.asIdsOrRanges; 1080 break; 1081 } 1082 } 1083 if (ext->rdi != NULL) { 1084 switch (ext->rdi->type) { 1085 case ASIdentifierChoice_inherit: 1086 inherit_rdi = 1; 1087 break; 1088 case ASIdentifierChoice_asIdsOrRanges: 1089 child_rdi = ext->rdi->u.asIdsOrRanges; 1090 break; 1091 } 1092 } 1093 1094 /* 1095 * Now walk up the chain. Extensions must be in canonical form, no 1096 * cert may list resources that its parent doesn't list. 1097 */ 1098 for (i++; i < sk_X509_num(chain); i++) { 1099 x = sk_X509_value(chain, i); 1100 1101 if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) 1102 validation_err(X509_V_ERR_INVALID_EXTENSION); 1103 if (x->rfc3779_asid == NULL) { 1104 if (child_as != NULL || child_rdi != NULL) 1105 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1106 continue; 1107 } 1108 if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { 1109 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1110 child_as = NULL; 1111 inherit_as = 0; 1112 } 1113 if (x->rfc3779_asid->asnum != NULL && 1114 x->rfc3779_asid->asnum->type == 1115 ASIdentifierChoice_asIdsOrRanges) { 1116 if (inherit_as || 1117 asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, 1118 child_as)) { 1119 child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; 1120 inherit_as = 0; 1121 } else { 1122 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1123 } 1124 } 1125 if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { 1126 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1127 child_rdi = NULL; 1128 inherit_rdi = 0; 1129 } 1130 if (x->rfc3779_asid->rdi != NULL && 1131 x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { 1132 if (inherit_rdi || 1133 asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, 1134 child_rdi)) { 1135 child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; 1136 inherit_rdi = 0; 1137 } else { 1138 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1139 } 1140 } 1141 } 1142 1143 /* 1144 * Trust anchor can't inherit. 1145 */ 1146 1147 if (x == NULL) 1148 goto err; 1149 1150 if (x->rfc3779_asid != NULL) { 1151 if (x->rfc3779_asid->asnum != NULL && 1152 x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) 1153 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1154 if (x->rfc3779_asid->rdi != NULL && 1155 x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) 1156 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 1157 } 1158 1159 done: 1160 return ret; 1161 1162 err: 1163 if (ctx != NULL) 1164 ctx->error = X509_V_ERR_UNSPECIFIED; 1165 1166 return 0; 1167 } 1168 1169 #undef validation_err 1170 1171 /* 1172 * RFC 3779 3.3 path validation -- called from X509_verify_cert(). 1173 */ 1174 int 1175 X509v3_asid_validate_path(X509_STORE_CTX *ctx) 1176 { 1177 if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) { 1178 ctx->error = X509_V_ERR_UNSPECIFIED; 1179 return 0; 1180 } 1181 return asid_validate_path_internal(ctx, ctx->chain, NULL); 1182 } 1183 LCRYPTO_ALIAS(X509v3_asid_validate_path); 1184 1185 /* 1186 * RFC 3779 3.3 path validation of an extension. 1187 * Test whether chain covers extension. 1188 */ 1189 int 1190 X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext, 1191 int allow_inheritance) 1192 { 1193 if (ext == NULL) 1194 return 1; 1195 if (sk_X509_num(chain) <= 0) 1196 return 0; 1197 if (!allow_inheritance && X509v3_asid_inherits(ext)) 1198 return 0; 1199 return asid_validate_path_internal(NULL, chain, ext); 1200 } 1201 LCRYPTO_ALIAS(X509v3_asid_validate_resource_set); 1202 1203 #endif /* OPENSSL_NO_RFC3779 */ 1204