diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java index 1ed1771b0..9e40d5892 100644 --- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java +++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportOptions.java @@ -16,6 +16,7 @@ */ package org.apache.qpid.jms.transports; +import javax.net.ssl.SSLContext; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -23,8 +24,6 @@ import java.util.Map; import java.util.function.Supplier; -import javax.net.ssl.SSLContext; - /** * Encapsulates all the Transport options in one configuration object. */ @@ -77,8 +76,10 @@ public class TransportOptions implements Cloneable { private int sharedEventLoopThreads = DEFAULT_SHARED_EVENT_LOOP_THREADS; private String keyStoreLocation; + private String keyStoreBase64Property; private String keyStorePassword; private String trustStoreLocation; + private String trustStoreBase64Property; private String trustStorePassword; private String keyStoreType; private String trustStoreType; @@ -323,6 +324,23 @@ public void setKeyStoreLocation(String keyStoreLocation) { this.keyStoreLocation = keyStoreLocation; } + /** + * @return the keyStoreBase64Property currently configured. + */ + public String getKeyStoreBase64Property() { + return keyStoreBase64Property; + } + + /** + * Sets the system property containing the base64 definition of the key store to use. + * + * @param keyStoreBase64Property + * the keyStoreBase64Property to use to create the key manager. + */ + public void setKeyStoreBase64Property(final String keyStoreBase64Property) { + this.keyStoreBase64Property = keyStoreBase64Property; + } + /** * @return the keyStorePassword */ @@ -351,6 +369,23 @@ public void setTrustStoreLocation(String trustStoreLocation) { this.trustStoreLocation = trustStoreLocation; } + /** + * @return the trustStoreBase64Property + */ + public String getTrustStoreBase64Property() { + return trustStoreBase64Property; + } + + /** + * Sets the system property containing the base64 definition of the trust store to use. + * + * @param trustStoreBase64Property + * the trustStoreBase64Property to set. + */ + public void setTrustStoreBase64Property(final String trustStoreBase64Property) { + this.trustStoreBase64Property = trustStoreBase64Property; + } + /** * @return the trustStorePassword */ @@ -581,8 +616,10 @@ protected TransportOptions copyOptions(TransportOptions copy) { copy.setUseEpoll(isUseEpoll()); copy.setTraceBytes(isTraceBytes()); copy.setKeyStoreLocation(getKeyStoreLocation()); + copy.setKeyStoreBase64Property(getKeyStoreBase64Property()); copy.setKeyStorePassword(getKeyStorePassword()); copy.setTrustStoreLocation(getTrustStoreLocation()); + copy.setTrustStoreBase64Property(getTrustStoreBase64Property()); copy.setTrustStorePassword(getTrustStorePassword()); copy.setKeyStoreType(getKeyStoreType()); copy.setTrustStoreType(getTrustStoreType()); diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java index 18eace6d0..7712c19b2 100644 --- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java +++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/transports/TransportSupport.java @@ -16,16 +16,16 @@ */ package org.apache.qpid.jms.transports; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.net.URI; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import io.netty.buffer.ByteBufAllocator; +import io.netty.handler.ssl.OpenSsl; +import io.netty.handler.ssl.OpenSslX509KeyManagerFactory; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.SslHandler; +import io.netty.handler.ssl.SslProvider; +import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; @@ -35,18 +35,17 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.netty.buffer.ByteBufAllocator; -import io.netty.handler.ssl.OpenSsl; -import io.netty.handler.ssl.OpenSslX509KeyManagerFactory; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.SslHandler; -import io.netty.handler.ssl.SslProvider; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URI; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; /** * Static class that provides various utility methods used by Transport implementations. @@ -341,39 +340,39 @@ private static TrustManagerFactory loadTrustManagerFactory(TransportOptions opti return InsecureTrustManagerFactory.INSTANCE; } - if (options.getTrustStoreLocation() == null) { + String storeLocation = options.getTrustStoreLocation(); + String storeBase64Property = options.getTrustStoreBase64Property(); + if (storeLocation == null && storeBase64Property == null) { return null; + } else if (storeLocation != null && storeBase64Property != null) { + throw new IllegalArgumentException("Only one of trustStoreLocation and trustStoreBase64Property should be defined"); } TrustManagerFactory fact = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - String storeLocation = options.getTrustStoreLocation(); String storePassword = options.getTrustStorePassword(); String storeType = options.getTrustStoreType(); - - LOG.trace("Attempt to load TrustStore from location {} of type {}", storeLocation, storeType); - - KeyStore trustStore = loadStore(storeLocation, storePassword, storeType); + KeyStore trustStore = loadStore(storeLocation, storeBase64Property, storePassword, storeType); fact.init(trustStore); return fact; } private static KeyManager[] loadKeyManagers(TransportOptions options) throws Exception { - if (options.getKeyStoreLocation() == null) { + String storeLocation = options.getKeyStoreLocation(); + String storeBase64Property = options.getKeyStoreBase64Property(); + if (storeLocation == null && storeBase64Property == null) { return null; + } else if (storeLocation != null && storeBase64Property != null) { + throw new IllegalArgumentException("Only one of keyStoreLocation and keyStoreBase64Property should be defined"); } KeyManagerFactory fact = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - String storeLocation = options.getKeyStoreLocation(); String storePassword = options.getKeyStorePassword(); String storeType = options.getKeyStoreType(); String alias = options.getKeyAlias(); - - LOG.trace("Attempt to load KeyStore from location {} of type {}", storeLocation, storeType); - - KeyStore keyStore = loadStore(storeLocation, storePassword, storeType); + KeyStore keyStore = loadStore(storeLocation, storeBase64Property, storePassword, storeType); fact.init(keyStore, storePassword != null ? storePassword.toCharArray() : null); if (alias == null) { @@ -385,8 +384,12 @@ private static KeyManager[] loadKeyManagers(TransportOptions options) throws Exc } private static KeyManagerFactory loadKeyManagerFactory(TransportOptions options, SslProvider provider) throws Exception { - if (options.getKeyStoreLocation() == null) { + String storeLocation = options.getKeyStoreLocation(); + String storeBase64Property = options.getKeyStoreBase64Property(); + if (storeLocation == null && storeBase64Property == null) { return null; + } else if (storeLocation != null && storeBase64Property != null) { + throw new IllegalArgumentException("Only one of keyStoreLocation and keyStoreBase64Property should be defined"); } final KeyManagerFactory factory; @@ -396,13 +399,9 @@ private static KeyManagerFactory loadKeyManagerFactory(TransportOptions options, factory = new OpenSslX509KeyManagerFactory(); } - String storeLocation = options.getKeyStoreLocation(); String storePassword = options.getKeyStorePassword(); String storeType = options.getKeyStoreType(); - - LOG.trace("Attempt to load KeyStore from location {} of type {}", storeLocation, storeType); - - KeyStore keyStore = loadStore(storeLocation, storePassword, storeType); + KeyStore keyStore = loadStore(storeLocation, storeBase64Property, storePassword, storeType); factory.init(keyStore, storePassword != null ? storePassword.toCharArray() : null); return factory; @@ -432,12 +431,33 @@ private static void validateAlias(KeyStore store, String alias) throws IllegalAr } } - private static KeyStore loadStore(String storePath, final String password, String storeType) throws Exception { + private static KeyStore loadStore(final String storeLocation, final String storeBase64Property, final String password, String storeType) throws Exception { + KeyStore store; + if (storeLocation != null) { + LOG.trace("Attempt to load store from location {} of type {}", storeLocation, storeType); + store = loadStoreFromFile(storeLocation, password, storeType); + } else { + LOG.trace("Attempt to load store from system property {} of type {}", storeBase64Property, storeType); + store = loadStoreFromSystemProperty(storeBase64Property, password, storeType); + } + return store; + } + + private static KeyStore loadStoreFromFile(final String storePath, final String password, final String storeType) throws Exception { KeyStore store = KeyStore.getInstance(storeType); - try (InputStream in = new FileInputStream(new File(storePath));) { + try (InputStream in = new FileInputStream(storePath)) { store.load(in, password != null ? password.toCharArray() : null); } return store; } + + private static KeyStore loadStoreFromSystemProperty(final String property, final String password, final String storeType) throws Exception { + KeyStore store = KeyStore.getInstance(storeType); + String keyStoreBase64 = System.getProperty(property); + byte[] keyStoreBytes = Base64.getDecoder().decode(keyStoreBase64); + store.load(new ByteArrayInputStream(keyStoreBytes), password != null ? password.toCharArray() : null); + + return store; + } } diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java index 5af668954..6d344ed5b 100644 --- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportOptionsTest.java @@ -16,22 +16,20 @@ */ package org.apache.qpid.jms.transports; +import io.netty.handler.proxy.ProxyHandler; +import org.apache.qpid.jms.test.QpidJmsTestCase; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import javax.net.ssl.SSLContext; +import java.util.function.Supplier; + import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.fail; -import java.util.function.Supplier; - -import javax.net.ssl.SSLContext; - -import org.apache.qpid.jms.test.QpidJmsTestCase; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import io.netty.handler.proxy.ProxyHandler; - /** * Test for class TransportOptions */ @@ -54,7 +52,9 @@ public class TransportOptionsTest extends QpidJmsTestCase { private static final String PASSWORD = "password"; private static final String CLIENT_KEYSTORE = "src/test/resources/client-jks.keystore"; + private static final String CLIENT_KEYSTORE_BASE64_PROPERTY = "base64.keystore.property"; private static final String CLIENT_TRUSTSTORE = "src/test/resources/client-jks.truststore"; + private static final String CLIENT_TRUSTSTORE_BASE64_PROPERTY = "base64.truststore.property"; private static final String KEYSTORE_TYPE = "jks"; private static final String KEY_ALIAS = "myTestAlias"; private static final String CONTEXT_PROTOCOL = "TLSv1.1"; @@ -93,8 +93,10 @@ public void testCreate() { assertNull(options.getDisabledCipherSuites()); assertNull(options.getKeyStoreLocation()); + assertNull(options.getKeyStoreBase64Property()); assertNull(options.getKeyStorePassword()); assertNull(options.getTrustStoreLocation()); + assertNull(options.getTrustStoreBase64Property()); assertNull(options.getTrustStorePassword()); assertNull(options.getKeyAlias()); assertNull(options.getSslContextOverride()); @@ -136,8 +138,10 @@ public void testClone() { assertEquals(TEST_USE_EPOLL_VALUE, options.isUseEpoll()); assertEquals(TEST_TRACE_BYTES_VALUE, options.isTraceBytes()); assertEquals(CLIENT_KEYSTORE, options.getKeyStoreLocation()); + assertEquals(CLIENT_KEYSTORE_BASE64_PROPERTY, options.getKeyStoreBase64Property()); assertEquals(PASSWORD, options.getKeyStorePassword()); assertEquals(CLIENT_TRUSTSTORE, options.getTrustStoreLocation()); + assertEquals(CLIENT_TRUSTSTORE_BASE64_PROPERTY, options.getTrustStoreBase64Property()); assertEquals(PASSWORD, options.getTrustStorePassword()); assertEquals(KEYSTORE_TYPE, options.getKeyStoreType()); assertEquals(KEYSTORE_TYPE, options.getTrustStoreType()); @@ -221,8 +225,10 @@ public void testCreateAndConfigure() { assertEquals(TEST_CONNECT_TIMEOUT, options.getConnectTimeout()); assertEquals(CLIENT_KEYSTORE, options.getKeyStoreLocation()); + assertEquals(CLIENT_KEYSTORE_BASE64_PROPERTY, options.getKeyStoreBase64Property()); assertEquals(PASSWORD, options.getKeyStorePassword()); assertEquals(CLIENT_TRUSTSTORE, options.getTrustStoreLocation()); + assertEquals(CLIENT_TRUSTSTORE_BASE64_PROPERTY, options.getTrustStoreBase64Property()); assertEquals(PASSWORD, options.getTrustStorePassword()); assertEquals(KEYSTORE_TYPE, options.getKeyStoreType()); assertEquals(KEYSTORE_TYPE, options.getTrustStoreType()); @@ -240,7 +246,9 @@ private TransportOptions createSslOptions() { TransportOptions options = new TransportOptions(); options.setKeyStoreLocation(CLIENT_KEYSTORE); + options.setKeyStoreBase64Property(CLIENT_KEYSTORE_BASE64_PROPERTY); options.setTrustStoreLocation(CLIENT_TRUSTSTORE); + options.setTrustStoreBase64Property(CLIENT_TRUSTSTORE_BASE64_PROPERTY); options.setKeyStorePassword(PASSWORD); options.setTrustStorePassword(PASSWORD); options.setStoreType(KEYSTORE_TYPE); @@ -327,8 +335,10 @@ private TransportOptions createNonDefaultOptions() { options.setUseEpoll(TEST_USE_EPOLL_VALUE); options.setTraceBytes(TEST_TRACE_BYTES_VALUE); options.setKeyStoreLocation(CLIENT_KEYSTORE); + options.setKeyStoreBase64Property(CLIENT_KEYSTORE_BASE64_PROPERTY); options.setKeyStorePassword(PASSWORD); options.setTrustStoreLocation(CLIENT_TRUSTSTORE); + options.setTrustStoreBase64Property(CLIENT_TRUSTSTORE_BASE64_PROPERTY); options.setTrustStorePassword(PASSWORD); options.setKeyAlias(KEY_ALIAS); options.setContextProtocol(CONTEXT_PROTOCOL); diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java index f40e0dd2a..6b052de60 100644 --- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java +++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/transports/TransportSupportTest.java @@ -16,6 +16,28 @@ */ package org.apache.qpid.jms.transports; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.handler.ssl.OpenSsl; +import io.netty.handler.ssl.OpenSslEngine; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslHandler; +import org.apache.qpid.jms.test.QpidJmsTestCase; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.UnrecoverableKeyException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; + import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -26,25 +48,6 @@ import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assumptions.assumeTrue; -import java.io.IOException; -import java.security.UnrecoverableKeyException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; - -import org.apache.qpid.jms.test.QpidJmsTestCase; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.handler.ssl.OpenSsl; -import io.netty.handler.ssl.OpenSslEngine; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslHandler; - /** * Tests for the TransportSupport class. */ @@ -67,6 +70,11 @@ public class TransportSupportTest extends QpidJmsTestCase { public static final String KEYSTORE_JCEKS_TYPE = "jceks"; public static final String KEYSTORE_PKCS12_TYPE = "pkcs12"; + public static final String KEYSTORE_SYSTEM_PROPERTY = "keystore.base64"; + public static final String TRUSTSTORE_SYSTEM_PROPERTY = "truststore.base64"; + + public static final String BAD_STORE_CONTENT = "bad-store-content"; + public static final String[] ENABLED_PROTOCOLS = new String[] { "TLSv1" }; // Currently the OpenSSL implementation cannot disable SSLv2Hello @@ -75,9 +83,10 @@ public class TransportSupportTest extends QpidJmsTestCase { private static final String ALIAS_DOES_NOT_EXIST = "alias.does.not.exist"; private static final String ALIAS_CA_CERT = "ca"; - @Test - public void testLegacySslProtocolsDisabledByDefaultJDK() throws Exception { - TransportOptions options = createJksSslOptions(null); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testLegacySslProtocolsDisabledByDefaultJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(null, useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -90,12 +99,13 @@ public void testLegacySslProtocolsDisabledByDefaultJDK() throws Exception { assertFalse(engineProtocols.contains("SSLv2Hello"), "SSLv2Hello should not be enabled by default"); } - @Test - public void testLegacySslProtocolsDisabledByDefaultOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testLegacySslProtocolsDisabledByDefaultOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(null); + TransportOptions options = createJksSslOptions(null, useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); @@ -110,9 +120,10 @@ public void testLegacySslProtocolsDisabledByDefaultOpenSSL() throws Exception { // assertFalse("SSLv2Hello should not be enabled by default", engineProtocols.contains("SSLv2Hello")); } - @Test - public void testCreateSslContextJksStoreJDK() throws Exception { - TransportOptions options = createJksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextJksStoreJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -120,12 +131,13 @@ public void testCreateSslContextJksStoreJDK() throws Exception { assertEquals("TLS", context.getProtocol()); } - @Test - public void testCreateSslContextJksStoreOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextJksStoreOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); @@ -134,9 +146,10 @@ public void testCreateSslContextJksStoreOpenSSL() throws Exception { // assertEquals("TLS", context.getProtocol()); } - @Test - public void testCreateSslContextJksStoreWithConfiguredContextProtocolJDK() throws Exception { - TransportOptions options = createJksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextJksStoreWithConfiguredContextProtocolJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(useStoreLocation); String contextProtocol = "TLSv1.2"; options.setContextProtocol(contextProtocol); @@ -146,12 +159,13 @@ public void testCreateSslContextJksStoreWithConfiguredContextProtocolJDK() throw assertEquals(contextProtocol, context.getProtocol()); } - @Test - public void testCreateSslContextJksStoreWithConfiguredContextProtocolOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextJksStoreWithConfiguredContextProtocolOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); String contextProtocol = "TLSv1.2"; options.setContextProtocol(contextProtocol); @@ -162,9 +176,10 @@ public void testCreateSslContextJksStoreWithConfiguredContextProtocolOpenSSL() t // assertEquals(contextProtocol, context.getProtocol()); } - @Test - public void testCreateSslContextNoKeyStorePasswordJDK() throws Exception { - TransportOptions options = createJksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextNoKeyStorePasswordJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(useStoreLocation); options.setKeyStorePassword(null); try { TransportSupport.createJdkSslContext(options); @@ -178,12 +193,13 @@ public void testCreateSslContextNoKeyStorePasswordJDK() throws Exception { } } - @Test - public void testCreateSslContextNoKeyStorePasswordOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextNoKeyStorePasswordOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); options.setKeyStorePassword(null); try { @@ -198,93 +214,122 @@ public void testCreateSslContextNoKeyStorePasswordOpenSSL() throws Exception { } } - @Test - public void testCreateSslContextWrongKeyStorePasswordJDK() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextWrongKeyStorePasswordJDK(boolean useStoreLocation) throws Exception { assertThrows(IOException.class, () -> { - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); options.setKeyStorePassword("wrong"); TransportSupport.createJdkSslContext(options); }); } - @Test - public void testCreateSslContextWrongKeyStorePasswordOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextWrongKeyStorePasswordOpenSSL(boolean useStoreLocation) throws Exception { assertThrows(IOException.class, () -> { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); options.setKeyStorePassword("wrong"); TransportSupport.createOpenSslContext(options); }); } - @Test - public void testCreateSslContextBadPathToKeyStoreJDK() throws Exception { - assertThrows(IOException.class, () -> { - TransportOptions options = createJksSslOptions(); - options.setKeyStoreLocation(CLIENT_JKS_KEYSTORE + ".bad"); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextBadPathToKeyStoreJDK(boolean useStoreLocation) throws Exception { + Class expectedException = useStoreLocation ? IOException.class : IllegalArgumentException.class; + assertThrows(expectedException, () -> { + TransportOptions options = createJksSslOptions(useStoreLocation); + if (useStoreLocation) { + options.setKeyStoreLocation(CLIENT_JKS_KEYSTORE + ".bad"); + } else { + System.setProperty(KEYSTORE_SYSTEM_PROPERTY, BAD_STORE_CONTENT); + } TransportSupport.createJdkSslContext(options); }); } - @Test - public void testCreateSslContextBadPathToKeyStoreOpenSSL() throws Exception { - assertThrows(IOException.class, () -> { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextBadPathToKeyStoreOpenSSL(boolean useStoreLocation) throws Exception { + Class expectedException = useStoreLocation ? IOException.class : IllegalArgumentException.class; + assertThrows(expectedException, () -> { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(); - options.setKeyStoreLocation(CLIENT_JKS_KEYSTORE + ".bad"); + TransportOptions options = createJksSslOptions(useStoreLocation); + if (useStoreLocation) { + options.setKeyStoreLocation(CLIENT_JKS_KEYSTORE + ".bad"); + } else { + System.setProperty(KEYSTORE_SYSTEM_PROPERTY, BAD_STORE_CONTENT); + } TransportSupport.createOpenSslContext(options); }); } - @Test - public void testCreateSslContextWrongTrustStorePasswordJDK() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextWrongTrustStorePasswordJDK(boolean useStoreLocation) throws Exception { assertThrows(IOException.class, () -> { - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); options.setTrustStorePassword("wrong"); TransportSupport.createJdkSslContext(options); }); } - @Test - public void testCreateSslContextWrongTrustStorePasswordOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextWrongTrustStorePasswordOpenSSL(boolean useStoreLocation) throws Exception { assertThrows(IOException.class, () -> { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); options.setTrustStorePassword("wrong"); TransportSupport.createOpenSslContext(options); }); } - @Test - public void testCreateSslContextBadPathToTrustStoreJDK() throws Exception { - assertThrows(IOException.class, () -> { - TransportOptions options = createJksSslOptions(); - options.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE + ".bad"); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextBadPathToTrustStoreJDK(boolean useStoreLocation) throws Exception { + Class expectedException = useStoreLocation ? IOException.class : IllegalArgumentException.class; + assertThrows(expectedException, () -> { + TransportOptions options = createJksSslOptions(useStoreLocation); + if (useStoreLocation) { + options.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE + ".bad"); + } else { + System.setProperty(TRUSTSTORE_SYSTEM_PROPERTY, BAD_STORE_CONTENT); + } TransportSupport.createJdkSslContext(options); }); } - @Test - public void testCreateSslContextBadPathToTrustStoreOpenSSL() throws Exception { - assertThrows(IOException.class, () -> { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextBadPathToTrustStoreOpenSSL(boolean useStoreLocation) throws Exception { + Class expectedException = useStoreLocation ? IOException.class : IllegalArgumentException.class; + assertThrows(expectedException, () -> { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(); - options.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE + ".bad"); + TransportOptions options = createJksSslOptions(useStoreLocation); + if (useStoreLocation) { + options.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE + ".bad"); + } else { + System.setProperty(TRUSTSTORE_SYSTEM_PROPERTY, BAD_STORE_CONTENT); + } TransportSupport.createOpenSslContext(options); }); } - @Test - public void testCreateSslContextJceksStoreJDK() throws Exception { - TransportOptions options = createJceksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextJceksStoreJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJceksSslOptions(useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -292,21 +337,23 @@ public void testCreateSslContextJceksStoreJDK() throws Exception { assertEquals("TLS", context.getProtocol()); } - @Test - public void testCreateSslContextJceksStoreOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextJceksStoreOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJceksSslOptions(); + TransportOptions options = createJceksSslOptions(useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); assertTrue(context.isClient()); } - @Test - public void testCreateSslContextPkcs12StoreJDK() throws Exception { - TransportOptions options = createPkcs12SslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextPkcs12StoreJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createPkcs12SslOptions(useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -314,42 +361,46 @@ public void testCreateSslContextPkcs12StoreJDK() throws Exception { assertEquals("TLS", context.getProtocol()); } - @Test - public void testCreateSslContextPkcs12StoreOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextPkcs12StoreOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createPkcs12SslOptions(); + TransportOptions options = createPkcs12SslOptions(useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); assertTrue(context.isClient()); } - @Test - public void testCreateSslContextIncorrectStoreTypeJDK() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextIncorrectStoreTypeJDK(boolean useStoreLocation) throws Exception { assertThrows(IOException.class, () -> { - TransportOptions options = createPkcs12SslOptions(); + TransportOptions options = createPkcs12SslOptions(useStoreLocation); options.setStoreType(KEYSTORE_JCEKS_TYPE); TransportSupport.createJdkSslContext(options); }); } - @Test - public void testCreateSslContextIncorrectStoreTypeOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextIncorrectStoreTypeOpenSSL(boolean useStoreLocation) throws Exception { assertThrows(IOException.class, () -> { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createPkcs12SslOptions(); + TransportOptions options = createPkcs12SslOptions(useStoreLocation); options.setStoreType(KEYSTORE_JCEKS_TYPE); TransportSupport.createOpenSslContext(options); }); } - @Test - public void testCreateSslEngineFromPkcs12StoreJDK() throws Exception { - TransportOptions options = createPkcs12SslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromPkcs12StoreJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createPkcs12SslOptions(useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -361,12 +412,13 @@ public void testCreateSslEngineFromPkcs12StoreJDK() throws Exception { assertFalse(engineProtocols.isEmpty()); } - @Test - public void testCreateSslEngineFromPkcs12StoreOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromPkcs12StoreOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createPkcs12SslOptions(); + TransportOptions options = createPkcs12SslOptions(useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); @@ -378,9 +430,10 @@ public void testCreateSslEngineFromPkcs12StoreOpenSSL() throws Exception { assertFalse(engineProtocols.isEmpty()); } - @Test - public void testCreateSslEngineFromPkcs12StoreWithExplicitEnabledProtocolsJDK() throws Exception { - TransportOptions options = createPkcs12SslOptions(ENABLED_PROTOCOLS); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromPkcs12StoreWithExplicitEnabledProtocolsJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createPkcs12SslOptions(ENABLED_PROTOCOLS, useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -391,12 +444,13 @@ public void testCreateSslEngineFromPkcs12StoreWithExplicitEnabledProtocolsJDK() assertArrayEquals(ENABLED_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromPkcs12StoreWithExplicitEnabledProtocolsOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromPkcs12StoreWithExplicitEnabledProtocolsOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createPkcs12SslOptions(ENABLED_PROTOCOLS); + TransportOptions options = createPkcs12SslOptions(ENABLED_PROTOCOLS, useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); @@ -407,9 +461,10 @@ public void testCreateSslEngineFromPkcs12StoreWithExplicitEnabledProtocolsOpenSS assertArrayEquals(ENABLED_OPENSSL_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreJDK() throws Exception { - TransportOptions options = createJksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -421,12 +476,13 @@ public void testCreateSslEngineFromJksStoreJDK() throws Exception { assertFalse(engineProtocols.isEmpty()); } - @Test - public void testCreateSslEngineFromJksStoreOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); @@ -438,9 +494,10 @@ public void testCreateSslEngineFromJksStoreOpenSSL() throws Exception { assertFalse(engineProtocols.isEmpty()); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitEnabledProtocolsJDK() throws Exception { - TransportOptions options = createJksSslOptions(ENABLED_PROTOCOLS); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitEnabledProtocolsJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(ENABLED_PROTOCOLS, useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -451,12 +508,13 @@ public void testCreateSslEngineFromJksStoreWithExplicitEnabledProtocolsJDK() thr assertArrayEquals(ENABLED_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitEnabledProtocolsOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitEnabledProtocolsOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJksSslOptions(ENABLED_PROTOCOLS); + TransportOptions options = createJksSslOptions(ENABLED_PROTOCOLS, useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); @@ -467,10 +525,11 @@ public void testCreateSslEngineFromJksStoreWithExplicitEnabledProtocolsOpenSSL() assertArrayEquals(ENABLED_OPENSSL_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitDisabledProtocolsJDK() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitDisabledProtocolsJDK(boolean useStoreLocation) throws Exception { // Discover the default enabled protocols - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createSSLEngineDirectly(options); String[] protocols = directEngine.getEnabledProtocols(); assertTrue(protocols.length > 0, "There were no initial protocols to choose from!"); @@ -487,13 +546,14 @@ public void testCreateSslEngineFromJksStoreWithExplicitDisabledProtocolsJDK() th assertArrayEquals(trimmedProtocols, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitDisabledProtocolsOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitDisabledProtocolsOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); // Discover the default enabled protocols - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createOpenSSLEngineDirectly(options); String[] protocols = directEngine.getEnabledProtocols(); assertTrue(protocols.length > 0, "There were no initial protocols to choose from!"); @@ -510,10 +570,11 @@ public void testCreateSslEngineFromJksStoreWithExplicitDisabledProtocolsOpenSSL( assertArrayEquals(trimmedProtocols, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledProtocolsJDK() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledProtocolsJDK(boolean useStoreLocation) throws Exception { // Discover the default enabled protocols - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createSSLEngineDirectly(options); String[] protocols = directEngine.getEnabledProtocols(); assumeTrue(protocols.length > 1 , "Insufficient initial protocols to filter from: " + Arrays.toString(protocols)); @@ -534,13 +595,14 @@ public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledProtoco assertArrayEquals(remainingProtocols, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledProtocolsOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledProtocolsOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); // Discover the default enabled protocols - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createOpenSSLEngineDirectly(options); String[] protocols = directEngine.getEnabledProtocols(); assumeTrue(protocols.length > 1 , "Insufficient initial protocols to filter from: " + Arrays.toString(protocols)); @@ -570,10 +632,11 @@ public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledProtoco assertTrue(remainingProtocolsList.containsAll(Arrays.asList(engine.getEnabledProtocols())), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitEnabledCiphersJDK() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitEnabledCiphersJDK(boolean useStoreLocation) throws Exception { // Discover the default enabled ciphers - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createSSLEngineDirectly(options); String[] ciphers = directEngine.getEnabledCipherSuites(); assertTrue(ciphers.length > 0, "There were no initial ciphers to choose from!"); @@ -590,13 +653,14 @@ public void testCreateSslEngineFromJksStoreWithExplicitEnabledCiphersJDK() throw assertArrayEquals(enabledCipher, engine.getEnabledCipherSuites(), "Enabled ciphers not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitEnabledCiphersOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitEnabledCiphersOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); // Discover the default enabled ciphers - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createOpenSSLEngineDirectly(options); String[] ciphers = directEngine.getEnabledCipherSuites(); assertTrue(ciphers.length > 0, "There were no initial ciphers to choose from!"); @@ -613,10 +677,11 @@ public void testCreateSslEngineFromJksStoreWithExplicitEnabledCiphersOpenSSL() t assertArrayEquals(enabledCipher, engine.getEnabledCipherSuites(), "Enabled ciphers not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitDisabledCiphersJDK() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitDisabledCiphersJDK(boolean useStoreLocation) throws Exception { // Discover the default enabled ciphers - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createSSLEngineDirectly(options); String[] ciphers = directEngine.getEnabledCipherSuites(); assertTrue(ciphers.length > 0, "There were no initial ciphers to choose from!"); @@ -633,13 +698,14 @@ public void testCreateSslEngineFromJksStoreWithExplicitDisabledCiphersJDK() thro assertArrayEquals(trimmedCiphers, engine.getEnabledCipherSuites(), "Enabled ciphers not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitDisabledCiphersOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitDisabledCiphersOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); // Discover the default enabled ciphers - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createOpenSSLEngineDirectly(options); String[] ciphers = directEngine.getEnabledCipherSuites(); assertTrue(ciphers.length > 0, "There were no initial ciphers to choose from!"); @@ -656,10 +722,11 @@ public void testCreateSslEngineFromJksStoreWithExplicitDisabledCiphersOpenSSL() assertArrayEquals(trimmedCiphers, engine.getEnabledCipherSuites(), "Enabled ciphers not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledCiphersJDK() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledCiphersJDK(boolean useStoreLocation) throws Exception { // Discover the default enabled ciphers - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createSSLEngineDirectly(options); String[] ciphers = directEngine.getEnabledCipherSuites(); assertTrue(ciphers.length > 1, "There werent enough initial ciphers to choose from!"); @@ -680,13 +747,14 @@ public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledCiphers assertArrayEquals(remainingCipher, engine.getEnabledCipherSuites(), "Enabled ciphers not as expected"); } - @Test - public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledCiphersOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledCiphersOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); // Discover the default enabled ciphers - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); SSLEngine directEngine = createOpenSSLEngineDirectly(options); String[] ciphers = directEngine.getEnabledCipherSuites(); assertTrue(ciphers.length > 1, "There werent enough initial ciphers to choose from!"); @@ -707,9 +775,10 @@ public void testCreateSslEngineFromJksStoreWithExplicitEnabledAndDisabledCiphers assertArrayEquals(remainingCipher, engine.getEnabledCipherSuites(), "Enabled ciphers not as expected"); } - @Test - public void testCreateSslEngineFromJceksStoreJDK() throws Exception { - TransportOptions options = createJceksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJceksStoreJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJceksSslOptions(useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -721,12 +790,13 @@ public void testCreateSslEngineFromJceksStoreJDK() throws Exception { assertFalse(engineProtocols.isEmpty()); } - @Test - public void testCreateSslEngineFromJceksStoreOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJceksStoreOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); - TransportOptions options = createJceksSslOptions(); + TransportOptions options = createJceksSslOptions(useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); @@ -738,9 +808,10 @@ public void testCreateSslEngineFromJceksStoreOpenSSL() throws Exception { assertFalse(engineProtocols.isEmpty()); } - @Test - public void testCreateSslEngineFromJceksStoreWithExplicitEnabledProtocolsJDK() throws Exception { - TransportOptions options = createJceksSslOptions(ENABLED_PROTOCOLS); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJceksStoreWithExplicitEnabledProtocolsJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJceksSslOptions(ENABLED_PROTOCOLS, useStoreLocation); SSLContext context = TransportSupport.createJdkSslContext(options); assertNotNull(context); @@ -751,14 +822,15 @@ public void testCreateSslEngineFromJceksStoreWithExplicitEnabledProtocolsJDK() t assertArrayEquals(ENABLED_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineFromJceksStoreWithExplicitEnabledProtocolsOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineFromJceksStoreWithExplicitEnabledProtocolsOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); // Try and disable all but the one we really want but for now expect that this one plus SSLv2Hello // is going to come back until the netty code can successfully disable them all. - TransportOptions options = createJceksSslOptions(ENABLED_PROTOCOLS); + TransportOptions options = createJceksSslOptions(ENABLED_PROTOCOLS, useStoreLocation); SslContext context = TransportSupport.createOpenSslContext(options); assertNotNull(context); @@ -769,9 +841,10 @@ public void testCreateSslEngineFromJceksStoreWithExplicitEnabledProtocolsOpenSSL assertArrayEquals(ENABLED_OPENSSL_PROTOCOLS, engine.getEnabledProtocols(), "Enabled protocols not as expected"); } - @Test - public void testCreateSslEngineWithVerifyHostJDK() throws Exception { - TransportOptions options = createJksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineWithVerifyHostJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(useStoreLocation); options.setVerifyHost(true); SSLContext context = TransportSupport.createJdkSslContext(options); @@ -783,13 +856,14 @@ public void testCreateSslEngineWithVerifyHostJDK() throws Exception { assertEquals("HTTPS", engine.getSSLParameters().getEndpointIdentificationAlgorithm()); } - @Test - public void testCreateSslEngineWithVerifyHostOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineWithVerifyHostOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); assumeTrue(OpenSsl.supportsHostnameValidation()); - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); options.setVerifyHost(true); SslContext context = TransportSupport.createOpenSslContext(options); @@ -801,9 +875,10 @@ public void testCreateSslEngineWithVerifyHostOpenSSL() throws Exception { assertEquals("HTTPS", engine.getSSLParameters().getEndpointIdentificationAlgorithm()); } - @Test - public void testCreateSslEngineWithoutVerifyHostJDK() throws Exception { - TransportOptions options = createJksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineWithoutVerifyHostJDK(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(useStoreLocation); options.setVerifyHost(false); SSLContext context = TransportSupport.createJdkSslContext(options); @@ -815,13 +890,14 @@ public void testCreateSslEngineWithoutVerifyHostJDK() throws Exception { assertNull(engine.getSSLParameters().getEndpointIdentificationAlgorithm()); } - @Test - public void testCreateSslEngineWithoutVerifyHostOpenSSL() throws Exception { + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslEngineWithoutVerifyHostOpenSSL(boolean useStoreLocation) throws Exception { assumeTrue(OpenSsl.isAvailable()); assumeTrue(OpenSsl.supportsKeyManagerFactory()); assumeTrue(OpenSsl.supportsHostnameValidation()); - TransportOptions options = createJksSslOptions(); + TransportOptions options = createJksSslOptions(useStoreLocation); options.setVerifyHost(false); SslContext context = TransportSupport.createOpenSslContext(options); @@ -833,9 +909,10 @@ public void testCreateSslEngineWithoutVerifyHostOpenSSL() throws Exception { assertNull(engine.getSSLParameters().getEndpointIdentificationAlgorithm()); } - @Test - public void testCreateSslContextWithKeyAliasWhichDoesntExist() throws Exception { - TransportOptions options = createJksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextWithKeyAliasWhichDoesntExist(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(useStoreLocation); options.setKeyAlias(ALIAS_DOES_NOT_EXIST); try { @@ -846,9 +923,10 @@ public void testCreateSslContextWithKeyAliasWhichDoesntExist() throws Exception } } - @Test - public void testCreateSslContextWithKeyAliasWhichRepresentsNonKeyEntry() throws Exception { - TransportOptions options = createJksSslOptions(); + @ValueSource(booleans = { true, false }) + @ParameterizedTest(name = "{index}: useStoreLocation={0}") + public void testCreateSslContextWithKeyAliasWhichRepresentsNonKeyEntry(boolean useStoreLocation) throws Exception { + TransportOptions options = createJksSslOptions(useStoreLocation); options.setKeyAlias(ALIAS_CA_CERT); try { @@ -948,15 +1026,22 @@ public void testCreateOpenSSLEngineFailsWhenAllocatorMissing() throws Exception } catch (IllegalArgumentException iae) {} } - private TransportOptions createJksSslOptions() { - return createJksSslOptions(null); + private TransportOptions createJksSslOptions(boolean useStoreLocation) throws IOException { + return createJksSslOptions(null, useStoreLocation); } - private TransportOptions createJksSslOptions(String[] enabledProtocols) { + private TransportOptions createJksSslOptions(String[] enabledProtocols, boolean useStoreLocation) throws IOException { TransportOptions options = new TransportOptions(); - options.setKeyStoreLocation(CLIENT_JKS_KEYSTORE); - options.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE); + if (useStoreLocation) { + options.setKeyStoreLocation(CLIENT_JKS_KEYSTORE); + options.setTrustStoreLocation(CLIENT_JKS_TRUSTSTORE); + } else { + System.setProperty(KEYSTORE_SYSTEM_PROPERTY, readStoreBase64Content(CLIENT_JKS_KEYSTORE)); + System.setProperty(TRUSTSTORE_SYSTEM_PROPERTY, readStoreBase64Content(CLIENT_JKS_TRUSTSTORE)); + options.setKeyStoreBase64Property(KEYSTORE_SYSTEM_PROPERTY); + options.setTrustStoreBase64Property(TRUSTSTORE_SYSTEM_PROPERTY); + } options.setStoreType(KEYSTORE_JKS_TYPE); options.setKeyStorePassword(PASSWORD); options.setTrustStorePassword(PASSWORD); @@ -967,15 +1052,22 @@ private TransportOptions createJksSslOptions(String[] enabledProtocols) { return options; } - private TransportOptions createJceksSslOptions() { - return createJceksSslOptions(null); + private TransportOptions createJceksSslOptions(boolean useStoreLocation) throws IOException { + return createJceksSslOptions(null, useStoreLocation); } - private TransportOptions createJceksSslOptions(String[] enabledProtocols) { + private TransportOptions createJceksSslOptions(String[] enabledProtocols, boolean useStoreLocation) throws IOException { TransportOptions options = new TransportOptions(); - options.setKeyStoreLocation(CLIENT_JCEKS_KEYSTORE); - options.setTrustStoreLocation(CLIENT_JCEKS_TRUSTSTORE); + if (useStoreLocation) { + options.setKeyStoreLocation(CLIENT_JCEKS_KEYSTORE); + options.setTrustStoreLocation(CLIENT_JCEKS_TRUSTSTORE); + } else { + System.setProperty(KEYSTORE_SYSTEM_PROPERTY, readStoreBase64Content(CLIENT_JCEKS_KEYSTORE)); + System.setProperty(TRUSTSTORE_SYSTEM_PROPERTY, readStoreBase64Content(CLIENT_JCEKS_TRUSTSTORE)); + options.setKeyStoreBase64Property(KEYSTORE_SYSTEM_PROPERTY); + options.setTrustStoreBase64Property(TRUSTSTORE_SYSTEM_PROPERTY); + } options.setStoreType(KEYSTORE_JCEKS_TYPE); options.setKeyStorePassword(PASSWORD); options.setTrustStorePassword(PASSWORD); @@ -986,15 +1078,22 @@ private TransportOptions createJceksSslOptions(String[] enabledProtocols) { return options; } - private TransportOptions createPkcs12SslOptions() { - return createPkcs12SslOptions(null); + private TransportOptions createPkcs12SslOptions(boolean useStoreLocation) throws IOException { + return createPkcs12SslOptions(null, useStoreLocation); } - private TransportOptions createPkcs12SslOptions(String[] enabledProtocols) { + private TransportOptions createPkcs12SslOptions(String[] enabledProtocols, boolean useStoreLocation) throws IOException { TransportOptions options = new TransportOptions(); - options.setKeyStoreLocation(CLIENT_PKCS12_KEYSTORE); - options.setTrustStoreLocation(CLIENT_PKCS12_TRUSTSTORE); + if (useStoreLocation) { + options.setKeyStoreLocation(CLIENT_PKCS12_KEYSTORE); + options.setTrustStoreLocation(CLIENT_PKCS12_TRUSTSTORE); + } else { + System.setProperty(KEYSTORE_SYSTEM_PROPERTY, readStoreBase64Content(CLIENT_PKCS12_KEYSTORE)); + System.setProperty(TRUSTSTORE_SYSTEM_PROPERTY, readStoreBase64Content(CLIENT_PKCS12_TRUSTSTORE)); + options.setKeyStoreBase64Property(KEYSTORE_SYSTEM_PROPERTY); + options.setTrustStoreBase64Property(TRUSTSTORE_SYSTEM_PROPERTY); + } options.setStoreType(KEYSTORE_PKCS12_TYPE); options.setKeyStorePassword(PASSWORD); options.setTrustStorePassword(PASSWORD); @@ -1016,4 +1115,9 @@ private SSLEngine createOpenSSLEngineDirectly(TransportOptions options) throws E SSLEngine engine = context.newEngine(PooledByteBufAllocator.DEFAULT); return engine; } + + private String readStoreBase64Content(String storePath) throws IOException { + byte[] storeBytes = Files.readAllBytes(Paths.get(storePath)); + return Base64.getEncoder().encodeToString(storeBytes); + } }