diff options
author | Rob Austein <sra@hactrn.net> | 2006-08-04 06:56:20 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2006-08-04 06:56:20 +0000 |
commit | 1d332ee76eae0b1f0a1af63bc7d8ff0f764e073f (patch) | |
tree | f353adc64553aeb0b06b16620594a1c75791b3a3 /openssl/trunk/crypto | |
parent | 051fc5c3971f0beedc136537551ba10f7e04c9b3 (diff) |
Checkpoint
svn path=/openssl/trunk/crypto/x509v3/v3_addr.c; revision=141
Diffstat (limited to 'openssl/trunk/crypto')
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3_addr.c | 91 | ||||
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3_asid.c | 202 | ||||
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3err.c | 1 | ||||
-rw-r--r-- | openssl/trunk/crypto/x509v3/x509v3.h | 1 |
4 files changed, 179 insertions, 116 deletions
diff --git a/openssl/trunk/crypto/x509v3/v3_addr.c b/openssl/trunk/crypto/x509v3/v3_addr.c index cf365e1a..0c6bda6d 100644 --- a/openssl/trunk/crypto/x509v3/v3_addr.c +++ b/openssl/trunk/crypto/x509v3/v3_addr.c @@ -608,6 +608,27 @@ static int addr_add_range(IPAddrBlocks *addr, } /* + * Extract min and max values from an IPAddressOrRange. + */ +static void extract_min_max(IPAddressOrRange *aor, + unsigned char *min, + unsigned char *max, + int length) +{ + assert(aor != NULL && min != NULL && max != NULL); + switch (aor->type) { + case IPAddressOrRange_addressPrefix: + addr_expand(min, aor->u.addressPrefix, length, 0x00); + addr_expand(max, aor->u.addressPrefix, length, 0xFF); + return; + case IPAddressOrRange_addressRange: + addr_expand(min, aor->u.addressRange->min, length, 0x00); + addr_expand(max, aor->u.addressRange->max, length, 0xFF); + return; + } +} + +/* * Whack an IPAddressOrRanges into canonical form. */ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, @@ -629,34 +650,8 @@ 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]; - /* - * Expand all the addresses once and get it over with. - */ - switch (a->type) { - case IPAddressOrRange_addressPrefix: - addr_expand(a_min, a->u.addressPrefix, length, 0x00); - addr_expand(a_max, a->u.addressPrefix, length, 0xFF); - break; - case IPAddressOrRange_addressRange: - addr_expand(a_min, a->u.addressRange->min, length, 0x00); - addr_expand(a_max, a->u.addressRange->max, length, 0xFF); - break; - } - switch (b->type) { - case IPAddressOrRange_addressPrefix: - addr_expand(b_min, b->u.addressPrefix, length, 0x00); - addr_expand(b_max, b->u.addressPrefix, length, 0xFF); - break; - case IPAddressOrRange_addressRange: - addr_expand(b_min, b->u.addressRange->min, length, 0x00); - addr_expand(b_max, b->u.addressRange->max, length, 0xFF); - break; - } - - /* - * Make sure we're sorted properly (paranoia). - */ - assert(memcmp(a_min, b_min, length) <= 0); + extract_min_max(a, a_min, a_max, length); + extract_min_max(b, b_min, b_max, length); /* * If a contains b, we can just get rid of b. @@ -764,8 +759,6 @@ static void *v2i_IPAddrBlocks(struct v3_ext_method *method, break; } - assert(s == NULL); /* Check for memory leak */ - /* * Handle SAFI, if any, and strdup() so we can null-terminate * the other input values. @@ -857,30 +850,25 @@ static void *v2i_IPAddrBlocks(struct v3_ext_method *method, goto err; } - assert(s != NULL); OPENSSL_free(s); s = NULL; } - assert(s == NULL); - /* * Canonize the result, then we're done. */ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); - unsigned afi = afi_from_addressfamily(f); if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && !IPAddressOrRanges_canonize(f->ipAddressChoice->u.addressesOrRanges, - afi)) + afi_from_addressfamily(f))) goto err; } sk_IPAddressFamily_sort(addr); return addr; err: - if (s != NULL) - OPENSSL_free(s); + OPENSSL_free(s); sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); return NULL; } @@ -903,27 +891,6 @@ X509V3_EXT_METHOD v3_addr = { }; /* - * Helper function to make addr_contains() more readable. - */ -static void addr_contains_helper(IPAddressOrRange *a, - unsigned char *min, - unsigned char *max, - int length) -{ - assert(a != NULL && min != NULL && max != NULL); - switch (a->type) { - case IPAddressOrRange_addressPrefix: - addr_expand(min, a->u.addressPrefix, length, 0x00); - addr_expand(max, a->u.addressPrefix, length, 0xFF); - return; - case IPAddressOrRange_addressRange: - addr_expand(min, a->u.addressRange->min, length, 0x00); - addr_expand(max, a->u.addressRange->max, length, 0xFF); - return; - } -} - -/* * Figure out whether parent contains child. */ static int addr_contains(IPAddressOrRanges *parent, @@ -941,13 +908,13 @@ static int addr_contains(IPAddressOrRanges *parent, p = 0; for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { - addr_contains_helper(sk_IPAddressOrRange_value(child, c), - c_min, c_max, length); + extract_min_max(sk_IPAddressOrRange_value(child, c), + c_min, c_max, length); for (;; p++) { if (p >= sk_IPAddressOrRange_num(parent)) return 0; - addr_contains_helper(sk_IPAddressOrRange_value(parent, p), - p_min, p_max, length); + extract_min_max(sk_IPAddressOrRange_value(parent, p), + p_min, p_max, length); if (memcmp(p_max, c_max, length) < 0) continue; if (memcmp(p_min, c_min, length) > 0) diff --git a/openssl/trunk/crypto/x509v3/v3_asid.c b/openssl/trunk/crypto/x509v3/v3_asid.c index aeb56bb4..39c43a21 100644 --- a/openssl/trunk/crypto/x509v3/v3_asid.c +++ b/openssl/trunk/crypto/x509v3/v3_asid.c @@ -217,6 +217,26 @@ static int asid_add_id_or_range(ASIdentifierChoice **choice, } /* + * Extract min and max values from an ASIdOrRange. + */ +static void extract_min_max(ASIdOrRange *aor, + ASN1_INTEGER **min, + ASN1_INTEGER **max) +{ + 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; + } +} + +/* * Whack an ASIdentifierChoice into canonical form. */ static int asid_canonize(ASIdentifierChoice *choice) @@ -245,25 +265,8 @@ static int asid_canonize(ASIdentifierChoice *choice) ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; - switch (a->type) { - case ASIdOrRange_id: - a_min = a_max = a->u.id; - break; - case ASIdOrRange_range: - a_min = a->u.range->min; - a_max = a->u.range->max; - break; - } - - switch (b->type) { - case ASIdOrRange_id: - b_min = b_max = b->u.id; - break; - case ASIdOrRange_range: - b_min = b->u.range->min; - b_max = b->u.range->max; - break; - } + extract_min_max(a, &a_min, &a_max); + extract_min_max(b, &b_min, &b_max); /* * Make sure we're properly sorted (paranoia). @@ -297,8 +300,10 @@ static int asid_canonize(ASIdentifierChoice *choice) 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) - goto err; + (a_max_plus_one = BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + X509V3err(X509V3_F_ASID_CANONIZE, X509V3_R_EXTENSION_VALUE_ERROR); + goto done; + } /* * If a and b are adjacent or overlap, merge them. @@ -306,36 +311,34 @@ static int asid_canonize(ASIdentifierChoice *choice) if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) { ASIdOrRange *aor = ASIdOrRange_new(); if (aor == NULL) - goto err; + goto done; aor->type = ASIdOrRange_range; assert(aor->u.range == NULL); if ((aor->u.range = ASRange_new()) == NULL) { ASIdOrRange_free(aor); - goto err; + goto done; } - ASN1_INTEGER_free(aor->u.range->min); - aor->u.range->min = a_min; - ASN1_INTEGER_free(aor->u.range->max); - aor->u.range->max = b_max; sk_ASIdOrRange_set(choice->u.asIdsOrRanges, i, aor); sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); switch (a->type) { case ASIdOrRange_id: - a->u.id = NULL; + a->u.id = aor->u.range->min; break; case ASIdOrRange_range: - a->u.range->min = NULL; + a->u.range->min = aor->u.range->min; break; } + aor->u.range->min = a_min; ASIdOrRange_free(a); switch (b->type) { case ASIdOrRange_id: - b->u.id = NULL; + b->u.id = aor->u.range->max; break; case ASIdOrRange_range: - b->u.range->max = NULL; + b->u.range->max = aor->u.range->max; break; } + aor->u.range->max = b_max; ASIdOrRange_free(b); i--; continue; @@ -344,7 +347,118 @@ static int asid_canonize(ASIdentifierChoice *choice) ret = 1; - err: + done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; +} + +/* + * Check whether an ASIdentifierChoice is in canonical form. + */ +static int asid_is_canonical(ASIdentifierChoice *choice, + int (*cb)(ASIdentifierChoice *, void *), + void *cookie) +{ + ASN1_INTEGER *a_max_plus_one = NULL; + ASIdOrRanges *aors = NULL; + BIGNUM *bn = NULL; + int i, ret = 0; + + assert(cb != 0); + + /* + * Empty element or inheritance is canonical. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If it's not a list at this point, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges) + return cb(choice, cookie); + + /* + * It's a list, we need a copy to sort. + */ + if ((aors = sk_ASIdOrRange_dup(choice->u.asIdsOrRanges)) == NULL) { + X509V3err(X509V3_F_ASID_IS_CANONICAL, ERR_R_MALLOC_FAILURE); + return 0; + } + sk_ASIdOrRange_set_cmp_func(aors, ASIdOrRange_cmp); + sk_ASIdOrRange_sort(aors); + + /* + * Check to see if it was misordered. + */ + for (i = 0; i < sk_ASIdOrRange_num(aors); i++) { + if (sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i) != + sk_ASIdOrRange_value(aors, i) && + !cb(choice, cookie)) + goto done; + } + + /* + * Now check for duplicates and overlaps in the sorted copy. + */ + for (i = 0; i < sk_ASIdOrRange_num(aors) - 1; i++) { + ASIdOrRange *a = sk_ASIdOrRange_value(aors, i); + ASIdOrRange *b = sk_ASIdOrRange_value(aors, 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). + */ + assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); + + /* + * Does a contain b? + */ + if (ASN1_INTEGER_cmp(a_max, b_max) >= 0) { + if (!cb(choice, cookie)) + goto done; + continue; + } + + /* + * Does b contain a? + */ + if (ASN1_INTEGER_cmp(a_min, b_min) == 0 && + ASN1_INTEGER_cmp(a_max, b_max) <= 0) { + if (!cb(choice, cookie)) + goto done; + continue; + } + + /* + * 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_ASID_IS_CANONICAL, ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * Are a and b adjacent or overlapping? + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) { + if (!cb(choice, cookie)) + goto done; + continue; + } + } + + ret = 1; + + done: + sk_ASIdOrRange_free(aors); ASN1_INTEGER_free(a_max_plus_one); BN_free(bn); return ret; @@ -482,26 +596,6 @@ X509V3_EXT_METHOD v3_asid = { }; /* - * Helper function to make asid_contains() more readable. - */ -static void asid_contains_helper(ASIdOrRange *a, - ASN1_INTEGER **min, - ASN1_INTEGER **max) -{ - assert(a != NULL && min != NULL && max != NULL); - switch (a->type) { - case ASIdOrRange_id: - *min = a->u.id; - *max = a->u.id; - return; - case ASIdOrRange_range: - *min = a->u.range->min; - *max = a->u.range->max; - return; - } -} - -/* * Figure out whether parent contains child. */ static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) @@ -516,11 +610,11 @@ static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) p = 0; for (c = 0; c < sk_ASIdOrRange_num(child); c++) { - asid_contains_helper(sk_ASIdOrRange_value(child, c), &c_min, &c_max); + extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max); for (;; p++) { if (p >= sk_ASIdOrRange_num(parent)) return 0; - asid_contains_helper(sk_ASIdOrRange_value(parent, p), &p_min, &p_max); + 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) diff --git a/openssl/trunk/crypto/x509v3/v3err.c b/openssl/trunk/crypto/x509v3/v3err.c index 50bc6bd4..04073ca6 100644 --- a/openssl/trunk/crypto/x509v3/v3err.c +++ b/openssl/trunk/crypto/x509v3/v3err.c @@ -70,6 +70,7 @@ static ERR_STRING_DATA X509V3_str_functs[]= { +{ERR_FUNC(X509V3_F_ASID_CANONIZE), "ASID_CANONIZE"}, {ERR_FUNC(X509V3_F_ASID_IS_CANONICAL), "ASID_IS_CANONICAL"}, {ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"}, {ERR_FUNC(X509V3_F_COPY_ISSUER), "COPY_ISSUER"}, diff --git a/openssl/trunk/crypto/x509v3/x509v3.h b/openssl/trunk/crypto/x509v3/x509v3.h index aaeadec7..ee642a44 100644 --- a/openssl/trunk/crypto/x509v3/x509v3.h +++ b/openssl/trunk/crypto/x509v3/x509v3.h @@ -742,6 +742,7 @@ void ERR_load_X509V3_strings(void); /* Error codes for the X509V3 functions. */ /* Function codes. */ +#define X509V3_F_ASID_CANONIZE 159 #define X509V3_F_ASID_IS_CANONICAL 158 #define X509V3_F_COPY_EMAIL 122 #define X509V3_F_COPY_ISSUER 123 |