From 2a522c9f05db9221cbf0087017af1e3473517ca7 Mon Sep 17 00:00:00 2001 From: bpaunescu Date: Fri, 21 Sep 2018 10:15:40 +0100 Subject: [PATCH] CORDA-2001 - SNI header for future inter-op (#3977) --- .../internal/protonwrapper/netty/AMQPClient.kt | 2 +- .../internal/protonwrapper/netty/SSLHelper.kt | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt index 7e8a8853f7..0fadcdda4d 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/AMQPClient.kt @@ -107,7 +107,7 @@ class AMQPClient(val targets: List, override fun initChannel(ch: SocketChannel) { val pipeline = ch.pipeline() - val handler = createClientSslHelper(parent.currentTarget, keyManagerFactory, trustManagerFactory) + val handler = createClientSslHelper(parent.currentTarget, parent.allowedRemoteLegalNames, keyManagerFactory, trustManagerFactory) pipeline.addLast("sslHandler", handler) if (parent.trace) pipeline.addLast("logger", LoggingHandler(LogLevel.INFO)) pipeline.addLast(AMQPChannelHandler(false, diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/SSLHelper.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/SSLHelper.kt index bf1be88377..df8b03744b 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/SSLHelper.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/protonwrapper/netty/SSLHelper.kt @@ -1,14 +1,20 @@ package net.corda.nodeapi.internal.protonwrapper.netty import io.netty.handler.ssl.SslHandler +import net.corda.core.crypto.SecureHash +import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.NetworkHostAndPort import net.corda.nodeapi.ArtemisTcpTransport import java.security.SecureRandom import javax.net.ssl.KeyManagerFactory +import javax.net.ssl.SNIHostName import javax.net.ssl.SSLContext import javax.net.ssl.TrustManagerFactory +private const val HOSTNAME_FORMAT = "%s.corda.net" + internal fun createClientSslHelper(target: NetworkHostAndPort, + expectedRemoteLegalNames: Set, keyManagerFactory: KeyManagerFactory, trustManagerFactory: TrustManagerFactory): SslHandler { val sslContext = SSLContext.getInstance("TLS") @@ -20,6 +26,11 @@ internal fun createClientSslHelper(target: NetworkHostAndPort, sslEngine.enabledProtocols = ArtemisTcpTransport.TLS_VERSIONS.toTypedArray() sslEngine.enabledCipherSuites = ArtemisTcpTransport.CIPHER_SUITES.toTypedArray() sslEngine.enableSessionCreation = true + if (expectedRemoteLegalNames.size == 1) { + val sslParameters = sslEngine.sslParameters + sslParameters.serverNames = listOf(SNIHostName(x500toHostName(expectedRemoteLegalNames.single()))) + sslEngine.sslParameters = sslParameters + } return SslHandler(sslEngine) } @@ -36,4 +47,11 @@ internal fun createServerSslHelper(keyManagerFactory: KeyManagerFactory, sslEngine.enabledCipherSuites = ArtemisTcpTransport.CIPHER_SUITES.toTypedArray() sslEngine.enableSessionCreation = true return SslHandler(sslEngine) +} + +internal fun x500toHostName(x500Name: CordaX500Name): String { + val secureHash = SecureHash.sha256(x500Name.toString()) + // RFC 1035 specifies a limit 255 bytes for hostnames with each label being 63 bytes or less. Due to this, the string + // representation of the SHA256 hash is truncated to 32 characters. + return String.format(HOSTNAME_FORMAT, secureHash.toString().substring(0..32).toLowerCase()) } \ No newline at end of file