diff --git a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md index a4fccf1f94e..6ed7c9f4a37 100644 --- a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md +++ b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md @@ -1687,7 +1687,7 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp Specifies the file path to a Java keystore containing the local credentials to be used for client and quorum TLS connections, and the password to unlock the file. - + * *ssl.keyStore.passwordPath* and *ssl.quorum.keyStore.passwordPath* : (Java system properties: **zookeeper.ssl.keyStore.passwordPath** and **zookeeper.ssl.quorum.keyStore.passwordPath**) **New in 3.8.0:** @@ -1762,20 +1762,59 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp **New in 3.9.4:** Specifies whether the client's hostname verification is enabled in client and quorum TLS negotiation process. This option requires the corresponding *hostnameVerification* option to be `true`, or it will be ignored. + *ssl.clientHostnameVerification* has no effect, as the client does not receive TLS connections. Default: true for quorum, false for clients * *ssl.crl* and *ssl.quorum.crl* : (Java system properties: **zookeeper.ssl.crl** and **zookeeper.ssl.quorum.crl**) **New in 3.5.5:** Specifies whether Certificate Revocation List is enabled in client and quorum TLS protocols. + This option requires that the *ssl.quorum.trustStore.location* is set, or it will be ignored. + Enabling this option will set the JVM global "com.sun.security.enableCRLDP" system property to true. Default: false * *ssl.ocsp* and *ssl.quorum.ocsp* : (Java system properties: **zookeeper.ssl.ocsp** and **zookeeper.ssl.quorum.ocsp**) **New in 3.5.5:** Specifies whether Online Certificate Status Protocol is enabled in client and quorum TLS protocols. + This option requires that the *ssl.trustStore.location* is set, or it will be ignored for the client. + Enabling this option will set the JVM global "com.sun.security.enableCRLDP" system property to true. + Enabling this option will set JVM global "ocsp.enable" security property to true. Default: false +* *ssl.revocationEnabled* and *ssl.quorum.revocationEnabled* : + (Java system properties: **zookeeper.ssl.revocationEnabled** and **zookeeper.ssl.quorum.revocationEnabled**) + **New in 3.10.0:** + Specifies whether Certificate Revocation checking is enabled in client and quorum TLS protocols. + This option requires that the *ssl.trustStore.location* is set, or it will be ignored for the client. + This options has no side effects on JVM global system properties. + Default: if the option is not set, or set to the value "default" then the JVM default settings + are used. + +* *ssl.disableLegacyRevocationLogic* and *ssl.quorum.disableLegacyRevocationLogic* : + (Java system properties: **zookeeper.ssl.disableLegacyRevocationLogic** and **zookeeper.ssl.quorum.disableLegacyRevocationLogic**) + **New in 3.10.0:** + Traditionally, ZK has always explicitly disabled or enabled certificate revocation in the trustmanager based on the values of the + *ssl.ocsp* and *ssl.crl* properties. This made it impossible to completely rely on System properties for configuring + revocation checking for ZooKeeper. + Setting this property disables the logic for implicitly setting the certificate revocation check status on the trustManager, + allowing the JVM default behavior to be used. + It is recommended to set *ssl.ocsp* and *ssl.crl* to false, and *ssl.disableLegacyRevocationLogic* to true. + With those settings, ZK will use the JVM default CRL/OCSP settings, and not change the defaults. *ssl.revocationEnabled* + can still be used to enable/disable revocation checking for the custom SSL truststore. + This option requires that the *ssl.trustStore.location* is set, or it will be ignored for the client. + Default: false. + +* *ssl.tcnative.ocsp* and *ssl.quorum.tcnative.ocsp* : + (Java system properties: **zookeeper.ssl.tcnative.ocsp** and **zookeeper.ssl.quorum.tcnative.ocsp**) + **New in 3.10.0:** + Specifies whether OCSP stapling is requested by the client. + This option has no effect unless the the OpenSSL tcnative SSL provider with the OpenSSL library is used. + Note that Zookeeper uses the the BoringSSL tcnative library by default, so even is the "OpenSSL" SSL provider is requested, + this won't do anything unless the default BoringSSL library is replaced with the OpenSSL one. + This options has no side effects on JVM global system properties. + Default: if the option is not set, or set to the value "default" then the library default is used. + * *ssl.clientAuth* and *ssl.quorum.clientAuth* : (Java system properties: **zookeeper.ssl.clientAuth** and **zookeeper.ssl.quorum.clientAuth**) **Added in 3.5.5, but broken until 3.5.7:** @@ -1785,7 +1824,8 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp * "want": server will "request" client authentication * "need": server will "require" client authentication - Default: "need" + *ssl.clientHostnameVerification* has no effect. + Default: "need" * *ssl.handshakeDetectionTimeoutMillis* and *ssl.quorum.handshakeDetectionTimeoutMillis* : (Java system properties: **zookeeper.ssl.handshakeDetectionTimeoutMillis** and **zookeeper.ssl.quorum.handshakeDetectionTimeoutMillis**) diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/ClientX509Util.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/ClientX509Util.java index 9aa03ae491a..07e37e394e0 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/common/ClientX509Util.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/ClientX509Util.java @@ -19,6 +19,7 @@ package org.apache.zookeeper.common; import io.netty.handler.ssl.DelegatingSslContext; +import io.netty.handler.ssl.OpenSsl; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslProvider; @@ -79,7 +80,21 @@ public SslContext createNettySslContextForClient(ZKConfig config) sslContextBuilder.trustManager(tm); } - sslContextBuilder.enableOcsp(config.getBoolean(getSslOcspEnabledProperty())); + SslProvider sslProvider = getSslProvider(config); + sslContextBuilder.sslProvider(sslProvider); + if (sslProvider == SslProvider.OPENSSL || sslProvider == SslProvider.OPENSSL_REFCNT) { + boolean ocspEnabled = config.getBoolean(getSslOcspEnabledProperty()); + logTcnativeOcsp(ocspEnabled); + // Set it even in unsupported, tcnative will just ignore it + sslContextBuilder.enableOcsp(ocspEnabled); + } + // Explicit option takes precedence if set + if (config.getTristate(getSslTcnativeOcspEnabledProperty()).isTrue()) { + logTcnativeOcsp(true); + sslContextBuilder.enableOcsp(true); + } else if (config.getTristate(getSslTcnativeOcspEnabledProperty()).isFalse()) { + sslContextBuilder.enableOcsp(false); + } String[] enabledProtocols = getEnabledProtocols(config); if (enabledProtocols != null) { sslContextBuilder.protocols(enabledProtocols); @@ -88,17 +103,25 @@ public SslContext createNettySslContextForClient(ZKConfig config) if (enabledCiphers != null) { sslContextBuilder.ciphers(enabledCiphers); } - sslContextBuilder.sslProvider(getSslProvider(config)); SslContext sslContext1 = sslContextBuilder.build(); - if (getFipsMode(config) && isServerHostnameVerificationEnabled(config)) { + if ((getFipsMode(config) || config.getProperty(getSslKeystoreLocationProperty(), "").isEmpty()) + && isServerHostnameVerificationEnabled(config)) { return addHostnameVerification(sslContext1, "Server"); } else { return sslContext1; } } + private void logTcnativeOcsp(boolean enable) { + if (enable && !OpenSsl.isOcspSupported()) { + // SslContextBuilder.enableOcsp() doesn't do anything, unless the default BoringSSL + // tcnative dependency is replaced with an OpenSsl one. + LOG.warn("Trying to enable OCSP for tcnative OpenSSL provider, but it is not supported. The setting will be ignored"); + } + } + public SslContext createNettySslContextForServer(ZKConfig config) throws X509Exception.SSLContextException, X509Exception.KeyManagerException, X509Exception.TrustManagerException, SSLException { String keyStoreLocation = config.getProperty(getSslKeystoreLocationProperty(), ""); @@ -123,7 +146,16 @@ public SslContext createNettySslContextForServer(ZKConfig config, KeyManager key sslContextBuilder.trustManager(trustManager); } - sslContextBuilder.enableOcsp(config.getBoolean(getSslOcspEnabledProperty())); + SslProvider sslProvider = getSslProvider(config); + sslContextBuilder.sslProvider(sslProvider); + if (sslProvider == SslProvider.OPENSSL || sslProvider == SslProvider.OPENSSL_REFCNT) { + sslContextBuilder.enableOcsp(config.getBoolean(getSslOcspEnabledProperty())); + } + if (config.getTristate(getSslTcnativeOcspEnabledProperty()).isTrue()) { + sslContextBuilder.enableOcsp(true); + } else if (config.getTristate(getSslTcnativeOcspEnabledProperty()).isFalse()) { + sslContextBuilder.enableOcsp(false); + } String[] enabledProtocols = getEnabledProtocols(config); if (enabledProtocols != null) { sslContextBuilder.protocols(enabledProtocols); @@ -133,7 +165,6 @@ public SslContext createNettySslContextForServer(ZKConfig config, KeyManager key if (enabledCiphers != null) { sslContextBuilder.ciphers(enabledCiphers); } - sslContextBuilder.sslProvider(getSslProvider(config)); SslContext sslContext1 = sslContextBuilder.build(); @@ -191,15 +222,21 @@ private TrustManager getTrustManager(ZKConfig config) throws X509Exception.Trust boolean sslCrlEnabled = config.getBoolean(getSslCrlEnabledProperty()); boolean sslOcspEnabled = config.getBoolean(getSslOcspEnabledProperty()); + TriState sslRevocationEnabled = config.getTristate(getSslRevocationEnabledProperty()); + boolean disableLegacyRevocationLogic = config.getBoolean(getSslDisableLegacyRevocationLogicProperty()); boolean sslServerHostnameVerificationEnabled = isServerHostnameVerificationEnabled(config); boolean sslClientHostnameVerificationEnabled = isClientHostnameVerificationEnabled(config); if (trustStoreLocation.isEmpty()) { LOG.warn("{} not specified", getSslTruststoreLocationProperty()); + LOG.info("The following options are ignored: {}, {}, {}, {}.\n{} and {} will behave as in FIPS mode.", + getSslCrlEnabledProperty(), getSslOcspEnabledProperty(), getSslRevocationEnabledProperty(), + getSslDisableLegacyRevocationLogicProperty(), getSslHostnameVerificationEnabledProperty(), + getSslClientHostnameVerificationEnabledProperty()); return null; } else { return createTrustManager(trustStoreLocation, trustStorePassword, trustStoreType, - sslCrlEnabled, sslOcspEnabled, sslServerHostnameVerificationEnabled, + sslCrlEnabled, sslOcspEnabled, sslRevocationEnabled, disableLegacyRevocationLogic, sslServerHostnameVerificationEnabled, sslClientHostnameVerificationEnabled, getFipsMode(config)); } } diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/TriState.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/TriState.java new file mode 100644 index 00000000000..373200a0087 --- /dev/null +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/TriState.java @@ -0,0 +1,53 @@ +/* + * 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.zookeeper.common; + +/** + * For storing configuration parameters where want to distinguish a default case + * in addition to true and false. + */ +public enum TriState { + True, False, Default; + + public static TriState parse(String value) { + if (value == null || value.equalsIgnoreCase("default")) { + return TriState.Default; + } else if (value.equalsIgnoreCase("true")) { + return TriState.True; + } else { + return TriState.False; + } + } + + public boolean isTrue() { + return this == TriState.True; + } + + public boolean isFalse() { + return this == TriState.False; + } + + public boolean isDefault() { + return this == TriState.Default; + } + + public boolean isNotDefault() { + return this != TriState.Default; + } +} diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/X509Util.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/X509Util.java index 153a826ba4f..441a0a83e7d 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/common/X509Util.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/X509Util.java @@ -164,6 +164,9 @@ public io.netty.handler.ssl.ClientAuth toNettyClientAuth() { private final String sslClientHostnameVerificationEnabledProperty = getConfigPrefix() + "clientHostnameVerification"; private final String sslCrlEnabledProperty = getConfigPrefix() + "crl"; private final String sslOcspEnabledProperty = getConfigPrefix() + "ocsp"; + private final String sslRevocationEnabledProperty = getConfigPrefix() + "revocationEnabled"; + private final String sslDisableLegacyRevocationLogic = getConfigPrefix() + "disableLegacyRevocationLogic"; + private final String sslTcnativeOcspEnabledProperty = getConfigPrefix() + ".tcnative.ocsp"; private final String sslClientAuthProperty = getConfigPrefix() + "clientAuth"; private final String sslHandshakeDetectionTimeoutMillisProperty = getConfigPrefix() + "handshakeDetectionTimeoutMillis"; @@ -248,6 +251,18 @@ public String getSslOcspEnabledProperty() { return sslOcspEnabledProperty; } + public String getSslRevocationEnabledProperty() { + return sslRevocationEnabledProperty; + } + + public String getSslTcnativeOcspEnabledProperty() { + return sslTcnativeOcspEnabledProperty; + } + + public String getSslDisableLegacyRevocationLogicProperty() { + return sslDisableLegacyRevocationLogic; + } + public String getSslClientAuthProperty() { return sslClientAuthProperty; } @@ -394,6 +409,8 @@ public SSLContextAndOptions createSSLContextAndOptionsFromConfig(ZKConfig config boolean sslCrlEnabled = config.getBoolean(this.sslCrlEnabledProperty); boolean sslOcspEnabled = config.getBoolean(this.sslOcspEnabledProperty); + TriState sslRevocationEnabled = config.getTristate(this.sslRevocationEnabledProperty); + boolean disableLegacyRevocationLogic = config.getBoolean(this.sslDisableLegacyRevocationLogic); boolean sslServerHostnameVerificationEnabled = isServerHostnameVerificationEnabled(config); boolean sslClientHostnameVerificationEnabled = isClientHostnameVerificationEnabled(config); boolean fipsMode = getFipsMode(config); @@ -404,7 +421,7 @@ public SSLContextAndOptions createSSLContextAndOptionsFromConfig(ZKConfig config try { trustManagers = new TrustManager[]{ createTrustManager(trustStoreLocationProp, trustStorePasswordProp, trustStoreTypeProp, sslCrlEnabled, - sslOcspEnabled, sslServerHostnameVerificationEnabled, sslClientHostnameVerificationEnabled, + sslOcspEnabled, sslRevocationEnabled, disableLegacyRevocationLogic, sslServerHostnameVerificationEnabled, sslClientHostnameVerificationEnabled, fipsMode)}; } catch (TrustManagerException trustManagerException) { throw new SSLContextException("Failed to create TrustManager", trustManagerException); @@ -521,6 +538,9 @@ public static X509KeyManager createKeyManager( * @param crlEnabled enable CRL (certificate revocation list) checks. * @param ocspEnabled enable OCSP (online certificate status protocol) * checks. + * @param revocationEnabled Enable certificate revocation checks + * @param disableLegacyRevocationLogic if true certificate revocation will only be affected + * by revocationEnabled and the JVM system properties * @param serverHostnameVerificationEnabled if true, verify hostnames of * remote servers that client * sockets created by this @@ -539,6 +559,8 @@ public static X509TrustManager createTrustManager( String trustStoreTypeProp, boolean crlEnabled, boolean ocspEnabled, + TriState revocationEnabled, + boolean disableLegacyRevocationLogic, final boolean serverHostnameVerificationEnabled, final boolean clientHostnameVerificationEnabled, final boolean fipsMode) throws TrustManagerException { @@ -549,13 +571,24 @@ public static X509TrustManager createTrustManager( KeyStore ts = loadTrustStore(trustStoreLocation, trustStorePassword, trustStoreTypeProp); PKIXBuilderParameters pbParams = new PKIXBuilderParameters(ts, new X509CertSelector()); if (crlEnabled || ocspEnabled) { - pbParams.setRevocationEnabled(true); + if (!disableLegacyRevocationLogic) { + pbParams.setRevocationEnabled(true); + } System.setProperty("com.sun.net.ssl.checkRevocation", "true"); System.setProperty("com.sun.security.enableCRLDP", "true"); if (ocspEnabled) { Security.setProperty("ocsp.enable", "true"); } } else { + if (!disableLegacyRevocationLogic) { + pbParams.setRevocationEnabled(false); + } + } + + // Setting revocationEnabled explicitly takes precedence + if (revocationEnabled.isTrue()) { + pbParams.setRevocationEnabled(true); + } else if (revocationEnabled.isFalse()) { pbParams.setRevocationEnabled(false); } diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/common/ZKConfig.java b/zookeeper-server/src/main/java/org/apache/zookeeper/common/ZKConfig.java index 846a5632e06..5c357a2e2d6 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/common/ZKConfig.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/common/ZKConfig.java @@ -131,6 +131,9 @@ private void putSSLProperties(X509Util x509Util) { properties.put(x509Util.getSslHostnameVerificationEnabledProperty(), System.getProperty(x509Util.getSslHostnameVerificationEnabledProperty())); properties.put(x509Util.getSslCrlEnabledProperty(), System.getProperty(x509Util.getSslCrlEnabledProperty())); properties.put(x509Util.getSslOcspEnabledProperty(), System.getProperty(x509Util.getSslOcspEnabledProperty())); + properties.put(x509Util.getSslTcnativeOcspEnabledProperty(), System.getProperty(x509Util.getSslTcnativeOcspEnabledProperty())); + properties.put(x509Util.getSslRevocationEnabledProperty(), System.getProperty(x509Util.getSslRevocationEnabledProperty())); + properties.put(x509Util.getSslDisableLegacyRevocationLogicProperty(), System.getProperty(x509Util.getSslDisableLegacyRevocationLogicProperty())); properties.put(x509Util.getSslClientAuthProperty(), System.getProperty(x509Util.getSslClientAuthProperty())); properties.put(x509Util.getSslHandshakeDetectionTimeoutMillisProperty(), System.getProperty(x509Util.getSslHandshakeDetectionTimeoutMillisProperty())); properties.put(x509Util.getFipsModeProperty(), System.getProperty(x509Util.getFipsModeProperty())); @@ -284,4 +287,15 @@ public int getInt(String key, int defaultValue) { return defaultValue; } + /** + * Returns {@code TriState.True} if and only if the property named by the argument + * exists and is equal to the string {@code "true"}. + * Returns {@code TriState.Default} if and only if the property named by the argument + * does not exist or is equal to the string {@code "default"}. + * Returns {@code TriState.False} otherwise. + */ + public TriState getTristate(String key) { + String propertyValue = getProperty(key); + return TriState.parse(propertyValue); + } } diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/X509AuthenticationProvider.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/X509AuthenticationProvider.java index 4ea925320f6..4f3b5717ff1 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/X509AuthenticationProvider.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/X509AuthenticationProvider.java @@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.common.ClientX509Util; +import org.apache.zookeeper.common.TriState; import org.apache.zookeeper.common.X509Exception; import org.apache.zookeeper.common.X509Exception.KeyManagerException; import org.apache.zookeeper.common.X509Exception.TrustManagerException; @@ -87,6 +88,8 @@ public X509AuthenticationProvider() throws X509Exception { boolean crlEnabled = Boolean.parseBoolean(config.getProperty(x509Util.getSslCrlEnabledProperty())); boolean ocspEnabled = Boolean.parseBoolean(config.getProperty(x509Util.getSslOcspEnabledProperty())); + TriState sslRevocationEnabled = config.getTristate(x509Util.getSslRevocationEnabledProperty()); + boolean disableLegacyRevocationLogic = config.getBoolean(x509Util.getSslDisableLegacyRevocationLogicProperty()); boolean hostnameVerificationEnabled = Boolean.parseBoolean(config.getProperty(x509Util.getSslHostnameVerificationEnabledProperty())); X509KeyManager km = null; @@ -118,6 +121,8 @@ public X509AuthenticationProvider() throws X509Exception { trustStoreTypeProp, crlEnabled, ocspEnabled, + sslRevocationEnabled, + disableLegacyRevocationLogic, hostnameVerificationEnabled, false, fipsMode); diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/common/X509UtilTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/common/X509UtilTest.java index e4f19d77fd1..7d7df3f83fe 100644 --- a/zookeeper-server/src/test/java/org/apache/zookeeper/common/X509UtilTest.java +++ b/zookeeper-server/src/test/java/org/apache/zookeeper/common/X509UtilTest.java @@ -239,6 +239,23 @@ public void testCRLEnabled( assertFalse(Boolean.valueOf(Security.getProperty("ocsp.enable"))); } + @ParameterizedTest + @MethodSource("data") + @Timeout(value = 5) + public void testCRLEnabledDisableLegacy( + X509KeyType caKeyType, X509KeyType certKeyType, String keyPassword, Integer paramIndex) + throws Exception { + System.setProperty("com.sun.net.ssl.checkRevocation", Boolean.FALSE.toString()); + init(caKeyType, certKeyType, keyPassword, paramIndex); + System.setProperty(x509Util.getSslCrlEnabledProperty(), "true"); + System.setProperty(x509Util.getSslDisableLegacyRevocationLogicProperty(), "true"); + x509Util.getDefaultSSLContext(); + // SslDisableLegacyRevocationLogic does only applies to the custom truststore property + assertTrue(Boolean.valueOf(System.getProperty("com.sun.net.ssl.checkRevocation"))); + assertTrue(Boolean.valueOf(System.getProperty("com.sun.security.enableCRLDP"))); + assertFalse(Boolean.valueOf(Security.getProperty("ocsp.enable"))); + } + @ParameterizedTest @MethodSource("data") @Timeout(value = 5) @@ -252,6 +269,21 @@ public void testCRLDisabled( assertFalse(Boolean.valueOf(Security.getProperty("ocsp.enable"))); } + @ParameterizedTest + @MethodSource("data") + @Timeout(value = 5) + public void testCRLDisabledDisableLegacy( + X509KeyType caKeyType, X509KeyType certKeyType, String keyPassword, Integer paramIndex) + throws Exception { + System.setProperty("com.sun.net.ssl.checkRevocation", Boolean.TRUE.toString()); + init(caKeyType, certKeyType, keyPassword, paramIndex); + System.setProperty(x509Util.getSslDisableLegacyRevocationLogicProperty(), "true"); + x509Util.getDefaultSSLContext(); + assertTrue(Boolean.valueOf(System.getProperty("com.sun.net.ssl.checkRevocation"))); + assertFalse(Boolean.valueOf(System.getProperty("com.sun.security.enableCRLDP"))); + assertFalse(Boolean.valueOf(Security.getProperty("ocsp.enable"))); + } + @ParameterizedTest @MethodSource("data") @Timeout(value = 5) @@ -266,6 +298,40 @@ public void testOCSPEnabled( assertTrue(Boolean.valueOf(Security.getProperty("ocsp.enable"))); } + @ParameterizedTest + @MethodSource("data") + @Timeout(value = 5) + public void testOCSPEnabledDisableLegacy( + X509KeyType caKeyType, X509KeyType certKeyType, String keyPassword, Integer paramIndex) + throws Exception { + System.setProperty("com.sun.net.ssl.checkRevocation", Boolean.FALSE.toString()); + init(caKeyType, certKeyType, keyPassword, paramIndex); + System.setProperty(x509Util.getSslDisableLegacyRevocationLogicProperty(), "true"); + System.setProperty(x509Util.getSslOcspEnabledProperty(), "true"); + x509Util.getDefaultSSLContext(); + // SslDisableLegacyRevocationLogic does only applies to the custom truststore property + assertTrue(Boolean.valueOf(System.getProperty("com.sun.net.ssl.checkRevocation"))); + assertTrue(Boolean.valueOf(System.getProperty("com.sun.security.enableCRLDP"))); + assertTrue(Boolean.valueOf(Security.getProperty("ocsp.enable"))); + } + + @ParameterizedTest + @MethodSource("data") + @Timeout(value = 5) + public void testOcspDisabledisNoop( + X509KeyType caKeyType, X509KeyType certKeyType, String keyPassword, Integer paramIndex) + throws Exception { + System.setProperty("com.sun.net.ssl.checkRevocation", Boolean.TRUE.toString()); + System.setProperty("com.sun.security.enableCRLDP", Boolean.TRUE.toString()); + Security.setProperty("ocsp.enable", Boolean.TRUE.toString()); + init(caKeyType, certKeyType, keyPassword, paramIndex); + System.setProperty(x509Util.getSslOcspEnabledProperty(), "false"); + x509Util.getDefaultSSLContext(); + assertTrue(Boolean.valueOf(System.getProperty("com.sun.net.ssl.checkRevocation"))); + assertTrue(Boolean.valueOf(System.getProperty("com.sun.security.enableCRLDP"))); + assertTrue(Boolean.valueOf(Security.getProperty("ocsp.enable"))); + } + @ParameterizedTest @MethodSource("data") @Timeout(value = 5) @@ -375,6 +441,8 @@ public void testLoadPEMTrustStore( x509TestContext.getTrustStorePassword(), KeyStoreFileType.PEM.getPropertyValue(), false, false, + TriState.False, + false, true, true, false); @@ -396,6 +464,8 @@ public void testLoadPEMTrustStoreNullPassword( KeyStoreFileType.PEM.getPropertyValue(), false, false, + TriState.False, + false, true, true, false); @@ -415,6 +485,8 @@ public void testLoadPEMTrustStoreAutodetectStoreFileType( null, // null StoreFileType means 'autodetect from file extension' false, false, + TriState.False, + false, true, true, false); @@ -490,6 +562,8 @@ public void testLoadJKSTrustStore( KeyStoreFileType.JKS.getPropertyValue(), true, true, + TriState.Default, + false, true, true, false); @@ -511,6 +585,8 @@ public void testLoadJKSTrustStoreNullPassword( KeyStoreFileType.JKS.getPropertyValue(), false, false, + TriState.False, + false, true, true, false); @@ -529,6 +605,8 @@ public void testLoadJKSTrustStoreAutodetectStoreFileType( null, // null StoreFileType means 'autodetect from file extension' true, true, + TriState.Default, + false, true, true, false); @@ -548,6 +626,8 @@ public void testLoadJKSTrustStoreWithWrongPassword( KeyStoreFileType.JKS.getPropertyValue(), true, true, + TriState.Default, + false, true, true, false); @@ -623,6 +703,8 @@ public void testLoadPKCS12TrustStore( x509TestContext.getTrustStorePassword(), KeyStoreFileType.PKCS12.getPropertyValue(), true, true, + TriState.Default, + false, true, true, false); @@ -644,6 +726,8 @@ public void testLoadPKCS12TrustStoreNullPassword( KeyStoreFileType.PKCS12.getPropertyValue(), false, false, + TriState.False, + false, true, true, false); @@ -662,6 +746,8 @@ public void testLoadPKCS12TrustStoreAutodetectStoreFileType( null, // null StoreFileType means 'autodetect from file extension' true, true, + TriState.Default, + false, true, true, false); @@ -681,6 +767,8 @@ public void testLoadPKCS12TrustStoreWithWrongPassword( KeyStoreFileType.PKCS12.getPropertyValue(), true, true, + TriState.Default, + false, true, true, false); @@ -740,6 +828,20 @@ public void testCreateSSLContext_validCustomSSLContextClass( assertEquals(SSLContext.getDefault(), sslContext); } + @ParameterizedTest + @MethodSource("data") + public void testCreateSSLContext_ocspWithJreProvider( + X509KeyType caKeyType, X509KeyType certKeyType, String keyPassword, Integer paramIndex) + throws Exception { + init(caKeyType, certKeyType, keyPassword, paramIndex); + ZKConfig zkConfig = new ZKConfig(); + try (ClientX509Util clientX509Util = new ClientX509Util();) { + zkConfig.setProperty(clientX509Util.getSslOcspEnabledProperty(), "true"); + // Must not throw IllegalArgumentException + clientX509Util.createSSLContext(zkConfig); + } + } + private static void forceClose(Socket s) { if (s == null || s.isClosed()) { return;