[1/2] activemq-artemis git commit: This closes #1834

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[1/2] activemq-artemis git commit: This closes #1834

jbertram
Repository: activemq-artemis
Updated Branches:
  refs/heads/master 9553de82b -> 9c40a514f


This closes #1834


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/9c40a514
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/9c40a514
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/9c40a514

Branch: refs/heads/master
Commit: 9c40a514f26c28b591516fa89f761740f1bc29dd
Parents: 9553de8 6501c3d
Author: Justin Bertram <[hidden email]>
Authored: Mon Feb 5 14:42:04 2018 -0600
Committer: Justin Bertram <[hidden email]>
Committed: Mon Feb 5 14:42:04 2018 -0600

----------------------------------------------------------------------
 .../remoting/impl/netty/NettyConnector.java     | 175 +++++++++++--------
 .../remoting/impl/netty/TransportConstants.java |   8 +
 .../core/remoting/impl/ssl/SSLSupport.java      |  80 ++++++---
 .../core/remoting/impl/netty/NettyAcceptor.java | 106 +++++++----
 docs/user-manual/en/configuring-transports.md   |  10 ++
 5 files changed, 252 insertions(+), 127 deletions(-)
----------------------------------------------------------------------


Reply | Threaded
Open this post in threaded view
|

[2/2] activemq-artemis git commit: ARTEMIS-1649 - enable openssl provider for Netty

jbertram
ARTEMIS-1649 - enable openssl provider for Netty


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/6501c3de
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/6501c3de
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/6501c3de

Branch: refs/heads/master
Commit: 6501c3de1fc8d440923b241f95a4f7f0ead6a7c3
Parents: 9553de8
Author: rico.pahlisch <[hidden email]>
Authored: Mon Feb 5 10:23:18 2018 +0100
Committer: Justin Bertram <[hidden email]>
Committed: Mon Feb 5 14:42:04 2018 -0600

----------------------------------------------------------------------
 .../remoting/impl/netty/NettyConnector.java     | 175 +++++++++++--------
 .../remoting/impl/netty/TransportConstants.java |   8 +
 .../core/remoting/impl/ssl/SSLSupport.java      |  80 ++++++---
 .../core/remoting/impl/netty/NettyAcceptor.java | 106 +++++++----
 docs/user-manual/en/configuring-transports.md   |  10 ++
 5 files changed, 252 insertions(+), 127 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6501c3de/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
----------------------------------------------------------------------
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 5874820..99d8447 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
@@ -33,6 +33,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CountDownLatch;
@@ -40,6 +41,7 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
@@ -49,6 +51,7 @@ import javax.security.auth.login.LoginContext;
 
 import io.netty.bootstrap.Bootstrap;
 import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelDuplexHandler;
@@ -90,13 +93,13 @@ import io.netty.handler.codec.http.HttpVersion;
 import io.netty.handler.codec.http.LastHttpContent;
 import io.netty.handler.codec.http.cookie.ClientCookieDecoder;
 import io.netty.handler.codec.http.cookie.Cookie;
+import io.netty.handler.ssl.SslContext;
 import io.netty.handler.ssl.SslHandler;
 import io.netty.util.AttributeKey;
 import io.netty.util.ResourceLeakDetector;
 import io.netty.util.ResourceLeakDetector.Level;
 import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.GlobalEventExecutor;
-
 import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
 import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.core.client.ActiveMQClientLogger;
