Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<SocketChannel> {

Expand All @@ -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()));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,36 @@
*/
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;
import java.security.KeyStore;
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 {
Expand All @@ -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,
Expand All @@ -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);
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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));
}
Expand Down