diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java index 6dc0457e4145c912eab6377ba4095824c24d0f2d..a1008a3f91bdf1547cb40ba0b56d4855596c97f1 100644 --- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java +++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingClient.java @@ -34,6 +34,7 @@ import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.concurrent.DefaultEventExecutorGroup; +import java.io.IOException; import java.net.SocketAddress; import java.security.cert.CertificateException; import java.util.Collections; @@ -52,7 +53,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import javax.net.ssl.SSLException; import org.apache.rocketmq.remoting.ChannelEventListener; import org.apache.rocketmq.remoting.InvokeCallback; import org.apache.rocketmq.remoting.RPCHook; @@ -133,7 +133,7 @@ public class NettyRemotingClient extends NettyRemotingAbstract implements Remoti try { sslContext = SslHelper.buildSslContext(true); log.info("SSL enabled for client"); - } catch (SSLException e) { + } catch (IOException e) { log.error("Failed to create SSLContext", e); } catch (CertificateException e) { log.error("Failed to create SSLContext", e); diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java index ec1927a699f4406c07a765c5656a6231e0551827..35894a0cc88f935364d8098a64eb76f382eab7e0 100644 --- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java +++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java @@ -37,6 +37,7 @@ import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.concurrent.DefaultEventExecutorGroup; +import java.io.IOException; import java.net.InetSocketAddress; import java.security.cert.CertificateException; import java.util.NoSuchElementException; @@ -46,7 +47,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; -import javax.net.ssl.SSLException; import org.apache.rocketmq.remoting.ChannelEventListener; import org.apache.rocketmq.remoting.InvokeCallback; import org.apache.rocketmq.remoting.RPCHook; @@ -148,7 +148,7 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti log.info("SSLContext created for server"); } catch (CertificateException e) { log.error("Failed to create SSLContext for server", e); - } catch (SSLException e) { + } catch (IOException e) { log.error("Failed to create SSLContext for server", e); } } diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/SslHelper.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/SslHelper.java index ebadd9682525bcb897a8b2f8fd243b6833d608c9..4bf3b52e1224641632e628f114917184d3b140d2 100644 --- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/SslHelper.java +++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/SslHelper.java @@ -31,16 +31,40 @@ import java.io.IOException; import java.io.InputStream; import java.security.cert.CertificateException; import java.util.Properties; -import javax.net.ssl.SSLException; import org.apache.rocketmq.remoting.common.RemotingHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SslHelper { + public interface DecryptionStrategy { + /** + * Decrypt the target encrpted private key file. + * + * @param privateKeyEncryptPath A pathname string + * @param forClient tells whether it's a client-side key file + * @return An input stream for a decrypted key file + * @throws IOException if an I/O error has occurred + */ + InputStream decryptPrivateKey(String privateKeyEncryptPath, boolean forClient) throws IOException; + } + private static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.ROCKETMQ_REMOTING); - public static SslContext buildSslContext(boolean forClient) throws SSLException, CertificateException { + private static DecryptionStrategy decryptionStrategy = new DecryptionStrategy() { + @Override + public InputStream decryptPrivateKey(final String privateKeyEncryptPath, + final boolean forClient) throws IOException { + return new FileInputStream(privateKeyEncryptPath); + } + }; + + + public static void registerDecryptionStrategy(final DecryptionStrategy decryptionStrategy) { + SslHelper.decryptionStrategy = decryptionStrategy; + } + + public static SslContext buildSslContext(boolean forClient) throws IOException, CertificateException { File configFile = new File(NettySystemConfig.sslConfigFile); boolean testMode = !(configFile.exists() && configFile.isFile() && configFile.canRead()); @@ -92,8 +116,8 @@ public class SslHelper { } return sslContextBuilder.keyManager( - properties.containsKey("client.keyCertChainFile") ? new File(properties.getProperty("client.keyCertChainFile")) : null, - properties.containsKey("client.keyFile") ? new File(properties.getProperty("client.keyFile")) : null, + properties.containsKey("client.keyCertChainFile") ? new FileInputStream(properties.getProperty("client.keyCertChainFile")) : null, + properties.containsKey("client.keyFile") ? decryptionStrategy.decryptPrivateKey(properties.getProperty("client.keyFile"), true) : null, properties.containsKey("client.password") ? properties.getProperty("client.password") : null) .build(); } @@ -108,8 +132,8 @@ public class SslHelper { .build(); } else { return SslContextBuilder.forServer( - properties.containsKey("server.keyCertChainFile") ? new File(properties.getProperty("server.keyCertChainFile")) : null, - properties.containsKey("server.keyFile") ? new File(properties.getProperty("server.keyFile")) : null, + properties.containsKey("server.keyCertChainFile") ? new FileInputStream(properties.getProperty("server.keyCertChainFile")) : null, + properties.containsKey("server.keyFile") ? decryptionStrategy.decryptPrivateKey(properties.getProperty("server.keyFile"), false) : null, properties.containsKey("server.password") ? properties.getProperty("server.password") : null) .sslProvider(provider) .trustManager(new File(properties.getProperty("server.trustManager")))