/*
 * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * Implementation of RFC 3779 section 2.2.
 */

#include <stdio.h>
#include <stdlib.h>

#include "internal/cryptlib.h"
#include <openssl/conf.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/buffer.h>
#include <openssl/x509v3.h>
#include "crypto/x509.h"
#include "ext_dat.h"
#include "x509_local.h"

#ifndef OPENSSL_NO_RFC3779

/*
 * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
 */

ASN1_SEQUENCE(IPAddressRange) = {
  ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
  ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(IPAddressRange)

ASN1_CHOICE(IPAddressOrRange) = {
  ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
  ASN1_SIMPLE(IPAddressOrRange, u.addressRange,  IPAddressRange)
} ASN1_CHOICE_END(IPAddressOrRange)

ASN1_CHOICE(IPAddressChoice) = {
  ASN1_SIMPLE(IPAddressChoice,      u.inherit,           ASN1_NULL),
  ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
} ASN1_CHOICE_END(IPAddressChoice)

ASN1_SEQUENCE(IPAddressFamily) = {
  ASN1_SIMPLE(IPAddressFamily, addressFamily,   ASN1_OCTET_STRING),
  ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
} ASN1_SEQUENCE_END(IPAddressFamily)

ASN1_ITEM_TEMPLATE(IPAddrBlocks) =
  ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
                        IPAddrBlocks, IPAddressFamily)
static_ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)

IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)

/*
 * How much buffer space do we need for a raw address?
 */
#define ADDR_RAW_BUF_LEN        16

/*
 * What's the address length associated with this AFI?
 */
static int length_from_afi(const unsigned afi)
{
    switch (afi) {
    case IANA_AFI_IPV4:
        return 4;
    case IANA_AFI_IPV6:
        return 16;
    default:
        return 0;
    }
}

/*
 * Extract the AFI from an IPAddressFamily.
 */
unsigned int X509v3_addr_get_afi(const IPAddressFamily *f)
{
    if (f == NULL
            || f->addressFamily == NULL
            || f->addressFamily->data == NULL
            || f->addressFamily->length < 2)
        return 0;
    return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1];
}

/*
 * Expand the bitstring form of an address into a raw byte array.
 * At the moment this is coded for simplicity, not speed.
 */
static int addr_expand(unsigned char *addr,
                       const ASN1_BIT_STRING *bs,
                       const int length, const unsigned char fill)
{
    if (bs->length < 0 || bs->length > length)
        return 0;
    if (bs->length > 0) {
        memcpy(addr, bs->data, bs->length);
        if ((bs->flags & 7) != 0) {
            unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
            if (fill == 0)
                addr[bs->length - 1] &= ~mask;
            else
                addr[bs->length - 1] |= mask;
        }
    }
    memset(addr + bs->length, fill, length - bs->length);
    return 1;
}

/*
 * Extract the prefix length from a bitstring.
 */
#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))

/*
 * i2r handler for one address bitstring.
 */
static int i2r_address(BIO *out,
                       const unsigned afi,
                       const unsigned char fill, const ASN1_BIT_STRING *bs)
{
    unsigned char addr[ADDR_RAW_BUF_LEN];
    int i, n;

    if (bs->length < 0)
        return 0;
    switch (afi) {
    case IANA_AFI_IPV4:
        if (!addr_expand(addr, bs, 4, fill))
            return 0;
        BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
        break;
    case IANA_AFI_IPV6:
        if (!addr_expand(addr, bs, 16, fill))
            return 0;
        for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00;
             n -= 2) ;
        for (i = 0; i < n; i += 2)
            BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1],
                       (i < 14 ? ":" : ""));
        if (i < 16)
            BIO_puts(out, ":");
        if (i == 0)
            BIO_puts(out, ":");
        break;
    default:
        for (i = 0; i < bs->length; i++)
            BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
        BIO_printf(out, "[%d]", (int)(bs->flags & 7));
        break;
    }
    return 1;
}

/*
 * i2r handler for a sequence of addresses and ranges.
 */
