summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_addr.c
diff options
context:
space:
mode:
authorjob <>2021-09-02 12:41:44 +0000
committerjob <>2021-09-02 12:41:44 +0000
commita9cb954f2cf630ab74009f5641622ac0d175bc58 (patch)
tree68881b07659cc9e2b17902a5156f430f2154ecf8 /src/lib/libcrypto/x509/x509_addr.c
parente7198b4ee0ece23326da3c1f771171a6ca285eca (diff)
downloadopenbsd-a9cb954f2cf630ab74009f5641622ac0d175bc58.tar.gz
openbsd-a9cb954f2cf630ab74009f5641622ac0d175bc58.tar.bz2
openbsd-a9cb954f2cf630ab74009f5641622ac0d175bc58.zip
Lay groundwork to support X.509 v3 extensions for IP Addresses and AS Identifiers
These extensions are defined in RFC 3779 and used in the RPKI (RFC 6482, RFC 8360). Imported from OpenSSL 1.1.1j (aaf2fcb575cdf6491b98ab4829abf78a3dec8402b8b81efc8f23c00d443981bf) This changeset is a no-op, as there are 10+ issues and at least 2 security issues. Work will continue in-tree. OK tb@, discussed with beck@
Diffstat (limited to 'src/lib/libcrypto/x509/x509_addr.c')
-rw-r--r--src/lib/libcrypto/x509/x509_addr.c1315
1 files changed, 1315 insertions, 0 deletions
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c
new file mode 100644
index 0000000000..4258dbc40c
--- /dev/null
+++ b/src/lib/libcrypto/x509/x509_addr.c
@@ -0,0 +1,1315 @@
1/*
2 * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/*
11 * Implementation of RFC 3779 section 2.2.
12 */
13
14#include <stdio.h>
15#include <stdlib.h>
16
17#include "internal/cryptlib.h"
18#include <openssl/conf.h>
19#include <openssl/asn1.h>
20#include <openssl/asn1t.h>
21#include <openssl/buffer.h>
22#include <openssl/x509v3.h>
23#include "crypto/x509.h"
24#include "ext_dat.h"
25
26#ifndef OPENSSL_NO_RFC3779
27
28/*
29 * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
30 */
31
32ASN1_SEQUENCE(IPAddressRange) = {
33 ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
34 ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
35} ASN1_SEQUENCE_END(IPAddressRange)
36
37ASN1_CHOICE(IPAddressOrRange) = {
38 ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
39 ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange)
40} ASN1_CHOICE_END(IPAddressOrRange)
41
42ASN1_CHOICE(IPAddressChoice) = {
43 ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL),
44 ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
45} ASN1_CHOICE_END(IPAddressChoice)
46
47ASN1_SEQUENCE(IPAddressFamily) = {
48 ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING),
49 ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
50} ASN1_SEQUENCE_END(IPAddressFamily)
51
52ASN1_ITEM_TEMPLATE(IPAddrBlocks) =
53 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
54 IPAddrBlocks, IPAddressFamily)
55static_ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
56
57IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
58IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
59IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
60IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
61
62/*
63 * How much buffer space do we need for a raw address?
64 */
65#define ADDR_RAW_BUF_LEN 16
66
67/*
68 * What's the address length associated with this AFI?
69 */
70static int length_from_afi(const unsigned afi)
71{
72 switch (afi) {
73 case IANA_AFI_IPV4:
74 return 4;
75 case IANA_AFI_IPV6:
76 return 16;
77 default:
78 return 0;
79 }
80}
81
82/*
83 * Extract the AFI from an IPAddressFamily.
84 */
85unsigned int X509v3_addr_get_afi(const IPAddressFamily *f)
86{
87 if (f == NULL
88 || f->addressFamily == NULL
89 || f->addressFamily->data == NULL
90 || f->addressFamily->length < 2)
91 return 0;
92 return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1];
93}
94
95/*
96 * Expand the bitstring form of an address into a raw byte array.
97 * At the moment this is coded for simplicity, not speed.
98 */
99static int addr_expand(unsigned char *addr,
100 const ASN1_BIT_STRING *bs,
101 const int length, const unsigned char fill)
102{
103 if (bs->length < 0 || bs->length > length)
104 return 0;
105 if (bs->length > 0) {
106 memcpy(addr, bs->data, bs->length);
107 if ((bs->flags & 7) != 0) {
108 unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
109 if (fill == 0)
110 addr[bs->length - 1] &= ~mask;
111 else
112 addr[bs->length - 1] |= mask;
113 }
114 }
115 memset(addr + bs->length, fill, length - bs->length);
116 return 1;
117}
118
119/*
120 * Extract the prefix length from a bitstring.
121 */
122#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
123
124/*
125 * i2r handler for one address bitstring.
126 */
127static int i2r_address(BIO *out,
128 const unsigned afi,
129 const unsigned char fill, const ASN1_BIT_STRING *bs)
130{
131 unsigned char addr[ADDR_RAW_BUF_LEN];
132 int i, n;
133
134 if (bs->length < 0)
135 return 0;
136 switch (afi) {
137 case IANA_AFI_IPV4:
138 if (!addr_expand(addr, bs, 4, fill))
139 return 0;
140 BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
141 break;
142 case IANA_AFI_IPV6:
143 if (!addr_expand(addr, bs, 16, fill))
144 return 0;
145 for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00;
146 n -= 2) ;
147 for (i = 0; i < n; i += 2)
148 BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1],
149 (i < 14 ? ":" : ""));
150 if (i < 16)
151 BIO_puts(out, ":");
152 if (i == 0)
153 BIO_puts(out, ":");
154 break;
155 default:
156 for (i = 0; i < bs->length; i++)
157 BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
158 BIO_printf(out, "[%d]", (int)(bs->flags & 7));
159 break;
160 }
161 return 1;
162}
163
164/*
165 * i2r handler for a sequence of addresses and ranges.
166 */
167static int i2r_IPAddressOrRanges(BIO *out,
168 const int indent,
169 const IPAddressOrRanges *aors,
170 const unsigned afi)
171{
172 int i;
173 for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
174 const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
175 BIO_printf(out, "%*s", indent, "");
176 switch (aor->type) {
177 case IPAddressOrRange_addressPrefix:
178 if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
179 return 0;
180 BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
181 continue;
182 case IPAddressOrRange_addressRange:
183 if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
184 return 0;
185 BIO_puts(out, "-");
186 if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
187 return 0;
188 BIO_puts(out, "\n");
189 continue;
190 }
191 }
192 return 1;
193}
194
195/*
196 * i2r handler for an IPAddrBlocks extension.
197 */
198static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
199 void *ext, BIO *out, int indent)
200{
201 const IPAddrBlocks *addr = ext;
202 int i;
203 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
204 IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
205 const unsigned int afi = X509v3_addr_get_afi(f);
206 switch (afi) {
207 case IANA_AFI_IPV4:
208 BIO_printf(out, "%*sIPv4", indent, "");
209 break;
210 case IANA_AFI_IPV6:
211 BIO_printf(out, "%*sIPv6", indent, "");
212 break;
213 default:
214 BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
215 break;
216 }
217 if (f->addressFamily->length > 2) {
218 switch (f->addressFamily->data[2]) {
219 case 1:
220 BIO_puts(out, " (Unicast)");
221 break;
222 case 2:
223 BIO_puts(out, " (Multicast)");
224 break;
225 case 3:
226 BIO_puts(out, " (Unicast/Multicast)");
227 break;
228 case 4:
229 BIO_puts(out, " (MPLS)");
230 break;
231 case 64:
232 BIO_puts(out, " (Tunnel)");
233 break;
234 case 65:
235 BIO_puts(out, " (VPLS)");
236 break;
237 case 66:
238 BIO_puts(out, " (BGP MDT)");
239 break;
240 case 128:
241 BIO_puts(out, " (MPLS-labeled VPN)");
242 break;
243 default:
244 BIO_printf(out, " (Unknown SAFI %u)",
245 (unsigned)f->addressFamily->data[2]);
246 break;
247 }
248 }
249 switch (f->ipAddressChoice->type) {
250 case IPAddressChoice_inherit:
251 BIO_puts(out, ": inherit\n");
252 break;
253 case IPAddressChoice_addressesOrRanges:
254 BIO_puts(out, ":\n");
255 if (!i2r_IPAddressOrRanges(out,
256 indent + 2,
257 f->ipAddressChoice->
258 u.addressesOrRanges, afi))
259 return 0;
260 break;
261 }
262 }
263 return 1;
264}
265
266/*
267 * Sort comparison function for a sequence of IPAddressOrRange
268 * elements.
269 *
270 * There's no sane answer we can give if addr_expand() fails, and an
271 * assertion failure on externally supplied data is seriously uncool,
272 * so we just arbitrarily declare that if given invalid inputs this
273 * function returns -1. If this messes up your preferred sort order
274 * for garbage input, tough noogies.
275 */
276static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
277 const IPAddressOrRange *b, const int length)
278{
279 unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
280 int prefixlen_a = 0, prefixlen_b = 0;
281 int r;
282
283 switch (a->type) {
284 case IPAddressOrRange_addressPrefix:
285 if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
286 return -1;
287 prefixlen_a = addr_prefixlen(a->u.addressPrefix);
288 break;
289 case IPAddressOrRange_addressRange:
290 if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
291 return -1;
292 prefixlen_a = length * 8;
293 break;
294 }
295
296 switch (b->type) {
297 case IPAddressOrRange_addressPrefix:
298 if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
299 return -1;
300 prefixlen_b = addr_prefixlen(b->u.addressPrefix);
301 break;
302 case IPAddressOrRange_addressRange:
303 if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
304 return -1;
305 prefixlen_b = length * 8;
306 break;
307 }
308
309 if ((r = memcmp(addr_a, addr_b, length)) != 0)
310 return r;
311 else
312 return prefixlen_a - prefixlen_b;
313}
314
315/*
316 * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
317 * comparison routines are only allowed two arguments.
318 */
319static int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
320 const IPAddressOrRange *const *b)
321{
322 return IPAddressOrRange_cmp(*a, *b, 4);
323}
324
325/*
326 * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
327 * comparison routines are only allowed two arguments.
328 */
329static int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
330 const IPAddressOrRange *const *b)
331{
332 return IPAddressOrRange_cmp(*a, *b, 16);
333}
334
335/*
336 * Calculate whether a range collapses to a prefix.
337 * See last paragraph of RFC 3779 2.2.3.7.
338 */
339static int range_should_be_prefix(const unsigned char *min,
340 const unsigned char *max, const int length)
341{
342 unsigned char mask;
343 int i, j;
344
345 if (memcmp(min, max, length) <= 0)
346 return -1;
347 for (i = 0; i < length && min[i] == max[i]; i++) ;
348 for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ;
349 if (i < j)
350 return -1;
351 if (i > j)
352 return i * 8;
353 mask = min[i] ^ max[i];
354 switch (mask) {
355 case 0x01:
356 j = 7;
357 break;
358 case 0x03:
359 j = 6;
360 break;
361 case 0x07:
362 j = 5;
363 break;
364 case 0x0F:
365 j = 4;
366 break;
367 case 0x1F:
368 j = 3;
369 break;
370 case 0x3F:
371 j = 2;
372 break;
373 case 0x7F:
374 j = 1;
375 break;
376 default:
377 return -1;
378 }
379 if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
380 return -1;
381 else
382 return i * 8 + j;
383}
384
385/*
386 * Construct a prefix.
387 */
388static int make_addressPrefix(IPAddressOrRange **result,
389 unsigned char *addr, const int prefixlen)
390{
391 int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
392 IPAddressOrRange *aor = IPAddressOrRange_new();
393
394 if (aor == NULL)
395 return 0;
396 aor->type = IPAddressOrRange_addressPrefix;
397 if (aor->u.addressPrefix == NULL &&
398 (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
399 goto err;
400 if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
401 goto err;
402 aor->u.addressPrefix->flags &= ~7;
403 aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
404 if (bitlen > 0) {
405 aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
406 aor->u.addressPrefix->flags |= 8 - bitlen;
407 }
408
409 *result = aor;
410 return 1;
411
412 err:
413 IPAddressOrRange_free(aor);
414 return 0;
415}
416
417/*
418 * Construct a range. If it can be expressed as a prefix,
419 * return a prefix instead. Doing this here simplifies
420 * the rest of the code considerably.
421 */
422static int make_addressRange(IPAddressOrRange **result,
423 unsigned char *min,
424 unsigned char *max, const int length)
425{
426 IPAddressOrRange *aor;
427 int i, prefixlen;
428
429 if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
430 return make_addressPrefix(result, min, prefixlen);
431
432 if ((aor = IPAddressOrRange_new()) == NULL)
433 return 0;
434 aor->type = IPAddressOrRange_addressRange;
435 if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
436 goto err;
437 if (aor->u.addressRange->min == NULL &&
438 (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
439 goto err;
440 if (aor->u.addressRange->max == NULL &&
441 (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
442 goto err;
443
444 for (i = length; i > 0 && min[i - 1] == 0x00; --i) ;
445 if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
446 goto err;
447 aor->u.addressRange->min->flags &= ~7;
448 aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
449 if (i > 0) {
450 unsigned char b = min[i - 1];
451 int j = 1;
452 while ((b & (0xFFU >> j)) != 0)
453 ++j;
454 aor->u.addressRange->min->flags |= 8 - j;
455 }
456
457 for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ;
458 if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
459 goto err;
460 aor->u.addressRange->max->flags &= ~7;
461 aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
462 if (i > 0) {
463 unsigned char b = max[i - 1];
464 int j = 1;
465 while ((b & (0xFFU >> j)) != (0xFFU >> j))
466 ++j;
467 aor->u.addressRange->max->flags |= 8 - j;
468 }
469
470 *result = aor;
471 return 1;
472
473 err:
474 IPAddressOrRange_free(aor);
475 return 0;
476}
477
478/*
479 * Construct a new address family or find an existing one.
480 */
481static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
482 const unsigned afi,
483 const unsigned *safi)
484{
485 IPAddressFamily *f;
486 unsigned char key[3];
487 int keylen;
488 int i;
489
490 key[0] = (afi >> 8) & 0xFF;
491 key[1] = afi & 0xFF;
492 if (safi != NULL) {
493 key[2] = *safi & 0xFF;
494 keylen = 3;
495 } else {
496 keylen = 2;
497 }
498
499 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
500 f = sk_IPAddressFamily_value(addr, i);
501 if (f->addressFamily->length == keylen &&
502 !memcmp(f->addressFamily->data, key, keylen))
503 return f;
504 }
505
506 if ((f = IPAddressFamily_new()) == NULL)
507 goto err;
508 if (f->ipAddressChoice == NULL &&
509 (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
510 goto err;
511 if (f->addressFamily == NULL &&
512 (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
513 goto err;
514 if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
515 goto err;
516 if (!sk_IPAddressFamily_push(addr, f))
517 goto err;
518
519 return f;
520
521 err:
522 IPAddressFamily_free(f);
523 return NULL;
524}
525
526/*
527 * Add an inheritance element.
528 */
529int X509v3_addr_add_inherit(IPAddrBlocks *addr,
530 const unsigned afi, const unsigned *safi)
531{
532 IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
533 if (f == NULL ||
534 f->ipAddressChoice == NULL ||
535 (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
536 f->ipAddressChoice->u.addressesOrRanges != NULL))
537 return 0;
538 if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
539 f->ipAddressChoice->u.inherit != NULL)
540 return 1;
541 if (f->ipAddressChoice->u.inherit == NULL &&
542 (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
543 return 0;
544 f->ipAddressChoice->type = IPAddressChoice_inherit;
545 return 1;
546}
547
548/*
549 * Construct an IPAddressOrRange sequence, or return an existing one.
550 */
551static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
552 const unsigned afi,
553 const unsigned *safi)
554{
555 IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
556 IPAddressOrRanges *aors = NULL;
557
558 if (f == NULL ||
559 f->ipAddressChoice == NULL ||
560 (f->ipAddressChoice->type == IPAddressChoice_inherit &&
561 f->ipAddressChoice->u.inherit != NULL))
562 return NULL;
563 if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
564 aors = f->ipAddressChoice->u.addressesOrRanges;
565 if (aors != NULL)
566 return aors;
567 if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
568 return NULL;
569 switch (afi) {
570 case IANA_AFI_IPV4:
571 (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
572 break;
573 case IANA_AFI_IPV6:
574 (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
575 break;
576 }
577 f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
578 f->ipAddressChoice->u.addressesOrRanges = aors;
579 return aors;
580}
581
582/*
583 * Add a prefix.
584 */
585int X509v3_addr_add_prefix(IPAddrBlocks *addr,
586 const unsigned afi,
587 const unsigned *safi,
588 unsigned char *a, const int prefixlen)
589{
590 IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
591 IPAddressOrRange *aor;
592 if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
593 return 0;
594 if (sk_IPAddressOrRange_push(aors, aor))
595 return 1;
596 IPAddressOrRange_free(aor);
597 return 0;
598}
599
600/*
601 * Add a range.
602 */
603int X509v3_addr_add_range(IPAddrBlocks *addr,
604 const unsigned afi,
605 const unsigned *safi,
606 unsigned char *min, unsigned char *max)
607{
608 IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
609 IPAddressOrRange *aor;
610 int length = length_from_afi(afi);
611 if (aors == NULL)
612 return 0;
613 if (!make_addressRange(&aor, min, max, length))
614 return 0;
615 if (sk_IPAddressOrRange_push(aors, aor))
616 return 1;
617 IPAddressOrRange_free(aor);
618 return 0;
619}
620
621/*
622 * Extract min and max values from an IPAddressOrRange.
623 */
624static int extract_min_max(IPAddressOrRange *aor,
625 unsigned char *min, unsigned char *max, int length)
626{
627 if (aor == NULL || min == NULL || max == NULL)
628 return 0;
629 switch (aor->type) {
630 case IPAddressOrRange_addressPrefix:
631 return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
632 addr_expand(max, aor->u.addressPrefix, length, 0xFF));
633 case IPAddressOrRange_addressRange:
634 return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
635 addr_expand(max, aor->u.addressRange->max, length, 0xFF));
636 }
637 return 0;
638}
639
640/*
641 * Public wrapper for extract_min_max().
642 */
643int X509v3_addr_get_range(IPAddressOrRange *aor,
644 const unsigned afi,
645 unsigned char *min,
646 unsigned char *max, const int length)
647{
648 int afi_length = length_from_afi(afi);
649 if (aor == NULL || min == NULL || max == NULL ||
650 afi_length == 0 || length < afi_length ||
651 (aor->type != IPAddressOrRange_addressPrefix &&
652 aor->type != IPAddressOrRange_addressRange) ||
653 !extract_min_max(aor, min, max, afi_length))
654 return 0;
655
656 return afi_length;
657}
658
659/*
660 * Sort comparison function for a sequence of IPAddressFamily.
661 *
662 * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
663 * the ordering: I can read it as meaning that IPv6 without a SAFI
664 * comes before IPv4 with a SAFI, which seems pretty weird. The
665 * examples in appendix B suggest that the author intended the
666 * null-SAFI rule to apply only within a single AFI, which is what I
667 * would have expected and is what the following code implements.
668 */
669static int IPAddressFamily_cmp(const IPAddressFamily *const *a_,
670 const IPAddressFamily *const *b_)
671{
672 const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
673 const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
674 int len = ((a->length <= b->length) ? a->length : b->length);
675 int cmp = memcmp(a->data, b->data, len);
676 return cmp ? cmp : a->length - b->length;
677}
678
679/*
680 * Check whether an IPAddrBLocks is in canonical form.
681 */
682int X509v3_addr_is_canonical(IPAddrBlocks *addr)
683{
684 unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
685 unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
686 IPAddressOrRanges *aors;
687 int i, j, k;
688
689 /*
690 * Empty extension is canonical.
691 */
692 if (addr == NULL)
693 return 1;
694
695 /*
696 * Check whether the top-level list is in order.
697 */
698 for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
699 const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
700 const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
701 if (IPAddressFamily_cmp(&a, &b) >= 0)
702 return 0;
703 }
704
705 /*
706 * Top level's ok, now check each address family.
707 */
708 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
709 IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
710 int length = length_from_afi(X509v3_addr_get_afi(f));
711
712 /*
713 * Inheritance is canonical. Anything other than inheritance or
714 * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
715 */
716 if (f == NULL || f->ipAddressChoice == NULL)
717 return 0;
718 switch (f->ipAddressChoice->type) {
719 case IPAddressChoice_inherit:
720 continue;
721 case IPAddressChoice_addressesOrRanges:
722 break;
723 default:
724 return 0;
725 }
726
727 /*
728 * It's an IPAddressOrRanges sequence, check it.
729 */
730 aors = f->ipAddressChoice->u.addressesOrRanges;
731 if (sk_IPAddressOrRange_num(aors) == 0)
732 return 0;
733 for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
734 IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
735 IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
736
737 if (!extract_min_max(a, a_min, a_max, length) ||
738 !extract_min_max(b, b_min, b_max, length))
739 return 0;
740
741 /*
742 * Punt misordered list, overlapping start, or inverted range.
743 */
744 if (memcmp(a_min, b_min, length) >= 0 ||
745 memcmp(a_min, a_max, length) > 0 ||
746 memcmp(b_min, b_max, length) > 0)
747 return 0;
748
749 /*
750 * Punt if adjacent or overlapping. Check for adjacency by
751 * subtracting one from b_min first.
752 */
753 for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ;
754 if (memcmp(a_max, b_min, length) >= 0)
755 return 0;
756
757 /*
758 * Check for range that should be expressed as a prefix.
759 */
760 if (a->type == IPAddressOrRange_addressRange &&
761 range_should_be_prefix(a_min, a_max, length) >= 0)
762 return 0;
763 }
764
765 /*
766 * Check range to see if it's inverted or should be a
767 * prefix.
768 */
769 j = sk_IPAddressOrRange_num(aors) - 1;
770 {
771 IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
772 if (a != NULL && a->type == IPAddressOrRange_addressRange) {
773 if (!extract_min_max(a, a_min, a_max, length))
774 return 0;
775 if (memcmp(a_min, a_max, length) > 0 ||
776 range_should_be_prefix(a_min, a_max, length) >= 0)
777 return 0;
778 }
779 }
780 }
781
782 /*
783 * If we made it through all that, we're happy.
784 */
785 return 1;
786}
787
788/*
789 * Whack an IPAddressOrRanges into canonical form.
790 */
791static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
792 const unsigned afi)
793{
794 int i, j, length = length_from_afi(afi);
795
796 /*
797 * Sort the IPAddressOrRanges sequence.
798 */
799 sk_IPAddressOrRange_sort(aors);
800
801 /*
802 * Clean up representation issues, punt on duplicates or overlaps.
803 */
804 for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
805 IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
806 IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
807 unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
808 unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
809
810 if (!extract_min_max(a, a_min, a_max, length) ||
811 !extract_min_max(b, b_min, b_max, length))
812 return 0;
813
814 /*
815 * Punt inverted ranges.
816 */
817 if (memcmp(a_min, a_max, length) > 0 ||
818 memcmp(b_min, b_max, length) > 0)
819 return 0;
820
821 /*
822 * Punt overlaps.
823 */
824 if (memcmp(a_max, b_min, length) >= 0)
825 return 0;
826
827 /*
828 * Merge if a and b are adjacent. We check for
829 * adjacency by subtracting one from b_min first.
830 */
831 for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ;
832 if (memcmp(a_max, b_min, length) == 0) {
833 IPAddressOrRange *merged;
834 if (!make_addressRange(&merged, a_min, b_max, length))
835 return 0;
836 (void)sk_IPAddressOrRange_set(aors, i, merged);
837 (void)sk_IPAddressOrRange_delete(aors, i + 1);
838 IPAddressOrRange_free(a);
839 IPAddressOrRange_free(b);
840 --i;
841 continue;
842 }
843 }
844
845 /*
846 * Check for inverted final range.
847 */
848 j = sk_IPAddressOrRange_num(aors) - 1;
849 {
850 IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
851 if (a != NULL && a->type == IPAddressOrRange_addressRange) {
852 unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
853 if (!extract_min_max(a, a_min, a_max, length))
854 return 0;
855 if (memcmp(a_min, a_max, length) > 0)
856 return 0;
857 }
858 }
859
860 return 1;
861}
862
863/*
864 * Whack an IPAddrBlocks extension into canonical form.
865 */
866int X509v3_addr_canonize(IPAddrBlocks *addr)
867{
868 int i;
869 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
870 IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
871 if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
872 !IPAddressOrRanges_canonize(f->ipAddressChoice->
873 u.addressesOrRanges,
874 X509v3_addr_get_afi(f)))
875 return 0;
876 }
877 (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
878 sk_IPAddressFamily_sort(addr);
879 if (!ossl_assert(X509v3_addr_is_canonical(addr)))
880 return 0;
881 return 1;
882}
883
884/*
885 * v2i handler for the IPAddrBlocks extension.
886 */
887static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
888 struct v3_ext_ctx *ctx,
889 STACK_OF(CONF_VALUE) *values)
890{
891 static const char v4addr_chars[] = "0123456789.";
892 static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
893 IPAddrBlocks *addr = NULL;
894 char *s = NULL, *t;
895 int i;
896
897 if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
898 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
899 return NULL;
900 }
901
902 for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
903 CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
904 unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
905 unsigned afi, *safi = NULL, safi_;
906 const char *addr_chars = NULL;
907 int prefixlen, i1, i2, delim, length;
908
909 if (!name_cmp(val->name, "IPv4")) {
910 afi = IANA_AFI_IPV4;
911 } else if (!name_cmp(val->name, "IPv6")) {
912 afi = IANA_AFI_IPV6;
913 } else if (!name_cmp(val->name, "IPv4-SAFI")) {
914 afi = IANA_AFI_IPV4;
915 safi = &safi_;
916 } else if (!name_cmp(val->name, "IPv6-SAFI")) {
917 afi = IANA_AFI_IPV6;
918 safi = &safi_;
919 } else {
920 X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
921 X509V3_R_EXTENSION_NAME_ERROR);
922 X509V3_conf_err(val);
923 goto err;
924 }
925
926 switch (afi) {
927 case IANA_AFI_IPV4:
928 addr_chars = v4addr_chars;
929 break;
930 case IANA_AFI_IPV6:
931 addr_chars = v6addr_chars;
932 break;
933 }
934
935 length = length_from_afi(afi);
936
937 /*
938 * Handle SAFI, if any, and OPENSSL_strdup() so we can null-terminate
939 * the other input values.
940 */
941 if (safi != NULL) {
942 *safi = strtoul(val->value, &t, 0);
943 t += strspn(t, " \t");
944 if (*safi > 0xFF || *t++ != ':') {
945 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
946 X509V3_conf_err(val);
947 goto err;
948 }
949 t += strspn(t, " \t");
950 s = OPENSSL_strdup(t);
951 } else {
952 s = OPENSSL_strdup(val->value);
953 }
954 if (s == NULL) {
955 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
956 goto err;
957 }
958
959 /*
960 * Check for inheritance. Not worth additional complexity to
961 * optimize this (seldom-used) case.
962 */
963 if (strcmp(s, "inherit") == 0) {
964 if (!X509v3_addr_add_inherit(addr, afi, safi)) {
965 X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
966 X509V3_R_INVALID_INHERITANCE);
967 X509V3_conf_err(val);
968 goto err;
969 }
970 OPENSSL_free(s);
971 s = NULL;
972 continue;
973 }
974
975 i1 = strspn(s, addr_chars);
976 i2 = i1 + strspn(s + i1, " \t");
977 delim = s[i2++];
978 s[i1] = '\0';
979
980 if (a2i_ipadd(min, s) != length) {
981 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
982 X509V3_conf_err(val);
983 goto err;
984 }
985
986 switch (delim) {
987 case '/':
988 prefixlen = (int)strtoul(s + i2, &t, 10);
989 if (t == s + i2 || *t != '\0') {
990 X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
991 X509V3_R_EXTENSION_VALUE_ERROR);
992 X509V3_conf_err(val);
993 goto err;
994 }
995 if (!X509v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
996 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
997 goto err;
998 }
999 break;
1000 case '-':
1001 i1 = i2 + strspn(s + i2, " \t");
1002 i2 = i1 + strspn(s + i1, addr_chars);
1003 if (i1 == i2 || s[i2] != '\0') {
1004 X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
1005 X509V3_R_EXTENSION_VALUE_ERROR);
1006 X509V3_conf_err(val);
1007 goto err;
1008 }
1009 if (a2i_ipadd(max, s + i1) != length) {
1010 X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
1011 X509V3_R_INVALID_IPADDRESS);
1012 X509V3_conf_err(val);
1013 goto err;
1014 }
1015 if (memcmp(min, max, length_from_afi(afi)) > 0) {
1016 X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
1017 X509V3_R_EXTENSION_VALUE_ERROR);
1018 X509V3_conf_err(val);
1019 goto err;
1020 }
1021 if (!X509v3_addr_add_range(addr, afi, safi, min, max)) {
1022 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
1023 goto err;
1024 }
1025 break;
1026 case '\0':
1027 if (!X509v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
1028 X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
1029 goto err;
1030 }
1031 break;
1032 default:
1033 X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
1034 X509V3_R_EXTENSION_VALUE_ERROR);
1035 X509V3_conf_err(val);
1036 goto err;
1037 }
1038
1039 OPENSSL_free(s);
1040 s = NULL;
1041 }
1042
1043 /*
1044 * Canonize the result, then we're done.
1045 */
1046 if (!X509v3_addr_canonize(addr))
1047 goto err;
1048 return addr;
1049
1050 err:
1051 OPENSSL_free(s);
1052 sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
1053 return NULL;
1054}
1055
1056/*
1057 * OpenSSL dispatch
1058 */
1059const X509V3_EXT_METHOD v3_addr = {
1060 NID_sbgp_ipAddrBlock, /* nid */
1061 0, /* flags */
1062 ASN1_ITEM_ref(IPAddrBlocks), /* template */
1063 0, 0, 0, 0, /* old functions, ignored */
1064 0, /* i2s */
1065 0, /* s2i */
1066 0, /* i2v */
1067 v2i_IPAddrBlocks, /* v2i */
1068 i2r_IPAddrBlocks, /* i2r */
1069 0, /* r2i */
1070 NULL /* extension-specific data */
1071};
1072
1073/*
1074 * Figure out whether extension sues inheritance.
1075 */
1076int X509v3_addr_inherits(IPAddrBlocks *addr)
1077{
1078 int i;
1079 if (addr == NULL)
1080 return 0;
1081 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
1082 IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
1083 if (f->ipAddressChoice->type == IPAddressChoice_inherit)
1084 return 1;
1085 }
1086 return 0;
1087}
1088
1089/*
1090 * Figure out whether parent contains child.
1091 */
1092static int addr_contains(IPAddressOrRanges *parent,
1093 IPAddressOrRanges *child, int length)
1094{
1095 unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
1096 unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
1097 int p, c;
1098
1099 if (child == NULL || parent == child)
1100 return 1;
1101 if (parent == NULL)
1102 return 0;
1103
1104 p = 0;
1105 for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
1106 if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
1107 c_min, c_max, length))
1108 return -1;
1109 for (;; p++) {
1110 if (p >= sk_IPAddressOrRange_num(parent))
1111 return 0;
1112 if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
1113 p_min, p_max, length))
1114 return 0;
1115 if (memcmp(p_max, c_max, length) < 0)
1116 continue;
1117 if (memcmp(p_min, c_min, length) > 0)
1118 return 0;
1119 break;
1120 }
1121 }
1122
1123 return 1;
1124}
1125
1126/*
1127 * Test whether a is a subset of b.
1128 */
1129int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
1130{
1131 int i;
1132 if (a == NULL || a == b)
1133 return 1;
1134 if (b == NULL || X509v3_addr_inherits(a) || X509v3_addr_inherits(b))
1135 return 0;
1136 (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
1137 for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
1138 IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
1139 int j = sk_IPAddressFamily_find(b, fa);
1140 IPAddressFamily *fb;
1141 fb = sk_IPAddressFamily_value(b, j);
1142 if (fb == NULL)
1143 return 0;
1144 if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges,
1145 fa->ipAddressChoice->u.addressesOrRanges,
1146 length_from_afi(X509v3_addr_get_afi(fb))))
1147 return 0;
1148 }
1149 return 1;
1150}
1151
1152/*
1153 * Validation error handling via callback.
1154 */
1155#define validation_err(_err_) \
1156 do { \
1157 if (ctx != NULL) { \
1158 ctx->error = _err_; \
1159 ctx->error_depth = i; \
1160 ctx->current_cert = x; \
1161 ret = ctx->verify_cb(0, ctx); \
1162 } else { \
1163 ret = 0; \
1164 } \
1165 if (!ret) \
1166 goto done; \
1167 } while (0)
1168
1169/*
1170 * Core code for RFC 3779 2.3 path validation.
1171 *
1172 * Returns 1 for success, 0 on error.
1173 *
1174 * When returning 0, ctx->error MUST be set to an appropriate value other than
1175 * X509_V_OK.
1176 */
1177static int addr_validate_path_internal(X509_STORE_CTX *ctx,
1178 STACK_OF(X509) *chain,
1179 IPAddrBlocks *ext)
1180{
1181 IPAddrBlocks *child = NULL;
1182 int i, j, ret = 1;
1183 X509 *x;
1184
1185 if (!ossl_assert(chain != NULL && sk_X509_num(chain) > 0)
1186 || !ossl_assert(ctx != NULL || ext != NULL)
1187 || !ossl_assert(ctx == NULL || ctx->verify_cb != NULL)) {
1188 if (ctx != NULL)
1189 ctx->error = X509_V_ERR_UNSPECIFIED;
1190 return 0;
1191 }
1192
1193 /*
1194 * Figure out where to start. If we don't have an extension to
1195 * check, we're done. Otherwise, check canonical form and
1196 * set up for walking up the chain.
1197 */
1198 if (ext != NULL) {
1199 i = -1;
1200 x = NULL;
1201 } else {
1202 i = 0;
1203 x = sk_X509_value(chain, i);
1204 if ((ext = x->rfc3779_addr) == NULL)
1205 goto done;
1206 }
1207 if (!X509v3_addr_is_canonical(ext))
1208 validation_err(X509_V_ERR_INVALID_EXTENSION);
1209 (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
1210 if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
1211 X509V3err(X509V3_F_ADDR_VALIDATE_PATH_INTERNAL,
1212 ERR_R_MALLOC_FAILURE);
1213 if (ctx != NULL)
1214 ctx->error = X509_V_ERR_OUT_OF_MEM;
1215 ret = 0;
1216 goto done;
1217 }
1218
1219 /*
1220 * Now walk up the chain. No cert may list resources that its
1221 * parent doesn't list.
1222 */
1223 for (i++; i < sk_X509_num(chain); i++) {
1224 x = sk_X509_value(chain, i);
1225 if (!X509v3_addr_is_canonical(x->rfc3779_addr))
1226 validation_err(X509_V_ERR_INVALID_EXTENSION);
1227 if (x->rfc3779_addr == NULL) {
1228 for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
1229 IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
1230 if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
1231 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1232 break;
1233 }
1234 }
1235 continue;
1236 }
1237 (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr,
1238 IPAddressFamily_cmp);
1239 for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
1240 IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
1241 int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
1242 IPAddressFamily *fp =
1243 sk_IPAddressFamily_value(x->rfc3779_addr, k);
1244 if (fp == NULL) {
1245 if (fc->ipAddressChoice->type ==
1246 IPAddressChoice_addressesOrRanges) {
1247 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1248 break;
1249 }
1250 continue;
1251 }
1252 if (fp->ipAddressChoice->type ==
1253 IPAddressChoice_addressesOrRanges) {
1254 if (fc->ipAddressChoice->type == IPAddressChoice_inherit
1255 || addr_contains(fp->ipAddressChoice->u.addressesOrRanges,
1256 fc->ipAddressChoice->u.addressesOrRanges,
1257 length_from_afi(X509v3_addr_get_afi(fc))))
1258 sk_IPAddressFamily_set(child, j, fp);
1259 else
1260 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1261 }
1262 }
1263 }
1264
1265 /*
1266 * Trust anchor can't inherit.
1267 */
1268 if (x->rfc3779_addr != NULL) {
1269 for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
1270 IPAddressFamily *fp =
1271 sk_IPAddressFamily_value(x->rfc3779_addr, j);
1272 if (fp->ipAddressChoice->type == IPAddressChoice_inherit
1273 && sk_IPAddressFamily_find(child, fp) >= 0)
1274 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1275 }
1276 }
1277
1278 done:
1279 sk_IPAddressFamily_free(child);
1280 return ret;
1281}
1282
1283#undef validation_err
1284
1285/*
1286 * RFC 3779 2.3 path validation -- called from X509_verify_cert().
1287 */
1288int X509v3_addr_validate_path(X509_STORE_CTX *ctx)
1289{
1290 if (ctx->chain == NULL
1291 || sk_X509_num(ctx->chain) == 0
1292 || ctx->verify_cb == NULL) {
1293 ctx->error = X509_V_ERR_UNSPECIFIED;
1294 return 0;
1295 }
1296 return addr_validate_path_internal(ctx, ctx->chain, NULL);
1297}
1298
1299/*
1300 * RFC 3779 2.3 path validation of an extension.
1301 * Test whether chain covers extension.
1302 */
1303int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain,
1304 IPAddrBlocks *ext, int allow_inheritance)
1305{
1306 if (ext == NULL)
1307 return 1;
1308 if (chain == NULL || sk_X509_num(chain) == 0)
1309 return 0;
1310 if (!allow_inheritance && X509v3_addr_inherits(ext))
1311 return 0;
1312 return addr_validate_path_internal(NULL, chain, ext);
1313}
1314
1315#endif /* OPENSSL_NO_RFC3779 */