Simplify some logic around X509_verify_cert callbacks If we simply set ctx->get_crl to get_crl, as the other callbacks do, we don't need to branch at the call site. Also get_issuer no longer needs to be a callback. We can just check if X509_STORE_CTX_set0_trusted_stack was called. Change-Id: I42235f141ee9f8463631f56471c12324a8755bba Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64988 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index bb256e5..d6debd2 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h
@@ -348,9 +348,6 @@ CRYPTO_refcount_t references; } /* X509_STORE */; -typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer, X509_STORE_CTX *ctx, - X509 *x); - // This is the functions plus an instance of the local variables. struct x509_lookup_st { const X509_LOOKUP_METHOD *method; // the functions @@ -371,11 +368,13 @@ STACK_OF(X509_CRL) *crls; // set of CRLs passed in X509_VERIFY_PARAM *param; - void *other_ctx; // Other info for use with get_issuer() + + // trusted_stack, if non-NULL, is a set of trusted certificates to consider + // instead of those from |X509_STORE|. + STACK_OF(X509) *trusted_stack; // Callbacks for various operations X509_STORE_CTX_verify_cb verify_cb; // error callback - X509_STORE_CTX_get_issuer_fn get_issuer; // get issuers cert from ctx X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 68effaf..6bf366b 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c
@@ -110,6 +110,7 @@ static int check_cert(X509_STORE_CTX *ctx); static int check_policy(X509_STORE_CTX *ctx); +static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, X509_CRL *crl, X509 *x); static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x); @@ -233,7 +234,7 @@ } // If asked see if we can find issuer in trusted store first if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { - ok = ctx->get_issuer(&xtmp, ctx, x); + ok = get_issuer(&xtmp, ctx, x); if (ok < 0) { ctx->error = X509_V_ERR_STORE_LOOKUP; goto end; @@ -290,7 +291,7 @@ // We have a single self signed certificate: see if we can // find it in the store. We must have an exact match to avoid // possible impersonation. - ok = ctx->get_issuer(&xtmp, ctx, x); + ok = get_issuer(&xtmp, ctx, x); if ((ok <= 0) || X509_cmp(x, xtmp)) { ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; ctx->current_cert = x; @@ -335,7 +336,7 @@ if (is_self_signed) { break; } - ok = ctx->get_issuer(&xtmp, ctx, x); + ok = get_issuer(&xtmp, ctx, x); if (ok < 0) { ctx->error = X509_V_ERR_STORE_LOOKUP; @@ -372,7 +373,7 @@ !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { while (j-- > 1) { xtmp2 = sk_X509_value(ctx->chain, j - 1); - ok = ctx->get_issuer(&xtmp, ctx, xtmp2); + ok = get_issuer(&xtmp, ctx, xtmp2); if (ok < 0) { goto end; } @@ -511,16 +512,18 @@ return ctx->verify_cb(0, ctx); } -// Alternative lookup method: look from a STACK stored in other_ctx - -static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { - *issuer = find_issuer(ctx, ctx->other_ctx, x); - if (*issuer) { - X509_up_ref(*issuer); - return 1; - } else { +static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { + if (ctx->trusted_stack != NULL) { + // Ignore the store and use the configured stack instead. + *issuer = find_issuer(ctx, ctx->trusted_stack, x); + if (*issuer) { + X509_up_ref(*issuer); + return 1; + } return 0; } + + return X509_STORE_CTX_get1_issuer(issuer, ctx, x); } // Check a certificate chains extensions for consistency with the supplied @@ -803,11 +806,7 @@ ctx->current_crl_score = 0; // Try to retrieve relevant CRL - if (ctx->get_crl) { - ok = ctx->get_crl(ctx, &crl, x); - } else { - ok = get_crl(ctx, &crl, x); - } + ok = ctx->get_crl(ctx, &crl, x); // If error looking up CRL, nothing we can do except notify callback if (!ok) { ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; @@ -1668,10 +1667,6 @@ goto err; } - // TODO(davidben): Remove this pointer. It only exists to be overwritten by - // X509_STORE_CTX_set0_trusted_stack. - ctx->get_issuer = X509_STORE_CTX_get1_issuer; - if (store->verify_cb) { ctx->verify_cb = store->verify_cb; } else { @@ -1681,7 +1676,7 @@ if (store->get_crl) { ctx->get_crl = store->get_crl; } else { - ctx->get_crl = NULL; + ctx->get_crl = get_crl; } if (store->check_crl) { @@ -1707,8 +1702,7 @@ void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { - ctx->other_ctx = sk; - ctx->get_issuer = get_issuer_sk; + ctx->trusted_stack = sk; } void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) {
diff --git a/include/openssl/x509.h b/include/openssl/x509.h index ba4d6a2..8fe59c7 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h
@@ -3789,7 +3789,9 @@ X509 *x509, STACK_OF(X509) *chain); // X509_STORE_CTX_set0_trusted_stack configures |ctx| to trust the certificates -// in |sk|. |sk| must remain valid for the duration of |ctx|. +// in |sk|. |sk| must remain valid for the duration of |ctx|. Calling this +// function causes |ctx| to ignore any certificates configured in the +// |X509_STORE|. // // WARNING: This function differs from most |set0| functions in that it does not // take ownership of its input. The caller is required to ensure the lifetimes