You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by an...@apache.org on 2026/09/02 20:02:15 UTC
(zookeeper) 01/03: Quorum TLS in FIPS mode accepts hostname-mismatched peer certificates
This is an automated email from the ASF dual-hosted git repository.
anmolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zookeeper.git
commit ead4f69bb1a55bd484db88b2eed7b8752331a841
Author: Andor Molnar <an...@cloudera.com>
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 167133424..23ce60728 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));