]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
CRL: Reject CRLs with malformed Issuing Distribution Point
authorDaniel Kubec <kubec@openssl.org>
Wed, 25 Feb 2026 09:51:08 +0000 (10:51 +0100)
committerNeil Horman <nhorman@openssl.org>
Fri, 27 Feb 2026 20:06:50 +0000 (15:06 -0500)
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)

CHANGES.md
crypto/x509/x_crl.c
test/crltest.c

index 5ca61c80e7935d9b690abe0f69231f4b61c6fffb..9fe41d31773eeb0247dd5ddad6709b74f45c6b73 100644 (file)
@@ -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.
 
index 89a64fec03ec17a216eae1d0e427ca78725a8929..f11e7b018b0789decb252e25fdba3a9be4d14447 100644 (file)
@@ -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;
index b13d5977ce1fab2928d14ca55f4b559fe7480839..245d2205f4977b19f5cd83f594c0480ba8281449 100644 (file)
@@ -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;