static int i2r_IPAddressOrRanges(BIO *out,
                                 const int indent,
                                 const IPAddressOrRanges *aors,
                                 const unsigned afi)
{
    int i;
    for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
        const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
        BIO_printf(out, "%*s", indent, "");
        switch (aor->type) {
        case IPAddressOrRange_addressPrefix:
            if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
                return 0;
            BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
            continue;
        case IPAddressOrRange_addressRange:
            if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
                return 0;
            BIO_puts(out, "-");
            if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
                return 0;
            BIO_puts(out, "\n");
            continue;
        }
    }
    return 1;
}

/*
 * i2r handler for an IPAddrBlocks extension.
 */
static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
                            void *ext, BIO *out, int indent)
{
    const IPAddrBlocks *addr = ext;
    int i;
    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
        const unsigned int afi = X509v3_addr_get_afi(f);
        switch (afi) {
        case IANA_AFI_IPV4:
            BIO_printf(out, "%*sIPv4", indent, "");
            break;
        case IANA_AFI_IPV6:
            BIO_printf(out, "%*sIPv6", indent, "");
            break;
        default:
            BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
            break;
        }
        if (f->addressFamily->length > 2) {
            switch (f->addressFamily->data[2]) {
            case 1:
                BIO_puts(out, " (Unicast)");
                break;
            case 2:
                BIO_puts(out, " (Multicast)");
                break;
            case 3:
                BIO_puts(out, " (Unicast/Multicast)");
                break;
            case 4:
                BIO_puts(out, " (MPLS)");
                break;
            case 64:
                BIO_puts(out, " (Tunnel)");
                break;
            case 65:
                BIO_puts(out, " (VPLS)");
                break;
            case 66:
                BIO_puts(out, " (BGP MDT)");
                break;
            case 128:
                BIO_puts(out, " (MPLS-labeled VPN)");
                break;
            default:
                BIO_printf(out, " (Unknown SAFI %u)",
                           (unsigned)f->addressFamily->data[2]);
                break;
            }
        }
        switch (f->ipAddressChoice->type) {
        case IPAddressChoice_inherit:
            BIO_puts(out, ": inherit\n");
            break;
        case IPAddressChoice_addressesOrRanges:
            BIO_puts(out, ":\n");
            if (!i2r_IPAddressOrRanges(out,
                                       indent + 2,
                                       f->ipAddressChoice->
                                       u.addressesOrRanges, afi))
                return 0;
            break;
        }
    }
    return 1;
}

/*
 * Sort comparison function for a sequence of IPAddressOrRange
 * elements.
 *
 * There's no sane answer we can give if addr_expand() fails, and an
 * assertion failure on externally supplied data is seriously uncool,
 * so we just arbitrarily declare that if given invalid inputs this
 * function returns -1.  If this messes up your preferred sort order
 * for garbage input, tough noogies.
 */
static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
                                const IPAddressOrRange *b, const int length)
{
    unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
    int prefixlen_a = 0, prefixlen_b = 0;
    int r;

    switch (a->type) {
    case IPAddressOrRange_addressPrefix:
        if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
            return -1;
        prefixlen_a = addr_prefixlen(a->u.addressPrefix);
        break;
    case IPAddressOrRange_addressRange:
        if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
            return -1;
        prefixlen_a = length * 8;
        break;
    }

    switch (b->type) {
    case IPAddressOrRange_addressPrefix:
        if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
            return -1;
        prefixlen_b = addr_prefixlen(b->u.addressPrefix);
        break;
    case IPAddressOrRange_addressRange:
        if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
            return -1;
        prefixlen_b = length * 8;
        break;
    }

    if ((r = memcmp(addr_a, addr_b, length)) != 0)
        return r;
    else
        return prefixlen_a - prefixlen_b;
}

/*
 * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
 * comparison routines are only allowed two arguments.
 */
static int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
                                  const IPAddressOrRange *const *b)
{
    return IPAddressOrRange_cmp(*a, *b, 4);
}

/*
 * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
 * comparison routines are only allowed two arguments.
 */
static int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
                                  const IPAddressOrRange *const *b)
{
    return IPAddressOrRange_cmp(*a, *b, 16);
}

/*
 * Calculate whether a range collapses to a prefix.
 * See last paragraph of RFC 3779 2.2.3.7.
 */
