Commit 8a6dffc063 for openssl.org
commit 8a6dffc063b2c9cfc7b96fc0ba296e576c73aa84
Author: Daniel Kubec <kubec@openssl.org>
Date: Wed Feb 25 10:51:08 2026 +0100
CRL: Reject CRLs with malformed Issuing Distribution Point
CRLs with a malformed Issuing Distribution Point are now rejected.
ASN.1 parsing errors from the IDP extension are propagated instead
of being suppressed.
Fixes #27251
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
MergeDate: Fri Feb 27 20:06:59 2026
(Merged from https://github.com/openssl/openssl/pull/30171)
diff --git a/CHANGES.md b/CHANGES.md
index 5ca61c80e7..9fe41d3177 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -177,6 +177,10 @@ OpenSSL 4.0
*Igor Ustinov*
+ * CRLs with a malformed Issuing Distribution Point are now rejected.
+
+ *Daniel Kubec*
+
* Added configure options to disable KDF algorithms for
hmac-drbg-kdf, kbkdf, krb5kdf, pvkkdf, snmpkdf, sskdf, sshkdf, x942kdf and x963kdf.
diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c
index 89a64fec03..f11e7b018b 100644
--- a/crypto/x509/x_crl.c
+++ b/crypto/x509/x_crl.c
@@ -247,9 +247,12 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
case ASN1_OP_D2I_POST:
if (!X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL))
crl->flags |= EXFLAG_NO_FINGERPRINT;
- crl->idp = X509_CRL_get_ext_d2i(crl,
- NID_issuing_distribution_point, &i,
- NULL);
+ crl->idp = X509_CRL_get_ext_d2i(crl, NID_issuing_distribution_point, &i, NULL);
+ if (crl->idp == NULL && i != -1) {
+ ERR_raise_data(ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT,
+ "CRL: malformed CRL issuing distribution point");
+ return 0;
+ }
if (crl->idp != NULL) {
if (!setup_idp(crl, crl->idp))
crl->flags |= EXFLAG_INVALID;
diff --git a/test/crltest.c b/test/crltest.c
index b13d5977ce..245d2205f4 100644
--- a/test/crltest.c
+++ b/test/crltest.c
@@ -266,10 +266,6 @@ static const char *kUnknownCriticalCRL2[] = {
NULL
};
-static const char **unknown_critical_crls[] = {
- kUnknownCriticalCRL, kUnknownCriticalCRL2
-};
-
/*
* RFC 5280 states that only CRL files with the Indirect CRL flag set to True in
* the IDP extension require the certificate_issuer extension.
@@ -403,6 +399,45 @@ static const char *kCrlNumberString[] = {
NULL
};
+/* https://github.com/openssl/openssl/issues/27251 */
+static const char *kCrlIDPWrongTag[] = {
+ "-----BEGIN X509 CRL-----\n",
+ "MIICZzCCAU8CAQEwDQYJKoZIhvcNAQELBQAweTELMAkGA1UEBhMCVVMxEzARBgNV\n",
+ "BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xEzARBgNVBAoM\n",
+ "Ck15IENvbXBhbnkxEzARBgNVBAMMCk15IFJvb3QgQ0ExEzARBgNVBAsMCk15IFJv\n",
+ "b3QgQ0EXDTI1MDEwMTAwMDAwMFoXDTI1MTIwMTAwMDAwMFowJzAlAhQcgAIu+B8k\n",
+ "Be6WphLcth/grHAeXhcNMjUwNDE3MTAxNjUxWqB5MHcwGAYDVR0UBBECDxnP/97a\n",
+ "dO3y9qRGDM7hQDAfBgNVHSMEGDAWgBTXYYkfk5aLdlQW6eV33Hy3ZRuAJDA6BgNV\n",
+ "HRwBAf8EMDAuoCagJKQihiBodHRwOi8vbG9jYWxob3N0OjgwMDAvY2FfY3JsLmRl\n",
+ "coEB/4IB/zANBgkqhkiG9w0BAQsFAAOCAQEANovDW2ry+y17K8CgjoD6C1Mwf8Je\n",
+ "uJiSw4kZnbtO/+/Benl3nWumMIH9liV6BSJnWZU3staGQaUyk+qou5udzSwh0Tw/\n",
+ "iGu/xygDlEBiJ/vFt0Bt6ImHCsNrd7UjNRGRJI7neeJdq6YlMOJ27JvKt9isRJIM\n",
+ "KsHBuqBs8G8g6XU0TfgoHYAPxtPF9uuFmC7k0Fs7z142C9/Im8m1CqqYet/kd/Hz\n",
+ "IErMxdvr1NfL7WHBIArW0BqjaR1E05ur8fPIHItVJtPV9V5UbRM1eeQiOfDCyZRJ\n",
+ "x9A/quodFMH781MsLnTktHqMmbOesiDycl0OehyrfXDEXLWIOH/EvqkyIA==\n",
+ "-----END X509 CRL-----\n",
+ NULL
+};
+
+static const char *kCrlIDPWrongTag2[] = {
+ "-----BEGIN X509 CRL-----\n",
+ "MIICZzCCAU8CAQEwDQYJKoZIhvcNAQELBQAweTELMAkGA1UEBhMCVVMxEzARBgNV\n",
+ "BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xEzARBgNVBAoM\n",
+ "Ck15IENvbXBhbnkxEzARBgNVBAMMCk15IFJvb3QgQ0ExEzARBgNVBAsMCk15IFJv\n",
+ "b3QgQ0EXDTI1MDEwMTAwMDAwMFoXDTI1MTIwMTAwMDAwMFowJzAlAhQcgAIu+B8k\n",
+ "Be6WphLcth/grHAeXhcNMjUwNDE3MTAxNjUxWqB5MHcwGAYDVR0UBBECDxnP/97a\n",
+ "dO3y9qRGDM7hQDAfBgNVHSMEGDAWgBTXYYkfk5aLdlQW6eV33Hy3ZRuAJDA6BgNV\n",
+ "HRwBAf8EMDAuoCagJKUihiBodHRwOi8vbG9jYWxob3N0OjgwMDAvY2FfY3JsLmRl\n",
+ "coEB/4IB/zANBgkqhkiG9w0BAQsFAAOCAQEAyLXs3RfVDDjTvvni2EyKRdnpODpY\n",
+ "hH5Q26NtA0S6/hXUOntR3N6jrqZQNo1Eg2iL9v6IzWnHEeWs4jSzMaOdAHW+iASY\n",
+ "COMIuNKY51E7dezIyY1Gjl3L9S/laGb0zPsgziAq8PFKP/FBC0uQbLmpbfvFSf0D\n",
+ "bZQzB0THvc3OjixEeRQPNkEApHPqmZpvr6ysQBpvzSQJhYaVT2JfUjAGBu1B6iIO\n",
+ "bwfzsFriiMUdnHp6I3mQ0LtzcxuzEDVifcE4dkl2PROsgwxiAbKXCYTDYGSTQ3Li\n",
+ "4ijLXcQYIZ3ZP6xs6qiYqphBF2ICGtMpD2XUxOSMfO42S2FYs/wZ38lnHg==\n",
+ "-----END X509 CRL-----\n",
+ NULL
+};
+
static X509 *test_root = NULL;
static X509 *test_leaf = NULL;
static X509 *test_root2 = NULL;
@@ -571,32 +606,45 @@ static int test_crl_empty_idp(void)
static int test_known_critical_crl(void)
{
- X509_CRL *known_critical_crl = CRL_from_strings(kKnownCriticalCRL);
- int r;
+ X509_CRL *crl = CRL_from_strings(kKnownCriticalCRL);
+ int test;
- r = TEST_ptr(known_critical_crl)
- && TEST_int_eq(verify(test_leaf, test_root,
- make_CRL_stack(known_critical_crl, NULL),
- X509_V_FLAG_CRL_CHECK, PARAM_TIME),
- X509_V_OK);
- X509_CRL_free(known_critical_crl);
- return r;
+ test = TEST_ptr_null(crl)
+ && TEST_err_r(ERR_LIB_ASN1, ASN1_R_TYPE_NOT_PRIMITIVE)
+ && TEST_err_r(ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT)
+ && TEST_err_s("CRL: malformed CRL issuing distribution point");
+
+ X509_CRL_free(crl);
+ return test;
}
-static int test_unknown_critical_crl(int n)
+static int test_unknown_critical_crl1(void)
{
- X509_CRL *unknown_critical_crl = CRL_from_strings(unknown_critical_crls[n]);
+ X509_CRL *unknown_critical_crl = CRL_from_strings(kUnknownCriticalCRL);
int r;
-
r = TEST_ptr(unknown_critical_crl)
&& TEST_int_eq(verify(test_leaf, test_root,
make_CRL_stack(unknown_critical_crl, NULL),
X509_V_FLAG_CRL_CHECK, PARAM_TIME),
X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
+
X509_CRL_free(unknown_critical_crl);
return r;
}
+static int test_unknown_critical_crl2(void)
+{
+ X509_CRL *crl;
+ int test;
+
+ test = TEST_ptr_null((crl = CRL_from_strings(kUnknownCriticalCRL2)))
+ && TEST_err_r(ERR_LIB_ASN1, ASN1_R_TYPE_NOT_PRIMITIVE)
+ && TEST_err_r(ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT)
+ && TEST_err_s("CRL: malformed CRL issuing distribution point");
+
+ return test;
+}
+
static int test_reuse_crl(int idx)
{
X509_CRL *result, *reused_crl = CRL_from_strings(kBasicCRL);
@@ -779,6 +827,34 @@ static int test_crl_number(void)
return test;
}
+static int test_crl_idp_malformed(void)
+{
+ X509_CRL *crl;
+ int test;
+
+ test = TEST_ptr_null((crl = CRL_from_strings(kCrlIDPWrongTag)))
+ && TEST_err_r(ERR_LIB_ASN1, ASN1_R_WRONG_TAG)
+ && TEST_err_r(ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT)
+ && TEST_err_s("CRL: malformed CRL issuing distribution point");
+
+ X509_CRL_free(crl);
+ return test;
+}
+
+static int test_crl_idp_malformed2(void)
+{
+ X509_CRL *crl;
+ int test;
+
+ test = TEST_ptr_null((crl = CRL_from_strings(kCrlIDPWrongTag2)))
+ && TEST_err_r(ERR_LIB_ASN1, ASN1_R_WRONG_TAG)
+ && TEST_err_r(ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT)
+ && TEST_err_s("CRL: malformed CRL issuing distribution point");
+
+ X509_CRL_free(crl);
+ return test;
+}
+
int setup_tests(void)
{
if (!TEST_ptr(test_root = X509_from_strings(kCRLTestRoot))
@@ -797,7 +873,10 @@ int setup_tests(void)
ADD_TEST(test_get_crl_fn_score);
ADD_TEST(test_crl_delta_indicator);
ADD_TEST(test_crl_number);
- ADD_ALL_TESTS(test_unknown_critical_crl, OSSL_NELEM(unknown_critical_crls));
+ ADD_TEST(test_crl_idp_malformed);
+ ADD_TEST(test_crl_idp_malformed2);
+ ADD_TEST(test_unknown_critical_crl1);
+ ADD_TEST(test_unknown_critical_crl2);
ADD_ALL_TESTS(test_reuse_crl, 6);
return 1;