mirror of
https://github.com/corda/corda.git
synced 2025-02-03 01:31:24 +00:00
Fixed identity generation of single node notaries as used by the driver and MockNetwork. (#2296)
The identity cert generated used to be of type SERVICE_IDENTITY when it should have been a LEGAL_IDENTITY.
This commit is contained in:
parent
cb0b311077
commit
39d25958e2
@ -1,66 +1,87 @@
|
||||
package net.corda.nodeapi.internal
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.cert
|
||||
import net.corda.core.internal.createDirectories
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.internal.toX509CertHolder
|
||||
import net.corda.core.utilities.trace
|
||||
import net.corda.nodeapi.internal.config.NodeSSLConfiguration
|
||||
import net.corda.nodeapi.internal.crypto.*
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.nio.file.Path
|
||||
import java.security.cert.X509Certificate
|
||||
|
||||
/**
|
||||
* Contains utility methods for generating identities for a node.
|
||||
*
|
||||
* WARNING: This is not application for production use and must never called by the node.
|
||||
*/
|
||||
// TODO Rename to DevIdentityGenerator
|
||||
object IdentityGenerator {
|
||||
private val log = LoggerFactory.getLogger(javaClass)
|
||||
|
||||
// TODO These don't need to be prefixes but can be the full aliases
|
||||
// TODO Move these constants out of here as the node needs access to them
|
||||
const val NODE_IDENTITY_ALIAS_PREFIX = "identity"
|
||||
const val DISTRIBUTED_NOTARY_ALIAS_PREFIX = "distributed-notary"
|
||||
|
||||
fun generateNodeIdentity(dir: Path, legalName: CordaX500Name, customRootCert: X509Certificate? = null): Party {
|
||||
return generateToDisk(listOf(dir), legalName, NODE_IDENTITY_ALIAS_PREFIX, threshold = 1, customRootCert = customRootCert)
|
||||
/**
|
||||
* Install a node key store for the given node directory using the given legal name and an optional root cert. If no
|
||||
* root cert is specified then the default one in certificates/cordadevcakeys.jks is used.
|
||||
*/
|
||||
fun installKeyStoreWithNodeIdentity(nodeDir: Path, legalName: CordaX500Name, customRootCert: X509Certificate? = null): Party {
|
||||
val nodeSslConfig = object : NodeSSLConfiguration {
|
||||
override val baseDirectory = nodeDir
|
||||
override val keyStorePassword: String = "cordacadevpass"
|
||||
override val trustStorePassword get() = throw NotImplementedError("Not expected to be called")
|
||||
}
|
||||
|
||||
// TODO The passwords for the dev key stores are spread everywhere and should be constants in a single location
|
||||
val caKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/cordadevcakeys.jks"), "cordacadevpass")
|
||||
val intermediateCa = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, "cordacadevkeypass")
|
||||
// TODO If using a custom root cert, then the intermidate cert needs to be generated from it as well, and not taken from the default
|
||||
val rootCert = customRootCert ?: caKeyStore.getCertificate(X509Utilities.CORDA_ROOT_CA)
|
||||
|
||||
nodeSslConfig.certificatesDirectory.createDirectories()
|
||||
nodeSslConfig.createDevKeyStores(rootCert.toX509CertHolder(), intermediateCa, legalName)
|
||||
|
||||
val keyStoreWrapper = KeyStoreWrapper(nodeSslConfig.nodeKeystore, nodeSslConfig.keyStorePassword)
|
||||
val identity = keyStoreWrapper.storeLegalIdentity(legalName, "$NODE_IDENTITY_ALIAS_PREFIX-private-key", Crypto.generateKeyPair())
|
||||
return identity.party
|
||||
}
|
||||
|
||||
fun generateDistributedNotaryIdentity(dirs: List<Path>, notaryName: CordaX500Name, threshold: Int = 1, customRootCert: X509Certificate? = null): Party {
|
||||
return generateToDisk(dirs, notaryName, DISTRIBUTED_NOTARY_ALIAS_PREFIX, threshold, customRootCert)
|
||||
}
|
||||
require(dirs.isNotEmpty())
|
||||
|
||||
/**
|
||||
* Generates signing key pairs and a common distributed service identity for a set of nodes.
|
||||
* The key pairs and the group identity get serialized to disk in the corresponding node directories.
|
||||
* This method should be called *before* any of the nodes are started.
|
||||
*
|
||||
* @param dirs List of node directories to place the generated identity and key pairs in.
|
||||
* @param name The name of the identity.
|
||||
* @param threshold The threshold for the generated group [CompositeKey].
|
||||
* @param customRootCert the certificate to use as the Corda root CA. If not specified the one in
|
||||
* internal/certificates/cordadevcakeys.jks is used.
|
||||
*/
|
||||
private fun generateToDisk(dirs: List<Path>,
|
||||
name: CordaX500Name,
|
||||
aliasPrefix: String,
|
||||
threshold: Int,
|
||||
customRootCert: X509Certificate?): Party {
|
||||
log.trace { "Generating identity \"$name\" for nodes: ${dirs.joinToString()}" }
|
||||
log.trace { "Generating identity \"$notaryName\" for nodes: ${dirs.joinToString()}" }
|
||||
val keyPairs = (1..dirs.size).map { generateKeyPair() }
|
||||
val key = CompositeKey.Builder().addKeys(keyPairs.map { it.public }).build(threshold)
|
||||
val compositeKey = CompositeKey.Builder().addKeys(keyPairs.map { it.public }).build(threshold)
|
||||
|
||||
val caKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/cordadevcakeys.jks"), "cordacadevpass")
|
||||
val intermediateCa = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, "cordacadevkeypass")
|
||||
// TODO If using a custom root cert, then the intermidate cert needs to be generated from it as well, and not taken from the default
|
||||
val rootCert = customRootCert ?: caKeyStore.getCertificate(X509Utilities.CORDA_ROOT_CA)
|
||||
|
||||
keyPairs.zip(dirs) { keyPair, dir ->
|
||||
val serviceKeyCert = X509Utilities.createCertificate(CertificateType.SERVICE_IDENTITY, intermediateCa.certificate, intermediateCa.keyPair, name, keyPair.public)
|
||||
val compositeKeyCert = X509Utilities.createCertificate(CertificateType.SERVICE_IDENTITY, intermediateCa.certificate, intermediateCa.keyPair, name, key)
|
||||
val certPath = (dir / "certificates").createDirectories() / "distributedService.jks"
|
||||
val keystore = loadOrCreateKeyStore(certPath, "cordacadevpass")
|
||||
keystore.setCertificateEntry("$aliasPrefix-composite-key", compositeKeyCert.cert)
|
||||
keystore.setKeyEntry("$aliasPrefix-private-key", keyPair.private, "cordacadevkeypass".toCharArray(), arrayOf(serviceKeyCert.cert, intermediateCa.certificate.cert, rootCert))
|
||||
keystore.save(certPath, "cordacadevpass")
|
||||
keyPairs.zip(dirs) { keyPair, nodeDir ->
|
||||
val (serviceKeyCert, compositeKeyCert) = listOf(keyPair.public, compositeKey).map { publicKey ->
|
||||
X509Utilities.createCertificate(CertificateType.SERVICE_IDENTITY, intermediateCa.certificate, intermediateCa.keyPair, notaryName, publicKey)
|
||||
}
|
||||
val distServKeyStoreFile = (nodeDir / "certificates").createDirectories() / "distributedService.jks"
|
||||
val keystore = loadOrCreateKeyStore(distServKeyStoreFile, "cordacadevpass")
|
||||
keystore.setCertificateEntry("$DISTRIBUTED_NOTARY_ALIAS_PREFIX-composite-key", compositeKeyCert.cert)
|
||||
keystore.setKeyEntry(
|
||||
"$DISTRIBUTED_NOTARY_ALIAS_PREFIX-private-key",
|
||||
keyPair.private,
|
||||
"cordacadevkeypass".toCharArray(),
|
||||
arrayOf(serviceKeyCert.cert, intermediateCa.certificate.cert, rootCert))
|
||||
keystore.save(distServKeyStoreFile, "cordacadevpass")
|
||||
}
|
||||
|
||||
return Party(name, key)
|
||||
return Party(notaryName, compositeKey)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package net.corda.nodeapi.internal
|
||||
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.x500Name
|
||||
import net.corda.nodeapi.internal.config.SSLConfiguration
|
||||
import net.corda.nodeapi.internal.crypto.*
|
||||
import org.bouncycastle.asn1.x509.GeneralName
|
||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||
import org.bouncycastle.asn1.x509.NameConstraints
|
||||
import org.bouncycastle.cert.X509CertificateHolder
|
||||
|
||||
/**
|
||||
* Create the node and SSL key stores needed by a node. The node key store will be populated with a node CA cert (using
|
||||
* the given legal name), and the SSL key store will store the TLS cert which is a sub-cert of the node CA.
|
||||
*/
|
||||
fun SSLConfiguration.createDevKeyStores(rootCert: X509CertificateHolder, intermediateCa: CertificateAndKeyPair, legalName: CordaX500Name) {
|
||||
val nodeCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.x500Name))), arrayOf())
|
||||
val nodeCaCert = X509Utilities.createCertificate(CertificateType.NODE_CA,
|
||||
intermediateCa.certificate,
|
||||
intermediateCa.keyPair,
|
||||
legalName,
|
||||
nodeCaKeyPair.public,
|
||||
nameConstraints = nameConstraints)
|
||||
|
||||
loadOrCreateKeyStore(nodeKeystore, keyStorePassword).apply {
|
||||
addOrReplaceKey(
|
||||
X509Utilities.CORDA_CLIENT_CA,
|
||||
nodeCaKeyPair.private,
|
||||
keyStorePassword.toCharArray(),
|
||||
arrayOf(nodeCaCert, intermediateCa.certificate, rootCert))
|
||||
save(nodeKeystore, keyStorePassword)
|
||||
}
|
||||
|
||||
val tlsKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val tlsCert = X509Utilities.createCertificate(CertificateType.TLS, nodeCaCert, nodeCaKeyPair, legalName, tlsKeyPair.public)
|
||||
|
||||
loadOrCreateKeyStore(sslKeystore, keyStorePassword).apply {
|
||||
addOrReplaceKey(
|
||||
X509Utilities.CORDA_CLIENT_TLS,
|
||||
tlsKeyPair.private,
|
||||
keyStorePassword.toCharArray(),
|
||||
arrayOf(tlsCert, nodeCaCert, intermediateCa.certificate, rootCert))
|
||||
save(sslKeystore, keyStorePassword)
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ interface SSLConfiguration {
|
||||
val trustStorePassword: String
|
||||
val certificatesDirectory: Path
|
||||
val sslKeystore: Path get() = certificatesDirectory / "sslkeystore.jks"
|
||||
// TODO This looks like it should be in NodeSSLConfiguration
|
||||
val nodeKeystore: Path get() = certificatesDirectory / "nodekeystore.jks"
|
||||
val trustStoreFile: Path get() = certificatesDirectory / "truststore.jks"
|
||||
}
|
||||
|
@ -1,41 +1,26 @@
|
||||
package net.corda.nodeapi.internal.crypto
|
||||
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.internal.cert
|
||||
import net.corda.core.internal.read
|
||||
import java.nio.file.Path
|
||||
import java.security.KeyPair
|
||||
import java.security.PublicKey
|
||||
import java.security.cert.CertPath
|
||||
import java.security.cert.Certificate
|
||||
|
||||
class KeyStoreWrapper(private val storePath: Path, private val storePassword: String) {
|
||||
private val keyStore = storePath.read { loadKeyStore(it, storePassword) }
|
||||
|
||||
private fun createCertificate(serviceName: CordaX500Name, pubKey: PublicKey): CertPath {
|
||||
val clientCertPath = keyStore.getCertificateChain(X509Utilities.CORDA_CLIENT_CA)
|
||||
// TODO This method seems misplaced in this class.
|
||||
fun storeLegalIdentity(legalName: CordaX500Name, alias: String, keyPair: KeyPair): PartyAndCertificate {
|
||||
val nodeCaCertChain = keyStore.getCertificateChain(X509Utilities.CORDA_CLIENT_CA)
|
||||
val nodeCa = getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA)
|
||||
val identityCert = X509Utilities.createCertificate(CertificateType.LEGAL_IDENTITY, nodeCa.certificate, nodeCa.keyPair, legalName, keyPair.public)
|
||||
val identityCertPath = X509CertificateFactory().generateCertPath(identityCert.cert, *nodeCaCertChain)
|
||||
// Assume key password = store password.
|
||||
val clientCA = certificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA)
|
||||
// Create new keys and store in keystore.
|
||||
val cert = X509Utilities.createCertificate(CertificateType.LEGAL_IDENTITY, clientCA.certificate, clientCA.keyPair, serviceName, pubKey)
|
||||
val certPath = X509CertificateFactory().generateCertPath(cert.cert, *clientCertPath)
|
||||
require(certPath.certificates.isNotEmpty()) { "Certificate path cannot be empty" }
|
||||
// TODO: X509Utilities.validateCertificateChain()
|
||||
return certPath
|
||||
}
|
||||
|
||||
fun signAndSaveNewKeyPair(serviceName: CordaX500Name, privateKeyAlias: String, keyPair: KeyPair) {
|
||||
val certPath = createCertificate(serviceName, keyPair.public)
|
||||
// Assume key password = store password.
|
||||
keyStore.addOrReplaceKey(privateKeyAlias, keyPair.private, storePassword.toCharArray(), certPath.certificates.toTypedArray())
|
||||
keyStore.save(storePath, storePassword)
|
||||
}
|
||||
|
||||
fun savePublicKey(serviceName: CordaX500Name, pubKeyAlias: String, pubKey: PublicKey) {
|
||||
val certPath = createCertificate(serviceName, pubKey)
|
||||
// Assume key password = store password.
|
||||
keyStore.addOrReplaceCertificate(pubKeyAlias, certPath.certificates.first())
|
||||
keyStore.addOrReplaceKey(alias, keyPair.private, storePassword.toCharArray(), identityCertPath.certificates.toTypedArray())
|
||||
keyStore.save(storePath, storePassword)
|
||||
return PartyAndCertificate(identityCertPath)
|
||||
}
|
||||
|
||||
// Delegate methods to keystore. Sadly keystore doesn't have an interface.
|
||||
@ -47,5 +32,5 @@ class KeyStoreWrapper(private val storePath: Path, private val storePassword: St
|
||||
|
||||
fun getCertificate(alias: String): Certificate = keyStore.getCertificate(alias)
|
||||
|
||||
fun certificateAndKeyPair(alias: String): CertificateAndKeyPair = keyStore.getCertificateAndKeyPair(alias, storePassword)
|
||||
fun getCertificateAndKeyPair(alias: String): CertificateAndKeyPair = keyStore.getCertificateAndKeyPair(alias, storePassword)
|
||||
}
|
@ -12,12 +12,16 @@ import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.node.serialization.KryoServerSerializationScheme
|
||||
import net.corda.node.services.config.createKeystoreForCordaNode
|
||||
import net.corda.nodeapi.internal.config.SSLConfiguration
|
||||
import net.corda.nodeapi.internal.createDevKeyStores
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
import net.corda.nodeapi.internal.serialization.SerializationContextImpl
|
||||
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
|
||||
import net.corda.nodeapi.internal.serialization.kryo.KryoHeaderV0_1
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.ALICE_NAME
|
||||
import net.corda.testing.BOB_NAME
|
||||
import net.corda.testing.TestIdentity
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x509.BasicConstraints
|
||||
import org.bouncycastle.asn1.x509.Extension
|
||||
@ -33,11 +37,8 @@ import java.io.IOException
|
||||
import java.net.InetAddress
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.file.Path
|
||||
import java.security.KeyStore
|
||||
import java.security.PrivateKey
|
||||
import java.security.SecureRandom
|
||||
import java.security.cert.CertPath
|
||||
import java.security.cert.Certificate
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.*
|
||||
import java.util.stream.Stream
|
||||
@ -52,6 +53,11 @@ class X509UtilitiesTest {
|
||||
val MEGA_CORP = TestIdentity(CordaX500Name("MegaCorp", "London", "GB")).party
|
||||
val BOB get() = bob.party
|
||||
val BOB_PUBKEY get() = bob.publicKey
|
||||
val CIPHER_SUITES = arrayOf(
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
)
|
||||
}
|
||||
|
||||
@Rule
|
||||
@ -155,107 +161,62 @@ class X509UtilitiesTest {
|
||||
assertEquals(edDSAKeypair.private, privateKey)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create full CA keystore`() {
|
||||
val tmpKeyStore = tempFile("keystore.jks")
|
||||
val tmpTrustStore = tempFile("truststore.jks")
|
||||
|
||||
// Generate Root and Intermediate CA cert and put both into key store and root ca cert into trust store
|
||||
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 = 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
|
||||
assertEquals(rootCaCert, rootCaFromTrustStore)
|
||||
rootCaCert.checkValidity(Date())
|
||||
rootCaCert.verify(rootCaCert.publicKey)
|
||||
|
||||
// Now sign something with private key and verify against certificate public key
|
||||
val testData = "12345".toByteArray()
|
||||
val caSignature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, rootCaPrivateKey, testData)
|
||||
assertTrue { Crypto.isValid(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, rootCaCert.publicKey, caSignature, testData) }
|
||||
|
||||
// Load back generated intermediate CA Cert and private key
|
||||
val intermediateCaCert = keyStore.getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA) as X509Certificate
|
||||
val intermediateCaCertPrivateKey = keyStore.getKey(X509Utilities.CORDA_INTERMEDIATE_CA, "keypass".toCharArray()) as PrivateKey
|
||||
intermediateCaCert.checkValidity(Date())
|
||||
intermediateCaCert.verify(rootCaCert.publicKey)
|
||||
|
||||
// Now sign something with private key and verify against certificate public key
|
||||
val intermediateSignature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, intermediateCaCertPrivateKey, testData)
|
||||
assertTrue { Crypto.isValid(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, intermediateCaCert.publicKey, intermediateSignature, testData) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create server certificate in keystore for SSL`() {
|
||||
val tmpCAKeyStore = tempFile("keystore.jks")
|
||||
val tmpTrustStore = tempFile("truststore.jks")
|
||||
val tmpSSLKeyStore = tempFile("sslkeystore.jks")
|
||||
val tmpServerKeyStore = tempFile("serverkeystore.jks")
|
||||
val sslConfig = object : SSLConfiguration {
|
||||
override val certificatesDirectory = tempFolder.root.toPath()
|
||||
override val keyStorePassword = "serverstorepass"
|
||||
override val trustStorePassword = "trustpass"
|
||||
}
|
||||
|
||||
// Generate Root and Intermediate CA cert and put both into key store and root ca cert into trust store
|
||||
createCAKeyStoreAndTrustStore(tmpCAKeyStore,
|
||||
"cakeystorepass",
|
||||
"cakeypass",
|
||||
tmpTrustStore,
|
||||
"trustpass")
|
||||
|
||||
// Load signing intermediate CA cert
|
||||
val caKeyStore = loadKeyStore(tmpCAKeyStore, "cakeystorepass")
|
||||
val caCertAndKey = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, "cakeypass")
|
||||
val (rootCert, intermediateCa) = createRootCertAndIntermediateCa()
|
||||
|
||||
// Generate server cert and private key and populate another keystore suitable for SSL
|
||||
createKeystoreForCordaNode(tmpSSLKeyStore, tmpServerKeyStore, "serverstorepass", "serverkeypass", caKeyStore, "cakeypass", MEGA_CORP.name)
|
||||
sslConfig.createDevKeyStores(rootCert, intermediateCa, MEGA_CORP.name)
|
||||
|
||||
// Load back server certificate
|
||||
val serverKeyStore = loadKeyStore(tmpServerKeyStore, "serverstorepass")
|
||||
val serverCertAndKey = serverKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA, "serverkeypass")
|
||||
val serverKeyStore = loadKeyStore(sslConfig.nodeKeystore, sslConfig.keyStorePassword)
|
||||
val (serverCert, serverKeyPair) = serverKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA, sslConfig.keyStorePassword)
|
||||
|
||||
serverCertAndKey.certificate.isValidOn(Date())
|
||||
serverCertAndKey.certificate.isSignatureValid(JcaContentVerifierProviderBuilder().build(caCertAndKey.certificate.subjectPublicKeyInfo))
|
||||
serverCert.cert.checkValidity()
|
||||
serverCert.cert.verify(intermediateCa.certificate.cert.publicKey)
|
||||
assertThat(CordaX500Name.parse(serverCert.subject.toString())).isEqualTo(MEGA_CORP.name)
|
||||
|
||||
assertTrue { serverCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.organisation) }
|
||||
// Load back SSL certificate
|
||||
val sslKeyStore = loadKeyStore(sslConfig.sslKeystore, sslConfig.keyStorePassword)
|
||||
val (sslCert) = sslKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_TLS, sslConfig.keyStorePassword)
|
||||
|
||||
// Load back server certificate
|
||||
val sslKeyStore = loadKeyStore(tmpSSLKeyStore, "serverstorepass")
|
||||
val sslCertAndKey = sslKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_TLS, "serverkeypass")
|
||||
sslCert.cert.checkValidity()
|
||||
sslCert.cert.verify(serverCert.cert.publicKey)
|
||||
assertThat(CordaX500Name.parse(sslCert.subject.toString())).isEqualTo(MEGA_CORP.name)
|
||||
|
||||
sslCertAndKey.certificate.isValidOn(Date())
|
||||
sslCertAndKey.certificate.isSignatureValid(JcaContentVerifierProviderBuilder().build(serverCertAndKey.certificate.subjectPublicKeyInfo))
|
||||
|
||||
assertTrue { sslCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.organisation) }
|
||||
// Now sign something with private key and verify against certificate public key
|
||||
val testData = "123456".toByteArray()
|
||||
val signature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, serverCertAndKey.keyPair.private, testData)
|
||||
val publicKey = Crypto.toSupportedPublicKey(serverCertAndKey.certificate.subjectPublicKeyInfo)
|
||||
val signature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, serverKeyPair.private, testData)
|
||||
val publicKey = Crypto.toSupportedPublicKey(serverCert.subjectPublicKeyInfo)
|
||||
assertTrue { Crypto.isValid(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, publicKey, signature, testData) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create server cert and use in SSL socket`() {
|
||||
val tmpCAKeyStore = tempFile("keystore.jks")
|
||||
val tmpTrustStore = tempFile("truststore.jks")
|
||||
val tmpSSLKeyStore = tempFile("sslkeystore.jks")
|
||||
val tmpServerKeyStore = tempFile("serverkeystore.jks")
|
||||
val sslConfig = object : SSLConfiguration {
|
||||
override val certificatesDirectory = tempFolder.root.toPath()
|
||||
override val keyStorePassword = "serverstorepass"
|
||||
override val trustStorePassword = "trustpass"
|
||||
}
|
||||
|
||||
// Generate Root and Intermediate CA cert and put both into key store and root ca cert into trust store
|
||||
val caKeyStore = createCAKeyStoreAndTrustStore(tmpCAKeyStore,
|
||||
"cakeystorepass",
|
||||
"cakeypass",
|
||||
tmpTrustStore,
|
||||
"trustpass")
|
||||
val (rootCert, intermediateCa) = createRootCertAndIntermediateCa()
|
||||
|
||||
// Generate server cert and private key and populate another keystore suitable for SSL
|
||||
createKeystoreForCordaNode(tmpSSLKeyStore, tmpServerKeyStore, "serverstorepass", "serverstorepass", caKeyStore, "cakeypass", MEGA_CORP.name)
|
||||
val keyStore = loadKeyStore(tmpSSLKeyStore, "serverstorepass")
|
||||
val trustStore = loadKeyStore(tmpTrustStore, "trustpass")
|
||||
sslConfig.createDevKeyStores(rootCert, intermediateCa, MEGA_CORP.name)
|
||||
sslConfig.createTrustStore(rootCert.cert)
|
||||
|
||||
val keyStore = loadKeyStore(sslConfig.sslKeystore, sslConfig.keyStorePassword)
|
||||
val trustStore = loadKeyStore(sslConfig.trustStoreFile, sslConfig.trustStorePassword)
|
||||
|
||||
val context = SSLContext.getInstance("TLS")
|
||||
val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
|
||||
keyManagerFactory.init(keyStore, "serverstorepass".toCharArray())
|
||||
keyManagerFactory.init(keyStore, sslConfig.keyStorePassword.toCharArray())
|
||||
val keyManagers = keyManagerFactory.keyManagers
|
||||
val trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
trustMgrFactory.init(trustStore)
|
||||
@ -266,13 +227,7 @@ class X509UtilitiesTest {
|
||||
val clientSocketFactory = context.socketFactory
|
||||
|
||||
val serverSocket = serverSocketFactory.createServerSocket(0) as SSLServerSocket // use 0 to get first free socket
|
||||
val serverParams = SSLParameters(arrayOf("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"),
|
||||
arrayOf("TLSv1.2"))
|
||||
val serverParams = SSLParameters(CIPHER_SUITES, arrayOf("TLSv1.2"))
|
||||
serverParams.wantClientAuth = true
|
||||
serverParams.needClientAuth = true
|
||||
serverParams.endpointIdentificationAlgorithm = null // Reconfirm default no server name indication, use our own validator.
|
||||
@ -280,13 +235,7 @@ class X509UtilitiesTest {
|
||||
serverSocket.useClientMode = false
|
||||
|
||||
val clientSocket = clientSocketFactory.createSocket() as SSLSocket
|
||||
val clientParams = SSLParameters(arrayOf("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"),
|
||||
arrayOf("TLSv1.2"))
|
||||
val clientParams = SSLParameters(CIPHER_SUITES, arrayOf("TLSv1.2"))
|
||||
clientParams.endpointIdentificationAlgorithm = null // Reconfirm default no server name indication, use our own validator.
|
||||
clientSocket.sslParameters = clientParams
|
||||
clientSocket.useClientMode = true
|
||||
@ -344,60 +293,30 @@ class X509UtilitiesTest {
|
||||
|
||||
private fun tempFile(name: String): Path = tempFolder.root.toPath() / name
|
||||
|
||||
/**
|
||||
* All in one wrapper to manufacture a root CA cert and an Intermediate CA cert.
|
||||
* Normally this would be run once and then the outputs would be re-used repeatedly to manufacture the server certs
|
||||
* @param keyStoreFilePath The output KeyStore path to publish the private keys of the CA root and intermediate certs into.
|
||||
* @param storePassword The storage password to protect access to the generated KeyStore and public certificates
|
||||
* @param keyPassword The password that protects the CA private keys.
|
||||
* Unlike the SSL libraries that tend to assume the password is the same as the keystore password.
|
||||
* These CA private keys should be protected more effectively with a distinct password.
|
||||
* @param trustStoreFilePath The output KeyStore to place the Root CA public certificate, which can be used as an SSL truststore
|
||||
* @param trustStorePassword The password to protect the truststore
|
||||
* @return The KeyStore object that was saved to file
|
||||
*/
|
||||
private fun createCAKeyStoreAndTrustStore(keyStoreFilePath: Path,
|
||||
storePassword: String,
|
||||
keyPassword: String,
|
||||
trustStoreFilePath: Path,
|
||||
trustStorePassword: String
|
||||
): KeyStore {
|
||||
val rootCAKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val baseName = CordaX500Name(organisation = "R3CEV", locality = "London", country = "GB")
|
||||
val rootCACert = X509Utilities.createSelfSignedCACertificate(baseName.copy(commonName = "Corda Node Root CA"), rootCAKey)
|
||||
private fun createRootCertAndIntermediateCa(): Pair<X509CertificateHolder, CertificateAndKeyPair> {
|
||||
val rootKeyPair = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val baseName = CordaX500Name(organisation = "R3 Ltd", locality = "London", country = "GB")
|
||||
val rootCert = X509Utilities.createSelfSignedCACertificate(baseName.copy(commonName = "Corda Root CA"), rootKeyPair)
|
||||
|
||||
val intermediateCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val intermediateCACert = X509Utilities.createCertificate(
|
||||
val intermediateCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val intermediateCaCert = X509Utilities.createCertificate(
|
||||
CertificateType.INTERMEDIATE_CA,
|
||||
rootCACert,
|
||||
rootCAKey,
|
||||
baseName.copy(commonName = "Corda Node Intermediate CA"),
|
||||
intermediateCAKeyPair.public)
|
||||
rootCert,
|
||||
rootKeyPair,
|
||||
baseName.copy(commonName = "Corda Intermediate CA"),
|
||||
intermediateCaKeyPair.public)
|
||||
|
||||
val keyPass = keyPassword.toCharArray()
|
||||
val keyStore = loadOrCreateKeyStore(keyStoreFilePath, storePassword)
|
||||
return Pair(rootCert, CertificateAndKeyPair(intermediateCaCert, intermediateCaKeyPair))
|
||||
}
|
||||
|
||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_ROOT_CA, rootCAKey.private, keyPass, arrayOf<Certificate>(rootCACert.cert))
|
||||
|
||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_INTERMEDIATE_CA,
|
||||
intermediateCAKeyPair.private,
|
||||
keyPass,
|
||||
Stream.of(intermediateCACert, rootCACert).map { it.cert }.toTypedArray<Certificate>())
|
||||
|
||||
keyStore.save(keyStoreFilePath, storePassword)
|
||||
|
||||
val trustStore = loadOrCreateKeyStore(trustStoreFilePath, trustStorePassword)
|
||||
|
||||
trustStore.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCACert.cert)
|
||||
trustStore.addOrReplaceCertificate(X509Utilities.CORDA_INTERMEDIATE_CA, intermediateCACert.cert)
|
||||
|
||||
trustStore.save(trustStoreFilePath, trustStorePassword)
|
||||
|
||||
return keyStore
|
||||
private fun SSLConfiguration.createTrustStore(rootCert: X509Certificate) {
|
||||
val trustStore = loadOrCreateKeyStore(trustStoreFile, trustStorePassword)
|
||||
trustStore.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCert)
|
||||
trustStore.save(trustStoreFile, trustStorePassword)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get correct private key type from Keystore`() {
|
||||
fun `get correct private key type from Keystore`() {
|
||||
val keyPair = generateKeyPair(Crypto.ECDSA_SECP256R1_SHA256)
|
||||
val testName = CordaX500Name(commonName = "Test", organisation = "R3 Ltd", locality = "London", country = "GB")
|
||||
val selfSignCert = X509Utilities.createSelfSignedCACertificate(testName, keyPair)
|
||||
|
@ -696,7 +696,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
|
||||
val trustStore = KeyStoreWrapper(configuration.trustStoreFile, configuration.trustStorePassword)
|
||||
val caKeyStore = KeyStoreWrapper(configuration.nodeKeystore, configuration.keyStorePassword)
|
||||
val trustRoot = trustStore.getX509Certificate(X509Utilities.CORDA_ROOT_CA)
|
||||
val clientCa = caKeyStore.certificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA)
|
||||
val clientCa = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA)
|
||||
val caCertificates = arrayOf(identityCert, clientCa.certificate.cert)
|
||||
return PersistentIdentityService(trustRoot, *caCertificates)
|
||||
}
|
||||
@ -739,10 +739,10 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
|
||||
"Unable to find in the key store the identity of the distributed notary ($id) the node is part of")
|
||||
// TODO: Remove use of [IdentityGenerator.generateToDisk].
|
||||
log.info("$privateKeyAlias not found in key store ${configuration.nodeKeystore}, generating fresh key!")
|
||||
keyStore.signAndSaveNewKeyPair(singleName, privateKeyAlias, generateKeyPair())
|
||||
keyStore.storeLegalIdentity(singleName, privateKeyAlias, generateKeyPair())
|
||||
}
|
||||
|
||||
val (x509Cert, keyPair) = keyStore.certificateAndKeyPair(privateKeyAlias)
|
||||
val (x509Cert, keyPair) = keyStore.getCertificateAndKeyPair(privateKeyAlias)
|
||||
|
||||
// TODO: Use configuration to indicate composite key should be used instead of public key for the identity.
|
||||
val compositeKeyAlias = "$id-composite-key"
|
||||
|
@ -4,18 +4,16 @@ import com.typesafe.config.Config
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigParseOptions
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SignatureScheme
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.*
|
||||
import net.corda.core.internal.createDirectories
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.internal.exists
|
||||
import net.corda.core.internal.toX509CertHolder
|
||||
import net.corda.nodeapi.internal.config.SSLConfiguration
|
||||
import net.corda.nodeapi.internal.createDevKeyStores
|
||||
import net.corda.nodeapi.internal.crypto.*
|
||||
import org.bouncycastle.asn1.x509.GeneralName
|
||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||
import org.bouncycastle.asn1.x509.NameConstraints
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.nio.file.Path
|
||||
import java.security.KeyStore
|
||||
|
||||
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)
|
||||
@ -45,8 +43,10 @@ object ConfigHelper {
|
||||
* Strictly for dev only automatically construct a server certificate/private key signed from
|
||||
* the CA certs in Node resources. Then provision KeyStores into certificates folder under node path.
|
||||
*/
|
||||
// TODO Move this to KeyStoreConfigHelpers
|
||||
fun NodeConfiguration.configureWithDevSSLCertificate() = configureDevKeyAndTrustStores(myLegalName)
|
||||
|
||||
// TODO Move this to KeyStoreConfigHelpers
|
||||
fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500Name) {
|
||||
certificatesDirectory.createDirectories()
|
||||
if (!trustStoreFile.exists()) {
|
||||
@ -54,7 +54,9 @@ fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500Name) {
|
||||
}
|
||||
if (!sslKeystore.exists() || !nodeKeystore.exists()) {
|
||||
val caKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/cordadevcakeys.jks"), "cordacadevpass")
|
||||
createKeystoreForCordaNode(sslKeystore, nodeKeystore, keyStorePassword, keyStorePassword, caKeyStore, "cordacadevkeypass", myLegalName)
|
||||
val rootCert = caKeyStore.getX509Certificate(X509Utilities.CORDA_ROOT_CA).toX509CertHolder()
|
||||
val intermediateCa = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, "cordacadevkeypass")
|
||||
createDevKeyStores(rootCert, intermediateCa, myLegalName)
|
||||
|
||||
// Move distributed service composite key (generated by IdentityGenerator.generateToDisk) to keystore if exists.
|
||||
val distributedServiceKeystore = certificatesDirectory / "distributedService.jks"
|
||||
@ -73,58 +75,3 @@ fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500Name) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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: CordaX500Name,
|
||||
signatureScheme: SignatureScheme = X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) {
|
||||
|
||||
val rootCACert = caKeyStore.getX509Certificate(X509Utilities.CORDA_ROOT_CA).toX509CertHolder()
|
||||
val (intermediateCACert, intermediateCAKeyPair) = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, caKeyPassword)
|
||||
|
||||
val clientKey = Crypto.generateKeyPair(signatureScheme)
|
||||
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.x500Name))), arrayOf())
|
||||
val clientCACert = X509Utilities.createCertificate(CertificateType.NODE_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,
|
||||
arrayOf(clientCACert, intermediateCACert, rootCACert))
|
||||
clientCAKeystore.save(clientCAKeystorePath, storePassword)
|
||||
|
||||
val tlsKeystore = loadOrCreateKeyStore(sslKeyStorePath, storePassword)
|
||||
tlsKeystore.addOrReplaceKey(
|
||||
X509Utilities.CORDA_CLIENT_TLS,
|
||||
tlsKey.private,
|
||||
keyPass,
|
||||
arrayOf(clientTLSCert, clientCACert, intermediateCACert, rootCACert))
|
||||
tlsKeystore.save(sslKeyStorePath, storePassword)
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration, private v
|
||||
caKeyStore.save(config.nodeKeystore, keystorePassword)
|
||||
println("Node private key and certificate stored in ${config.nodeKeystore}.")
|
||||
|
||||
// TODO This should actually be using X509Utilities.validateCertificateChain
|
||||
// Check that the root of the signed certificate matches the expected certificate in the truststore.
|
||||
if (rootCert != certificates.last()) {
|
||||
// Assumes certificate chain always starts with client certificate and end with root certificate.
|
||||
|
@ -4,7 +4,6 @@ import net.corda.cordform.CordformContext
|
||||
import net.corda.cordform.CordformDefinition
|
||||
import net.corda.cordform.CordformNode
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.node.services.NotaryService
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.node.services.config.NotaryConfig
|
||||
import net.corda.node.services.config.RaftConfig
|
||||
|
@ -2,6 +2,7 @@ package net.corda.testing.driver
|
||||
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.CertRole
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.internal.list
|
||||
import net.corda.core.internal.readLines
|
||||
@ -42,12 +43,28 @@ class DriverTests {
|
||||
@Test
|
||||
fun `simple node startup and shutdown`() {
|
||||
val handle = driver {
|
||||
val regulator = startNode(providedName = DUMMY_REGULATOR_NAME)
|
||||
nodeMustBeUp(regulator)
|
||||
val node = startNode(providedName = DUMMY_REGULATOR_NAME)
|
||||
nodeMustBeUp(node)
|
||||
}
|
||||
nodeMustBeDown(handle)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `starting with default notary`() {
|
||||
driver {
|
||||
// Make sure the default is a single-node notary
|
||||
val notary = defaultNotaryNode.getOrThrow()
|
||||
val notaryIdentities = notary.nodeInfo.legalIdentitiesAndCerts
|
||||
// Make sure the notary node has only one identity
|
||||
assertThat(notaryIdentities).hasSize(1)
|
||||
val identity = notaryIdentities[0]
|
||||
// Make sure this identity is a legal identity, like it is for normal nodes.
|
||||
assertThat(CertRole.extract(identity.certificate)).isEqualTo(CertRole.LEGAL_IDENTITY)
|
||||
// And make sure this identity is published as the notary identity (via the network parameters)
|
||||
assertThat(notary.rpc.notaryIdentities()).containsOnly(identity.party)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `random free port allocation`() {
|
||||
val nodeHandle = driver(portAllocation = PortAllocation.RandomFree) {
|
||||
|
@ -235,7 +235,7 @@ open class MockNetwork(private val cordappPackages: List<String>,
|
||||
|
||||
private fun generateNotaryIdentities(): List<NotaryInfo> {
|
||||
return notarySpecs.mapIndexed { index, (name, validating) ->
|
||||
val identity = IdentityGenerator.generateNodeIdentity(baseDirectory(nextNodeId + index), name)
|
||||
val identity = IdentityGenerator.installKeyStoreWithNodeIdentity(baseDirectory(nextNodeId + index), name)
|
||||
NotaryInfo(identity, validating)
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,8 @@ import net.corda.cordform.CordformContext
|
||||
import net.corda.cordform.CordformNode
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.concurrent.firstOf
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.*
|
||||
import net.corda.core.internal.concurrent.*
|
||||
import net.corda.core.messaging.CordaRPCOps
|
||||
@ -31,7 +29,6 @@ import net.corda.node.services.config.*
|
||||
import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
|
||||
import net.corda.node.utilities.registration.NetworkRegistrationHelper
|
||||
import net.corda.nodeapi.internal.IdentityGenerator
|
||||
import net.corda.nodeapi.internal.IdentityGenerator.NODE_IDENTITY_ALIAS_PREFIX
|
||||
import net.corda.nodeapi.internal.addShutdownHook
|
||||
import net.corda.nodeapi.internal.config.User
|
||||
import net.corda.nodeapi.internal.config.parseAs
|
||||
@ -46,7 +43,6 @@ import net.corda.nodeapi.internal.network.NotaryInfo
|
||||
import net.corda.testing.ALICE_NAME
|
||||
import net.corda.testing.BOB_NAME
|
||||
import net.corda.testing.DUMMY_BANK_A_NAME
|
||||
import net.corda.nodeapi.internal.crypto.*
|
||||
import net.corda.nodeapi.internal.network.NetworkParameters
|
||||
import net.corda.testing.common.internal.testNetworkParameters
|
||||
import net.corda.testing.driver.*
|
||||
@ -270,7 +266,7 @@ class DriverDSLImpl(
|
||||
clusterNodes.put(ClusterType.NON_VALIDATING_BFT, name)
|
||||
} else {
|
||||
// We have all we need here to generate the identity for single node notaries
|
||||
val identity = IdentityGenerator.generateNodeIdentity(baseDirectory(name), legalName = name)
|
||||
val identity = IdentityGenerator.installKeyStoreWithNodeIdentity(baseDirectory(name), legalName = name)
|
||||
notaryInfos += NotaryInfo(identity, notaryConfig.validating)
|
||||
}
|
||||
}
|
||||
@ -364,7 +360,7 @@ class DriverDSLImpl(
|
||||
private fun generateNotaryIdentities(): List<NotaryInfo> {
|
||||
return notarySpecs.map { spec ->
|
||||
val identity = if (spec.cluster == null) {
|
||||
IdentityGenerator.generateNodeIdentity(baseDirectory(spec.name), spec.name, compatibilityZone?.rootCert)
|
||||
IdentityGenerator.installKeyStoreWithNodeIdentity(baseDirectory(spec.name), spec.name, compatibilityZone?.rootCert)
|
||||
} else {
|
||||
IdentityGenerator.generateDistributedNotaryIdentity(
|
||||
dirs = generateNodeNames(spec).map { baseDirectory(it) },
|
||||
|
@ -153,7 +153,7 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() {
|
||||
|
||||
// Generate notary identity and save it into node's directory. This identity will be used in network parameters.
|
||||
private fun getNotaryIdentity(config: NodeConfigWrapper): Party {
|
||||
return IdentityGenerator.generateNodeIdentity(config.nodeDir, config.nodeConfig.myLegalName)
|
||||
return IdentityGenerator.installKeyStoreWithNodeIdentity(config.nodeDir, config.nodeConfig.myLegalName)
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user