From 8115852351479e26aa34648cc9d94c94e5d3b642 Mon Sep 17 00:00:00 2001 From: Masakazu Kitajo Date: Sat, 10 Feb 2018 15:08:05 +0900 Subject: [PATCH 1/3] Use SecurityUtility class --- .../service/PulsarChannelInitializer.java | 36 +------------ .../apache/pulsar/client/impl/HttpClient.java | 4 +- .../pulsar/common/util/SecurityUtility.java | 53 +++++++++++++++---- .../server/ServiceChannelInitializer.java | 30 ++--------- 4 files changed, 51 insertions(+), 72 deletions(-) diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/PulsarChannelInitializer.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/PulsarChannelInitializer.java index 31387696a8199..da10a2df711ea 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/PulsarChannelInitializer.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/PulsarChannelInitializer.java @@ -18,22 +18,15 @@ */ package org.apache.pulsar.broker.service; -import java.io.File; -import java.security.cert.X509Certificate; - -import org.apache.commons.lang3.StringUtils; import org.apache.pulsar.broker.ServiceConfiguration; -import org.apache.pulsar.client.impl.auth.AuthenticationDataTls; import org.apache.pulsar.common.api.ByteBufPair; import org.apache.pulsar.common.api.PulsarDecoder; +import org.apache.pulsar.common.util.SecurityUtility; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; -import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; public class PulsarChannelInitializer extends ChannelInitializer { @@ -57,32 +50,7 @@ public PulsarChannelInitializer(BrokerService brokerService, ServiceConfiguratio @Override protected void initChannel(SocketChannel ch) throws Exception { if (enableTLS) { - File tlsCert = new File(serviceConfig.getTlsCertificateFilePath()); - File tlsKey = new File(serviceConfig.getTlsKeyFilePath()); - SslContextBuilder builder = SslContextBuilder.forServer(tlsCert, tlsKey); - if (serviceConfig.isTlsAllowInsecureConnection()) { - builder.trustManager(InsecureTrustManagerFactory.INSTANCE); - } else { - if (serviceConfig.getTlsTrustCertsFilePath().isEmpty()) { - // Use system default - builder.trustManager((File) null); - } else { - File trustCertCollection = new File(serviceConfig.getTlsTrustCertsFilePath()); - builder.trustManager(trustCertCollection); - } - } - - ServiceConfiguration config = brokerService.pulsar().getConfiguration(); - String certFilePath = config.getTlsCertificateFilePath(); - String keyFilePath = config.getTlsKeyFilePath(); - if (StringUtils.isNotBlank(certFilePath) && StringUtils.isNotBlank(keyFilePath)) { - AuthenticationDataTls authTlsData = new AuthenticationDataTls(certFilePath, keyFilePath); - builder.keyManager(authTlsData.getTlsPrivateKey(), - (X509Certificate[]) authTlsData.getTlsCertificates()); - } - - - SslContext sslCtx = builder.clientAuth(ClientAuth.OPTIONAL).build(); + SslContext sslCtx = SecurityUtility.createNettySslContextForServer(serviceConfig.isTlsAllowInsecureConnection(), serviceConfig.getTlsTrustCertsFilePath(), serviceConfig.getTlsCertificateFilePath(), serviceConfig.getTlsKeyFilePath()); ch.pipeline().addLast(TLS_HANDLER, sslCtx.newHandler(ch.alloc())); } diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/HttpClient.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/HttpClient.java index d178c24579d8e..d4e1f54fc068c 100644 --- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/HttpClient.java +++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/HttpClient.java @@ -92,10 +92,10 @@ public boolean keepAlive(Request ahcRequest, HttpRequest request, HttpResponse r // Set client key and certificate if available AuthenticationDataProvider authData = authentication.getAuthData(); if (authData.hasDataForTls()) { - sslCtx = SecurityUtility.createNettySslContext(tlsAllowInsecureConnection, tlsTrustCertsFilePath, + sslCtx = SecurityUtility.createNettySslContextForClient(tlsAllowInsecureConnection, tlsTrustCertsFilePath, authData.getTlsCertificates(), authData.getTlsPrivateKey()); } else { - sslCtx = SecurityUtility.createNettySslContext(tlsAllowInsecureConnection, tlsTrustCertsFilePath); + sslCtx = SecurityUtility.createNettySslContextForClient(tlsAllowInsecureConnection, tlsTrustCertsFilePath); } confBuilder.setSslContext(sslCtx); diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java b/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java index d66b33919a11d..3e0c95d4885f7 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java @@ -18,7 +18,11 @@ */ package org.apache.pulsar.common.util; -import java.io.*; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.KeyManagementException; @@ -26,18 +30,23 @@ import java.security.PrivateKey; import java.security.SecureRandom; import java.security.cert.Certificate; -import java.security.cert.X509Certificate; import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.Collection; -import javax.net.ssl.*; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import io.netty.handler.ssl.ClientAuth; 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; public class SecurityUtility { @@ -47,9 +56,10 @@ public static SSLContext createSslContext(boolean allowInsecureConnection, Certi return createSslContext(allowInsecureConnection, trustCertificates, (Certificate[]) null, (PrivateKey) null); } - public static SslContext createNettySslContext(boolean allowInsecureConnection, String trustCertsFilePath) + public static SslContext createNettySslContextForClient(boolean allowInsecureConnection, String trustCertsFilePath) throws GeneralSecurityException, SSLException, FileNotFoundException { - return createNettySslContext(allowInsecureConnection, trustCertsFilePath, (Certificate[]) null, (PrivateKey) null); + return createNettySslContextForClient(allowInsecureConnection, trustCertsFilePath, (Certificate[]) null, + (PrivateKey) null); } public static SSLContext createSslContext(boolean allowInsecureConnection, String trustCertsFilePath, @@ -60,15 +70,17 @@ public static SSLContext createSslContext(boolean allowInsecureConnection, Strin return createSslContext(allowInsecureConnection, trustCertificates, certificates, privateKey); } - public static SslContext createNettySslContext(boolean allowInsecureConnection, String trustCertsFilePath, - String certFilePath, String keyFilePath) throws GeneralSecurityException, SSLException, FileNotFoundException { + public static SslContext createNettySslContextForClient(boolean allowInsecureConnection, String trustCertsFilePath, + String certFilePath, String keyFilePath) + throws GeneralSecurityException, SSLException, FileNotFoundException { X509Certificate[] certificates = loadCertificatesFromPemFile(certFilePath); PrivateKey privateKey = loadPrivateKeyFromPemFile(keyFilePath); - return createNettySslContext(allowInsecureConnection, trustCertsFilePath, certificates, privateKey); + return createNettySslContextForClient(allowInsecureConnection, trustCertsFilePath, certificates, privateKey); } - public static SslContext createNettySslContext(boolean allowInsecureConnection, String trustCertsFilePath, - Certificate[] certificates, PrivateKey privateKey) throws GeneralSecurityException, SSLException, FileNotFoundException { + public static SslContext createNettySslContextForClient(boolean allowInsecureConnection, String trustCertsFilePath, + Certificate[] certificates, PrivateKey privateKey) + throws GeneralSecurityException, SSLException, FileNotFoundException { SslContextBuilder builder = SslContextBuilder.forClient(); if (allowInsecureConnection) { builder.trustManager(InsecureTrustManagerFactory.INSTANCE); @@ -81,6 +93,25 @@ public static SslContext createNettySslContext(boolean allowInsecureConnection, return builder.build(); } + public static SslContext createNettySslContextForServer(boolean allowInsecureConnection, String trustCertsFilePath, + String certFilePath, String keyFilePath) + throws GeneralSecurityException, SSLException, FileNotFoundException { + X509Certificate[] certificates = loadCertificatesFromPemFile(certFilePath); + PrivateKey privateKey = loadPrivateKeyFromPemFile(keyFilePath); + + SslContextBuilder builder = SslContextBuilder.forServer(privateKey, (X509Certificate[]) certificates); + if (allowInsecureConnection) { + builder.trustManager(InsecureTrustManagerFactory.INSTANCE); + } else { + if (trustCertsFilePath != null && trustCertsFilePath.length() != 0) { + builder.trustManager(new FileInputStream(trustCertsFilePath)); + } + } + builder.keyManager(privateKey, (X509Certificate[]) certificates); + builder.clientAuth(ClientAuth.OPTIONAL); + return builder.build(); + } + public static SSLContext createSslContext(boolean allowInsecureConnection, Certificate[] trustCertficates, Certificate[] certificates, PrivateKey privateKey) throws GeneralSecurityException { KeyStoreHolder ksh = new KeyStoreHolder(); diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java index e7b0be74b7bdb..68d9d2d4493a3 100644 --- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java +++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java @@ -18,21 +18,13 @@ */ package org.apache.pulsar.proxy.server; -import java.io.File; -import java.security.cert.X509Certificate; - -import org.apache.commons.lang3.StringUtils; -import org.apache.pulsar.broker.ServiceConfiguration; -import org.apache.pulsar.client.impl.auth.AuthenticationDataTls; import org.apache.pulsar.common.api.PulsarDecoder; +import org.apache.pulsar.common.util.SecurityUtility; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; -import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslContextBuilder; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; /** * Initialize service channel handlers. @@ -55,24 +47,12 @@ public ServiceChannelInitializer(ProxyService proxyService, ProxyConfiguration s @Override protected void initChannel(SocketChannel ch) throws Exception { if (enableTLS) { - File tlsCert = new File(serviceConfig.getTlsCertificateFilePath()); - File tlsKey = new File(serviceConfig.getTlsKeyFilePath()); - SslContextBuilder builder = SslContextBuilder.forServer(tlsCert, tlsKey); - // allows insecure connection - builder.trustManager(InsecureTrustManagerFactory.INSTANCE); - SslContext sslCtx = builder.clientAuth(ClientAuth.OPTIONAL).build(); + SslContext sslCtx = SecurityUtility.createNettySslContextForClient(true, + serviceConfig.getTlsTrustCertsFilePath(), serviceConfig.getTlsCertificateFilePath(), + serviceConfig.getTlsKeyFilePath()); ch.pipeline().addLast(TLS_HANDLER, sslCtx.newHandler(ch.alloc())); - - String certFilePath = serviceConfig.getTlsCertificateFilePath(); - String keyFilePath = serviceConfig.getTlsKeyFilePath(); - if (StringUtils.isNotBlank(certFilePath) && StringUtils.isNotBlank(keyFilePath)) { - AuthenticationDataTls authTlsData = new AuthenticationDataTls(certFilePath, keyFilePath); - builder.keyManager(authTlsData.getTlsPrivateKey(), - (X509Certificate[]) authTlsData.getTlsCertificates()); - } - } - + ch.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(PulsarDecoder.MaxFrameSize, 0, 4, 0, 4)); ch.pipeline().addLast("handler", new ProxyConnection(proxyService)); } From e601a92cbeefff2aa57427b097652a8b5eba87ad Mon Sep 17 00:00:00 2001 From: Masakazu Kitajo Date: Sat, 10 Feb 2018 16:12:11 +0900 Subject: [PATCH 2/3] Add a comment --- .../apache/pulsar/proxy/server/ServiceChannelInitializer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java index 68d9d2d4493a3..9016e457673c6 100644 --- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java +++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java @@ -47,7 +47,7 @@ public ServiceChannelInitializer(ProxyService proxyService, ProxyConfiguration s @Override protected void initChannel(SocketChannel ch) throws Exception { if (enableTLS) { - SslContext sslCtx = SecurityUtility.createNettySslContextForClient(true, + SslContext sslCtx = SecurityUtility.createNettySslContextForClient(true /* to allow InsecureConnection */, serviceConfig.getTlsTrustCertsFilePath(), serviceConfig.getTlsCertificateFilePath(), serviceConfig.getTlsKeyFilePath()); ch.pipeline().addLast(TLS_HANDLER, sslCtx.newHandler(ch.alloc())); From 9624af85842d507907404502cb08817cbe052336 Mon Sep 17 00:00:00 2001 From: Masakazu Kitajo Date: Sat, 10 Feb 2018 16:45:34 +0900 Subject: [PATCH 3/3] Fix a careless mistake --- .../java/org/apache/pulsar/common/util/SecurityUtility.java | 3 +++ .../apache/pulsar/proxy/server/ServiceChannelInitializer.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java b/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java index 3e0c95d4885f7..e9106f64cecd4 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java @@ -19,6 +19,7 @@ package org.apache.pulsar.common.util; import java.io.BufferedReader; +import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; @@ -105,6 +106,8 @@ public static SslContext createNettySslContextForServer(boolean allowInsecureCon } else { if (trustCertsFilePath != null && trustCertsFilePath.length() != 0) { builder.trustManager(new FileInputStream(trustCertsFilePath)); + } else { + builder.trustManager((File) null); } } builder.keyManager(privateKey, (X509Certificate[]) certificates); diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java index 9016e457673c6..5bd177c298ef5 100644 --- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java +++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ServiceChannelInitializer.java @@ -47,7 +47,7 @@ public ServiceChannelInitializer(ProxyService proxyService, ProxyConfiguration s @Override protected void initChannel(SocketChannel ch) throws Exception { if (enableTLS) { - SslContext sslCtx = SecurityUtility.createNettySslContextForClient(true /* to allow InsecureConnection */, + SslContext sslCtx = SecurityUtility.createNettySslContextForServer(true /* to allow InsecureConnection */, serviceConfig.getTlsTrustCertsFilePath(), serviceConfig.getTlsCertificateFilePath(), serviceConfig.getTlsKeyFilePath()); ch.pipeline().addLast(TLS_HANDLER, sslCtx.newHandler(ch.alloc()));