ARTEMIS-1649 - enable openssl provider for Netty

This commit is contained in:
rico.pahlisch 2018-02-05 10:23:18 +01:00 committed by Justin Bertram
parent 9553de82bb
commit 6501c3de1f
5 changed files with 253 additions and 128 deletions

View File

@ -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;
final String realKeyStorePath;
final String realKeyStoreProvider;
final String realKeyStorePassword;
final String realTrustStorePath;
final String realTrustStoreProvider;
final String realTrustStorePassword;
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);
}
// HORNETQ-680 - override the server-side config if client-side system properties are set
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);
}
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);
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);
}
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

View File

@ -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);

View File

@ -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,12 +171,22 @@ public class SSLSupport {
if (!initialized) {
trustMgrFactory.init(trustStore);
}
return trustMgrFactory.getTrustManagers();
return trustMgrFactory;
}
}
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 {
if (crlPath == null) {
return null;
@ -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;
}
}

View File

@ -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,36 +458,13 @@ 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;
public synchronized SslHandler getSslHandler(ByteBufAllocator alloc) throws Exception {
SSLEngine engine;
if (sslProvider.equals(TransportConstants.OPENSSL_PROVIDER)) {
engine = loadOpenSslEngine(alloc);
} else {
engine = loadJdkSslEngine();
}
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();
}
}
});
engine.setUseClientMode(false);
@ -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) {

View File

@ -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