static int range_should_be_prefix(const unsigned char *min,
                                  const unsigned char *max, const int length)
{
    unsigned char mask;
    int i, j;

    if (memcmp(min, max, length) <= 0)
        return -1;
    for (i = 0; i < length && min[i] == max[i]; i++) ;
    for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ;
    if (i < j)
        return -1;
    if (i > j)
        return i * 8;
    mask = min[i] ^ max[i];
    switch (mask) {
    case 0x01:
        j = 7;
        break;
    case 0x03:
        j = 6;
        break;
    case 0x07:
        j = 5;
        break;
    case 0x0F:
        j = 4;
        break;
    case 0x1F:
        j = 3;
        break;
    case 0x3F:
        j = 2;
        break;
    case 0x7F:
        j = 1;
        break;
    default:
        return -1;
    }
    if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
        return -1;
    else
        return i * 8 + j;
}

/*
 * Construct a prefix.
 */
static int make_addressPrefix(IPAddressOrRange **result,
                              unsigned char *addr, const int prefixlen)
{
    int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
    IPAddressOrRange *aor = IPAddressOrRange_new();

    if (aor == NULL)
        return 0;
    aor->type = IPAddressOrRange_addressPrefix;
    if (aor->u.addressPrefix == NULL &&
        (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
        goto err;
    if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
        goto err;
    aor->u.addressPrefix->flags &= ~7;
    aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    if (bitlen > 0) {
        aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
        aor->u.addressPrefix->flags |= 8 - bitlen;
    }

    *result = aor;
    return 1;

 err:
    IPAddressOrRange_free(aor);
    return 0;
}

/*
 * Construct a range.  If it can be expressed as a prefix,
 * return a prefix instead.  Doing this here simplifies
 * the rest of the code considerably.
 */
static int make_addressRange(IPAddressOrRange **result,
                             unsigned char *min,
                             unsigned char *max, const int length)
{
    IPAddressOrRange *aor;
    int i, prefixlen;

    if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
        return make_addressPrefix(result, min, prefixlen);

    if ((aor = IPAddressOrRange_new()) == NULL)
        return 0;
    aor->type = IPAddressOrRange_addressRange;
    if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
        goto err;
    if (aor->u.addressRange->min == NULL &&
        (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
        goto err;
    if (aor->u.addressRange->max == NULL &&
        (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
        goto err;

    for (i = length; i > 0 && min[i - 1] == 0x00; --i) ;
    if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
        goto err;
    aor->u.addressRange->min->flags &= ~7;
    aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    if (i > 0) {
        unsigned char b = min[i - 1];
        int j = 1;
        while ((b & (0xFFU >> j)) != 0)
            ++j;
        aor->u.addressRange->min->flags |= 8 - j;
    }

    for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ;
    if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
        goto err;
    aor->u.addressRange->max->flags &= ~7;
    aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    if (i > 0) {
        unsigned char b = max[i - 1];
        int j = 1;
        while ((b & (0xFFU >> j)) != (0xFFU >> j))
            ++j;
        aor->u.addressRange->max->flags |= 8 - j;
    }

    *result = aor;
    return 1;

 err:
    IPAddressOrRange_free(aor);
    return 0;
}

/*
 * Construct a new address family or find an existing one.
 */
static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
                                             const unsigned afi,
                                             const unsigned *safi)
{
    IPAddressFamily *f;
    unsigned char key[3];
    int keylen;
    int i;

    key[0] = (afi >> 8) & 0xFF;
    key[1] = afi & 0xFF;
    if (safi != NULL) {
        key[2] = *safi & 0xFF;
        keylen = 3;
    } else {
        keylen = 2;
    }

    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        f = sk_IPAddressFamily_value(addr, i);
        if (f->addressFamily->length == keylen &&
            !memcmp(f->addressFamily->data, key, keylen))
            return f;
    }

    if ((f = IPAddressFamily_new()) == NULL)
        goto err;
    if (f->ipAddressChoice == NULL &&
        (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
        goto err;
    if (f->addressFamily == NULL &&
        (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
        goto err;
    if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
        goto err;
    if (!sk_IPAddressFamily_push(addr, f))
        goto err;

    return f;

 err:
    IPAddressFamily_free(f);
    return NULL;
}

/*
 * Add an inheritance element.
 */
int X509v3_addr_add_inherit(IPAddrBlocks *addr,
                            const unsigned afi, const unsigned *safi)
{
    IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
    if (f == NULL ||
        f->ipAddressChoice == NULL ||
        (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
         f->ipAddressChoice->u.addressesOrRanges != NULL))
        return 0;
    if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
        f->ipAddressChoice->u.inherit != NULL)
        return 1;
    if (f->ipAddressChoice->u.inherit == NULL &&
        (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
        return 0;
    f->ipAddressChoice->type = IPAddressChoice_inherit;
    return 1;
}

/*
 * Construct an IPAddressOrRange sequence, or return an existing one.
 */
static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
                                               const unsigned afi,
                                               const unsigned *safi)
{
    IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
    IPAddressOrRanges *aors = NULL;

    if (f == NULL ||
        f->ipAddressChoice == NULL ||
        (f->ipAddressChoice->type == IPAddressChoice_inherit &&
         f->ipAddressChoice->u.inherit != NULL))
        return NULL;
    if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
        aors = f->ipAddressChoice->u.addressesOrRanges;
    if (aors != NULL)
        return aors;
    if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
        return NULL;
    switch (afi) {
    case IANA_AFI_IPV4:
        (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
        break;
    case IANA_AFI_IPV6:
        (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
        break;
    }
    f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
    f->ipAddressChoice->u.addressesOrRanges = aors;
    return aors;
}

/*
 * Add a prefix.
 */
int X509v3_addr_add_prefix(IPAddrBlocks *addr,
                           const unsigned afi,
                           const unsigned *safi,
                           unsigned char *a, const int prefixlen)
{
    IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
    IPAddressOrRange *aor;
    if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
        return 0;
    if (sk_IPAddressOrRange_push(aors, aor))
        return 1;
    IPAddressOrRange_free(aor);
    return 0;
}

/*
 * Add a range.
 */
int X509v3_addr_add_range(IPAddrBlocks *addr,
                          const unsigned afi,
                          const unsigned *safi,
                          unsigned char *min, unsigned char *max)
{
    IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
    IPAddressOrRange *aor;
    int length = length_from_afi(afi);
    if (aors == NULL)
        return 0;
    if (!make_addressRange(&aor, min, max, length))
        return 0;
    if (sk_IPAddressOrRange_push(aors, aor))
        return 1;
    IPAddressOrRange_free(aor);
    return 0;
}

/*
 * Extract min and max values from an IPAddressOrRange.
 */
static int extract_min_max(IPAddressOrRange *aor,
                           unsigned char *min, unsigned char *max, int length)
{
    if (aor == NULL || min == NULL || max == NULL)
        return 0;
    switch (aor->type) {
    case IPAddressOrRange_addressPrefix:
        return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
                addr_expand(max, aor->u.addressPrefix, length, 0xFF));
    case IPAddressOrRange_addressRange:
        return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
                addr_expand(max, aor->u.addressRange->max, length, 0xFF));
    }
    return 0;
}

/*
 * Public wrapper for extract_min_max().
 */
int X509v3_addr_get_range(IPAddressOrRange *aor,
                          const unsigned afi,
                          unsigned char *min,
                          unsigned char *max, const int length)
{
    int afi_length = length_from_afi(afi);
    if (aor == NULL || min == NULL || max == NULL ||
        afi_length == 0 || length < afi_length ||
        (aor->type != IPAddressOrRange_addressPrefix &&
         aor->type != IPAddressOrRange_addressRange) ||
        !extract_min_max(aor, min, max, afi_length))
        return 0;

    return afi_length;
}

/*
 * Sort comparison function for a sequence of IPAddressFamily.
 *
 * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
 * the ordering: I can read it as meaning that IPv6 without a SAFI
 * comes before IPv4 with a SAFI, which seems pretty weird.  The
 * examples in appendix B suggest that the author intended the
 * null-SAFI rule to apply only within a single AFI, which is what I
 * would have expected and is what the following code implements.
 */
static int IPAddressFamily_cmp(const IPAddressFamily *const *a_,
                               const IPAddressFamily *const *b_)
{
    const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
    const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
    int len = ((a->length <= b->length) ? a->length : b->length);
    int cmp = memcmp(a->data, b->data, len);
    return cmp ? cmp : a->length - b->length;
}

/*
 * Check whether an IPAddrBLocks is in canonical form.
 */
int X509v3_addr_is_canonical(IPAddrBlocks *addr)
{
    unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
    unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
    IPAddressOrRanges *aors;
    int i, j, k;

    /*
     * Empty extension is canonical.
     */
    if (addr == NULL)
        return 1;

    /*
     * Check whether the top-level list is in order.
     */
    for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
        const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
        const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
        if (IPAddressFamily_cmp(&a, &b) >= 0)
            return 0;
    }

    /*
     * Top level's ok, now check each address family.
     */
    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
        int length = length_from_afi(X509v3_addr_get_afi(f));

        /*
         * Inheritance is canonical.  Anything other than inheritance or
         * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
         */
        if (f == NULL || f->ipAddressChoice == NULL)
            return 0;
        switch (f->ipAddressChoice->type) {
        case IPAddressChoice_inherit:
            continue;
        case IPAddressChoice_addressesOrRanges:
            break;
        default:
            return 0;
        }

        /*
         * It's an IPAddressOrRanges sequence, check it.
         */
        aors = f->ipAddressChoice->u.addressesOrRanges;
        if (sk_IPAddressOrRange_num(aors) == 0)
            return 0;
        for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
            IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
            IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);

            if (!extract_min_max(a, a_min, a_max, length) ||
                !extract_min_max(b, b_min, b_max, length))
                return 0;

            /*
             * Punt misordered list, overlapping start, or inverted range.
             */
            if (memcmp(a_min, b_min, length) >= 0 ||
                memcmp(a_min, a_max, length) > 0 ||
                memcmp(b_min, b_max, length) > 0)
                return 0;

            /*
             * Punt if adjacent or overlapping.  Check for adjacency by
             * subtracting one from b_min first.
             */
            for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ;
            if (memcmp(a_max, b_min, length) >= 0)
                return 0;

            /*
             * Check for range that should be expressed as a prefix.
             */
            if (a->type == IPAddressOrRange_addressRange &&
                range_should_be_prefix(a_min, a_max, length) >= 0)
                return 0;
        }

        /*
         * Check range to see if it's inverted or should be a
         * prefix.
         */
        j = sk_IPAddressOrRange_num(aors) - 1;
        {
            IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
            if (a != NULL && a->type == IPAddressOrRange_addressRange) {
                if (!extract_min_max(a, a_min, a_max, length))
                    return 0;
                if (memcmp(a_min, a_max, length) > 0 ||
                    range_should_be_prefix(a_min, a_max, length) >= 0)
                    return 0;
            }
        }
    }

    /*
     * If we made it through all that, we're happy.
     */
    return 1;
}

/*
 * Whack an IPAddressOrRanges into canonical form.
 */
static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
                                      const unsigned afi)
{
    int i, j, length = length_from_afi(afi);

    /*
     * Sort the IPAddressOrRanges sequence.
     */
    sk_IPAddressOrRange_sort(aors);

    /*
     * Clean up representation issues, punt on duplicates or overlaps.
     */
    for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
        IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
        IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
        unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
        unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];

        if (!extract_min_max(a, a_min, a_max, length) ||
            !extract_min_max(b, b_min, b_max, length))
            return 0;

        /*
         * Punt inverted ranges.
         */
        if (memcmp(a_min, a_max, length) > 0 ||
            memcmp(b_min, b_max, length) > 0)
            return 0;

        /*
         * Punt overlaps.
         */
        if (memcmp(a_max, b_min, length) >= 0)
            return 0;

        /*
         * Merge if a and b are adjacent.  We check for
         * adjacency by subtracting one from b_min first.
         */
        for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ;
        if (memcmp(a_max, b_min, length) == 0) {
            IPAddressOrRange *merged;
            if (!make_addressRange(&merged, a_min, b_max, length))
                return 0;
            (void)sk_IPAddressOrRange_set(aors, i, merged);
            (void)sk_IPAddressOrRange_delete(aors, i + 1);
            IPAddressOrRange_free(a);
            IPAddressOrRange_free(b);
            --i;
            continue;
        }
    }

    /*
     * Check for inverted final range.
     */
    j = sk_IPAddressOrRange_num(aors) - 1;
    {
        IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
        if (a != NULL && a->type == IPAddressOrRange_addressRange) {
            unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
            if (!extract_min_max(a, a_min, a_max, length))
                return 0;
            if (memcmp(a_min, a_max, length) > 0)
                return 0;
        }
    }

    return 1;
}

/*
 * Whack an IPAddrBlocks extension into canonical form.
 */
int X509v3_addr_canonize(IPAddrBlocks *addr)
{
    int i;
    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
        if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
            !IPAddressOrRanges_canonize(f->ipAddressChoice->
                                        u.addressesOrRanges,
                                        X509v3_addr_get_afi(f)))
            return 0;
    }
    (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
    sk_IPAddressFamily_sort(addr);
    if (!ossl_assert(X509v3_addr_is_canonical(addr)))
        return 0;
    return 1;
}

