mirror of
https://github.com/corda/corda.git
synced 2025-06-16 06:08:13 +00:00
OS->Ent merge
This commit is contained in:
@ -30,9 +30,9 @@ object DevIdentityGenerator {
|
||||
/** Install a node key store for the given node directory using the given legal name. */
|
||||
fun installKeyStoreWithNodeIdentity(nodeDir: Path, legalName: CordaX500Name): Party {
|
||||
val certificatesDirectory = nodeDir / "certificates"
|
||||
val signingCertStore = FileBasedCertificateStoreSupplier(certificatesDirectory / "nodekeystore.jks", "cordacadevpass")
|
||||
val p2pKeyStore = FileBasedCertificateStoreSupplier(certificatesDirectory / "sslkeystore.jks", "cordacadevpass")
|
||||
val p2pTrustStore = FileBasedCertificateStoreSupplier(certificatesDirectory / "truststore.jks", "trustpass")
|
||||
val signingCertStore = FileBasedCertificateStoreSupplier(certificatesDirectory / "nodekeystore.jks", DEV_CA_KEY_STORE_PASS, DEV_CA_KEY_STORE_PASS)
|
||||
val p2pKeyStore = FileBasedCertificateStoreSupplier(certificatesDirectory / "sslkeystore.jks", DEV_CA_KEY_STORE_PASS, DEV_CA_KEY_STORE_PASS)
|
||||
val p2pTrustStore = FileBasedCertificateStoreSupplier(certificatesDirectory / "truststore.jks", DEV_CA_TRUST_STORE_PASS, DEV_CA_TRUST_STORE_PRIVATE_KEY_PASS)
|
||||
val p2pSslConfig = SslConfiguration.mutual(p2pKeyStore, p2pTrustStore)
|
||||
|
||||
certificatesDirectory.createDirectories()
|
||||
@ -77,13 +77,16 @@ object DevIdentityGenerator {
|
||||
publicKey)
|
||||
}
|
||||
val distServKeyStoreFile = (nodeDir / "certificates").createDirectories() / "distributedService.jks"
|
||||
X509KeyStore.fromFile(distServKeyStoreFile, "cordacadevpass", createNew = true).update {
|
||||
X509KeyStore.fromFile(distServKeyStoreFile, DEV_CA_KEY_STORE_PASS, createNew = true).update {
|
||||
setCertificate("$DISTRIBUTED_NOTARY_ALIAS_PREFIX-composite-key", compositeKeyCert)
|
||||
setPrivateKey(
|
||||
"$DISTRIBUTED_NOTARY_ALIAS_PREFIX-private-key",
|
||||
keyPair.private,
|
||||
listOf(serviceKeyCert, DEV_INTERMEDIATE_CA.certificate, DEV_ROOT_CA.certificate),
|
||||
"cordacadevkeypass")
|
||||
DEV_CA_KEY_STORE_PASS // Unfortunately we have to use the same password for private key due to Artemis limitation, for more details please see:
|
||||
// org.apache.activemq.artemis.core.remoting.impl.ssl.SSLSupport.loadKeyManagerFactory
|
||||
// where it is calling `KeyManagerFactory.init()` with store password
|
||||
/*DEV_CA_PRIVATE_KEY_PASS*/)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ fun CertificateStore.registerDevSigningCertificates(legalName: CordaX500Name,
|
||||
devNodeCa: CertificateAndKeyPair = createDevNodeCa(intermediateCa, legalName)) {
|
||||
|
||||
update {
|
||||
setPrivateKey(X509Utilities.CORDA_CLIENT_CA, devNodeCa.keyPair.private, listOf(devNodeCa.certificate, intermediateCa.certificate, rootCert))
|
||||
setPrivateKey(X509Utilities.CORDA_CLIENT_CA, devNodeCa.keyPair.private, listOf(devNodeCa.certificate, intermediateCa.certificate, rootCert),
|
||||
this@registerDevSigningCertificates.entryPassword)
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +40,8 @@ fun CertificateStore.registerDevP2pCertificates(legalName: CordaX500Name,
|
||||
update {
|
||||
val tlsKeyPair = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val tlsCert = X509Utilities.createCertificate(CertificateType.TLS, devNodeCa.certificate, devNodeCa.keyPair, legalName.x500Principal, tlsKeyPair.public)
|
||||
setPrivateKey(X509Utilities.CORDA_CLIENT_TLS, tlsKeyPair.private, listOf(tlsCert, devNodeCa.certificate, intermediateCa.certificate, rootCert))
|
||||
setPrivateKey(X509Utilities.CORDA_CLIENT_TLS, tlsKeyPair.private, listOf(tlsCert, devNodeCa.certificate, intermediateCa.certificate, rootCert),
|
||||
this@registerDevP2pCertificates.entryPassword)
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,15 +49,14 @@ fun CertificateStore.storeLegalIdentity(alias: String, keyPair: KeyPair = Crypto
|
||||
val identityCertPath = query {
|
||||
val nodeCaCertPath = getCertificateChain(X509Utilities.CORDA_CLIENT_CA)
|
||||
// Assume key password = store password.
|
||||
val nodeCaCertAndKeyPair = getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA)
|
||||
val nodeCaCertAndKeyPair = getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA, this@storeLegalIdentity.entryPassword)
|
||||
// Create new keys and store in keystore.
|
||||
val identityCert = X509Utilities.createCertificate(CertificateType.LEGAL_IDENTITY, nodeCaCertAndKeyPair.certificate, nodeCaCertAndKeyPair.keyPair, nodeCaCertAndKeyPair.certificate.subjectX500Principal, keyPair.public)
|
||||
// TODO: X509Utilities.validateCertificateChain()
|
||||
// Assume key password = store password.
|
||||
listOf(identityCert) + nodeCaCertPath
|
||||
}
|
||||
update {
|
||||
setPrivateKey(alias, keyPair.private, identityCertPath)
|
||||
setPrivateKey(alias, keyPair.private, identityCertPath, this@storeLegalIdentity.entryPassword)
|
||||
}
|
||||
return PartyAndCertificate(X509Utilities.buildCertPath(identityCertPath))
|
||||
}
|
||||
@ -96,6 +97,7 @@ const val DEV_CA_KEY_STORE_FILE: String = "cordadevcakeys.jks"
|
||||
const val DEV_CA_KEY_STORE_PASS: String = "cordacadevpass"
|
||||
const val DEV_CA_TRUST_STORE_FILE: String = "cordatruststore.jks"
|
||||
const val DEV_CA_TRUST_STORE_PASS: String = "trustpass"
|
||||
const val DEV_CA_TRUST_STORE_PRIVATE_KEY_PASS: String = "trustpasskeypass"
|
||||
|
||||
// We need a class so that we can get hold of the class loader
|
||||
internal object DevCaHelper {
|
||||
@ -104,6 +106,8 @@ internal object DevCaHelper {
|
||||
}
|
||||
}
|
||||
|
||||
fun loadDevCaKeyStore(classLoader: ClassLoader = DevCaHelper::class.java.classLoader): CertificateStore = CertificateStore.fromResource("certificates/$DEV_CA_KEY_STORE_FILE", DEV_CA_KEY_STORE_PASS, classLoader)
|
||||
fun loadDevCaKeyStore(classLoader: ClassLoader = DevCaHelper::class.java.classLoader): CertificateStore = CertificateStore.fromResource(
|
||||
"certificates/$DEV_CA_KEY_STORE_FILE", DEV_CA_KEY_STORE_PASS, DEV_CA_PRIVATE_KEY_PASS, classLoader)
|
||||
|
||||
fun loadDevCaTrustStore(classLoader: ClassLoader = DevCaHelper::class.java.classLoader): CertificateStore = CertificateStore.fromResource("certificates/$DEV_CA_TRUST_STORE_FILE", DEV_CA_TRUST_STORE_PASS, classLoader)
|
||||
fun loadDevCaTrustStore(classLoader: ClassLoader = DevCaHelper::class.java.classLoader): CertificateStore = CertificateStore.fromResource(
|
||||
"certificates/$DEV_CA_TRUST_STORE_FILE", DEV_CA_TRUST_STORE_PASS, DEV_CA_TRUST_STORE_PRIVATE_KEY_PASS, classLoader)
|
||||
|
@ -14,17 +14,18 @@ interface CertificateStore : Iterable<Pair<String, X509Certificate>> {
|
||||
|
||||
companion object {
|
||||
|
||||
fun of(store: X509KeyStore, password: String): CertificateStore = DelegatingCertificateStore(store, password)
|
||||
fun of(store: X509KeyStore, password: String, entryPassword: String): CertificateStore = DelegatingCertificateStore(store, password, entryPassword)
|
||||
|
||||
fun fromFile(storePath: Path, password: String, createNew: Boolean): CertificateStore = DelegatingCertificateStore(X509KeyStore.fromFile(storePath, password, createNew), password)
|
||||
fun fromFile(storePath: Path, password: String, entryPassword: String, createNew: Boolean): CertificateStore = DelegatingCertificateStore(X509KeyStore.fromFile(storePath, password, createNew), password, entryPassword)
|
||||
|
||||
fun fromInputStream(stream: InputStream, password: String): CertificateStore = DelegatingCertificateStore(X509KeyStore.fromInputStream(stream, password), password)
|
||||
fun fromInputStream(stream: InputStream, password: String, entryPassword: String): CertificateStore = DelegatingCertificateStore(X509KeyStore.fromInputStream(stream, password), password, entryPassword)
|
||||
|
||||
fun fromResource(storeResourceName: String, password: String, classLoader: ClassLoader = Thread.currentThread().contextClassLoader): CertificateStore = fromInputStream(classLoader.getResourceAsStream(storeResourceName), password)
|
||||
fun fromResource(storeResourceName: String, password: String, entryPassword: String, classLoader: ClassLoader = Thread.currentThread().contextClassLoader): CertificateStore = fromInputStream(classLoader.getResourceAsStream(storeResourceName), password, entryPassword)
|
||||
}
|
||||
|
||||
val value: X509KeyStore
|
||||
val password: String
|
||||
val entryPassword: String
|
||||
|
||||
fun writeTo(stream: OutputStream) = value.internal.store(stream, password.toCharArray())
|
||||
|
||||
@ -80,4 +81,4 @@ interface CertificateStore : Iterable<Pair<String, X509Certificate>> {
|
||||
}
|
||||
}
|
||||
|
||||
private class DelegatingCertificateStore(override val value: X509KeyStore, override val password: String) : CertificateStore
|
||||
private class DelegatingCertificateStore(override val value: X509KeyStore, override val password: String, override val entryPassword: String) : CertificateStore
|
@ -18,7 +18,7 @@ interface CertificateStoreSupplier {
|
||||
}
|
||||
|
||||
// TODO replace reference to FileBasedCertificateStoreSupplier with CertificateStoreSupplier, after coming up with a way of passing certificate stores to Artemis.
|
||||
class FileBasedCertificateStoreSupplier(val path: Path, val password: String) : CertificateStoreSupplier {
|
||||
class FileBasedCertificateStoreSupplier(val path: Path, val storePassword: String, val entryPassword: String) : CertificateStoreSupplier {
|
||||
|
||||
override fun get(createNew: Boolean) = CertificateStore.fromFile(path, password, createNew)
|
||||
override fun get(createNew: Boolean) = CertificateStore.fromFile(path, storePassword, entryPassword, createNew)
|
||||
}
|
@ -151,7 +151,7 @@ private fun Config.getSingleValue(path: String, type: KType, onUnknownKeys: (Set
|
||||
|
||||
private fun ConfigException.Missing.relative(path: String, nestedPath: String?): ConfigException.Missing {
|
||||
return when {
|
||||
nestedPath != null -> throw ConfigException.Missing("$nestedPath.$path")
|
||||
nestedPath != null -> throw ConfigException.Missing("$nestedPath.$path", this)
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
@ -53,17 +53,17 @@ class X509KeyStore private constructor(val internal: KeyStore, private val store
|
||||
return uncheckedCast(certArray.asList())
|
||||
}
|
||||
|
||||
fun getCertificateAndKeyPair(alias: String, keyPassword: String = storePassword): CertificateAndKeyPair {
|
||||
fun getCertificateAndKeyPair(alias: String, keyPassword: String): CertificateAndKeyPair {
|
||||
val cert = getCertificate(alias)
|
||||
val publicKey = Crypto.toSupportedPublicKey(cert.publicKey)
|
||||
return CertificateAndKeyPair(cert, KeyPair(publicKey, getPrivateKey(alias, keyPassword)))
|
||||
}
|
||||
|
||||
fun getPrivateKey(alias: String, keyPassword: String = storePassword): PrivateKey {
|
||||
fun getPrivateKey(alias: String, keyPassword: String): PrivateKey {
|
||||
return internal.getSupportedKey(alias, keyPassword)
|
||||
}
|
||||
|
||||
fun setPrivateKey(alias: String, key: PrivateKey, certificates: List<X509Certificate>, keyPassword: String = storePassword) {
|
||||
fun setPrivateKey(alias: String, key: PrivateKey, certificates: List<X509Certificate>, keyPassword: String) {
|
||||
internal.setKeyEntry(alias, key, keyPassword.toCharArray(), certificates.toTypedArray())
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,9 @@ internal fun splitKeystore(config: AMQPConfiguration): Map<String, CertHoldingKe
|
||||
}.toMap()
|
||||
}
|
||||
|
||||
fun KeyManagerFactory.init(keyStore: CertificateStore) = init(keyStore.value.internal, keyStore.password.toCharArray())
|
||||
// As per Javadoc in: https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/KeyManagerFactory.html `init` method
|
||||
// 2nd parameter `password` - the password for recovering keys in the KeyStore
|
||||
fun KeyManagerFactory.init(keyStore: CertificateStore) = init(keyStore.value.internal, keyStore.entryPassword.toCharArray())
|
||||
|
||||
fun TrustManagerFactory.init(trustStore: CertificateStore) = init(trustStore.value.internal)
|
||||
|
||||
|
@ -247,8 +247,9 @@ class X509UtilitiesTest {
|
||||
signingCertStore.get(createNew = true).also { it.registerDevSigningCertificates(MEGA_CORP.name, rootCa.certificate, intermediateCa, nodeCa) }
|
||||
p2pSslConfig.keyStore.get(createNew = true).also { it.registerDevP2pCertificates(MEGA_CORP.name, rootCa.certificate, intermediateCa, nodeCa) }
|
||||
// Load back server certificate
|
||||
val serverKeyStore = signingCertStore.get().value
|
||||
val (serverCert, serverKeyPair) = serverKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA)
|
||||
val certStore = signingCertStore.get()
|
||||
val serverKeyStore = certStore.value
|
||||
val (serverCert, serverKeyPair) = serverKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA, certStore.entryPassword)
|
||||
|
||||
serverCert.checkValidity()
|
||||
serverCert.verify(intermediateCa.certificate.publicKey)
|
||||
@ -256,7 +257,7 @@ class X509UtilitiesTest {
|
||||
|
||||
// Load back SSL certificate
|
||||
val sslKeyStoreReloaded = p2pSslConfig.keyStore.get()
|
||||
val (sslCert) = sslKeyStoreReloaded.query { getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_TLS, p2pSslConfig.keyStore.password) }
|
||||
val (sslCert) = sslKeyStoreReloaded.query { getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_TLS, sslKeyStoreReloaded.entryPassword) }
|
||||
|
||||
sslCert.checkValidity()
|
||||
sslCert.verify(serverCert.publicKey)
|
||||
|
@ -20,8 +20,10 @@ class SSLHelperTest {
|
||||
val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
|
||||
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
|
||||
keyManagerFactory.init(CertificateStore.fromFile(sslConfig.keyStore.path, sslConfig.keyStore.password, false))
|
||||
trustManagerFactory.init(initialiseTrustStoreAndEnableCrlChecking(CertificateStore.fromFile(sslConfig.trustStore.path, sslConfig.trustStore.password, false), false))
|
||||
val keyStore = sslConfig.keyStore
|
||||
keyManagerFactory.init(CertificateStore.fromFile(keyStore.path, keyStore.storePassword, keyStore.entryPassword, false))
|
||||
val trustStore = sslConfig.trustStore
|
||||
trustManagerFactory.init(initialiseTrustStoreAndEnableCrlChecking(CertificateStore.fromFile(trustStore.path, trustStore.storePassword, trustStore.entryPassword, false), false))
|
||||
|
||||
val sslHandler = createClientSslHelper(NetworkHostAndPort("localhost", 1234), setOf(legalName), keyManagerFactory, trustManagerFactory)
|
||||
val legalNameHash = SecureHash.sha256(legalName.toString()).toString().take(32).toLowerCase()
|
||||
|
Reference in New Issue
Block a user