Home | History | Annotate | Download | only in x509v3
      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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) 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 */
    891