/*
 * v2i handler for the IPAddrBlocks extension.
 */
static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
                              struct v3_ext_ctx *ctx,
                              STACK_OF(CONF_VALUE) *values)
{
    static const char v4addr_chars[] = "0123456789.";
    static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
    IPAddrBlocks *addr = NULL;
    char *s = NULL, *t;
    int i;

    if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
        ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
        CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
        unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
        unsigned afi, *safi = NULL, safi_;
        const char *addr_chars = NULL;
        int prefixlen, i1, i2, delim, length;

        if (!ossl_v3_name_cmp(val->name, "IPv4")) {
            afi = IANA_AFI_IPV4;
        } else if (!ossl_v3_name_cmp(val->name, "IPv6")) {
            afi = IANA_AFI_IPV6;
        } else if (!ossl_v3_name_cmp(val->name, "IPv4-SAFI")) {
            afi = IANA_AFI_IPV4;
            safi = &safi_;
        } else if (!ossl_v3_name_cmp(val->name, "IPv6-SAFI")) {
            afi = IANA_AFI_IPV6;
            safi = &safi_;
        } else {
            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR,
                           "%s", val->name);
            goto err;
        }

        switch (afi) {
        case IANA_AFI_IPV4:
            addr_chars = v4addr_chars;
            break;
        case IANA_AFI_IPV6:
            addr_chars = v6addr_chars;
            break;
        }

        length = length_from_afi(afi);

        /*
         * Handle SAFI, if any, and OPENSSL_strdup() so we can null-terminate
         * the other input values.
         */
        if (safi != NULL) {
            *safi = strtoul(val->value, &t, 0);
            t += strspn(t, " \t");
            if (*safi > 0xFF || *t++ != ':') {
                ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SAFI);
                X509V3_conf_add_error_name_value(val);
                goto err;
            }
            t += strspn(t, " \t");
            s = OPENSSL_strdup(t);
        } else {
            s = OPENSSL_strdup(val->value);
        }
        if (s == NULL) {
            ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
            goto err;
        }

        /*
         * Check for inheritance.  Not worth additional complexity to
         * optimize this (seldom-used) case.
         */
        if (strcmp(s, "inherit") == 0) {
            if (!X509v3_addr_add_inherit(addr, afi, safi)) {
                ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_INHERITANCE);
                X509V3_conf_add_error_name_value(val);
                goto err;
            }
            OPENSSL_free(s);
            s = NULL;
            continue;
        }

        i1 = strspn(s, addr_chars);
        i2 = i1 + strspn(s + i1, " \t");
        delim = s[i2++];
        s[i1] = '\0';

        if (ossl_a2i_ipadd(min, s) != length) {
            ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_IPADDRESS);
            X509V3_conf_add_error_name_value(val);
            goto err;
        }

        switch (delim) {
        case '/':
            prefixlen = (int)strtoul(s + i2, &t, 10);
            if (t == s + i2 || *t != '\0') {
                ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
                X509V3_conf_add_error_name_value(val);
                goto err;
            }
            if (!X509v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
                ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            break;
        case '-':
            i1 = i2 + strspn(s + i2, " \t");
            i2 = i1 + strspn(s + i1, addr_chars);
            if (i1 == i2 || s[i2] != '\0') {
                ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
                X509V3_conf_add_error_name_value(val);
                goto err;
            }
            if (ossl_a2i_ipadd(max, s + i1) != length) {
                ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_IPADDRESS);
                X509V3_conf_add_error_name_value(val);
                goto err;
            }
            if (memcmp(min, max, length_from_afi(afi)) > 0) {
                ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
                X509V3_conf_add_error_name_value(val);
                goto err;
            }
            if (!X509v3_addr_add_range(addr, afi, safi, min, max)) {
                ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            break;
        case '\0':
            if (!X509v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
                ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            break;
        default:
            ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
            X509V3_conf_add_error_name_value(val);
            goto err;
        }

        OPENSSL_free(s);
        s = NULL;
    }

    /*
     * Canonize the result, then we're done.
     */
    if (!X509v3_addr_canonize(addr))
        goto err;
    return addr;

 err:
    OPENSSL_free(s);
    sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
    return NULL;
}

