Fetch KeyStore passwords from NodeConfiguration

This commit is contained in:
Matthew Nesbit 2016-07-22 18:06:21 +01:00
parent b042fac905
commit 83c89c3ec8
9 changed files with 44 additions and 7 deletions

View File

@ -54,6 +54,8 @@ object X509Utilities {
* @param daysAfter number of days to roll forward returned end date relative to current date
* @param parentNotBefore if provided is used to lower bound the date interval returned
* @param parentNotAfter if provided is used to upper bound the date interval returned
* Note we use Date rather than LocalDate as the consuming java.security and BouncyCastle certificate apis all use Date
* Thus we avoid too many round trip conversions.
*/
private fun getCertificateValidityWindow(daysBefore: Int, daysAfter: Int, parentNotBefore: Date? = null, parentNotAfter: Date? = null): Pair<Date, Date> {
val startOfDayUTC = Instant.now().truncatedTo(ChronoUnit.DAYS)

View File

@ -67,7 +67,7 @@ class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort,
// when our process shuts down, but we try in stop() anyway just to be nice.
private var nodeFileLock: FileLock? = null
override fun makeMessagingService(): MessagingService = ArtemisMessagingService(dir, p2pAddr, serverThread)
override fun makeMessagingService(): MessagingService = ArtemisMessagingService(dir, p2pAddr, configuration, serverThread)
override fun startMessagingService() {
// Start up the MQ service.

View File

@ -119,6 +119,8 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
override val myLegalName: String = legalName ?: "Mock Company $id"
override val exportJMXto: String = ""
override val nearestCity: String = "Atlantis"
override val keyStorePassword: String = "dummy"
override val trustStorePassword: String = "trustpass"
}
val node = nodeFactory.create(path, config, this, networkMapAddress, advertisedServices.toSet(), id, keyPair)
if (start) {

View File

@ -59,6 +59,8 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
override val myLegalName: String = "Bank $letter"
override val exportJMXto: String = ""
override val nearestCity: String = city
override val keyStorePassword: String = "dummy"
override val trustStorePassword: String = "trustpass"
}
return SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair)
}
@ -77,6 +79,8 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
override val myLegalName: String = "Network coordination center"
override val exportJMXto: String = ""
override val nearestCity: String = "Amsterdam"
override val keyStorePassword: String = "dummy"
override val trustStorePassword: String = "trustpass"
}
return object : SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair) {}
@ -91,6 +95,8 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
override val myLegalName: String = "Notary Service"
override val exportJMXto: String = ""
override val nearestCity: String = "Zurich"
override val keyStorePassword: String = "dummy"
override val trustStorePassword: String = "trustpass"
}
return SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair)
}
@ -104,6 +110,8 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
override val myLegalName: String = "Rates Service Provider"
override val exportJMXto: String = ""
override val nearestCity: String = "Madrid"
override val keyStorePassword: String = "dummy"
override val trustStorePassword: String = "trustpass"
}
return object : SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair) {
@ -122,6 +130,8 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
override val myLegalName: String = "Regulator A"
override val exportJMXto: String = ""
override val nearestCity: String = "Paris"
override val keyStorePassword: String = "dummy"
override val trustStorePassword: String = "trustpass"
}
val n = object : SimulatedNode(dir, cfg, network, networkMapAddr, advertisedServices, id, keyPair) {

View File

@ -8,6 +8,8 @@ interface NodeConfiguration {
val myLegalName: String
val exportJMXto: String
val nearestCity: String
val keyStorePassword: String
val trustStorePassword: String
}
// Allow the use of "String by config" syntax. TODO: Make it more flexible.
@ -17,4 +19,6 @@ class NodeConfigurationFromConfig(val config: Config = ConfigFactory.load()) : N
override val myLegalName: String by config
override val exportJMXto: String by config
override val nearestCity: String by config
override val keyStorePassword: String by config
override val trustStorePassword: String by config
}

View File

