]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
X509_STORE_CTX_get1_issuer(): make happy path quicker again
authorDr. David von Oheimb <dev@ddvo.net>
Fri, 31 Jan 2025 15:03:34 +0000 (16:03 +0100)
committerNeil Horman <nhorman@openssl.org>
Wed, 12 Feb 2025 13:07:57 +0000 (08:07 -0500)
Fixes #26588

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26600)

crypto/x509/x509_local.h
crypto/x509/x509_lu.c
crypto/x509/x509_vfy.c

index 6d602e1d8ef59164077ee678b783b19ec7ca846f..26c4482f343f46e9e79812745b199965e8a2c3cc 100644 (file)
@@ -157,3 +157,5 @@ DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
 
 int ossl_x509_likely_issued(X509 *issuer, X509 *subject);
 int ossl_x509_signing_allowed(const X509 *issuer, const X509 *subject);
+int ossl_x509_store_ctx_get_by_subject(const X509_STORE_CTX *ctx, X509_LOOKUP_TYPE type,
+                                       const X509_NAME *name, X509_OBJECT *ret);
index 7b0979b5b8e015d3a553389335307b62dac8722b..de1e60bb2bd822f775f905c3e992990783ae786f 100644 (file)
@@ -317,10 +317,8 @@ X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *ctx,
  * 0 if not found or X509_LOOKUP_by_subject_ex() returns an error,
  * -1 on failure
  */
-static int ossl_x509_store_ctx_get_by_subject(const X509_STORE_CTX *ctx,
-                                              X509_LOOKUP_TYPE type,
-                                              const X509_NAME *name,
-                                              X509_OBJECT *ret)
+int ossl_x509_store_ctx_get_by_subject(const X509_STORE_CTX *ctx, X509_LOOKUP_TYPE type,
+                                       const X509_NAME *name, X509_OBJECT *ret)
 {
     X509_STORE *store = ctx->store;
     X509_LOOKUP *lu;
index 0ad0e99511342469f803af7f12b2498567050ffd..bdd1b9161c1dff0e40112a1fc3f0adb9b9b2960f 100644 (file)
@@ -423,6 +423,7 @@ static X509 *get0_best_issuer_sk(X509_STORE_CTX *ctx, int check_signing_allowed,
 
 /*-
  * Try to get issuer cert from |ctx->store| accepted by |ctx->check_issued|.
+ * Prefer the first match with suitable validity period or latest expiration.
  *
  * Return values are:
  *  1 lookup successful.
@@ -431,15 +432,38 @@ static X509 *get0_best_issuer_sk(X509_STORE_CTX *ctx, int check_signing_allowed,
  */
 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
 {
-    STACK_OF(X509) *certs = X509_STORE_CTX_get1_certs(ctx, X509_get_issuer_name(x));
-    int ret = 0;
+    const X509_NAME *xn = X509_get_issuer_name(x);
+    X509_OBJECT *obj = X509_OBJECT_new();
+    STACK_OF(X509) *certs;
+    int ret;
 
-    if (certs == NULL)
+    *issuer = NULL;
+    if (obj == NULL)
         return -1;
+    ret = ossl_x509_store_ctx_get_by_subject(ctx, X509_LU_X509, xn, obj);
+    if (ret != 1)
+        goto end;
+
+    /* quick happy path: certificate matches and is currently valid */
+    if (ctx->check_issued(ctx, x, obj->data.x509)) {
+        if (ossl_x509_check_cert_time(ctx, obj->data.x509, -1)) {
+            *issuer = obj->data.x509;
+            /* |*issuer| has taken over the cert reference from |obj| */
+            obj->type = X509_LU_NONE;
+            goto end;
+        }
+    }
+
+    ret = -1;
+    if ((certs = X509_STORE_CTX_get1_certs(ctx, xn)) == NULL)
+        goto end;
     *issuer = get0_best_issuer_sk(ctx, 0, 0 /* allow duplicates */, certs, x);
+    ret = 0;
     if (*issuer != NULL)
         ret = X509_up_ref(*issuer) ? 1 : -1;
     OSSL_STACK_OF_X509_free(certs);
+ end:
+    X509_OBJECT_free(obj);
     return ret;
 }