Commit 4be37de061 for openssl.org

commit 4be37de061f5f6dee743fc5f55d832a1178405ca
Author: Mounir IDRASSI <mounir.idrassi@idrix.fr>
Date:   Sun May 31 23:16:03 2026 +0900

    Tighten CRL issuer matching

    Require a candidate CRL issuer certificate subject to match the CRL
    issuer name before accepting an AKID match. This avoids accepting the
    truncated chain anchor as a CRL issuer solely because the CRL has no
    AKID.

    Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
    Reviewed-by: Andrew Dinh <andrewd@openssl.org>
    MergeDate: Tue Aug 18 15:44:24 2026
    (Merged from https://github.com/openssl/openssl/pull/30945)

diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 6186ef676a..977d6165ca 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -79,6 +79,8 @@ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
     STACK_OF(X509_CRL) *crls);
 static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
     int *pcrl_score);
+static int matching_crl_issuer_and_akid(const X509_CRL *crl,
+    const X509 *issuer, const X509_NAME *crl_issuer_name);
 static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
     unsigned int *preasons);
 static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
@@ -1776,7 +1778,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,

     crl_issuer = sk_X509_value(ctx->chain, cidx);

-    if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+    if (matching_crl_issuer_and_akid(crl, crl_issuer, cnm)) {
         if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
             *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
             *pissuer = crl_issuer;
@@ -1786,9 +1788,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,

     for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) {
         crl_issuer = sk_X509_value(ctx->chain, cidx);
-        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
-            continue;
-        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+        if (matching_crl_issuer_and_akid(crl, crl_issuer, cnm)) {
             *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
             *pissuer = crl_issuer;
             return;
@@ -1805,9 +1805,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
      */
     for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
         crl_issuer = sk_X509_value(ctx->untrusted, i);
-        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm) != 0)
-            continue;
-        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+        if (matching_crl_issuer_and_akid(crl, crl_issuer, cnm)) {
             *pissuer = crl_issuer;
             *pcrl_score |= CRL_SCORE_AKID;
             return;
@@ -1815,6 +1813,16 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
     }
 }

+static int matching_crl_issuer_and_akid(const X509_CRL *crl,
+    const X509 *issuer, const X509_NAME *crl_issuer_name)
+{
+    if (issuer == NULL)
+        return 0;
+    if (X509_NAME_cmp(X509_get_subject_name(issuer), crl_issuer_name) != 0)
+        return 0;
+    return X509_check_akid(issuer, crl->akid) == X509_V_OK;
+}
+
 /*
  * Check the path of a CRL issuer certificate. This creates a new
  * X509_STORE_CTX and populates it with most of the parameters from the