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));
