diff options
author | jkim <jkim@FreeBSD.org> | 2012-06-27 18:44:36 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2012-06-27 18:44:36 +0000 |
commit | 299ab12592ee76c1d23012fb680eb3de3047a332 (patch) | |
tree | eec54a5ed50326dd4ab254bab7df3b566651ac6d /crypto/openssl/crypto/x509v3 | |
parent | a461bd15071993dd2121ed8ddfaee9fef880cd56 (diff) | |
download | FreeBSD-src-299ab12592ee76c1d23012fb680eb3de3047a332.zip FreeBSD-src-299ab12592ee76c1d23012fb680eb3de3047a332.tar.gz |
Merge OpenSSL 0.9.8x.
Reviewed by: stas
Approved by: benl (maintainer)
MFC after: 3 days
Diffstat (limited to 'crypto/openssl/crypto/x509v3')
-rw-r--r-- | crypto/openssl/crypto/x509v3/v3_addr.c | 111 | ||||
-rw-r--r-- | crypto/openssl/crypto/x509v3/v3_asid.c | 90 |
2 files changed, 149 insertions, 52 deletions
diff --git a/crypto/openssl/crypto/x509v3/v3_addr.c b/crypto/openssl/crypto/x509v3/v3_addr.c index efdf7c3..c0e1d2d 100644 --- a/crypto/openssl/crypto/x509v3/v3_addr.c +++ b/crypto/openssl/crypto/x509v3/v3_addr.c @@ -142,12 +142,13 @@ unsigned int v3_addr_get_afi(const IPAddressFamily *f) * Expand the bitstring form of an address into a raw byte array. * At the moment this is coded for simplicity, not speed. */ -static void addr_expand(unsigned char *addr, +static int addr_expand(unsigned char *addr, const ASN1_BIT_STRING *bs, const int length, const unsigned char fill) { - OPENSSL_assert(bs->length >= 0 && bs->length <= length); + if (bs->length < 0 || bs->length > length) + return 0; if (bs->length > 0) { memcpy(addr, bs->data, bs->length); if ((bs->flags & 7) != 0) { @@ -159,6 +160,7 @@ static void addr_expand(unsigned char *addr, } } memset(addr + bs->length, fill, length - bs->length); + return 1; } /* @@ -177,13 +179,17 @@ static int i2r_address(BIO *out, unsigned char addr[ADDR_RAW_BUF_LEN]; int i, n; + if (bs->length < 0) + return 0; switch (afi) { case IANA_AFI_IPV4: - addr_expand(addr, bs, 4, fill); + 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: - addr_expand(addr, bs, 16, fill); + 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) @@ -309,6 +315,12 @@ static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method, /* * Sort comparison function for a sequence of IPAddressOrRange * elements. + * + * There's no sane answer we can give if addr_expand() fails, and an + * assertion failure on externally supplied data is seriously uncool, + * so we just arbitrarily declare that if given invalid inputs this + * function returns -1. If this messes up your preferred sort order + * for garbage input, tough noogies. */ static int IPAddressOrRange_cmp(const IPAddressOrRange *a, const IPAddressOrRange *b, @@ -321,22 +333,26 @@ static int IPAddressOrRange_cmp(const IPAddressOrRange *a, switch (a->type) { case IPAddressOrRange_addressPrefix: - addr_expand(addr_a, a->u.addressPrefix, length, 0x00); + if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) + return -1; prefixlen_a = addr_prefixlen(a->u.addressPrefix); break; case IPAddressOrRange_addressRange: - addr_expand(addr_a, a->u.addressRange->min, length, 0x00); + if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) + return -1; prefixlen_a = length * 8; break; } switch (b->type) { case IPAddressOrRange_addressPrefix: - addr_expand(addr_b, b->u.addressPrefix, length, 0x00); + if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) + return -1; prefixlen_b = addr_prefixlen(b->u.addressPrefix); break; case IPAddressOrRange_addressRange: - addr_expand(addr_b, b->u.addressRange->min, length, 0x00); + if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) + return -1; prefixlen_b = length * 8; break; } @@ -378,6 +394,7 @@ static int range_should_be_prefix(const unsigned char *min, 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--) @@ -651,22 +668,22 @@ int v3_addr_add_range(IPAddrBlocks *addr, /* * Extract min and max values from an IPAddressOrRange. */ -static void extract_min_max(IPAddressOrRange *aor, +static int extract_min_max(IPAddressOrRange *aor, unsigned char *min, unsigned char *max, int length) { - OPENSSL_assert(aor != NULL && min != NULL && max != NULL); + if (aor == NULL || min == NULL || max == NULL) + return 0; switch (aor->type) { case IPAddressOrRange_addressPrefix: - addr_expand(min, aor->u.addressPrefix, length, 0x00); - addr_expand(max, aor->u.addressPrefix, length, 0xFF); - return; + return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && + addr_expand(max, aor->u.addressPrefix, length, 0xFF)); case IPAddressOrRange_addressRange: - addr_expand(min, aor->u.addressRange->min, length, 0x00); - addr_expand(max, aor->u.addressRange->max, length, 0xFF); - return; + return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && + addr_expand(max, aor->u.addressRange->max, length, 0xFF)); } + return 0; } /* @@ -682,9 +699,10 @@ int v3_addr_get_range(IPAddressOrRange *aor, if (aor == NULL || min == NULL || max == NULL || afi_length == 0 || length < afi_length || (aor->type != IPAddressOrRange_addressPrefix && - aor->type != IPAddressOrRange_addressRange)) + aor->type != IPAddressOrRange_addressRange) || + !extract_min_max(aor, min, max, afi_length)) return 0; - extract_min_max(aor, min, max, afi_length); + return afi_length; } @@ -766,8 +784,9 @@ int v3_addr_is_canonical(IPAddrBlocks *addr) IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); - extract_min_max(a, a_min, a_max, length); - extract_min_max(b, b_min, b_max, length); + 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. @@ -795,14 +814,17 @@ int v3_addr_is_canonical(IPAddrBlocks *addr) } /* - * Check final range to see if it should be a prefix. + * 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->type == IPAddressOrRange_addressRange) { - extract_min_max(a, a_min, a_max, length); - if (range_should_be_prefix(a_min, a_max, length) >= 0) + 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; } } @@ -836,8 +858,16 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, 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]; - extract_min_max(a, a_min, a_max, length); - extract_min_max(b, b_min, b_max, length); + 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. @@ -864,6 +894,20 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, } } + /* + * 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; } @@ -1012,6 +1056,11 @@ static void *v2i_IPAddrBlocks(struct v3_ext_method *method, 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; @@ -1097,13 +1146,15 @@ static int addr_contains(IPAddressOrRanges *parent, p = 0; for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { - extract_min_max(sk_IPAddressOrRange_value(child, c), - c_min, c_max, length); + 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; - extract_min_max(sk_IPAddressOrRange_value(parent, p), - p_min, p_max, length); + 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) diff --git a/crypto/openssl/crypto/x509v3/v3_asid.c b/crypto/openssl/crypto/x509v3/v3_asid.c index abd497e..11aad0b 100644 --- a/crypto/openssl/crypto/x509v3/v3_asid.c +++ b/crypto/openssl/crypto/x509v3/v3_asid.c @@ -61,7 +61,6 @@ #include <stdio.h> #include <string.h> -#include <assert.h> #include "cryptlib.h" #include <openssl/conf.h> #include <openssl/asn1.h> @@ -172,11 +171,11 @@ static int ASIdOrRange_cmp(const ASIdOrRange * const *a_, { const ASIdOrRange *a = *a_, *b = *b_; - assert((a->type == ASIdOrRange_id && a->u.id != 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)); - assert((b->type == ASIdOrRange_id && b->u.id != 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)); @@ -215,7 +214,7 @@ int v3_asid_add_inherit(ASIdentifiers *asid, int which) if (*choice == NULL) { if ((*choice = ASIdentifierChoice_new()) == NULL) return 0; - assert((*choice)->u.inherit == NULL); + OPENSSL_assert((*choice)->u.inherit == NULL); if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) return 0; (*choice)->type = ASIdentifierChoice_inherit; @@ -250,7 +249,7 @@ int v3_asid_add_id_or_range(ASIdentifiers *asid, if (*choice == NULL) { if ((*choice = ASIdentifierChoice_new()) == NULL) return 0; - assert((*choice)->u.asIdsOrRanges == NULL); + OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); if ((*choice)->u.asIdsOrRanges == NULL) return 0; @@ -286,7 +285,7 @@ static void extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max) { - assert(aor != NULL && min != NULL && max != NULL); + OPENSSL_assert(aor != NULL && min != NULL && max != NULL); switch (aor->type) { case ASIdOrRange_id: *min = aor->u.id; @@ -359,6 +358,20 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) 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: @@ -373,7 +386,7 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) int v3_asid_is_canonical(ASIdentifiers *asid) { return (asid == NULL || - (ASIdentifierChoice_is_canonical(asid->asnum) || + (ASIdentifierChoice_is_canonical(asid->asnum) && ASIdentifierChoice_is_canonical(asid->rdi))); } @@ -393,9 +406,18 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) return 1; /* - * We have a list. Sort it. + * 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. */ - assert(choice->type == ASIdentifierChoice_asIdsOrRanges); sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); /* @@ -413,7 +435,14 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) /* * Make sure we're properly sorted (paranoia). */ - assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); + 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. @@ -466,13 +495,27 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) break; } ASIdOrRange_free(b); - (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); + (void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); i--; continue; } } - assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ + /* + * 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; @@ -499,6 +542,7 @@ static void *v2i_ASIdentifiers(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; @@ -509,7 +553,6 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method, for (i = 0; i < sk_CONF_VALUE_num(values); i++) { CONF_VALUE *val = sk_CONF_VALUE_value(values, i); - ASN1_INTEGER *min = NULL, *max = NULL; int i1, i2, i3, is_range, which; /* @@ -579,18 +622,19 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method, max = s2i_ASN1_INTEGER(NULL, s + i2); OPENSSL_free(s); if (min == NULL || max == NULL) { - ASN1_INTEGER_free(min); - ASN1_INTEGER_free(max); 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)) { - ASN1_INTEGER_free(min); - ASN1_INTEGER_free(max); X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); goto err; } + min = max = NULL; } /* @@ -602,6 +646,8 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method, err: ASIdentifiers_free(asid); + ASN1_INTEGER_free(min); + ASN1_INTEGER_free(max); return NULL; } @@ -709,9 +755,9 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, int i, ret = 1, inherit_as = 0, inherit_rdi = 0; X509 *x = NULL; - assert(chain != NULL && sk_X509_num(chain) > 0); - assert(ctx != NULL || ext != NULL); - assert(ctx == NULL || ctx->verify_cb != NULL); + 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 @@ -723,7 +769,7 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, } else { i = 0; x = sk_X509_value(chain, i); - assert(x != NULL); + OPENSSL_assert(x != NULL); if ((ext = x->rfc3779_asid) == NULL) goto done; } @@ -756,7 +802,7 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, */ for (i++; i < sk_X509_num(chain); i++) { x = sk_X509_value(chain, i); - assert(x != NULL); + OPENSSL_assert(x != NULL); if (x->rfc3779_asid == NULL) { if (child_as != NULL || child_rdi != NULL) validation_err(X509_V_ERR_UNNESTED_RESOURCE); |