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