Test the X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE codepath

This seems to only be reachable via the verify callback, but it is
possible for internal_verify to see a single-element certificate that
isn't self-signed. There's a special error code for this. We probably
can safely change it, but cover the codepath in the meantime.

Change-Id: Id4c81e1826f0b43b369e8f00de36313e5fa4360d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/65053
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index e259859..0283503 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -4360,6 +4360,23 @@
                               {intermediate.valid.get()}, {}));
   EXPECT_EQ(X509_V_OK, Verify(leaf.bad_key_type.get(), {root.valid.get()},
                               {intermediate.valid.get()}, {}));
+
+  // At the time we go to verify signatures, it is possible that we have a
+  // single-element certificate chain with a certificate that isn't self-signed.
+  // This does not seem to be reachable except if missing trust anchors are
+  // suppressed with the verify callback, but exercise this codepath anyway.
+  EXPECT_EQ(X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE,
+            Verify(leaf.valid.get(), {}, {}, {}, 0, [](X509_STORE_CTX *ctx) {
+              X509_STORE_CTX_set_verify_cb(
+                  ctx, [](int ok, X509_STORE_CTX *ctx_inner) -> int {
+                    if (ok) {
+                      return ok;
+                    }
+                    // Suppress the missing issuer certificate.
+                    int err = X509_STORE_CTX_get_error(ctx_inner);
+                    return err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
+                  });
+            }));
 }
 
 // kConstructedBitString is an X.509 certificate where the signature is encoded