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