/*
 * OpenSSL dispatch
 */
const X509V3_EXT_METHOD ossl_v3_addr = {
    NID_sbgp_ipAddrBlock,       /* nid */
    0,                          /* flags */
    ASN1_ITEM_ref(IPAddrBlocks), /* template */
    0, 0, 0, 0,                 /* old functions, ignored */
    0,                          /* i2s */
    0,                          /* s2i */
    0,                          /* i2v */
    v2i_IPAddrBlocks,           /* v2i */
    i2r_IPAddrBlocks,           /* i2r */
    0,                          /* r2i */
    NULL                        /* extension-specific data */
};

/*
 * Figure out whether extension sues inheritance.
 */
int X509v3_addr_inherits(IPAddrBlocks *addr)
{
    int i;
    if (addr == NULL)
        return 0;
    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
        IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
        if (f->ipAddressChoice->type == IPAddressChoice_inherit)
            return 1;
    }
    return 0;
}

/*
 * Figure out whether parent contains child.
 */
static int addr_contains(IPAddressOrRanges *parent,
                         IPAddressOrRanges *child, int length)
{
    unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
    unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
    int p, c;

    if (child == NULL || parent == child)
        return 1;
    if (parent == NULL)
        return 0;

    p = 0;
    for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
        if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
                             c_min, c_max, length))
            return -1;
        for (;; p++) {
            if (p >= sk_IPAddressOrRange_num(parent))
                return 0;
            if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
                                 p_min, p_max, length))
                return 0;
            if (memcmp(p_max, c_max, length) < 0)
                continue;
            if (memcmp(p_min, c_min, length) > 0)
                return 0;
            break;
        }
    }

    return 1;
}

