Skip to content

Commit 230d12d

Browse files
garyrussellartembilan
authored andcommitted
TCP, SSL, Enable Host Verification by default
Make key/trust store types configurable; add a test with host violation. * Fix some typos and code style in the related classed and docs * Add asserts for the store type properties
1 parent 075d237 commit 230d12d

File tree

11 files changed

+340
-126
lines changed

11 files changed

+340
-126
lines changed

spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,22 +24,41 @@
2424

2525
import javax.net.ssl.SSLContext;
2626
import javax.net.ssl.SSLEngine;
27+
import javax.net.ssl.SSLParameters;
2728

2829
import org.springframework.context.ApplicationEventPublisher;
2930
import org.springframework.util.Assert;
3031

3132
/**
3233
* Implementation of {@link TcpNioConnectionSupport} for SSL
3334
* NIO connections.
35+
*
3436
* @author Gary Russell
37+
*
3538
* @since 2.2
3639
*
3740
*/
3841
public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupport implements TcpNioConnectionSupport {
3942

40-
private volatile SSLContext sslContext;
43+
private final SSLContext sslContext;
44+
45+
private final boolean sslVerifyHost;
4146

47+
/**
48+
* Create an instance with host verification enabled.
49+
* @param sslContextSupport the ssl context support.
50+
*/
4251
public DefaultTcpNioSSLConnectionSupport(TcpSSLContextSupport sslContextSupport) {
52+
this(sslContextSupport, true);
53+
}
54+
55+
/**
56+
* Create an instance.
57+
* @param sslContextSupport the ssl context support.
58+
* @param sslVerifyHost true to verify the host during handshake.
59+
* @since 5.0.8
60+
*/
61+
public DefaultTcpNioSSLConnectionSupport(TcpSSLContextSupport sslContextSupport, boolean sslVerifyHost) {
4362
Assert.notNull(sslContextSupport, "TcpSSLContextSupport must not be null");
4463
try {
4564
this.sslContext = sslContextSupport.getSSLContext();
@@ -48,6 +67,7 @@ public DefaultTcpNioSSLConnectionSupport(TcpSSLContextSupport sslContextSupport)
4867
throw new IllegalArgumentException("Invalid TcpSSLContextSupport - it failed to provide an SSLContext", e);
4968
}
5069
Assert.notNull(this.sslContext, "SSLContext retrieved from context support must not be null");
70+
this.sslVerifyHost = sslVerifyHost;
5171
}
5272

5373
/**
@@ -56,8 +76,19 @@ public DefaultTcpNioSSLConnectionSupport(TcpSSLContextSupport sslContextSupport)
5676
@Override
5777
public TcpNioConnection createNewConnection(SocketChannel socketChannel, boolean server, boolean lookupHost,
5878
ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) throws Exception {
79+
5980
SSLEngine sslEngine = this.sslContext.createSSLEngine();
6081
postProcessSSLEngine(sslEngine);
82+
if (this.sslVerifyHost) {
83+
SSLParameters sslParameters = sslEngine.getSSLParameters();
84+
if (sslParameters == null) {
85+
sslParameters = new SSLParameters();
86+
}
87+
// HTTPS works for any TCP connection.
88+
// It checks SAN (Subject Alternative Name) as well as CN.
89+
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
90+
sslEngine.setSSLParameters(sslParameters);
91+
}
6192
TcpNioSSLConnection tcpNioSSLConnection;
6293
if (isPushbackCapable()) {
6394
tcpNioSSLConnection = new PushBackTcpNioSSLConnection(socketChannel, server, lookupHost,

spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -32,12 +32,18 @@
3232
* Default implementation of {@link TcpSSLContextSupport}; uses a
3333
* 'TLS' (by default) {@link SSLContext}, initialized with 'JKS'
3434
* keystores, managed by 'SunX509' Key and Trust managers.
35+
*
3536
* @author Gary Russell
37+
*
3638
* @since 2.1
3739
*
3840
*/
3941
public class DefaultTcpSSLContextSupport implements TcpSSLContextSupport {
4042

43+
private static final String DEFAULT_KEY_STORE_TYPE = "JKS";
44+
45+
private static final String DEFAULT_TRUST_STORE_TYPE = "JKS";
46+
4147
private final Resource keyStore;
4248

4349
private final Resource trustStore;
@@ -46,7 +52,11 @@ public class DefaultTcpSSLContextSupport implements TcpSSLContextSupport {
4652

4753
private final char[] trustStorePassword;
4854

49-
private volatile String protocol = "TLS";
55+
private String protocol = "TLS";
56+
57+
private String keyStoreType = DEFAULT_KEY_STORE_TYPE;
58+
59+
private String trustStoreType = DEFAULT_TRUST_STORE_TYPE;
5060

5161
/**
5262
* Prepares for the creation of an SSLContext using the supplied
@@ -69,9 +79,30 @@ public DefaultTcpSSLContextSupport(String keyStore, String trustStore,
6979
this.trustStorePassword = trustStorePassword.toCharArray();
7080
}
7181

72-
public SSLContext getSSLContext() throws GeneralSecurityException, IOException {
73-
KeyStore ks = KeyStore.getInstance("JKS");
74-
KeyStore ts = KeyStore.getInstance("JKS");
82+
/**
83+
* Set the key store type. Default JKS.
84+
* @param keyStoreType the type.
85+
* @since 5.0.8
86+
*/
87+
public void setKeyStoreType(String keyStoreType) {
88+
Assert.hasText(keyStoreType, "'keyStoreType' cannot be empty");
89+
this.keyStoreType = keyStoreType;
90+
}
91+
92+
/**
93+
* Set the trust store type. Default JKS.
94+
* @param trustStoreType the type.
95+
* @since 5.0.8
96+
*/
97+
public void setTrustStoreType(String trustStoreType) {
98+
Assert.hasText(trustStoreType, "'trustStoreType' cannot be empty");
99+
this.trustStoreType = trustStoreType;
100+
}
101+
102+
@Override
103+
public SSLContext getSSLContext() throws GeneralSecurityException, IOException {
104+
KeyStore ks = KeyStore.getInstance(this.keyStoreType);
105+
KeyStore ts = KeyStore.getInstance(this.trustStoreType);
75106

76107
ks.load(this.keyStore.getInputStream(), this.keyStorePassword);
77108
ts.load(this.trustStore.getInputStream(), this.trustStorePassword);

spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,25 +19,61 @@
1919
import java.net.ServerSocket;
2020
import java.net.Socket;
2121

22+
import javax.net.ssl.SSLParameters;
23+
import javax.net.ssl.SSLSocket;
24+
2225
/**
2326
* Default implementation of {@link TcpSocketSupport}; makes no
2427
* changes to sockets.
28+
*
2529
* @author Gary Russell
30+
*
2631
* @since 2.2
2732
*
2833
*/
2934
public class DefaultTcpSocketSupport implements TcpSocketSupport {
3035

36+
private final boolean sslVerifyHost;
37+
38+
/**
39+
* Construct an instance with host verification enabled.
40+
*/
41+
public DefaultTcpSocketSupport() {
42+
this(true);
43+
}
44+
45+
/**
46+
* Construct an instance with the provided sslVerifyHost.
47+
* @param sslVerifyHost true to verify host during SSL handshake.
48+
* @since 5.0.8.
49+
*/
50+
public DefaultTcpSocketSupport(boolean sslVerifyHost) {
51+
this.sslVerifyHost = sslVerifyHost;
52+
}
53+
3154
/**
3255
* No-Op.
3356
*/
57+
@Override
3458
public void postProcessServerSocket(ServerSocket serverSocket) {
3559
}
3660

3761
/**
38-
* No-Op.
62+
* Enables host verification for SSL, if so configured.
3963
*/
64+
@Override
4065
public void postProcessSocket(Socket socket) {
66+
if (this.sslVerifyHost && socket instanceof SSLSocket) {
67+
SSLSocket sslSocket = (SSLSocket) socket;
68+
SSLParameters sslParameters = sslSocket.getSSLParameters();
69+
if (sslParameters == null) {
70+
sslParameters = new SSLParameters();
71+
}
72+
// HTTPS works for any TCP connection.
73+
// It checks SAN (Subject Alternative Name) as well as CN.
74+
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
75+
sslSocket.setSSLParameters(sslParameters);
76+
}
4177
}
4278

4379
}

spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@
8181
</bean>
8282

8383
<bean id="nioConnectionSupport"
84-
class="org.springframework.integration.ip.tcp.connection.DefaultTcpNioSSLConnectionSupport" />
84+
class="org.springframework.integration.ip.tcp.connection.DefaultTcpNioSSLConnectionSupport">
85+
<constructor-arg ref="sslContextSupport" />
86+
</bean>
8587

8688
<ip:tcp-connection-factory id="secureServer"
8789
type="server"

spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/PushbackTcpTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -401,7 +401,7 @@ public DefaultTcpNioSSLConnectionSupport connectionSupport() {
401401
"test.truststore.ks", "secret", "secret");
402402
sslContextSupport.setProtocol("SSL");
403403
DefaultTcpNioSSLConnectionSupport tcpNioConnectionSupport =
404-
new DefaultTcpNioSSLConnectionSupport(sslContextSupport);
404+
new DefaultTcpNioSSLConnectionSupport(sslContextSupport, false);
405405
tcpNioConnectionSupport.setPushbackCapable(true);
406406
return tcpNioConnectionSupport;
407407
}

0 commit comments

Comments
 (0)