@@ -216,6 +219,8 @@ public class NettyConnector extends AbstractConnector {
 
    private String enabledProtocols;
 
+   private String sslProvider;
+
    private boolean verifyHost;
 
    private boolean trustAll;
@@ -354,6 +359,8 @@ public class NettyConnector extends AbstractConnector {
 
          trustAll = ConfigurationHelper.getBooleanProperty(TransportConstants.TRUST_ALL_PROP_NAME, TransportConstants.DEFAULT_TRUST_ALL, configuration);
 
+         sslProvider = ConfigurationHelper.getStringProperty(TransportConstants.SSL_PROVIDER, TransportConstants.DEFAULT_SSL_PROVIDER, configuration);
+
          sniHost = ConfigurationHelper.getStringProperty(TransportConstants.SNIHOST_PROP_NAME, TransportConstants.DEFAULT_SNIHOST_CONFIG, configuration);
 
          kerb5Config = ConfigurationHelper.getStringProperty(TransportConstants.SSL_KRB5_CONFIG_PROP_NAME, TransportConstants.DEFAULT_SSL_KRB5_CONFIG, configuration);
@@ -484,67 +491,30 @@ public class NettyConnector extends AbstractConnector {
       bootstrap.option(ChannelOption.SO_REUSEADDR, true);
       channelGroup = new DefaultChannelGroup("activemq-connector", GlobalEventExecutor.INSTANCE);
 
-      final SSLContext context;
-      if (sslEnabled) {
-         try {
-            if (useDefaultSslContext) {
-               context = SSLContext.getDefault();
-            } else {
-               // HORNETQ-680 - override the server-side config if client-side system properties are set
-               String realKeyStorePath = keyStorePath;
-               String realKeyStoreProvider = keyStoreProvider;
-               String realKeyStorePassword = keyStorePassword;
-               if (System.getProperty(JAVAX_KEYSTORE_PATH_PROP_NAME) != null) {
-                  realKeyStorePath = System.getProperty(JAVAX_KEYSTORE_PATH_PROP_NAME);
-               }
-               if (System.getProperty(JAVAX_KEYSTORE_PASSWORD_PROP_NAME) != null) {
-                  realKeyStorePassword = System.getProperty(JAVAX_KEYSTORE_PASSWORD_PROP_NAME);
-               }
+      final String realKeyStorePath;
+      final String realKeyStoreProvider;
+      final String realKeyStorePassword;
+      final String realTrustStorePath;
+      final String realTrustStoreProvider;
+      final String realTrustStorePassword;
 
-               if (System.getProperty(ACTIVEMQ_KEYSTORE_PROVIDER_PROP_NAME) != null) {
-                  realKeyStoreProvider = System.getProperty(ACTIVEMQ_KEYSTORE_PROVIDER_PROP_NAME);
-               }
-               if (System.getProperty(ACTIVEMQ_KEYSTORE_PATH_PROP_NAME) != null) {
-                  realKeyStorePath = System.getProperty(ACTIVEMQ_KEYSTORE_PATH_PROP_NAME);
-               }
-               if (System.getProperty(ACTIVEMQ_KEYSTORE_PASSWORD_PROP_NAME) != null) {
-                  realKeyStorePassword = System.getProperty(ACTIVEMQ_KEYSTORE_PASSWORD_PROP_NAME);
-               }
+      if (sslEnabled) {
+         // HORNETQ-680 - override the server-side config if client-side system properties are set
 
-               String realTrustStorePath = trustStorePath;
-               String realTrustStoreProvider = trustStoreProvider;
-               String realTrustStorePassword = trustStorePassword;
-               if (System.getProperty(JAVAX_TRUSTSTORE_PATH_PROP_NAME) != null) {
-                  realTrustStorePath = System.getProperty(JAVAX_TRUSTSTORE_PATH_PROP_NAME);
-               }
-               if (System.getProperty(JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME) != null) {
-                  realTrustStorePassword = System.getProperty(JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME);
-               }
+         realKeyStorePath = Stream.of(System.getProperty(JAVAX_KEYSTORE_PATH_PROP_NAME), System.getProperty(ACTIVEMQ_KEYSTORE_PATH_PROP_NAME), keyStorePath).map(v -> useDefaultSslContext ? keyStorePath : v).filter(Objects::nonNull).findFirst().orElse(null);
+         realKeyStorePassword = Stream.of(System.getProperty(JAVAX_KEYSTORE_PASSWORD_PROP_NAME), System.getProperty(ACTIVEMQ_KEYSTORE_PASSWORD_PROP_NAME), keyStorePassword).map(v -> useDefaultSslContext ? keyStorePassword : v).filter(Objects::nonNull).findFirst().orElse(null);
+         realKeyStoreProvider = Stream.of(System.getProperty(ACTIVEMQ_KEYSTORE_PROVIDER_PROP_NAME), keyStoreProvider).map(v -> useDefaultSslContext ? keyStoreProvider : v).filter(Objects::nonNull).findFirst().orElse(null);
 
-               if (System.getProperty(ACTIVEMQ_TRUSTSTORE_PROVIDER_PROP_NAME) != null) {
-                  realTrustStoreProvider = System.getProperty(ACTIVEMQ_TRUSTSTORE_PROVIDER_PROP_NAME);
-               }
-               if (System.getProperty(ACTIVEMQ_TRUSTSTORE_PATH_PROP_NAME) != null) {
-                  realTrustStorePath = System.getProperty(ACTIVEMQ_TRUSTSTORE_PATH_PROP_NAME);
-               }
-               if (System.getProperty(ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME) != null) {
-                  realTrustStorePassword = System.getProperty(ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME);
-               }
-               context = SSLSupport.createContext(realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword, trustAll, crlPath);
-            }
-         } catch (Exception e) {
-            close();
-            IllegalStateException ise = new IllegalStateException("Unable to create NettyConnector for " + host + ":" + port);
-            ise.initCause(e);
-            throw ise;
-         }
+         realTrustStorePath = Stream.of(System.getProperty(JAVAX_TRUSTSTORE_PATH_PROP_NAME), System.getProperty(ACTIVEMQ_TRUSTSTORE_PATH_PROP_NAME), trustStorePath).map(v -> useDefaultSslContext ? trustStorePath : v).filter(Objects::nonNull).findFirst().orElse(null);
+         realTrustStorePassword = Stream.of(System.getProperty(JAVAX_TRUSTSTORE_PASSWORD_PROP_NAME), System.getProperty(ACTIVEMQ_TRUSTSTORE_PASSWORD_PROP_NAME), trustStorePassword).map(v -> useDefaultSslContext ? trustStorePassword : v).filter(Objects::nonNull).findFirst().orElse(null);
+         realTrustStoreProvider = Stream.of(System.getProperty(ACTIVEMQ_TRUSTSTORE_PROVIDER_PROP_NAME), trustStoreProvider).map(v -> useDefaultSslContext ? trustStoreProvider : v).filter(Objects::nonNull).findFirst().orElse(null);
       } else {
-         context = null; // Unused
-      }
-
-      if (context != null && useServlet) {
-         // TODO: Fix me
-         //bootstrap.setOption("sslContext", context);
+         realKeyStorePath = null;
+         realKeyStoreProvider = null;
+         realKeyStorePassword = null;
+         realTrustStorePath = null;
+         realTrustStoreProvider = null;
+         realTrustStorePassword = null;
       }
 
       bootstrap.handler(new ChannelInitializer<Channel>() {
@@ -553,25 +523,13 @@ public class NettyConnector extends AbstractConnector {
             final ChannelPipeline pipeline = channel.pipeline();
             if (sslEnabled && !useServlet) {
 
-               Subject subject = null;
-               if (kerb5Config != null) {
-                  LoginContext loginContext = new LoginContext(kerb5Config);
-                  loginContext.login();
-                  subject = loginContext.getSubject();
-                  verifyHost = true;
+               SSLEngine engine;
+               if (sslProvider.equals(TransportConstants.OPENSSL_PROVIDER)) {
+                  engine = loadOpenSslEngine(channel.alloc(), realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword);
+               } else {
+                  engine = loadJdkSslEngine(useDefaultSslContext, realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword);
                }
 
-               SSLEngine engine = Subject.doAs(subject, new PrivilegedExceptionAction<SSLEngine>() {
-                  @Override
-                  public SSLEngine run() {
-                     if (verifyHost) {
-                        return context.createSSLEngine(sniHost != null ? sniHost : host, port);
-                     } else {
-                        return context.createSSLEngine();
-                     }
-                  }
-               });
-
                engine.setUseClientMode(true);
 
                engine.setWantClientAuth(true);
@@ -640,7 +598,72 @@ public class NettyConnector extends AbstractConnector {
 
          batchFlusherFuture = scheduledThreadPool.scheduleWithFixedDelay(flusher, batchDelay, batchDelay, TimeUnit.MILLISECONDS);
       }
-      ActiveMQClientLogger.LOGGER.startedNettyConnector(connectorType,  TransportConstants.NETTY_VERSION, host, port);
+      ActiveMQClientLogger.LOGGER.startedNettyConnector(connectorType, TransportConstants.NETTY_VERSION, host, port);
+   }
+
+   private SSLEngine loadJdkSslEngine(boolean useDefaultSslContext,
+                                      String realKeyStoreProvider,
+                                      String realKeyStorePath,
+                                      String realKeyStorePassword,
+                                      String realTrustStoreProvider,
+                                      String realTrustStorePath,
+                                      String realTrustStorePassword) throws Exception {
+      SSLContext context;
+      if (useDefaultSslContext) {
+         context = SSLContext.getDefault();
+      } else {
+         context = SSLSupport.createContext(realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword, trustAll, crlPath);
+      }
+      Subject subject = null;
+      if (kerb5Config != null) {
+         LoginContext loginContext = new LoginContext(kerb5Config);
+         loginContext.login();
+         subject = loginContext.getSubject();
+         verifyHost = true;
+      }
+
+      SSLEngine engine = Subject.doAs(subject, new PrivilegedExceptionAction<SSLEngine>() {
+         @Override
+         public SSLEngine run() {
+            if (verifyHost) {
+               return context.createSSLEngine(host, port);
+            } else {
+               return context.createSSLEngine();
+            }
+         }
+      });
+      return engine;
+   }
+
+   private SSLEngine loadOpenSslEngine(ByteBufAllocator alloc,
+                                       String realKeyStoreProvider,
+                                       String realKeyStorePath,
+                                       String realKeyStorePassword,
+                                       String realTrustStoreProvider,
+                                       String realTrustStorePath,
+                                       String realTrustStorePassword) throws Exception {
+
+      SslContext context = SSLSupport.createNettyContext(realKeyStoreProvider, realKeyStorePath, realKeyStorePassword, realTrustStoreProvider, realTrustStorePath, realTrustStorePassword, sslProvider);
+
+      Subject subject = null;
+      if (kerb5Config != null) {
+         LoginContext loginContext = new LoginContext(kerb5Config);
+         loginContext.login();
+         subject = loginContext.getSubject();
+         verifyHost = true;
+      }
+
+      SSLEngine engine = Subject.doAs(subject, new PrivilegedExceptionAction<SSLEngine>() {
+         @Override
+         public SSLEngine run() {
+            if (verifyHost) {
+               return context.newEngine(alloc, sniHost != null ? sniHost : host, port);
+            } else {
+               return context.newEngine(alloc);
+            }
+         }
+      });
+      return engine;
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6501c3de/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
index 81efb31..d8a8854 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
@@ -113,6 +113,8 @@ public class TransportConstants {
 
    public static final String USE_DEFAULT_SSL_CONTEXT_PROP_NAME = "useDefaultSslContext";
 
+   public static final String SSL_PROVIDER = "sslProvider";
+
    public static final String NETTY_VERSION;
 
    /**
@@ -201,6 +203,10 @@ public class TransportConstants {
 
    public static final boolean DEFAULT_VERIFY_HOST = false;
 
+   public static final String DEFAULT_SSL_PROVIDER = "JDK";
+
+   public static final String OPENSSL_PROVIDER = "OPENSSL";
+
    public static final boolean DEFAULT_TRUST_ALL = false;
 
    public static final boolean DEFAULT_USE_DEFAULT_SSL_CONTEXT = false;
@@ -316,6 +322,7 @@ public class TransportConstants {
       allowableAcceptorKeys.add(TransportConstants.BACKLOG_PROP_NAME);
       allowableAcceptorKeys.add(TransportConstants.CRL_PATH_PROP_NAME);
       allowableAcceptorKeys.add(TransportConstants.HANDSHAKE_TIMEOUT);
+      allowableAcceptorKeys.add(TransportConstants.SSL_PROVIDER);
 
       ALLOWABLE_ACCEPTOR_KEYS = Collections.unmodifiableSet(allowableAcceptorKeys);
 
@@ -361,6 +368,7 @@ public class TransportConstants {
       allowableConnectorKeys.add(ActiveMQDefaultConfiguration.getPropPasswordCodec());
       allowableConnectorKeys.add(TransportConstants.NETTY_CONNECT_TIMEOUT);
       allowableConnectorKeys.add(TransportConstants.USE_DEFAULT_SSL_CONTEXT_PROP_NAME);
+      allowableConnectorKeys.add(TransportConstants.SSL_PROVIDER);
       allowableConnectorKeys.add(TransportConstants.HANDSHAKE_TIMEOUT);
       allowableConnectorKeys.add(TransportConstants.CRL_PATH_PROP_NAME);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6501c3de/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
----------------------------------------------------------------------
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 03b6e08..297b294 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
@@ -16,14 +16,6 @@
  */
 package org.apache.activemq.artemis.core.remoting.impl.ssl;
 
-import java.security.Security;
-import java.security.cert.CRL;
-import java.security.cert.CertStore;
-import java.security.cert.CertificateFactory;
-import java.security.cert.CollectionCertStoreParameters;
-import java.security.cert.PKIXBuilderParameters;
-import java.security.cert.X509CertSelector;
-import java.util.Collection;
 import javax.net.ssl.CertPathTrustManagerParameters;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
@@ -37,12 +29,24 @@ 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 org.apache.activemq.artemis.utils.ClassloadingUtil;
+import java.security.Security;
+import java.security.cert.CRL;
+import java.security.cert.CertStore;
+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;
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.SslProvider;
 import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-
+import org.apache.activemq.artemis.utils.ClassloadingUtil;
 
 /**
  * Please note, this class supports PKCS#11 keystores, but there are no specific tests in the ActiveMQ Artemis test-suite to
@@ -99,6 +103,21 @@ public class SSLSupport {
       return context;
    }
 
+   public static SslContext createNettyContext(final String keystoreProvider,
+                                               final String keystorePath,
+                                               final String keystorePassword,
+                                               final String trustStoreProvider,
+                                               final String trustStorePath,
+                                               final String trustStorePassword,
+                                               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();
+   }
+
    public static String[] parseCommaSeparatedListIntoArray(String suites) {
       String[] cipherSuites = suites.split(",");
       for (int i = 0; i < cipherSuites.length; i++) {
@@ -120,15 +139,14 @@ public class SSLSupport {
    }
 
    // Private -------------------------------------------------------
-
-   private static TrustManager[] loadTrustManager(final String trustStoreProvider,
-                                                  final String trustStorePath,
-                                                  final String trustStorePassword,
-                                                  final boolean trustAll,
-                                                  final String crlPath) throws Exception {
+   private static TrustManagerFactory loadTrustManagerFactory(final String trustStoreProvider,
+                                                              final String trustStorePath,
+                                                              final String trustStorePassword,
+                                                              final boolean trustAll,
+                                                              final String crlPath) throws Exception {
       if (trustAll) {
          //This is useful for testing but not should be used outside of that purpose
-         return InsecureTrustManagerFactory.INSTANCE.getTrustManagers();
+         return InsecureTrustManagerFactory.INSTANCE;
       } else if (trustStorePath == null && (trustStoreProvider == null || !"PKCS11".equals(trustStoreProvider.toUpperCase()))) {
          return null;
       } else {
@@ -153,10 +171,20 @@ public class SSLSupport {
          if (!initialized) {
             trustMgrFactory.init(trustStore);
          }
+         return trustMgrFactory;
+      }
+   }
 
-         return trustMgrFactory.getTrustManagers();
-
+   private static TrustManager[] loadTrustManager(final String trustStoreProvider,
+                                                  final String trustStorePath,
+                                                  final String trustStorePassword,
+                                                  final boolean trustAll,
+                                                  final String crlPath) throws Exception {
+      TrustManagerFactory trustManagerFactory = loadTrustManagerFactory(trustStoreProvider, trustStorePath, trustStorePassword, trustAll, crlPath);
+      if (trustManagerFactory == null) {
+         return null;
       }
+      return trustManagerFactory.getTrustManagers();
    }
 
    private static Collection<? extends CRL> loadCRL(String crlPath) throws Exception {
@@ -196,14 +224,24 @@ public class SSLSupport {
    private static KeyManager[] loadKeyManagers(final String keyStoreProvider,
                                                final String keystorePath,
                                                final String keystorePassword) throws Exception {
+
+      KeyManagerFactory factory = loadKeyManagerFactory(keyStoreProvider, keystorePath, keystorePassword);
+      if (factory == null) {
+         return null;
+      }
+      return factory.getKeyManagers();
+   }
+
+   private static KeyManagerFactory loadKeyManagerFactory(final String keyStoreProvider,
+                                                          final String keystorePath,
+                                                          final String keystorePassword) throws Exception {
       if (keystorePath == null && (keyStoreProvider == null || !"PKCS11".equals(keyStoreProvider.toUpperCase()))) {
          return null;
       } else {
          KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
          KeyStore ks = SSLSupport.loadKeystore(keyStoreProvider, keystorePath, keystorePassword);
          kmf.init(ks, keystorePassword == null ? null : keystorePassword.toCharArray());
-
-         return kmf.getKeyManagers();
+         return kmf;
       }
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6501c3de/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
index 52c5b7e..f6424e3 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
@@ -40,6 +40,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import io.netty.bootstrap.ServerBootstrap;
+import io.netty.buffer.ByteBufAllocator;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
@@ -63,6 +64,7 @@ import io.netty.channel.local.LocalAddress;
 import io.netty.channel.local.LocalServerChannel;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.ssl.SslContext;
 import io.netty.handler.ssl.SslHandler;
 import io.netty.util.ResourceLeakDetector;
 import io.netty.util.concurrent.GenericFutureListener;
@@ -164,6 +166,8 @@ public class NettyAcceptor extends AbstractAcceptor {
 
    private final boolean needClientAuth;
 
+   private final String sslProvider;
+
    private final boolean verifyHost;
 
    private final String kerb5Config;
@@ -270,6 +274,8 @@ public class NettyAcceptor extends AbstractAcceptor {
          needClientAuth = ConfigurationHelper.getBooleanProperty(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, TransportConstants.DEFAULT_NEED_CLIENT_AUTH, configuration);
 
          verifyHost = ConfigurationHelper.getBooleanProperty(TransportConstants.VERIFY_HOST_PROP_NAME, TransportConstants.DEFAULT_VERIFY_HOST, configuration);
+
+         sslProvider = ConfigurationHelper.getStringProperty(TransportConstants.SSL_PROVIDER, TransportConstants.DEFAULT_SSL_PROVIDER, configuration);
       } else {
          keyStoreProvider = TransportConstants.DEFAULT_KEYSTORE_PROVIDER;
          keyStorePath = TransportConstants.DEFAULT_KEYSTORE_PATH;
@@ -282,6 +288,7 @@ public class NettyAcceptor extends AbstractAcceptor {
          enabledProtocols = TransportConstants.DEFAULT_ENABLED_PROTOCOLS;
          needClientAuth = TransportConstants.DEFAULT_NEED_CLIENT_AUTH;
          verifyHost = TransportConstants.DEFAULT_VERIFY_HOST;
+         sslProvider = TransportConstants.DEFAULT_SSL_PROVIDER;
       }
 
       tcpNoDelay = ConfigurationHelper.getBooleanProperty(TransportConstants.TCP_NODELAY_PROPNAME, TransportConstants.DEFAULT_TCP_NODELAY, configuration);
@@ -364,7 +371,7 @@ public class NettyAcceptor extends AbstractAcceptor {
          public void initChannel(Channel channel) throws Exception {
             ChannelPipeline pipeline = channel.pipeline();
             if (sslEnabled) {
-               pipeline.addLast("ssl", getSslHandler());
+               pipeline.addLast("ssl", getSslHandler(channel.alloc()));
                pipeline.addLast("sslHandshakeExceptionHandler", new SslHandshakeExceptionHandler());
             }
             pipeline.addLast(protocolHandler.getProtocolDecoder());
@@ -451,37 +458,14 @@ public class NettyAcceptor extends AbstractAcceptor {
       startServerChannels();
    }
 
-   public synchronized SslHandler getSslHandler() throws Exception {
-      final SSLContext context;
-      try {
-         if (kerb5Config == null && keyStorePath == null && TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER.equals(keyStoreProvider))
-            throw new IllegalArgumentException("If \"" + TransportConstants.SSL_ENABLED_PROP_NAME +
-                                                  "\" is true then \"" + TransportConstants.KEYSTORE_PATH_PROP_NAME + "\" must be non-null " +
-                                                  "unless an alternative \"" + TransportConstants.KEYSTORE_PROVIDER_PROP_NAME + "\" has been specified.");
-         context = SSLSupport.createContext(keyStoreProvider, keyStorePath, keyStorePassword, trustStoreProvider, trustStorePath, trustStorePassword, crlPath);
-      } catch (Exception e) {
-         IllegalStateException ise = new IllegalStateException("Unable to create NettyAcceptor for " + host + ":" + port);
-         ise.initCause(e);
-         throw ise;
-      }
-      Subject subject = null;
-      if (kerb5Config != null) {
-         LoginContext loginContext = new LoginContext(kerb5Config);
-         loginContext.login();
-         subject = loginContext.getSubject();
+   public synchronized SslHandler getSslHandler(ByteBufAllocator alloc) throws Exception {
+      SSLEngine engine;
+      if (sslProvider.equals(TransportConstants.OPENSSL_PROVIDER)) {
+         engine = loadOpenSslEngine(alloc);
+      } else {
+         engine = loadJdkSslEngine();
       }
 
-      SSLEngine engine = Subject.doAs(subject, new PrivilegedExceptionAction<SSLEngine>() {
-         @Override
-         public SSLEngine run() {
-            if (verifyHost) {
-               return context.createSSLEngine(host, port);
-            } else {
-               return context.createSSLEngine();
-            }
-         }
-      });
-
       engine.setUseClientMode(false);
 
       if (needClientAuth)
@@ -539,6 +523,68 @@ public class NettyAcceptor extends AbstractAcceptor {
       return new SslHandler(engine);
    }
 
+   private SSLEngine loadJdkSslEngine() throws Exception {
+      final SSLContext context;
+      try {
+         if (kerb5Config == null && keyStorePath == null && TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER.equals(keyStoreProvider))
+            throw new IllegalArgumentException("If \"" + TransportConstants.SSL_ENABLED_PROP_NAME + "\" is true then \"" + TransportConstants.KEYSTORE_PATH_PROP_NAME + "\" must be non-null " + "unless an alternative \"" + TransportConstants.KEYSTORE_PROVIDER_PROP_NAME + "\" has been specified.");
+         context = SSLSupport.createContext(keyStoreProvider, keyStorePath, keyStorePassword, trustStoreProvider, trustStorePath, trustStorePassword, crlPath);
+      } catch (Exception e) {
+         IllegalStateException ise = new IllegalStateException("Unable to create NettyAcceptor for " + host + ":" + port);
+         ise.initCause(e);
+         throw ise;
+      }
+      Subject subject = null;
+      if (kerb5Config != null) {
+         LoginContext loginContext = new LoginContext(kerb5Config);
+         loginContext.login();
+         subject = loginContext.getSubject();
+      }
+
+      SSLEngine engine = Subject.doAs(subject, new PrivilegedExceptionAction<SSLEngine>() {
+         @Override
+         public SSLEngine run() {
+            if (verifyHost) {
+               return context.createSSLEngine(host, port);
+            } else {
+               return context.createSSLEngine();
+            }
+         }
+      });
+      return engine;
+   }
+
+   private SSLEngine loadOpenSslEngine(ByteBufAllocator alloc) throws Exception {
+      final SslContext context;
+      try {
+         if (kerb5Config == null && keyStorePath == null && TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER.equals(keyStoreProvider))
+            throw new IllegalArgumentException("If \"" + TransportConstants.SSL_ENABLED_PROP_NAME + "\" is true then \"" + TransportConstants.KEYSTORE_PATH_PROP_NAME + "\" must be non-null " + "unless an alternative \"" + TransportConstants.KEYSTORE_PROVIDER_PROP_NAME + "\" has been specified.");
+         context = SSLSupport.createNettyContext(keyStoreProvider, keyStorePath, keyStorePassword, trustStoreProvider, trustStorePath, trustStorePassword, sslProvider);
+      } catch (Exception e) {
+         IllegalStateException ise = new IllegalStateException("Unable to create NettyAcceptor for " + host + ":" + port);
+         ise.initCause(e);
+         throw ise;
+      }
+      Subject subject = null;
+      if (kerb5Config != null) {
+         LoginContext loginContext = new LoginContext(kerb5Config);
+         loginContext.login();
+         subject = loginContext.getSubject();
+      }
+
+      SSLEngine engine = Subject.doAs(subject, new PrivilegedExceptionAction<SSLEngine>() {
+         @Override
+         public SSLEngine run() {
+            if (verifyHost) {
+               return context.newEngine(alloc, host, port);
+            } else {
+               return context.newEngine(alloc);
+            }
+         }
+      });
+      return engine;
+   }
+
    private void startServerChannels() {
       String[] hosts = TransportConfiguration.splitHosts(host);
       for (String h : hosts) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6501c3de/docs/user-manual/en/configuring-transports.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/configuring-transports.md b/docs/user-manual/en/configuring-transports.md
index 566f69f..5f83627 100644
--- a/docs/user-manual/en/configuring-transports.md
+++ b/docs/user-manual/en/configuring-transports.md
@@ -433,6 +433,16 @@ following additional properties:
 
     Valid values are `true` or `false`. Default is `false`.
 
+-   `sslProvider`
+    
+    Used to change the SSL Provider between `JDK` and `OPENSSL`. The default is `JDK`.
+    If used with `OPENSSL` you can add `netty-tcnative` to your classpath to use the native
+    installed openssl. This can be useful if you want to use special ciphersuite - elliptic curve combinations
+    which are support through openssl but not through the JDK provider. See https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations
+    for more information's.
+    
+    
+    
 ## Configuring Netty HTTP
 
 Netty HTTP tunnels packets over the HTTP protocol. It can be useful in