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 <openssl/local/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 78ASN1_SEQUENCE(ASRange) = { 79 ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), 80 ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) 81} ASN1_SEQUENCE_END(ASRange) 82 83ASN1_CHOICE(ASIdOrRange) = { 84 ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), 85 ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) 86} ASN1_CHOICE_END(ASIdOrRange) 87 88ASN1_CHOICE(ASIdentifierChoice) = { 89 ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), 90 ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) 91} ASN1_CHOICE_END(ASIdentifierChoice) 92 93ASN1_SEQUENCE(ASIdentifiers) = { 94 ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), 95 ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) 96} ASN1_SEQUENCE_END(ASIdentifiers) 97 98IMPLEMENT_ASN1_FUNCTIONS(ASRange) 99IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange) 100IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice) 101IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) 102 103/* 104 * i2r method for an ASIdentifierChoice. 105 */ 106static 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 */ 154static 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 */ 169static 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 */ 199int 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 */ 228int 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 */ 284static 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 */ 304static 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 ret = 1; 362 363 done: 364 ASN1_INTEGER_free(a_max_plus_one); 365 BN_free(bn); 366 return ret; 367} 368 369/* 370 * Check whether an ASIdentifier extension is in canonical form. 371 */ 372int v3_asid_is_canonical(ASIdentifiers *asid) 373{ 374 return (asid == NULL || 375 (ASIdentifierChoice_is_canonical(asid->asnum) && 376 ASIdentifierChoice_is_canonical(asid->rdi))); 377} 378 379/* 380 * Whack an ASIdentifierChoice into canonical form. 381 */ 382static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) 383{ 384 ASN1_INTEGER *a_max_plus_one = NULL; 385 BIGNUM *bn = NULL; 386 int i, ret = 0; 387 388 /* 389 * Nothing to do for empty element or inheritance. 390 */ 391 if (choice == NULL || choice->type == ASIdentifierChoice_inherit) 392 return 1; 393 394 /* 395 * We have a list. Sort it. 396 */ 397 OPENSSL_assert(choice->type == ASIdentifierChoice_asIdsOrRanges); 398 sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); 399 400 /* 401 * Now check for errors and suboptimal encoding, rejecting the 402 * former and fixing the latter. 403 */ 404 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { 405 ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 406 ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); 407 ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; 408 409 extract_min_max(a, &a_min, &a_max); 410 extract_min_max(b, &b_min, &b_max); 411 412 /* 413 * Make sure we're properly sorted (paranoia). 414 */ 415 OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); 416 417 /* 418 * Check for overlaps. 419 */ 420 if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { 421 X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, 422 X509V3_R_EXTENSION_VALUE_ERROR); 423 goto done; 424 } 425 426 /* 427 * Calculate a_max + 1 to check for adjacency. 428 */ 429 if ((bn == NULL && (bn = BN_new()) == NULL) || 430 ASN1_INTEGER_to_BN(a_max, bn) == NULL || 431 !BN_add_word(bn, 1) || 432 (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { 433 X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE); 434 goto done; 435 } 436 437 /* 438 * If a and b are adjacent, merge them. 439 */ 440 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { 441 ASRange *r; 442 switch (a->type) { 443 case ASIdOrRange_id: 444 if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) { 445 X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, 446 ERR_R_MALLOC_FAILURE); 447 goto done; 448 } 449 r->min = a_min; 450 r->max = b_max; 451 a->type = ASIdOrRange_range; 452 a->u.range = r; 453 break; 454 case ASIdOrRange_range: 455 ASN1_INTEGER_free(a->u.range->max); 456 a->u.range->max = b_max; 457 break; 458 } 459 switch (b->type) { 460 case ASIdOrRange_id: 461 b->u.id = NULL; 462 break; 463 case ASIdOrRange_range: 464 b->u.range->max = NULL; 465 break; 466 } 467 ASIdOrRange_free(b); 468 sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); 469 i--; 470 continue; 471 } 472 } 473 474 OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ 475 476 ret = 1; 477 478 done: 479 ASN1_INTEGER_free(a_max_plus_one); 480 BN_free(bn); 481 return ret; 482} 483 484/* 485 * Whack an ASIdentifier extension into canonical form. 486 */ 487int v3_asid_canonize(ASIdentifiers *asid) 488{ 489 return (asid == NULL || 490 (ASIdentifierChoice_canonize(asid->asnum) && 491 ASIdentifierChoice_canonize(asid->rdi))); 492} 493 494/* 495 * v2i method for an ASIdentifier extension. 496 */ 497static void *v2i_ASIdentifiers(const struct v3_ext_method *method, 498 struct v3_ext_ctx *ctx, 499 STACK_OF(CONF_VALUE) *values) 500{ 501 ASIdentifiers *asid = NULL; 502 int i; 503 504 if ((asid = ASIdentifiers_new()) == NULL) { 505 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 506 return NULL; 507 } 508 509 for (i = 0; i < sk_CONF_VALUE_num(values); i++) { 510 CONF_VALUE *val = sk_CONF_VALUE_value(values, i); 511 ASN1_INTEGER *min = NULL, *max = NULL; 512 int i1, i2, i3, is_range, which; 513 514 /* 515 * Figure out whether this is an AS or an RDI. 516 */ 517 if ( !name_cmp(val->name, "AS")) { 518 which = V3_ASID_ASNUM; 519 } else if (!name_cmp(val->name, "RDI")) { 520 which = V3_ASID_RDI; 521 } else { 522 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR); 523 X509V3_conf_err(val); 524 goto err; 525 } 526 527 /* 528 * Handle inheritance. 529 */ 530 if (!strcmp(val->value, "inherit")) { 531 if (v3_asid_add_inherit(asid, which)) 532 continue; 533 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE); 534 X509V3_conf_err(val); 535 goto err; 536 } 537 538 /* 539 * Number, range, or mistake, pick it apart and figure out which. 540 */ 541 i1 = strspn(val->value, "0123456789"); 542 if (val->value[i1] == '\0') { 543 is_range = 0; 544 } else { 545 is_range = 1; 546 i2 = i1 + strspn(val->value + i1, " \t"); 547 if (val->value[i2] != '-') { 548 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER); 549 X509V3_conf_err(val); 550 goto err; 551 } 552 i2++; 553 i2 = i2 + strspn(val->value + i2, " \t"); 554 i3 = i2 + strspn(val->value + i2, "0123456789"); 555 if (val->value[i3] != '\0') { 556 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE); 557 X509V3_conf_err(val); 558 goto err; 559 } 560 } 561 562 /* 563 * Syntax is ok, read and add it. 564 */ 565 if (!is_range) { 566 if (!X509V3_get_value_int(val, &min)) { 567 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 568 goto err; 569 } 570 } else { 571 char *s = BUF_strdup(val->value); 572 if (s == NULL) { 573 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 574 goto err; 575 } 576 s[i1] = '\0'; 577 min = s2i_ASN1_INTEGER(NULL, s); 578 max = s2i_ASN1_INTEGER(NULL, s + i2); 579 OPENSSL_free(s); 580 if (min == NULL || max == NULL) { 581 ASN1_INTEGER_free(min); 582 ASN1_INTEGER_free(max); 583 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 584 goto err; 585 } 586 } 587 if (!v3_asid_add_id_or_range(asid, which, min, max)) { 588 ASN1_INTEGER_free(min); 589 ASN1_INTEGER_free(max); 590 X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); 591 goto err; 592 } 593 } 594 595 /* 596 * Canonize the result, then we're done. 597 */ 598 if (!v3_asid_canonize(asid)) 599 goto err; 600 return asid; 601 602 err: 603 ASIdentifiers_free(asid); 604 return NULL; 605} 606 607/* 608 * OpenSSL dispatch. 609 */ 610const X509V3_EXT_METHOD v3_asid = { 611 NID_sbgp_autonomousSysNum, /* nid */ 612 0, /* flags */ 613 ASN1_ITEM_ref(ASIdentifiers), /* template */ 614 0, 0, 0, 0, /* old functions, ignored */ 615 0, /* i2s */ 616 0, /* s2i */ 617 0, /* i2v */ 618 v2i_ASIdentifiers, /* v2i */ 619 i2r_ASIdentifiers, /* i2r */ 620 0, /* r2i */ 621 NULL /* extension-specific data */ 622}; 623 624/* 625 * Figure out whether extension uses inheritance. 626 */ 627int v3_asid_inherits(ASIdentifiers *asid) 628{ 629 return (asid != NULL && 630 ((asid->asnum != NULL && 631 asid->asnum->type == ASIdentifierChoice_inherit) || 632 (asid->rdi != NULL && 633 asid->rdi->type == ASIdentifierChoice_inherit))); 634} 635 636/* 637 * Figure out whether parent contains child. 638 */ 639static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) 640{ 641 ASN1_INTEGER *p_min, *p_max, *c_min, *c_max; 642 int p, c; 643 644 if (child == NULL || parent == child) 645 return 1; 646 if (parent == NULL) 647 return 0; 648 649 p = 0; 650 for (c = 0; c < sk_ASIdOrRange_num(child); c++) { 651 extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max); 652 for (;; p++) { 653 if (p >= sk_ASIdOrRange_num(parent)) 654 return 0; 655 extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max); 656 if (ASN1_INTEGER_cmp(p_max, c_max) < 0) 657 continue; 658 if (ASN1_INTEGER_cmp(p_min, c_min) > 0) 659 return 0; 660 break; 661 } 662 } 663 664 return 1; 665} 666 667/* 668 * Test whether a is a subet of b. 669 */ 670int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) 671{ 672 return (a == NULL || 673 a == b || 674 (b != NULL && 675 !v3_asid_inherits(a) && 676 !v3_asid_inherits(b) && 677 asid_contains(b->asnum->u.asIdsOrRanges, 678 a->asnum->u.asIdsOrRanges) && 679 asid_contains(b->rdi->u.asIdsOrRanges, 680 a->rdi->u.asIdsOrRanges))); 681} 682 683/* 684 * Validation error handling via callback. 685 */ 686#define validation_err(_err_) \ 687 do { \ 688 if (ctx != NULL) { \ 689 ctx->error = _err_; \ 690 ctx->error_depth = i; \ 691 ctx->current_cert = x; \ 692 ret = ctx->verify_cb(0, ctx); \ 693 } else { \ 694 ret = 0; \ 695 } \ 696 if (!ret) \ 697 goto done; \ 698 } while (0) 699 700/* 701 * Core code for RFC 3779 3.3 path validation. 702 */ 703static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, 704 STACK_OF(X509) *chain, 705 ASIdentifiers *ext) 706{ 707 ASIdOrRanges *child_as = NULL, *child_rdi = NULL; 708 int i, ret = 1, inherit_as = 0, inherit_rdi = 0; 709 X509 *x; 710 711 OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); 712 OPENSSL_assert(ctx != NULL || ext != NULL); 713 OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); 714 715 /* 716 * Figure out where to start. If we don't have an extension to 717 * check, we're done. Otherwise, check canonical form and 718 * set up for walking up the chain. 719 */ 720 if (ext != NULL) { 721 i = -1; 722 x = NULL; 723 } else { 724 i = 0; 725 x = sk_X509_value(chain, i); 726 OPENSSL_assert(x != NULL); 727 if ((ext = x->rfc3779_asid) == NULL) 728 goto done; 729 } 730 if (!v3_asid_is_canonical(ext)) 731 validation_err(X509_V_ERR_INVALID_EXTENSION); 732 if (ext->asnum != NULL) { 733 switch (ext->asnum->type) { 734 case ASIdentifierChoice_inherit: 735 inherit_as = 1; 736 break; 737 case ASIdentifierChoice_asIdsOrRanges: 738 child_as = ext->asnum->u.asIdsOrRanges; 739 break; 740 } 741 } 742 if (ext->rdi != NULL) { 743 switch (ext->rdi->type) { 744 case ASIdentifierChoice_inherit: 745 inherit_rdi = 1; 746 break; 747 case ASIdentifierChoice_asIdsOrRanges: 748 child_rdi = ext->rdi->u.asIdsOrRanges; 749 break; 750 } 751 } 752 753 /* 754 * Now walk up the chain. Extensions must be in canonical form, no 755 * cert may list resources that its parent doesn't list. 756 */ 757 for (i++; i < sk_X509_num(chain); i++) { 758 x = sk_X509_value(chain, i); 759 OPENSSL_assert(x != NULL); 760 if (x->rfc3779_asid == NULL) { 761 if (child_as != NULL || child_rdi != NULL) 762 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 763 continue; 764 } 765 if (!v3_asid_is_canonical(x->rfc3779_asid)) 766 validation_err(X509_V_ERR_INVALID_EXTENSION); 767 if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { 768 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 769 child_as = NULL; 770 inherit_as = 0; 771 } 772 if (x->rfc3779_asid->asnum != NULL && 773 x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) { 774 if (inherit_as || 775 asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) { 776 child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; 777 inherit_as = 0; 778 } else { 779 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 780 } 781 } 782 if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { 783 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 784 child_rdi = NULL; 785 inherit_rdi = 0; 786 } 787 if (x->rfc3779_asid->rdi != NULL && 788 x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { 789 if (inherit_rdi || 790 asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) { 791 child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; 792 inherit_rdi = 0; 793 } else { 794 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 795 } 796 } 797 } 798 799 /* 800 * Trust anchor can't inherit. 801 */ 802 OPENSSL_assert(x != NULL); 803 if (x->rfc3779_asid != NULL) { 804 if (x->rfc3779_asid->asnum != NULL && 805 x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) 806 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 807 if (x->rfc3779_asid->rdi != NULL && 808 x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) 809 validation_err(X509_V_ERR_UNNESTED_RESOURCE); 810 } 811 812 done: 813 return ret; 814} 815 816#undef validation_err 817 818/* 819 * RFC 3779 3.3 path validation -- called from X509_verify_cert(). 820 */ 821int v3_asid_validate_path(X509_STORE_CTX *ctx) 822{ 823 return v3_asid_validate_path_internal(ctx, ctx->chain, NULL); 824} 825 826/* 827 * RFC 3779 3.3 path validation of an extension. 828 * Test whether chain covers extension. 829 */ 830int v3_asid_validate_resource_set(STACK_OF(X509) *chain, 831 ASIdentifiers *ext, 832 int allow_inheritance) 833{ 834 if (ext == NULL) 835 return 1; 836 if (chain == NULL || sk_X509_num(chain) == 0) 837 return 0; 838 if (!allow_inheritance && v3_asid_inherits(ext)) 839 return 0; 840 return v3_asid_validate_path_internal(NULL, chain, ext); 841} 842 843#endif /* OPENSSL_NO_RFC3779 */ 844