This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 6907d47ea2 Fix OpenSSL with OpenSSL trust, server cert in a keys tore 
and a CRL
6907d47ea2 is described below

commit 6907d47ea2d4c3f13ef9f65b0c51ff2fd485c252
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Aug 12 21:48:27 2026 +0100

    Fix OpenSSL with OpenSSL trust, server cert in a keys tore and a CRL
---
 .../tomcat/util/net/openssl/OpenSSLContext.java    |   8 +-
 .../util/net/openssl/panama/OpenSSLContext.java    |  55 ++++-----
 .../org/apache/tomcat/util/net/TestCrlSupport.java | 124 +++++++++++++++++++++
 test/org/apache/tomcat/util/net/TesterSupport.java |  36 ++++--
 test/org/apache/tomcat/util/net/empty-crl.pem      |  18 +++
 test/org/apache/tomcat/util/net/populated-crl.pem  |  20 ++++
 webapps/docs/changelog.xml                         |   4 +
 7 files changed, 225 insertions(+), 40 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java 
b/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
index 3528a913b4..3bcbbb3d6b 100644
--- a/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
+++ b/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
@@ -546,10 +546,6 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
             // Set certificate chain file
             SSLContext.setCertificateChainFile(state.ctx,
                     
SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), false);
-            // Set revocation
-            SSLContext.setCARevocation(state.ctx,
-                    
SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()),
-                    
SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()));
         } else {
             String alias = certificate.getCertificateKeyAlias();
             X509KeyManager x509KeyManager = 
certificate.getCertificateKeyManager();
@@ -570,6 +566,10 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
                 SSLContext.addChainCertificateRaw(state.ctx, 
chain[i].getEncoded());
             }
         }
+        // Set revocation
+        SSLContext.setCARevocation(state.ctx,
+                
SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()),
+                
SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()));
     }
 
 
diff --git a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java 
b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
index 976985472c..48e4296632 100644
--- a/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
+++ b/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLContext.java
@@ -1199,31 +1199,6 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
                         BIO_free(certificateChainBIO);
                     }
                 }
-                // Set revocation
-                MemorySegment certificateStore = 
SSL_CTX_get_cert_store(state.sslCtx);
-                if (sslHostConfig.getCertificateRevocationListFile() != null) {
-                    MemorySegment x509Lookup = 
X509_STORE_add_lookup(certificateStore, X509_LOOKUP_file());
-                    var certificateRevocationListFileNative = 
localArena.allocateFrom(
-                            
SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()));
-                    if (X509_LOOKUP_load_file(x509Lookup, 
certificateRevocationListFileNative,
-                            X509_FILETYPE_PEM()) <= 0) {
-                        throw new IllegalArgumentException(sm.getString(
-                                
"openssl.errorLoadingCertificateRevocationListWithError",
-                                
sslHostConfig.getCertificateRevocationListFile(), 
OpenSSLLibrary.getLastError()));
-                    }
-                }
-                if (sslHostConfig.getCertificateRevocationListPath() != null) {
-                    MemorySegment x509Lookup = 
X509_STORE_add_lookup(certificateStore, X509_LOOKUP_hash_dir());
-                    var certificateRevocationListPathNative = 
localArena.allocateFrom(
-                            
SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()));
-                    if (X509_LOOKUP_add_dir(x509Lookup, 
certificateRevocationListPathNative,
-                            X509_FILETYPE_PEM()) <= 0) {
-                        throw new IllegalArgumentException(sm.getString(
-                                
"openssl.errorLoadingCertificateRevocationListWithError",
-                                
sslHostConfig.getCertificateRevocationListPath(), 
OpenSSLLibrary.getLastError()));
-                    }
-                }
-                X509_STORE_set_flags(certificateStore, X509_V_FLAG_CRL_CHECK() 
| X509_V_FLAG_CRL_CHECK_ALL());
             } finally {
                 BIO_free(certificateBIO);
             }
