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