diff options
Diffstat (limited to 'openssl/trunk/crypto/x509v3/v3_asid.c')
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3_asid.c | 97 |
1 files changed, 55 insertions, 42 deletions
diff --git a/openssl/trunk/crypto/x509v3/v3_asid.c b/openssl/trunk/crypto/x509v3/v3_asid.c index 50e316ee..25b154be 100644 --- a/openssl/trunk/crypto/x509v3/v3_asid.c +++ b/openssl/trunk/crypto/x509v3/v3_asid.c @@ -531,15 +531,30 @@ static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) } /* + * Validation error handling via callback. + */ +#define validation_err(_err_) \ + do { \ + ctx->error = _err_; \ + ctx->error_depth = i; \ + ctx->current_cert = x; \ + ret = ctx->verify_cb(0, ctx); \ + if (!ret) \ + goto done; \ + } while (0) + +/* * RFC 3779 3.3 path validation. Intended to be called from X509_verify_cert(). */ int v3_asid_validate_path(X509_STORE_CTX *ctx) { - ASIdOrRanges *parent_as = NULL, *parent_rdi = NULL, *child_as, *child_rdi; - ASIdentifiers *asid; - int i, has_ext; + ASIdOrRanges *parent_as = NULL, *parent_rdi = NULL; + ASIdentifiers *asid = NULL; + int i, has_ext, ret = 1; X509 *x; + assert(ctx->verify_cb); + /* * Start with the ancestral cert. It can't inherit anything. */ @@ -555,7 +570,8 @@ int v3_asid_validate_path(X509_STORE_CTX *ctx) parent_as = asid->asnum->u.asIdsOrRanges; break; case ASIdentifierChoice_inherit: - goto err; + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + goto done; /* callback insists on continuing */ } } if (asid->rdi != NULL) { @@ -564,10 +580,13 @@ int v3_asid_validate_path(X509_STORE_CTX *ctx) parent_rdi = asid->rdi->u.asIdsOrRanges; break; case ASIdentifierChoice_inherit: - goto err; + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + goto done; /* callback insists on continuing */ } } } + ASIdentifiers_free(asid); + asid = NULL; /* * Now walk down the chain. No cert may list resources that its @@ -576,50 +595,44 @@ int v3_asid_validate_path(X509_STORE_CTX *ctx) while (--i >= 0) { 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; - child_as = child_rdi = NULL; } else if (!has_ext) { - goto err; - } else { - if (asid->asnum == NULL) { - child_as = NULL; - } else { - switch (asid->asnum->type) { - case ASIdentifierChoice_asIdsOrRanges: - child_as = asid->asnum->u.asIdsOrRanges; - break; - case ASIdentifierChoice_inherit: - child_as = parent_as; - break; - } + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + has_ext = 1; /* callback insists on continuing */ + } + + 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) { - child_rdi = NULL; - } else { - switch (asid->rdi->type) { - case ASIdentifierChoice_asIdsOrRanges: - child_rdi = asid->rdi->u.asIdsOrRanges; - break; - case ASIdentifierChoice_inherit: - child_rdi = parent_rdi; - break; - } + 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 (!asid_contains(parent_as, child_as) || - !asid_contains(parent_rdi, child_rdi)) - goto err; } - parent_as = child_as; - parent_rdi = child_rdi; - } - return 1; + ASIdentifiers_free(asid); + asid = NULL; + } - err: - ctx->error = X509_V_ERR_UNNESTED_RESOURCE; - ctx->error_depth = i; - ctx->current_cert = x; - return 0; + done: + sk_ASIdOrRange_pop_free(parent_as, ASIdOrRange_free); + sk_ASIdOrRange_pop_free(parent_rdi, ASIdOrRange_free); + ASIdentifiers_free(asid); + return ret; } + +#undef validation_err |