1 /* 2 * Contributed to the OpenSSL Project by the American Registry for 3 * Internet Numbers ("ARIN"). 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 */ 57 58 /* 59 * Implementation of RFC 3779 section 3.2. 60 */ 61 62 #include <stdio.h> 63 #include <string.h> 64 #include "cryptlib.h" 65 #include <openssl/conf.h> 66 #include <openssl/asn1.h> 67 #include <openssl/asn1t.h> 68 #include <openssl/x509v3.h> 69 #include <openssl/x509.h> 70 #include <openssl/bn.h> 71 72 #ifndef OPENSSL_NO_RFC3779 73 74 /* 75 * OpenSSL ASN.1 template translation of RFC 3779 3.2.3. 76 */ 77 78 ASN1_SEQUENCE(ASRange) = { 79 ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), 80 ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) 81 } ASN1_SEQUENCE_END(ASRange) 82 83 ASN1_CHOICE(ASIdOrRange) = { 84 ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), 85 ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) 86 } ASN1_CHOICE_END(ASIdOrRange) 87 88 ASN1_CHOICE(ASIdentifierChoice) = { 89 ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), 90 ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) 91 } ASN1_CHOICE_END(ASIdentifierChoice) 92 93 ASN1_SEQUENCE(ASIdentifiers) = { 94 ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), 95 ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) 96 } ASN1_SEQUENCE_END(ASIdentifiers) 97 98 IMPLEMENT_ASN1_FUNCTIONS(ASRange) 99 IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange) 100 IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice) 101 IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) 102 103 /* 104 * i2r method for an ASIdentifierChoice. 105 */ 106 static int i2r_ASIdentifierChoice(BIO *out, 107 ASIdentifierChoice *choice, 108 int indent, 109 const char *msg) 110 { 111 int i; 112 char *s; 113 if (choice == NULL) 114 return 1; 115 BIO_printf(out, "%*s%s:\n", indent, "", msg); 116 switch (choice->type) { 117 case ASIdentifierChoice_inherit: 118 BIO_printf(out, "%*sinherit\n", indent + 2, ""); 119 break; 120 case ASIdentifierChoice_asIdsOrRanges: 121 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) { 122 ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 123 switch (aor->type) { 124 case ASIdOrRange_id: 125 if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL) 126 return 0; 127 BIO_printf(out, "%*s%s\n", indent + 2, "", s); 128 OPENSSL_free(s); 129 break; 130 case ASIdOrRange_range: 131 if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL) 132 return 0; 133 BIO_printf(out, "%*s%s-", indent + 2, "", s); 134 OPENSSL_free(s); 135 if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL) 136 return 0; 137 BIO_printf(out, "%s\n", s); 138 OPENSSL_free(s); 139 break; 140 default: 141 return 0; 142 } 143 } 144 break; 145 default: 146 return 0; 147 } 148 return 1; 149 } 150 151 /* 152 * i2r method for an ASIdentifier extension. 153 */ 154 static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, 155 void *ext, 156 BIO *out, 157 int indent) 158 { 159 ASIdentifiers *asid = ext; 160 return (i2r_ASIdentifierChoice(out, asid->asnum, indent, 161 "Autonomous System Numbers") && 162 i2r_ASIdentifierChoice(out, asid->rdi, indent, 163 "Routing Domain Identifiers")); 164 } 165 166 /* 167 * Sort comparision function for a sequence of ASIdOrRange elements. 168 */ 169 static int ASIdOrRange_cmp(const ASIdOrRange * const *a_, 170 const ASIdOrRange * const *b_) 171 { 172 const ASIdOrRange *a = *a_, *b = *b_; 173 174 OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || 175 (a->type == ASIdOrRange_range && a->u.range != NULL && 176 a->u.range->min != NULL && a->u.range->max != NULL)); 177 178 OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || 179 (b->type == ASIdOrRange_range && b->u.range != NULL && 180 b->u.range->min != NULL && b->u.range->max != NULL)); 181 182 if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) 183 return ASN1_INTEGER_cmp(a->u.id, b->u.id); 184 185 if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { 186 int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); 187 return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max); 188 } 189 190 if (a->type == ASIdOrRange_id) 191 return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); 192 else 193 return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); 194 } 195 196 /* 197 * Add an inherit element. 198 */ 199 int v3_asid_add_inherit(ASIdentifiers *asid, int which) 200 { 201 ASIdentifierChoice **choice; 202 if (asid == NULL) 203 return 0; 204 switch (which) { 205 case V3_ASID_ASNUM: 206 choice = &asid->asnum; 207 break; 208 case V3_ASID_RDI: 209 choice = &asid->rdi; 210 break; 211 default: 212 return 0; 213 } 214 if (*choice == NULL) { 215 if ((*choice = ASIdentifierChoice_new()) == NULL) 216 return 0; 217 OPENSSL_assert((*choice)->u.inherit == NULL); 218 if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) 219 return 0; 220 (*choice)->type = ASIdentifierChoice_inherit; 221 } 222 return (*choice)->type == ASIdentifierChoice_inherit; 223 } 224 225 /* 226 * Add an ID or range to an ASIdentifierChoice. 227 */ 228 int v3_asid_add_id_or_range(ASIdentifiers *asid, 229 int which, 230 ASN1_INTEGER *min, 231 ASN1_INTEGER *max) 232 { 233 ASIdentifierChoice **choice; 234 ASIdOrRange *aor; 235 if (asid == NULL) 236 return 0; 237 switch (which) { 238 case V3_ASID_ASNUM: 239 choice = &asid->asnum; 240 break; 241 case V3_ASID_RDI: 242 choice = &asid->rdi; 243 break; 244 default: 245 return 0; 246 } 247 if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) 248 return 0; 249 if (*choice == NULL) { 250 if ((*choice = ASIdentifierChoice_new()) == NULL) 251 return 0; 252 OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); 253 (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); 254 if ((*choice)->u.asIdsOrRanges == NULL) 255 return 0; 256 (*choice)->type = ASIdentifierChoice_asIdsOrRanges; 257 } 258 if ((aor = ASIdOrRange_new()) == NULL) 259 return 0; 260 if (max == NULL) { 261 aor->type = ASIdOrRange_id; 262 aor->u.id = min; 263 } else { 264 aor->type = ASIdOrRange_range; 265 if ((aor->u.range = ASRange_new()) == NULL) 266 goto err; 267 ASN1_INTEGER_free(aor->u.range->min); 268 aor->u.range->min = min; 269 ASN1_INTEGER_free(aor->u.range->max); 270 aor->u.range->max = max; 271 } 272 if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) 273 goto err; 274 return 1; 275 276 err: 277 ASIdOrRange_free(aor); 278 return 0; 279 } 280 281 /* 282 * Extract min and max values from an ASIdOrRange. 283 */ 284 static void extract_min_max(ASIdOrRange *aor, 285 ASN1_INTEGER **min, 286 ASN1_INTEGER **max) 287 { 288 OPENSSL_assert(aor != NULL && min != NULL && max != NULL); 289 switch (aor->type) { 290 case ASIdOrRange_id: 291 *min = aor->u.id; 292 *max = aor->u.id; 293 return; 294 case ASIdOrRange_range: 295 *min = aor->u.range->min; 296 *max = aor->u.range->max; 297 return; 298 } 299 } 300 301 /* 302 * Check whether an ASIdentifierChoice is in canonical form. 303 */ 304 static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) 305 { 306 ASN1_INTEGER *a_max_plus_one = NULL; 307 BIGNUM *bn = NULL; 308 int i, ret = 0; 309 310 /* 311 * Empty element or inheritance is canonical. 312 */ 313 if (choice == NULL || choice->type == ASIdentifierChoice_inherit) 314 return 1; 315 316 /* 317 * If not a list, or if empty list, it's broken. 318 */ 319 if (choice->type != ASIdentifierChoice_asIdsOrRanges || 320 sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) 321 return 0; 322 323 /* 324 * It's a list, check it. 325 */ 326 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { 327 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 328 ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); 329 ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; 330 331 extract_min_max(a, &a_min, &a_max); 332 extract_min_max(b, &b_min, &b_max); 333 334 /* 335 * Punt misordered list, overlapping start, or inverted range. 336 */ 337 if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || 338 ASN1_INTEGER_cmp(a_min, a_max) > 0 || 339 ASN1_INTEGER_cmp(b_min, b_max) > 0) 340 goto done; 341 342 /* 343 * Calculate a_max + 1 to check for adjacency. 344 */ 345 if ((bn == NULL && (bn = BN_new()) == NULL) || 346 ASN1_INTEGER_to_BN(a_max, bn) == NULL || 347 !BN_add_word(bn, 1) || 348 (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { 349 X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, 350 ERR_R_MALLOC_FAILURE); 351 goto done; 352 } 353 354 /* 355 * Punt if adjacent or overlapping. 356 */ 357 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) 358 goto done; 359 } 360 361 /* 362 * Check for inverted range. 363 */ 364 i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; 365 { 366 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 367 ASN1_INTEGER *a_min, *a_max; 368 if (a != NULL && a->type == ASIdOrRange_range) { 369 extract_min_max(a, &a_min, &a_max); 370 if (ASN1_INTEGER_cmp(a_min, a_max) > 0) 371 goto done; 372 } 373 } 374 375 ret = 1; 376 377 done: 378 ASN1_INTEGER_free(a_max_plus_one); 379 BN_free(bn); 380 return ret; 381 } 382 383 /* 384 * Check whether an ASIdentifier extension is in canonical form. 385 */ 386 int v3_asid_is_canonical(ASIdentifiers *asid) 387 { 388 return (asid == NULL || 389 (ASIdentifierChoice_is_canonical(asid->asnum) && 390 ASIdentifierChoice_is_canonical(asid->rdi))); 391 } 392 393 /* 394 * Whack an ASIdentifierChoice into canonical form. 395 */ 396 static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) 397 { 398 ASN1_INTEGER *a_max_plus_one = NULL; 399 BIGNUM *bn = NULL; 400 int i, ret = 0; 401 402 /* 403 * Nothing to do for empty element or inheritance. 404 */ 405 if (choice == NULL || choice->type == ASIdentifierChoice_inherit) 406 return 1; 407 408 /* 409 * If not a list, or if empty list, it's broken. 410 */ 411 if (choice->type != ASIdentifierChoice_asIdsOrRanges || 412 sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { 413 X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, 414 X509V3_R_EXTENSION_VALUE_ERROR); 415 return 0; 416 } 417 418 /* 419 * We have a non-empty list. Sort it. 420 */ 421 sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); 422 423 /* 424 * Now check for errors and suboptimal encoding, rejecting the 425 * former and fixing the latter. 426 */ 427 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { 428 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 429 ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); 430 ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; 431 432 extract_min_max(a, &a_min, &a_max); 433 extract_min_max(b, &b_min, &b_max); 434 435 /* 436 * Make sure we're properly sorted (paranoia). 437 */ 438 OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); 439 440 /* 441 * Punt inverted ranges. 442 */ 443 if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || 444 ASN1_INTEGER_cmp(b_min, b_max) > 0) 445 goto done; 446 447 /* 448 * Check for overlaps. 449 */ 450 if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { 451 X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, 452 X509V3_R_EXTENSION_VALUE_ERROR); 453 goto done; 454 } 455 456 /* 457 * Calculate a_max + 1 to check for adjacency. 458 */ 459 if ((bn == NULL && (bn = BN_new()) == NULL) || 460 ASN1_INTEGER_to_BN(a_max, bn) == NULL || 461 !BN_add_word(bn, 1) || 462 (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { 463 X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE); 464 goto done; 465 } 466 467 /* 468 * If a and b are adjacent, merge them. 469 */ 470 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { 471 ASRange *r; 472 switch (a->type) { 473 case ASIdOrRange_id: 474 if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) { 475 X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, 476 ERR_R_MALLOC_FAILURE); 477 goto done; 478 } 479 r->min = a_min; 480 r->max = b_max; 481 a->type = ASIdOrRange_range; 482 a->u.range = r; 483 break; 484 case ASIdOrRange_range: 485 ASN1_INTEGER_free(a->u.range->max); 486 a->u.range->max = b_max; 487 break; 488 } 489 switch (b->type) { 490 case ASIdOrRange_id: 491 b->u.id = NULL; 492 break; 493 case ASIdOrRange_range: 494 b->u.range->max = NULL; 495 break; 496 } 497 ASIdOrRange_free(b); 498 (void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); 499 i--; 500 continue; 501 } 502 } 503 504 /* 505 * Check for final inverted range. 506 */ 507 i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; 508 { 509 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 510 ASN1_INTEGER *a_min, *a_max; 511 if (a != NULL && a->type == ASIdOrRange_range) { 512 extract_min_max(a, &a_min, &a_max); 513 if (ASN1_INTEGER_cmp(a_min, a_max) > 0) 514 goto done; 515 } 516 } 517 518 OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ 519 520 ret = 1; 521 522 done: 523 ASN1_INTEGER_free(a_max_plus_one); 524 BN_free(bn); 525 return ret; 526 } 527 528 /* 529 * Whack an ASIdentifier extension into canonical form. 530 */ 531 int v3_asid_canonize(ASIdentifiers *asid) 532 { 533 return (asid == NULL || 534 (ASIdentifierChoice_canonize(asid->asnum) && 535 ASIdentifierChoice_canonize(asid->rdi))); 536 } 537 538 /* 539 * v2i method for an ASIdentifier extension. 540 */ 541 static void *v2i_ASIdentifiers(const struct v3_ext_method *method, 542 struct v3_ext_ctx *ctx, 543 STACK_OF(CONF_VALUE) *values) 544 { 545 ASN1_INTEGER *min = NULL, *max = NULL; 546 ASIdentifiers *asid = NULL; 547 int i; 548 549 if ((asid = ASIdentifiers_new()) == NULL) { 550 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 551 return NULL; 552 } 553 554 for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 555 CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 556 int i1, i2, i3, is_range, which; 557 558 /* 559 * Figure out whether this is an AS or an RDI. 560 */ 561 if ( !name_cmp(val->name, "AS")) { 562 which = V3_ASID_ASNUM; 563 } else if (!name_cmp(val->name, "RDI")) { 564 which = V3_ASID_RDI; 565 } else { 566 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR); 567 X509V3_conf_err(val); 568 goto err; 569 } 570 571 /* 572 * Handle inheritance. 573 */ 574 if (!strcmp(val->value, "inherit")) { 575 if (v3_asid_add_inherit(asid, which)) 576 continue; 577 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE); 578 X509V3_conf_err(val); 579 goto err; 580 } 581 582 /* 583 * Number, range, or mistake, pick it apart and figure out which. 584 */ 585 i1 = strspn(val->value, "0123456789"); 586 if (val->value[i1] == '\0') { 587 is_range = 0; 588 } else { 589 is_range = 1; 590 i2 = i1 + strspn(val->value + i1, " \t"); 591 if (val->value[i2] != '-') { 592 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER); 593 X509V3_conf_err(val); 594 goto err; 595 } 596 i2++; 597 i2 = i2 + strspn(val->value + i2, " \t"); 598 i3 = i2 + strspn(val->value + i2, "0123456789"); 599 if (val->value[i3] != '\0') { 600 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE); 601 X509V3_conf_err(val); 602 goto err; 603 } 604 } 605 606 /* 607 * Syntax is ok, read and add it. 608 */ 609 if (!is_range) { 610 if (!X509V3_get_value_int(val, &min)) { 611 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 612 goto err; 613 } 614 } else { 615 char *s = BUF_strdup(val->value); 616 if (s == NULL) { 617 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 618 goto err; 619 } 620 s[i1] = '\0'; 621 min = s2i_ASN1_INTEGER(NULL, s); 622 max = s2i_ASN1_INTEGER(NULL, s + i2); 623 OPENSSL_free(s); 624 if (min == NULL || max == NULL) { 625 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 626 goto err; 627 } 628 if (ASN1_INTEGER_cmp(min, max) > 0) { 629 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_VALUE_ERROR); 630 goto err; 631 } 632 } 633 if (!v3_asid_add_id_or_range(asid, which, min, max)) { 634 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 635 goto err; 636 } 637 min = max = NULL; 638 } 639 640 /* 641 * Canonize the result, then we're done. 642 */ 643 if (!v3_asid_canonize(asid)) 644 goto err; 645 return asid; 646 647 err: 648 ASIdentifiers_free(asid); 649 ASN1_INTEGER_free(min); 650 ASN1_INTEGER_free(max); 651 return NULL; 652 } 653 654 /* 655 * OpenSSL dispatch. 656 */ 657 const X509V3_EXT_METHOD v3_asid = { 658 NID_sbgp_autonomousSysNum, /* nid */ 659 0, /* flags */ 660 ASN1_ITEM_ref(ASIdentifiers), /* template */ 661 0, 0, 0, 0, /* old functions, ignored */ 662 0, /* i2s */ 663 0, /* s2i */ 664 0, /* i2v */ 665 v2i_ASIdentifiers, /* v2i */ 666 i2r_ASIdentifiers, /* i2r */ 667 0, /* r2i */ 668 NULL /* extension-specific data */ 669 }; 670 671 /* 672 * Figure out whether extension uses inheritance. 673 */ 674 int v3_asid_inherits(ASIdentifiers *asid) 675 { 676 return (asid != NULL && 677 ((asid->asnum != NULL && 678 asid->asnum->type == ASIdentifierChoice_inherit) || 679 (asid->rdi != NULL && 680 asid->rdi->type == ASIdentifierChoice_inherit))); 681 } 682 683 /* 684 * Figure out whether parent contains child. 685 */ 686 static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) 687 { 688 ASN1_INTEGER *p_min, *p_max, *c_min, *c_max; 689 int p, c; 690 691 if (child == NULL || parent == child) 692 return 1; 693 if (parent == NULL) 694 return 0; 695 696 p = 0; 697 for (c = 0; c < sk_ASIdOrRange_num(child); c++) { 698 extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max); 699 for (;; p++) { 700 if (p >= sk_ASIdOrRange_num(parent)) 701 return 0; 702 extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max); 703 if (ASN1_INTEGER_cmp(p_max, c_max) < 0) 704 continue; 705 if (ASN1_INTEGER_cmp(p_min, c_min) > 0) 706 return 0; 707 break; 708 } 709 } 710 711 return 1; 712 } 713 714 /* 715 * Test whether a is a subet of b. 716 */ 717 int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) 718 { 719 return (a == NULL || 720 a == b || 721 (b != NULL && 722 !v3_asid_inherits(a) && 723 !v3_asid_inherits(b) && 724 asid_contains(b->asnum->u.asIdsOrRanges, 725 a->asnum->u.asIdsOrRanges) && 726 asid_contains(b->rdi->u.asIdsOrRanges, 727 a->rdi->u.asIdsOrRanges))); 728 } 729 730 /* 731 * Validation error handling via callback. 732 */ 733 #define validation_err(_err_) \ 734 do { \ 735 if (ctx != NULL) { \ 736 ctx->error = _err_; \ 737 ctx->error_depth = i; \ 738 ctx->current_cert = x; \ 739 ret = ctx->verify_cb(0, ctx); \ 740 } else { \ 741 ret = 0; \ 742 } \ 743 if (!ret) \ 744 goto done; \ 745 } while (0) 746 747 /* 748 * Core code for RFC 3779 3.3 path validation. 749 */ 750 static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, 751 STACK_OF(X509) *chain, 752 ASIdentifiers *ext) 753 { 754 ASIdOrRanges *child_as = NULL, *child_rdi = NULL; 755 int i, ret = 1, inherit_as = 0, inherit_rdi = 0; 756 X509 *x; 757 758 OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); 759 OPENSSL_assert(ctx != NULL || ext != NULL); 760 OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); 761 762 /* 763 * Figure out where to start. If we don't have an extension to 764 * check, we're done. Otherwise, check canonical form and 765 * set up for walking up the chain. 766 */ 767 if (ext != NULL) { 768 i = -1; 769 x = NULL; 770 } else { 771 i = 0; 772 x = sk_X509_value(chain, i); 773 OPENSSL_assert(x != NULL); 774 if ((ext = x->rfc3779_asid) == NULL) 775 goto done; 776 } 777 if (!v3_asid_is_canonical(ext)) 778 validation_err(X509_V_ERR_INVALID_EXTENSION); 779 if (ext->asnum != NULL) { 780 switch (ext->asnum->type) { 781 case ASIdentifierChoice_inherit: 782 inherit_as = 1; 783 break; 784 case ASIdentifierChoice_asIdsOrRanges: 785 child_as = ext->asnum->u.asIdsOrRanges; 786 break; 787 } 788 } 789 if (ext->rdi != NULL) { 790 switch (ext->rdi->type) { 791 case ASIdentifierChoice_inherit: 792 inherit_rdi = 1; 793 break; 794 case ASIdentifierChoice_asIdsOrRanges: 795 child_rdi = ext->rdi->u.asIdsOrRanges; 796 break; 797 } 798 } 799 800 /* 801 * Now walk up the chain. Extensions must be in canonical form, no 802 * cert may list resources that its parent doesn't list. 803 */ 804 for (i++; i < sk_X509_num(chain); i++) { 805 x = sk_X509_value(chain, i); 806 OPENSSL_assert(x != NULL); 807 if (x->rfc3779_asid == NULL) { 808 if (child_as != NULL || child_rdi != NULL) 809 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 810 continue; 811 } 812 if (!v3_asid_is_canonical(x->rfc3779_asid)) 813 validation_err(X509_V_ERR_INVALID_EXTENSION); 814 if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { 815 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 816 child_as = NULL; 817 inherit_as = 0; 818 } 819 if (x->rfc3779_asid->asnum != NULL && 820 x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) { 821 if (inherit_as || 822 asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) { 823 child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; 824 inherit_as = 0; 825 } else { 826 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 827 } 828 } 829 if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { 830 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 831 child_rdi = NULL; 832 inherit_rdi = 0; 833 } 834 if (x->rfc3779_asid->rdi != NULL && 835 x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { 836 if (inherit_rdi || 837 asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) { 838 child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; 839 inherit_rdi = 0; 840 } else { 841 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 842 } 843 } 844 } 845 846 /* 847 * Trust anchor can't inherit. 848 */ 849 OPENSSL_assert(x != NULL); 850 if (x->rfc3779_asid != NULL) { 851 if (x->rfc3779_asid->asnum != NULL && 852 x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) 853 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 854 if (x->rfc3779_asid->rdi != NULL && 855 x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) 856 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 857 } 858 859 done: 860 return ret; 861 } 862 863 #undef validation_err 864 865 /* 866 * RFC 3779 3.3 path validation -- called from X509_verify_cert(). 867 */ 868 int v3_asid_validate_path(X509_STORE_CTX *ctx) 869 { 870 return v3_asid_validate_path_internal(ctx, ctx->chain, NULL); 871 } 872 873 /* 874 * RFC 3779 3.3 path validation of an extension. 875 * Test whether chain covers extension. 876 */ 877 int v3_asid_validate_resource_set(STACK_OF(X509) *chain, 878 ASIdentifiers *ext, 879 int allow_inheritance) 880 { 881 if (ext == NULL) 882 return 1; 883 if (chain == NULL || sk_X509_num(chain) == 0) 884 return 0; 885 if (!allow_inheritance && v3_asid_inherits(ext)) 886 return 0; 887 return v3_asid_validate_path_internal(NULL, chain, ext); 888 } 889 890 #endif /* OPENSSL_NO_RFC3779 */