From a133c0fd40d96f91ee5c22dffd155ec9207a0792 Mon Sep 17 00:00:00 2001 From: Scott Leberknight <174812+sleberknight@users.noreply.github.com> Date: Sat, 25 Nov 2023 13:39:40 -0500 Subject: [PATCH] Add disableSniHostCheck property to TLS and SSL configuration classes (#1086) * Add disableSniHostCheck to TlsContextConfiguration, SSLContextConfiguration, and SimpleSSLContextFactory * Update SSLContextConfiguration#toSimpleSSLContextFactory factory method to provide disableSniHostCheck to SimpleSSLContextFactory * Update SSLContextConfiguration#toTlsContextConfiguration factory method to provide disableSniHostCheck to TlsContextConfiguration * Update javadoc of the conversion functions in TlsContextConfiguration to explain how disableSniHostCheck is handled (since it does not exist in Dropwizard TlsConfiguration) * Update TlsContextConfiguration#toSslContextConfiguration to provide disableSniHostCheck to SSLContextConfiguration * Add new all-args constructor to SimpleSSLContextFactory * Clean up duplicative code in SimpleSSLContextFactory by extracting several private helper methods * Change SimpleSSLContextFactory#configuration method to be public, and to return unmodifiable map. * Change tests with lots of assertions to use assertAll * Minor grammatical fixes in javadocs and comments Closes #1080 Closes #1085 --- .../config/SSLContextConfiguration.java | 27 +- .../config/TlsContextConfiguration.java | 28 ++- .../security/SimpleSSLContextFactory.java | 140 ++++++++--- .../config/SSLContextConfigurationTest.java | 42 +++- .../config/TlsContextConfigurationTest.java | 231 ++++++++++-------- .../security/SimpleSSLContextFactoryTest.java | 61 ++++- .../full-tls-config.yml | 1 + 7 files changed, 370 insertions(+), 160 deletions(-) diff --git a/src/main/java/org/kiwiproject/config/SSLContextConfiguration.java b/src/main/java/org/kiwiproject/config/SSLContextConfiguration.java index 9afdc524..4ccc0439 100644 --- a/src/main/java/org/kiwiproject/config/SSLContextConfiguration.java +++ b/src/main/java/org/kiwiproject/config/SSLContextConfiguration.java @@ -25,6 +25,7 @@ public class SSLContextConfiguration implements KeyAndTrustStoreConfigProvider { private String keyStoreType = KeyStoreType.JKS.value; private String trustStoreType = KeyStoreType.JKS.value; private boolean verifyHostname = true; + private boolean disableSniHostCheck; /** * A builder class for {@link SSLContextConfiguration}. @@ -110,6 +111,20 @@ public Builder setVerifyHostname(boolean verifyHostname) { return this; } + /** + * Whether the SNI (Server Name Indication) host check is disabled. Default is {@code false} + * + * @see What is SNI? How TLS server name indication works + */ + public Builder disableSniHostCheck(boolean disableSniHostCheck) { + return setDisableSniHostCheck(disableSniHostCheck); + } + + public Builder setDisableSniHostCheck(boolean disableSniHostCheck) { + configuration.setDisableSniHostCheck(disableSniHostCheck); + return this; + } + public SSLContextConfiguration build() { return configuration; } @@ -145,8 +160,15 @@ public SSLContext toSSLContext() { * @return a new instance */ public SimpleSSLContextFactory toSimpleSSLContextFactory() { - return new SimpleSSLContextFactory( - keyStorePath, keyStorePassword, keyStoreType, trustStorePath, trustStorePassword, trustStoreType, protocol, verifyHostname); + return new SimpleSSLContextFactory(keyStorePath, + keyStorePassword, + keyStoreType, + trustStorePath, + trustStorePassword, + trustStoreType, + protocol, + verifyHostname, + disableSniHostCheck); } /** @@ -164,6 +186,7 @@ public TlsContextConfiguration toTlsContextConfiguration() { .trustStoreType(trustStoreType) .protocol(protocol) .verifyHostname(verifyHostname) + .disableSniHostCheck(disableSniHostCheck) .build(); } diff --git a/src/main/java/org/kiwiproject/config/TlsContextConfiguration.java b/src/main/java/org/kiwiproject/config/TlsContextConfiguration.java index 5a87a9c8..3c37dbc3 100644 --- a/src/main/java/org/kiwiproject/config/TlsContextConfiguration.java +++ b/src/main/java/org/kiwiproject/config/TlsContextConfiguration.java @@ -34,7 +34,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) // for Builder (b/c also need no-args constructor) -@ToString(exclude = {"keyStorePassword", "trustStorePassword"}) +@ToString(exclude = { "keyStorePassword", "trustStorePassword" }) public class TlsContextConfiguration implements KeyAndTrustStoreConfigProvider { /** @@ -47,7 +47,7 @@ public class TlsContextConfiguration implements KeyAndTrustStoreConfigProvider { private String protocol = SSLContextProtocol.TLS_1_2.value; /** - * The name of the JCE (Java Cryptography Extension) provider to use on client side for cryptographic + * The name of the JCE (Java Cryptography Extension) provider to use on the client side for cryptographic * support (for example, SunJCE, Conscrypt, BC, etc.). *

* For more details, see the "Java Cryptography Architecture (JCA) Reference Guide" section of the Java @@ -75,7 +75,7 @@ public class TlsContextConfiguration implements KeyAndTrustStoreConfigProvider { private String keyStoreType = KeyStoreType.JKS.value; /** - * The name of the provider for the key store, i.e. the value of {@code provider} to use when getting the + * The name of the provider for the key store, i.e., the value of {@code provider} to use when getting the * {@link java.security.KeyStore} instance for the key store. *

* For more details, see the "Java Cryptography Architecture (JCA) Reference Guide" section of the Java @@ -107,7 +107,7 @@ public class TlsContextConfiguration implements KeyAndTrustStoreConfigProvider { private String trustStoreType = KeyStoreType.JKS.value; /** - * The name of the provider for the trust store, i.e. the value of {@code provider} to use when getting the + * The name of the provider for the trust store, i.e., the value of {@code provider} to use when getting the * {@link java.security.KeyStore} instance for the trust store. *

* For more details, see the "Java Cryptography Architecture (JCA) Reference Guide" section of the Java @@ -128,6 +128,13 @@ public class TlsContextConfiguration implements KeyAndTrustStoreConfigProvider { @Builder.Default private boolean verifyHostname = true; + /** + * Whether the SNI (Server Name Indication) host check is disabled. Default is {@code false} + * + * @see What is SNI? How TLS server name indication works + */ + private boolean disableSniHostCheck; + /** * List of supported protocols. It can be {@code null}. See the implementation note for why. * @@ -139,7 +146,7 @@ public class TlsContextConfiguration implements KeyAndTrustStoreConfigProvider { * {@link org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory#createLayeredSocket(Socket, String, int, org.apache.hc.core5.http.protocol.HttpContext)}. * You will need to look at the source code, as the JavaDoc doesn't mention this tidbit, nor do the constructors * since they don't have any documentation regarding their arguments. If you don't like reading source code of the - * open source tools you rely on, then please close this file, log out, and change careers. + * open-source tools you rely on, then please close this file, log out, and change careers. */ private List supportedProtocols; @@ -162,8 +169,12 @@ public class TlsContextConfiguration implements KeyAndTrustStoreConfigProvider { * Given a Dropwizard {@link TlsConfiguration}, create a new {@link TlsContextConfiguration}. *

* Even though {@link TlsContextConfiguration} does not permit null trust store properties (per the validation - * annotations), the {@link TlsConfiguration} does. If we encounter this sitation, we will be lenient; even though + * annotations), the {@link TlsConfiguration} does. If we encounter this situation, we will be lenient; even though * this could possibly cause downstream problems, we will just assume the caller knows what it is doing. + *

+ * The Dropwizard {@link TlsConfiguration} class does not contain a {@code disableSniHostCheck} property, so + * it cannot transfer and is therefore ignored during conversions. Also note that it is set to {@code false} + * in the returned {@link TlsContextConfiguration} since that is the more secure option. * * @param tlsConfig the Dropwizard TlsConfiguration from which to pull information * @return a new TlsContextConfiguration instance @@ -185,6 +196,7 @@ public static TlsContextConfiguration fromDropwizardTlsConfiguration(TlsConfigur .trustStoreProvider(tlsConfig.getTrustStoreProvider()) .trustSelfSignedCertificates(tlsConfig.isTrustSelfSignedCertificates()) .verifyHostname(tlsConfig.isVerifyHostname()) + .disableSniHostCheck(false) .supportedProtocols(tlsConfig.getSupportedProtocols()) .supportedCiphers(tlsConfig.getSupportedCiphers()) .certAlias(tlsConfig.getCertAlias()) @@ -198,6 +210,9 @@ private static String absolutePathOrNull(@Nullable File nullableFile) { /** * Convert this {@link TlsContextConfiguration} into a Dropwizard {@link TlsConfiguration} object. Assumes that * this object is valid. + *

+ * The Dropwizard {@link TlsConfiguration} class does not contain a {@code disableSniHostCheck} property, so + * it cannot transfer and is therefore ignored during conversions. * * @return a new Dropwizard TlsConfiguration instance * @implNote Requires dropwizard-client as a dependency @@ -248,6 +263,7 @@ public SSLContextConfiguration toSslContextConfiguration() { .trustStoreType(trustStoreType) .protocol(protocol) .verifyHostname(verifyHostname) + .disableSniHostCheck(disableSniHostCheck) .build(); } } diff --git a/src/main/java/org/kiwiproject/security/SimpleSSLContextFactory.java b/src/main/java/org/kiwiproject/security/SimpleSSLContextFactory.java index 0cf21de6..3906b9ef 100644 --- a/src/main/java/org/kiwiproject/security/SimpleSSLContextFactory.java +++ b/src/main/java/org/kiwiproject/security/SimpleSSLContextFactory.java @@ -3,12 +3,12 @@ import static java.util.Objects.isNull; import static org.kiwiproject.base.KiwiStrings.f; -import com.google.common.annotations.VisibleForTesting; import lombok.Getter; import lombok.Synchronized; import org.kiwiproject.collect.KiwiMaps; import javax.net.ssl.SSLContext; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -17,6 +17,8 @@ * A "simple" factory class that makes it simpler to create {@link SSLContext} instances. *

* Construct using one of the public constructors or via the {@link #builder()}. + * Prefer using the builder, as the constructors may be deprecated + * (most likely for removal) in the future. *

* This abstracts the much lower level {@link KiwiSecurity} class. * @@ -32,6 +34,7 @@ public class SimpleSSLContextFactory { private static final String TRUST_STORE_TYPE_PROPERTY = "trustStoreType"; private static final String PROTOCOL_PROPERTY = "protocol"; private static final String VERIFY_HOSTNAME_PROPERTY = "verifyHostname"; + private static final String DISABLE_SNI_HOST_CHECK_PROPERTY = "disableSniHostCheck"; private static final List REQUIRED_PROPERTIES = List.of( TRUST_STORE_PATH_PROPERTY, TRUST_STORE_PASSWORD_PROPERTY, PROTOCOL_PROPERTY @@ -55,6 +58,14 @@ public class SimpleSSLContextFactory { @Getter private final boolean verifyHostname; + /** + * This is not strictly needed when creating {@link SSLContext}s. It is here only in case this factory + * will be supplied to other code that makes HTTPS connections and needs to create {@link SSLContext} + * instances AND also needs to know whether it should perform SNI host checking. + */ + @Getter + private boolean disableSniHostCheck; + /** * Create a new {@link SimpleSSLContextFactory} with {@code verifyHostname} set to {@code true} and "JKS" as * the key and trust store type. @@ -89,7 +100,14 @@ public SimpleSSLContextFactory(String keyStorePath, String trustStorePassword, String protocol, boolean verifyHostname) { - this(keyStorePath, keyStorePassword, KeyStoreType.JKS.value, trustStorePath, trustStorePassword, KeyStoreType.JKS.value, protocol, verifyHostname); + this(keyStorePath, + keyStorePassword, + KeyStoreType.JKS.value, + trustStorePath, + trustStorePassword, + KeyStoreType.JKS.value, + protocol, + verifyHostname); } /** @@ -123,6 +141,40 @@ public SimpleSSLContextFactory(String keyStorePath, this.verifyHostname = verifyHostname; } + /** + * Create a new {@link SimpleSSLContextFactory}. + * + * @param keyStorePath path to the key store + * @param keyStorePassword password of the key store + * @param keyStoreType the keystore type + * @param trustStorePath path to the trust store + * @param trustStorePassword password of the trust store + * @param trustStoreType the trust store type + * @param protocol the protocol to use + * @param verifyHostname whether to verify host names or not + * @param disableSniHostCheck whether to disable SNI host checking + */ + @SuppressWarnings("java:S107") + public SimpleSSLContextFactory(String keyStorePath, + String keyStorePassword, + String keyStoreType, + String trustStorePath, + String trustStorePassword, + String trustStoreType, + String protocol, + boolean verifyHostname, + boolean disableSniHostCheck) { + this.keyStorePath = keyStorePath; + this.keyStorePassword = keyStorePassword; + this.keyStoreType = keyStoreType; + this.trustStorePath = trustStorePath; + this.trustStorePassword = trustStorePassword; + this.trustStoreType = trustStoreType; + this.protocol = protocol; + this.verifyHostname = verifyHostname; + this.disableSniHostCheck = disableSniHostCheck; + } + /** * A builder class for {@link SimpleSSLContextFactory}. *

@@ -145,7 +197,8 @@ protected Builder() { TRUST_STORE_PASSWORD_PROPERTY, Optional.empty(), TRUST_STORE_TYPE_PROPERTY, Optional.of(KeyStoreType.JKS.value), PROTOCOL_PROPERTY, Optional.empty(), - VERIFY_HOSTNAME_PROPERTY, Optional.of("true") + VERIFY_HOSTNAME_PROPERTY, Optional.of("true"), + DISABLE_SNI_HOST_CHECK_PROPERTY, Optional.of("false") ); } @@ -217,22 +270,36 @@ public Builder verifyHostname(boolean verifyHostname) { } public Builder setVerifyHostname(boolean verifyHostname) { - entries.put(VERIFY_HOSTNAME_PROPERTY, Optional.of(String.valueOf(verifyHostname))); + entries.put(VERIFY_HOSTNAME_PROPERTY, optionalStringOf(verifyHostname)); + return this; + } + + public Builder disableSniHostCheck(boolean disableSniHostCheck) { + return setDisableSniHostCheck(disableSniHostCheck); + } + + public Builder setDisableSniHostCheck(boolean disableSniHostCheck) { + entries.put(DISABLE_SNI_HOST_CHECK_PROPERTY, optionalStringOf(disableSniHostCheck)); return this; } + private static Optional optionalStringOf(boolean value) { + return Optional.of(String.valueOf(value)); + } + public SimpleSSLContextFactory build() { validateBuilderState(); return new SimpleSSLContextFactory( - entries.get(KEY_STORE_PATH_PROPERTY).orElse(null), - entries.get(KEY_STORE_PASSWORD_PROPERTY).orElse(null), - entries.get(KEY_STORE_TYPE_PROPERTY).orElseThrow(IllegalStateException::new), - entries.get(TRUST_STORE_PATH_PROPERTY).orElseThrow(IllegalStateException::new), - entries.get(TRUST_STORE_PASSWORD_PROPERTY).orElseThrow(IllegalStateException::new), - entries.get(TRUST_STORE_TYPE_PROPERTY).orElseThrow(IllegalStateException::new), - entries.get(PROTOCOL_PROPERTY).orElseThrow(IllegalStateException::new), - Boolean.parseBoolean(entries.get(VERIFY_HOSTNAME_PROPERTY).orElseThrow(IllegalStateException::new)) + stringOrNull(KEY_STORE_PATH_PROPERTY), + stringOrNull(KEY_STORE_PASSWORD_PROPERTY), + stringOrThrow(KEY_STORE_TYPE_PROPERTY), + stringOrThrow(TRUST_STORE_PATH_PROPERTY), + stringOrThrow(TRUST_STORE_PASSWORD_PROPERTY), + stringOrThrow(TRUST_STORE_TYPE_PROPERTY), + stringOrThrow(PROTOCOL_PROPERTY), + toBooleanOrThrow(VERIFY_HOSTNAME_PROPERTY), + toBooleanOrThrow(DISABLE_SNI_HOST_CHECK_PROPERTY) ); } @@ -244,6 +311,19 @@ public void validateBuilderState() { .ifPresent(entry -> throwBuildException(entry.getKey())); } + private String stringOrNull(String propertyName) { + return entries.get(propertyName).orElse(null); + } + + private String stringOrThrow(String propertyName) { + return entries.get(propertyName).orElseThrow(IllegalStateException::new); + } + + private boolean toBooleanOrThrow(String propertyName) { + var boolString = entries.get(propertyName).orElseThrow(IllegalStateException::new); + return Boolean.parseBoolean(boolString); + } + private static void throwBuildException(String property) { throw new SSLContextException( f("Required property '{}' not set; cannot build SimpleSSLContextFactory", property) @@ -265,8 +345,8 @@ public static Builder builder() { * {@link SimpleSSLContextFactory} instance was built with. * * @return a new {@link SSLContext} instance when first called; all subsequent calls return the same cached instance - * @implNote This is intended to be called infrequently, e.g. once when a service/app starts. It is internally - * synchronized to ensure thread-safety when creating the {@link SSLContext}. + * @implNote This is intended to be called infrequently, e.g., once when a service/app starts. + * It is internally synchronized to ensure thread-safety when creating the {@link SSLContext}. */ @Synchronized public SSLContext getSslContext() { @@ -279,23 +359,25 @@ public SSLContext getSslContext() { /** * Get the properties this factory was configured with, including passwords. + * Callers are responsible for securely handling the result, and not unnecessarily exposing it. * * @return a map containing the configuration of this factory - * @apiNote Currently this is not publicly exposed, as it should not generally be needed except in tests. - * @implNote Uses {@link KiwiMaps#newHashMap(Object...)} because some values may be {@code null}, e.g. the key - * store path + * @apiNote This is publicly exposed, but should not generally be needed except in tests, and perhaps debugging. + * @implNote Uses {@link KiwiMaps#newHashMap(Object...)} because some values may be {@code null}, e.g., the key + * store path, and wraps that using {@link Collections#unmodifiableMap(Map)} to prevent modification of the + * returned map. */ - @VisibleForTesting - Map configuration() { - return KiwiMaps.newHashMap( - KEY_STORE_PATH_PROPERTY, keyStorePath, - KEY_STORE_PASSWORD_PROPERTY, keyStorePassword, - KEY_STORE_TYPE_PROPERTY, keyStoreType, - TRUST_STORE_PATH_PROPERTY, trustStorePath, - TRUST_STORE_PASSWORD_PROPERTY, trustStorePassword, - TRUST_STORE_TYPE_PROPERTY, trustStoreType, - PROTOCOL_PROPERTY, protocol, - VERIFY_HOSTNAME_PROPERTY, verifyHostname - ); + public Map configuration() { + return Collections.unmodifiableMap(KiwiMaps.newHashMap( + KEY_STORE_PATH_PROPERTY, keyStorePath, + KEY_STORE_PASSWORD_PROPERTY, keyStorePassword, + KEY_STORE_TYPE_PROPERTY, keyStoreType, + TRUST_STORE_PATH_PROPERTY, trustStorePath, + TRUST_STORE_PASSWORD_PROPERTY, trustStorePassword, + TRUST_STORE_TYPE_PROPERTY, trustStoreType, + PROTOCOL_PROPERTY, protocol, + VERIFY_HOSTNAME_PROPERTY, verifyHostname, + DISABLE_SNI_HOST_CHECK_PROPERTY, disableSniHostCheck + )); } } diff --git a/src/test/java/org/kiwiproject/config/SSLContextConfigurationTest.java b/src/test/java/org/kiwiproject/config/SSLContextConfigurationTest.java index 0440bb7d..bc160667 100644 --- a/src/test/java/org/kiwiproject/config/SSLContextConfigurationTest.java +++ b/src/test/java/org/kiwiproject/config/SSLContextConfigurationTest.java @@ -1,14 +1,18 @@ package org.kiwiproject.config; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.kiwiproject.beans.BeanConverter; import org.kiwiproject.security.KeyStoreType; import org.kiwiproject.security.SecureTestConstants; +import java.util.Map; + @DisplayName("SSLContextConfiguration") class SSLContextConfigurationTest { @@ -66,15 +70,34 @@ void shouldConvertToTlsContextConfiguration() { var tlsConfig = sslConfig.toTlsContextConfiguration(); - assertThat(tlsConfig.getKeyStorePath()).isEqualTo(sslConfig.getKeyStorePath()); - assertThat(tlsConfig.getKeyStorePassword()).isEqualTo(sslConfig.getKeyStorePassword()); - assertThat(tlsConfig.getKeyStoreType()).isEqualTo(sslConfig.getKeyStoreType()); - assertThat(tlsConfig.getTrustStorePath()).isEqualTo(sslConfig.getTrustStorePath()); - assertThat(tlsConfig.getTrustStorePassword()).isEqualTo(sslConfig.getTrustStorePassword()); - assertThat(tlsConfig.getTrustStoreType()).isEqualTo(sslConfig.getTrustStoreType()); - assertThat(tlsConfig.isVerifyHostname()).isEqualTo(sslConfig.isVerifyHostname()); - assertThat(tlsConfig.getProtocol()).isEqualTo(sslConfig.getProtocol()); - assertThat(tlsConfig.getSupportedProtocols()).isNull(); + assertAll( + () -> assertThat(tlsConfig.getKeyStorePath()).isEqualTo(sslConfig.getKeyStorePath()), + () -> assertThat(tlsConfig.getKeyStorePassword()).isEqualTo(sslConfig.getKeyStorePassword()), + () -> assertThat(tlsConfig.getKeyStoreType()).isEqualTo(sslConfig.getKeyStoreType()), + () -> assertThat(tlsConfig.getTrustStorePath()).isEqualTo(sslConfig.getTrustStorePath()), + () -> assertThat(tlsConfig.getTrustStorePassword()).isEqualTo(sslConfig.getTrustStorePassword()), + () -> assertThat(tlsConfig.getTrustStoreType()).isEqualTo(sslConfig.getTrustStoreType()), + () -> assertThat(tlsConfig.isVerifyHostname()).isEqualTo(sslConfig.isVerifyHostname()), + () -> assertThat(tlsConfig.isDisableSniHostCheck()).isEqualTo(sslConfig.isDisableSniHostCheck()), + () -> assertThat(tlsConfig.getProtocol()).isEqualTo(sslConfig.getProtocol()), + () -> assertThat(tlsConfig.getSupportedProtocols()).isNull() + ); + } + + @Test + void shouldConvertToSimpleSSLContextFactory() { + var sslConfig = newSampleSslContextConfiguration(); + var sslContextFactory = sslConfig.toSimpleSSLContextFactory(); + + // Since SimpleSSLContextFactory does not have getters for most properties, get its + // configuration as a Map, convert it to an SSLContextConfiguration, and verify that + // it is equal to the original sslConfig + var converter = new BeanConverter>(); + var expectedConfig = converter.convert(sslContextFactory.configuration(), new SSLContextConfiguration()); + assertThat(expectedConfig) + .describedAs("round-trip conversion should result in equal SSLContextConfiguration") + .usingRecursiveComparison() + .isEqualTo(sslConfig); } private SSLContextConfiguration newSampleSslContextConfiguration() { @@ -87,6 +110,7 @@ private SSLContextConfiguration newSampleSslContextConfiguration() { .trustStoreType(type) .protocol(protocol) .verifyHostname(false) + .disableSniHostCheck(true) .build(); } } diff --git a/src/test/java/org/kiwiproject/config/TlsContextConfigurationTest.java b/src/test/java/org/kiwiproject/config/TlsContextConfigurationTest.java index cc94fd92..0a6568b2 100644 --- a/src/test/java/org/kiwiproject/config/TlsContextConfigurationTest.java +++ b/src/test/java/org/kiwiproject/config/TlsContextConfigurationTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.kiwiproject.util.YamlTestHelper.loadFromYaml; import static org.kiwiproject.validation.ValidationTestHelper.assertNoViolations; import static org.kiwiproject.validation.ValidationTestHelper.assertOnePropertyViolation; @@ -46,21 +47,24 @@ void shouldHaveDefaultValues() { } private static void assertAllDefaultValues(TlsContextConfiguration config) { - assertThat(config.getProtocol()).isEqualTo(SSLContextProtocol.TLS_1_2.value); - assertThat(config.getProvider()).isNull(); - assertThat(config.getKeyStorePath()).isNull(); - assertThat(config.getKeyStorePassword()).isNull(); - assertThat(config.getKeyStoreType()).isEqualTo(KeyStoreType.JKS.value); - assertThat(config.getKeyStoreProvider()).isNull(); - assertThat(config.getTrustStorePath()).isNull(); - assertThat(config.getTrustStorePassword()).isNull(); - assertThat(config.getTrustStoreType()).isEqualTo(KeyStoreType.JKS.value); - assertThat(config.getTrustStoreProvider()).isNull(); - assertThat(config.isTrustSelfSignedCertificates()).isFalse(); - assertThat(config.isVerifyHostname()).isTrue(); - assertThat(config.getSupportedProtocols()).isNull(); - assertThat(config.getSupportedCiphers()).isNull(); - assertThat(config.getCertAlias()).isNull(); + assertAll( + () -> assertThat(config.getProtocol()).isEqualTo(SSLContextProtocol.TLS_1_2.value), + () -> assertThat(config.getProvider()).isNull(), + () -> assertThat(config.getKeyStorePath()).isNull(), + () -> assertThat(config.getKeyStorePassword()).isNull(), + () -> assertThat(config.getKeyStoreType()).isEqualTo(KeyStoreType.JKS.value), + () -> assertThat(config.getKeyStoreProvider()).isNull(), + () -> assertThat(config.getTrustStorePath()).isNull(), + () -> assertThat(config.getTrustStorePassword()).isNull(), + () -> assertThat(config.getTrustStoreType()).isEqualTo(KeyStoreType.JKS.value), + () -> assertThat(config.getTrustStoreProvider()).isNull(), + () -> assertThat(config.isTrustSelfSignedCertificates()).isFalse(), + () -> assertThat(config.isVerifyHostname()).isTrue(), + () -> assertThat(config.isDisableSniHostCheck()).isFalse(), + () -> assertThat(config.getSupportedProtocols()).isNull(), + () -> assertThat(config.getSupportedCiphers()).isNull(), + () -> assertThat(config.getCertAlias()).isNull() + ); } @Nested @@ -106,10 +110,12 @@ void shouldDeserializeMinimalConfig() { assertDefaultValues(tlsConfig); - assertThat(tlsConfig.getKeyStorePath()).isEqualTo("/path/to/keystore.jks"); - assertThat(tlsConfig.getKeyStorePassword()).isEqualTo("ksPassWd"); - assertThat(tlsConfig.getTrustStorePath()).isEqualTo("/path/to/truststore.jks"); - assertThat(tlsConfig.getTrustStorePassword()).isEqualTo("tsPass100"); + assertAll( + () -> assertThat(tlsConfig.getKeyStorePath()).isEqualTo("/path/to/keystore.jks"), + () -> assertThat(tlsConfig.getKeyStorePassword()).isEqualTo("ksPassWd"), + () -> assertThat(tlsConfig.getTrustStorePath()).isEqualTo("/path/to/truststore.jks"), + () -> assertThat(tlsConfig.getTrustStorePassword()).isEqualTo("tsPass100") + ); } @Test @@ -118,35 +124,43 @@ void shouldDeserializeMinimalWithNoKeyStorePropertiesConfig() { assertDefaultValues(tlsConfig); - assertThat(tlsConfig.getKeyStorePath()).isNull(); - assertThat(tlsConfig.getKeyStorePassword()).isNull(); + assertAll( + () -> assertThat(tlsConfig.getKeyStorePath()).isNull(), + () -> assertThat(tlsConfig.getKeyStorePassword()).isNull() + ); } @Test void shouldDeserializeFullConfig() { var tlsConfig = loadTlsContextConfiguration("TlsContextConfigurationTest/full-tls-config.yml"); - assertThat(tlsConfig.getProtocol()).isEqualTo("TLSv1.3"); - assertThat(tlsConfig.getKeyStorePath()).isEqualTo("/path/to/keystore.pkcs12"); - assertThat(tlsConfig.getKeyStorePassword()).isEqualTo("ksPassWd"); - assertThat(tlsConfig.getKeyStoreType()).isEqualTo("PKCS12"); - assertThat(tlsConfig.getTrustStorePath()).isEqualTo("/path/to/truststore.pkcs12"); - assertThat(tlsConfig.getTrustStorePassword()).isEqualTo("tsPass100"); - assertThat(tlsConfig.getTrustStoreType()).isEqualTo("PKCS12"); - assertThat(tlsConfig.isVerifyHostname()).isFalse(); - assertThat(tlsConfig.getSupportedProtocols()).containsOnly( - SSLContextProtocol.TLS_1_2.value, - SSLContextProtocol.TLS_1_3.value + assertAll( + () -> assertThat(tlsConfig.getProtocol()).isEqualTo("TLSv1.3"), + () -> assertThat(tlsConfig.getKeyStorePath()).isEqualTo("/path/to/keystore.pkcs12"), + () -> assertThat(tlsConfig.getKeyStorePassword()).isEqualTo("ksPassWd"), + () -> assertThat(tlsConfig.getKeyStoreType()).isEqualTo("PKCS12"), + () -> assertThat(tlsConfig.getTrustStorePath()).isEqualTo("/path/to/truststore.pkcs12"), + () -> assertThat(tlsConfig.getTrustStorePassword()).isEqualTo("tsPass100"), + () -> assertThat(tlsConfig.getTrustStoreType()).isEqualTo("PKCS12"), + () -> assertThat(tlsConfig.isVerifyHostname()).isFalse(), + () -> assertThat(tlsConfig.isDisableSniHostCheck()).isTrue(), + () -> assertThat(tlsConfig.getSupportedProtocols()).containsOnly( + SSLContextProtocol.TLS_1_2.value, + SSLContextProtocol.TLS_1_3.value + ) ); } } private static void assertDefaultValues(TlsContextConfiguration config) { - assertThat(config.getProtocol()).isEqualTo(SSLContextProtocol.TLS_1_2.value); - assertThat(config.getKeyStoreType()).isEqualTo(KeyStoreType.JKS.value); - assertThat(config.getTrustStoreType()).isEqualTo(KeyStoreType.JKS.value); - assertThat(config.isVerifyHostname()).isTrue(); - assertThat(config.getSupportedProtocols()).isNull(); + assertAll( + () -> assertThat(config.getProtocol()).isEqualTo(SSLContextProtocol.TLS_1_2.value), + () -> assertThat(config.getKeyStoreType()).isEqualTo(KeyStoreType.JKS.value), + () -> assertThat(config.getTrustStoreType()).isEqualTo(KeyStoreType.JKS.value), + () -> assertThat(config.isVerifyHostname()).isTrue(), + () -> assertThat(config.isDisableSniHostCheck()).isFalse(), + () -> assertThat(config.getSupportedProtocols()).isNull() + ); } @Nested @@ -235,6 +249,7 @@ void setUp() { .trustStoreProvider("BC") .trustSelfSignedCertificates(true) .verifyHostname(false) + .disableSniHostCheck(true) .supportedProtocols(List.of("TLSv1.3")) .supportedCiphers(List.of("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256")) .certAlias("cert84") @@ -279,44 +294,50 @@ void shouldReturnTlsContextConfiguration_FromDefaultDropwizardTlsConfiguration() var tlsContextConfig = TlsContextConfiguration.fromDropwizardTlsConfiguration(dwTlsConfig); - // The following also test assumptions about defaults of Dropwizard's TlsConfiguration, for example - // which are null. This isn't wonderful but at the same time we'll find out quickly what Dropwizard + // The following also tests assumptions about defaults of Dropwizard's TlsConfiguration, for example, + // which ones are null. This isn't wonderful, but at the same time we'll find out quickly what Dropwizard // has changed. - assertThat(tlsContextConfig.getProtocol()).isNotNull().isEqualTo(dwTlsConfig.getProtocol()); - assertThat(tlsContextConfig.getKeyStorePath()).isNull(); - assertThat(tlsContextConfig.getKeyStorePassword()).isNull(); - assertThat(tlsContextConfig.getKeyStoreType()).isNotNull().isEqualTo(dwTlsConfig.getKeyStoreType()); - assertThat(tlsContextConfig.getKeyStoreProvider()).isNull(); - assertThat(tlsContextConfig.getTrustStorePath()).isNull(); - assertThat(tlsContextConfig.getTrustStorePassword()).isNull(); - assertThat(tlsContextConfig.getTrustStoreType()).isNotNull().isEqualTo(dwTlsConfig.getTrustStoreType()); - assertThat(tlsContextConfig.getTrustStoreProvider()).isNull(); - assertThat(tlsContextConfig.isTrustSelfSignedCertificates()).isFalse(); - assertThat(tlsContextConfig.isVerifyHostname()).isTrue(); - assertThat(tlsContextConfig.getSupportedProtocols()).isNull(); - assertThat(tlsContextConfig.getSupportedCiphers()).isNull(); - assertThat(tlsContextConfig.getCertAlias()).isNull(); + assertAll( + () -> assertThat(tlsContextConfig.getProtocol()).isNotNull().isEqualTo(dwTlsConfig.getProtocol()), + () -> assertThat(tlsContextConfig.getKeyStorePath()).isNull(), + () -> assertThat(tlsContextConfig.getKeyStorePassword()).isNull(), + () -> assertThat(tlsContextConfig.getKeyStoreType()).isNotNull().isEqualTo(dwTlsConfig.getKeyStoreType()), + () -> assertThat(tlsContextConfig.getKeyStoreProvider()).isNull(), + () -> assertThat(tlsContextConfig.getTrustStorePath()).isNull(), + () -> assertThat(tlsContextConfig.getTrustStorePassword()).isNull(), + () -> assertThat(tlsContextConfig.getTrustStoreType()).isNotNull().isEqualTo(dwTlsConfig.getTrustStoreType()), + () -> assertThat(tlsContextConfig.getTrustStoreProvider()).isNull(), + () -> assertThat(tlsContextConfig.isTrustSelfSignedCertificates()).isFalse(), + () -> assertThat(tlsContextConfig.isVerifyHostname()).isTrue(), + () -> assertThat(tlsContextConfig.isDisableSniHostCheck()).isFalse(), + () -> assertThat(tlsContextConfig.getSupportedProtocols()).isNull(), + () -> assertThat(tlsContextConfig.getSupportedCiphers()).isNull(), + () -> assertThat(tlsContextConfig.getCertAlias()).isNull() + ); } @Test void shouldReturnTlsContextConfiguration() { var tlsContextConfig = TlsContextConfiguration.fromDropwizardTlsConfiguration(dwTlsConfig); - assertThat(tlsContextConfig.getProtocol()).isEqualTo("TLSv1.3"); - assertThat(tlsContextConfig.getProvider()).isEqualTo("BC"); - assertThat(tlsContextConfig.getKeyStorePath()).isEqualTo("/pki/test.ks"); - assertThat(tlsContextConfig.getKeyStorePassword()).isEqualTo("ks-pass"); - assertThat(tlsContextConfig.getKeyStoreType()).isEqualTo("PKCS12"); - assertThat(tlsContextConfig.getKeyStoreProvider()).isEqualTo("BC"); - assertThat(tlsContextConfig.getTrustStorePath()).isEqualTo("/pki/test.ts"); - assertThat(tlsContextConfig.getTrustStorePassword()).isEqualTo("ts-pass"); - assertThat(tlsContextConfig.getTrustStoreType()).isEqualTo("PKCS12"); - assertThat(tlsContextConfig.getTrustStoreProvider()).isEqualTo("BC"); - assertThat(tlsContextConfig.isTrustSelfSignedCertificates()).isTrue(); - assertThat(tlsContextConfig.isVerifyHostname()).isFalse(); - assertThat(tlsContextConfig.getSupportedProtocols()).containsOnly("TLSv1.3"); - assertThat(tlsContextConfig.getSupportedCiphers()).containsOnly("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"); - assertThat(tlsContextConfig.getCertAlias()).isEqualTo("cert42"); + assertAll( + () -> assertThat(tlsContextConfig.getProtocol()).isEqualTo("TLSv1.3"), + () -> assertThat(tlsContextConfig.getProvider()).isEqualTo("BC"), + () -> assertThat(tlsContextConfig.getKeyStorePath()).isEqualTo("/pki/test.ks"), + () -> assertThat(tlsContextConfig.getKeyStorePassword()).isEqualTo("ks-pass"), + () -> assertThat(tlsContextConfig.getKeyStoreType()).isEqualTo("PKCS12"), + () -> assertThat(tlsContextConfig.getKeyStoreProvider()).isEqualTo("BC"), + () -> assertThat(tlsContextConfig.getTrustStorePath()).isEqualTo("/pki/test.ts"), + () -> assertThat(tlsContextConfig.getTrustStorePassword()).isEqualTo("ts-pass"), + () -> assertThat(tlsContextConfig.getTrustStoreType()).isEqualTo("PKCS12"), + () -> assertThat(tlsContextConfig.getTrustStoreProvider()).isEqualTo("BC"), + () -> assertThat(tlsContextConfig.isTrustSelfSignedCertificates()).isTrue(), + () -> assertThat(tlsContextConfig.isVerifyHostname()).isFalse(), + () -> assertThat(tlsContextConfig.isDisableSniHostCheck()).isFalse(), + () -> assertThat(tlsContextConfig.getSupportedProtocols()).containsOnly("TLSv1.3"), + () -> assertThat(tlsContextConfig.getSupportedCiphers()).containsOnly("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"), + () -> assertThat(tlsContextConfig.getCertAlias()).isEqualTo("cert42") + ); } @Test @@ -381,21 +402,25 @@ class ToDropwizardTlsConfiguration { void shouldReturnTlsConfiguration() { var dwTlsConfig = tlsConfig.toDropwizardTlsConfiguration(); - assertThat(dwTlsConfig.getProtocol()).isEqualTo(protocol); - assertThat(dwTlsConfig.getProvider()).isEqualTo("BC"); - assertThat(dwTlsConfig.getKeyStorePath().getAbsolutePath()).isEqualTo(path); - assertThat(dwTlsConfig.getKeyStorePassword()).isEqualTo(password); - assertThat(dwTlsConfig.getKeyStoreType()).isEqualTo(type); - assertThat(dwTlsConfig.getKeyStoreProvider()).isEqualTo("BC"); - assertThat(dwTlsConfig.getTrustStorePath().getAbsolutePath()).isEqualTo(path); - assertThat(dwTlsConfig.getTrustStorePassword()).isEqualTo(password); - assertThat(dwTlsConfig.getTrustStoreType()).isEqualTo(type); - assertThat(dwTlsConfig.getTrustStoreProvider()).isEqualTo("BC"); - assertThat(dwTlsConfig.isTrustSelfSignedCertificates()).isTrue(); - assertThat(dwTlsConfig.isVerifyHostname()).isFalse(); - assertThat(dwTlsConfig.getSupportedProtocols()).containsOnly("TLSv1.3"); - assertThat(dwTlsConfig.getSupportedCiphers()).containsOnly("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"); - assertThat(dwTlsConfig.getCertAlias()).isEqualTo("cert84"); + // Note: Dropwizard TlsConfiguration does not contain disableSniHostCheck, so we cannot check it + + assertAll( + () -> assertThat(dwTlsConfig.getProtocol()).isEqualTo(protocol), + () -> assertThat(dwTlsConfig.getProvider()).isEqualTo("BC"), + () -> assertThat(dwTlsConfig.getKeyStorePath().getAbsolutePath()).isEqualTo(path), + () -> assertThat(dwTlsConfig.getKeyStorePassword()).isEqualTo(password), + () -> assertThat(dwTlsConfig.getKeyStoreType()).isEqualTo(type), + () -> assertThat(dwTlsConfig.getKeyStoreProvider()).isEqualTo("BC"), + () -> assertThat(dwTlsConfig.getTrustStorePath().getAbsolutePath()).isEqualTo(path), + () -> assertThat(dwTlsConfig.getTrustStorePassword()).isEqualTo(password), + () -> assertThat(dwTlsConfig.getTrustStoreType()).isEqualTo(type), + () -> assertThat(dwTlsConfig.getTrustStoreProvider()).isEqualTo("BC"), + () -> assertThat(dwTlsConfig.isTrustSelfSignedCertificates()).isTrue(), + () -> assertThat(dwTlsConfig.isVerifyHostname()).isFalse(), + () -> assertThat(dwTlsConfig.getSupportedProtocols()).containsOnly("TLSv1.3"), + () -> assertThat(dwTlsConfig.getSupportedCiphers()).containsOnly("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"), + () -> assertThat(dwTlsConfig.getCertAlias()).isEqualTo("cert84") + ); } @SuppressWarnings("DataFlowIssue") // b/c IntelliJ sees Dropwizard [key|trust]StorePath are @Nullable @@ -409,14 +434,16 @@ void shouldCorrectlyHandleWhenOnlyTrustStoreIsPresent() { var dwTlsConfig = tlsConfig.toDropwizardTlsConfiguration(); - assertThat(dwTlsConfig.getProtocol()).isEqualTo(SSLContextProtocol.TLS_1_2.value); - assertThat(dwTlsConfig.getKeyStorePath()).isNull(); - assertThat(dwTlsConfig.getKeyStorePassword()).isNull(); - assertThat(dwTlsConfig.getKeyStoreType()).isEqualTo(KeyStoreType.JKS.value); - assertThat(dwTlsConfig.getTrustStorePath().getAbsolutePath()).isEqualTo("/data/pki/trust-store.pkcs12"); - assertThat(dwTlsConfig.getTrustStorePassword()).isEqualTo("mySuperSecretTsPassword"); - assertThat(dwTlsConfig.getTrustStoreType()).isEqualTo(KeyStoreType.PKCS12.value); - assertThat(dwTlsConfig.isVerifyHostname()).isTrue(); + assertAll( + () -> assertThat(dwTlsConfig.getProtocol()).isEqualTo(SSLContextProtocol.TLS_1_2.value), + () -> assertThat(dwTlsConfig.getKeyStorePath()).isNull(), + () -> assertThat(dwTlsConfig.getKeyStorePassword()).isNull(), + () -> assertThat(dwTlsConfig.getKeyStoreType()).isEqualTo(KeyStoreType.JKS.value), + () -> assertThat(dwTlsConfig.getTrustStorePath().getAbsolutePath()).isEqualTo("/data/pki/trust-store.pkcs12"), + () -> assertThat(dwTlsConfig.getTrustStorePassword()).isEqualTo("mySuperSecretTsPassword"), + () -> assertThat(dwTlsConfig.getTrustStoreType()).isEqualTo(KeyStoreType.PKCS12.value), + () -> assertThat(dwTlsConfig.isVerifyHostname()).isTrue() + ); } } @@ -428,6 +455,7 @@ void shouldReturnSSLContextConfiguration() { var tlsContextConfig = TlsContextConfiguration.builder() .protocol(SSLContextProtocol.TLS_1_3.value) .verifyHostname(false) + .disableSniHostCheck(true) .keyStorePath("/data/pki/key-store.pkcs12") .keyStorePassword("myKsPassword") .keyStoreType(KeyStoreType.PKCS12.value) @@ -439,16 +467,17 @@ void shouldReturnSSLContextConfiguration() { var sslConfig = tlsContextConfig.toSslContextConfiguration(); - assertThat(sslConfig.getProtocol()).isEqualTo(SSLContextProtocol.TLS_1_3.value); - assertThat(sslConfig.isVerifyHostname()).isFalse(); - - assertThat(sslConfig.getKeyStorePath()).isEqualTo("/data/pki/key-store.pkcs12"); - assertThat(sslConfig.getKeyStorePassword()).isEqualTo("myKsPassword"); - assertThat(sslConfig.getKeyStoreType()).isEqualTo(KeyStoreType.PKCS12.value); - - assertThat(sslConfig.getTrustStorePath()).isEqualTo("/data/pki/trust-store.pkcs12"); - assertThat(sslConfig.getTrustStorePassword()).isEqualTo("myTsPassword"); - assertThat(sslConfig.getTrustStoreType()).isEqualTo(KeyStoreType.PKCS12.value); + assertAll( + () -> assertThat(sslConfig.getProtocol()).isEqualTo(SSLContextProtocol.TLS_1_3.value), + () -> assertThat(sslConfig.isVerifyHostname()).isFalse(), + () -> assertThat(sslConfig.isDisableSniHostCheck()).isTrue(), + () -> assertThat(sslConfig.getKeyStorePath()).isEqualTo("/data/pki/key-store.pkcs12"), + () -> assertThat(sslConfig.getKeyStorePassword()).isEqualTo("myKsPassword"), + () -> assertThat(sslConfig.getKeyStoreType()).isEqualTo(KeyStoreType.PKCS12.value), + () -> assertThat(sslConfig.getTrustStorePath()).isEqualTo("/data/pki/trust-store.pkcs12"), + () -> assertThat(sslConfig.getTrustStorePassword()).isEqualTo("myTsPassword"), + () -> assertThat(sslConfig.getTrustStoreType()).isEqualTo(KeyStoreType.PKCS12.value) + ); } @Test diff --git a/src/test/java/org/kiwiproject/security/SimpleSSLContextFactoryTest.java b/src/test/java/org/kiwiproject/security/SimpleSSLContextFactoryTest.java index 2ceaf4f5..b643b0a1 100644 --- a/src/test/java/org/kiwiproject/security/SimpleSSLContextFactoryTest.java +++ b/src/test/java/org/kiwiproject/security/SimpleSSLContextFactoryTest.java @@ -8,7 +8,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.kiwiproject.junit.jupiter.ClearBoxTest; @DisplayName("SimpleSSLContextFactory") class SimpleSSLContextFactoryTest { @@ -42,6 +41,24 @@ void shouldDefaultVerifyHostNameToTrue_ForBuilder() { assertThat(contextFactory.isVerifyHostname()).isTrue(); } + @Test + void shouldDefaultDisableSniHostCheckToFalse() { + var contextFactory = new SimpleSSLContextFactory(path, password, path, password, protocol); + + assertThat(contextFactory.isDisableSniHostCheck()).isFalse(); + } + + @Test + void shouldDefaultDisableSniHostCheckToFalse_ForBuilder() { + var contextFactory = SimpleSSLContextFactory.builder() + .trustStorePath(path) + .trustStorePassword(password) + .protocol(protocol) + .build(); + + assertThat(contextFactory.isDisableSniHostCheck()).isFalse(); + } + @Test void shouldCreateSimpleSSLContextFactory() { var contextFactory = new SimpleSSLContextFactory(path, password, path, password, protocol); @@ -59,10 +76,12 @@ void shouldBuildSimpleSSLContextFactory() { .trustStorePassword(password) .protocol(protocol) .verifyHostname(false) + .disableSniHostCheck(true) .build(); assertThat(contextFactory.getSslContext()).isNotNull(); assertThat(contextFactory.isVerifyHostname()).isFalse(); + assertThat(contextFactory.isDisableSniHostCheck()).isTrue(); } @Test @@ -119,7 +138,20 @@ void whenMissing_Protocol() { @Nested class Configuration { - @ClearBoxTest + @Test + void shouldReturnUnmodifiableMap() { + var factory = SimpleSSLContextFactory.builder() + .trustStorePath("/path/to/trust_store") + .trustStorePassword("password_12345") + .protocol("TLSv1.3") + .build(); + + var config = factory.configuration(); + + assertThat(config).isUnmodifiable(); + } + + @Test void shouldSetDefaultsForSomeProperties() { var factory = SimpleSSLContextFactory.builder() .trustStorePath("/path/to/trust_store") @@ -139,11 +171,12 @@ void shouldSetDefaultsForSomeProperties() { entry("trustStorePassword", "password_12345"), entry("trustStoreType", "JKS"), entry("protocol", "TLSv1.2"), - entry("verifyHostname", true) - ); + entry("verifyHostname", true), + entry("disableSniHostCheck", false) + ); } - @ClearBoxTest + @Test void shouldSetAllProperties() { var factory = SimpleSSLContextFactory.builder() .keyStorePath("/path/to/key_store") @@ -154,19 +187,21 @@ void shouldSetAllProperties() { .trustStoreType(KeyStoreType.PKCS12.value) .protocol("TLSv1.1") .verifyHostname(false) + .disableSniHostCheck(true) .build(); var config = factory.configuration(); assertThat(config).containsOnly( - entry("keyStorePath", "/path/to/key_store"), - entry("keyStorePassword", "password_xyz"), - entry("keyStoreType", "PKCS11"), - entry("trustStorePath", "/path/to/trust_store"), - entry("trustStorePassword", "password_12345"), - entry("trustStoreType", "PKCS12"), - entry("protocol", "TLSv1.1"), - entry("verifyHostname", false) + entry("keyStorePath", "/path/to/key_store"), + entry("keyStorePassword", "password_xyz"), + entry("keyStoreType", "PKCS11"), + entry("trustStorePath", "/path/to/trust_store"), + entry("trustStorePassword", "password_12345"), + entry("trustStoreType", "PKCS12"), + entry("protocol", "TLSv1.1"), + entry("verifyHostname", false), + entry("disableSniHostCheck", true) ); } } diff --git a/src/test/resources/TlsContextConfigurationTest/full-tls-config.yml b/src/test/resources/TlsContextConfigurationTest/full-tls-config.yml index 1de264f6..b0e57143 100644 --- a/src/test/resources/TlsContextConfigurationTest/full-tls-config.yml +++ b/src/test/resources/TlsContextConfigurationTest/full-tls-config.yml @@ -7,6 +7,7 @@ tlsConfig: trustStorePassword: tsPass100 trustStoreType: PKCS12 verifyHostname: false + disableSniHostCheck: true supportedProtocols: - TLSv1.2 - TLSv1.3