diff options
author | Rob Austein <sra@hactrn.net> | 2006-08-16 01:09:27 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2006-08-16 01:09:27 +0000 |
commit | 19a1b0eab24ab520c0daff2f808153e6bbfcf4a6 (patch) | |
tree | 54afc11d3a4587910197437fc80a8a0889396068 /openssl/trunk/crypto/x509v3 | |
parent | 44ff60bdd4686d90cfe86da3d88445a3a9cb6a97 (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/crypto/x509v3')
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3_addr.c | 2 | ||||
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3_asid.c | 131 | ||||
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3_purp.c | 3 |
3 files changed, 73 insertions, 63 deletions
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); |