From 6934690947550cb741dff1600ab918f95e569022 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Wed, 29 Aug 2018 17:04:14 -0400 Subject: [PATCH] TCP, SSL, Configure Host Verification 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 * Changes for 5.0.x to disable by default, after cherry-pick. --- .../DefaultTcpNioSSLConnectionSupport.java | 35 ++- .../DefaultTcpSSLContextSupport.java | 41 +++- .../connection/DefaultTcpSocketSupport.java | 40 ++- .../ip/config/ParserUnitTests-context.xml | 4 +- .../ip/tcp/connection/PushbackTcpTests.java | 4 +- .../ip/tcp/connection/SocketSupportTests.java | 227 +++++++++++------- .../src/test/resources/test.cer | 31 ++- .../src/test/resources/test.ks | Bin 1386 -> 2316 bytes .../src/test/resources/test.truststore.ks | Bin 681 -> 1027 bytes src/reference/asciidoc/ip.adoc | 41 +++- src/reference/asciidoc/whats-new.adoc | 9 +- 11 files changed, 322 insertions(+), 110 deletions(-) diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java index 346e20685f..3ffefc0f0f 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import java.security.GeneralSecurityException; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; import org.springframework.context.ApplicationEventPublisher; import org.springframework.util.Assert; @@ -31,15 +32,33 @@ import org.springframework.util.Assert; /** * Implementation of {@link TcpNioConnectionSupport} for SSL * NIO connections. + * * @author Gary Russell + * * @since 2.2 * */ public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupport implements TcpNioConnectionSupport { - private volatile SSLContext sslContext; + private final SSLContext sslContext; + private final boolean sslVerifyHost; + + /** + * Create an instance with host verification disabled. + * @param sslContextSupport the ssl context support. + */ public DefaultTcpNioSSLConnectionSupport(TcpSSLContextSupport sslContextSupport) { + this(sslContextSupport, false); + } + + /** + * Create an instance. + * @param sslContextSupport the ssl context support. + * @param sslVerifyHost true to verify the host during handshake. + * @since 5.0.8 + */ + public DefaultTcpNioSSLConnectionSupport(TcpSSLContextSupport sslContextSupport, boolean sslVerifyHost) { Assert.notNull(sslContextSupport, "TcpSSLContextSupport must not be null"); try { this.sslContext = sslContextSupport.getSSLContext(); @@ -48,6 +67,7 @@ public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupp throw new IllegalArgumentException("Invalid TcpSSLContextSupport - it failed to provide an SSLContext", e); } Assert.notNull(this.sslContext, "SSLContext retrieved from context support must not be null"); + this.sslVerifyHost = sslVerifyHost; } /** @@ -56,8 +76,19 @@ public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupp @Override public TcpNioConnection createNewConnection(SocketChannel socketChannel, boolean server, boolean lookupHost, ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) throws Exception { + SSLEngine sslEngine = this.sslContext.createSSLEngine(); postProcessSSLEngine(sslEngine); + if (this.sslVerifyHost) { + SSLParameters sslParameters = sslEngine.getSSLParameters(); + if (sslParameters == null) { + sslParameters = new SSLParameters(); + } + // HTTPS works for any TCP connection. + // It checks SAN (Subject Alternative Name) as well as CN. + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslEngine.setSSLParameters(sslParameters); + } TcpNioSSLConnection tcpNioSSLConnection; if (isPushbackCapable()) { tcpNioSSLConnection = new PushBackTcpNioSSLConnection(socketChannel, server, lookupHost, diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java index bce4c44431..30cb1fbe0c 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,12 +32,18 @@ import org.springframework.util.Assert; * Default implementation of {@link TcpSSLContextSupport}; uses a * 'TLS' (by default) {@link SSLContext}, initialized with 'JKS' * keystores, managed by 'SunX509' Key and Trust managers. + * * @author Gary Russell + * * @since 2.1 * */ public class DefaultTcpSSLContextSupport implements TcpSSLContextSupport { + private static final String DEFAULT_KEY_STORE_TYPE = "JKS"; + + private static final String DEFAULT_TRUST_STORE_TYPE = "JKS"; + private final Resource keyStore; private final Resource trustStore; @@ -46,7 +52,11 @@ public class DefaultTcpSSLContextSupport implements TcpSSLContextSupport { private final char[] trustStorePassword; - private volatile String protocol = "TLS"; + private String protocol = "TLS"; + + private String keyStoreType = DEFAULT_KEY_STORE_TYPE; + + private String trustStoreType = DEFAULT_TRUST_STORE_TYPE; /** * Prepares for the creation of an SSLContext using the supplied @@ -69,9 +79,30 @@ public class DefaultTcpSSLContextSupport implements TcpSSLContextSupport { this.trustStorePassword = trustStorePassword.toCharArray(); } - public SSLContext getSSLContext() throws GeneralSecurityException, IOException { - KeyStore ks = KeyStore.getInstance("JKS"); - KeyStore ts = KeyStore.getInstance("JKS"); + /** + * Set the key store type. Default JKS. + * @param keyStoreType the type. + * @since 5.0.8 + */ + public void setKeyStoreType(String keyStoreType) { + Assert.hasText(keyStoreType, "'keyStoreType' cannot be empty"); + this.keyStoreType = keyStoreType; + } + + /** + * Set the trust store type. Default JKS. + * @param trustStoreType the type. + * @since 5.0.8 + */ + public void setTrustStoreType(String trustStoreType) { + Assert.hasText(trustStoreType, "'trustStoreType' cannot be empty"); + this.trustStoreType = trustStoreType; + } + + @Override + public SSLContext getSSLContext() throws GeneralSecurityException, IOException { + KeyStore ks = KeyStore.getInstance(this.keyStoreType); + KeyStore ts = KeyStore.getInstance(this.trustStoreType); ks.load(this.keyStore.getInputStream(), this.keyStorePassword); ts.load(this.trustStore.getInputStream(), this.trustStorePassword); diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java index a4712a751e..06760eca66 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,25 +19,61 @@ package org.springframework.integration.ip.tcp.connection; import java.net.ServerSocket; import java.net.Socket; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSocket; + /** * Default implementation of {@link TcpSocketSupport}; makes no * changes to sockets. + * * @author Gary Russell + * * @since 2.2 * */ public class DefaultTcpSocketSupport implements TcpSocketSupport { + private final boolean sslVerifyHost; + + /** + * Construct an instance with host verification disabled. + */ + public DefaultTcpSocketSupport() { + this(false); + } + + /** + * Construct an instance with the provided sslVerifyHost. + * @param sslVerifyHost true to verify host during SSL handshake. + * @since 5.0.8. + */ + public DefaultTcpSocketSupport(boolean sslVerifyHost) { + this.sslVerifyHost = sslVerifyHost; + } + /** * No-Op. */ + @Override public void postProcessServerSocket(ServerSocket serverSocket) { } /** - * No-Op. + * Enables host verification for SSL, if so configured. */ + @Override public void postProcessSocket(Socket socket) { + if (this.sslVerifyHost && socket instanceof SSLSocket) { + SSLSocket sslSocket = (SSLSocket) socket; + SSLParameters sslParameters = sslSocket.getSSLParameters(); + if (sslParameters == null) { + sslParameters = new SSLParameters(); + } + // HTTPS works for any TCP connection. + // It checks SAN (Subject Alternative Name) as well as CN. + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslSocket.setSSLParameters(sslParameters); + } } } diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml b/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml index 7a38a45b42..993735276d 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml @@ -81,7 +81,9 @@ + class="org.springframework.integration.ip.tcp.connection.DefaultTcpNioSSLConnectionSupport"> + + - (RETURN if same as keystore password): + Enter key password for + (RETURN if same as keystore password): -$ keytool -list -v -keystore src/test/resources/test.ks -Enter keystore password: secret + $ keytool -list -v -keystore src/test/resources/test.ks + Enter keystore password: secret -Keystore type: JKS -Keystore provider: SUN + Keystore type: JKS + Keystore provider: SUN -Your keystore contains 1 entry + Your keystore contains 1 entry -Alias name: sitestcertkey -Creation date: Feb 25, 2012 -Entry type: PrivateKeyEntry -Certificate chain length: 1 -Certificate[1]: -Owner: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Issuer: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Serial number: 4f491902 -Valid from: Sat Feb 25 12:23:14 EST 2012 until: Mon Feb 01 12:23:14 EST 2112 -Certificate fingerprints: - MD5: 4F:A9:76:0E:A9:C0:A8:B7:26:E7:7E:C7:E8:22:1F:8B - SHA1: 88:AC:9E:4D:29:0D:3A:59:3B:73:95:4A:E1:BB:D0:22:89:37:64:4C - Signature algorithm name: SHA1withRSA - Version: 3 + Alias name: sitestcertkey + Creation date: Aug 29, 2018 + Entry type: PrivateKeyEntry + Certificate chain length: 1 + Certificate[1]: + Owner: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Issuer: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Serial number: 3f2ab6ef + Valid from: Wed Aug 29 14:58:27 EDT 2018 until: Fri Aug 05 14:58:27 EDT 2118 + Certificate fingerprints: + MD5: 74:14:93:3C:6E:7B:14:59:30:A3:90:C4:A2:AD:52:5E + SHA1: 12:BE:77:93:ED:C3:20:23:75:D7:D5:D9:FE:D9:5E:D1:D3:3E:E2:DC + SHA256: 6B:90:65:8D:AA:F6:F3:89:38:AE:92:8E:F0:83:26:17:DD:8A:2C:F6:7E:C5:39:F0:7E:DC:60:A3:6D:73:E1:7A + Signature algorithm name: SHA256withRSA + Subject Public Key Algorithm: 2048-bit RSA key + Version: 3 + + Extensions: + + #1: ObjectId: 2.5.29.17 Criticality=false + SubjectAlternativeName [ + DNSName: localhost + ] + + #2: ObjectId: 2.5.29.14 Criticality=false + SubjectKeyIdentifier [ + KeyIdentifier [ + 0000: 78 2D FA 48 D8 21 73 86 68 CE 77 B9 98 5A BA 0F x-.H.!s.h.w..Z.. + 0010: E2 FE CD 8C .... + ] + ] -******************************************* -******************************************* -$ keytool -export -alias sitestcertkey -keystore src/test/resources/test.ks -rfc -file src/test/resources/test.cer -Enter keystore password: -Certificate stored in file - -$ keytool -import -alias sitestcertkey -file src/test/resources/test.cer -keystore src/test/resources/test.truststore.ks -Enter keystore password: secret -Re-enter new password: secret -Owner: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Issuer: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Serial number: 4f491902 -Valid from: Sat Feb 25 12:23:14 EST 2012 until: Mon Feb 01 12:23:14 EST 2112 -Certificate fingerprints: - MD5: 4F:A9:76:0E:A9:C0:A8:B7:26:E7:7E:C7:E8:22:1F:8B - SHA1: 88:AC:9E:4D:29:0D:3A:59:3B:73:95:4A:E1:BB:D0:22:89:37:64:4C - Signature algorithm name: SHA1withRSA - Version: 3 -Trust this certificate? [no]: yes -Certificate was added to keystore - -$ keytool -list -v -keystore src/test/resources/test.truststore.ks -Enter keystore password: secret - -Keystore type: JKS -Keystore provider: SUN - -Your keystore contains 1 entry - -Alias name: sitestcertkey -Creation date: Feb 25, 2012 -Entry type: trustedCertEntry - -Owner: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Issuer: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Serial number: 4f491902 -Valid from: Sat Feb 25 12:23:14 EST 2012 until: Mon Feb 01 12:23:14 EST 2112 -Certificate fingerprints: - MD5: 4F:A9:76:0E:A9:C0:A8:B7:26:E7:7E:C7:E8:22:1F:8B - SHA1: 88:AC:9E:4D:29:0D:3A:59:3B:73:95:4A:E1:BB:D0:22:89:37:64:4C - Signature algorithm name: SHA1withRSA - Version: 3 + ******************************************* + ******************************************* -******************************************* -******************************************* + $ keytool -export -alias sitestcertkey -keystore src/test/resources/test.ks -rfc -file src/test/resources/test.cer + Enter keystore password: + Certificate stored in file - */ + $ keytool -import -alias sitestcertkey -file src/test/resources/test.cer -keystore src/test/resources/test.truststore.ks + Enter keystore password: secret + Re-enter new password: secret + Owner: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Issuer: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Serial number: 3f2ab6ef + Valid from: Wed Aug 29 14:58:27 EDT 2018 until: Fri Aug 05 14:58:27 EDT 2118 + Certificate fingerprints: + MD5: 74:14:93:3C:6E:7B:14:59:30:A3:90:C4:A2:AD:52:5E + SHA1: 12:BE:77:93:ED:C3:20:23:75:D7:D5:D9:FE:D9:5E:D1:D3:3E:E2:DC + SHA256: 6B:90:65:8D:AA:F6:F3:89:38:AE:92:8E:F0:83:26:17:DD:8A:2C:F6:7E:C5:39:F0:7E:DC:60:A3:6D:73:E1:7A + Signature algorithm name: SHA256withRSA + Subject Public Key Algorithm: 2048-bit RSA key + Version: 3 + + Extensions: + + #1: ObjectId: 2.5.29.17 Criticality=false + SubjectAlternativeName [ + DNSName: localhost + ] + + #2: ObjectId: 2.5.29.14 Criticality=false + SubjectKeyIdentifier [ + KeyIdentifier [ + 0000: 78 2D FA 48 D8 21 73 86 68 CE 77 B9 98 5A BA 0F x-.H.!s.h.w..Z.. + 0010: E2 FE CD 8C .... + ] + ] + + Trust this certificate? [no]: yes + Certificate was added to keystore + + $ keytool -list -v -keystore src/test/resources/test.truststore.ks + Enter keystore password: secret + + Keystore type: JKS + Keystore provider: SUN + + Your keystore contains 1 entry + + Alias name: sitestcertkey + Creation date: Aug 29, 2018 + Entry type: trustedCertEntry + + Owner: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Issuer: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Serial number: 3f2ab6ef + Valid from: Wed Aug 29 14:58:27 EDT 2018 until: Fri Aug 05 14:58:27 EDT 2118 + Certificate fingerprints: + MD5: 74:14:93:3C:6E:7B:14:59:30:A3:90:C4:A2:AD:52:5E + SHA1: 12:BE:77:93:ED:C3:20:23:75:D7:D5:D9:FE:D9:5E:D1:D3:3E:E2:DC + SHA256: 6B:90:65:8D:AA:F6:F3:89:38:AE:92:8E:F0:83:26:17:DD:8A:2C:F6:7E:C5:39:F0:7E:DC:60:A3:6D:73:E1:7A + Signature algorithm name: SHA256withRSA + Subject Public Key Algorithm: 2048-bit RSA key + Version: 3 + + Extensions: + + #1: ObjectId: 2.5.29.17 Criticality=false + SubjectAlternativeName [ + DNSName: localhost + ] + + #2: ObjectId: 2.5.29.14 Criticality=false + SubjectKeyIdentifier [ + KeyIdentifier [ + 0000: 78 2D FA 48 D8 21 73 86 68 CE 77 B9 98 5A BA 0F x-.H.!s.h.w..Z.. + 0010: E2 FE CD 8C .... + ] + ] + + + + ******************************************* + ******************************************* + */ @Test public void testNetClientAndServerSSL() throws Exception { System.setProperty("javax.net.debug", "all"); // SSL activity in the console @@ -299,6 +353,7 @@ Certificate fingerprints: TcpNetClientConnectionFactory client = new TcpNetClientConnectionFactory("localhost", server.getPort()); client.setTcpSocketFactorySupport(tcpSocketFactorySupport); + client.setTcpSocketSupport(new DefaultTcpSocketSupport(true)); client.start(); TcpConnection connection = client.getConnection(); @@ -402,7 +457,8 @@ Certificate fingerprints: client.setSslHandshakeTimeout(34); client.setTcpNioConnectionSupport(tcpNioConnectionSupport); client.registerListener(message -> false); - client.setApplicationEventPublisher(e -> { }); + client.setApplicationEventPublisher(e -> { + }); client.start(); TcpConnection connection = client.getConnection(); @@ -533,7 +589,8 @@ Certificate fingerprints: return false; }); client.setDeserializer(deserializer); - client.setApplicationEventPublisher(e -> { }); + client.setApplicationEventPublisher(e -> { + }); client.start(); TcpConnection connection = client.getConnection(); diff --git a/spring-integration-ip/src/test/resources/test.cer b/spring-integration-ip/src/test/resources/test.cer index e46e6ae864..faebc34c6b 100644 --- a/spring-integration-ip/src/test/resources/test.cer +++ b/spring-integration-ip/src/test/resources/test.cer @@ -1,13 +1,22 @@ -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/spring-integration-ip/src/test/resources/test.ks b/spring-integration-ip/src/test/resources/test.ks index 243b3d0244aa7df52bda5e82e727f6b15eef7d20..235a45c49988798a61d9ddaf69f40d2cd2cf0fac 100644 GIT binary patch literal 2316 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 diff --git a/spring-integration-ip/src/test/resources/test.truststore.ks b/spring-integration-ip/src/test/resources/test.truststore.ks index 24ead4bc6dd844adfa16f76f4d17d08bacce6300..f60c4cd5c452ef2167b5e047206cb6be6eb552fd 100644 GIT binary patch literal 1027 zcmezO_TO6u1_mY|W(3o`#hE3k#U;t9MJ3s(l|a$dcI8hV46G4)rUsS_49t5CnwWPQ zG%+n)z|6$R#KdB+we7tDFB_*;n@8JsUPeZ4RtAH{219NGPB!LH7B*p~&|nycLzv0g z(NN4l1SG>Q%p07Tr{GqUn3tScoSbhcXCMO-=MokT$Slh*Nz73Q&QB{TPb^AR@XSlr zGvo)_0+i<#W(zJT%FIhQls1qA2`~!_K?H!xN>bB{5=%1k^9&Tkc?~TLEQ~A-Ele$p z%%ddujSN8o2BuJf!QjXyMkVB+V`ODuZerwTFlb`rVrpV!WSD%KBsA$<3TO>L=@MHgE72)}fXFC>GEPv*8F7T*dUH#Ks6{%?x5 z@loc=z8P#NsF$a<#NuDO-I}$g#zqmx?mqnM8T;|&Z<~Lo*Eqav>R+EIx2!&L;^JwJ zvkv*p{QB+OmAI`>TRdKzKGSh8>X)}Whe_u17R4lkyXPbSuY6$;I#o?pbd#X{WQU_0 z*CbunIMp#xZ1TMm$|03<*K7Z6c;V?3G&zVd;f{Zuf?9I%6jk?sZ|4-|Oe+v)VrFDu zTx@P&3QjVzf-JlS+)bQ0`N@en8TrK}2C~5Tm*ry-V-cy){pE2(vA8YcT=~u!QM>pb z{X5%(9JIhx2@G0B2BB7sP^ll&_Gj?!*|xf#^Qbb*N^{A>TNbXYSG?rbd0+uk-3w8b zwpfn!D?UDw2nt`N_=(%{D@%RYWvlWPLK}FED?Y4HYdLP%`S)324)g1UlL{=VgI06x z$@zMsF*NSfb|K-JhWyi+K2)(AzHd3==k3ql8Sa;HJv&$Vdb#_X$yWu;wc3^%MD$G- zo|50GGkxLJxiO7lMO&6CN8Q&J)vAv@v+8S=3-#it6txsd&m?<YW;3>rI`8XFnTEtFfiqeo-ofg4=sXEGi;I(tX}k$|$IgClyR4a* z85tOnod=9OW}v%rHTl*~n)&ru*F&R3l@I@46zsA66j&&3(IW2iyjA>xOxV|u#C2xg z-Z%52c3xfi>s9AG+n@)UKI?aC$F?z^T#}M>@{G+b;{`vTUfrdlcVp^A0cXLp7qXAp zt>8QMcE`t0T5DHpJy?20V)sM++M=nVHx-W`SsWL>G>4;YQ(shX4{MM7#`y`mPNw~y Q6lG#+x^TZZpI`4m0LCWfF#rGn diff --git a/src/reference/asciidoc/ip.adoc b/src/reference/asciidoc/ip.adoc index ac714e46f6..400199ffcc 100644 --- a/src/reference/asciidoc/ip.adoc +++ b/src/reference/asciidoc/ip.adoc @@ -655,7 +655,7 @@ For both inbound and outbound, if the adapter is started, you may force the adap The inbound TCP gateway `TcpInboundGateway` and outbound TCP gateway `TcpOutboundGateway` use a server and client connection factory respectively. Each connection can process a single request/response at a time. -The inbound gateway, after constructing a message with the incoming payload and sending it to the requestChannel, waits for a response and sends the payload from the response message by writing it to the connection. +The inbound gateway, after constructing a message with the incoming payload and sending it to the `requestChannel`, waits for a response and sends the payload from the response message by writing it to the connection. NOTE: For the inbound gateway, care must be taken to retain, or populate, the _ip_connectionId_ header because it is used to correlate the message to a connection. Messages that originate at the gateway will automatically have the header set. @@ -1014,6 +1014,45 @@ The keystore file names (first two constructor arguments) use the Spring `Resour Starting with _version 4.3.6_, when using NIO, you can specify an `ssl-handshake-timeout` (seconds) on the connection factory. This timeout (default 30) is used during SSL handshake when waiting for data; if the timeout is exceeded, the process is aborted and the socket closed. +[[tcp-ssl-host-verification]] +==== Host Verification + +Starting with version 5.0.8, you can configure whether or not to enable host verification. +Starting with version 5.1, it will be enabled by default; before that version, the mechanism to enable it depends on whether or not you are using NIO. + +Host verification is used to ensure the server you are connected to matches information in the certificate, even if the certificate is trusted. + +When using NIO, configure the `DefaultTcpNioSSLConnectionSupport`, for example. + +==== +[source, java] +---- +@Bean +public DefaultTcpNioSSLConnectionSupport connectionSupport() { + DefaultTcpSSLContextSupport sslContextSupport = new DefaultTcpSSLContextSupport("test.ks", + "test.truststore.ks", "secret", "secret"); + sslContextSupport.setProtocol("SSL"); + DefaultTcpNioSSLConnectionSupport tcpNioConnectionSupport = + new DefaultTcpNioSSLConnectionSupport(sslContextSupport, true); + return tcpNioConnectionSupport; +} +---- +==== + +The second constructor argument enables host verification. +The `connectionSupport` bean is then injected into the NIO connection factory. + +When not using NIO, the configuration is in the `TcpSocketSupport`: + +==== +[source, java] +---- +connectionFactory.setTcpSocketSupport(new DefaultTcpSocketSupport(true)); +---- +==== + +Again, the constructor argument enables host verification. + [[tcp-advanced-techniques]] === Advanced Techniques diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc index fe0a8b848c..e879a115f0 100644 --- a/src/reference/asciidoc/whats-new.adoc +++ b/src/reference/asciidoc/whats-new.adoc @@ -314,6 +314,14 @@ See <> for more information. IMPORTANT: Changes were made to the Micrometer `Meters` in _version 5.0.3_ to make them more suitable for use in dimensional systems. Further changes were made in 5.0.4; if using Micrometer, a minimum of version 5.0.4 is recommended. +[[x51.-tcp]] +=== TCP Support + +When using SSL, host verification can be configured, to prevent man-in-the-middle attacks with a trusted certificate. +See <> for more information. + +In addition the key and trust store types can now be configured on the `DefaultTcpSSLContextSupport`. + ==== @EndpointId Annotations @@ -325,4 +333,3 @@ See <> for more information. Starting with _version 5.0.5_, generated bean names for the components in an `IntegrationFlow` include the flow bean name, followed by a dot, as a prefix. See <> for more information. -