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