mirror of
https://github.com/corda/corda.git
synced 2025-01-20 03:36:29 +00:00
Moved KeyStoreUtilities out of core and into node
This commit is contained in:
parent
5438e82e68
commit
a49baddd4b
@ -1,11 +1,12 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.crypto.Crypto.generateKeyPair
|
||||
import org.bouncycastle.asn1.ASN1Encodable
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x500.X500NameBuilder
|
||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
||||
import org.bouncycastle.asn1.x509.*
|
||||
import org.bouncycastle.asn1.x509.KeyPurposeId
|
||||
import org.bouncycastle.asn1.x509.KeyUsage
|
||||
import org.bouncycastle.asn1.x509.NameConstraints
|
||||
import org.bouncycastle.cert.X509CertificateHolder
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMWriter
|
||||
@ -15,10 +16,8 @@ import java.io.FileWriter
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import java.security.KeyPair
|
||||
import java.security.KeyStore
|
||||
import java.security.PublicKey
|
||||
import java.security.cert.*
|
||||
import java.security.cert.Certificate
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.time.temporal.ChronoUnit
|
||||
@ -167,55 +166,6 @@ object X509Utilities {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An all in wrapper to manufacture a server certificate and keys all stored in a KeyStore suitable for running TLS on the local machine.
|
||||
* @param sslKeyStorePath KeyStore path to save ssl key and cert to.
|
||||
* @param clientCAKeystorePath KeyStore path to save client CA key and cert to.
|
||||
* @param storePassword access password for KeyStore.
|
||||
* @param keyPassword PrivateKey access password for the generated keys.
|
||||
* It is recommended that this is the same as the storePassword as most TLS libraries assume they are the same.
|
||||
* @param caKeyStore KeyStore containing CA keys generated by createCAKeyStoreAndTrustStore.
|
||||
* @param caKeyPassword password to unlock private keys in the CA KeyStore.
|
||||
* @return The KeyStore created containing a private key, certificate chain and root CA public cert for use in TLS applications.
|
||||
*/
|
||||
fun createKeystoreForCordaNode(sslKeyStorePath: Path,
|
||||
clientCAKeystorePath: Path,
|
||||
storePassword: String,
|
||||
keyPassword: String,
|
||||
caKeyStore: KeyStore,
|
||||
caKeyPassword: String,
|
||||
legalName: X500Name,
|
||||
signatureScheme: SignatureScheme = DEFAULT_TLS_SIGNATURE_SCHEME) {
|
||||
|
||||
val rootCACert = caKeyStore.getX509Certificate(CORDA_ROOT_CA)
|
||||
val (intermediateCACert, intermediateCAKeyPair) = caKeyStore.getCertificateAndKeyPair(CORDA_INTERMEDIATE_CA, caKeyPassword)
|
||||
|
||||
val clientKey = generateKeyPair(signatureScheme)
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName))), arrayOf())
|
||||
val clientCACert = createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCACert, intermediateCAKeyPair, legalName, clientKey.public, nameConstraints = nameConstraints)
|
||||
|
||||
val tlsKey = generateKeyPair(signatureScheme)
|
||||
val clientTLSCert = createCertificate(CertificateType.TLS, clientCACert, clientKey, legalName, tlsKey.public)
|
||||
|
||||
val keyPass = keyPassword.toCharArray()
|
||||
|
||||
val clientCAKeystore = KeyStoreUtilities.loadOrCreateKeyStore(clientCAKeystorePath, storePassword)
|
||||
clientCAKeystore.addOrReplaceKey(
|
||||
CORDA_CLIENT_CA,
|
||||
clientKey.private,
|
||||
keyPass,
|
||||
org.bouncycastle.cert.path.CertPath(arrayOf(clientCACert, intermediateCACert, rootCACert)))
|
||||
clientCAKeystore.save(clientCAKeystorePath, storePassword)
|
||||
|
||||
val tlsKeystore = KeyStoreUtilities.loadOrCreateKeyStore(sslKeyStorePath, storePassword)
|
||||
tlsKeystore.addOrReplaceKey(
|
||||
CORDA_CLIENT_TLS,
|
||||
tlsKey.private,
|
||||
keyPass,
|
||||
org.bouncycastle.cert.path.CertPath(arrayOf(clientTLSCert, clientCACert, intermediateCACert, rootCACert)))
|
||||
tlsKeystore.save(sslKeyStorePath, storePassword)
|
||||
}
|
||||
|
||||
fun createCertificateSigningRequest(subject: X500Name, keyPair: KeyPair, signatureScheme: SignatureScheme = DEFAULT_TLS_SIGNATURE_SCHEME) = Crypto.createCertificateSigningRequest(subject, keyPair, signatureScheme)
|
||||
}
|
||||
|
||||
|
@ -6,10 +6,14 @@ import net.corda.core.crypto.composite.CompositeSignaturesWithKeys
|
||||
import net.corda.core.div
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.node.utilities.loadKeyStore
|
||||
import net.corda.node.utilities.loadOrCreateKeyStore
|
||||
import net.corda.node.utilities.save
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import java.security.PublicKey
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertFalse
|
||||
@ -24,9 +28,9 @@ class CompositeKeyTests {
|
||||
val bobKey = generateKeyPair()
|
||||
val charlieKey = generateKeyPair()
|
||||
|
||||
val alicePublicKey = aliceKey.public
|
||||
val bobPublicKey = bobKey.public
|
||||
val charliePublicKey = charlieKey.public
|
||||
val alicePublicKey: PublicKey = aliceKey.public
|
||||
val bobPublicKey: PublicKey = bobKey.public
|
||||
val charliePublicKey: PublicKey = charlieKey.public
|
||||
|
||||
val message = OpaqueBytes("Transaction".toByteArray())
|
||||
|
||||
@ -332,12 +336,12 @@ class CompositeKeyTests {
|
||||
|
||||
// Store certificate to keystore.
|
||||
val keystorePath = tempFolder.root.toPath() / "keystore.jks"
|
||||
val keystore = KeyStoreUtilities.loadOrCreateKeyStore(keystorePath, "password")
|
||||
val keystore = loadOrCreateKeyStore(keystorePath, "password")
|
||||
keystore.setCertificateEntry("CompositeKey", compositeKeyCert.cert)
|
||||
keystore.save(keystorePath, "password")
|
||||
|
||||
// Load keystore from disk.
|
||||
val keystore2 = KeyStoreUtilities.loadKeyStore(keystorePath, "password")
|
||||
val keystore2 = loadKeyStore(keystorePath, "password")
|
||||
assertTrue { keystore2.containsAlias("CompositeKey") }
|
||||
|
||||
val key = keystore2.getCertificate("CompositeKey").publicKey
|
||||
|
@ -1,6 +1,9 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.toTypedArray
|
||||
import net.corda.node.utilities.KEYSTORE_TYPE
|
||||
import net.corda.node.utilities.addOrReplaceCertificate
|
||||
import net.corda.node.utilities.addOrReplaceKey
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x509.GeneralName
|
||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||
@ -26,14 +29,14 @@ class X509NameConstraintsTest {
|
||||
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCACert, intermediateCAKeyPair, X509Utilities.getX509Name("Corda Client CA","London","demo@r3.com",null), clientCAKeyPair.public, nameConstraints = nameConstraints)
|
||||
|
||||
val keyPass = "password"
|
||||
val trustStore = KeyStore.getInstance(KeyStoreUtilities.KEYSTORE_TYPE)
|
||||
val trustStore = KeyStore.getInstance(KEYSTORE_TYPE)
|
||||
trustStore.load(null, keyPass.toCharArray())
|
||||
trustStore.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCACert.cert)
|
||||
|
||||
val tlsKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val tlsCert = X509Utilities.createCertificate(CertificateType.TLS, clientCACert, clientCAKeyPair, subjectName, tlsKey.public)
|
||||
|
||||
val keyStore = KeyStore.getInstance(KeyStoreUtilities.KEYSTORE_TYPE)
|
||||
val keyStore = KeyStore.getInstance(KEYSTORE_TYPE)
|
||||
keyStore.load(null, keyPass.toCharArray())
|
||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_CLIENT_TLS, tlsKey.private, keyPass.toCharArray(),
|
||||
Stream.of(tlsCert, clientCACert, intermediateCACert, rootCACert).map { it.cert }.toTypedArray<Certificate>())
|
||||
|
@ -6,6 +6,8 @@ import net.corda.core.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
|
||||
import net.corda.core.crypto.X509Utilities.createSelfSignedCACertificate
|
||||
import net.corda.core.div
|
||||
import net.corda.core.toTypedArray
|
||||
import net.corda.node.services.config.createKeystoreForCordaNode
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.testing.MEGA_CORP
|
||||
import net.corda.testing.getTestX509Name
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
@ -89,13 +91,13 @@ class X509UtilitiesTest {
|
||||
assertTrue(Arrays.equals(selfSignCert.subjectPublicKeyInfo.encoded, keyPair.public.encoded))
|
||||
|
||||
// Save the EdDSA private key with self sign cert in the keystore.
|
||||
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
val keyStore = loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
keyStore.setKeyEntry("Key", keyPair.private, "password".toCharArray(),
|
||||
Stream.of(selfSignCert).map { it.cert }.toTypedArray())
|
||||
keyStore.save(tmpKeyStore, "keystorepass")
|
||||
|
||||
// Load the keystore from file and make sure keys are intact.
|
||||
val keyStore2 = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
val keyStore2 = loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
val privateKey = keyStore2.getKey("Key", "password".toCharArray())
|
||||
val pubKey = keyStore2.getCertificate("Key").publicKey
|
||||
|
||||
@ -114,13 +116,13 @@ class X509UtilitiesTest {
|
||||
val edDSACert = X509Utilities.createCertificate(CertificateType.TLS, ecDSACert, ecDSAKey, X500Name("CN=TestEdDSA"), edDSAKeypair.public)
|
||||
|
||||
// Save the EdDSA private key with cert chains.
|
||||
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
val keyStore = loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
keyStore.setKeyEntry("Key", edDSAKeypair.private, "password".toCharArray(),
|
||||
Stream.of(ecDSACert, edDSACert).map { it.cert }.toTypedArray())
|
||||
keyStore.save(tmpKeyStore, "keystorepass")
|
||||
|
||||
// Load the keystore from file and make sure keys are intact.
|
||||
val keyStore2 = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
val keyStore2 = loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
val privateKey = keyStore2.getKey("Key", "password".toCharArray())
|
||||
val certs = keyStore2.getCertificateChain("Key")
|
||||
|
||||
@ -142,8 +144,8 @@ class X509UtilitiesTest {
|
||||
createCAKeyStoreAndTrustStore(tmpKeyStore, "keystorepass", "keypass", tmpTrustStore, "trustpass")
|
||||
|
||||
// Load back generated root CA Cert and private key from keystore and check against copy in truststore
|
||||
val keyStore = KeyStoreUtilities.loadKeyStore(tmpKeyStore, "keystorepass")
|
||||
val trustStore = KeyStoreUtilities.loadKeyStore(tmpTrustStore, "trustpass")
|
||||
val keyStore = loadKeyStore(tmpKeyStore, "keystorepass")
|
||||
val trustStore = loadKeyStore(tmpTrustStore, "trustpass")
|
||||
val rootCaCert = keyStore.getCertificate(X509Utilities.CORDA_ROOT_CA) as X509Certificate
|
||||
val rootCaPrivateKey = keyStore.getKey(X509Utilities.CORDA_ROOT_CA, "keypass".toCharArray()) as PrivateKey
|
||||
val rootCaFromTrustStore = trustStore.getCertificate(X509Utilities.CORDA_ROOT_CA) as X509Certificate
|
||||
@ -182,14 +184,14 @@ class X509UtilitiesTest {
|
||||
"trustpass")
|
||||
|
||||
// Load signing intermediate CA cert
|
||||
val caKeyStore = KeyStoreUtilities.loadKeyStore(tmpCAKeyStore, "cakeystorepass")
|
||||
val caKeyStore = loadKeyStore(tmpCAKeyStore, "cakeystorepass")
|
||||
val caCertAndKey = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, "cakeypass")
|
||||
|
||||
// Generate server cert and private key and populate another keystore suitable for SSL
|
||||
X509Utilities.createKeystoreForCordaNode(tmpSSLKeyStore, tmpServerKeyStore, "serverstorepass", "serverkeypass", caKeyStore, "cakeypass", MEGA_CORP.name)
|
||||
createKeystoreForCordaNode(tmpSSLKeyStore, tmpServerKeyStore, "serverstorepass", "serverkeypass", caKeyStore, "cakeypass", MEGA_CORP.name)
|
||||
|
||||
// Load back server certificate
|
||||
val serverKeyStore = KeyStoreUtilities.loadKeyStore(tmpServerKeyStore, "serverstorepass")
|
||||
val serverKeyStore = loadKeyStore(tmpServerKeyStore, "serverstorepass")
|
||||
val serverCertAndKey = serverKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA, "serverkeypass")
|
||||
|
||||
serverCertAndKey.certificate.isValidOn(Date())
|
||||
@ -198,7 +200,7 @@ class X509UtilitiesTest {
|
||||
assertTrue { serverCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.commonName) }
|
||||
|
||||
// Load back server certificate
|
||||
val sslKeyStore = KeyStoreUtilities.loadKeyStore(tmpSSLKeyStore, "serverstorepass")
|
||||
val sslKeyStore = loadKeyStore(tmpSSLKeyStore, "serverstorepass")
|
||||
val sslCertAndKey = sslKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_TLS, "serverkeypass")
|
||||
|
||||
sslCertAndKey.certificate.isValidOn(Date())
|
||||
@ -227,9 +229,9 @@ class X509UtilitiesTest {
|
||||
"trustpass")
|
||||
|
||||
// Generate server cert and private key and populate another keystore suitable for SSL
|
||||
X509Utilities.createKeystoreForCordaNode(tmpSSLKeyStore, tmpServerKeyStore, "serverstorepass", "serverstorepass", caKeyStore, "cakeypass", MEGA_CORP.name)
|
||||
val keyStore = KeyStoreUtilities.loadKeyStore(tmpSSLKeyStore, "serverstorepass")
|
||||
val trustStore = KeyStoreUtilities.loadKeyStore(tmpTrustStore, "trustpass")
|
||||
createKeystoreForCordaNode(tmpSSLKeyStore, tmpServerKeyStore, "serverstorepass", "serverstorepass", caKeyStore, "cakeypass", MEGA_CORP.name)
|
||||
val keyStore = loadKeyStore(tmpSSLKeyStore, "serverstorepass")
|
||||
val trustStore = loadKeyStore(tmpTrustStore, "trustpass")
|
||||
|
||||
val context = SSLContext.getInstance("TLS")
|
||||
val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
|
||||
@ -348,7 +350,7 @@ class X509UtilitiesTest {
|
||||
val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, X509Utilities.getX509Name("Corda Node Intermediate CA","London","demo@r3.com",null), intermediateCAKeyPair.public)
|
||||
|
||||
val keyPass = keyPassword.toCharArray()
|
||||
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(keyStoreFilePath, storePassword)
|
||||
val keyStore = loadOrCreateKeyStore(keyStoreFilePath, storePassword)
|
||||
|
||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_ROOT_CA, rootCAKey.private, keyPass, arrayOf<Certificate>(rootCACert.cert))
|
||||
|
||||
@ -359,7 +361,7 @@ class X509UtilitiesTest {
|
||||
|
||||
keyStore.save(keyStoreFilePath, storePassword)
|
||||
|
||||
val trustStore = KeyStoreUtilities.loadOrCreateKeyStore(trustStoreFilePath, trustStorePassword)
|
||||
val trustStore = loadOrCreateKeyStore(trustStoreFilePath, trustStorePassword)
|
||||
|
||||
trustStore.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCACert.cert)
|
||||
trustStore.addOrReplaceCertificate(X509Utilities.CORDA_INTERMEDIATE_CA, intermediateCACert.cert)
|
||||
@ -373,7 +375,7 @@ class X509UtilitiesTest {
|
||||
fun `Get correct private key type from Keystore`() {
|
||||
val keyPair = generateKeyPair(Crypto.ECDSA_SECP256R1_SHA256)
|
||||
val selfSignCert = createSelfSignedCACertificate(X500Name("CN=Test"), keyPair)
|
||||
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tempFile("testKeystore.jks"), "keystorepassword")
|
||||
val keyStore = loadOrCreateKeyStore(tempFile("testKeystore.jks"), "keystorepassword")
|
||||
keyStore.setKeyEntry("Key", keyPair.private, "keypassword".toCharArray(), arrayOf(selfSignCert.cert))
|
||||
|
||||
val keyFromKeystore = keyStore.getKey("Key", "keypassword".toCharArray())
|
||||
@ -382,5 +384,4 @@ class X509UtilitiesTest {
|
||||
assertTrue(keyFromKeystore is java.security.interfaces.ECPrivateKey) // by default JKS returns SUN EC key
|
||||
assertTrue(keyFromKeystoreCasted is org.bouncycastle.jce.interfaces.ECPrivateKey)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,8 +2,11 @@ package net.corda.services.messaging
|
||||
|
||||
import net.corda.core.copyTo
|
||||
import net.corda.core.createDirectories
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.crypto.CertificateType
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.exists
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.nodeapi.ArtemisMessagingComponent.Companion.NODE_USER
|
||||
import net.corda.nodeapi.ArtemisMessagingComponent.Companion.PEER_USER
|
||||
import net.corda.nodeapi.RPCApi
|
||||
@ -94,7 +97,9 @@ class MQSecurityAsNodeTest : MQSecurityTest() {
|
||||
javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordatruststore.jks").copyTo(trustStoreFile)
|
||||
}
|
||||
|
||||
val caKeyStore = KeyStoreUtilities.loadKeyStore(javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordadevcakeys.jks"), "cordacadevpass")
|
||||
val caKeyStore = loadKeyStore(
|
||||
javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordadevcakeys.jks"),
|
||||
"cordacadevpass")
|
||||
|
||||
val rootCACert = caKeyStore.getX509Certificate(X509Utilities.CORDA_ROOT_CA)
|
||||
val intermediateCA = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, "cordacadevkeypass")
|
||||
@ -102,12 +107,13 @@ class MQSecurityAsNodeTest : MQSecurityTest() {
|
||||
|
||||
// Set name constrain to the legal name.
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName))), arrayOf())
|
||||
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCA.certificate, intermediateCA.keyPair, legalName, clientKey.public, nameConstraints = nameConstraints)
|
||||
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCA.certificate,
|
||||
intermediateCA.keyPair, legalName, clientKey.public, nameConstraints = nameConstraints)
|
||||
val tlsKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
// Using different x500 name in the TLS cert which is not allowed in the name constraints.
|
||||
val clientTLSCert = X509Utilities.createCertificate(CertificateType.TLS, clientCACert, clientKey, MINI_CORP.name, tlsKey.public)
|
||||
val keyPass = keyStorePassword.toCharArray()
|
||||
val clientCAKeystore = KeyStoreUtilities.loadOrCreateKeyStore(nodeKeystore, keyStorePassword)
|
||||
val clientCAKeystore = loadOrCreateKeyStore(nodeKeystore, keyStorePassword)
|
||||
clientCAKeystore.addOrReplaceKey(
|
||||
X509Utilities.CORDA_CLIENT_CA,
|
||||
clientKey.private,
|
||||
@ -115,7 +121,7 @@ class MQSecurityAsNodeTest : MQSecurityTest() {
|
||||
CertPath(arrayOf(clientCACert, intermediateCA.certificate, rootCACert)))
|
||||
clientCAKeystore.save(nodeKeystore, keyStorePassword)
|
||||
|
||||
val tlsKeystore = KeyStoreUtilities.loadOrCreateKeyStore(sslKeystore, keyStorePassword)
|
||||
val tlsKeystore = loadOrCreateKeyStore(sslKeystore, keyStorePassword)
|
||||
tlsKeystore.addOrReplaceKey(
|
||||
X509Utilities.CORDA_CLIENT_TLS,
|
||||
tlsKey.private,
|
||||
|
@ -59,10 +59,8 @@ import net.corda.node.services.vault.CashBalanceAsMetricsObserver
|
||||
import net.corda.node.services.vault.HibernateVaultQueryImpl
|
||||
import net.corda.node.services.vault.NodeVaultService
|
||||
import net.corda.node.services.vault.VaultSoftLockManager
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.node.utilities.AddOrRemove.ADD
|
||||
import net.corda.node.utilities.AffinityExecutor
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.node.utilities.transaction
|
||||
import org.apache.activemq.artemis.utils.ReusableLatch
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
@ -520,8 +518,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
private fun validateKeystore() {
|
||||
val containCorrectKeys = try {
|
||||
// This will throw IOException if key file not found or KeyStoreException if keystore password is incorrect.
|
||||
val sslKeystore = KeyStoreUtilities.loadKeyStore(configuration.sslKeystore, configuration.keyStorePassword)
|
||||
val identitiesKeystore = KeyStoreUtilities.loadKeyStore(configuration.nodeKeystore, configuration.keyStorePassword)
|
||||
val sslKeystore = loadKeyStore(configuration.sslKeystore, configuration.keyStorePassword)
|
||||
val identitiesKeystore = loadKeyStore(configuration.nodeKeystore, configuration.keyStorePassword)
|
||||
sslKeystore.containsAlias(X509Utilities.CORDA_CLIENT_TLS) && identitiesKeystore.containsAlias(X509Utilities.CORDA_CLIENT_CA)
|
||||
} catch (e: KeyStoreException) {
|
||||
log.warn("Certificate key store found but key store password does not match configuration.")
|
||||
@ -535,7 +533,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
"or if you don't have one yet, fill out the config file and run corda.jar --initial-registration. " +
|
||||
"Read more at: https://docs.corda.net/permissioning.html"
|
||||
}
|
||||
val identitiesKeystore = KeyStoreUtilities.loadKeyStore(configuration.sslKeystore, configuration.keyStorePassword)
|
||||
val identitiesKeystore = loadKeyStore(configuration.sslKeystore, configuration.keyStorePassword)
|
||||
val tlsIdentity = identitiesKeystore.getX509Certificate(X509Utilities.CORDA_CLIENT_TLS).subject
|
||||
|
||||
require(tlsIdentity == configuration.myLegalName) {
|
||||
@ -839,7 +837,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
}
|
||||
|
||||
private class KeyStoreWrapper(val keyStore: KeyStore, val storePath: Path, private val storePassword: String) {
|
||||
constructor(storePath: Path, storePassword: String) : this(KeyStoreUtilities.loadKeyStore(storePath, storePassword), storePath, storePassword)
|
||||
constructor(storePath: Path, storePassword: String) : this(loadKeyStore(storePath, storePassword), storePath, storePassword)
|
||||
|
||||
fun certificateAndKeyPair(alias: String): CertificateAndKeyPair? {
|
||||
return if (keyStore.containsAlias(alias)) keyStore.getCertificateAndKeyPair(alias, storePassword) else null
|
||||
|
@ -1,6 +1,3 @@
|
||||
// TODO: Remove when configureTestSSL() is moved.
|
||||
@file:JvmName("ConfigUtilities")
|
||||
|
||||
package net.corda.node.services.config
|
||||
|
||||
import com.typesafe.config.Config
|
||||
@ -9,17 +6,21 @@ import com.typesafe.config.ConfigParseOptions
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
import net.corda.core.copyTo
|
||||
import net.corda.core.createDirectories
|
||||
import net.corda.core.crypto.KeyStoreUtilities
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.div
|
||||
import net.corda.core.exists
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.nodeapi.config.SSLConfiguration
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x509.GeneralName
|
||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||
import org.bouncycastle.asn1.x509.NameConstraints
|
||||
import java.nio.file.Path
|
||||
import java.security.KeyStore
|
||||
|
||||
fun configOf(vararg pairs: Pair<String, Any?>) = ConfigFactory.parseMap(mapOf(*pairs))
|
||||
operator fun Config.plus(overrides: Map<String, Any?>) = ConfigFactory.parseMap(overrides).withFallback(this)
|
||||
fun configOf(vararg pairs: Pair<String, Any?>): Config = ConfigFactory.parseMap(mapOf(*pairs))
|
||||
operator fun Config.plus(overrides: Map<String, Any?>): Config = ConfigFactory.parseMap(overrides).withFallback(this)
|
||||
|
||||
object ConfigHelper {
|
||||
private val log = loggerFor<ConfigHelper>()
|
||||
@ -55,7 +56,56 @@ fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: X500Name) {
|
||||
javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordatruststore.jks").copyTo(trustStoreFile)
|
||||
}
|
||||
if (!sslKeystore.exists() || !nodeKeystore.exists()) {
|
||||
val caKeyStore = KeyStoreUtilities.loadKeyStore(javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordadevcakeys.jks"), "cordacadevpass")
|
||||
X509Utilities.createKeystoreForCordaNode(sslKeystore, nodeKeystore, keyStorePassword, keyStorePassword, caKeyStore, "cordacadevkeypass", myLegalName)
|
||||
val caKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordadevcakeys.jks"), "cordacadevpass")
|
||||
createKeystoreForCordaNode(sslKeystore, nodeKeystore, keyStorePassword, keyStorePassword, caKeyStore, "cordacadevkeypass", myLegalName)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An all in wrapper to manufacture a server certificate and keys all stored in a KeyStore suitable for running TLS on the local machine.
|
||||
* @param sslKeyStorePath KeyStore path to save ssl key and cert to.
|
||||
* @param clientCAKeystorePath KeyStore path to save client CA key and cert to.
|
||||
* @param storePassword access password for KeyStore.
|
||||
* @param keyPassword PrivateKey access password for the generated keys.
|
||||
* It is recommended that this is the same as the storePassword as most TLS libraries assume they are the same.
|
||||
* @param caKeyStore KeyStore containing CA keys generated by createCAKeyStoreAndTrustStore.
|
||||
* @param caKeyPassword password to unlock private keys in the CA KeyStore.
|
||||
* @return The KeyStore created containing a private key, certificate chain and root CA public cert for use in TLS applications.
|
||||
*/
|
||||
fun createKeystoreForCordaNode(sslKeyStorePath: Path,
|
||||
clientCAKeystorePath: Path,
|
||||
storePassword: String,
|
||||
keyPassword: String,
|
||||
caKeyStore: KeyStore,
|
||||
caKeyPassword: String,
|
||||
legalName: X500Name,
|
||||
signatureScheme: SignatureScheme = X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) {
|
||||
|
||||
val rootCACert = caKeyStore.getX509Certificate(X509Utilities.CORDA_ROOT_CA)
|
||||
val (intermediateCACert, intermediateCAKeyPair) = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, caKeyPassword)
|
||||
|
||||
val clientKey = Crypto.generateKeyPair(signatureScheme)
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName))), arrayOf())
|
||||
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCACert, intermediateCAKeyPair, legalName, clientKey.public, nameConstraints = nameConstraints)
|
||||
|
||||
val tlsKey = Crypto.generateKeyPair(signatureScheme)
|
||||
val clientTLSCert = X509Utilities.createCertificate(CertificateType.TLS, clientCACert, clientKey, legalName, tlsKey.public)
|
||||
|
||||
val keyPass = keyPassword.toCharArray()
|
||||
|
||||
val clientCAKeystore = loadOrCreateKeyStore(clientCAKeystorePath, storePassword)
|
||||
clientCAKeystore.addOrReplaceKey(
|
||||
X509Utilities.CORDA_CLIENT_CA,
|
||||
clientKey.private,
|
||||
keyPass,
|
||||
org.bouncycastle.cert.path.CertPath(arrayOf(clientCACert, intermediateCACert, rootCACert)))
|
||||
clientCAKeystore.save(clientCAKeystorePath, storePassword)
|
||||
|
||||
val tlsKeystore = loadOrCreateKeyStore(sslKeyStorePath, storePassword)
|
||||
tlsKeystore.addOrReplaceKey(
|
||||
X509Utilities.CORDA_CLIENT_TLS,
|
||||
tlsKey.private,
|
||||
keyPass,
|
||||
org.bouncycastle.cert.path.CertPath(arrayOf(clientTLSCert, clientCACert, intermediateCACert, rootCACert)))
|
||||
tlsKeystore.save(sslKeyStorePath, storePassword)
|
||||
}
|
@ -20,6 +20,8 @@ import net.corda.node.services.messaging.NodeLoginModule.Companion.NODE_ROLE
|
||||
import net.corda.node.services.messaging.NodeLoginModule.Companion.PEER_ROLE
|
||||
import net.corda.node.services.messaging.NodeLoginModule.Companion.RPC_ROLE
|
||||
import net.corda.node.services.messaging.NodeLoginModule.Companion.VERIFIER_ROLE
|
||||
import net.corda.node.utilities.getX509Certificate
|
||||
import net.corda.node.utilities.loadKeyStore
|
||||
import net.corda.nodeapi.*
|
||||
import net.corda.nodeapi.ArtemisMessagingComponent.Companion.NODE_USER
|
||||
import net.corda.nodeapi.ArtemisMessagingComponent.Companion.PEER_USER
|
||||
@ -264,8 +266,8 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
|
||||
@Throws(IOException::class, KeyStoreException::class)
|
||||
private fun createArtemisSecurityManager(): ActiveMQJAASSecurityManager {
|
||||
val keyStore = KeyStoreUtilities.loadKeyStore(config.sslKeystore, config.keyStorePassword)
|
||||
val trustStore = KeyStoreUtilities.loadKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
val keyStore = loadKeyStore(config.sslKeystore, config.keyStorePassword)
|
||||
val trustStore = loadKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
val ourCertificate = keyStore.getX509Certificate(CORDA_CLIENT_TLS)
|
||||
|
||||
// This is a sanity check and should not fail unless things have been misconfigured
|
||||
|
@ -1,5 +1,8 @@
|
||||
package net.corda.core.crypto
|
||||
package net.corda.node.utilities
|
||||
|
||||
import net.corda.core.crypto.CertificateAndKeyPair
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.cert
|
||||
import net.corda.core.exists
|
||||
import net.corda.core.read
|
||||
import net.corda.core.write
|
||||
@ -12,60 +15,58 @@ import java.nio.file.Path
|
||||
import java.security.*
|
||||
import java.security.cert.Certificate
|
||||
|
||||
object KeyStoreUtilities {
|
||||
val KEYSTORE_TYPE = "JKS"
|
||||
val KEYSTORE_TYPE = "JKS"
|
||||
|
||||
/**
|
||||
* Helper method to either open an existing keystore for modification, or create a new blank keystore.
|
||||
* @param keyStoreFilePath location of KeyStore file.
|
||||
* @param storePassword password to open the store. This does not have to be the same password as any keys stored,
|
||||
* but for SSL purposes this is recommended.
|
||||
* @return returns the KeyStore opened/created.
|
||||
*/
|
||||
fun loadOrCreateKeyStore(keyStoreFilePath: Path, storePassword: String): KeyStore {
|
||||
val pass = storePassword.toCharArray()
|
||||
val keyStore = KeyStore.getInstance(KEYSTORE_TYPE)
|
||||
if (keyStoreFilePath.exists()) {
|
||||
keyStoreFilePath.read { keyStore.load(it, pass) }
|
||||
} else {
|
||||
keyStore.load(null, pass)
|
||||
keyStoreFilePath.write { keyStore.store(it, pass) }
|
||||
}
|
||||
return keyStore
|
||||
/**
|
||||
* Helper method to either open an existing keystore for modification, or create a new blank keystore.
|
||||
* @param keyStoreFilePath location of KeyStore file.
|
||||
* @param storePassword password to open the store. This does not have to be the same password as any keys stored,
|
||||
* but for SSL purposes this is recommended.
|
||||
* @return returns the KeyStore opened/created.
|
||||
*/
|
||||
fun loadOrCreateKeyStore(keyStoreFilePath: Path, storePassword: String): KeyStore {
|
||||
val pass = storePassword.toCharArray()
|
||||
val keyStore = KeyStore.getInstance(KEYSTORE_TYPE)
|
||||
if (keyStoreFilePath.exists()) {
|
||||
keyStoreFilePath.read { keyStore.load(it, pass) }
|
||||
} else {
|
||||
keyStore.load(null, pass)
|
||||
keyStoreFilePath.write { keyStore.store(it, pass) }
|
||||
}
|
||||
return keyStore
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to open an existing keystore for modification/read.
|
||||
* @param keyStoreFilePath location of KeyStore file which must exist, or this will throw FileNotFoundException.
|
||||
* @param storePassword password to open the store. This does not have to be the same password as any keys stored,
|
||||
* but for SSL purposes this is recommended.
|
||||
* @return returns the KeyStore opened.
|
||||
* @throws IOException if there was an error reading the key store from the file.
|
||||
* @throws KeyStoreException if the password is incorrect or the key store is damaged.
|
||||
*/
|
||||
@Throws(KeyStoreException::class, IOException::class)
|
||||
fun loadKeyStore(keyStoreFilePath: Path, storePassword: String): KeyStore {
|
||||
return keyStoreFilePath.read { loadKeyStore(it, storePassword) }
|
||||
}
|
||||
/**
|
||||
* Helper method to open an existing keystore for modification/read.
|
||||
* @param keyStoreFilePath location of KeyStore file which must exist, or this will throw FileNotFoundException.
|
||||
* @param storePassword password to open the store. This does not have to be the same password as any keys stored,
|
||||
* but for SSL purposes this is recommended.
|
||||
* @return returns the KeyStore opened.
|
||||
* @throws IOException if there was an error reading the key store from the file.
|
||||
* @throws KeyStoreException if the password is incorrect or the key store is damaged.
|
||||
*/
|
||||
@Throws(KeyStoreException::class, IOException::class)
|
||||
fun loadKeyStore(keyStoreFilePath: Path, storePassword: String): KeyStore {
|
||||
return keyStoreFilePath.read { loadKeyStore(it, storePassword) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to open an existing keystore for modification/read.
|
||||
* @param input stream containing a KeyStore e.g. loaded from a resource file.
|
||||
* @param storePassword password to open the store. This does not have to be the same password as any keys stored,
|
||||
* but for SSL purposes this is recommended.
|
||||
* @return returns the KeyStore opened.
|
||||
* @throws IOException if there was an error reading the key store from the stream.
|
||||
* @throws KeyStoreException if the password is incorrect or the key store is damaged.
|
||||
*/
|
||||
@Throws(KeyStoreException::class, IOException::class)
|
||||
fun loadKeyStore(input: InputStream, storePassword: String): KeyStore {
|
||||
val pass = storePassword.toCharArray()
|
||||
val keyStore = KeyStore.getInstance(KEYSTORE_TYPE)
|
||||
input.use {
|
||||
keyStore.load(input, pass)
|
||||
}
|
||||
return keyStore
|
||||
/**
|
||||
* Helper method to open an existing keystore for modification/read.
|
||||
* @param input stream containing a KeyStore e.g. loaded from a resource file.
|
||||
* @param storePassword password to open the store. This does not have to be the same password as any keys stored,
|
||||
* but for SSL purposes this is recommended.
|
||||
* @return returns the KeyStore opened.
|
||||
* @throws IOException if there was an error reading the key store from the stream.
|
||||
* @throws KeyStoreException if the password is incorrect or the key store is damaged.
|
||||
*/
|
||||
@Throws(KeyStoreException::class, IOException::class)
|
||||
fun loadKeyStore(input: InputStream, storePassword: String): KeyStore {
|
||||
val pass = storePassword.toCharArray()
|
||||
val keyStore = KeyStore.getInstance(KEYSTORE_TYPE)
|
||||
input.use {
|
||||
keyStore.load(input, pass)
|
||||
}
|
||||
return keyStore
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,7 +108,6 @@ fun KeyStore.addOrReplaceCertificate(alias: String, cert: Certificate) {
|
||||
this.setCertificateEntry(alias, cert)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method save KeyStore to storage.
|
||||
* @param keyStoreFilePath the file location to save to.
|
||||
@ -118,7 +118,6 @@ fun KeyStore.save(keyStoreFilePath: Path, storePassword: String) = keyStoreFileP
|
||||
|
||||
fun KeyStore.store(out: OutputStream, password: String) = store(out, password.toCharArray())
|
||||
|
||||
|
||||
/**
|
||||
* Extract public and private keys from a KeyStore file assuming storage alias is known.
|
||||
* @param alias The name to lookup the Key and Certificate chain from.
|
||||
@ -146,7 +145,7 @@ fun KeyStore.getCertificateAndKeyPair(alias: String, keyPassword: String): Certi
|
||||
* @return The X509Certificate found in the KeyStore under the specified alias.
|
||||
*/
|
||||
fun KeyStore.getX509Certificate(alias: String): X509CertificateHolder {
|
||||
val encoded = getCertificate(alias)?.encoded ?: throw IllegalArgumentException("No certificate under alias \"${alias}\"")
|
||||
val encoded = getCertificate(alias)?.encoded ?: throw IllegalArgumentException("No certificate under alias \"$alias\"")
|
||||
return X509CertificateHolder(encoded)
|
||||
}
|
||||
|
@ -1,24 +1,30 @@
|
||||
package net.corda.node.utilities.registration
|
||||
|
||||
import net.corda.core.*
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.crypto.CertificateType
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_CLIENT_CA
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_CLIENT_TLS
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_ROOT_CA
|
||||
import net.corda.core.crypto.cert
|
||||
import net.corda.node.services.config.NodeConfiguration
|
||||
import net.corda.node.utilities.*
|
||||
import org.bouncycastle.cert.path.CertPath
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMWriter
|
||||
import org.bouncycastle.util.io.pem.PemObject
|
||||
import java.io.StringWriter
|
||||
import java.security.KeyPair
|
||||
import java.security.KeyStore
|
||||
import java.security.cert.Certificate
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
/**
|
||||
* This checks the config.certificatesDirectory field for certificates required to connect to a Corda network.
|
||||
* If the certificates are not found, a [org.bouncycastle.pkcs.PKCS10CertificationRequest] will be submitted to
|
||||
* Corda network permissioning server using [NetworkRegistrationService]. This process will enter a polling loop until the request has been approved, and then
|
||||
* the certificate chain will be downloaded and stored in [Keystore] reside in the certificates directory.
|
||||
* Corda network permissioning server using [NetworkRegistrationService]. This process will enter a polling loop until
|
||||
* the request has been approved, and then the certificate chain will be downloaded and stored in [KeyStore] reside in
|
||||
* the certificates directory.
|
||||
*/
|
||||
class NetworkRegistrationHelper(val config: NodeConfiguration, val certService: NetworkRegistrationService) {
|
||||
companion object {
|
||||
@ -33,7 +39,7 @@ class NetworkRegistrationHelper(val config: NodeConfiguration, val certService:
|
||||
|
||||
fun buildKeystore() {
|
||||
config.certificatesDirectory.createDirectories()
|
||||
val caKeyStore = KeyStoreUtilities.loadOrCreateKeyStore(config.nodeKeystore, keystorePassword)
|
||||
val caKeyStore = loadOrCreateKeyStore(config.nodeKeystore, keystorePassword)
|
||||
if (!caKeyStore.containsAlias(CORDA_CLIENT_CA)) {
|
||||
// Create or load self signed keypair from the key store.
|
||||
// We use the self sign certificate to store the key temporarily in the keystore while waiting for the request approval.
|
||||
@ -64,7 +70,7 @@ class NetworkRegistrationHelper(val config: NodeConfiguration, val certService:
|
||||
caKeyStore.deleteEntry(SELF_SIGNED_PRIVATE_KEY)
|
||||
caKeyStore.save(config.nodeKeystore, keystorePassword)
|
||||
// Save root certificates to trust store.
|
||||
val trustStore = KeyStoreUtilities.loadOrCreateKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
val trustStore = loadOrCreateKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
// Assumes certificate chain always starts with client certificate and end with root certificate.
|
||||
trustStore.addOrReplaceCertificate(CORDA_ROOT_CA, certificates.last())
|
||||
trustStore.save(config.trustStoreFile, config.trustStorePassword)
|
||||
@ -74,7 +80,7 @@ class NetworkRegistrationHelper(val config: NodeConfiguration, val certService:
|
||||
val sslKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val caCert = caKeyStore.getX509Certificate(CORDA_CLIENT_CA)
|
||||
val sslCert = X509Utilities.createCertificate(CertificateType.TLS, caCert, keyPair, caCert.subject, sslKey.public)
|
||||
val sslKeyStore = KeyStoreUtilities.loadOrCreateKeyStore(config.sslKeystore, keystorePassword)
|
||||
val sslKeyStore = loadOrCreateKeyStore(config.sslKeystore, keystorePassword)
|
||||
sslKeyStore.addOrReplaceKey(CORDA_CLIENT_TLS, sslKey.private, privateKeyPassword.toCharArray(),
|
||||
arrayOf(sslCert.cert, *certificates))
|
||||
sslKeyStore.save(config.sslKeystore, config.keyStorePassword)
|
||||
|
@ -6,6 +6,7 @@ import com.nhaarman.mockito_kotlin.mock
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.exists
|
||||
import net.corda.core.toTypedArray
|
||||
import net.corda.node.utilities.loadKeyStore
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.testing.getTestX509Name
|
||||
import net.corda.testing.testNodeConfiguration
|
||||
@ -52,10 +53,9 @@ class NetworkRegistrationHelperTest {
|
||||
assertTrue(config.sslKeystore.exists())
|
||||
assertTrue(config.trustStoreFile.exists())
|
||||
|
||||
val nodeKeystore = KeyStoreUtilities.loadKeyStore(config.nodeKeystore, config.keyStorePassword)
|
||||
val sslKeystore = KeyStoreUtilities.loadKeyStore(config.sslKeystore, config.keyStorePassword)
|
||||
val trustStore = KeyStoreUtilities.loadKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
|
||||
val nodeKeystore = loadKeyStore(config.nodeKeystore, config.keyStorePassword)
|
||||
val sslKeystore = loadKeyStore(config.sslKeystore, config.keyStorePassword)
|
||||
val trustStore = loadKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
|
||||
nodeKeystore.run {
|
||||
assertTrue(containsAlias(X509Utilities.CORDA_CLIENT_CA))
|
||||
|
Loading…
Reference in New Issue
Block a user