diff options
-rw-r--r-- | lib/libcrypto/x509v3/v3_addr.c | 2068 | ||||
-rw-r--r-- | lib/libcrypto/x509v3/v3_akey.c | 122 | ||||
-rw-r--r-- | lib/libcrypto/x509v3/v3_akeya.c | 2 | ||||
-rw-r--r-- | lib/libcrypto/x509v3/v3_alt.c | 517 | ||||
-rw-r--r-- | lib/libcrypto/x509v3/v3_asid.c | 1354 |
5 files changed, 2092 insertions, 1971 deletions
diff --git a/lib/libcrypto/x509v3/v3_addr.c b/lib/libcrypto/x509v3/v3_addr.c index 179f08d2222..084209f5a17 100644 --- a/lib/libcrypto/x509v3/v3_addr.c +++ b/lib/libcrypto/x509v3/v3_addr.c @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -76,28 +76,28 @@ */ ASN1_SEQUENCE(IPAddressRange) = { - ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), - ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) + 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_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_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_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) +ASN1_ITEM_TEMPLATE(IPAddrBlocks) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + IPAddrBlocks, IPAddressFamily) ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) @@ -113,54 +113,53 @@ IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) /* * What's the address length associated with this AFI? */ -static int length_from_afi(const unsigned 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; - } + 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 v3_addr_get_afi(const IPAddressFamily *f) +unsigned int +v3_addr_get_afi(const IPAddressFamily *f) { - return ((f != NULL && - f->addressFamily != NULL && - f->addressFamily->data != NULL) - ? ((f->addressFamily->data[0] << 8) | - (f->addressFamily->data[1])) - : 0); + return ((f != NULL && f->addressFamily != NULL && + f->addressFamily->data != NULL) ? + ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) : + 0); } /* * 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) +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; + 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; } /* @@ -171,145 +170,150 @@ static int addr_expand(unsigned char *addr, /* * i2r handler for one address bitstring. */ -static int i2r_address(BIO *out, - const unsigned afi, - const unsigned char fill, - const ASN1_BIT_STRING *bs) +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; + 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) +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; + 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) +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 = v3_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; + 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 = v3_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; } /* @@ -322,134 +326,151 @@ static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, * 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) +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; + 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() * comparision routines are only allowed two arguments. */ -static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a, - const IPAddressOrRange * const *b) +static int +v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a, + const IPAddressOrRange * const *b) { - return IPAddressOrRange_cmp(*a, *b, 4); + return IPAddressOrRange_cmp(*a, *b, 4); } /* * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() * comparision routines are only allowed two arguments. */ -static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a, - const IPAddressOrRange * const *b) +static int +v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a, + const IPAddressOrRange * const *b) { - return IPAddressOrRange_cmp(*a, *b, 16); + 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) +static int +range_should_be_prefix(const unsigned char *min, const unsigned char *max, + const int length) { - unsigned char mask; - int i, j; - - OPENSSL_assert(memcmp(min, max, length) <= 0); - 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; + unsigned char mask; + int i, j; + + OPENSSL_assert(memcmp(min, max, length) <= 0); + 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) +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; + 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; } /* @@ -457,252 +478,251 @@ static int make_addressPrefix(IPAddressOrRange **result, * 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) +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; - OPENSSL_assert(aor->u.addressRange == NULL); - 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; + 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; + OPENSSL_assert(aor->u.addressRange == NULL); + 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) +static IPAddressFamily * +make_IPAddressFamily(IPAddrBlocks *addr, const unsigned afi, + const unsigned *safi) { - IPAddressFamily *f; - unsigned char key[3]; - unsigned 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); - OPENSSL_assert(f->addressFamily->data != NULL); - 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; + IPAddressFamily *f; + unsigned char key[3]; + unsigned 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); + OPENSSL_assert(f->addressFamily->data != NULL); + 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 v3_addr_add_inherit(IPAddrBlocks *addr, - const unsigned afi, - const unsigned *safi) +int +v3_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; + 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) +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; + 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 v3_addr_add_prefix(IPAddrBlocks *addr, - const unsigned afi, - const unsigned *safi, - unsigned char *a, - const int prefixlen) +int +v3_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; + 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 v3_addr_add_range(IPAddrBlocks *addr, - const unsigned afi, - const unsigned *safi, - unsigned char *min, - unsigned char *max) +int +v3_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; + 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) +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; + 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 v3_addr_get_range(IPAddressOrRange *aor, - const unsigned afi, - unsigned char *min, - unsigned char *max, - const int length) +int +v3_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; + 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; } /* @@ -715,480 +735,513 @@ int v3_addr_get_range(IPAddressOrRange *aor, * 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_) +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; + 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 v3_addr_is_canonical(IPAddrBlocks *addr) +int +v3_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 cannonical. - */ - 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(v3_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; + 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 cannonical. + */ + 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; + } - /* - * 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; + /* + * 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(v3_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; + } + } + } - /* - * 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; + /* + * 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) +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]; - extract_min_max(a, a_min, a_max, length); - if (memcmp(a_min, a_max, length) > 0) - return 0; - } - } + 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]; + extract_min_max(a, a_min, a_max, length); + if (memcmp(a_min, a_max, length) > 0) + return 0; + } + } - return 1; + return 1; } /* * Whack an IPAddrBlocks extension into canonical form. */ -int v3_addr_canonize(IPAddrBlocks *addr) +int +v3_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, - v3_addr_get_afi(f))) - return 0; - } - (void) sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); - sk_IPAddressFamily_sort(addr); - OPENSSL_assert(v3_addr_is_canonical(addr)); - return 1; + 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, + v3_addr_get_afi(f))) + return 0; + } + (void) sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); + sk_IPAddressFamily_sort(addr); + OPENSSL_assert(v3_addr_is_canonical(addr)); + 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 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) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 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; - int prefixlen, i1, i2, delim, length; - - if ( !name_cmp(val->name, "IPv4")) { - afi = IANA_AFI_IPV4; - } else if (!name_cmp(val->name, "IPv6")) { - afi = IANA_AFI_IPV6; - } else if (!name_cmp(val->name, "IPv4-SAFI")) { - afi = IANA_AFI_IPV4; - safi = &safi_; - } else if (!name_cmp(val->name, "IPv6-SAFI")) { - afi = IANA_AFI_IPV6; - safi = &safi_; - } else { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_NAME_ERROR); - X509V3_conf_err(val); - 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 BUF_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++ != ':') { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); - X509V3_conf_err(val); - goto err; - } - t += strspn(t, " \t"); - s = BUF_strdup(t); - } else { - s = BUF_strdup(val->value); - } - if (s == NULL) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * Check for inheritance. Not worth additional complexity to - * optimize this (seldom-used) case. - */ - if (!strcmp(s, "inherit")) { - if (!v3_addr_add_inherit(addr, afi, safi)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_INHERITANCE); - X509V3_conf_err(val); - goto err; - } - free(s); - s = NULL; - continue; - } - - i1 = strspn(s, addr_chars); - i2 = i1 + strspn(s + i1, " \t"); - delim = s[i2++]; - s[i1] = '\0'; - - if (a2i_ipadd(min, s) != length) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); - X509V3_conf_err(val); - goto err; - } - - switch (delim) { - case '/': - prefixlen = (int) strtoul(s + i2, &t, 10); - if (t == s + i2 || *t != '\0') { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 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') { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (a2i_ipadd(max, s + i1) != length) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); - X509V3_conf_err(val); - goto err; - } - if (memcmp(min, max, length_from_afi(afi)) > 0) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (!v3_addr_add_range(addr, afi, safi, min, max)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); - goto err; - } - break; - case '\0': - if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); - goto err; - } - break; - default: - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - - free(s); - s = NULL; - } - - /* - * Canonize the result, then we're done. - */ - if (!v3_addr_canonize(addr)) - goto err; - return addr; - - err: - free(s); - sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); - return NULL; + 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) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, 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; + int prefixlen, i1, i2, delim, length; + + if (!name_cmp(val->name, "IPv4")) { + afi = IANA_AFI_IPV4; + } else if (!name_cmp(val->name, "IPv6")) { + afi = IANA_AFI_IPV6; + } else if (!name_cmp(val->name, "IPv4-SAFI")) { + afi = IANA_AFI_IPV4; + safi = &safi_; + } else if (!name_cmp(val->name, "IPv6-SAFI")) { + afi = IANA_AFI_IPV6; + safi = &safi_; + } else { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_err(val); + 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 BUF_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++ != ':') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_INVALID_SAFI); + X509V3_conf_err(val); + goto err; + } + t += strspn(t, " \t"); + s = BUF_strdup(t); + } else { + s = BUF_strdup(val->value); + } + if (s == NULL) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Check for inheritance. Not worth additional complexity to + * optimize this (seldom-used) case. + */ + if (!strcmp(s, "inherit")) { + if (!v3_addr_add_inherit(addr, afi, safi)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_INVALID_INHERITANCE); + X509V3_conf_err(val); + goto err; + } + free(s); + s = NULL; + continue; + } + + i1 = strspn(s, addr_chars); + i2 = i1 + strspn(s + i1, " \t"); + delim = s[i2++]; + s[i1] = '\0'; + + if (a2i_ipadd(min, s) != length) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_INVALID_IPADDRESS); + X509V3_conf_err(val); + goto err; + } + + switch (delim) { + case '/': + prefixlen = (int) strtoul(s + i2, &t, 10); + if (t == s + i2 || *t != '\0') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (!v3_addr_add_prefix(addr, afi, safi, min, + prefixlen)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + 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') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (a2i_ipadd(max, s + i1) != length) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_INVALID_IPADDRESS); + X509V3_conf_err(val); + goto err; + } + if (memcmp(min, max, length_from_afi(afi)) > 0) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (!v3_addr_add_range(addr, afi, safi, min, max)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + ERR_R_MALLOC_FAILURE); + goto err; + } + break; + case '\0': + if (!v3_addr_add_prefix(addr, afi, safi, min, + length * 8)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + ERR_R_MALLOC_FAILURE); + goto err; + } + break; + default: + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + + free(s); + s = NULL; + } + + /* + * Canonize the result, then we're done. + */ + if (!v3_addr_canonize(addr)) + goto err; + return addr; + +err: + free(s); + sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); + return NULL; } /* * OpenSSL dispatch */ const X509V3_EXT_METHOD 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 */ + 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 v3_addr_inherits(IPAddrBlocks *addr) +int +v3_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; + 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) +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; - } - } + 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; + return 1; } /* * Test whether a is a subset of b. */ -int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) +int +v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) { - int i; - if (a == NULL || a == b) - return 1; - if (b == NULL || v3_addr_inherits(a) || v3_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(v3_addr_get_afi(fb)))) - return 0; - } - return 1; + int i; + + if (a == NULL || a == b) + return 1; + if (b == NULL || v3_addr_inherits(a) || v3_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(v3_addr_get_afi(fb)))) + return 0; + } + return 1; } /* @@ -1211,101 +1264,115 @@ int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) /* * Core code for RFC 3779 2.3 path validation. */ -static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, - STACK_OF(X509) *chain, - IPAddrBlocks *ext) +static int +v3_addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, + IPAddrBlocks *ext) { - IPAddrBlocks *child = NULL; - int i, j, ret = 1; - X509 *x; - - OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); - OPENSSL_assert(ctx != NULL || ext != NULL); - OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); - - /* - * 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); - OPENSSL_assert(x != NULL); - if ((ext = x->rfc3779_addr) == NULL) - goto done; - } - if (!v3_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) { - X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE); - 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); - OPENSSL_assert(x != NULL); - if (!v3_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; + IPAddrBlocks *child = NULL; + int i, j, ret = 1; + X509 *x; + + OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); + OPENSSL_assert(ctx != NULL || ext != NULL); + OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); + + /* + * 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); + OPENSSL_assert(x != NULL); + if ((ext = x->rfc3779_addr) == NULL) + goto done; } - } - 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; + if (!v3_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) { + X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, + ERR_R_MALLOC_FAILURE); + ret = 0; + goto done; } - 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(v3_addr_get_afi(fc)))) - sk_IPAddressFamily_set(child, j, fp); - else - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - } - - /* - * Trust anchor can't inherit. - */ - OPENSSL_assert(x != NULL); - 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; + + /* + * 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); + OPENSSL_assert(x != NULL); + if (!v3_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(v3_addr_get_afi(fc)))) + sk_IPAddressFamily_set(child, j, fp); + else + validation_err( + X509_V_ERR_UNNESTED_RESOURCE); + } + } + } + + /* + * Trust anchor can't inherit. + */ + OPENSSL_assert(x != NULL); + 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 @@ -1313,26 +1380,27 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, /* * RFC 3779 2.3 path validation -- called from X509_verify_cert(). */ -int v3_addr_validate_path(X509_STORE_CTX *ctx) +int +v3_addr_validate_path(X509_STORE_CTX *ctx) { - return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); + return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); } /* * RFC 3779 2.3 path validation of an extension. * Test whether chain covers extension. */ -int v3_addr_validate_resource_set(STACK_OF(X509) *chain, - IPAddrBlocks *ext, - int allow_inheritance) +int +v3_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 && v3_addr_inherits(ext)) - return 0; - return v3_addr_validate_path_internal(NULL, chain, ext); + if (ext == NULL) + return 1; + if (chain == NULL || sk_X509_num(chain) == 0) + return 0; + if (!allow_inheritance && v3_addr_inherits(ext)) + return 0; + return v3_addr_validate_path_internal(NULL, chain, ext); } #endif /* OPENSSL_NO_RFC3779 */ diff --git a/lib/libcrypto/x509v3/v3_akey.c b/lib/libcrypto/x509v3/v3_akey.c index 04e1fb95442..6d5c576e23a 100644 --- a/lib/libcrypto/x509v3/v3_akey.c +++ b/lib/libcrypto/x509v3/v3_akey.c @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -64,36 +64,37 @@ #include <openssl/x509v3.h> static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist); + AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist); static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); -const X509V3_EXT_METHOD v3_akey_id = - { +const X509V3_EXT_METHOD v3_akey_id = { NID_authority_key_identifier, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID), - 0,0,0,0, - 0,0, + 0, 0,0, 0, + 0, 0, (X509V3_EXT_I2V)i2v_AUTHORITY_KEYID, (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, - 0,0, + 0, 0, NULL - }; +}; -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist) +static +STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist) { char *tmp; - if(akeyid->keyid) { + + if (akeyid->keyid) { tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length); X509V3_add_value("keyid", tmp, &extlist); free(tmp); } - if(akeyid->issuer) + if (akeyid->issuer) extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); - if(akeyid->serial) { + if (akeyid->serial) { tmp = hex_to_string(akeyid->serial->data, - akeyid->serial->length); + akeyid->serial->length); X509V3_add_value("serial", tmp, &extlist); free(tmp); } @@ -108,10 +109,11 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, * this is always included. */ -static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) - { - char keyid=0, issuer=0; +static AUTHORITY_KEYID * +v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + char keyid = 0, issuer = 0; int i; CONF_VALUE *cnf; ASN1_OCTET_STRING *ikeyid = NULL; @@ -123,76 +125,70 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509 *cert; AUTHORITY_KEYID *akeyid; - for(i = 0; i < sk_CONF_VALUE_num(values); i++) - { + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { cnf = sk_CONF_VALUE_value(values, i); - if(!strcmp(cnf->name, "keyid")) - { + if (!strcmp(cnf->name, "keyid")) { keyid = 1; - if(cnf->value && !strcmp(cnf->value, "always")) + if (cnf->value && !strcmp(cnf->value, "always")) keyid = 2; - } - else if(!strcmp(cnf->name, "issuer")) - { + } + else if (!strcmp(cnf->name, "issuer")) { issuer = 1; - if(cnf->value && !strcmp(cnf->value, "always")) + if (cnf->value && !strcmp(cnf->value, "always")) issuer = 2; - } - else - { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNKNOWN_OPTION); + } else { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNKNOWN_OPTION); ERR_add_error_data(2, "name=", cnf->name); return NULL; - } } + } - if(!ctx || !ctx->issuer_cert) - { - if(ctx && (ctx->flags==CTX_TEST)) + if (!ctx || !ctx->issuer_cert) { + if (ctx && (ctx->flags == CTX_TEST)) return AUTHORITY_KEYID_new(); - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_NO_ISSUER_CERTIFICATE); + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_NO_ISSUER_CERTIFICATE); return NULL; - } + } cert = ctx->issuer_cert; - if(keyid) - { + if (keyid) { i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); - if((i >= 0) && (ext = X509_get_ext(cert, i))) + if ((i >= 0) && (ext = X509_get_ext(cert, i))) ikeyid = X509V3_EXT_d2i(ext); - if(keyid==2 && !ikeyid) - { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); + if (keyid == 2 && !ikeyid) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); return NULL; - } } + } - if((issuer && !ikeyid) || (issuer == 2)) - { + if ((issuer && !ikeyid) || (issuer == 2)) { isname = X509_NAME_dup(X509_get_issuer_name(cert)); serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)); - if(!isname || !serial) - { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); + if (!isname || !serial) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); goto err; - } } + } - if(!(akeyid = AUTHORITY_KEYID_new())) goto err; + if (!(akeyid = AUTHORITY_KEYID_new())) + goto err; - if(isname) - { - if(!(gens = sk_GENERAL_NAME_new_null()) - || !(gen = GENERAL_NAME_new()) - || !sk_GENERAL_NAME_push(gens, gen)) - { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,ERR_R_MALLOC_FAILURE); + if (isname) { + if (!(gens = sk_GENERAL_NAME_new_null()) || + !(gen = GENERAL_NAME_new()) || + !sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + ERR_R_MALLOC_FAILURE); goto err; - } + } gen->type = GEN_DIRNAME; gen->d.dirn = isname; - } + } akeyid->issuer = gens; akeyid->serial = serial; @@ -200,9 +196,9 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, return akeyid; - err: +err: X509_NAME_free(isname); M_ASN1_INTEGER_free(serial); M_ASN1_OCTET_STRING_free(ikeyid); return NULL; - } +} diff --git a/lib/libcrypto/x509v3/v3_akeya.c b/lib/libcrypto/x509v3/v3_akeya.c index 2c50f7360eb..2bf84b4f1b8 100644 --- a/lib/libcrypto/x509v3/v3_akeya.c +++ b/lib/libcrypto/x509v3/v3_akeya.c @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in diff --git a/lib/libcrypto/x509v3/v3_alt.c b/lib/libcrypto/x509v3/v3_alt.c index 636677df94a..e61ed673c0c 100644 --- a/lib/libcrypto/x509v3/v3_alt.c +++ b/lib/libcrypto/x509v3/v3_alt.c @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -61,178 +61,181 @@ #include <openssl/conf.h> #include <openssl/x509v3.h> -static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); const X509V3_EXT_METHOD v3_alt[] = { -{ NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), -0,0,0,0, -0,0, -(X509V3_EXT_I2V)i2v_GENERAL_NAMES, -(X509V3_EXT_V2I)v2i_subject_alt, -NULL, NULL, NULL}, - -{ NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), -0,0,0,0, -0,0, -(X509V3_EXT_I2V)i2v_GENERAL_NAMES, -(X509V3_EXT_V2I)v2i_issuer_alt, -NULL, NULL, NULL}, - -{ NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), -0,0,0,0, -0,0, -(X509V3_EXT_I2V)i2v_GENERAL_NAMES, -NULL, NULL, NULL, NULL}, + { + NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + (X509V3_EXT_V2I)v2i_subject_alt, + NULL, NULL, NULL + }, + { + NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + (X509V3_EXT_V2I)v2i_issuer_alt, + NULL, NULL, NULL + }, + { + NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V)i2v_GENERAL_NAMES, + NULL, NULL, NULL, NULL + }, }; -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, - GENERAL_NAMES *gens, STACK_OF(CONF_VALUE) *ret) +STACK_OF(CONF_VALUE) * +i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, GENERAL_NAMES *gens, + STACK_OF(CONF_VALUE) *ret) { int i; GENERAL_NAME *gen; - for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { gen = sk_GENERAL_NAME_value(gens, i); ret = i2v_GENERAL_NAME(method, gen, ret); } - if(!ret) return sk_CONF_VALUE_new_null(); + if (!ret) + return sk_CONF_VALUE_new_null(); return ret; } -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, - GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret) +STACK_OF(CONF_VALUE) * +i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret) { unsigned char *p; char oline[256], htmp[5]; int i; - switch (gen->type) - { - case GEN_OTHERNAME: - X509V3_add_value("othername","<unsupported>", &ret); + + switch (gen->type) { + case GEN_OTHERNAME: + X509V3_add_value("othername", "<unsupported>", &ret); break; - case GEN_X400: - X509V3_add_value("X400Name","<unsupported>", &ret); + case GEN_X400: + X509V3_add_value("X400Name", "<unsupported>", &ret); break; - case GEN_EDIPARTY: - X509V3_add_value("EdiPartyName","<unsupported>", &ret); + case GEN_EDIPARTY: + X509V3_add_value("EdiPartyName", "<unsupported>", &ret); break; - case GEN_EMAIL: - X509V3_add_value_uchar("email",gen->d.ia5->data, &ret); + case GEN_EMAIL: + X509V3_add_value_uchar("email", gen->d.ia5->data, &ret); break; - case GEN_DNS: - X509V3_add_value_uchar("DNS",gen->d.ia5->data, &ret); + case GEN_DNS: + X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret); break; - case GEN_URI: - X509V3_add_value_uchar("URI",gen->d.ia5->data, &ret); + case GEN_URI: + X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret); break; - case GEN_DIRNAME: + case GEN_DIRNAME: X509_NAME_oneline(gen->d.dirn, oline, 256); - X509V3_add_value("DirName",oline, &ret); + X509V3_add_value("DirName", oline, &ret); break; - case GEN_IPADD: + case GEN_IPADD: p = gen->d.ip->data; - if(gen->d.ip->length == 4) + if (gen->d.ip->length == 4) (void) snprintf(oline, sizeof oline, - "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - else if(gen->d.ip->length == 16) - { + "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { oline[0] = 0; - for (i = 0; i < 8; i++) - { + for (i = 0; i < 8; i++) { (void) snprintf(htmp, sizeof htmp, - "%X", p[0] << 8 | p[1]); + "%X", p[0] << 8 | p[1]); p += 2; strlcat(oline, htmp, sizeof(oline)); if (i != 7) strlcat(oline, ":", sizeof(oline)); - } } - else - { - X509V3_add_value("IP Address","<invalid>", &ret); + } else { + X509V3_add_value("IP Address", "<invalid>", &ret); break; - } - X509V3_add_value("IP Address",oline, &ret); + } + X509V3_add_value("IP Address", oline, &ret); break; - case GEN_RID: + case GEN_RID: i2t_ASN1_OBJECT(oline, 256, gen->d.rid); - X509V3_add_value("Registered ID",oline, &ret); + X509V3_add_value("Registered ID", oline, &ret); break; } return ret; } -int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) +int +GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { unsigned char *p; int i; - switch (gen->type) - { - case GEN_OTHERNAME: + + switch (gen->type) { + case GEN_OTHERNAME: BIO_printf(out, "othername:<unsupported>"); break; - case GEN_X400: + case GEN_X400: BIO_printf(out, "X400Name:<unsupported>"); break; - case GEN_EDIPARTY: + case GEN_EDIPARTY: /* Maybe fix this: it is supported now */ BIO_printf(out, "EdiPartyName:<unsupported>"); break; - case GEN_EMAIL: - BIO_printf(out, "email:%s",gen->d.ia5->data); + case GEN_EMAIL: + BIO_printf(out, "email:%s", gen->d.ia5->data); break; - case GEN_DNS: - BIO_printf(out, "DNS:%s",gen->d.ia5->data); + case GEN_DNS: + BIO_printf(out, "DNS:%s", gen->d.ia5->data); break; - case GEN_URI: - BIO_printf(out, "URI:%s",gen->d.ia5->data); + case GEN_URI: + BIO_printf(out, "URI:%s", gen->d.ia5->data); break; - case GEN_DIRNAME: + case GEN_DIRNAME: BIO_printf(out, "DirName: "); X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); break; - case GEN_IPADD: + case GEN_IPADD: p = gen->d.ip->data; - if(gen->d.ip->length == 4) + if (gen->d.ip->length == 4) BIO_printf(out, "IP Address:%d.%d.%d.%d", - p[0], p[1], p[2], p[3]); - else if(gen->d.ip->length == 16) - { + p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { BIO_printf(out, "IP Address"); - for (i = 0; i < 8; i++) - { + for (i = 0; i < 8; i++) { BIO_printf(out, ":%X", p[0] << 8 | p[1]); p += 2; - } - BIO_puts(out, "\n"); } - else - { - BIO_printf(out,"IP Address:<invalid>"); + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "IP Address:<invalid>"); break; - } + } break; - case GEN_RID: + case GEN_RID: BIO_printf(out, "Registered ID"); i2a_ASN1_OBJECT(out, gen->d.rid); break; @@ -240,333 +243,348 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) return 1; } -static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +static GENERAL_NAMES * +v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) { GENERAL_NAMES *gens = NULL; CONF_VALUE *cnf; int i; - if(!(gens = sk_GENERAL_NAME_new_null())) { - X509V3err(X509V3_F_V2I_ISSUER_ALT,ERR_R_MALLOC_FAILURE); + + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); return NULL; } - for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { cnf = sk_CONF_VALUE_value(nval, i); - if(!name_cmp(cnf->name, "issuer") && cnf->value && - !strcmp(cnf->value, "copy")) { - if(!copy_issuer(ctx, gens)) goto err; + if (!name_cmp(cnf->name, "issuer") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_issuer(ctx, gens)) + goto err; } else { GENERAL_NAME *gen; - if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; sk_GENERAL_NAME_push(gens, gen); } } return gens; - err: + +err: sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); return NULL; } /* Append subject altname of issuer to issuer alt name of subject */ -static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) +static int +copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) { GENERAL_NAMES *ialt; GENERAL_NAME *gen; X509_EXTENSION *ext; int i; - if(ctx && (ctx->flags == CTX_TEST)) return 1; - if(!ctx || !ctx->issuer_cert) { - X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_NO_ISSUER_DETAILS); + + if (ctx && (ctx->flags == CTX_TEST)) + return 1; + if (!ctx || !ctx->issuer_cert) { + X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); goto err; } - i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); - if(i < 0) return 1; - if(!(ext = X509_get_ext(ctx->issuer_cert, i)) || - !(ialt = X509V3_EXT_d2i(ext)) ) { - X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_ISSUER_DECODE_ERROR); + i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); + if (i < 0) + return 1; + if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || + !(ialt = X509V3_EXT_d2i(ext))) { + X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); goto err; } - for(i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { + for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { gen = sk_GENERAL_NAME_value(ialt, i); - if(!sk_GENERAL_NAME_push(gens, gen)) { - X509V3err(X509V3_F_COPY_ISSUER,ERR_R_MALLOC_FAILURE); + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); goto err; } } sk_GENERAL_NAME_free(ialt); return 1; - - err: + +err: return 0; - + } -static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +static GENERAL_NAMES * +v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) { GENERAL_NAMES *gens = NULL; CONF_VALUE *cnf; int i; - if(!(gens = sk_GENERAL_NAME_new_null())) { - X509V3err(X509V3_F_V2I_SUBJECT_ALT,ERR_R_MALLOC_FAILURE); + + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); return NULL; } - for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { cnf = sk_CONF_VALUE_value(nval, i); - if(!name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "copy")) { - if(!copy_email(ctx, gens, 0)) goto err; - } else if(!name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "move")) { - if(!copy_email(ctx, gens, 1)) goto err; + if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_email(ctx, gens, 0)) + goto err; + } else if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "move")) { + if (!copy_email(ctx, gens, 1)) + goto err; } else { GENERAL_NAME *gen; - if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; sk_GENERAL_NAME_push(gens, gen); } } return gens; - err: + +err: sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); return NULL; } -/* Copy any email addresses in a certificate or request to +/* Copy any email addresses in a certificate or request to * GENERAL_NAMES */ -static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) +static int +copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) { X509_NAME *nm; ASN1_IA5STRING *email = NULL; X509_NAME_ENTRY *ne; GENERAL_NAME *gen = NULL; int i; - if(ctx != NULL && ctx->flags == CTX_TEST) + + if (ctx != NULL && ctx->flags == CTX_TEST) return 1; - if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) { - X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS); + if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); goto err; } /* Find the subject name */ - if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert); - else nm = X509_REQ_get_subject_name(ctx->subject_req); + if (ctx->subject_cert) + nm = X509_get_subject_name(ctx->subject_cert); + else + nm = X509_REQ_get_subject_name(ctx->subject_req); /* Now add any email address(es) to STACK */ i = -1; - while((i = X509_NAME_get_index_by_NID(nm, - NID_pkcs9_emailAddress, i)) >= 0) { + while ((i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i)) >= 0) { ne = X509_NAME_get_entry(nm, i); email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); - if (move_p) - { - X509_NAME_delete_entry(nm, i); + if (move_p) { + X509_NAME_delete_entry(nm, i); X509_NAME_ENTRY_free(ne); - i--; - } - if(!email || !(gen = GENERAL_NAME_new())) { - X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); + i--; + } + if (!email || !(gen = GENERAL_NAME_new())) { + X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); goto err; } gen->d.ia5 = email; email = NULL; gen->type = GEN_EMAIL; - if(!sk_GENERAL_NAME_push(gens, gen)) { - X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); goto err; } gen = NULL; } - return 1; - - err: + +err: GENERAL_NAME_free(gen); M_ASN1_IA5STRING_free(email); return 0; - } -GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +GENERAL_NAMES * +v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) { GENERAL_NAME *gen; GENERAL_NAMES *gens = NULL; CONF_VALUE *cnf; int i; - if(!(gens = sk_GENERAL_NAME_new_null())) { - X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); + + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); return NULL; } - for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { cnf = sk_CONF_VALUE_value(nval, i); - if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; sk_GENERAL_NAME_push(gens, gen); } return gens; - err: + +err: sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); return NULL; } -GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - CONF_VALUE *cnf) - { +GENERAL_NAME * +v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf) +{ return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); - } +} -GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - int gen_type, char *value, int is_nc) - { +GENERAL_NAME * +a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, char *value, int is_nc) +{ char is_string = 0; GENERAL_NAME *gen = NULL; - if(!value) - { - X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_MISSING_VALUE); + if (!value) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); return NULL; - } + } if (out) gen = out; - else - { + else { gen = GENERAL_NAME_new(); - if(gen == NULL) - { - X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); + if (gen == NULL) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + ERR_R_MALLOC_FAILURE); return NULL; - } } + } - switch (gen_type) - { - case GEN_URI: - case GEN_EMAIL: - case GEN_DNS: + switch (gen_type) { + case GEN_URI: + case GEN_EMAIL: + case GEN_DNS: is_string = 1; break; - - case GEN_RID: + + case GEN_RID: { - ASN1_OBJECT *obj; - if(!(obj = OBJ_txt2obj(value,0))) - { - X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_OBJECT); - ERR_add_error_data(2, "value=", value); - goto err; + ASN1_OBJECT *obj; + if (!(obj = OBJ_txt2obj(value, 0))) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", value); + goto err; } - gen->d.rid = obj; + gen->d.rid = obj; } break; - case GEN_IPADD: + case GEN_IPADD: if (is_nc) gen->d.ip = a2i_IPADDRESS_NC(value); else gen->d.ip = a2i_IPADDRESS(value); - if(gen->d.ip == NULL) - { - X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS); + if (gen->d.ip == NULL) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + X509V3_R_BAD_IP_ADDRESS); ERR_add_error_data(2, "value=", value); goto err; - } + } break; - case GEN_DIRNAME: - if (!do_dirname(gen, value, ctx)) - { - X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_DIRNAME_ERROR); + case GEN_DIRNAME: + if (!do_dirname(gen, value, ctx)) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + X509V3_R_DIRNAME_ERROR); goto err; - } + } break; - case GEN_OTHERNAME: - if (!do_othername(gen, value, ctx)) - { - X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_OTHERNAME_ERROR); + case GEN_OTHERNAME: + if (!do_othername(gen, value, ctx)) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + X509V3_R_OTHERNAME_ERROR); goto err; - } + } break; - default: - X509V3err(X509V3_F_A2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_TYPE); + + default: + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); goto err; - } + } - if(is_string) - { - if(!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || - !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value, - strlen(value))) - { - X509V3err(X509V3_F_A2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); + if (is_string) { + if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || + !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value, + strlen(value))) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, + ERR_R_MALLOC_FAILURE); goto err; - } } + } gen->type = gen_type; return gen; - err: +err: if (!out) GENERAL_NAME_free(gen); return NULL; - } +} -GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) - { +GENERAL_NAME * +v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) +{ int type; - char *name, *value; name = cnf->name; value = cnf->value; - if(!value) - { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_MISSING_VALUE); + if (!value) { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); return NULL; - } + } - if(!name_cmp(name, "email")) + if (!name_cmp(name, "email")) type = GEN_EMAIL; - else if(!name_cmp(name, "URI")) + else if (!name_cmp(name, "URI")) type = GEN_URI; - else if(!name_cmp(name, "DNS")) + else if (!name_cmp(name, "DNS")) type = GEN_DNS; - else if(!name_cmp(name, "RID")) + else if (!name_cmp(name, "RID")) type = GEN_RID; - else if(!name_cmp(name, "IP")) + else if (!name_cmp(name, "IP")) type = GEN_IPADD; - else if(!name_cmp(name, "dirName")) + else if (!name_cmp(name, "dirName")) type = GEN_DIRNAME; - else if(!name_cmp(name, "otherName")) + else if (!name_cmp(name, "otherName")) type = GEN_OTHERNAME; - else - { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX,X509V3_R_UNSUPPORTED_OPTION); + else { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, + X509V3_R_UNSUPPORTED_OPTION); ERR_add_error_data(2, "name=", name); return NULL; - } + } return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); +} - } - -static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) - { +static int +do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +{ char *objtmp = NULL, *p; int objlen; + if (!(p = strchr(value, ';'))) return 0; if (!(gen->d.otherName = OTHERNAME_new())) @@ -588,29 +606,30 @@ static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) if (!gen->d.otherName->type_id) return 0; return 1; - } +} -static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) - { +static int +do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +{ int ret; STACK_OF(CONF_VALUE) *sk; X509_NAME *nm; + if (!(nm = X509_NAME_new())) return 0; sk = X509V3_get_section(ctx, value); - if (!sk) - { - X509V3err(X509V3_F_DO_DIRNAME,X509V3_R_SECTION_NOT_FOUND); + if (!sk) { + X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); ERR_add_error_data(2, "section=", value); X509_NAME_free(nm); return 0; - } + } /* FIXME: should allow other character types... */ ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); if (!ret) X509_NAME_free(nm); gen->d.dirn = nm; X509V3_section_free(ctx, sk); - + return ret; - } +} diff --git a/lib/libcrypto/x509v3/v3_asid.c b/lib/libcrypto/x509v3/v3_asid.c index 325c8e04064..6335a31d197 100644 --- a/lib/libcrypto/x509v3/v3_asid.c +++ b/lib/libcrypto/x509v3/v3_asid.c @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -76,23 +76,23 @@ */ ASN1_SEQUENCE(ASRange) = { - ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), - ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) + ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), + ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) } ASN1_SEQUENCE_END(ASRange) ASN1_CHOICE(ASIdOrRange) = { - ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), - ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) + ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), + ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) } ASN1_CHOICE_END(ASIdOrRange) ASN1_CHOICE(ASIdentifierChoice) = { - ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), - ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) + ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), + ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) } ASN1_CHOICE_END(ASIdentifierChoice) ASN1_SEQUENCE(ASIdentifiers) = { - ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), - ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) + ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), + ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) } ASN1_SEQUENCE_END(ASIdentifiers) IMPLEMENT_ASN1_FUNCTIONS(ASRange) @@ -103,628 +103,662 @@ IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) /* * i2r method for an ASIdentifierChoice. */ -static int i2r_ASIdentifierChoice(BIO *out, - ASIdentifierChoice *choice, - int indent, - const char *msg) +static int +i2r_ASIdentifierChoice(BIO *out, ASIdentifierChoice *choice, int indent, + const char *msg) { - int i; - char *s; - if (choice == NULL) - return 1; - BIO_printf(out, "%*s%s:\n", indent, "", msg); - switch (choice->type) { - case ASIdentifierChoice_inherit: - BIO_printf(out, "%*sinherit\n", indent + 2, ""); - break; - case ASIdentifierChoice_asIdsOrRanges: - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) { - ASIdOrRange *aor = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - switch (aor->type) { - case ASIdOrRange_id: - if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL) - return 0; - BIO_printf(out, "%*s%s\n", indent + 2, "", s); - free(s); - break; - case ASIdOrRange_range: - if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL) - return 0; - BIO_printf(out, "%*s%s-", indent + 2, "", s); - free(s); - if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL) - return 0; - BIO_printf(out, "%s\n", s); - free(s); - break; - default: - return 0; - } - } - break; - default: - return 0; - } - return 1; + int i; + char *s; + + if (choice == NULL) + return 1; + BIO_printf(out, "%*s%s:\n", indent, "", msg); + switch (choice->type) { + case ASIdentifierChoice_inherit: + BIO_printf(out, "%*sinherit\n", indent + 2, ""); + break; + case ASIdentifierChoice_asIdsOrRanges: + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); + i++) { + ASIdOrRange *aor = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + switch (aor->type) { + case ASIdOrRange_id: + if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == + NULL) + return 0; + BIO_printf(out, "%*s%s\n", indent + 2, "", s); + free(s); + break; + case ASIdOrRange_range: + if ((s = i2s_ASN1_INTEGER(NULL, + aor->u.range->min)) == NULL) + return 0; + BIO_printf(out, "%*s%s-", indent + 2, "", s); + free(s); + if ((s = i2s_ASN1_INTEGER(NULL, + aor->u.range->max)) == NULL) + return 0; + BIO_printf(out, "%s\n", s); + free(s); + break; + default: + return 0; + } + } + break; + + default: + return 0; + } + return 1; } /* * i2r method for an ASIdentifier extension. */ -static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, - void *ext, - BIO *out, - int indent) +static int +i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, void *ext, BIO *out, + int indent) { - ASIdentifiers *asid = ext; - return (i2r_ASIdentifierChoice(out, asid->asnum, indent, - "Autonomous System Numbers") && - i2r_ASIdentifierChoice(out, asid->rdi, indent, - "Routing Domain Identifiers")); + ASIdentifiers *asid = ext; + + return (i2r_ASIdentifierChoice(out, asid->asnum, indent, + "Autonomous System Numbers") && + i2r_ASIdentifierChoice(out, asid->rdi, indent, + "Routing Domain Identifiers")); } /* * Sort comparision function for a sequence of ASIdOrRange elements. */ -static int ASIdOrRange_cmp(const ASIdOrRange * const *a_, - const ASIdOrRange * const *b_) +static int +ASIdOrRange_cmp(const ASIdOrRange * const *a_, const ASIdOrRange * const *b_) { - const ASIdOrRange *a = *a_, *b = *b_; + const ASIdOrRange *a = *a_, *b = *b_; - OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || - (a->type == ASIdOrRange_range && a->u.range != NULL && - a->u.range->min != NULL && a->u.range->max != NULL)); + OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || + (a->type == ASIdOrRange_range && a->u.range != NULL && + a->u.range->min != NULL && a->u.range->max != NULL)); - OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || - (b->type == ASIdOrRange_range && b->u.range != NULL && - b->u.range->min != NULL && b->u.range->max != NULL)); + OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || + (b->type == ASIdOrRange_range && b->u.range != NULL && + b->u.range->min != NULL && b->u.range->max != NULL)); - if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) - return ASN1_INTEGER_cmp(a->u.id, b->u.id); + if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) + return ASN1_INTEGER_cmp(a->u.id, b->u.id); - if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { - int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); - return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max); - } + if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { + int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); + return r != 0 ? r : + ASN1_INTEGER_cmp(a->u.range->max, b->u.range->max); + } - if (a->type == ASIdOrRange_id) - return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); - else - return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); + if (a->type == ASIdOrRange_id) + return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); + else + return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); } /* * Add an inherit element. */ -int v3_asid_add_inherit(ASIdentifiers *asid, int which) +int +v3_asid_add_inherit(ASIdentifiers *asid, int which) { - ASIdentifierChoice **choice; - if (asid == NULL) - return 0; - switch (which) { - case V3_ASID_ASNUM: - choice = &asid->asnum; - break; - case V3_ASID_RDI: - choice = &asid->rdi; - break; - default: - return 0; - } - if (*choice == NULL) { - if ((*choice = ASIdentifierChoice_new()) == NULL) - return 0; - OPENSSL_assert((*choice)->u.inherit == NULL); - if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) - return 0; - (*choice)->type = ASIdentifierChoice_inherit; - } - return (*choice)->type == ASIdentifierChoice_inherit; + ASIdentifierChoice **choice; + + if (asid == NULL) + return 0; + switch (which) { + case V3_ASID_ASNUM: + choice = &asid->asnum; + break; + case V3_ASID_RDI: + choice = &asid->rdi; + break; + default: + return 0; + } + if (*choice == NULL) { + if ((*choice = ASIdentifierChoice_new()) == NULL) + return 0; + OPENSSL_assert((*choice)->u.inherit == NULL); + if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) + return 0; + (*choice)->type = ASIdentifierChoice_inherit; + } + return (*choice)->type == ASIdentifierChoice_inherit; } /* * Add an ID or range to an ASIdentifierChoice. */ -int v3_asid_add_id_or_range(ASIdentifiers *asid, - int which, - ASN1_INTEGER *min, - ASN1_INTEGER *max) +int +v3_asid_add_id_or_range(ASIdentifiers *asid, int which, ASN1_INTEGER *min, + ASN1_INTEGER *max) { - ASIdentifierChoice **choice; - ASIdOrRange *aor; - if (asid == NULL) - return 0; - switch (which) { - case V3_ASID_ASNUM: - choice = &asid->asnum; - break; - case V3_ASID_RDI: - choice = &asid->rdi; - break; - default: - return 0; - } - if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) - return 0; - if (*choice == NULL) { - if ((*choice = ASIdentifierChoice_new()) == NULL) - return 0; - OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); - (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); - if ((*choice)->u.asIdsOrRanges == NULL) - return 0; - (*choice)->type = ASIdentifierChoice_asIdsOrRanges; - } - if ((aor = ASIdOrRange_new()) == NULL) - return 0; - if (max == NULL) { - aor->type = ASIdOrRange_id; - aor->u.id = min; - } else { - aor->type = ASIdOrRange_range; - if ((aor->u.range = ASRange_new()) == NULL) - goto err; - ASN1_INTEGER_free(aor->u.range->min); - aor->u.range->min = min; - ASN1_INTEGER_free(aor->u.range->max); - aor->u.range->max = max; - } - if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) - goto err; - return 1; - - err: - ASIdOrRange_free(aor); - return 0; + ASIdentifierChoice **choice; + ASIdOrRange *aor; + + if (asid == NULL) + return 0; + switch (which) { + case V3_ASID_ASNUM: + choice = &asid->asnum; + break; + case V3_ASID_RDI: + choice = &asid->rdi; + break; + default: + return 0; + } + if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) + return 0; + if (*choice == NULL) { + if ((*choice = ASIdentifierChoice_new()) == NULL) + return 0; + OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); + (*choice)->u.asIdsOrRanges = + sk_ASIdOrRange_new(ASIdOrRange_cmp); + if ((*choice)->u.asIdsOrRanges == NULL) + return 0; + (*choice)->type = ASIdentifierChoice_asIdsOrRanges; + } + if ((aor = ASIdOrRange_new()) == NULL) + return 0; + if (max == NULL) { + aor->type = ASIdOrRange_id; + aor->u.id = min; + } else { + aor->type = ASIdOrRange_range; + if ((aor->u.range = ASRange_new()) == NULL) + goto err; + ASN1_INTEGER_free(aor->u.range->min); + aor->u.range->min = min; + ASN1_INTEGER_free(aor->u.range->max); + aor->u.range->max = max; + } + if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) + goto err; + return 1; + +err: + ASIdOrRange_free(aor); + return 0; } /* * Extract min and max values from an ASIdOrRange. */ -static void extract_min_max(ASIdOrRange *aor, - ASN1_INTEGER **min, - ASN1_INTEGER **max) +static void +extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max) { - OPENSSL_assert(aor != NULL && min != NULL && max != NULL); - switch (aor->type) { - case ASIdOrRange_id: - *min = aor->u.id; - *max = aor->u.id; - return; - case ASIdOrRange_range: - *min = aor->u.range->min; - *max = aor->u.range->max; - return; - } + OPENSSL_assert(aor != NULL && min != NULL && max != NULL); + + switch (aor->type) { + case ASIdOrRange_id: + *min = aor->u.id; + *max = aor->u.id; + return; + case ASIdOrRange_range: + *min = aor->u.range->min; + *max = aor->u.range->max; + return; + } } /* * Check whether an ASIdentifierChoice is in canonical form. */ -static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) +static int +ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) { - ASN1_INTEGER *a_max_plus_one = NULL; - BIGNUM *bn = NULL; - int i, ret = 0; - - /* - * Empty element or inheritance is canonical. - */ - if (choice == NULL || choice->type == ASIdentifierChoice_inherit) - return 1; - - /* - * If not a list, or if empty list, it's broken. - */ - if (choice->type != ASIdentifierChoice_asIdsOrRanges || - sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) - return 0; - - /* - * It's a list, check it. - */ - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { - ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); - ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; - - extract_min_max(a, &a_min, &a_max); - extract_min_max(b, &b_min, &b_max); - - /* - * Punt misordered list, overlapping start, or inverted range. - */ - if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || - ASN1_INTEGER_cmp(a_min, a_max) > 0 || - ASN1_INTEGER_cmp(b_min, b_max) > 0) - goto done; - - /* - * Calculate a_max + 1 to check for adjacency. - */ - if ((bn == NULL && (bn = BN_new()) == NULL) || - ASN1_INTEGER_to_BN(a_max, bn) == NULL || - !BN_add_word(bn, 1) || - (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, - ERR_R_MALLOC_FAILURE); - goto done; - } - - /* - * Punt if adjacent or overlapping. - */ - if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) - goto done; - } - - /* - * Check for inverted range. - */ - i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; - { - ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - ASN1_INTEGER *a_min, *a_max; - if (a != NULL && a->type == ASIdOrRange_range) { - extract_min_max(a, &a_min, &a_max); - if (ASN1_INTEGER_cmp(a_min, a_max) > 0) - goto done; - } - } - - ret = 1; - - done: - ASN1_INTEGER_free(a_max_plus_one); - BN_free(bn); - return ret; + ASN1_INTEGER *a_max_plus_one = NULL; + BIGNUM *bn = NULL; + int i, ret = 0; + + /* + * Empty element or inheritance is canonical. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If not a list, or if empty list, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) + return 0; + + /* + * It's a list, check it. + */ + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { + ASIdOrRange *a = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASIdOrRange *b = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); + ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; + + extract_min_max(a, &a_min, &a_max); + extract_min_max(b, &b_min, &b_max); + + /* + * Punt misordered list, overlapping start, or inverted range. + */ + if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || + ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* + * Calculate a_max + 1 to check for adjacency. + */ + if ((bn == NULL && (bn = BN_new()) == NULL) || + ASN1_INTEGER_to_BN(a_max, bn) == NULL || + !BN_add_word(bn, 1) || (a_max_plus_one = + BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, + ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * Punt if adjacent or overlapping. + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) + goto done; + } + + /* + * Check for inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASN1_INTEGER *a_min, *a_max; + + if (a != NULL && a->type == ASIdOrRange_range) { + extract_min_max(a, &a_min, &a_max); + if (ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + + ret = 1; + +done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; } /* * Check whether an ASIdentifier extension is in canonical form. */ -int v3_asid_is_canonical(ASIdentifiers *asid) +int +v3_asid_is_canonical(ASIdentifiers *asid) { - return (asid == NULL || - (ASIdentifierChoice_is_canonical(asid->asnum) && - ASIdentifierChoice_is_canonical(asid->rdi))); + return (asid == NULL || + (ASIdentifierChoice_is_canonical(asid->asnum) && + ASIdentifierChoice_is_canonical(asid->rdi))); } /* * Whack an ASIdentifierChoice into canonical form. */ -static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) +static int +ASIdentifierChoice_canonize(ASIdentifierChoice *choice) { - ASN1_INTEGER *a_max_plus_one = NULL; - BIGNUM *bn = NULL; - int i, ret = 0; - - /* - * Nothing to do for empty element or inheritance. - */ - if (choice == NULL || choice->type == ASIdentifierChoice_inherit) - return 1; - - /* - * If not a list, or if empty list, it's broken. - */ - if (choice->type != ASIdentifierChoice_asIdsOrRanges || - sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - X509V3_R_EXTENSION_VALUE_ERROR); - return 0; - } - - /* - * We have a non-empty list. Sort it. - */ - sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); - - /* - * Now check for errors and suboptimal encoding, rejecting the - * former and fixing the latter. - */ - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { - ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); - ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; - - extract_min_max(a, &a_min, &a_max); - extract_min_max(b, &b_min, &b_max); - - /* - * Make sure we're properly sorted (paranoia). - */ - OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); - - /* - * Punt inverted ranges. - */ - if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || - ASN1_INTEGER_cmp(b_min, b_max) > 0) - goto done; - - /* - * Check for overlaps. - */ - if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + ASN1_INTEGER *a_max_plus_one = NULL; + BIGNUM *bn = NULL; + int i, ret = 0; + + /* + * Nothing to do for empty element or inheritance. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If not a list, or if empty list, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, X509V3_R_EXTENSION_VALUE_ERROR); - goto done; - } - - /* - * Calculate a_max + 1 to check for adjacency. - */ - if ((bn == NULL && (bn = BN_new()) == NULL) || - ASN1_INTEGER_to_BN(a_max, bn) == NULL || - !BN_add_word(bn, 1) || - (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, ERR_R_MALLOC_FAILURE); - goto done; - } - - /* - * If a and b are adjacent, merge them. - */ - if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { - ASRange *r; - switch (a->type) { - case ASIdOrRange_id: - if ((r = malloc(sizeof(ASRange))) == NULL) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - ERR_R_MALLOC_FAILURE); - goto done; + return 0; + } + + /* + * We have a non-empty list. Sort it. + */ + sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); + + /* + * Now check for errors and suboptimal encoding, rejecting the + * former and fixing the latter. + */ + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { + ASIdOrRange *a = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASIdOrRange *b = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); + ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; + + extract_min_max(a, &a_min, &a_max); + extract_min_max(b, &b_min, &b_max); + + /* + * Make sure we're properly sorted (paranoia). + */ + OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); + + /* + * Punt inverted ranges. + */ + if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* + * Check for overlaps. + */ + if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + X509V3_R_EXTENSION_VALUE_ERROR); + goto done; + } + + /* + * Calculate a_max + 1 to check for adjacency. + */ + if ((bn == NULL && (bn = BN_new()) == NULL) || + ASN1_INTEGER_to_BN(a_max, bn) == NULL || + !BN_add_word(bn, 1) || (a_max_plus_one = + BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * If a and b are adjacent, merge them. + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { + ASRange *r; + switch (a->type) { + case ASIdOrRange_id: + if ((r = malloc(sizeof(ASRange))) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + ERR_R_MALLOC_FAILURE); + goto done; + } + r->min = a_min; + r->max = b_max; + a->type = ASIdOrRange_range; + a->u.range = r; + break; + case ASIdOrRange_range: + ASN1_INTEGER_free(a->u.range->max); + a->u.range->max = b_max; + break; + } + switch (b->type) { + case ASIdOrRange_id: + b->u.id = NULL; + break; + case ASIdOrRange_range: + b->u.range->max = NULL; + break; + } + ASIdOrRange_free(b); + (void) sk_ASIdOrRange_delete( + choice->u.asIdsOrRanges, i + 1); + i--; + continue; + } + } + + /* + * Check for final inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + extract_min_max(a, &a_min, &a_max); + if (ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } } - r->min = a_min; - r->max = b_max; - a->type = ASIdOrRange_range; - a->u.range = r; - break; - case ASIdOrRange_range: - ASN1_INTEGER_free(a->u.range->max); - a->u.range->max = b_max; - break; - } - switch (b->type) { - case ASIdOrRange_id: - b->u.id = NULL; - break; - case ASIdOrRange_range: - b->u.range->max = NULL; - break; - } - ASIdOrRange_free(b); - (void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); - i--; - continue; - } - } - - /* - * Check for final inverted range. - */ - i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; - { - ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - ASN1_INTEGER *a_min, *a_max; - if (a != NULL && a->type == ASIdOrRange_range) { - extract_min_max(a, &a_min, &a_max); - if (ASN1_INTEGER_cmp(a_min, a_max) > 0) - goto done; - } - } - - OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ - - ret = 1; - - done: - ASN1_INTEGER_free(a_max_plus_one); - BN_free(bn); - return ret; + + OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ + + ret = 1; + +done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; } /* * Whack an ASIdentifier extension into canonical form. */ -int v3_asid_canonize(ASIdentifiers *asid) +int +v3_asid_canonize(ASIdentifiers *asid) { - return (asid == NULL || - (ASIdentifierChoice_canonize(asid->asnum) && - ASIdentifierChoice_canonize(asid->rdi))); + return (asid == NULL || + (ASIdentifierChoice_canonize(asid->asnum) && + ASIdentifierChoice_canonize(asid->rdi))); } /* * v2i method for an ASIdentifier extension. */ -static void *v2i_ASIdentifiers(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, - STACK_OF(CONF_VALUE) *values) +static void * +v2i_ASIdentifiers(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values) { - ASN1_INTEGER *min = NULL, *max = NULL; - ASIdentifiers *asid = NULL; - int i; - - if ((asid = ASIdentifiers_new()) == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, 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); - int i1, i2, i3, is_range, which; - - /* - * Figure out whether this is an AS or an RDI. - */ - if ( !name_cmp(val->name, "AS")) { - which = V3_ASID_ASNUM; - } else if (!name_cmp(val->name, "RDI")) { - which = V3_ASID_RDI; - } else { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_NAME_ERROR); - X509V3_conf_err(val); - goto err; - } - - /* - * Handle inheritance. - */ - if (!strcmp(val->value, "inherit")) { - if (v3_asid_add_inherit(asid, which)) - continue; - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_INHERITANCE); - X509V3_conf_err(val); - goto err; - } - - /* - * Number, range, or mistake, pick it apart and figure out which. - */ - i1 = strspn(val->value, "0123456789"); - if (val->value[i1] == '\0') { - is_range = 0; - } else { - is_range = 1; - i2 = i1 + strspn(val->value + i1, " \t"); - if (val->value[i2] != '-') { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASNUMBER); - X509V3_conf_err(val); - goto err; - } - i2++; - i2 = i2 + strspn(val->value + i2, " \t"); - i3 = i2 + strspn(val->value + i2, "0123456789"); - if (val->value[i3] != '\0') { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_INVALID_ASRANGE); - X509V3_conf_err(val); - goto err; - } - } - - /* - * Syntax is ok, read and add it. - */ - if (!is_range) { - if (!X509V3_get_value_int(val, &min)) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - goto err; - } - } else { - char *s = BUF_strdup(val->value); - if (s == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - goto err; - } - s[i1] = '\0'; - min = s2i_ASN1_INTEGER(NULL, s); - max = s2i_ASN1_INTEGER(NULL, s + i2); - free(s); - if (min == NULL || max == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - goto err; - } - if (ASN1_INTEGER_cmp(min, max) > 0) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_VALUE_ERROR); - goto err; - } - } - if (!v3_asid_add_id_or_range(asid, which, min, max)) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - goto err; - } - min = max = NULL; - } - - /* - * Canonize the result, then we're done. - */ - if (!v3_asid_canonize(asid)) - goto err; - return asid; - - err: - ASIdentifiers_free(asid); - ASN1_INTEGER_free(min); - ASN1_INTEGER_free(max); - return NULL; + ASN1_INTEGER *min = NULL, *max = NULL; + ASIdentifiers *asid = NULL; + int i; + + if ((asid = ASIdentifiers_new()) == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, 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); + int i1, i2, i3, is_range, which; + + /* + * Figure out whether this is an AS or an RDI. + */ + if (!name_cmp(val->name, "AS")) { + which = V3_ASID_ASNUM; + } else if (!name_cmp(val->name, "RDI")) { + which = V3_ASID_RDI; + } else { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_err(val); + goto err; + } + + /* + * Handle inheritance. + */ + if (!strcmp(val->value, "inherit")) { + if (v3_asid_add_inherit(asid, which)) + continue; + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_INHERITANCE); + X509V3_conf_err(val); + goto err; + } + + /* + * Number, range, or mistake, pick it apart and figure out which. + */ + i1 = strspn(val->value, "0123456789"); + if (val->value[i1] == '\0') { + is_range = 0; + } else { + is_range = 1; + i2 = i1 + strspn(val->value + i1, " \t"); + if (val->value[i2] != '-') { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_ASNUMBER); + X509V3_conf_err(val); + goto err; + } + i2++; + i2 = i2 + strspn(val->value + i2, " \t"); + i3 = i2 + strspn(val->value + i2, "0123456789"); + if (val->value[i3] != '\0') { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_ASRANGE); + X509V3_conf_err(val); + goto err; + } + } + + /* + * Syntax is ok, read and add it. + */ + if (!is_range) { + if (!X509V3_get_value_int(val, &min)) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + char *s = BUF_strdup(val->value); + if (s == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + ERR_R_MALLOC_FAILURE); + goto err; + } + s[i1] = '\0'; + min = s2i_ASN1_INTEGER(NULL, s); + max = s2i_ASN1_INTEGER(NULL, s + i2); + free(s); + if (min == NULL || max == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (ASN1_INTEGER_cmp(min, max) > 0) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_EXTENSION_VALUE_ERROR); + goto err; + } + } + if (!v3_asid_add_id_or_range(asid, which, min, max)) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + ERR_R_MALLOC_FAILURE); + goto err; + } + min = max = NULL; + } + + /* + * Canonize the result, then we're done. + */ + if (!v3_asid_canonize(asid)) + goto err; + return asid; + +err: + ASIdentifiers_free(asid); + ASN1_INTEGER_free(min); + ASN1_INTEGER_free(max); + return NULL; } /* * OpenSSL dispatch. */ const X509V3_EXT_METHOD v3_asid = { - NID_sbgp_autonomousSysNum, /* nid */ - 0, /* flags */ - ASN1_ITEM_ref(ASIdentifiers), /* template */ - 0, 0, 0, 0, /* old functions, ignored */ - 0, /* i2s */ - 0, /* s2i */ - 0, /* i2v */ - v2i_ASIdentifiers, /* v2i */ - i2r_ASIdentifiers, /* i2r */ - 0, /* r2i */ - NULL /* extension-specific data */ + NID_sbgp_autonomousSysNum, /* nid */ + 0, /* flags */ + ASN1_ITEM_ref(ASIdentifiers), /* template */ + 0, 0, 0, 0, /* old functions, ignored */ + 0, /* i2s */ + 0, /* s2i */ + 0, /* i2v */ + v2i_ASIdentifiers, /* v2i */ + i2r_ASIdentifiers, /* i2r */ + 0, /* r2i */ + NULL /* extension-specific data */ }; /* * Figure out whether extension uses inheritance. */ -int v3_asid_inherits(ASIdentifiers *asid) +int +v3_asid_inherits(ASIdentifiers *asid) { - return (asid != NULL && - ((asid->asnum != NULL && + return (asid != NULL && + ((asid->asnum != NULL && asid->asnum->type == ASIdentifierChoice_inherit) || - (asid->rdi != NULL && + (asid->rdi != NULL && asid->rdi->type == ASIdentifierChoice_inherit))); } /* * Figure out whether parent contains child. */ -static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) +static int +asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) { - ASN1_INTEGER *p_min, *p_max, *c_min, *c_max; - int p, c; - - if (child == NULL || parent == child) - return 1; - if (parent == NULL) - return 0; - - p = 0; - for (c = 0; c < sk_ASIdOrRange_num(child); c++) { - extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max); - for (;; p++) { - if (p >= sk_ASIdOrRange_num(parent)) - return 0; - extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max); - if (ASN1_INTEGER_cmp(p_max, c_max) < 0) - continue; - if (ASN1_INTEGER_cmp(p_min, c_min) > 0) - return 0; - break; - } - } + ASN1_INTEGER *p_min, *p_max, *c_min, *c_max; + int p, c; + + if (child == NULL || parent == child) + return 1; + if (parent == NULL) + return 0; + + p = 0; + for (c = 0; c < sk_ASIdOrRange_num(child); c++) { + extract_min_max(sk_ASIdOrRange_value(child, c), + &c_min, &c_max); + for (; ; p++) { + if (p >= sk_ASIdOrRange_num(parent)) + return 0; + extract_min_max(sk_ASIdOrRange_value(parent, p), + &p_min, &p_max); + if (ASN1_INTEGER_cmp(p_max, c_max) < 0) + continue; + if (ASN1_INTEGER_cmp(p_min, c_min) > 0) + return 0; + break; + } + } - return 1; + return 1; } /* * Test whether a is a subet of b. */ -int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) +int +v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) { - return (a == NULL || - a == b || - (b != NULL && - !v3_asid_inherits(a) && - !v3_asid_inherits(b) && - asid_contains(b->asnum->u.asIdsOrRanges, - a->asnum->u.asIdsOrRanges) && - asid_contains(b->rdi->u.asIdsOrRanges, - a->rdi->u.asIdsOrRanges))); + return (a == NULL || a == b || + (b != NULL && !v3_asid_inherits(a) && !v3_asid_inherits(b) && + asid_contains(b->asnum->u.asIdsOrRanges, + a->asnum->u.asIdsOrRanges) && + asid_contains(b->rdi->u.asIdsOrRanges, + a->rdi->u.asIdsOrRanges))); } /* @@ -747,117 +781,120 @@ int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) /* * Core code for RFC 3779 3.3 path validation. */ -static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, - STACK_OF(X509) *chain, - ASIdentifiers *ext) +static int +v3_asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, + ASIdentifiers *ext) { - ASIdOrRanges *child_as = NULL, *child_rdi = NULL; - int i, ret = 1, inherit_as = 0, inherit_rdi = 0; - X509 *x; - - OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); - OPENSSL_assert(ctx != NULL || ext != NULL); - OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); - - /* - * 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); - OPENSSL_assert(x != NULL); - if ((ext = x->rfc3779_asid) == NULL) - goto done; - } - if (!v3_asid_is_canonical(ext)) - validation_err(X509_V_ERR_INVALID_EXTENSION); - if (ext->asnum != NULL) { - switch (ext->asnum->type) { - case ASIdentifierChoice_inherit: - inherit_as = 1; - break; - case ASIdentifierChoice_asIdsOrRanges: - child_as = ext->asnum->u.asIdsOrRanges; - break; - } - } - if (ext->rdi != NULL) { - switch (ext->rdi->type) { - case ASIdentifierChoice_inherit: - inherit_rdi = 1; - break; - case ASIdentifierChoice_asIdsOrRanges: - child_rdi = ext->rdi->u.asIdsOrRanges; - break; - } - } - - /* - * Now walk up the chain. Extensions must be in canonical form, 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); - OPENSSL_assert(x != NULL); - if (x->rfc3779_asid == NULL) { - if (child_as != NULL || child_rdi != NULL) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - continue; - } - if (!v3_asid_is_canonical(x->rfc3779_asid)) - validation_err(X509_V_ERR_INVALID_EXTENSION); - if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - child_as = NULL; - inherit_as = 0; - } - if (x->rfc3779_asid->asnum != NULL && - x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) { - if (inherit_as || - asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as)) { - child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; - inherit_as = 0; - } else { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - child_rdi = NULL; - inherit_rdi = 0; - } - if (x->rfc3779_asid->rdi != NULL && - x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { - if (inherit_rdi || - asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) { - child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; - inherit_rdi = 0; - } else { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - } - - /* - * Trust anchor can't inherit. - */ - OPENSSL_assert(x != NULL); - if (x->rfc3779_asid != NULL) { - if (x->rfc3779_asid->asnum != NULL && - x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - if (x->rfc3779_asid->rdi != NULL && - x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - - done: - return ret; + ASIdOrRanges *child_as = NULL, *child_rdi = NULL; + int i, ret = 1, inherit_as = 0, inherit_rdi = 0; + X509 *x; + + OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); + OPENSSL_assert(ctx != NULL || ext != NULL); + OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); + + /* + * 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); + OPENSSL_assert(x != NULL); + if ((ext = x->rfc3779_asid) == NULL) + goto done; + } + if (!v3_asid_is_canonical(ext)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (ext->asnum != NULL) { + switch (ext->asnum->type) { + case ASIdentifierChoice_inherit: + inherit_as = 1; + break; + case ASIdentifierChoice_asIdsOrRanges: + child_as = ext->asnum->u.asIdsOrRanges; + break; + } + } + if (ext->rdi != NULL) { + switch (ext->rdi->type) { + case ASIdentifierChoice_inherit: + inherit_rdi = 1; + break; + case ASIdentifierChoice_asIdsOrRanges: + child_rdi = ext->rdi->u.asIdsOrRanges; + break; + } + } + + /* + * Now walk up the chain. Extensions must be in canonical form, 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); + OPENSSL_assert(x != NULL); + if (x->rfc3779_asid == NULL) { + if (child_as != NULL || child_rdi != NULL) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + continue; + } + if (!v3_asid_is_canonical(x->rfc3779_asid)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + child_as = NULL; + inherit_as = 0; + } + if (x->rfc3779_asid->asnum != NULL && + x->rfc3779_asid->asnum->type == + ASIdentifierChoice_asIdsOrRanges) { + if (inherit_as || asid_contains( + x->rfc3779_asid->asnum->u.asIdsOrRanges, + child_as)) { + child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; + inherit_as = 0; + } else { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + child_rdi = NULL; + inherit_rdi = 0; + } + if (x->rfc3779_asid->rdi != NULL && + x->rfc3779_asid->rdi->type == + ASIdentifierChoice_asIdsOrRanges) { + if (inherit_rdi || asid_contains( + x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi)) { + child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; + inherit_rdi = 0; + } else { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + } + + /* + * Trust anchor can't inherit. + */ + OPENSSL_assert(x != NULL); + if (x->rfc3779_asid != NULL) { + if (x->rfc3779_asid->asnum != NULL && + x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + if (x->rfc3779_asid->rdi != NULL && + x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + +done: + return ret; } #undef validation_err @@ -865,26 +902,27 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, /* * RFC 3779 3.3 path validation -- called from X509_verify_cert(). */ -int v3_asid_validate_path(X509_STORE_CTX *ctx) +int +v3_asid_validate_path(X509_STORE_CTX *ctx) { - return v3_asid_validate_path_internal(ctx, ctx->chain, NULL); + return v3_asid_validate_path_internal(ctx, ctx->chain, NULL); } /* * RFC 3779 3.3 path validation of an extension. * Test whether chain covers extension. */ -int v3_asid_validate_resource_set(STACK_OF(X509) *chain, - ASIdentifiers *ext, - int allow_inheritance) +int +v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext, + int allow_inheritance) { - if (ext == NULL) - return 1; - if (chain == NULL || sk_X509_num(chain) == 0) - return 0; - if (!allow_inheritance && v3_asid_inherits(ext)) - return 0; - return v3_asid_validate_path_internal(NULL, chain, ext); + if (ext == NULL) + return 1; + if (chain == NULL || sk_X509_num(chain) == 0) + return 0; + if (!allow_inheritance && v3_asid_inherits(ext)) + return 0; + return v3_asid_validate_path_internal(NULL, chain, ext); } #endif /* OPENSSL_NO_RFC3779 */ |