v3_asid.c revision 256281
12061Sjkh/* 250479Speter * Contributed to the OpenSSL Project by the American Registry for 32061Sjkh * Internet Numbers ("ARIN"). 438666Sjb */ 532427Sjb/* ==================================================================== 6111131Sru * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7111131Sru * 838666Sjb * Redistribution and use in source and binary forms, with or without 938666Sjb * modification, are permitted provided that the following conditions 1038666Sjb * are met: 11159363Strhodes * 1264049Salex * 1. Redistributions of source code must retain the above copyright 1364049Salex * notice, this list of conditions and the following disclaimer. 14116679Ssimokawa * 1566071Smarkm * 2. Redistributions in binary form must reproduce the above copyright 16116679Ssimokawa * notice, this list of conditions and the following disclaimer in 1773504Sobrien * the documentation and/or other materials provided with the 18204661Simp * distribution. 19158962Snetchild * 2038666Sjb * 3. All advertising materials mentioning features or use of this 21169597Sdes * software must display the following acknowledgment: 22169597Sdes * "This product includes software developed by the OpenSSL Project 23169597Sdes * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24169597Sdes * 25169597Sdes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26169597Sdes * endorse or promote products derived from this software without 27169597Sdes * prior written permission. For written permission, please contact 28169597Sdes * licensing@OpenSSL.org. 2932427Sjb * 3038666Sjb * 5. Products derived from this software may not be called "OpenSSL" 31108451Sschweikh * nor may "OpenSSL" appear in their names without prior written 3238666Sjb * permission of the OpenSSL Project. 3338666Sjb * 3438666Sjb * 6. Redistributions of any form whatsoever must retain the following 3538666Sjb * acknowledgment: 3617308Speter * "This product includes software developed by the OpenSSL Project 3791606Skeramida * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3819175Sbde * 3996205Sjwd * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40177794Spav * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4138042Sbde * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4296205Sjwd * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4396205Sjwd * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4438042Sbde * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4596205Sjwd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46159363Strhodes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47159363Strhodes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4817308Speter * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4996205Sjwd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5096205Sjwd * OF THE POSSIBILITY OF SUCH DAMAGE. 5117308Speter * ==================================================================== 52148330Snetchild * 53148330Snetchild * This product includes cryptographic software written by Eric Young 54148330Snetchild * (eay@cryptsoft.com). This product includes software written by Tim 55148330Snetchild * Hudson (tjh@cryptsoft.com). 56159831Sobrien */ 57148330Snetchild 58148330Snetchild/* 59148330Snetchild * Implementation of RFC 3779 section 3.2. 60148330Snetchild */ 61178653Srwatson 62148330Snetchild#include <stdio.h> 63148330Snetchild#include <string.h> 6496205Sjwd#include "cryptlib.h" 6596205Sjwd#include <openssl/conf.h> 6696205Sjwd#include <openssl/asn1.h> 67162147Sru#include <openssl/asn1t.h> 68162147Sru#include <openssl/x509v3.h> 6998723Sdillon#include <openssl/x509.h> 7098723Sdillon#include <openssl/bn.h> 7198723Sdillon 7238666Sjb#ifndef OPENSSL_NO_RFC3779 7338666Sjb 7417308Speter/* 75123311Speter * OpenSSL ASN.1 template translation of RFC 3779 3.2.3. 76123311Speter */ 77123311Speter 78123311SpeterASN1_SEQUENCE(ASRange) = { 79175833Sjhb ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), 80175833Sjhb ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) 81169597Sdes} ASN1_SEQUENCE_END(ASRange) 82169597Sdes 83169597SdesASN1_CHOICE(ASIdOrRange) = { 84169597Sdes ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), 85159349Simp ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) 86158962Snetchild} ASN1_CHOICE_END(ASIdOrRange) 87158962Snetchild 88158962SnetchildASN1_CHOICE(ASIdentifierChoice) = { 89156840Sru ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), 90123311Speter ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) 91137288Speter} ASN1_CHOICE_END(ASIdentifierChoice) 92189760Simp 93156740SruASN1_SEQUENCE(ASIdentifiers) = { 942061Sjkh ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), 9597769Sru ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) 9697252Sru} ASN1_SEQUENCE_END(ASIdentifiers) 97119579Sru 9897252SruIMPLEMENT_ASN1_FUNCTIONS(ASRange) 9995730SruIMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange) 10095793SruIMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice) 101111617SruIMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) 10295730Sru 103116679Ssimokawa/* 10495730Sru * i2r method for an ASIdentifierChoice. 105116679Ssimokawa */ 10695730Srustatic int i2r_ASIdentifierChoice(BIO *out, 107110035Sru ASIdentifierChoice *choice, 108107516Sru int indent, 109138921Sru const char *msg) 110156145Syar{ 111138921Sru int i; 112133942Sru char *s; 113133942Sru if (choice == NULL) 114156145Syar return 1; 115133942Sru BIO_printf(out, "%*s%s:\n", indent, "", msg); 116110035Sru switch (choice->type) { 117117234Sru case ASIdentifierChoice_inherit: 118110035Sru BIO_printf(out, "%*sinherit\n", indent + 2, ""); 119117229Sru break; 120117234Sru case ASIdentifierChoice_asIdsOrRanges: 12154324Smarcel for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) { 12217308Speter ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 123119519Smarcel switch (aor->type) { 124119519Smarcel case ASIdOrRange_id: 125119519Smarcel if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL) 126119519Smarcel return 0; 127119519Smarcel BIO_printf(out, "%*s%s\n", indent + 2, "", s); 128119519Smarcel OPENSSL_free(s); 129119579Sru break; 130119519Smarcel case ASIdOrRange_range: 131119519Smarcel if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL) 132119519Smarcel return 0; 133119519Smarcel BIO_printf(out, "%*s%s-", indent + 2, "", s); 134119519Smarcel OPENSSL_free(s); 135126031Sgad if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL) 136126024Sgad return 0; 137126024Sgad BIO_printf(out, "%s\n", s); 138126024Sgad OPENSSL_free(s); 139126024Sgad break; 140126024Sgad default: 141126024Sgad return 0; 142126024Sgad } 143126024Sgad } 144126024Sgad break; 145126024Sgad default: 146126024Sgad return 0; 147126024Sgad } 148126024Sgad return 1; 149126031Sgad} 150126024Sgad 151126024Sgad/* 152126024Sgad * i2r method for an ASIdentifier extension. 153172744Sdelphij */ 154126024Sgadstatic int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, 155126024Sgad void *ext, 156126024Sgad BIO *out, 157133376Sharti int indent) 158126024Sgad{ 159126024Sgad ASIdentifiers *asid = ext; 160172744Sdelphij return (i2r_ASIdentifierChoice(out, asid->asnum, indent, 161126024Sgad "Autonomous System Numbers") && 162126024Sgad i2r_ASIdentifierChoice(out, asid->rdi, indent, 163125885Sgad "Routing Domain Identifiers")); 164125885Sgad} 16538666Sjb 16617308Speter/* 167119519Smarcel * Sort comparision function for a sequence of ASIdOrRange elements. 168119579Sru */ 169133376Shartistatic int ASIdOrRange_cmp(const ASIdOrRange * const *a_, 170110035Sru const ASIdOrRange * const *b_) 1712302Spaul{ 17239206Sjkh const ASIdOrRange *a = *a_, *b = *b_; 17339206Sjkh 17439206Sjkh OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || 175133945Sru (a->type == ASIdOrRange_range && a->u.range != NULL && 176177609Sru a->u.range->min != NULL && a->u.range->max != NULL)); 177177609Sru 178177609Sru OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || 179177609Sru (b->type == ASIdOrRange_range && b->u.range != NULL && 180133945Sru b->u.range->min != NULL && b->u.range->max != NULL)); 181132358Smarkm 18217308Speter if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) 18354324Smarcel return ASN1_INTEGER_cmp(a->u.id, b->u.id); 18454324Smarcel 185132234Smarcel if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { 186132234Smarcel int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); 187132234Smarcel return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max); 188132234Smarcel } 18954324Smarcel 19054324Smarcel if (a->type == ASIdOrRange_id) 19154324Smarcel return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); 192118531Sru else 19354324Smarcel return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); 19454324Smarcel} 19554324Smarcel 19654324Smarcel/* 19754324Smarcel * Add an inherit element. 19854324Smarcel */ 199133376Shartiint v3_asid_add_inherit(ASIdentifiers *asid, int which) 20054324Smarcel{ 201133376Sharti ASIdentifierChoice **choice; 202133376Sharti if (asid == NULL) 20354324Smarcel return 0; 20454324Smarcel switch (which) { 20554324Smarcel case V3_ASID_ASNUM: 20654324Smarcel choice = &asid->asnum; 20754324Smarcel break; 208133376Sharti case V3_ASID_RDI: 20954324Smarcel choice = &asid->rdi; 21054324Smarcel break; 21154324Smarcel default: 212118531Sru return 0; 213118531Sru } 21454324Smarcel if (*choice == NULL) { 215132234Smarcel if ((*choice = ASIdentifierChoice_new()) == NULL) 216132234Smarcel return 0; 217132234Smarcel OPENSSL_assert((*choice)->u.inherit == NULL); 218132234Smarcel if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) 219132234Smarcel return 0; 220132588Skensmith (*choice)->type = ASIdentifierChoice_inherit; 221132358Smarkm } 222132234Smarcel return (*choice)->type == ASIdentifierChoice_inherit; 223132358Smarkm} 224132234Smarcel 225132234Smarcel/* 226132234Smarcel * Add an ID or range to an ASIdentifierChoice. 22754324Smarcel */ 22854324Smarcelint v3_asid_add_id_or_range(ASIdentifiers *asid, 22995730Sru int which, 23095730Sru ASN1_INTEGER *min, 23195730Sru ASN1_INTEGER *max) 23295730Sru{ 23395730Sru ASIdentifierChoice **choice; 23495730Sru ASIdOrRange *aor; 23595730Sru if (asid == NULL) 23638666Sjb return 0; 237107374Sru switch (which) { 23817308Speter case V3_ASID_ASNUM: 23955678Smarcel choice = &asid->asnum; 240143032Sharti break; 241138515Sharti case V3_ASID_RDI: 242117793Sru choice = &asid->rdi; 243110035Sru break; 244174564Simp default: 245110035Sru return 0; 2462061Sjkh } 24717308Speter if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) 248107516Sru return 0; 249174539Simp if (*choice == NULL) { 250174539Simp if ((*choice = ASIdentifierChoice_new()) == NULL) 25155678Smarcel return 0; 252107516Sru OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); 253107516Sru (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); 254107516Sru if ((*choice)->u.asIdsOrRanges == NULL) 255174564Simp return 0; 256107516Sru (*choice)->type = ASIdentifierChoice_asIdsOrRanges; 257139112Sru } 258164470Sjb if ((aor = ASIdOrRange_new()) == NULL) 259107516Sru return 0; 260122204Skris if (max == NULL) { 26155678Smarcel aor->type = ASIdOrRange_id; 26255678Smarcel aor->u.id = min; 263116696Sru } else { 26455678Smarcel aor->type = ASIdOrRange_range; 265133376Sharti if ((aor->u.range = ASRange_new()) == NULL) 266107516Sru goto err; 267107516Sru ASN1_INTEGER_free(aor->u.range->min); 268107516Sru aor->u.range->min = min; 269107516Sru ASN1_INTEGER_free(aor->u.range->max); 27055678Smarcel aor->u.range->max = max; 271185499Salfred } 272185499Salfred if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) 273185499Salfred goto err; 274185499Salfred return 1; 27555678Smarcel 276111131Sru err: 277111131Sru ASIdOrRange_free(aor); 278111131Sru return 0; 279133945Sru} 280111131Sru 281111131Sru/* 282201815Sbz * Extract min and max values from an ASIdOrRange. 283190628Sbz */ 284168280Smarcelstatic void extract_min_max(ASIdOrRange *aor, 285185499Salfred ASN1_INTEGER **min, 286185499Salfred ASN1_INTEGER **max) 287185499Salfred{ 288185499Salfred OPENSSL_assert(aor != NULL && min != NULL && max != NULL); 289185499Salfred switch (aor->type) { 290185499Salfred case ASIdOrRange_id: 291185499Salfred *min = aor->u.id; 292133945Sru *max = aor->u.id; 293133945Sru return; 294103985Sphk case ASIdOrRange_range: 295103985Sphk *min = aor->u.range->min; 296103985Sphk *max = aor->u.range->max; 297185499Salfred return; 298185499Salfred } 299185499Salfred} 300168280Smarcel 301162147Sru/* 302162147Sru * Check whether an ASIdentifierChoice is in canonical form. 303162147Sru */ 304179232Sjbstatic int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) 305162147Sru{ 306185250Sdes ASN1_INTEGER *a_max_plus_one = NULL; 307202629Sed BIGNUM *bn = NULL; 308162147Sru int i, ret = 0; 309185250Sdes 310185499Salfred /* 311185499Salfred * Empty element or inheritance is canonical. 312162147Sru */ 313179232Sjb if (choice == NULL || choice->type == ASIdentifierChoice_inherit) 314162147Sru return 1; 315185250Sdes 316185250Sdes /* 317185499Salfred * If not a list, or if empty list, it's broken. 318185499Salfred */ 319103985Sphk if (choice->type != ASIdentifierChoice_asIdsOrRanges || 320201815Sbz sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) 321201815Sbz return 0; 322201815Sbz 323201815Sbz /* 324201815Sbz * It's a list, check it. 325202095Sbz */ 326202095Sbz for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { 327202095Sbz ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); 328201815Sbz ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); 329201815Sbz ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; 330201815Sbz 331201815Sbz extract_min_max(a, &a_min, &a_max); 332148154Sru extract_min_max(b, &b_min, &b_max); 333185250Sdes 334185250Sdes /* 335201815Sbz * Punt misordered list, overlapping start, or inverted range. 336148154Sru */ 337201815Sbz if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || 338201815Sbz ASN1_INTEGER_cmp(a_min, a_max) > 0 || 339201815Sbz ASN1_INTEGER_cmp(b_min, b_max) > 0) 340148154Sru goto done; 341133945Sru 342133945Sru /* 343103985Sphk * Calculate a_max + 1 to check for adjacency. 344118531Sru */ 345118531Sru if ((bn == NULL && (bn = BN_new()) == NULL) || 346103985Sphk ASN1_INTEGER_to_BN(a_max, bn) == NULL || 347185499Salfred !BN_add_word(bn, 1) || 348185499Salfred (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { 349185499Salfred X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, 350185499Salfred ERR_R_MALLOC_FAILURE); 351185499Salfred goto done; 352185499Salfred } 353133945Sru 354185499Salfred /* 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 */ 386int 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 */ 396static 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 */ 531int 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 */ 541static 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 */ 657const 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 */ 674int 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 */ 686static 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 */ 717int 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 */ 750static 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 */ 868int 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 */ 877int 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 */ 891