ENT-11118: Netty SSL handshake fix (#5028)

* ENT-11118: Added fix for netty SSL handshake fail
This commit is contained in:
Tom Stark 2023-12-15 16:24:11 +00:00 committed by tomstark99
parent bf6fcb2a8f
commit 71e187dddb

View File

@ -4,13 +4,19 @@ import io.netty.handler.ssl.SslContext
import io.netty.handler.ssl.SslContextBuilder
import io.netty.handler.ssl.SslProvider
import net.corda.nodeapi.internal.ArtemisTcpTransport.Companion.TRUST_MANAGER_FACTORY_NAME
import net.corda.nodeapi.internal.config.CertificateStore
import net.corda.nodeapi.internal.protonwrapper.netty.createAndInitSslContext
import net.corda.nodeapi.internal.protonwrapper.netty.keyManagerFactory
import org.apache.activemq.artemis.core.remoting.impl.ssl.DefaultOpenSSLContextFactory
import org.apache.activemq.artemis.core.remoting.impl.ssl.DefaultSSLContextFactory
import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig
import java.nio.file.Paths
import org.apache.activemq.artemis.utils.ClassloadingUtil
import org.apache.commons.io.IOUtils
import java.io.File
import java.io.InputStream
import java.net.MalformedURLException
import java.net.URL
import java.security.AccessController
import java.security.KeyStore
import java.security.PrivilegedAction
import javax.net.ssl.KeyManagerFactory
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManagerFactory
@ -54,6 +60,69 @@ class NodeOpenSSLContextFactory : DefaultOpenSSLContextFactory() {
private fun loadKeyManagerFactory(config: SSLContextConfig): KeyManagerFactory {
val keyStore = CertificateStore.fromFile(Paths.get(config.keystorePath), config.keystorePassword, config.keystorePassword, false)
return keyManagerFactory(keyStore)
val keyStore = loadKeystore(config.keystoreProvider, config.keystoreType, config.keystorePath, config.keystorePassword)
val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
keyManagerFactory.init(keyStore, config.keystorePassword?.toCharArray())
return keyManagerFactory
}
/**
* This is a copy of [SSLSupport.loadKeystore] so that we can use the [NodeSSLContextFactory] and
* maintain keystore loading with the correct [keystoreProvider].
*/
private fun loadKeystore(
keystoreProvider: String?,
keystoreType: String,
keystorePath: String?,
keystorePassword: String?
) : KeyStore {
val keyStore = keystoreProvider?.let { KeyStore.getInstance(keystoreType, it) } ?: KeyStore.getInstance(keystoreType)
var inputStream : InputStream? = null
try {
if (keystorePath != null && keystorePath.isNotEmpty()) {
val keystoreURL = validateStoreURL(keystorePath)
inputStream = keystoreURL.openStream()
}
keyStore.load(inputStream, keystorePassword?.toCharArray())
} finally {
inputStream?.closeQuietly()
}
return keyStore
}
/**
* This is a copy of [SSLSupport.validateStoreURL] so we can have a full copy of
* [SSLSupport.loadKeystore].
*/
private fun validateStoreURL(storePath: String): URL {
return try {
URL(storePath)
} catch (e: MalformedURLException) {
val file = File(storePath)
if (file.exists() && file.isFile) {
file.toURI().toURL()
} else {
findResource(storePath)
}
}
}
/**
* This is a copy of [SSLSupport.findResource] so we can have a full copy of
* [SSLSupport.validateStoreURL] and.
*/
private fun findResource(resourceName: String): URL {
return AccessController.doPrivileged(PrivilegedAction {
ClassloadingUtil.findResource(resourceName)
})
}
/**
* This is an inline function for [InputStream] so it can be closed and
* ignore an exception.
*/
private fun InputStream?.closeQuietly() = IOUtils.closeQuietly(this)