/*
 * Test whether a is a subset of b.
 */
int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
{
    int i;
    if (a == NULL || a == b)
        return 1;
    if (b == NULL || X509v3_addr_inherits(a) || X509v3_addr_inherits(b))
        return 0;
    (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
    for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
        IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
        int j = sk_IPAddressFamily_find(b, fa);
        IPAddressFamily *fb;
        fb = sk_IPAddressFamily_value(b, j);
        if (fb == NULL)
            return 0;
        if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges,
                           fa->ipAddressChoice->u.addressesOrRanges,
                           length_from_afi(X509v3_addr_get_afi(fb))))
            return 0;
    }
    return 1;
}

/*
 * Validation error handling via callback.
 */
#define validation_err(_err_)           \
  do {                                  \
    if (ctx != NULL) {                  \
      ctx->error = _err_;               \
      ctx->error_depth = i;             \
      ctx->current_cert = x;            \
      ret = ctx->verify_cb(0, ctx);     \
    } else {                            \
      ret = 0;                          \
    }                                   \
    if (!ret)                           \
      goto done;                        \
  } while (0)

/*
 * Core code for RFC 3779 2.3 path validation.
 *
 * Returns 1 for success, 0 on error.
 *
 * When returning 0, ctx->error MUST be set to an appropriate value other than
 * X509_V_OK.
 */
