Skip to content

Commit c1e3bb3

Browse files
dmercurialidennis.mercuriali
andauthored
Add pkcs12 support on cache server (#201)
* #200 support for pkcs12 server certs * #200 allow to set secure ssl on client * #200 allow to set secure ssl on client * fix apache.rat --------- Co-authored-by: dennis.mercuriali <dennis.mercuriali@diennea.com>
1 parent d57582f commit c1e3bb3

File tree

12 files changed

+150
-44
lines changed

12 files changed

+150
-44
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
**/.settings/
1212
**/.DS_Store/
1313
/.idea/
14+
**/*.iml
1415
/.vscode/

blazingcache-core/src/main/java/blazingcache/client/CacheClient.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ public CacheClient(String clientId, String sharedSecret, ServerLocator brokerLoc
363363
}
364364

365365
private CacheClient(String clientId, String sharedSecret, ServerLocator brokerLocator,
366-
boolean offHeap, ByteBufAllocator allocator, MetricsProvider metricsProvider) {
366+
boolean offHeap, ByteBufAllocator allocator, MetricsProvider metricsProvider) {
367367
this.offHeap = offHeap;
368368
this.brokerLocator = brokerLocator;
369369
this.sharedSecret = sharedSecret;
@@ -712,7 +712,7 @@ private void performEviction() throws InterruptedException {
712712
@Override
713713
public void accept(EntryHandle t) {
714714
if ((maxMemory > 0 && releasedMemory < to_release)
715-
|| (maxLocalEntryAge > 0 && t.getLastGetTime() < maxAgeTsNanos)) {
715+
|| (maxLocalEntryAge > 0 && t.getLastGetTime() < maxAgeTsNanos)) {
716716
evictable.add(t);
717717
releasedMemory += t.getSerializedDataLength();
718718
}
@@ -758,7 +758,7 @@ public void accept(EntryHandle t) {
758758

759759
private boolean checkPerformEvictionForMaxLocalEntryAge(final long now) {
760760
return maxLocalEntryAge > 0
761-
&& now - lastPerformedEvictionTimestamp >= maxLocalEntryAge / 2;
761+
&& now - lastPerformedEvictionTimestamp >= maxLocalEntryAge / 2;
762762
}
763763

764764
@Override

blazingcache-core/src/main/java/blazingcache/client/CacheClientBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public class CacheClientBuilder {
5353
private Object cacheServer;
5454
private int port = 1025;
5555
private boolean ssl = false;
56+
private boolean sslInsecure = true;
5657
private boolean jmx = false;
5758
private EntrySerializer entrySerializer = new JDKEntrySerializer();
5859
private MetricsProvider metricsProvider;
@@ -290,11 +291,13 @@ public CacheClient build() {
290291
locator = new NettyCacheServerLocator(host, port, ssl);
291292
((GenericNettyBrokerLocator) locator).setConnectTimeout(connectTimeout);
292293
((GenericNettyBrokerLocator) locator).setSocketTimeout(socketTimeout);
294+
((GenericNettyBrokerLocator) locator).setSslInsecure(sslInsecure);
293295
break;
294296
case CLUSTERED:
295297
locator = new ZKCacheServerLocator(zkConnectString, zkSessionTimeout, zkPath);
296298
((GenericNettyBrokerLocator) locator).setConnectTimeout(connectTimeout);
297299
((GenericNettyBrokerLocator) locator).setSocketTimeout(socketTimeout);
300+
((GenericNettyBrokerLocator) locator).setSslInsecure(sslInsecure);
298301
break;
299302
case LOCAL:
300303
if (cacheServer == null) {

blazingcache-core/src/main/java/blazingcache/network/netty/GenericNettyBrokerLocator.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public abstract class GenericNettyBrokerLocator implements ServerLocator {
4444

4545
protected int connectTimeout = 60000;
4646
protected int socketTimeout = 240000;
47+
protected boolean sslInsecure = true;
4748

4849
public int getConnectTimeout() {
4950
return connectTimeout;
@@ -61,6 +62,14 @@ public void setSocketTimeout(int socketTimeout) {
6162
this.socketTimeout = socketTimeout;
6263
}
6364

65+
public boolean isSslInsecure() {
66+
return sslInsecure;
67+
}
68+
69+
public void setSslInsecure(boolean sslInsecure) {
70+
this.sslInsecure = sslInsecure;
71+
}
72+
6473
@Override
6574
public Channel connect(ChannelEventListener messageReceiver, ConnectionRequestInfo clientInfo) throws InterruptedException, ServerNotAvailableException, ServerRejectedConnectionException {
6675
boolean ok = false;
@@ -82,6 +91,7 @@ public Channel connect(ChannelEventListener messageReceiver, ConnectionRequestIn
8291
connector.setConnectTimeout(connectTimeout);
8392
connector.setSocketTimeout(socketTimeout);
8493
connector.setSsl(broker.isSsl());
94+
connector.setSslInsecure(sslInsecure);
8595
NettyChannel channel;
8696
try {
8797
channel = connector.connect();

blazingcache-core/src/main/java/blazingcache/network/netty/NettyChannelAcceptor.java

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import io.netty.handler.ssl.SslProvider;
3939
import io.netty.handler.ssl.util.SelfSignedCertificate;
4040
import java.io.File;
41+
import java.io.FileInputStream;
42+
import java.security.KeyStore;
4143
import java.util.List;
4244
import java.util.concurrent.ExecutionException;
4345
import java.util.concurrent.ExecutorService;
@@ -48,6 +50,8 @@
4850
import java.util.concurrent.atomic.AtomicLong;
4951
import java.util.logging.Level;
5052
import java.util.logging.Logger;
53+
import javax.net.ssl.KeyManagerFactory;
54+
import javax.net.ssl.SSLException;
5155

5256
/**
5357
* Accepts connections from workers
@@ -165,21 +169,38 @@ public void start() throws Exception {
165169
SelfSignedCertificate ssc = new SelfSignedCertificate();
166170
try {
167171
sslCtx = SslContextBuilder
168-
.forServer(ssc.certificate(), ssc.privateKey())
169-
.sslProvider(useOpenSSL ? SslProvider.OPENSSL : SslProvider.JDK)
170-
.ciphers(sslCiphers)
171-
.build();
172+
.forServer(ssc.certificate(), ssc.privateKey())
173+
.sslProvider(useOpenSSL ? SslProvider.OPENSSL : SslProvider.JDK)
174+
.ciphers(sslCiphers)
175+
.build();
172176
} finally {
173177
ssc.delete();
174178
}
175179
} else {
176-
LOGGER.log(Level.SEVERE, "start SSL with certificate " + sslCertFile.getAbsolutePath() + " chain file " + sslCertChainFile.getAbsolutePath() + ", useOpenSSL:" + useOpenSSL);
180+
LOGGER.log(Level.SEVERE, "start SSL with certificate " + sslCertFile.getAbsolutePath()
181+
+ " chain file " + (sslCertChainFile == null ? "null" : sslCertChainFile.getAbsolutePath())
182+
+ ", useOpenSSL:" + useOpenSSL);
177183
if (sslCiphers != null) {
178184
LOGGER.log(Level.SEVERE, "required sslCiphers " + sslCiphers);
179185
}
180-
sslCtx = SslContextBuilder.forServer(sslCertChainFile, sslCertFile, sslCertPassword)
181-
.sslProvider(useOpenSSL ? SslProvider.OPENSSL : SslProvider.JDK)
182-
.ciphers(sslCiphers).build();
186+
SslContextBuilder builder;
187+
if (sslCertFile.getName().endsWith(".p12") || sslCertFile.getName().endsWith(".pfx")) {
188+
try (FileInputStream fis = new FileInputStream(sslCertFile)) {
189+
KeyStore ks = KeyStore.getInstance("PKCS12");
190+
ks.load(fis, sslCertPassword.toCharArray());
191+
192+
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
193+
kmf.init(ks, sslCertPassword.toCharArray());
194+
195+
builder = SslContextBuilder.forServer(kmf);
196+
} catch (Exception e) {
197+
throw new SSLException("provided certFile looks like a PKCS12 file but could not be loaded", e);
198+
}
199+
} else {
200+
builder = SslContextBuilder.forServer(sslCertChainFile, sslCertFile, sslCertPassword);
201+
}
202+
sslCtx = builder.sslProvider(useOpenSSL ? SslProvider.OPENSSL : SslProvider.JDK)
203+
.ciphers(sslCiphers).build();
183204
}
184205

185206
}
@@ -205,31 +226,31 @@ public Thread newThread(Runnable r) {
205226
}
206227
ServerBootstrap b = new ServerBootstrap();
207228
b.group(bossGroup, workerGroup)
208-
.channel(NetworkUtils.isEnableEpollNative() ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
209-
.childHandler(new ChannelInitializer<SocketChannel>() {
210-
@Override
211-
public void initChannel(SocketChannel ch) throws Exception {
212-
NettyChannel session = new NettyChannel("unnamed", ch, callbackExecutor, null);
213-
if (acceptor != null) {
214-
acceptor.createConnection(session);
215-
}
229+
.channel(NetworkUtils.isEnableEpollNative() ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
230+
.childHandler(new ChannelInitializer<SocketChannel>() {
231+
@Override
232+
public void initChannel(SocketChannel ch) throws Exception {
233+
NettyChannel session = new NettyChannel("unnamed", ch, callbackExecutor, null);
234+
if (acceptor != null) {
235+
acceptor.createConnection(session);
236+
}
216237

217238
// ch.pipeline().addLast(new LoggingHandler());
218-
// Add SSL handler first to encrypt and decrypt everything.
219-
if (ssl) {
220-
ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()));
239+
// Add SSL handler first to encrypt and decrypt everything.
240+
if (ssl) {
241+
ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()));
242+
}
243+
244+
ch.pipeline().addLast("lengthprepender", new LengthFieldPrepender(4));
245+
ch.pipeline().addLast("lengthbaseddecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
246+
ch.pipeline().addLast("messageencoder", new DataMessageEncoder());
247+
ch.pipeline().addLast("messagedecoder", new DataMessageDecoder());
248+
ch.pipeline().addLast(new InboundMessageHandler(session));
221249
}
222-
223-
ch.pipeline().addLast("lengthprepender", new LengthFieldPrepender(4));
224-
ch.pipeline().addLast("lengthbaseddecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
225-
ch.pipeline().addLast("messageencoder", new DataMessageEncoder());
226-
ch.pipeline().addLast("messagedecoder", new DataMessageDecoder());
227-
ch.pipeline().addLast(new InboundMessageHandler(session));
228-
}
229-
})
230-
.option(ChannelOption.SO_BACKLOG, 128)
231-
.option(ChannelOption.SO_REUSEADDR, true)
232-
.childOption(ChannelOption.SO_KEEPALIVE, true);
250+
})
251+
.option(ChannelOption.SO_BACKLOG, 128)
252+
.option(ChannelOption.SO_REUSEADDR, true)
253+
.childOption(ChannelOption.SO_KEEPALIVE, true);
233254

234255
ChannelFuture f = b.bind(host, port).sync(); // (7)
235256
this.channel = f.channel();

blazingcache-core/src/main/java/blazingcache/network/netty/NettyConnector.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import io.netty.handler.timeout.ReadTimeoutHandler;
4141
import java.util.concurrent.ExecutorService;
4242
import java.util.concurrent.Executors;
43-
import java.util.logging.Level;
4443
import java.util.logging.Logger;
4544

4645
/**
@@ -59,7 +58,7 @@ public class NettyConnector implements AutoCloseable {
5958
private EventLoopGroup group;
6059
private SslContext sslCtx;
6160
private boolean ssl;
62-
private boolean sslUnsecure = true;
61+
private boolean sslInsecure = true;
6362
protected int connectTimeout = 60000;
6463
protected int socketTimeout = 240000;
6564
private final ExecutorService callbackExecutor = Executors.newCachedThreadPool();
@@ -100,12 +99,12 @@ public void setSsl(boolean ssl) {
10099
this.ssl = ssl;
101100
}
102101

103-
public boolean isSslUnsecure() {
104-
return sslUnsecure;
102+
public boolean isSslInsecure() {
103+
return sslInsecure;
105104
}
106105

107-
public void setSslUnsecure(boolean sslUnsecure) {
108-
this.sslUnsecure = sslUnsecure;
106+
public void setSslInsecure(boolean sslInsecure) {
107+
this.sslInsecure = sslInsecure;
109108
}
110109

111110
private ChannelEventListener receiver;
@@ -117,7 +116,7 @@ public NettyConnector(ChannelEventListener receiver) {
117116
public NettyChannel connect() throws Exception {
118117
if (ssl) {
119118
boolean useOpenSSL = NetworkUtils.isOpenSslAvailable();
120-
if (sslUnsecure) {
119+
if (sslInsecure) {
121120
this.sslCtx = SslContextBuilder
122121
.forClient()
123122
.sslProvider(useOpenSSL ? SslProvider.OPENSSL : SslProvider.JDK)

blazingcache-core/src/test/java/blazingcache/SimpleSSLTest.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import blazingcache.server.CacheServer;
2828
import io.netty.handler.ssl.util.SelfSignedCertificate;
2929
import java.io.File;
30+
import java.net.URL;
3031
import java.nio.charset.StandardCharsets;
3132
import org.junit.Assert;
3233
import org.junit.Test;
@@ -35,21 +36,34 @@ public class SimpleSSLTest {
3536

3637
@Test
3738
public void basicTestSslSelfSigned() throws Exception {
38-
basicTestSsl(null, null);
39+
basicTestSsl(null, null, null);
3940
}
4041

4142
@Test
4243
public void basicTestSslWithCert() throws Exception {
4344
SelfSignedCertificate ssc = new SelfSignedCertificate();
44-
basicTestSsl(ssc.privateKey(), ssc.certificate());
45+
basicTestSsl(ssc.privateKey(), ssc.certificate(), null);
4546
}
4647

47-
private void basicTestSsl(File certificateFile, File certificateChain) throws Exception {
48+
@Test
49+
public void basicTestSslWithPwdProtectedCert() throws Exception {
50+
File cert = new File(this.getClass().getClassLoader().getResource("cert1.key").getFile());
51+
File chain = new File(this.getClass().getClassLoader().getResource("cert1_chain.pem").getFile());
52+
basicTestSsl(cert, chain, "blazingcache1");
53+
}
54+
55+
@Test
56+
public void basicTestSslWithPKCS12() throws Exception {
57+
File cert = new File(this.getClass().getClassLoader().getResource("cert1.p12").getFile());
58+
basicTestSsl(cert, null, "blazingcache1");
59+
}
60+
61+
private void basicTestSsl(File certificateFile, File certificateChain, String certificateFilePassword) throws Exception {
4862
byte[] data = "testdata".getBytes(StandardCharsets.UTF_8);
4963

5064
ServerHostData serverHostData = new ServerHostData("localhost", 1234, "test", true, null);
5165
try (CacheServer cacheServer = new CacheServer("ciao", serverHostData)) {
52-
cacheServer.setupSsl(certificateFile, null, certificateChain, null);
66+
cacheServer.setupSsl(certificateFile, certificateFilePassword, certificateChain, null);
5367
cacheServer.start();
5468
try (CacheClient client1 = new CacheClient("theClient1", "ciao", new NettyCacheServerLocator(serverHostData));
5569
CacheClient client2 = new CacheClient("theClient2", "ciao", new NettyCacheServerLocator(serverHostData));) {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
-----BEGIN ENCRYPTED PRIVATE KEY-----
2+
MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI0cy6qzGPdncCAggA
3+
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBD4YpSngAfZjRa9qJ87LmpVBIIE
4+
0JyIDCAHYufKL06QAJgmtoUjDxK28y7S7HkT/RB+6UDLtaWy6XDaFtXOfAymQsgx
5+
L48rX9JkYjPR+O/A+3ddbA7yMiGUYnPH2mk0WCJdehGGI9D1oBkf18qyKIbV0fqE
6+
W5wcpggFYY+issTxX5njhr4Q1iyiA94SHmZG/0TPL3dKlN9XkKVW2eNkm2xH6W3m
7+
AEX4uRC3x2VH0sTW1i7eHhisSz6STlMtdzl4j/SzWsBwNnCHfu8v3GIvGwI9OQ63
8+
OKean6Dv68vmTitFPIHEDeWiZ2dD2SbRJhANxjDrn6buT1IVLZ4AGvS0+MrmQZSf
9+
oJan0z9A0G9q/xnwfAq9RGlswK2fDJCt+rtpVJdTSLr7OP0cWxqBaFFM3ZL+eoFK
10+
wOxcI4hmNlnbvk6+lYUY7G2i+ZXcGQz+jE/ArJ07NJUH8YXbh7DDV69HqkilJRM4
11+
f/JpVjMk0zT/ygzRosgGW2MndBGiBV1EP835Nd7zzkKfyvT98+o0zEp9r7FZP7mv
12+
qLuQGSaiACgWlcc7YG9cjEPqbMQ/6jwlOACwLo7hvE/JcRZHN23ib7ssg8hvlpi7
13+
EW60ZK9fGtJgMm9CDgn0UVdVaCXNXUonuI2r3AD6B7xhlV0ScEZ2T+myQ7vvMvNi
14+
vlK6NbCmms0PgbG0jvzFlAeXw8hWq7cuTbv6dBDokNjQ9XM6GZPDG/ynYpFb7SnK
15+
eznAHtWPYnDjSRtYWaqU3sTWqh0BkAR3xaL0/jRDm3MJBhcE8U3gEugVC5yHML7q
16+
4Ux+aBt/Gq0jT6M3PZENheN8c5wso9shL3M8m+mQ760sHNYH3vTGF+4Z/AOBsgpU
17+
sYTgrPLMScxDfTomf/srT9XG6P+Cd2X5d6pLMWy8FS5/R3GNRRDkOnI3BlkkTR8Y
18+
0Kw8Z7CE05Uw8rUwlkpSGrGwWxq5+ZMN7YnvJH4I3P0FMzl8BSPmVI3XGyaibpBi
19+
reU36l0QekkDIoVa3erMnB0FYO6R29XpY83BGbtiQlrS8Mw47zMHJRo3W4Zl7TdF
20+
2vdNjoKw+Fe3tvMkOT1cNBzHyU00uSaKFB8kxTOv/sLkXeGUUT1n+SLscaxqfGV6
21+
Ctxwims18/ItUsMkMAHX3fedRbBXRV99Cr5wBg9NPc3j+NAC2c5w/8Xt+e66C6lB
22+
bFPRlRXyPJlWCEPrGQEX4OgVQI//JtiRaB39wjCDW+RCYlz2a1fDVy4mfOuu3jp5
23+
RBz1WxL+gJWbpGbXwqBv8jofxm7DtQl8wghWbCGmNTj4pXtPQBA4zamdvi/s2qrL
24+
IZerX0k5zZnY5KQYUgpxybpU28ua9fgrIxzA/Tg5V5dL34WjF3S4IQBqz4PYLVMh
25+
t0Uz6l8s8ccLkZ0e0j9vsFM91oiAn2RIOBheoLg2vNJeLl5KGi+gl3SoiEigdwG8
26+
hTAO8FR+iCoYz+ApOV6H1rqs3g4cWWP/RKWxjBFJ4qERXBDNvBtbA97b/yDnv7hh
27+
X3ZtXtsml9sT4gOZmAtZD3VviJWiuSWpfEcN/DWaNtMLzyQ1WW8Ai+iKqMODjcw/
28+
EnU+/kl2zWvOpbRGK2G8HI7FJVWo6dPfApXdY16ITMXKY35uQAD6HqP2vbPGeBrh
29+
QcZh2pbF3v86Kmwlcj0dTWS4UBSPWJtyeIresTOp3+be
30+
-----END ENCRYPTED PRIVATE KEY-----
2.55 KB
Binary file not shown.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDXzCCAkegAwIBAgIUI9HMRW+gfFWKIV3y+Nu3jCj+ZpowDQYJKoZIhvcNAQEL
3+
BQAwPjELMAkGA1UEBhMCSVQxCzAJBgNVBAgMAlJBMRAwDgYDVQQKDAdEaWVubmVh
4+
MRAwDgYDVQQLDAdEaWVubmVhMCAXDTI1MDMxMzExNDUwN1oYDzIxMjUwMjE3MTE0
5+
NTA3WjA+MQswCQYDVQQGEwJJVDELMAkGA1UECAwCUkExEDAOBgNVBAoMB0RpZW5u
6+
ZWExEDAOBgNVBAsMB0RpZW5uZWEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
7+
AoIBAQCtpMg1OcPN985H9cVRy9S9fqHZWCH9EuSHrtFgD+l+XA72lDVI6Z20NNQA
8+
OJoKLEnpJyfeMTYVvr13zo49OefPsEh4xQTp4RnmYFynAptw/pI/7LjPe6w0jgsu
9+
HhTKN9IHyoJykELkfTmGoj21aWP7dK4/OBZUuoIgbI26oWNRahHpsoc8pxf/M5tM
10+
aZZxAQm0Vk2dA7U7qHWjFopwsEQwRGKSl1SRRtoIut5QYdN7SRRZeJXdzqdUmcjx
11+
mEBsOiRoaCa+p6C6MKwhVCAPUdV3UM1v0W/jWVB/NVe/x/vjiqEJITbNvyFRxw57
12+
c39A9TgqPFFV8cYNWJPEo+DyKJ4DAgMBAAGjUzBRMB0GA1UdDgQWBBRSxJLBO4Xu
13+
H/ImY7eJ7nlm4+doajAfBgNVHSMEGDAWgBRSxJLBO4XuH/ImY7eJ7nlm4+doajAP
14+
BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQChpeQew+D/Vp15izU6
15+
dOlrwVjeJfj5r2nkpQOAtx8G8lNjfXt7+5zKz/s4WsD+L8JrMLGPQy6roXP2kx2t
16+
ZhClGTRojPhFiOdcJ2l2fwzXFW3kREPhvHuKOzr1O3U4nguKO9+vE4prlfX1hL48
17+
N11WULA1vd5H6zI/Yn7l6i9RiCp9hwYZKGq9zgiZzhq5+YSVSN+nkEycEDmBDl4+
18+
frBoamxgE1dapdfHcKrEz8HXplCzmkx1JEkAdvB/+Jwf4RkeIhqcPreyhBR7Axqj
19+
U4iCziFwHkNuRa55T1YfZaZMo0zPOOHkb0OR/dRR3DYF5wwtO+tR11AKPUdj7sns
20+
sdxJ
21+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)