Switching strategy for SSL detection to try to initialize a Client SslHandler

This commit is contained in:
Viktor Klang 2012-06-18 14:55:49 +02:00
parent da5862ab6f
commit ceb7d1515a
2 changed files with 40 additions and 38 deletions

View file

@ -53,8 +53,23 @@ private[akka] object NettySSLSupport {
rng rng
} }
private def initializeClientSSL(settings: NettySettings, log: LoggingAdapter): SslHandler = { def initializeClientSSL(settings: NettySettings, log: LoggingAdapter): SslHandler = {
log.debug("Client SSL is enabled, initialising ...") log.debug("Client SSL is enabled, initialising ...")
def constructClientContext(settings: NettySettings, log: LoggingAdapter, trustStorePath: String, trustStorePassword: String, protocol: String): Option[SSLContext] =
try {
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
val trustStore = KeyStore.getInstance(KeyStore.getDefaultType)
trustStore.load(new FileInputStream(trustStorePath), trustStorePassword.toCharArray) //FIXME does the FileInputStream need to be closed?
trustManagerFactory.init(trustStore)
val trustManagers: Array[TrustManager] = trustManagerFactory.getTrustManagers
Option(SSLContext.getInstance(protocol)) map { ctx ctx.init(null, trustManagers, initializeCustomSecureRandom(settings.SSLRandomNumberGenerator, settings.SSLRandomSource, log)); ctx }
} catch {
case e: FileNotFoundException throw new RemoteTransportException("Client SSL connection could not be established because trust store could not be loaded", e)
case e: IOException throw new RemoteTransportException("Client SSL connection could not be established because: " + e.getMessage, e)
case e: GeneralSecurityException throw new RemoteTransportException("Client SSL connection could not be established because SSL context could not be constructed", e)
}
((settings.SSLTrustStore, settings.SSLTrustStorePassword, settings.SSLProtocol) match { ((settings.SSLTrustStore, settings.SSLTrustStorePassword, settings.SSLProtocol) match {
case (Some(trustStore), Some(password), Some(protocol)) constructClientContext(settings, log, trustStore, password, protocol) case (Some(trustStore), Some(password), Some(protocol)) constructClientContext(settings, log, trustStore, password, protocol)
case (trustStore, password, protocol) throw new GeneralSecurityException( case (trustStore, password, protocol) throw new GeneralSecurityException(
@ -79,24 +94,22 @@ private[akka] object NettySSLSupport {
} }
} }
private def constructClientContext(settings: NettySettings, log: LoggingAdapter, trustStorePath: String, trustStorePassword: String, protocol: String): Option[SSLContext] = { def initializeServerSSL(settings: NettySettings, log: LoggingAdapter): SslHandler = {
try {
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
val trustStore = KeyStore.getInstance(KeyStore.getDefaultType)
trustStore.load(new FileInputStream(trustStorePath), trustStorePassword.toCharArray) //FIXME does the FileInputStream need to be closed?
trustManagerFactory.init(trustStore)
val trustManagers: Array[TrustManager] = trustManagerFactory.getTrustManagers
Option(SSLContext.getInstance(protocol)) map { ctx ctx.init(null, trustManagers, initializeCustomSecureRandom(settings.SSLRandomNumberGenerator, settings.SSLRandomSource, log)); ctx }
} catch {
case e: FileNotFoundException throw new RemoteTransportException("Client SSL connection could not be established because trust store could not be loaded", e)
case e: IOException throw new RemoteTransportException("Client SSL connection could not be established because: " + e.getMessage, e)
case e: GeneralSecurityException throw new RemoteTransportException("Client SSL connection could not be established because SSL context could not be constructed", e)
}
}
private def initializeServerSSL(settings: NettySettings, log: LoggingAdapter): SslHandler = {
log.debug("Server SSL is enabled, initialising ...") log.debug("Server SSL is enabled, initialising ...")
def constructServerContext(settings: NettySettings, log: LoggingAdapter, keyStorePath: String, keyStorePassword: String, protocol: String): Option[SSLContext] =
try {
val factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType)
keyStore.load(new FileInputStream(keyStorePath), keyStorePassword.toCharArray) //FIXME does the FileInputStream need to be closed?
factory.init(keyStore, keyStorePassword.toCharArray)
Option(SSLContext.getInstance(protocol)) map { ctx ctx.init(factory.getKeyManagers, null, initializeCustomSecureRandom(settings.SSLRandomNumberGenerator, settings.SSLRandomSource, log)); ctx }
} catch {
case e: FileNotFoundException throw new RemoteTransportException("Server SSL connection could not be established because key store could not be loaded", e)
case e: IOException throw new RemoteTransportException("Server SSL connection could not be established because: " + e.getMessage, e)
case e: GeneralSecurityException throw new RemoteTransportException("Server SSL connection could not be established because SSL context could not be constructed", e)
}
((settings.SSLKeyStore, settings.SSLKeyStorePassword, settings.SSLProtocol) match { ((settings.SSLKeyStore, settings.SSLKeyStorePassword, settings.SSLProtocol) match {
case (Some(keyStore), Some(password), Some(protocol)) constructServerContext(settings, log, keyStore, password, protocol) case (Some(keyStore), Some(password), Some(protocol)) constructServerContext(settings, log, keyStore, password, protocol)
case (keyStore, password, protocol) throw new GeneralSecurityException( case (keyStore, password, protocol) throw new GeneralSecurityException(
@ -116,18 +129,4 @@ private[akka] object NettySSLSupport {
settings.SSLProtocol)) settings.SSLProtocol))
} }
} }
private def constructServerContext(settings: NettySettings, log: LoggingAdapter, keyStorePath: String, keyStorePassword: String, protocol: String): Option[SSLContext] = {
try {
val factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
val keyStore = KeyStore.getInstance(KeyStore.getDefaultType)
keyStore.load(new FileInputStream(keyStorePath), keyStorePassword.toCharArray) //FIXME does the FileInputStream need to be closed?
factory.init(keyStore, keyStorePassword.toCharArray)
Option(SSLContext.getInstance(protocol)) map { ctx ctx.init(factory.getKeyManagers, null, initializeCustomSecureRandom(settings.SSLRandomNumberGenerator, settings.SSLRandomSource, log)); ctx }
} catch {
case e: FileNotFoundException throw new RemoteTransportException("Server SSL connection could not be established because key store could not be loaded", e)
case e: IOException throw new RemoteTransportException("Server SSL connection could not be established because: " + e.getMessage, e)
case e: GeneralSecurityException throw new RemoteTransportException("Server SSL connection could not be established because SSL context could not be constructed", e)
}
}
} }

View file

@ -9,9 +9,9 @@ import com.typesafe.config._
import akka.dispatch.{ Await, Future } import akka.dispatch.{ Await, Future }
import akka.pattern.ask import akka.pattern.ask
import java.io.File import java.io.File
import java.security.{ SecureRandom, PrivilegedAction, AccessController }
import netty.NettySSLSupport
import akka.event.{ NoLogging, LoggingAdapter } import akka.event.{ NoLogging, LoggingAdapter }
import java.security.{ NoSuchAlgorithmException, SecureRandom, PrivilegedAction, AccessController }
import netty.{ NettySettings, NettySSLSupport }
object Configuration { object Configuration {
// set this in your JAVA_OPTS to see all ssl debug info: "-Djavax.net.debug=ssl,keymanager" // set this in your JAVA_OPTS to see all ssl debug info: "-Djavax.net.debug=ssl,keymanager"
@ -42,12 +42,15 @@ object Configuration {
} }
""" """
def getCipherConfig(cipher: String, enabled: String*): (String, Boolean, Config) = if (try { def getCipherConfig(cipher: String, enabled: String*): (String, Boolean, Config) = try {
NettySSLSupport.initializeCustomSecureRandom(Some(cipher), None, NoLogging) ne null //NettySSLSupport.initializeCustomSecureRandom(Some(cipher), None, NoLogging) ne null
val config = ConfigFactory.parseString(conf.format(trustStore, keyStore, cipher, enabled.mkString(", ")))
val settings = new NettySettings(config.withFallback(AkkaSpec.testConf).withFallback(ConfigFactory.load).getConfig("akka.remote.netty"), "pigdog")
(NettySSLSupport.initializeClientSSL(settings, NoLogging) ne null) || (throw new NoSuchAlgorithmException(cipher))
(cipher, true, config)
} catch { } catch {
case _: IllegalArgumentException false // Cannot match against the message since the message might be localized :S case (_: IllegalArgumentException) | (_: NoSuchAlgorithmException) (cipher, false, AkkaSpec.testConf) // Cannot match against the message since the message might be localized :S
case _: java.security.NoSuchAlgorithmException false }
}) (cipher, true, ConfigFactory.parseString(conf.format(trustStore, keyStore, cipher, enabled.mkString(", ")))) else (cipher, false, AkkaSpec.testConf)
} }
import Configuration.getCipherConfig import Configuration.getCipherConfig