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..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 @@ -18,7 +18,12 @@ */ package org.apache.pulsar.common.util; -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +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 +31,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 +57,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 +71,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 +94,27 @@ 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)); + } else { + builder.trustManager((File) null); + } + } + 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..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 @@ -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.createNettySslContextForServer(true /* to allow InsecureConnection */, + 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)); }