xref: /dragonfly/crypto/libressl/crypto/x509/x509_asid.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1 /*        $OpenBSD: x509_asid.c,v 1.35 2022/07/30 17:50:17 tb Exp $ */
2 /*
3  * Contributed to the OpenSSL Project by the American Registry for
4  * Internet Numbers ("ARIN").
5  */
6 /* ====================================================================
7  * Copyright (c) 2006-2018 The OpenSSL Project.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. All advertising materials mentioning features or use of this
22  *    software must display the following acknowledgment:
23  *    "This product includes software developed by the OpenSSL Project
24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25  *
26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27  *    endorse or promote products derived from this software without
28  *    prior written permission. For written permission, please contact
29  *    licensing@OpenSSL.org.
30  *
31  * 5. Products derived from this software may not be called "OpenSSL"
32  *    nor may "OpenSSL" appear in their names without prior written
33  *    permission of the OpenSSL Project.
34  *
35  * 6. Redistributions of any form whatsoever must retain the following
36  *    acknowledgment:
37  *    "This product includes software developed by the OpenSSL Project
38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51  * OF THE POSSIBILITY OF SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This product includes cryptographic software written by Eric Young
55  * (eay@cryptsoft.com).  This product includes software written by Tim
56  * Hudson (tjh@cryptsoft.com).
57  */
58 
59 /*
60  * Implementation of RFC 3779 section 3.2.
61  */
62 
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>
66 
67 #include <openssl/asn1.h>
68 #include <openssl/asn1t.h>
69 #include <openssl/bn.h>
70 #include <openssl/conf.h>
71 #include <openssl/err.h>
72 #include <openssl/x509.h>
73 #include <openssl/x509.h>
74 #include <openssl/x509v3.h>
75 
76 #include "x509_lcl.h"
77 
78 #ifndef OPENSSL_NO_RFC3779
79 
80 static const ASN1_TEMPLATE ASRange_seq_tt[] = {
81           {
82                     .flags = 0,
83                     .tag = 0,
84                     .offset = offsetof(ASRange, min),
85                     .field_name = "min",
86                     .item = &ASN1_INTEGER_it,
87           },
88           {
89                     .flags = 0,
90                     .tag = 0,
91                     .offset = offsetof(ASRange, max),
92                     .field_name = "max",
93                     .item = &ASN1_INTEGER_it,
94           },
95 };
96 
97 const ASN1_ITEM ASRange_it = {
98           .itype = ASN1_ITYPE_SEQUENCE,
99           .utype = V_ASN1_SEQUENCE,
100           .templates = ASRange_seq_tt,
101           .tcount = sizeof(ASRange_seq_tt) / sizeof(ASN1_TEMPLATE),
102           .funcs = NULL,
103           .size = sizeof(ASRange),
104           .sname = "ASRange",
105 };
106 
107 static const ASN1_TEMPLATE ASIdOrRange_ch_tt[] = {
108           {
109                     .flags = 0,
110                     .tag = 0,
111                     .offset = offsetof(ASIdOrRange, u.id),
112                     .field_name = "u.id",
113                     .item = &ASN1_INTEGER_it,
114           },
115           {
116                     .flags = 0,
117                     .tag = 0,
118                     .offset = offsetof(ASIdOrRange, u.range),
119                     .field_name = "u.range",
120                     .item = &ASRange_it,
121           },
122 };
123 
124 const ASN1_ITEM ASIdOrRange_it = {
125           .itype = ASN1_ITYPE_CHOICE,
126           .utype = offsetof(ASIdOrRange, type),
127           .templates = ASIdOrRange_ch_tt,
128           .tcount = sizeof(ASIdOrRange_ch_tt) / sizeof(ASN1_TEMPLATE),
129           .funcs = NULL,
130           .size = sizeof(ASIdOrRange),
131           .sname = "ASIdOrRange",
132 };
133 
134 static const ASN1_TEMPLATE ASIdentifierChoice_ch_tt[] = {
135           {
136                     .flags = 0,
137                     .tag = 0,
138                     .offset = offsetof(ASIdentifierChoice, u.inherit),
139                     .field_name = "u.inherit",
140                     .item = &ASN1_NULL_it,
141           },
142           {
143                     .flags = ASN1_TFLG_SEQUENCE_OF,
144                     .tag = 0,
145                     .offset = offsetof(ASIdentifierChoice, u.asIdsOrRanges),
146                     .field_name = "u.asIdsOrRanges",
147                     .item = &ASIdOrRange_it,
148           },
149 };
150 
151 const ASN1_ITEM ASIdentifierChoice_it = {
152           .itype = ASN1_ITYPE_CHOICE,
153           .utype = offsetof(ASIdentifierChoice, type),
154           .templates = ASIdentifierChoice_ch_tt,
155           .tcount = sizeof(ASIdentifierChoice_ch_tt) / sizeof(ASN1_TEMPLATE),
156           .funcs = NULL,
157           .size = sizeof(ASIdentifierChoice),
158           .sname = "ASIdentifierChoice",
159 };
160 
161 static const ASN1_TEMPLATE ASIdentifiers_seq_tt[] = {
162           {
163                     .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
164                     .tag = 0,
165                     .offset = offsetof(ASIdentifiers, asnum),
166                     .field_name = "asnum",
167                     .item = &ASIdentifierChoice_it,
168           },
169           {
170                     .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
171                     .tag = 1,
172                     .offset = offsetof(ASIdentifiers, rdi),
173                     .field_name = "rdi",
174                     .item = &ASIdentifierChoice_it,
175           },
176 };
177 
178 const ASN1_ITEM ASIdentifiers_it = {
179           .itype = ASN1_ITYPE_SEQUENCE,
180           .utype = V_ASN1_SEQUENCE,
181           .templates = ASIdentifiers_seq_tt,
182           .tcount = sizeof(ASIdentifiers_seq_tt) / sizeof(ASN1_TEMPLATE),
183           .funcs = NULL,
184           .size = sizeof(ASIdentifiers),
185           .sname = "ASIdentifiers",
186 };
187 
188 ASRange *
d2i_ASRange(ASRange ** a,const unsigned char ** in,long len)189 d2i_ASRange(ASRange **a, const unsigned char **in, long len)
190 {
191           return (ASRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
192               &ASRange_it);
193 }
194 
195 int
i2d_ASRange(ASRange * a,unsigned char ** out)196 i2d_ASRange(ASRange *a, unsigned char **out)
197 {
198           return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASRange_it);
199 }
200 
201 ASRange *
ASRange_new(void)202 ASRange_new(void)
203 {
204           return (ASRange *)ASN1_item_new(&ASRange_it);
205 }
206 
207 void
ASRange_free(ASRange * a)208 ASRange_free(ASRange *a)
209 {
210           ASN1_item_free((ASN1_VALUE *)a, &ASRange_it);
211 }
212 
213 ASIdOrRange *
d2i_ASIdOrRange(ASIdOrRange ** a,const unsigned char ** in,long len)214 d2i_ASIdOrRange(ASIdOrRange **a, const unsigned char **in, long len)
215 {
216           return (ASIdOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
217               &ASIdOrRange_it);
218 }
219 
220 int
i2d_ASIdOrRange(ASIdOrRange * a,unsigned char ** out)221 i2d_ASIdOrRange(ASIdOrRange *a, unsigned char **out)
222 {
223           return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdOrRange_it);
224 }
225 
226 ASIdOrRange *
ASIdOrRange_new(void)227 ASIdOrRange_new(void)
228 {
229           return (ASIdOrRange *)ASN1_item_new(&ASIdOrRange_it);
230 }
231 
232 void
ASIdOrRange_free(ASIdOrRange * a)233 ASIdOrRange_free(ASIdOrRange *a)
234 {
235           ASN1_item_free((ASN1_VALUE *)a, &ASIdOrRange_it);
236 }
237 
238 ASIdentifierChoice *
d2i_ASIdentifierChoice(ASIdentifierChoice ** a,const unsigned char ** in,long len)239 d2i_ASIdentifierChoice(ASIdentifierChoice **a, const unsigned char **in,
240     long len)
241 {
242           return (ASIdentifierChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
243               &ASIdentifierChoice_it);
244 }
245 
246 int
i2d_ASIdentifierChoice(ASIdentifierChoice * a,unsigned char ** out)247 i2d_ASIdentifierChoice(ASIdentifierChoice *a, unsigned char **out)
248 {
249           return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifierChoice_it);
250 }
251 
252 ASIdentifierChoice *
ASIdentifierChoice_new(void)253 ASIdentifierChoice_new(void)
254 {
255           return (ASIdentifierChoice *)ASN1_item_new(&ASIdentifierChoice_it);
256 }
257 
258 void
ASIdentifierChoice_free(ASIdentifierChoice * a)259 ASIdentifierChoice_free(ASIdentifierChoice *a)
260 {
261           ASN1_item_free((ASN1_VALUE *)a, &ASIdentifierChoice_it);
262 }
263 
264 ASIdentifiers *
d2i_ASIdentifiers(ASIdentifiers ** a,const unsigned char ** in,long len)265 d2i_ASIdentifiers(ASIdentifiers **a, const unsigned char **in, long len)
266 {
267           return (ASIdentifiers *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
268               &ASIdentifiers_it);
269 }
270 
271 int
i2d_ASIdentifiers(ASIdentifiers * a,unsigned char ** out)272 i2d_ASIdentifiers(ASIdentifiers *a, unsigned char **out)
273 {
274           return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifiers_it);
275 }
276 
277 ASIdentifiers *
ASIdentifiers_new(void)278 ASIdentifiers_new(void)
279 {
280           return (ASIdentifiers *)ASN1_item_new(&ASIdentifiers_it);
281 }
282 
283 void
ASIdentifiers_free(ASIdentifiers * a)284 ASIdentifiers_free(ASIdentifiers *a)
285 {
286           ASN1_item_free((ASN1_VALUE *)a, &ASIdentifiers_it);
287 }
288 
289 /*
290  * i2r method for an ASIdentifierChoice.
291  */
292 static int
i2r_ASIdentifierChoice(BIO * out,ASIdentifierChoice * choice,int indent,const char * msg)293 i2r_ASIdentifierChoice(BIO *out, ASIdentifierChoice *choice, int indent,
294     const char *msg)
295 {
296           int i;
297           char *s;
298           if (choice == NULL)
299                     return 1;
300           BIO_printf(out, "%*s%s:\n", indent, "", msg);
301           switch (choice->type) {
302           case ASIdentifierChoice_inherit:
303                     BIO_printf(out, "%*sinherit\n", indent + 2, "");
304                     break;
305           case ASIdentifierChoice_asIdsOrRanges:
306                     for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges);
307                         i++) {
308                               ASIdOrRange *aor =
309                                   sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
310                               switch (aor->type) {
311                               case ASIdOrRange_id:
312                                         if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) ==
313                                             NULL)
314                                                   return 0;
315                                         BIO_printf(out, "%*s%s\n", indent + 2, "", s);
316                                         free(s);
317                                         break;
318                               case ASIdOrRange_range:
319                                         if ((s = i2s_ASN1_INTEGER(NULL,
320                                             aor->u.range->min)) == NULL)
321                                                   return 0;
322                                         BIO_printf(out, "%*s%s-", indent + 2, "", s);
323                                         free(s);
324                                         if ((s = i2s_ASN1_INTEGER(NULL,
325                                             aor->u.range->max)) == NULL)
326                                                   return 0;
327                                         BIO_printf(out, "%s\n", s);
328                                         free(s);
329                                         break;
330                               default:
331                                         return 0;
332                               }
333                     }
334                     break;
335           default:
336                     return 0;
337           }
338           return 1;
339 }
340 
341 /*
342  * i2r method for an ASIdentifier extension.
343  */
344 static int
i2r_ASIdentifiers(const X509V3_EXT_METHOD * method,void * ext,BIO * out,int indent)345 i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, void *ext, BIO *out,
346     int indent)
347 {
348           ASIdentifiers *asid = ext;
349           return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
350               "Autonomous System Numbers") &&
351               i2r_ASIdentifierChoice(out, asid->rdi, indent,
352               "Routing Domain Identifiers"));
353 }
354 
355 /*
356  * Sort comparison function for a sequence of ASIdOrRange elements.
357  */
358 static int
ASIdOrRange_cmp(const ASIdOrRange * const * a_,const ASIdOrRange * const * b_)359 ASIdOrRange_cmp(const ASIdOrRange *const *a_, const ASIdOrRange *const *b_)
360 {
361           const ASIdOrRange *a = *a_, *b = *b_;
362 
363           /* XXX: these asserts need to be replaced */
364           OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
365               (a->type == ASIdOrRange_range && a->u.range != NULL &&
366                a->u.range->min != NULL && a->u.range->max != NULL));
367 
368           OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
369               (b->type == ASIdOrRange_range && b->u.range != NULL &&
370                b->u.range->min != NULL && b->u.range->max != NULL));
371 
372           if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
373                     return ASN1_INTEGER_cmp(a->u.id, b->u.id);
374 
375           if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
376                     int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
377                     return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max,
378                         b->u.range->max);
379           }
380 
381           if (a->type == ASIdOrRange_id)
382                     return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
383           else
384                     return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
385 }
386 
387 /*
388  * Add an inherit element.
389  */
390 int
X509v3_asid_add_inherit(ASIdentifiers * asid,int which)391 X509v3_asid_add_inherit(ASIdentifiers *asid, int which)
392 {
393           ASIdentifierChoice **choice;
394           if (asid == NULL)
395                     return 0;
396           switch (which) {
397           case V3_ASID_ASNUM:
398                     choice = &asid->asnum;
399                     break;
400           case V3_ASID_RDI:
401                     choice = &asid->rdi;
402                     break;
403           default:
404                     return 0;
405           }
406           if (*choice == NULL) {
407                     if ((*choice = ASIdentifierChoice_new()) == NULL)
408                               return 0;
409                     if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
410                               return 0;
411                     (*choice)->type = ASIdentifierChoice_inherit;
412           }
413           return (*choice)->type == ASIdentifierChoice_inherit;
414 }
415 
416 /*
417  * Add an ID or range to an ASIdentifierChoice.
418  */
419 int
X509v3_asid_add_id_or_range(ASIdentifiers * asid,int which,ASN1_INTEGER * min,ASN1_INTEGER * max)420 X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, ASN1_INTEGER *min,
421     ASN1_INTEGER *max)
422 {
423           ASIdentifierChoice **choice;
424           ASIdOrRange *aor;
425           if (asid == NULL)
426                     return 0;
427           switch (which) {
428           case V3_ASID_ASNUM:
429                     choice = &asid->asnum;
430                     break;
431           case V3_ASID_RDI:
432                     choice = &asid->rdi;
433                     break;
434           default:
435                     return 0;
436           }
437           if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
438                     return 0;
439           if (*choice == NULL) {
440                     if ((*choice = ASIdentifierChoice_new()) == NULL)
441                               return 0;
442                     (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
443                     if ((*choice)->u.asIdsOrRanges == NULL)
444                               return 0;
445                     (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
446           }
447           if ((aor = ASIdOrRange_new()) == NULL)
448                     return 0;
449           if (max == NULL) {
450                     aor->type = ASIdOrRange_id;
451                     aor->u.id = min;
452           } else {
453                     aor->type = ASIdOrRange_range;
454                     if ((aor->u.range = ASRange_new()) == NULL)
455                               goto err;
456                     ASN1_INTEGER_free(aor->u.range->min);
457                     aor->u.range->min = min;
458                     ASN1_INTEGER_free(aor->u.range->max);
459                     aor->u.range->max = max;
460           }
461           if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
462                     goto err;
463           return 1;
464 
465  err:
466           ASIdOrRange_free(aor);
467           return 0;
468 }
469 
470 /*
471  * Extract min and max values from an ASIdOrRange.
472  */
473 static int
extract_min_max(ASIdOrRange * aor,ASN1_INTEGER ** min,ASN1_INTEGER ** max)474 extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max)
475 {
476           switch (aor->type) {
477           case ASIdOrRange_id:
478                     *min = aor->u.id;
479                     *max = aor->u.id;
480                     return 1;
481           case ASIdOrRange_range:
482                     *min = aor->u.range->min;
483                     *max = aor->u.range->max;
484                     return 1;
485           }
486 
487           return 0;
488 }
489 
490 /*
491  * Check whether an ASIdentifierChoice is in canonical form.
492  */
493 static int
ASIdentifierChoice_is_canonical(ASIdentifierChoice * choice)494 ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
495 {
496           ASN1_INTEGER *a_max_plus_one = NULL;
497           ASN1_INTEGER *orig;
498           BIGNUM *bn = NULL;
499           int i, ret = 0;
500 
501           /*
502            * Empty element or inheritance is canonical.
503            */
504           if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
505                     return 1;
506 
507           /*
508            * If not a list, or if empty list, it's broken.
509            */
510           if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
511               sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
512                     return 0;
513 
514           /*
515            * It's a list, check it.
516            */
517           for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
518                     ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges,
519                         i);
520                     ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges,
521                         i + 1);
522                     ASN1_INTEGER *a_min = NULL,
523                     *a_max = NULL,
524                     *b_min = NULL,
525                     *b_max =
526                         NULL;
527 
528                     if (!extract_min_max(a, &a_min, &a_max) ||
529                         !extract_min_max(b, &b_min, &b_max))
530                               goto done;
531 
532                     /*
533                      * Punt misordered list, overlapping start, or inverted range.
534                      */
535                     if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
536                         ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
537                         ASN1_INTEGER_cmp(b_min, b_max) > 0)
538                               goto done;
539 
540                     /*
541                      * Calculate a_max + 1 to check for adjacency.
542                      */
543                     if ((bn == NULL && (bn = BN_new()) == NULL) ||
544                         ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
545                         !BN_add_word(bn, 1)) {
546                               X509V3error(ERR_R_MALLOC_FAILURE);
547                               goto done;
548                     }
549 
550                     if ((a_max_plus_one =
551                         BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) {
552                               a_max_plus_one = orig;
553                               X509V3error(ERR_R_MALLOC_FAILURE);
554                               goto done;
555                     }
556 
557                     /*
558                      * Punt if adjacent or overlapping.
559                      */
560                     if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
561                               goto done;
562           }
563 
564           /*
565           * Check for inverted range.
566           */
567           i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
568           {
569                     ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges,
570                         i);
571                     ASN1_INTEGER *a_min, *a_max;
572                     if (a != NULL && a->type == ASIdOrRange_range) {
573                               if (!extract_min_max(a, &a_min, &a_max) ||
574                                   ASN1_INTEGER_cmp(a_min, a_max) > 0)
575                                         goto done;
576                     }
577           }
578 
579           ret = 1;
580 
581  done:
582           ASN1_INTEGER_free(a_max_plus_one);
583           BN_free(bn);
584           return ret;
585 }
586 
587 /*
588  * Check whether an ASIdentifier extension is in canonical form.
589  */
590 int
X509v3_asid_is_canonical(ASIdentifiers * asid)591 X509v3_asid_is_canonical(ASIdentifiers *asid)
592 {
593           return (asid == NULL ||
594               (ASIdentifierChoice_is_canonical(asid->asnum) &&
595                ASIdentifierChoice_is_canonical(asid->rdi)));
596 }
597 
598 /*
599  * Whack an ASIdentifierChoice into canonical form.
600  */
601 static int
ASIdentifierChoice_canonize(ASIdentifierChoice * choice)602 ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
603 {
604           ASN1_INTEGER *a_max_plus_one = NULL;
605           ASN1_INTEGER *orig;
606           BIGNUM *bn = NULL;
607           int i, ret = 0;
608 
609           /*
610            * Nothing to do for empty element or inheritance.
611            */
612           if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
613                     return 1;
614 
615           /*
616            * If not a list, or if empty list, it's broken.
617            */
618           if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
619               sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
620                     X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
621                     return 0;
622           }
623 
624           /*
625            * We have a non-empty list.  Sort it.
626            */
627           sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
628 
629           /*
630            * Now check for errors and suboptimal encoding, rejecting the
631            * former and fixing the latter.
632            */
633           for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
634                     ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges,
635                         i);
636                     ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges,
637                         i + 1);
638                     ASN1_INTEGER *a_min = NULL,
639                     *a_max = NULL,
640                     *b_min = NULL,
641                     *b_max =
642                         NULL;
643 
644                     if (!extract_min_max(a, &a_min, &a_max) ||
645                         !extract_min_max(b, &b_min, &b_max))
646                               goto done;
647 
648                     /*
649                      * Make sure we're properly sorted (paranoia).
650                      */
651                     if (ASN1_INTEGER_cmp(a_min, b_min) > 0)
652                               goto done;
653 
654                     /*
655                      * Punt inverted ranges.
656                      */
657                     if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
658                         ASN1_INTEGER_cmp(b_min, b_max) > 0)
659                               goto done;
660 
661                     /*
662                      * Check for overlaps.
663                      */
664                     if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
665                               X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
666                               goto done;
667                     }
668 
669                     /*
670                      * Calculate a_max + 1 to check for adjacency.
671                      */
672                     if ((bn == NULL && (bn = BN_new()) == NULL) ||
673                         ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
674                         !BN_add_word(bn, 1)) {
675                               X509V3error(ERR_R_MALLOC_FAILURE);
676                               goto done;
677                     }
678 
679                     if ((a_max_plus_one =
680                         BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) {
681                               a_max_plus_one = orig;
682                               X509V3error(ERR_R_MALLOC_FAILURE);
683                               goto done;
684                     }
685 
686                     /*
687                      * If a and b are adjacent, merge them.
688                      */
689                     if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
690                               ASRange *r;
691                               switch (a->type) {
692                               case ASIdOrRange_id:
693                                         if ((r = calloc(1, sizeof(*r))) == NULL) {
694                                                   X509V3error(ERR_R_MALLOC_FAILURE);
695                                                   goto done;
696                                         }
697                                         r->min = a_min;
698                                         r->max = b_max;
699                                         a->type = ASIdOrRange_range;
700                                         a->u.range = r;
701                                         break;
702                               case ASIdOrRange_range:
703                                         ASN1_INTEGER_free(a->u.range->max);
704                                         a->u.range->max = b_max;
705                                         break;
706                               }
707                               switch (b->type) {
708                               case ASIdOrRange_id:
709                                         b->u.id = NULL;
710                                         break;
711                               case ASIdOrRange_range:
712                                         b->u.range->max = NULL;
713                                         break;
714                               }
715                               ASIdOrRange_free(b);
716                               (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges,
717                                   i + 1);
718                               i--;
719                               continue;
720                     }
721           }
722 
723           /*
724            * Check for final inverted range.
725            */
726           i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
727           {
728                     ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges,
729                         i);
730                     ASN1_INTEGER *a_min, *a_max;
731                     if (a != NULL && a->type == ASIdOrRange_range) {
732                               if (!extract_min_max(a, &a_min, &a_max) ||
733                                   ASN1_INTEGER_cmp(a_min, a_max) > 0)
734                                         goto done;
735                     }
736           }
737 
738           /* Paranoia */
739           if (!ASIdentifierChoice_is_canonical(choice))
740                     goto done;
741 
742           ret = 1;
743 
744  done:
745           ASN1_INTEGER_free(a_max_plus_one);
746           BN_free(bn);
747           return ret;
748 }
749 
750 /*
751  * Whack an ASIdentifier extension into canonical form.
752  */
753 int
X509v3_asid_canonize(ASIdentifiers * asid)754 X509v3_asid_canonize(ASIdentifiers *asid)
755 {
756           if (asid == NULL)
757                     return 1;
758 
759           if (!ASIdentifierChoice_canonize(asid->asnum))
760                     return 0;
761 
762           return ASIdentifierChoice_canonize(asid->rdi);
763 }
764 
765 /*
766  * v2i method for an ASIdentifier extension.
767  */
768 static void *
v2i_ASIdentifiers(const struct v3_ext_method * method,struct v3_ext_ctx * ctx,STACK_OF (CONF_VALUE)* values)769 v2i_ASIdentifiers(const struct v3_ext_method *method, struct v3_ext_ctx *ctx,
770     STACK_OF(CONF_VALUE)*values)
771 {
772           ASN1_INTEGER *min = NULL, *max = NULL;
773           ASIdentifiers *asid = NULL;
774           int i;
775 
776           if ((asid = ASIdentifiers_new()) == NULL) {
777                     X509V3error(ERR_R_MALLOC_FAILURE);
778                     return NULL;
779           }
780 
781           for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
782                     CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
783                     int i1 = 0, i2 = 0, i3 = 0, is_range = 0, which = 0;
784 
785                     /*
786                      * Figure out whether this is an AS or an RDI.
787                      */
788                     if (!name_cmp(val->name, "AS")) {
789                               which = V3_ASID_ASNUM;
790                     } else if (!name_cmp(val->name, "RDI")) {
791                               which = V3_ASID_RDI;
792                     } else {
793                               X509V3error(X509V3_R_EXTENSION_NAME_ERROR);
794                               X509V3_conf_err(val);
795                               goto err;
796                     }
797 
798                     /*
799                      * Handle inheritance.
800                      */
801                     if (strcmp(val->value, "inherit") == 0) {
802                               if (X509v3_asid_add_inherit(asid, which))
803                                         continue;
804                               X509V3error(X509V3_R_INVALID_INHERITANCE);
805                               X509V3_conf_err(val);
806                               goto err;
807                     }
808 
809                     /*
810                      * Number, range, or mistake, pick it apart and figure out which
811                      */
812                     i1 = strspn(val->value, "0123456789");
813                     if (val->value[i1] == '\0') {
814                               is_range = 0;
815                     } else {
816                               is_range = 1;
817                               i2 = i1 + strspn(val->value + i1, " \t");
818                               if (val->value[i2] != '-') {
819                                         X509V3error(X509V3_R_INVALID_ASNUMBER);
820                                         X509V3_conf_err(val);
821                                         goto err;
822                               }
823                               i2++;
824                               i2 = i2 + strspn(val->value + i2, " \t");
825                               i3 = i2 + strspn(val->value + i2, "0123456789");
826                               if (val->value[i3] != '\0') {
827                                         X509V3error(X509V3_R_INVALID_ASRANGE);
828                                         X509V3_conf_err(val);
829                                         goto err;
830                               }
831                     }
832 
833                     /*
834                      * Syntax is ok, read and add it.
835                      */
836                     if (!is_range) {
837                               if (!X509V3_get_value_int(val, &min)) {
838                                         X509V3error(ERR_R_MALLOC_FAILURE);
839                                         goto err;
840                               }
841                     } else {
842                               char *s = strdup(val->value);
843                               if (s == NULL) {
844                                         X509V3error(ERR_R_MALLOC_FAILURE);
845                                         goto err;
846                               }
847                               s[i1] = '\0';
848                               min = s2i_ASN1_INTEGER(NULL, s);
849                               max = s2i_ASN1_INTEGER(NULL, s + i2);
850                               free(s);
851                               if (min == NULL || max == NULL) {
852                                         X509V3error(ERR_R_MALLOC_FAILURE);
853                                         goto err;
854                               }
855                               if (ASN1_INTEGER_cmp(min, max) > 0) {
856                                         X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
857                                         goto err;
858                               }
859                     }
860                     if (!X509v3_asid_add_id_or_range(asid, which, min, max)) {
861                               X509V3error(ERR_R_MALLOC_FAILURE);
862                               goto err;
863                     }
864                     min = max = NULL;
865           }
866 
867           /*
868            * Canonize the result, then we're done.
869            */
870           if (!X509v3_asid_canonize(asid))
871                     goto err;
872           return asid;
873 
874  err:
875           ASIdentifiers_free(asid);
876           ASN1_INTEGER_free(min);
877           ASN1_INTEGER_free(max);
878           return NULL;
879 }
880 
881 /*
882  * OpenSSL dispatch.
883  */
884 const X509V3_EXT_METHOD v3_asid = {
885           .ext_nid = NID_sbgp_autonomousSysNum,
886           .ext_flags = 0,
887           .it = &ASIdentifiers_it,
888           .ext_new = NULL,
889           .ext_free = NULL,
890           .d2i = NULL,
891           .i2d = NULL,
892           .i2s = NULL,
893           .s2i = NULL,
894           .i2v = NULL,
895           .v2i = v2i_ASIdentifiers,
896           .i2r = i2r_ASIdentifiers,
897           .r2i = NULL,
898           .usr_data = NULL,
899 };
900 
901 /*
902  * Figure out whether extension uses inheritance.
903  */
904 int
X509v3_asid_inherits(ASIdentifiers * asid)905 X509v3_asid_inherits(ASIdentifiers *asid)
906 {
907           if (asid == NULL)
908                     return 0;
909 
910           if (asid->asnum != NULL) {
911                     if (asid->asnum->type == ASIdentifierChoice_inherit)
912                               return 1;
913           }
914 
915           if (asid->rdi != NULL) {
916                     if (asid->rdi->type == ASIdentifierChoice_inherit)
917                               return 1;
918           }
919 
920           return 0;
921 }
922 
923 /*
924  * Figure out whether parent contains child.
925  */
926 static int
asid_contains(ASIdOrRanges * parent,ASIdOrRanges * child)927 asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
928 {
929           ASN1_INTEGER *p_min = NULL, *p_max = NULL, *c_min = NULL, *c_max = NULL;
930           int p, c;
931 
932           if (child == NULL || parent == child)
933                     return 1;
934 
935           if (parent == NULL)
936                     return 0;
937 
938           p = 0;
939           for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
940                     if (!extract_min_max(sk_ASIdOrRange_value(child, c), &c_min,
941                         &c_max))
942                               return 0;
943                     for (;; p++) {
944                               if (p >= sk_ASIdOrRange_num(parent))
945                                         return 0;
946                               if (!extract_min_max(sk_ASIdOrRange_value(parent, p),
947                                   &p_min, &p_max))
948                                         return 0;
949                               if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
950                                         continue;
951                               if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
952                                         return 0;
953                               break;
954                     }
955           }
956 
957           return 1;
958 }
959 
960 /*
961  * Test whether child is a subset of parent.
962  */
963 int
X509v3_asid_subset(ASIdentifiers * child,ASIdentifiers * parent)964 X509v3_asid_subset(ASIdentifiers *child, ASIdentifiers *parent)
965 {
966           if (child == NULL || child == parent)
967                     return 1;
968 
969           if (parent == NULL)
970                     return 0;
971 
972           if (X509v3_asid_inherits(child) || X509v3_asid_inherits(parent))
973                     return 0;
974 
975           if (child->asnum != NULL) {
976                     if (parent->asnum == NULL)
977                               return 0;
978 
979                     if (!asid_contains(parent->asnum->u.asIdsOrRanges,
980                         child->asnum->u.asIdsOrRanges))
981                               return 0;
982           }
983 
984           if (child->rdi != NULL) {
985                     if (parent->rdi == NULL)
986                               return 0;
987 
988                     if (!asid_contains(parent->rdi->u.asIdsOrRanges,
989                         child->rdi->u.asIdsOrRanges))
990                               return 0;
991           }
992 
993           return 1;
994 }
995 
996 /*
997  * Validation error handling via callback.
998  */
999 #define validation_err(_err_)           \
1000   do {                                  \
1001     if (ctx != NULL) {                  \
1002       ctx->error = _err_;               \
1003       ctx->error_depth = i;             \
1004       ctx->current_cert = x;            \
1005       ret = ctx->verify_cb(0, ctx);     \
1006     } else {                            \
1007       ret = 0;                          \
1008     }                                   \
1009     if (!ret)                           \
1010       goto done;                        \
1011   } while (0)
1012 
1013 /*
1014  * Core code for RFC 3779 3.3 path validation.
1015  */
1016 static int
asid_validate_path_internal(X509_STORE_CTX * ctx,STACK_OF (X509)* chain,ASIdentifiers * ext)1017 asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain,
1018     ASIdentifiers *ext)
1019 {
1020           ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
1021           int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
1022           X509 *x;
1023 
1024           /* We need a non-empty chain to test against. */
1025           if (sk_X509_num(chain) <= 0)
1026                     goto err;
1027           /* We need either a store ctx or an extension to work with. */
1028           if (ctx == NULL && ext == NULL)
1029                     goto err;
1030           /* If there is a store ctx, it needs a verify_cb. */
1031           if (ctx != NULL && ctx->verify_cb == NULL)
1032                     goto err;
1033 
1034           /*
1035            * Figure out where to start. If we don't have an extension to check,
1036            * (either extracted from the leaf or passed by the caller), we're done.
1037            * Otherwise, check canonical form and set up for walking up the chain.
1038            */
1039           if (ext != NULL) {
1040                     i = -1;
1041                     x = NULL;
1042                     if (!X509v3_asid_is_canonical(ext))
1043                               validation_err(X509_V_ERR_INVALID_EXTENSION);
1044           } else {
1045                     i = 0;
1046                     x = sk_X509_value(chain, i);
1047                     if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0)
1048                               goto done;
1049                     if ((ext = x->rfc3779_asid) == NULL)
1050                               goto done;
1051           }
1052           if (ext->asnum != NULL) {
1053                     switch (ext->asnum->type) {
1054                     case ASIdentifierChoice_inherit:
1055                               inherit_as = 1;
1056                               break;
1057                     case ASIdentifierChoice_asIdsOrRanges:
1058                               child_as = ext->asnum->u.asIdsOrRanges;
1059                               break;
1060                     }
1061           }
1062           if (ext->rdi != NULL) {
1063                     switch (ext->rdi->type) {
1064                     case ASIdentifierChoice_inherit:
1065                               inherit_rdi = 1;
1066                               break;
1067                     case ASIdentifierChoice_asIdsOrRanges:
1068                               child_rdi = ext->rdi->u.asIdsOrRanges;
1069                               break;
1070                     }
1071           }
1072 
1073           /*
1074            * Now walk up the chain.  Extensions must be in canonical form, no
1075            * cert may list resources that its parent doesn't list.
1076            */
1077           for (i++; i < sk_X509_num(chain); i++) {
1078                     x = sk_X509_value(chain, i);
1079 
1080                     if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0)
1081                               validation_err(X509_V_ERR_INVALID_EXTENSION);
1082                     if (x->rfc3779_asid == NULL) {
1083                               if (child_as != NULL || child_rdi != NULL)
1084                                         validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1085                               continue;
1086                     }
1087                     if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
1088                               validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1089                               child_as = NULL;
1090                               inherit_as = 0;
1091                     }
1092                     if (x->rfc3779_asid->asnum != NULL &&
1093                         x->rfc3779_asid->asnum->type ==
1094                         ASIdentifierChoice_asIdsOrRanges) {
1095                               if (inherit_as ||
1096                                   asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges,
1097                                   child_as)) {
1098                                         child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
1099                                         inherit_as = 0;
1100                               } else {
1101                                         validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1102                               }
1103                     }
1104                     if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
1105                               validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1106                               child_rdi = NULL;
1107                               inherit_rdi = 0;
1108                     }
1109                     if (x->rfc3779_asid->rdi != NULL &&
1110                         x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
1111                               if (inherit_rdi ||
1112                                   asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges,
1113                                   child_rdi)) {
1114                                         child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
1115                                         inherit_rdi = 0;
1116                               } else {
1117                                         validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1118                               }
1119                     }
1120           }
1121 
1122           /*
1123            * Trust anchor can't inherit.
1124            */
1125 
1126           if (x == NULL)
1127                     goto err;
1128 
1129           if (x->rfc3779_asid != NULL) {
1130                     if (x->rfc3779_asid->asnum != NULL &&
1131                         x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
1132                               validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1133                     if (x->rfc3779_asid->rdi != NULL &&
1134                         x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
1135                               validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1136           }
1137 
1138  done:
1139           return ret;
1140 
1141  err:
1142           if (ctx != NULL)
1143                     ctx->error = X509_V_ERR_UNSPECIFIED;
1144 
1145           return 0;
1146 }
1147 
1148 #undef validation_err
1149 
1150 /*
1151  * RFC 3779 3.3 path validation -- called from X509_verify_cert().
1152  */
1153 int
X509v3_asid_validate_path(X509_STORE_CTX * ctx)1154 X509v3_asid_validate_path(X509_STORE_CTX *ctx)
1155 {
1156           if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) {
1157                     ctx->error = X509_V_ERR_UNSPECIFIED;
1158                     return 0;
1159           }
1160           return asid_validate_path_internal(ctx, ctx->chain, NULL);
1161 }
1162 
1163 /*
1164  * RFC 3779 3.3 path validation of an extension.
1165  * Test whether chain covers extension.
1166  */
1167 int
X509v3_asid_validate_resource_set(STACK_OF (X509)* chain,ASIdentifiers * ext,int allow_inheritance)1168 X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext,
1169     int allow_inheritance)
1170 {
1171           if (ext == NULL)
1172                     return 1;
1173           if (sk_X509_num(chain) <= 0)
1174                     return 0;
1175           if (!allow_inheritance && X509v3_asid_inherits(ext))
1176                     return 0;
1177           return asid_validate_path_internal(NULL, chain, ext);
1178 }
1179 
1180 #endif                          /* OPENSSL_NO_RFC3779 */
1181