@ -9,6 +9,7 @@ import com.r3corda.core.messaging.*
import com.r3corda.core.serialization.SingletonSerializeAsToken
import com.r3corda.core.utilities.loggerFor
import com.r3corda.node.internal.Node
import com.r3corda.node.services.config.NodeConfiguration
import org.apache.activemq.artemis.api.core.SimpleString
import org.apache.activemq.artemis.api.core.TransportConfiguration
import org.apache.activemq.artemis.api.core.client.*
@ -49,11 +50,13 @@ import javax.annotation.concurrent.ThreadSafe
*
* @param directory A place where Artemis can stash its message journal and other files.
* @param myHostPort What host and port to bind to for receiving inbound connections.
* @param config The config object is used to pass in the passwords for the certificate KeyStore and TrustStore
* @param defaultExecutor This will be used as the default executor to run message handlers on, if no other is specified.
*/
@ThreadSafe
class ArtemisMessagingService(val directory: Path,
val myHostPort: HostAndPort,
val config: NodeConfiguration,
val defaultExecutor: Executor = RunOnCallerThread) : SingletonSerializeAsToken(), MessagingService {
// In future: can contain onion routing info, etc.
@ -98,7 +101,10 @@ class ArtemisMessagingService(val directory: Path,
private val keyStorePath = directory.resolve("certificates").resolve("sslkeystore.jks")
private val trustStorePath = directory.resolve("certificates").resolve("truststore.jks")
private val KEYSTORE_PASSWORD = "cordacadevpass" // TODO we need a proper way of managing keystores and passwords
// Restrict enabled Cipher Suites to AES and GCM as minimum for the bulk cipher.
// Our self-generated certificates all use ECDSA for handshakes, but we allow classical RSA certificates to work
// in case we need to use keytool certificates in some demos
private val CIPHER_SUITES = listOf(
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
@ -340,10 +346,10 @@ class ArtemisMessagingService(val directory: Path,
SSL_ENABLED_PROP_NAME to true,
KEYSTORE_PROVIDER_PROP_NAME to "JKS",
KEYSTORE_PATH_PROP_NAME to keyStorePath,
KEYSTORE_PASSWORD_PROP_NAME to KEYSTORE_PASSWORD, // TODO proper management of keystores and password
KEYSTORE_PASSWORD_PROP_NAME to config.keyStorePassword, // TODO proper management of keystores and password
TRUSTSTORE_PROVIDER_PROP_NAME to "JKS",
TRUSTSTORE_PATH_PROP_NAME to trustStorePath,
TRUSTSTORE_PASSWORD_PROP_NAME to "trustpass",
TRUSTSTORE_PASSWORD_PROP_NAME to config.trustStorePassword,
ENABLED_CIPHER_SUITES_PROP_NAME to CIPHER_SUITES.joinToString(","),
ENABLED_PROTOCOLS_PROP_NAME to "TLSv1.2",
NEED_CLIENT_AUTH_PROP_NAME to true
@ -364,7 +370,7 @@ class ArtemisMessagingService(val directory: Path,
val caKeyStore = X509Utilities.loadKeyStore(
javaClass.classLoader.getResourceAsStream("com/r3corda/node/internal/certificates/cordadevcakeys.jks"),
"cordacadevpass")
X509Utilities.createKeystoreForSSL(keyStorePath, KEYSTORE_PASSWORD, KEYSTORE_PASSWORD, caKeyStore, "cordacadevkeypass")
X509Utilities.createKeystoreForSSL(keyStorePath, config.keyStorePassword, config.keyStorePassword, caKeyStore, "cordacadevkeypass")
}
}

View File

@ -2,6 +2,7 @@ package com.r3corda.node.services
import com.r3corda.core.messaging.Message
import com.r3corda.core.testing.freeLocalHostAndPort
import com.r3corda.node.services.config.NodeConfiguration
import com.r3corda.node.services.messaging.ArtemisMessagingService
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
@ -55,7 +56,15 @@ class ArtemisMessagingServiceTests {
}
private fun createMessagingService(): ArtemisMessagingService {
return ArtemisMessagingService(temporaryFolder.newFolder().toPath(), hostAndPort).apply {
val config = object: NodeConfiguration {
override val myLegalName: String = "me"
override val exportJMXto: String = ""
override val nearestCity: String = "London"
override val keyStorePassword: String = "testpass"
override val trustStorePassword: String = "trustpass"
}
return ArtemisMessagingService(temporaryFolder.newFolder().toPath(), hostAndPort, config).apply {
configureWithDevSSLCertificate()
messagingNetwork = this
}

View File

@ -76,6 +76,8 @@ fun main(args: Array<String>) {
override val myLegalName: String = "Rate fix demo node"
override val exportJMXto: String = "http"
override val nearestCity: String = "Atlantis"
override val keyStorePassword: String = "cordacadevpass"
override val trustStorePassword: String = "trustpass"
}
val apiAddr = HostAndPort.fromParts(myNetAddr.hostText, myNetAddr.port + 1)

View File

@ -1,3 +1,5 @@
myLegalName = "Vast Global MegaCorp, Ltd"
exportJMXto = "http"
nearestCity = "The Moon"
nearestCity = "The Moon"
keyStorePassword = "cordacadevpass"
trustStorePassword = "trustpass"