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