You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by jb...@apache.org on 2018/02/05 20:44:03 UTC
[2/2] activemq-artemis git commit: ARTEMIS-1649 - enable openssl
provider for Netty
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 <ri...@kiwigrid.com>
Authored: Mon Feb 5 10:23:18 2018 +0100
Committer: Justin Bertram <jb...@apache.org>
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