static int addr_validate_path_internal(X509_STORE_CTX *ctx,
                                       STACK_OF(X509) *chain,
                                       IPAddrBlocks *ext)
{
    IPAddrBlocks *child = NULL;
    int i, j, ret = 1;
    X509 *x;

    if (!ossl_assert(chain != NULL && sk_X509_num(chain) > 0)
            || !ossl_assert(ctx != NULL || ext != NULL)
            || !ossl_assert(ctx == NULL || ctx->verify_cb != NULL)) {
        if (ctx != NULL)
            ctx->error = X509_V_ERR_UNSPECIFIED;
        return 0;
    }

    /*
     * Figure out where to start.  If we don't have an extension to
     * check, we're done.  Otherwise, check canonical form and
     * set up for walking up the chain.
     */
    if (ext != NULL) {
        i = -1;
        x = NULL;
    } else {
        i = 0;
        x = sk_X509_value(chain, i);
        if ((ext = x->rfc3779_addr) == NULL)
            goto done;
    }
    if (!X509v3_addr_is_canonical(ext))
        validation_err(X509_V_ERR_INVALID_EXTENSION);
    (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
    if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
        ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
        if (ctx != NULL)
            ctx->error = X509_V_ERR_OUT_OF_MEM;
        ret = 0;
        goto done;
    }

    /*
     * Now walk up the chain.  No cert may list resources that its
     * parent doesn't list.
     */
    for (i++; i < sk_X509_num(chain); i++) {
        x = sk_X509_value(chain, i);
        if (!X509v3_addr_is_canonical(x->rfc3779_addr))
            validation_err(X509_V_ERR_INVALID_EXTENSION);
        if (x->rfc3779_addr == NULL) {
            for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
                IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
                if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
                    validation_err(X509_V_ERR_UNNESTED_RESOURCE);
                    break;
                }
            }
            continue;
        }
        (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr,
                                              IPAddressFamily_cmp);
        for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
            IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
            int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
            IPAddressFamily *fp =
                sk_IPAddressFamily_value(x->rfc3779_addr, k);
            if (fp == NULL) {
                if (fc->ipAddressChoice->type ==
                    IPAddressChoice_addressesOrRanges) {
                    validation_err(X509_V_ERR_UNNESTED_RESOURCE);
                    break;
                }
                continue;
            }
            if (fp->ipAddressChoice->type ==
                IPAddressChoice_addressesOrRanges) {
                if (fc->ipAddressChoice->type == IPAddressChoice_inherit
                    || addr_contains(fp->ipAddressChoice->u.addressesOrRanges,
                                     fc->ipAddressChoice->u.addressesOrRanges,
                                     length_from_afi(X509v3_addr_get_afi(fc))))
                    (void)sk_IPAddressFamily_set(child, j, fp);
                else
                    validation_err(X509_V_ERR_UNNESTED_RESOURCE);
            }
        }
    }

    /*
     * Trust anchor can't inherit.
     */
    if (x->rfc3779_addr != NULL) {
        for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
            IPAddressFamily *fp =
                sk_IPAddressFamily_value(x->rfc3779_addr, j);
            if (fp->ipAddressChoice->type == IPAddressChoice_inherit
                && sk_IPAddressFamily_find(child, fp) >= 0)
                validation_err(X509_V_ERR_UNNESTED_RESOURCE);
        }
    }

 done:
    sk_IPAddressFamily_free(child);
    return ret;
}

#undef validation_err

/*
 * RFC 3779 2.3 path validation -- called from X509_verify_cert().
 */
int X509v3_addr_validate_path(X509_STORE_CTX *ctx)
{
    if (ctx->chain == NULL
            || sk_X509_num(ctx->chain) == 0
            || ctx->verify_cb == NULL) {
        ctx->error = X509_V_ERR_UNSPECIFIED;
        return 0;
    }
    return addr_validate_path_internal(ctx, ctx->chain, NULL);
}

/*
 * RFC 3779 2.3 path validation of an extension.
 * Test whether chain covers extension.
 */
int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain,
                                  IPAddrBlocks *ext, int allow_inheritance)
{
    if (ext == NULL)
        return 1;
    if (chain == NULL || sk_X509_num(chain) == 0)
        return 0;
    if (!allow_inheritance && X509v3_addr_inherits(ext))
        return 0;
    return addr_validate_path_internal(NULL, chain, ext);
}

#endif                          /* OPENSSL_NO_RFC3779 */
