I think I nailed it.
This commit is contained in:
parent
e730432cb0
commit
4f3f4aadba
5 changed files with 17 additions and 16 deletions
|
|
@ -193,7 +193,7 @@ akka {
|
||||||
# Examples: [ "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA" ]
|
# Examples: [ "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA" ]
|
||||||
# You need to install the JCE Unlimited Strength Jurisdiction Policy Files to use AES 256
|
# You need to install the JCE Unlimited Strength Jurisdiction Policy Files to use AES 256
|
||||||
# More info here: http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJCEProvider
|
# More info here: http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJCEProvider
|
||||||
supported-algorithms = ["TLS_RSA_WITH_AES_128_CBC_SHA"]
|
enabled-algorithms = ["TLS_RSA_WITH_AES_128_CBC_SHA"]
|
||||||
|
|
||||||
# Using /dev/./urandom is only necessary when using SHA1PRNG on Linux to prevent blocking
|
# Using /dev/./urandom is only necessary when using SHA1PRNG on Linux to prevent blocking
|
||||||
# It is NOT as secure because it reuses the seed
|
# It is NOT as secure because it reuses the seed
|
||||||
|
|
@ -208,7 +208,7 @@ akka {
|
||||||
# The following use one of 3 possible seed sources, depending on availability: /dev/random, random.org and SecureRandom (provided by Java)
|
# The following use one of 3 possible seed sources, depending on availability: /dev/random, random.org and SecureRandom (provided by Java)
|
||||||
# "AES128CounterRNGSecure"
|
# "AES128CounterRNGSecure"
|
||||||
# "AES256CounterRNGSecure" (Install JCE Unlimited Strength Jurisdiction Policy Files first)
|
# "AES256CounterRNGSecure" (Install JCE Unlimited Strength Jurisdiction Policy Files first)
|
||||||
# Setting a value here may require you to supply the appropriate cipher suite (see supported-algorithms section above)
|
# Setting a value here may require you to supply the appropriate cipher suite (see enabled-algorithms section above)
|
||||||
random-number-generator = ""
|
random-number-generator = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ import akka.security.provider.AkkaProvider
|
||||||
* Internal use only
|
* Internal use only
|
||||||
*/
|
*/
|
||||||
private[akka] object NettySSLSupport {
|
private[akka] object NettySSLSupport {
|
||||||
|
|
||||||
|
val akka = new AkkaProvider
|
||||||
|
Security.addProvider(akka)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a SSLHandler which can be inserted into a Netty server/client pipeline
|
* Construct a SSLHandler which can be inserted into a Netty server/client pipeline
|
||||||
*/
|
*/
|
||||||
|
|
@ -34,8 +38,6 @@ private[akka] object NettySSLSupport {
|
||||||
val rng = rngName match {
|
val rng = rngName match {
|
||||||
case Some(r @ ("AES128CounterRNGFast" | "AES128CounterRNGSecure" | "AES256CounterRNGSecure")) ⇒
|
case Some(r @ ("AES128CounterRNGFast" | "AES128CounterRNGSecure" | "AES256CounterRNGSecure")) ⇒
|
||||||
log.debug("SSL random number generator set to: {}", r)
|
log.debug("SSL random number generator set to: {}", r)
|
||||||
val akka = new AkkaProvider
|
|
||||||
Security.addProvider(akka)
|
|
||||||
SecureRandom.getInstance(r, akka)
|
SecureRandom.getInstance(r, akka)
|
||||||
case Some("SHA1PRNG") ⇒
|
case Some("SHA1PRNG") ⇒
|
||||||
log.debug("SSL random number generator set to: SHA1PRNG")
|
log.debug("SSL random number generator set to: SHA1PRNG")
|
||||||
|
|
@ -82,7 +84,7 @@ private[akka] object NettySSLSupport {
|
||||||
log.debug("Using client SSL context to create SSLEngine ...")
|
log.debug("Using client SSL context to create SSLEngine ...")
|
||||||
val sslEngine = context.createSSLEngine
|
val sslEngine = context.createSSLEngine
|
||||||
sslEngine.setUseClientMode(true)
|
sslEngine.setUseClientMode(true)
|
||||||
sslEngine.setEnabledCipherSuites(settings.SSLSupportedAlgorithms.toArray.map(_.toString))
|
sslEngine.setEnabledCipherSuites(settings.SSLEnabledAlgorithms.toArray.map(_.toString))
|
||||||
new SslHandler(sslEngine)
|
new SslHandler(sslEngine)
|
||||||
case None ⇒
|
case None ⇒
|
||||||
throw new GeneralSecurityException(
|
throw new GeneralSecurityException(
|
||||||
|
|
@ -119,7 +121,7 @@ private[akka] object NettySSLSupport {
|
||||||
log.debug("Using server SSL context to create SSLEngine ...")
|
log.debug("Using server SSL context to create SSLEngine ...")
|
||||||
val sslEngine = context.createSSLEngine
|
val sslEngine = context.createSSLEngine
|
||||||
sslEngine.setUseClientMode(false)
|
sslEngine.setUseClientMode(false)
|
||||||
sslEngine.setEnabledCipherSuites(settings.SSLSupportedAlgorithms.toArray.map(_.toString))
|
sslEngine.setEnabledCipherSuites(settings.SSLEnabledAlgorithms.toArray.map(_.toString))
|
||||||
new SslHandler(sslEngine)
|
new SslHandler(sslEngine)
|
||||||
case None ⇒ throw new GeneralSecurityException(
|
case None ⇒ throw new GeneralSecurityException(
|
||||||
"""Failed to initialize server SSL because SSL context could not be found.
|
"""Failed to initialize server SSL because SSL context could not be found.
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ private[akka] class NettySettings(config: Config, val systemName: String) {
|
||||||
case password ⇒ Some(password)
|
case password ⇒ Some(password)
|
||||||
}
|
}
|
||||||
|
|
||||||
val SSLSupportedAlgorithms = getStringList("ssl.supported-algorithms").toArray.toSet
|
val SSLEnabledAlgorithms = getStringList("ssl.enabled-algorithms").toArray.toSet
|
||||||
|
|
||||||
val SSLProtocol = getString("ssl.protocol") match {
|
val SSLProtocol = getString("ssl.protocol") match {
|
||||||
case "" ⇒ None
|
case "" ⇒ None
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ object Configuration {
|
||||||
trust-store = "%s"
|
trust-store = "%s"
|
||||||
key-store = "%s"
|
key-store = "%s"
|
||||||
random-number-generator = "%s"
|
random-number-generator = "%s"
|
||||||
supported-algorithms = [%s]
|
enabled-algorithms = [%s]
|
||||||
sha1prng-random-source = "/dev/./urandom"
|
sha1prng-random-source = "/dev/./urandom"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ object Configuration {
|
||||||
|
|
||||||
def getCipherConfig(cipher: String, enabled: String*): (String, Boolean, Config) = try {
|
def getCipherConfig(cipher: String, enabled: String*): (String, Boolean, Config) = try {
|
||||||
|
|
||||||
if (true) throw new IllegalArgumentException("This is not working properly yet")
|
if (false) throw new IllegalArgumentException("This is not working properly yet")
|
||||||
|
|
||||||
val config = ConfigFactory.parseString("akka.remote.netty.port=12345").withFallback(ConfigFactory.parseString(conf.format(trustStore, keyStore, cipher, enabled.mkString(", "))))
|
val config = ConfigFactory.parseString("akka.remote.netty.port=12345").withFallback(ConfigFactory.parseString(conf.format(trustStore, keyStore, cipher, enabled.mkString(", "))))
|
||||||
val fullConfig = config.withFallback(AkkaSpec.testConf).withFallback(ConfigFactory.load).getConfig("akka.remote.netty")
|
val fullConfig = config.withFallback(AkkaSpec.testConf).withFallback(ConfigFactory.load).getConfig("akka.remote.netty")
|
||||||
|
|
@ -62,16 +62,16 @@ object Configuration {
|
||||||
rng.nextInt() // Has to work
|
rng.nextInt() // Has to work
|
||||||
settings.SSLRandomNumberGenerator foreach { sRng ⇒ rng.getAlgorithm == sRng || (throw new NoSuchAlgorithmException(sRng)) }
|
settings.SSLRandomNumberGenerator foreach { sRng ⇒ rng.getAlgorithm == sRng || (throw new NoSuchAlgorithmException(sRng)) }
|
||||||
|
|
||||||
val engine = NettySSLSupport.initializeServerSSL(settings, NoLogging).getEngine
|
val engine = NettySSLSupport.initializeClientSSL(settings, NoLogging).getEngine
|
||||||
val gotAllSupported = enabled.toSet -- engine.getSupportedCipherSuites.toSet
|
val gotAllSupported = enabled.toSet -- engine.getSupportedCipherSuites.toSet
|
||||||
val gotAllEnabled = enabled.toSet -- engine.getEnabledCipherSuites.toSet
|
val gotAllEnabled = enabled.toSet -- engine.getEnabledCipherSuites.toSet
|
||||||
gotAllSupported.isEmpty || (throw new IllegalArgumentException("Cipher Suite not supported: " + gotAllSupported))
|
gotAllSupported.isEmpty || (throw new IllegalArgumentException("Cipher Suite not supported: " + gotAllSupported))
|
||||||
gotAllEnabled.isEmpty || (throw new IllegalArgumentException("Cipher Suite not enabled: " + gotAllEnabled))
|
gotAllEnabled.isEmpty || (throw new IllegalArgumentException("Cipher Suite not enabled: " + gotAllEnabled))
|
||||||
engine.getSupportedProtocols.contains(settings.SSLProtocol.get) || (throw new IllegalArgumentException(settings.SSLProtocol.get))
|
engine.getSupportedProtocols.contains(settings.SSLProtocol.get) || (throw new IllegalArgumentException("Protocol not supported: " + settings.SSLProtocol.get))
|
||||||
|
|
||||||
(cipher, true, config)
|
(cipher, true, config)
|
||||||
} catch {
|
} catch {
|
||||||
case (_: IllegalArgumentException) | (_: NoSuchAlgorithmException) | (_: SSLException) ⇒ (cipher, false, AkkaSpec.testConf) // 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ class Ticket1978AES128CounterRNGFastSpec extends Ticket1978CommunicationSpec(get
|
||||||
* Both of the <quote>Secure</quote> variants require access to the Internet to access random.org.
|
* Both of the <quote>Secure</quote> variants require access to the Internet to access random.org.
|
||||||
*/
|
*/
|
||||||
@org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner])
|
@org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner])
|
||||||
class Ticket1978AES128CounterRNGSecureSpec extends Ticket1978CommunicationSpec(getCipherConfig("AES128CounterRNGSecure", "TLS_RSA_WITH_AES_256_CBC_SHA"))
|
class Ticket1978AES128CounterRNGSecureSpec extends Ticket1978CommunicationSpec(getCipherConfig("AES128CounterRNGSecure", "TLS_RSA_WITH_AES_128_CBC_SHA"))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Both of the <quote>Secure</quote> variants require access to the Internet to access random.org.
|
* Both of the <quote>Secure</quote> variants require access to the Internet to access random.org.
|
||||||
|
|
@ -111,6 +111,7 @@ abstract class Ticket1978CommunicationSpec(val cipherEnabledconfig: (String, Boo
|
||||||
|
|
||||||
override def atTermination() {
|
override def atTermination() {
|
||||||
other.shutdown()
|
other.shutdown()
|
||||||
|
other.awaitTermination()
|
||||||
}
|
}
|
||||||
|
|
||||||
"SSL Remoting" must {
|
"SSL Remoting" must {
|
||||||
|
|
@ -161,8 +162,6 @@ abstract class Ticket1978CommunicationSpec(val cipherEnabledconfig: (String, Boo
|
||||||
expectMsg("preRestart")
|
expectMsg("preRestart")
|
||||||
r ! 42
|
r ! 42
|
||||||
expectMsg(42)
|
expectMsg(42)
|
||||||
system.stop(r)
|
|
||||||
expectMsg("postStop")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ akka {
|
||||||
SSLTrustStore must be(Some("truststore"))
|
SSLTrustStore must be(Some("truststore"))
|
||||||
SSLTrustStorePassword must be(Some("changeme"))
|
SSLTrustStorePassword must be(Some("changeme"))
|
||||||
SSLProtocol must be(Some("TLSv1"))
|
SSLProtocol must be(Some("TLSv1"))
|
||||||
SSLSupportedAlgorithms must be(Set("TLS_RSA_WITH_AES_128_CBC_SHA"))
|
SSLEnabledAlgorithms must be(Set("TLS_RSA_WITH_AES_128_CBC_SHA"))
|
||||||
SSLRandomSource must be(None)
|
SSLRandomSource must be(None)
|
||||||
SSLRandomNumberGenerator must be(None)
|
SSLRandomNumberGenerator must be(None)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue