aboutsummaryrefslogtreecommitdiff
path: root/openssl/trunk/crypto
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2006-08-04 06:56:20 +0000
committerRob Austein <sra@hactrn.net>2006-08-04 06:56:20 +0000
commit1d332ee76eae0b1f0a1af63bc7d8ff0f764e073f (patch)
treef353adc64553aeb0b06b16620594a1c75791b3a3 /openssl/trunk/crypto
parent051fc5c3971f0beedc136537551ba10f7e04c9b3 (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.c91
-rw-r--r--openssl/trunk/crypto/x509v3/v3_asid.c202
-rw-r--r--openssl/trunk/crypto/x509v3/v3err.c1
-rw-r--r--openssl/trunk/crypto/x509v3/x509v3.h1
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