aboutsummaryrefslogtreecommitdiff
path: root/openssl/trunk
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2006-08-16 01:09:27 +0000
committerRob Austein <sra@hactrn.net>2006-08-16 01:09:27 +0000
commit19a1b0eab24ab520c0daff2f808153e6bbfcf4a6 (patch)
tree54afc11d3a4587910197437fc80a8a0889396068 /openssl/trunk
parent44ff60bdd4686d90cfe86da3d88445a3a9cb6a97 (diff)
Cache RFC 3779 extensions in X509 structure so we don't have to expand
them every time we check a certificate chain. Rewrite ASID path validation to use cached extensions, to allow null inheritance, and to start with the target certificate. Still need to rewrite address path validation. svn path=/openssl/README; revision=154
Diffstat (limited to 'openssl/trunk')
-rw-r--r--openssl/trunk/crypto/asn1/x_x509.c4
-rw-r--r--openssl/trunk/crypto/x509/x509.h2
-rw-r--r--openssl/trunk/crypto/x509v3/v3_addr.c2
-rw-r--r--openssl/trunk/crypto/x509v3/v3_asid.c131
-rw-r--r--openssl/trunk/crypto/x509v3/v3_purp.c3
5 files changed, 79 insertions, 63 deletions
diff --git a/openssl/trunk/crypto/asn1/x_x509.c b/openssl/trunk/crypto/asn1/x_x509.c
index 12d1a256..01c586f4 100644
--- a/openssl/trunk/crypto/asn1/x_x509.c
+++ b/openssl/trunk/crypto/asn1/x_x509.c
@@ -94,6 +94,8 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
ret->ex_pathlen = -1;
ret->skid = NULL;
ret->akid = NULL;
+ ret->rfc3779_addr = NULL;
+ ret->rfc3779_asid = NULL;
ret->aux = NULL;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
break;
@@ -109,6 +111,8 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
ASN1_OCTET_STRING_free(ret->skid);
AUTHORITY_KEYID_free(ret->akid);
policy_cache_free(ret->policy_cache);
+ sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
+ ASIdentifiers_free(ret->rfc3779_asid);
if (ret->name != NULL) OPENSSL_free(ret->name);
break;
diff --git a/openssl/trunk/crypto/x509/x509.h b/openssl/trunk/crypto/x509/x509.h
index 66990ae5..16d7bbf5 100644
--- a/openssl/trunk/crypto/x509/x509.h
+++ b/openssl/trunk/crypto/x509/x509.h
@@ -288,6 +288,8 @@ struct x509_st
ASN1_OCTET_STRING *skid;
struct AUTHORITY_KEYID_st *akid;
X509_POLICY_CACHE *policy_cache;
+ STACK_OF(IPAddressFamily) *rfc3779_addr;
+ struct ASIdentifiers_st *rfc3779_asid;
#ifndef OPENSSL_NO_SHA
unsigned char sha1_hash[SHA_DIGEST_LENGTH];
#endif
diff --git a/openssl/trunk/crypto/x509v3/v3_addr.c b/openssl/trunk/crypto/x509v3/v3_addr.c
index 707fdd5f..0355dda2 100644
--- a/openssl/trunk/crypto/x509v3/v3_addr.c
+++ b/openssl/trunk/crypto/x509v3/v3_addr.c
@@ -922,6 +922,8 @@ static int addr_contains(IPAddressOrRanges *parent,
break;
}
}
+
+ return 1;
}
/*
diff --git a/openssl/trunk/crypto/x509v3/v3_asid.c b/openssl/trunk/crypto/x509v3/v3_asid.c
index 39c43a21..98fa39cd 100644
--- a/openssl/trunk/crypto/x509v3/v3_asid.c
+++ b/openssl/trunk/crypto/x509v3/v3_asid.c
@@ -622,6 +622,8 @@ static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
break;
}
}
+
+ return 1;
}
/*
@@ -642,92 +644,95 @@ static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
*/
int v3_asid_validate_path(X509_STORE_CTX *ctx)
{
- ASIdOrRanges *parent_as = NULL, *parent_rdi = NULL;
- ASIdentifiers *asid = NULL;
- int i, has_ext, ret = 1;
+ ASIdOrRanges *child_as, *child_rdi, *inherit_marker = (ASIdOrRanges *) 1;
+ int i, ret = 1;
X509 *x;
assert(ctx->verify_cb);
/*
- * Start with the ancestral cert. It can't inherit anything.
+ * Start with the target certificate. If it doesn't have the extension,
+ * we're done.
*/
- i = sk_X509_num(ctx->chain) - 1;
- x = sk_X509_value(ctx->chain, i);
+ x = sk_X509_value(ctx->chain, 0);
assert(x != NULL);
- asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, NULL, NULL);
- has_ext = asid != NULL;
- if (has_ext) {
- if (asid->asnum != NULL) {
- switch (asid->asnum->type) {
- case ASIdentifierChoice_asIdsOrRanges:
- parent_as = asid->asnum->u.asIdsOrRanges;
- asid->asnum->u.asIdsOrRanges = NULL;
- break;
- case ASIdentifierChoice_inherit:
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- goto done; /* callback insists on continuing */
- }
+ if (x->rfc3779_asid == NULL)
+ goto done;
+
+ /*
+ * Has extension, have to check the whole chain.
+ */
+ if (x->rfc3779_asid->asnum == NULL) {
+ child_as = NULL;
+ } else {
+ switch (x->rfc3779_asid->asnum->type) {
+ case ASIdentifierChoice_inherit:
+ child_as = inherit_marker;
+ break;
+ case ASIdentifierChoice_asIdsOrRanges:
+ child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
+ break;
}
- if (asid->rdi != NULL) {
- switch (asid->rdi->type) {
- case ASIdentifierChoice_asIdsOrRanges:
- parent_rdi = asid->rdi->u.asIdsOrRanges;
- asid->rdi->u.asIdsOrRanges = NULL;
- break;
- case ASIdentifierChoice_inherit:
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- goto done; /* callback insists on continuing */
- }
+ }
+ if (x->rfc3779_asid->rdi == NULL) {
+ child_rdi = NULL;
+ } else {
+ switch (x->rfc3779_asid->rdi->type) {
+ case ASIdentifierChoice_inherit:
+ child_rdi = inherit_marker;
+ break;
+ case ASIdentifierChoice_asIdsOrRanges:
+ child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
+ break;
}
}
- ASIdentifiers_free(asid);
- asid = NULL;
/*
- * Now walk down the chain. No cert may list resources that its
+ * Now walk up the chain. No cert may list resources that its
* parent doesn't list.
*/
- while (--i >= 0) {
+ for (i = 1; i < sk_X509_num(ctx->chain); i++) {
x = sk_X509_value(ctx->chain, i);
assert(x != NULL);
-
- assert(asid == NULL);
- asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, NULL, NULL);
- if (asid == NULL) {
- has_ext = 0;
- } else if (!has_ext) {
+ if (x->rfc3779_asid == NULL) {
validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- has_ext = 1; /* callback insists on continuing */
+ continue;
}
-
- if (has_ext) {
- if (asid->asnum != NULL &&
- asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) {
- if (!asid_contains(parent_as, asid->asnum->u.asIdsOrRanges))
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- sk_ASIdOrRange_pop_free(parent_as, ASIdOrRange_free);
- parent_as = asid->asnum->u.asIdsOrRanges;
- asid->asnum->u.asIdsOrRanges = NULL;
- }
- if (asid->rdi != NULL &&
- asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
- if (!asid_contains(parent_rdi, asid->rdi->u.asIdsOrRanges))
- validation_err(X509_V_ERR_UNNESTED_RESOURCE);
- sk_ASIdOrRange_pop_free(parent_rdi, ASIdOrRange_free);
- parent_rdi = asid->rdi->u.asIdsOrRanges;
- asid->rdi->u.asIdsOrRanges = NULL;
- }
+ if (x->rfc3779_asid->asnum == NULL && child_as != NULL)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ if (x->rfc3779_asid->asnum != NULL &&
+ x->rfc3779_asid->asnum->type == ASIdentifierChoice_asIdsOrRanges) {
+ if (child_as == inherit_marker ||
+ asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, child_as))
+ child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
+ else
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
}
+ if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL)
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ if (x->rfc3779_asid->rdi != NULL &&
+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
+ if (child_rdi == inherit_marker ||
+ asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, child_rdi))
+ child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
+ else
+ validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+ }
+ }
- ASIdentifiers_free(asid);
- asid = NULL;
+ /*
+ * Trust anchor can't inherit.
+ */
+ 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:
- sk_ASIdOrRange_pop_free(parent_as, ASIdOrRange_free);
- sk_ASIdOrRange_pop_free(parent_rdi, ASIdOrRange_free);
- ASIdentifiers_free(asid);
return ret;
}
diff --git a/openssl/trunk/crypto/x509v3/v3_purp.c b/openssl/trunk/crypto/x509v3/v3_purp.c
index ae05b39b..5ad2047e 100644
--- a/openssl/trunk/crypto/x509v3/v3_purp.c
+++ b/openssl/trunk/crypto/x509v3/v3_purp.c
@@ -413,6 +413,9 @@ static void x509v3_cache_extensions(X509 *x)
}
x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
+ x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
+ x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
+ NULL, NULL);
for (i = 0; i < X509_get_ext_count(x); i++)
{
ex = X509_get_ext(x, i);