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