@@ -1318,6 +1293,36 @@ public class OpenSSLContext implements 
org.apache.tomcat.util.net.SSLContext {
                 BIO_free(keyBIO);
             }
         }
+        // Set revocation
+        boolean crlPresent = false;
+        MemorySegment certificateStore = SSL_CTX_get_cert_store(state.sslCtx);
+        if (sslHostConfig.getCertificateRevocationListFile() != null) {
+            MemorySegment x509Lookup = X509_STORE_add_lookup(certificateStore, 
X509_LOOKUP_file());
+            var certificateRevocationListFileNative = localArena.allocateFrom(
+                    
SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListFile()));
+            if (X509_LOOKUP_load_file(x509Lookup, 
certificateRevocationListFileNative,
+                    X509_FILETYPE_PEM()) <= 0) {
+                throw new IllegalArgumentException(sm.getString(
+                        
"openssl.errorLoadingCertificateRevocationListWithError",
+                        sslHostConfig.getCertificateRevocationListFile(), 
OpenSSLLibrary.getLastError()));
+            }
+            crlPresent = true;
+        }
+        if (sslHostConfig.getCertificateRevocationListPath() != null) {
+            MemorySegment x509Lookup = X509_STORE_add_lookup(certificateStore, 
X509_LOOKUP_hash_dir());
+            var certificateRevocationListPathNative = localArena.allocateFrom(
+                    
SSLHostConfig.adjustRelativePath(sslHostConfig.getCertificateRevocationListPath()));
+            if (X509_LOOKUP_add_dir(x509Lookup, 
certificateRevocationListPathNative,
+                    X509_FILETYPE_PEM()) <= 0) {
+                throw new IllegalArgumentException(sm.getString(
+                        
"openssl.errorLoadingCertificateRevocationListWithError",
+                        sslHostConfig.getCertificateRevocationListPath(), 
OpenSSLLibrary.getLastError()));
+            }
+            crlPresent = true;
+        }
+        if (crlPresent) {
+            X509_STORE_set_flags(certificateStore, X509_V_FLAG_CRL_CHECK() | 
X509_V_FLAG_CRL_CHECK_ALL());
+        }
         return true;
     }
 
