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

anmolnar pushed a commit to branch branch-3.9
in repository https://gitbox.apache.org/repos/asf/zookeeper.git

commit 8b4266550dbac68fd27586c023bbaa714f9f0754
Author: Andor Molnar <[email protected]>
AuthorDate: Tue Jun 23 15:33:21 2026 -0500

    Quorum TLS in FIPS mode accepts hostname-mismatched peer certificates
---
 .../zookeeper/common/SSLContextAndOptions.java     | 32 ++++++++++++++++++----
 .../zookeeper/server/quorum/QuorumSSLTest.java     | 14 ++++++----
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git 
a/zookeeper-server/src/main/java/org/apache/zookeeper/common/SSLContextAndOptions.java
 
b/zookeeper-server/src/main/java/org/apache/zookeeper/common/SSLContextAndOptions.java
index c712f6acb..627cc17b3 100644
--- 
a/zookeeper-server/src/main/java/org/apache/zookeeper/common/SSLContextAndOptions.java
+++ 
b/zookeeper-server/src/main/java/org/apache/zookeeper/common/SSLContextAndOptions.java
@@ -47,7 +47,7 @@ public class SSLContextAndOptions {
     private final X509Util.ClientAuth clientAuth;
     private final SSLContext sslContext;
     private final int handshakeDetectionTimeoutMillis;
-
+    private final ZKConfig zkConfig;
 
     /**
      * Note: constructor is intentionally package-private, only the X509Util 
class should be creating instances of this
@@ -59,10 +59,11 @@ public class SSLContextAndOptions {
     SSLContextAndOptions(final X509Util x509Util, final ZKConfig config, final 
SSLContext sslContext) {
         this.x509Util = requireNonNull(x509Util);
         this.sslContext = requireNonNull(sslContext);
-        this.enabledProtocols = getEnabledProtocols(requireNonNull(config), 
sslContext);
-        this.cipherSuites = getCipherSuites(config);
-        this.clientAuth = getClientAuth(config);
-        this.handshakeDetectionTimeoutMillis = 
getHandshakeDetectionTimeoutMillis(config);
+        this.zkConfig = requireNonNull(config);
+        this.enabledProtocols = getEnabledProtocols(zkConfig, sslContext);
+        this.cipherSuites = getCipherSuites(zkConfig);
+        this.clientAuth = getClientAuth(zkConfig);
+        this.handshakeDetectionTimeoutMillis = 
getHandshakeDetectionTimeoutMillis(zkConfig);
     }
 
     public SSLContext getSSLContext() {
@@ -144,6 +145,27 @@ private void configureSslParameters(SSLParameters 
sslParameters, boolean isClien
                 break;
             }
         }
+
+        // In FIPS-mode we deal with hostname verification here,
+        // while in non-FIPS mode verification is handled by ZKTrustManager.
+        if (X509Util.getFipsMode(zkConfig)) {
+            String clientOrServer = isClientSocket ? "Server" : "Client";
+            if (isClientSocket) {
+                if (x509Util.isServerHostnameVerificationEnabled(zkConfig)) {
+                    sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("{} hostname verification: enabled HTTPS 
style endpoint identification algorithm", clientOrServer);
+                    }
+                }
+            } else {
+                if (x509Util.isClientHostnameVerificationEnabled(zkConfig)) {
+                    sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("{} hostname verification: enabled HTTPS 
style endpoint identification algorithm", clientOrServer);
+                    }
+                }
+            }
+        }
     }
 
     private String[] getEnabledProtocols(final ZKConfig config, final 
SSLContext sslContext) {
diff --git 
a/zookeeper-server/src/test/java/org/apache/zookeeper/server/quorum/QuorumSSLTest.java
 
b/zookeeper-server/src/test/java/org/apache/zookeeper/server/quorum/QuorumSSLTest.java
index 95ff31be9..b905422b3 100644
--- 
a/zookeeper-server/src/test/java/org/apache/zookeeper/server/quorum/QuorumSSLTest.java
+++ 
b/zookeeper-server/src/test/java/org/apache/zookeeper/server/quorum/QuorumSSLTest.java
@@ -621,7 +621,7 @@ private void stopAppendConfigRestartAll(Map<Integer, 
MainThread> members, String
         }
     }
 
-    @TestNoFipsOnly
+    @TestBothFipsModes
     @Timeout(value = 5, unit = TimeUnit.MINUTES)
     public void testHostnameVerificationWithInvalidHostname(boolean 
fipsEnabled) throws Exception {
         System.setProperty(quorumX509Util.getFipsModeProperty(), 
Boolean.toString(fipsEnabled));
@@ -639,7 +639,7 @@ public void 
testHostnameVerificationWithInvalidHostname(boolean fipsEnabled) thr
         testHostnameVerification(badhostnameKeystorePath, false);
     }
 
-    @TestNoFipsOnly
+    @TestBothFipsModes
     @Timeout(value = 5, unit = TimeUnit.MINUTES)
     public void testHostnameVerificationWithInvalidIPAddress(boolean 
fipsEnabled) throws Exception {
         System.setProperty(quorumX509Util.getFipsModeProperty(), 
Boolean.toString(fipsEnabled));
@@ -657,7 +657,7 @@ public void 
testHostnameVerificationWithInvalidIPAddress(boolean fipsEnabled) th
         testHostnameVerification(badhostnameKeystorePath, false);
     }
 
-    @TestNoFipsOnly
+    @TestBothFipsModes
     @Timeout(value = 5, unit = TimeUnit.MINUTES)
     public void 
testHostnameVerificationWithInvalidIpAddressAndInvalidHostname(boolean 
fipsEnabled) throws Exception {
         System.setProperty(quorumX509Util.getFipsModeProperty(), 
Boolean.toString(fipsEnabled));
@@ -676,7 +676,7 @@ public void 
testHostnameVerificationWithInvalidIpAddressAndInvalidHostname(boole
         testHostnameVerification(badhostnameKeystorePath, false);
     }
 
-    @TestNoFipsOnly
+    @TestBothFipsModes
     @Timeout(value = 5, unit = TimeUnit.MINUTES)
     public void 
testHostnameVerificationForInvalidMultiAddressServerConfig(boolean fipsEnabled) 
throws Exception {
         System.setProperty(quorumX509Util.getFipsModeProperty(), 
Boolean.toString(fipsEnabled));
@@ -698,6 +698,10 @@ public void 
testHostnameVerificationForInvalidMultiAddressServerConfig(boolean f
         testHostnameVerification(badhostnameKeystorePath, false);
     }
 
+    /**
+     * This test is NoFips only, because it needs reverse Dns lookup for 
client hostname verification,
+     * which is not supported in Fips mode.
+     */
     @TestNoFipsOnly
     @Timeout(value = 5, unit = TimeUnit.MINUTES)
     public void 
testHostnameVerificationWithInvalidIpAddressAndValidHostname(boolean 
fipsEnabled) throws Exception {
@@ -719,7 +723,7 @@ public void 
testHostnameVerificationWithInvalidIpAddressAndValidHostname(boolean
         testHostnameVerification(badhostnameKeystorePath, true);
     }
 
-    @TestNoFipsOnly
+    @TestBothFipsModes
     @Timeout(value = 5, unit = TimeUnit.MINUTES)
     public void 
testHostnameVerificationWithValidIpAddressAndInvalidHostname(boolean 
fipsEnabled) throws Exception {
         System.setProperty(quorumX509Util.getFipsModeProperty(), 
Boolean.toString(fipsEnabled));

Reply via email to