diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
index 65a63e5337..ebb274a1d8 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
@@ -642,7 +642,7 @@ public class NettyConnector extends AbstractConnector {
String realTrustStorePath,
String realTrustStorePassword) throws Exception {
- SslContext context = SSLSupport.createNettyContext(realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword, sslProvider);
+ SslContext context = SSLSupport.createNettyClientContext(realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword, sslProvider, trustAll);
Subject subject = null;
if (kerb5Config != null) {
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
index 297b294ec6..85c2c50609 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
@@ -29,7 +29,6 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.KeyStore;
-import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.SecureRandom;
import java.security.Security;
@@ -39,7 +38,6 @@ import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.X509CertSelector;
-import java.security.cert.X509Certificate;
import java.util.Collection;
import io.netty.handler.ssl.SslContext;
@@ -112,12 +110,26 @@ public class SSLSupport {
final String sslProvider) throws Exception {
KeyStore keyStore = SSLSupport.loadKeystore(keystoreProvider, keystorePath, keystorePassword);
- String alias = keyStore.aliases().nextElement();
- PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, keystorePassword.toCharArray());
- X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias);
- return SslContextBuilder.forServer(privateKey, certificate).sslProvider(SslProvider.valueOf(sslProvider)).trustManager(SSLSupport.loadTrustManagerFactory(trustStoreProvider, trustStorePath, trustStorePassword, false, null)).build();
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(keyStore, keystorePassword.toCharArray());
+ return SslContextBuilder.forServer(keyManagerFactory).sslProvider(SslProvider.valueOf(sslProvider)).trustManager(SSLSupport.loadTrustManagerFactory(trustStoreProvider, trustStorePath, trustStorePassword, false, null)).build();
}
+ public static SslContext createNettyClientContext(final String keystoreProvider,
+ final String keystorePath,
+ final String keystorePassword,
+ final String trustStoreProvider,
+ final String trustStorePath,
+ final String trustStorePassword,
+ final String sslProvider,
+ final boolean trustAll ) throws Exception {
+ KeyStore keyStore = SSLSupport.loadKeystore(keystoreProvider, keystorePath, keystorePassword);
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(keyStore, keystorePassword.toCharArray());
+ return SslContextBuilder.forClient().sslProvider(SslProvider.valueOf(sslProvider)).keyManager(keyManagerFactory).trustManager(SSLSupport.loadTrustManagerFactory(trustStoreProvider, trustStorePath, trustStorePassword, trustAll, null)).build();
+ }
+
+
public static String[] parseCommaSeparatedListIntoArray(String suites) {
String[] cipherSuites = suites.split(",");
for (int i = 0; i < cipherSuites.length; i++) {
diff --git a/tests/integration-tests/pom.xml b/tests/integration-tests/pom.xml
index 0558075876..b8ff029756 100644
--- a/tests/integration-tests/pom.xml
+++ b/tests/integration-tests/pom.xml
@@ -396,6 +396,13 @@
org.jgroups
jgroups
+
+
+
+ io.netty
+ netty-tcnative-boringssl-static
+ 2.0.7.Final
+
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ssl/CoreClientOverTwoWayOpenSSLServerTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ssl/CoreClientOverTwoWayOpenSSLServerTest.java
new file mode 100644
index 0000000000..dac87fcfd2
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ssl/CoreClientOverTwoWayOpenSSLServerTest.java
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.ssl;
+
+import io.netty.handler.ssl.SslHandler;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException;
+import org.apache.activemq.artemis.api.core.Interceptor;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.api.core.client.ClientConsumer;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
+import org.apache.activemq.artemis.core.protocol.core.Packet;
+import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptor;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnection;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.RandomUtil;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Test connecting to a server running with OpenSSL TLS from a client that is running with JDK TLS
+ */
+@RunWith(value = Parameterized.class)
+public class CoreClientOverTwoWayOpenSSLServerTest extends ActiveMQTestBase {
+
+ @Parameterized.Parameters(name = "storeType={0}")
+ public static Collection getParameters() {
+ return Arrays.asList(new Object[][]{{"JCEKS"}, {"JKS"}});
+ }
+
+ public CoreClientOverTwoWayOpenSSLServerTest(String storeType) {
+ this.storeType = storeType;
+ SERVER_SIDE_KEYSTORE = "openssl-server-side-keystore." + storeType.toLowerCase();
+ SERVER_SIDE_TRUSTSTORE = "openssl-server-side-truststore." + storeType.toLowerCase();
+ CLIENT_SIDE_TRUSTSTORE = "openssl-client-side-truststore." + storeType.toLowerCase();
+ CLIENT_SIDE_KEYSTORE = "openssl-client-side-keystore." + storeType.toLowerCase();
+ }
+
+ public static final SimpleString QUEUE = new SimpleString("QueueOverSSL");
+
+ /**
+ * These artifacts are required for testing 2-way SSL with open SSL - note the EC key and ECDSA signature to comply with what OpenSSL offers
+ *
+ * Commands to create the JKS artifacts:
+ * keytool -genkey -keystore openssl-client-side-keystore.jks -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Client, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore openssl-client-side-keystore.jks -file activemq-jks.cer -storepass secureexample
+ * keytool -import -keystore openssl-server-side-truststore.jks -file activemq-jks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * keytool -genkey -keystore openssl-server-side-keystore.jks -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Server, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore openssl-server-side-keystore.jks -file activemq-jks.cer -storepass secureexample
+ * keytool -import -keystore openssl-client-side-truststore.jks -file activemq-jks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * keytool -genkey -keystore verified-openssl-client-side-keystore.jks -storepass secureexample -keypass secureexample -dname "CN=localhost, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore verified-openssl-client-side-keystore.jks -file activemq-jks.cer -storepass secureexample
+ * keytool -import -keystore verified-openssl-server-side-truststore.jks -file activemq-jks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * Commands to create the JCEKS artifacts:
+ * keytool -genkey -keystore openssl-client-side-keystore.jceks -storetype JCEKS -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Client, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore openssl-client-side-keystore.jceks -file activemq-jceks.cer -storetype jceks -storepass secureexample
+ * keytool -import -keystore openssl-server-side-truststore.jceks -storetype JCEKS -file activemq-jceks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * keytool -genkey -keystore openssl-server-side-keystore.jceks -storetype JCEKS -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Server, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore openssl-server-side-keystore.jceks -file activemq-jceks.cer -storetype jceks -storepass secureexample
+ * keytool -import -keystore openssl-client-side-truststore.jceks -storetype JCEKS -file activemq-jceks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * keytool -genkey -keystore verified-openssl-client-side-keystore.jceks -storetype JCEKS -storepass secureexample -keypass secureexample -dname "CN=localhost, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore verified-openssl-client-side-keystore.jceks -file activemq-jceks.cer -storetype jceks -storepass secureexample
+ * keytool -import -keystore verified-openssl-server-side-truststore.jceks -storetype JCEKS -file activemq-jceks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ */
+
+ private String storeType;
+ private String SERVER_SIDE_KEYSTORE;
+ private String SERVER_SIDE_TRUSTSTORE;
+ private String CLIENT_SIDE_TRUSTSTORE;
+ private String CLIENT_SIDE_KEYSTORE;
+ private final String PASSWORD = "secureexample";
+
+ private ActiveMQServer server;
+
+ private TransportConfiguration tc;
+
+ private class MyInterceptor implements Interceptor {
+
+ @Override
+ public boolean intercept(final Packet packet, final RemotingConnection connection) throws ActiveMQException {
+ if (packet.getType() == PacketImpl.SESS_SEND) {
+ try {
+ if (connection.getTransportConnection() instanceof NettyConnection) {
+ System.out.println("Passed through....");
+ NettyConnection nettyConnection = (NettyConnection) connection.getTransportConnection();
+ SslHandler sslHandler = (SslHandler) nettyConnection.getChannel().pipeline().get("ssl");
+ Assert.assertNotNull(sslHandler);
+ Assert.assertNotNull(sslHandler.engine().getSession());
+ Assert.assertNotNull(sslHandler.engine().getSession().getPeerCertificateChain());
+ }
+ } catch (SSLPeerUnverifiedException e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+ return true;
+ }
+ }
+
+ @Test
+ public void testTwoWaySSL() throws Exception {
+ String text = RandomUtil.randomString();
+
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, CLIENT_SIDE_TRUSTSTORE);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ //tc.getParams().put(TransportConstants.ENABLED_CIPHER_SUITES_PROP_NAME, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ ClientSessionFactory sf = createSessionFactory(locator);
+ ClientSession session = sf.createSession(false, true, true);
+ session.createQueue(CoreClientOverTwoWayOpenSSLServerTest.QUEUE, CoreClientOverTwoWayOpenSSLServerTest.QUEUE, false);
+ ClientProducer producer = session.createProducer(CoreClientOverTwoWayOpenSSLServerTest.QUEUE);
+
+ ClientMessage message = createTextMessage(session, text);
+ producer.send(message);
+
+ ClientConsumer consumer = session.createConsumer(CoreClientOverTwoWayOpenSSLServerTest.QUEUE);
+ session.start();
+
+ ClientMessage m = consumer.receive(1000);
+ Assert.assertNotNull(m);
+ Assert.assertEquals(text, m.getBodyBuffer().readString());
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientHost() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.VERIFY_HOST_PROP_NAME, true);
+ acceptor.getConfiguration().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "verified-" + SERVER_SIDE_TRUSTSTORE);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ String text = RandomUtil.randomString();
+
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, CLIENT_SIDE_TRUSTSTORE);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "verified-" + CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ ClientSessionFactory sf = createSessionFactory(locator);
+ ClientSession session = sf.createSession(false, true, true);
+ session.createQueue(CoreClientOverTwoWayOpenSSLServerTest.QUEUE, CoreClientOverTwoWayOpenSSLServerTest.QUEUE, false);
+ ClientProducer producer = session.createProducer(CoreClientOverTwoWayOpenSSLServerTest.QUEUE);
+
+ ClientMessage message = createTextMessage(session, text);
+ producer.send(message);
+
+ ClientConsumer consumer = session.createConsumer(CoreClientOverTwoWayOpenSSLServerTest.QUEUE);
+ session.start();
+
+ ClientMessage m = consumer.receive(1000);
+ Assert.assertNotNull(m);
+ Assert.assertEquals(text, m.getBodyBuffer().readString());
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientHostNegative() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.VERIFY_HOST_PROP_NAME, true);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, CLIENT_SIDE_TRUSTSTORE);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ try {
+ ClientSessionFactory sf = createSessionFactory(locator);
+ fail("Creating a session here should fail due to a certificate with a CN that doesn't match the host name.");
+ } catch (ActiveMQNotConnectedException se) {
+ // ignore
+ }
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientTrustAllTrue() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ //Set trust all so this should work even with no trust store set
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.TRUST_ALL_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ ClientSessionFactory sf = createSessionFactory(locator);
+ sf.close();
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientTrustAllTrueByURI() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ //Set trust all so this should work even with no trust store set
+ StringBuilder uri = new StringBuilder("tcp://" + tc.getParams().get(TransportConstants.HOST_PROP_NAME).toString()
+ + ":" + tc.getParams().get(TransportConstants.PORT_PROP_NAME).toString());
+
+ uri.append("?").append(TransportConstants.SSL_ENABLED_PROP_NAME).append("=true");
+ uri.append("&").append(TransportConstants.TRUST_ALL_PROP_NAME).append("=true");
+ uri.append("&").append(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME).append("=").append(storeType);
+ uri.append("&").append(TransportConstants.KEYSTORE_PATH_PROP_NAME).append("=").append(CLIENT_SIDE_KEYSTORE);
+ uri.append("&").append(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME).append("=").append(PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocator(uri.toString()));
+ ClientSessionFactory sf = createSessionFactory(locator);
+ sf.close();
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientTrustAllFalse() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ //Trust all defaults to false so this should fail with no trust store set
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ try {
+ ClientSessionFactory sf = createSessionFactory(locator);
+ fail("Creating a session here should fail due to no trust store being set");
+ } catch (ActiveMQNotConnectedException se) {
+ // ignore
+ }
+ }
+
+ @Test
+ public void testTwoWaySSLWithoutClientKeyStore() throws Exception {
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, CLIENT_SIDE_TRUSTSTORE);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ try {
+ createSessionFactory(locator);
+ Assert.fail();
+ } catch (ActiveMQNotConnectedException se) {
+ //ok
+ } catch (ActiveMQException e) {
+ Assert.fail("Invalid Exception type:" + e.getType());
+ }
+ }
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ Map params = new HashMap<>();
+ params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ params.put(TransportConstants.SSL_PROVIDER, TransportConstants.OPENSSL_PROVIDER);
+ params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, SERVER_SIDE_KEYSTORE);
+ params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, SERVER_SIDE_TRUSTSTORE);
+ params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ params.put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ params.put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ params.put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ ConfigurationImpl config = createBasicConfig().addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params, "nettySSL"));
+ server = createServer(false, config);
+ server.start();
+ waitForServerToStart(server);
+ tc = new TransportConfiguration(NETTY_CONNECTOR_FACTORY);
+ }
+}
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ssl/CoreClientOverTwoWayOpenSSLTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ssl/CoreClientOverTwoWayOpenSSLTest.java
new file mode 100644
index 0000000000..cb8c73dd27
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/ssl/CoreClientOverTwoWayOpenSSLTest.java
@@ -0,0 +1,351 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.ssl;
+
+import io.netty.handler.ssl.SslHandler;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException;
+import org.apache.activemq.artemis.api.core.Interceptor;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.api.core.client.ClientConsumer;
+import org.apache.activemq.artemis.api.core.client.ClientMessage;
+import org.apache.activemq.artemis.api.core.client.ClientProducer;
+import org.apache.activemq.artemis.api.core.client.ClientSession;
+import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
+import org.apache.activemq.artemis.core.protocol.core.Packet;
+import org.apache.activemq.artemis.core.protocol.core.impl.PacketImpl;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptor;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnection;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.utils.RandomUtil;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Testing connection where client and server are running OpenSSL TLS
+ */
+@RunWith(value = Parameterized.class)
+public class CoreClientOverTwoWayOpenSSLTest extends ActiveMQTestBase {
+
+ @Parameterized.Parameters(name = "storeType={0}")
+ public static Collection getParameters() {
+ return Arrays.asList(new Object[][]{{"JCEKS"}, {"JKS"}});
+ }
+
+ public CoreClientOverTwoWayOpenSSLTest(String storeType) {
+ this.storeType = storeType;
+ SERVER_SIDE_KEYSTORE = "openssl-server-side-keystore." + storeType.toLowerCase();
+ SERVER_SIDE_TRUSTSTORE = "openssl-server-side-truststore." + storeType.toLowerCase();
+ CLIENT_SIDE_TRUSTSTORE = "openssl-client-side-truststore." + storeType.toLowerCase();
+ CLIENT_SIDE_KEYSTORE = "openssl-client-side-keystore." + storeType.toLowerCase();
+ }
+
+ public static final SimpleString QUEUE = new SimpleString("QueueOverSSL");
+
+ /**
+ * These artifacts are required for testing 2-way SSL with open SSL - note the EC key and ECDSA signature to comply with what OpenSSL offers
+ *
+ * Commands to create the JKS artifacts:
+ * keytool -genkey -keystore openssl-client-side-keystore.jks -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Client, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore openssl-client-side-keystore.jks -file activemq-jks.cer -storepass secureexample
+ * keytool -import -keystore openssl-server-side-truststore.jks -file activemq-jks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * keytool -genkey -keystore openssl-server-side-keystore.jks -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Server, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore openssl-server-side-keystore.jks -file activemq-jks.cer -storepass secureexample
+ * keytool -import -keystore openssl-client-side-truststore.jks -file activemq-jks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * keytool -genkey -keystore verified-openssl-client-side-keystore.jks -storepass secureexample -keypass secureexample -dname "CN=localhost, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore verified-openssl-client-side-keystore.jks -file activemq-jks.cer -storepass secureexample
+ * keytool -import -keystore verified-openssl-server-side-truststore.jks -file activemq-jks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * Commands to create the JCEKS artifacts:
+ * keytool -genkey -keystore openssl-client-side-keystore.jceks -storetype JCEKS -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Client, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore openssl-client-side-keystore.jceks -file activemq-jceks.cer -storetype jceks -storepass secureexample
+ * keytool -import -keystore openssl-server-side-truststore.jceks -storetype JCEKS -file activemq-jceks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * keytool -genkey -keystore openssl-server-side-keystore.jceks -storetype JCEKS -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Server, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore openssl-server-side-keystore.jceks -file activemq-jceks.cer -storetype jceks -storepass secureexample
+ * keytool -import -keystore openssl-client-side-truststore.jceks -storetype JCEKS -file activemq-jceks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ * keytool -genkey -keystore verified-openssl-client-side-keystore.jceks -storetype JCEKS -storepass secureexample -keypass secureexample -dname "CN=localhost, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg EC -sigalg SHA256withECDSA
+ * keytool -export -keystore verified-openssl-client-side-keystore.jceks -file activemq-jceks.cer -storetype jceks -storepass secureexample
+ * keytool -import -keystore verified-openssl-server-side-truststore.jceks -storetype JCEKS -file activemq-jceks.cer -storepass secureexample -keypass secureexample -noprompt
+ *
+ */
+
+ private String storeType;
+ private String SERVER_SIDE_KEYSTORE;
+ private String SERVER_SIDE_TRUSTSTORE;
+ private String CLIENT_SIDE_TRUSTSTORE;
+ private String CLIENT_SIDE_KEYSTORE;
+ private final String PASSWORD = "secureexample";
+
+ private ActiveMQServer server;
+
+ private TransportConfiguration tc;
+
+ private class MyInterceptor implements Interceptor {
+
+ @Override
+ public boolean intercept(final Packet packet, final RemotingConnection connection) throws ActiveMQException {
+ if (packet.getType() == PacketImpl.SESS_SEND) {
+ try {
+ if (connection.getTransportConnection() instanceof NettyConnection) {
+ System.out.println("Passed through....");
+ NettyConnection nettyConnection = (NettyConnection) connection.getTransportConnection();
+ SslHandler sslHandler = (SslHandler) nettyConnection.getChannel().pipeline().get("ssl");
+ Assert.assertNotNull(sslHandler);
+ Assert.assertNotNull(sslHandler.engine().getSession());
+ Assert.assertNotNull(sslHandler.engine().getSession().getPeerCertificateChain());
+ }
+ } catch (SSLPeerUnverifiedException e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+ return true;
+ }
+ }
+
+ @Test
+ public void testTwoWaySSL() throws Exception {
+ String text = RandomUtil.randomString();
+
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.SSL_PROVIDER, TransportConstants.OPENSSL_PROVIDER);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, CLIENT_SIDE_TRUSTSTORE);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ //tc.getParams().put(TransportConstants.ENABLED_CIPHER_SUITES_PROP_NAME, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ ClientSessionFactory sf = createSessionFactory(locator);
+ ClientSession session = sf.createSession(false, true, true);
+ session.createQueue(CoreClientOverTwoWayOpenSSLTest.QUEUE, CoreClientOverTwoWayOpenSSLTest.QUEUE, false);
+ ClientProducer producer = session.createProducer(CoreClientOverTwoWayOpenSSLTest.QUEUE);
+
+ ClientMessage message = createTextMessage(session, text);
+ producer.send(message);
+
+ ClientConsumer consumer = session.createConsumer(CoreClientOverTwoWayOpenSSLTest.QUEUE);
+ session.start();
+
+ ClientMessage m = consumer.receive(1000);
+ Assert.assertNotNull(m);
+ Assert.assertEquals(text, m.getBodyBuffer().readString());
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientHost() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.VERIFY_HOST_PROP_NAME, true);
+ acceptor.getConfiguration().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "verified-" + SERVER_SIDE_TRUSTSTORE);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ String text = RandomUtil.randomString();
+
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.SSL_PROVIDER, TransportConstants.OPENSSL_PROVIDER);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, CLIENT_SIDE_TRUSTSTORE);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, "verified-" + CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ ClientSessionFactory sf = createSessionFactory(locator);
+ ClientSession session = sf.createSession(false, true, true);
+ session.createQueue(CoreClientOverTwoWayOpenSSLTest.QUEUE, CoreClientOverTwoWayOpenSSLTest.QUEUE, false);
+ ClientProducer producer = session.createProducer(CoreClientOverTwoWayOpenSSLTest.QUEUE);
+
+ ClientMessage message = createTextMessage(session, text);
+ producer.send(message);
+
+ ClientConsumer consumer = session.createConsumer(CoreClientOverTwoWayOpenSSLTest.QUEUE);
+ session.start();
+
+ ClientMessage m = consumer.receive(1000);
+ Assert.assertNotNull(m);
+ Assert.assertEquals(text, m.getBodyBuffer().readString());
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientHostNegative() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.VERIFY_HOST_PROP_NAME, true);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.SSL_PROVIDER, TransportConstants.OPENSSL_PROVIDER);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, CLIENT_SIDE_TRUSTSTORE);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ try {
+ ClientSessionFactory sf = createSessionFactory(locator);
+ fail("Creating a session here should fail due to a certificate with a CN that doesn't match the host name.");
+ } catch (ActiveMQNotConnectedException se) {
+ // ignore
+ }
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientTrustAllTrue() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ //Set trust all so this should work even with no trust store set
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.SSL_PROVIDER, TransportConstants.OPENSSL_PROVIDER);
+ tc.getParams().put(TransportConstants.TRUST_ALL_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ ClientSessionFactory sf = createSessionFactory(locator);
+ sf.close();
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientTrustAllTrueByURI() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ //Set trust all so this should work even with no trust store set
+ StringBuilder uri = new StringBuilder("tcp://" + tc.getParams().get(TransportConstants.HOST_PROP_NAME).toString()
+ + ":" + tc.getParams().get(TransportConstants.PORT_PROP_NAME).toString());
+
+ uri.append("?").append(TransportConstants.SSL_ENABLED_PROP_NAME).append("=true");
+ uri.append("&").append(TransportConstants.SSL_PROVIDER).append("=").append(TransportConstants.OPENSSL_PROVIDER);
+ uri.append("&").append(TransportConstants.TRUST_ALL_PROP_NAME).append("=true");
+ uri.append("&").append(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME).append("=").append(storeType);
+ uri.append("&").append(TransportConstants.KEYSTORE_PATH_PROP_NAME).append("=").append(CLIENT_SIDE_KEYSTORE);
+ uri.append("&").append(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME).append("=").append(PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocator(uri.toString()));
+ ClientSessionFactory sf = createSessionFactory(locator);
+ sf.close();
+ }
+
+ @Test
+ public void testTwoWaySSLVerifyClientTrustAllFalse() throws Exception {
+ NettyAcceptor acceptor = (NettyAcceptor) server.getRemotingService().getAcceptor("nettySSL");
+ acceptor.getConfiguration().put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ server.getRemotingService().stop(false);
+ server.getRemotingService().start();
+ server.getRemotingService().startAcceptors();
+
+ //Trust all defaults to false so this should fail with no trust store set
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.KEYSTORE_PATH_PROP_NAME, CLIENT_SIDE_KEYSTORE);
+ tc.getParams().put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ server.getRemotingService().addIncomingInterceptor(new MyInterceptor());
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ try {
+ ClientSessionFactory sf = createSessionFactory(locator);
+ fail("Creating a session here should fail due to no trust store being set");
+ } catch (ActiveMQNotConnectedException se) {
+ // ignore
+ }
+ }
+
+ @Test
+ public void testTwoWaySSLWithoutClientKeyStore() throws Exception {
+ tc.getParams().put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, CLIENT_SIDE_TRUSTSTORE);
+ tc.getParams().put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+
+ ServerLocator locator = addServerLocator(ActiveMQClient.createServerLocatorWithoutHA(tc));
+ try {
+ createSessionFactory(locator);
+ Assert.fail();
+ } catch (ActiveMQNotConnectedException se) {
+ //ok
+ } catch (ActiveMQException e) {
+ Assert.fail("Invalid Exception type:" + e.getType());
+ }
+ }
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ Map params = new HashMap<>();
+ params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true);
+ params.put(TransportConstants.SSL_PROVIDER, TransportConstants.OPENSSL_PROVIDER);
+ params.put(TransportConstants.KEYSTORE_PATH_PROP_NAME, SERVER_SIDE_KEYSTORE);
+ params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, SERVER_SIDE_TRUSTSTORE);
+ params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, PASSWORD);
+ params.put(TransportConstants.TRUSTSTORE_PROVIDER_PROP_NAME, storeType);
+ params.put(TransportConstants.KEYSTORE_PROVIDER_PROP_NAME, storeType);
+ params.put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true);
+ ConfigurationImpl config = createBasicConfig().addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params, "nettySSL"));
+ server = createServer(false, config);
+ server.start();
+ waitForServerToStart(server);
+ tc = new TransportConfiguration(NETTY_CONNECTOR_FACTORY);
+ }
+}
diff --git a/tests/unit-tests/src/test/resources/openssl-client-side-keystore.jceks b/tests/unit-tests/src/test/resources/openssl-client-side-keystore.jceks
new file mode 100644
index 0000000000..787213710c
Binary files /dev/null and b/tests/unit-tests/src/test/resources/openssl-client-side-keystore.jceks differ
diff --git a/tests/unit-tests/src/test/resources/openssl-client-side-keystore.jks b/tests/unit-tests/src/test/resources/openssl-client-side-keystore.jks
new file mode 100644
index 0000000000..fd644568e3
Binary files /dev/null and b/tests/unit-tests/src/test/resources/openssl-client-side-keystore.jks differ
diff --git a/tests/unit-tests/src/test/resources/openssl-client-side-truststore.jceks b/tests/unit-tests/src/test/resources/openssl-client-side-truststore.jceks
new file mode 100644
index 0000000000..9881cebdbb
Binary files /dev/null and b/tests/unit-tests/src/test/resources/openssl-client-side-truststore.jceks differ
diff --git a/tests/unit-tests/src/test/resources/openssl-client-side-truststore.jks b/tests/unit-tests/src/test/resources/openssl-client-side-truststore.jks
new file mode 100644
index 0000000000..3ef44dc4bc
Binary files /dev/null and b/tests/unit-tests/src/test/resources/openssl-client-side-truststore.jks differ
diff --git a/tests/unit-tests/src/test/resources/openssl-server-side-keystore.jceks b/tests/unit-tests/src/test/resources/openssl-server-side-keystore.jceks
new file mode 100644
index 0000000000..d54310159c
Binary files /dev/null and b/tests/unit-tests/src/test/resources/openssl-server-side-keystore.jceks differ
diff --git a/tests/unit-tests/src/test/resources/openssl-server-side-keystore.jks b/tests/unit-tests/src/test/resources/openssl-server-side-keystore.jks
new file mode 100644
index 0000000000..0a26208761
Binary files /dev/null and b/tests/unit-tests/src/test/resources/openssl-server-side-keystore.jks differ
diff --git a/tests/unit-tests/src/test/resources/openssl-server-side-truststore.jceks b/tests/unit-tests/src/test/resources/openssl-server-side-truststore.jceks
new file mode 100644
index 0000000000..9ebd0c75bc
Binary files /dev/null and b/tests/unit-tests/src/test/resources/openssl-server-side-truststore.jceks differ
diff --git a/tests/unit-tests/src/test/resources/openssl-server-side-truststore.jks b/tests/unit-tests/src/test/resources/openssl-server-side-truststore.jks
new file mode 100644
index 0000000000..89217a3815
Binary files /dev/null and b/tests/unit-tests/src/test/resources/openssl-server-side-truststore.jks differ
diff --git a/tests/unit-tests/src/test/resources/verified-openssl-client-side-keystore.jceks b/tests/unit-tests/src/test/resources/verified-openssl-client-side-keystore.jceks
new file mode 100644
index 0000000000..fc8c4cc4d1
Binary files /dev/null and b/tests/unit-tests/src/test/resources/verified-openssl-client-side-keystore.jceks differ
diff --git a/tests/unit-tests/src/test/resources/verified-openssl-client-side-keystore.jks b/tests/unit-tests/src/test/resources/verified-openssl-client-side-keystore.jks
new file mode 100644
index 0000000000..d60a9e7bab
Binary files /dev/null and b/tests/unit-tests/src/test/resources/verified-openssl-client-side-keystore.jks differ
diff --git a/tests/unit-tests/src/test/resources/verified-openssl-server-side-truststore.jceks b/tests/unit-tests/src/test/resources/verified-openssl-server-side-truststore.jceks
new file mode 100644
index 0000000000..c91e3f2e5a
Binary files /dev/null and b/tests/unit-tests/src/test/resources/verified-openssl-server-side-truststore.jceks differ
diff --git a/tests/unit-tests/src/test/resources/verified-openssl-server-side-truststore.jks b/tests/unit-tests/src/test/resources/verified-openssl-server-side-truststore.jks
new file mode 100644
index 0000000000..22fda4bb41
Binary files /dev/null and b/tests/unit-tests/src/test/resources/verified-openssl-server-side-truststore.jks differ