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 */