summaryrefslogtreecommitdiffstats
path: root/crypto/x509/x509_vfy.c
diff options
context:
space:
mode:
authorViktor Dukhovni <openssl-users@dukhovni.org>2016-01-29 02:28:43 -0500
committerViktor Dukhovni <openssl-users@dukhovni.org>2016-01-31 21:24:12 -0500
commit33cc5dde478ba5ad79f8fd4acd8737f0e60e236e (patch)
tree9c1ab89462ef00d5700c3712737a6ae960c2e604 /crypto/x509/x509_vfy.c
parent0daccd4dc1f1ac62181738a91714f35472e50f3c (diff)
Compat self-signed trust with reject-only aux data
When auxiliary data contains only reject entries, continue to trust self-signed objects just as when no auxiliary data is present. This makes it possible to reject specific uses without changing what's accepted (and thus overring the underlying EKU). Added new supported certs and doubled test count from 38 to 76. Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
Diffstat (limited to 'crypto/x509/x509_vfy.c')
-rw-r--r--crypto/x509/x509_vfy.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 14d6a8d74e..1f3b2b9dab 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -369,12 +369,11 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm)
static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth,
int must_be_ca)
{
- int pu_ok = X509_check_purpose(x, purpose, must_be_ca > 0);
int tr_ok = X509_TRUST_UNTRUSTED;
/*
* For trusted certificates we want to see whether any auxiliary trust
- * settings override the purpose constraints we failed to meet above.
+ * settings trump the purpose constraints.
*
* This is complicated by the fact that the trust ordinals in
* ctx->param->trust are entirely independent of the purpose ordinals in
@@ -388,15 +387,28 @@ static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth,
*
* Therefore, we can only check for trust overrides when the purpose we're
* checking is the same as ctx->param->purpose and ctx->param->trust is
- * also set, or can be inferred from the purpose.
+ * also set.
*/
if (depth >= ctx->num_untrusted && purpose == ctx->param->purpose)
tr_ok = X509_check_trust(x, ctx->param->trust, X509_TRUST_NO_SS_COMPAT);
- if (tr_ok != X509_TRUST_REJECTED &&
- (pu_ok == 1 ||
- (pu_ok != 0 && (ctx->param->flags & X509_V_FLAG_X509_STRICT) == 0)))
+ switch (tr_ok) {
+ case X509_TRUST_TRUSTED:
return 1;
+ case X509_TRUST_REJECTED:
+ break;
+ default:
+ switch (X509_check_purpose(x, purpose, must_be_ca > 0)) {
+ case 1:
+ return 1;
+ case 0:
+ break;
+ default:
+ if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) == 0)
+ return 1;
+ }
+ break;
+ }
ctx->error = X509_V_ERR_INVALID_PURPOSE;
ctx->error_depth = depth;
@@ -493,7 +505,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
if (ret == 0) {
ctx->error_depth = i;
ctx->current_cert = x;
- if (! ctx->verify_cb(0, ctx))
+ if (!ctx->verify_cb(0, ctx))
return 0;
}
if (purpose > 0) {