X509_STORE_CTX_get1_issuer(): make happy path quicker again

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)
This commit is contained in:
Dr. David von Oheimb 2025-01-31 16:03:34 +01:00 committed by Neil Horman
parent 5ebd6d26a8
commit b45e035bf7
3 changed files with 31 additions and 7 deletions

View 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);

View 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;

View 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;
}