From b45e035bf7a93df67d2b5fd96f818d02f977ec8a Mon Sep 17 00:00:00 2001 From: "Dr. David von Oheimb" Date: Fri, 31 Jan 2025 16:03:34 +0100 Subject: [PATCH] X509_STORE_CTX_get1_issuer(): make happy path quicker again Fixes #26588 Reviewed-by: Neil Horman Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/26600) --- crypto/x509/x509_local.h | 2 ++ crypto/x509/x509_lu.c | 6 ++---- crypto/x509/x509_vfy.c | 30 +++++++++++++++++++++++++++--- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/crypto/x509/x509_local.h b/crypto/x509/x509_local.h index 6d602e1d8ef..26c4482f343 100644 --- a/crypto/x509/x509_local.h +++ b/crypto/x509/x509_local.h @@ -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); diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index 7b0979b5b8e..de1e60bb2bd 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -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; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 0ad0e995113..bdd1b9161c1 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -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; } -- 2.47.2