mirror of
https://github.com/corda/corda.git
synced 2025-06-20 08:03:53 +00:00
CORDA-2001: added SNI header to TLS connections based on hashed CordaX500 (#3968)
* CORDA-2001: added SNI header to TLS connections based on hashed CordaX500 * CORDA-2001: added newline * CORDA-2001: truncate hashed x500 to pass IDN validations * CORDA-2001: convert hostname to lower case * CORDA-2001: to lower after truncating, use of better suited method * CORDA-2001: to lower after truncating, use of better suited method * CORDA-2001: correctly set ssl parameters in the engine
This commit is contained in:
@ -123,7 +123,7 @@ class AMQPClient(val targets: List<NetworkHostAndPort>,
|
|||||||
override fun initChannel(ch: SocketChannel) {
|
override fun initChannel(ch: SocketChannel) {
|
||||||
val pipeline = ch.pipeline()
|
val pipeline = ch.pipeline()
|
||||||
val target = parent.currentTarget
|
val target = parent.currentTarget
|
||||||
val handler = createClientSslHelper(target, keyManagerFactory, trustManagerFactory)
|
val handler = createClientSslHelper(target, parent.allowedRemoteLegalNames, keyManagerFactory, trustManagerFactory)
|
||||||
pipeline.addLast("sslHandler", handler)
|
pipeline.addLast("sslHandler", handler)
|
||||||
if (conf.trace) pipeline.addLast("logger", LoggingHandler(LogLevel.INFO))
|
if (conf.trace) pipeline.addLast("logger", LoggingHandler(LogLevel.INFO))
|
||||||
pipeline.addLast(AMQPChannelHandler(false,
|
pipeline.addLast(AMQPChannelHandler(false,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package net.corda.nodeapi.internal.protonwrapper.netty
|
package net.corda.nodeapi.internal.protonwrapper.netty
|
||||||
|
|
||||||
import io.netty.handler.ssl.SslHandler
|
import io.netty.handler.ssl.SslHandler
|
||||||
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.newSecureRandom
|
import net.corda.core.crypto.newSecureRandom
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.toHex
|
import net.corda.core.utilities.toHex
|
||||||
@ -16,6 +18,8 @@ import java.security.cert.*
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.net.ssl.*
|
import javax.net.ssl.*
|
||||||
|
|
||||||
|
private const val HOSTNAME_FORMAT = "%s.corda.net"
|
||||||
|
|
||||||
internal class LoggingTrustManagerWrapper(val wrapped: X509ExtendedTrustManager) : X509ExtendedTrustManager() {
|
internal class LoggingTrustManagerWrapper(val wrapped: X509ExtendedTrustManager) : X509ExtendedTrustManager() {
|
||||||
companion object {
|
companion object {
|
||||||
val log = contextLogger()
|
val log = contextLogger()
|
||||||
@ -102,6 +106,7 @@ internal class LoggingTrustManagerWrapper(val wrapped: X509ExtendedTrustManager)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun createClientSslHelper(target: NetworkHostAndPort,
|
internal fun createClientSslHelper(target: NetworkHostAndPort,
|
||||||
|
expectedRemoteLegalNames: Set<CordaX500Name>,
|
||||||
keyManagerFactory: KeyManagerFactory,
|
keyManagerFactory: KeyManagerFactory,
|
||||||
trustManagerFactory: TrustManagerFactory): SslHandler {
|
trustManagerFactory: TrustManagerFactory): SslHandler {
|
||||||
val sslContext = SSLContext.getInstance("TLS")
|
val sslContext = SSLContext.getInstance("TLS")
|
||||||
@ -113,6 +118,11 @@ internal fun createClientSslHelper(target: NetworkHostAndPort,
|
|||||||
sslEngine.enabledProtocols = ArtemisTcpTransport.TLS_VERSIONS.toTypedArray()
|
sslEngine.enabledProtocols = ArtemisTcpTransport.TLS_VERSIONS.toTypedArray()
|
||||||
sslEngine.enabledCipherSuites = ArtemisTcpTransport.CIPHER_SUITES.toTypedArray()
|
sslEngine.enabledCipherSuites = ArtemisTcpTransport.CIPHER_SUITES.toTypedArray()
|
||||||
sslEngine.enableSessionCreation = true
|
sslEngine.enableSessionCreation = true
|
||||||
|
if (expectedRemoteLegalNames.size == 1) {
|
||||||
|
val sslParameters = sslEngine.sslParameters
|
||||||
|
sslParameters.serverNames = listOf(SNIHostName(x500toHostName(expectedRemoteLegalNames.single())))
|
||||||
|
sslEngine.sslParameters = sslParameters
|
||||||
|
}
|
||||||
return SslHandler(sslEngine)
|
return SslHandler(sslEngine)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,3 +162,10 @@ internal fun initialiseTrustStoreAndEnableCrlChecking(trustStore: CertificateSto
|
|||||||
fun KeyManagerFactory.init(keyStore: CertificateStore) = init(keyStore.value.internal, keyStore.password.toCharArray())
|
fun KeyManagerFactory.init(keyStore: CertificateStore) = init(keyStore.value.internal, keyStore.password.toCharArray())
|
||||||
|
|
||||||
fun TrustManagerFactory.init(trustStore: CertificateStore) = init(trustStore.value.internal)
|
fun TrustManagerFactory.init(trustStore: CertificateStore) = init(trustStore.value.internal)
|
||||||
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user