diff --git a/test/org/apache/tomcat/util/net/TestCrlSupport.java 
b/test/org/apache/tomcat/util/net/TestCrlSupport.java
new file mode 100644
index 0000000000..aee75538af
--- /dev/null
+++ b/test/org/apache/tomcat/util/net/TestCrlSupport.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.net;
+
+import java.io.File;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.net.ssl.SSLHandshakeException;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+@RunWith(Parameterized.class)
+public class TestCrlSupport extends TomcatBaseTest {
+
+    @Parameters(name = "{0} with OpenSSL trust {2}, revoked cert {4}, CRL {5}")
+    public static Collection<Object[]> parameters() {
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Boolean clientCertificateIsRevoked : booleans) {
+            for (Boolean crlIsPopulated : booleans) {
+                parameterSets.add(new Object[] { "JSSE", Boolean.FALSE, 
Boolean.FALSE,
+                        "org.apache.tomcat.util.net.jsse.JSSEImplementation", 
clientCertificateIsRevoked, crlIsPopulated});
+                parameterSets.add(new Object[] { "OpenSSL", Boolean.TRUE, 
Boolean.TRUE,
+                        
"org.apache.tomcat.util.net.openssl.OpenSSLImplementation", 
clientCertificateIsRevoked, crlIsPopulated });
+                parameterSets.add(new Object[] { "OpenSSL", Boolean.TRUE, 
Boolean.FALSE,
+                        
"org.apache.tomcat.util.net.openssl.OpenSSLImplementation", 
clientCertificateIsRevoked, crlIsPopulated });
+                parameterSets.add(new Object[] { "OpenSSL-FFM", Boolean.TRUE, 
Boolean.TRUE,
+                        
"org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation", 
clientCertificateIsRevoked, crlIsPopulated });
+                parameterSets.add(new Object[] { "OpenSSL-FFM", Boolean.TRUE, 
Boolean.FALSE,
+                        
"org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation", 
clientCertificateIsRevoked, crlIsPopulated });
+            }
+        }
+
+        return parameterSets;
+    }
+
+    @Parameter(0)
+    public String connectorName;
+
+    @Parameter(1)
+    public boolean useOpenSSL;
+
+    @Parameter(2)
+    public boolean useOpenSSLTrust;
+
+    @Parameter(3)
+    public String sslImplementationName;
+
+    @Parameter(4)
+    public boolean clientCertificateIsRevoked;
+
+    @Parameter(5)
+    public boolean crlIsPopulated;
+
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        Tomcat tomcat = getTomcatInstance();
+        TesterSupport.configureSSLImplementation(tomcat, 
sslImplementationName, useOpenSSL);
+        TesterSupport.configureClientCertContext(tomcat, useOpenSSLTrust, 
TesterSupport.CLIENT_JKS, TesterSupport.CLIENT_CRL_JKS);
+        // Configure the CRL
+        if (crlIsPopulated) {
+            
tomcat.getConnector().findSslHostConfigs()[0].setCertificateRevocationListFile(
+                    new File(TesterSupport.POPULATED_CRL).getAbsolutePath());
+        } else {
+            
tomcat.getConnector().findSslHostConfigs()[0].setCertificateRevocationListFile(
+                    new File(TesterSupport.EMPTY_CRL).getAbsolutePath());
+        }
+    }
+
+
+    @Test
+    public void testCrlClient() throws Exception {
+        if (clientCertificateIsRevoked) {
+            TesterSupport.configureClientSsl(false, 
TesterSupport.CLIENT_CRL_JKS);
+        } else {
+            TesterSupport.configureClientSsl(false, TesterSupport.CLIENT_JKS);
+        }
+
+        getTomcatInstance().start();
+
+        // Protected resource
+        String body;
+        try {
+            ByteChunk res = getUrl("https://localhost:"; + getPort() + 
"/protected");
+            body = res.toString();
+        } catch (SSLHandshakeException | SocketException e) {
+            // May be observed when client certificate is rejected
+            body = "FAILED";
+        }
+
+        if (!clientCertificateIsRevoked || !crlIsPopulated) {
+            Assert.assertEquals("OK-" + TesterSupport.ROLE, body);
+        } else {
+            Assert.assertFalse(body, body.startsWith("OK-"));
+        }
+    }
+}
diff --git a/test/org/apache/tomcat/util/net/TesterSupport.java 
b/test/org/apache/tomcat/util/net/TesterSupport.java
index 63ce9a3585..9de53b213b 100644
--- a/test/org/apache/tomcat/util/net/TesterSupport.java
+++ b/test/org/apache/tomcat/util/net/TesterSupport.java
@@ -105,6 +105,8 @@ public final class TesterSupport {
     public static final String LOCALHOST_CRL_RSA_JKS = SSL_DIR + 
"localhost-crl-rsa.jks";
     public static final String CLIENT_CRL_JKS = SSL_DIR + "user2-crl.jks";
     public static final String CLIENT_CRL_LONG_JKS = SSL_DIR + 
"user3-crl-long.jks";
+    public static final String EMPTY_CRL = SSL_DIR + "empty-crl.pem";
+    public static final String POPULATED_CRL = SSL_DIR + "populated-crl.pem";
     public static final boolean TLSV13_AVAILABLE;
 
     public static final String ROLE = "testrole";
@@ -318,7 +320,11 @@ public final class TesterSupport {
     }
 
     public static void configureClientCertContext(Tomcat tomcat) {
-        initSsl(tomcat);
+        configureClientCertContext(tomcat, false, CLIENT_JKS);
+    }
+
+    public static void configureClientCertContext(Tomcat tomcat, boolean 
useOpenSSLTrust, String... keyStores) {
+        initSsl(tomcat, useOpenSSLTrust);
 
         /* When running on Java 11, TLSv1.3 is enabled by default. The JSSE
          * implementation of TLSv1.3 does not support
@@ -356,17 +362,25 @@ public final class TesterSupport {
             throw new RuntimeException(ex);
         }
 
-        String cn = "NOTFOUND";
-        try {
-            KeyStore ks = getKeyStore(CLIENT_JKS);
-            X509Certificate cert = 
(X509Certificate)ks.getCertificate(CLIENT_ALIAS);
-            cn = cert.getSubjectX500Principal().toString();
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
+        // Add the user for each certificate in each key store to the realm 
and assign each user the standard role
+        for (String keyStore : keyStores) {
+            String cn = "NOTFOUND";
+            try {
+                KeyStore ks = getKeyStore(keyStore);
+                Enumeration<String> aliases = ks.aliases();
+                while (aliases.hasMoreElements()) {
+                    String alias = aliases.nextElement();
+                    X509Certificate cert = 
(X509Certificate)ks.getCertificate(alias);
+                    cn = cert.getSubjectX500Principal().toString();
+
+                    realm.addUser(cn, "not used");
+                    realm.addUserRole(cn, ROLE);
+                }
+            } catch (Exception ex) {
+                throw new RuntimeException(ex);
+            }
 
-        realm.addUser(cn, "not used");
-        realm.addUserRole(cn, ROLE);
+        }
         ctx.setRealm(realm);
 
         // Configure the authenticator
diff --git a/test/org/apache/tomcat/util/net/empty-crl.pem 
b/test/org/apache/tomcat/util/net/empty-crl.pem
new file mode 100644
index 0000000000..e4b6c011d8
--- /dev/null
+++ b/test/org/apache/tomcat/util/net/empty-crl.pem
@@ -0,0 +1,18 @@
+-----BEGIN X509 CRL-----
+MIIC7zCB2AIBATANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMCVVMxCzAJBgNV
+BAgTAkRFMRMwEQYDVQQHEwpXaWxtaW5ndG9uMScwJQYDVQQKEx5UaGUgQXBhY2hl
+IFNvZnR3YXJlIEZvdW5kYXRpb24xGjAYBgNVBAsTEUFwYWNoZSBUb21jYXQgUE1D
+MR4wHAYDVQQDExVBcGFjaGUgVG9tY2F0IFRlc3QgQ0EXDTI2MDgxMjEzMTkyMloX
+DTI4MDgxMTEzMTkyMlqgDzANMAsGA1UdFAQEAgIQADANBgkqhkiG9w0BAQUFAAOC
+AgEAHh0y6uXKHskWDcgUa0/7qA7xI9qArf3Zgxjdzp02Ys8drYh1mq9SDAfLYwNP
+nPFF0B+dTGVWo0/WzllykMZkhS3qbOu1EhBEobxBidc2yatqsGMqmT6otxr1JtFh
+LRdPWo4/g5SrU1lu4rH7L+7tI2aDBogqYbO4uW09fZ3MM1MCMxEt+KUTs40WKmAy
+QrC9b2hjviVKl+3WwmZRRx1aVewercmCwNeZXh9B8qLvB/Py8dJEymZhaBKy2Rs/
+1uN0P5vJ57eAUoNe9XRZm41opqDGyPdRX5QgFjlIhmaTgQ9HxVLCwRHTD7mPEjBZ
+OUDPPvzBmWux4TJRGo/H/xlIEzdEiY8xnM0xJSMPHHw4nWwVo7ggMfvGYol2ojA4
+CDYEw03T85RwCeerYeVLz9b8PCkcDHjqlJzkEu0NtK2XibWiSECh5psK30KYzH0G
+c6QLY20tDbwl6mJxBB6nvDdPNF8a6qq2+AyygZt2lKzxEWRbvL4mqukW9neFOc5m
+LLT0SGLvULEAG3WEOGPL2zgCsNKrfu54PbjaOBzCFFlZc2Sizi2+Mlik0ThSGjaa
+AXlviXQ6mQ0bLHAelkXBRKGT/gNbDRfvx1BSFL6hYXWRyM97KW5S9P4iFne/Biwu
+ovgWmYNtZ0N6vv1SBxaEVtO7Yy5bHEFpoZsme9Hl04/Ezr0=
+-----END X509 CRL-----
diff --git a/test/org/apache/tomcat/util/net/populated-crl.pem 
b/test/org/apache/tomcat/util/net/populated-crl.pem
new file mode 100644
index 0000000000..a007012f9a
--- /dev/null
+++ b/test/org/apache/tomcat/util/net/populated-crl.pem
@@ -0,0 +1,20 @@
+-----BEGIN X509 CRL-----
+MIIDMTCCARkCAQEwDQYJKoZIhvcNAQEFBQAwgZQxCzAJBgNVBAYTAlVTMQswCQYD
+VQQIEwJERTETMBEGA1UEBxMKV2lsbWluZ3RvbjEnMCUGA1UEChMeVGhlIEFwYWNo
+ZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFjaGUgVG9tY2F0IFBN
+QzEeMBwGA1UEAxMVQXBhY2hlIFRvbWNhdCBUZXN0IENBFw0yNjA4MTIxMzE5MjJa
+Fw0yODA4MTExMzE5MjJaMD8wEwICEAEXDTI2MDgxMjEzMTkyMlowEwICEAMXDTI2
+MDgxMjEzMTkyMlowEwICEAYXDTI2MDgxMjEzMTkyMlqgDzANMAsGA1UdFAQEAgIQ
+ATANBgkqhkiG9w0BAQUFAAOCAgEAFiLND1ZwZ0qIuuIA9NxHjkoqULtnbUxTAQzH
+ZYD3/TYtM1mrvs/dXZh8MYfW/dMtdEq4lV79BoJVYFGVzNhweO5xet66BHwAXehp
+6GFDu7n88Q/oSfvv14WtlyNrpJObYHRJPXDzEqSdamQSQKzn+Yjf3VQATKZFG73P
+ltxDTYfT0OGjrwcpyqqVtteJ11FOgrJ2LORFp+i2eQxWsjxZJjcL+xZmM49sVWns
+7KK1FKmy3QdDCezG2tgAym+j/wqTj1el1aLBLt7Wn6w1W6XSM7TEtHCuonpYnbhy
+GZuDcGYlcco9xZZi8Xu6Kvx2usJsm6odQI4GIa4a/4p2JMz3vGsiuOfEreVz8z6e
+Y1RR9rlzrhbW9cgX3cROoUarai3Gpj97DFMQxtBYkOGlpm5K50NROPNNYk/UBUCD
+LgxukOIqQd8DYx843GoJfqKXl/AlO4YwqWLtwWRSuNZ7QUmG6S4Af4BUBuZ3yEze
+oihjTcIt46ICjrUZZ1ATZpf0lUGi048Cp4ww60pNJZ/PbO5JcpEShUKCsKr5z8XK
+K7sRWnhzEi9HCNLUqjXZ/xeI4UAK86wT24n+dZbLZ51Nsj4KIsReQubX/ucZ3WrL
+U869KvDeSkMWtbm9iRX/wYJQvDePtNy6uxEr01C2F/WHtWgH2wAma73F4qxbndy3
+hAYNg4M=
+-----END X509 CRL-----
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 9e75a239d3..3676d6de03 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -227,6 +227,10 @@
         Small per performance optimisation. Don't waste cycles swallowing an 
AJP
         response body when the connection is going to be closed. (markt)
       </fix>
+      <fix>
+        Fix OpenSSL support for CRLs when using OpenSSL trust with the server
+        key held in a Java key store. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to