ENT-1443 Add cert role to CSR and doorman issue cert according to the cert role (#2620)

* ENT-1443 Add cert role to CSR and doorman issue cert according to the cert role (#431)

* Doorman and HSM create certificate base on requested cert role specified in the certificate signing request.

(cherry picked from commit 94f7392)

* remove R3 corda code
This commit is contained in:
Patrick Kuo 2018-02-23 13:38:09 +00:00 committed by GitHub
parent c8672d373f
commit 1552e992e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 177 additions and 81 deletions

View File

@ -2,10 +2,7 @@
package net.corda.nodeapi.internal.config
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigUtil
import com.typesafe.config.ConfigValueFactory
import com.typesafe.config.*
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.noneOrSingle
import net.corda.core.internal.uncheckedCast
@ -78,7 +75,12 @@ private fun Config.getSingleValue(path: String, type: KType): Any? {
NetworkHostAndPort::class -> NetworkHostAndPort.parse(getString(path))
Path::class -> Paths.get(getString(path))
URL::class -> URL(getString(path))
CordaX500Name::class -> CordaX500Name.parse(getString(path))
CordaX500Name::class -> {
when (getValue(path).valueType()) {
ConfigValueType.OBJECT -> getConfig(path).parseAs()
else -> CordaX500Name.parse(getString(path))
}
}
Properties::class -> getConfig(path).toProperties()
Config::class -> getConfig(path)
else -> if (typeClass.java.isEnum) {

View File

@ -259,13 +259,17 @@ object X509Utilities {
private fun createCertificateSigningRequest(subject: X500Principal,
email: String,
keyPair: KeyPair,
signatureScheme: SignatureScheme): PKCS10CertificationRequest {
signatureScheme: SignatureScheme,
certRole: CertRole): PKCS10CertificationRequest {
val signer = ContentSignerBuilder.build(signatureScheme, keyPair.private, Crypto.findProvider(signatureScheme.providerName))
return JcaPKCS10CertificationRequestBuilder(subject, keyPair.public).addAttribute(BCStyle.E, DERUTF8String(email)).build(signer)
return JcaPKCS10CertificationRequestBuilder(subject, keyPair.public)
.addAttribute(BCStyle.E, DERUTF8String(email))
.addAttribute(ASN1ObjectIdentifier(CordaOID.X509_EXTENSION_CORDA_ROLE), certRole)
.build(signer)
}
fun createCertificateSigningRequest(subject: X500Principal, email: String, keyPair: KeyPair): PKCS10CertificationRequest {
return createCertificateSigningRequest(subject, email, keyPair, DEFAULT_TLS_SIGNATURE_SCHEME)
fun createCertificateSigningRequest(subject: X500Principal, email: String, keyPair: KeyPair, certRole: CertRole = CertRole.NODE_CA): PKCS10CertificationRequest {
return createCertificateSigningRequest(subject, email, keyPair, DEFAULT_TLS_SIGNATURE_SCHEME, certRole)
}
fun buildCertPath(first: X509Certificate, remaining: List<X509Certificate>): CertPath {
@ -284,19 +288,24 @@ object X509Utilities {
}
}
// Assuming cert type to role is 1:1
val CertRole.certificateType: CertificateType get() = CertificateType.values().first { it.role == this }
/**
* Convert a [X509Certificate] into Bouncycastle's [X509CertificateHolder].
*
* NOTE: To avoid unnecessary copying use [X509Certificate] where possible.
*/
fun X509Certificate.toBc() = X509CertificateHolder(encoded)
fun X509CertificateHolder.toJca(): X509Certificate = X509CertificateFactory().generateCertificate(encoded.inputStream())
val CertPath.x509Certificates: List<X509Certificate> get() {
val CertPath.x509Certificates: List<X509Certificate>
get() {
require(type == "X.509") { "Not an X.509 cert path: $this" }
// We're not mapping the list to avoid creating a new one.
return uncheckedCast(certificates)
}
}
val Certificate.x509: X509Certificate get() = requireNotNull(this as? X509Certificate) { "Not an X.509 certificate: $this" }

View File

@ -87,10 +87,15 @@ class ConfigParsingTest {
@Test
fun CordaX500Name() {
val name1 = CordaX500Name(organisation = "Mock Party", locality = "London", country = "GB")
testPropertyType<CordaX500NameData, CordaX500NameListData, CordaX500Name>(
CordaX500Name(organisation = "Mock Party", locality = "London", country = "GB"),
name1,
CordaX500Name(organisation = "Mock Party 2", locality = "London", country = "GB"),
valuesToString = true)
// Test with config object.
val config = config("value" to mapOf("organisation" to "Mock Party", "locality" to "London", "country" to "GB"))
assertThat(config.parseAs<CordaX500NameData>().value).isEqualTo(name1)
}
@Test
@ -273,6 +278,7 @@ class ConfigParsingTest {
data class OldData(
@OldConfig("oldValue")
val newValue: String)
data class DataWithCompanion(val value: Int) {
companion object {
@Suppress("unused")

View File

@ -3,7 +3,10 @@ package net.corda.node
import com.typesafe.config.ConfigFactory
import joptsimple.OptionParser
import joptsimple.util.EnumConverter
import joptsimple.util.PathConverter
import net.corda.core.internal.CertRole
import net.corda.core.internal.div
import net.corda.core.internal.exists
import net.corda.node.services.config.ConfigHelper
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.parseAsNodeConfiguration
@ -34,9 +37,11 @@ class ArgsParser {
private val sshdServerArg = optionParser.accepts("sshd", "Enables SSHD server for node administration.")
private val noLocalShellArg = optionParser.accepts("no-local-shell", "Do not start the embedded shell locally.")
private val isRegistrationArg = optionParser.accepts("initial-registration", "Start initial node registration with Corda network to obtain certificate from the permissioning server.")
private val networkRootTruststorePathArg = optionParser.accepts("network-root-truststore", "Network root trust store obtained from network operator.")
private val networkRootTrustStorePathArg = optionParser.accepts("network-root-truststore", "Network root trust store obtained from network operator.")
.withRequiredArg()
private val networkRootTruststorePasswordArg = optionParser.accepts("network-root-truststore-password", "Network root trust store password obtained from network operator.")
.withValuesConvertedBy(PathConverter())
.defaultsTo((Paths.get("certificates") / "network-root-truststore.jks"))
private val networkRootTrustStorePasswordArg = optionParser.accepts("network-root-truststore-password", "Network root trust store password obtained from network operator.")
.withRequiredArg()
private val isVersionArg = optionParser.accepts("version", "Print the version and exit")
private val justGenerateNodeInfoArg = optionParser.accepts("just-generate-node-info",
@ -60,16 +65,23 @@ class ArgsParser {
val sshdServer = optionSet.has(sshdServerArg)
val justGenerateNodeInfo = optionSet.has(justGenerateNodeInfoArg)
val bootstrapRaftCluster = optionSet.has(bootstrapRaftClusterArg)
val networkRootTruststorePath = optionSet.valueOf(networkRootTruststorePathArg)?.let { Paths.get(it).normalize().toAbsolutePath() }
val networkRootTruststorePassword = optionSet.valueOf(networkRootTruststorePasswordArg)
val networkRootTrustStorePath = optionSet.valueOf(networkRootTrustStorePathArg)
val networkRootTrustStorePassword = optionSet.valueOf(networkRootTrustStorePasswordArg)
val registrationConfig = if (isRegistration) {
requireNotNull(networkRootTrustStorePassword) { "Network root trust store password must be provided in registration mode." }
require(networkRootTrustStorePath.exists()) { "Network root trust store path: '$networkRootTrustStorePath' doesn't exist" }
NodeRegistrationOption(networkRootTrustStorePath, networkRootTrustStorePassword)
} else {
null
}
return CmdLineOptions(baseDirectory,
configFile,
help,
loggingLevel,
logToConsole,
isRegistration,
networkRootTruststorePath,
networkRootTruststorePassword,
registrationConfig,
isVersion,
noLocalShell,
sshdServer,
@ -80,14 +92,14 @@ class ArgsParser {
fun printHelp(sink: PrintStream) = optionParser.printHelpOn(sink)
}
data class NodeRegistrationOption(val networkRootTrustStorePath: Path, val networkRootTrustStorePassword: String)
data class CmdLineOptions(val baseDirectory: Path,
val configFile: Path,
val help: Boolean,
val loggingLevel: Level,
val logToConsole: Boolean,
val isRegistration: Boolean,
val networkRootTruststorePath: Path?,
val networkRootTruststorePassword: String?,
val nodeRegistrationConfig: NodeRegistrationOption?,
val isVersion: Boolean,
val noLocalShell: Boolean,
val sshdServer: Boolean,
@ -97,10 +109,8 @@ data class CmdLineOptions(val baseDirectory: Path,
val config = ConfigHelper.loadConfig(baseDirectory, configFile, configOverrides = ConfigFactory.parseMap(
mapOf("noLocalShell" to this.noLocalShell)
)).parseAsNodeConfiguration()
if (isRegistration) {
if (nodeRegistrationConfig != null) {
requireNotNull(config.compatibilityZoneURL) { "Compatibility Zone Url must be provided in registration mode." }
requireNotNull(networkRootTruststorePath) { "Network root trust store path must be provided in registration mode." }
requireNotNull(networkRootTruststorePassword) { "Network root trust store password must be provided in registration mode." }
}
return config
}

View File

@ -99,9 +99,9 @@ open class NodeStartup(val args: Array<String>) {
try {
banJavaSerialisation(conf)
preNetworkRegistration(conf)
if (shouldRegisterWithNetwork(cmdlineOptions, conf)) {
if (cmdlineOptions.nodeRegistrationConfig != null) {
// Null checks for [compatibilityZoneURL], [rootTruststorePath] and [rootTruststorePassword] has been done in [CmdLineOptions.loadConfig]
registerWithNetwork(conf, cmdlineOptions.networkRootTruststorePath!!, cmdlineOptions.networkRootTruststorePassword!!)
registerWithNetwork(conf, cmdlineOptions.nodeRegistrationConfig)
return true
}
logStartupInfo(versionInfo, cmdlineOptions, conf)
@ -184,12 +184,7 @@ open class NodeStartup(val args: Array<String>) {
logger.info("Starting as node on ${conf.p2pAddress}")
}
private fun shouldRegisterWithNetwork(cmdlineOptions: CmdLineOptions, conf: NodeConfiguration): Boolean {
val compatibilityZoneURL = conf.compatibilityZoneURL
return !(!cmdlineOptions.isRegistration || compatibilityZoneURL == null)
}
open protected fun registerWithNetwork(conf: NodeConfiguration, networkRootTruststorePath: Path, networkRootTruststorePassword: String) {
open protected fun registerWithNetwork(conf: NodeConfiguration, nodeRegistrationConfig: NodeRegistrationOption) {
val compatibilityZoneURL = conf.compatibilityZoneURL!!
println()
println("******************************************************************")
@ -197,7 +192,7 @@ open class NodeStartup(val args: Array<String>) {
println("* Registering as a new participant with Corda network *")
println("* *")
println("******************************************************************")
NetworkRegistrationHelper(conf, HTTPNetworkRegistrationService(compatibilityZoneURL), networkRootTruststorePath, networkRootTruststorePassword).buildKeystore()
NetworkRegistrationHelper(conf, HTTPNetworkRegistrationService(compatibilityZoneURL), nodeRegistrationConfig).buildKeystore()
}
open protected fun loadConfigFile(cmdlineOptions: CmdLineOptions): NodeConfiguration = cmdlineOptions.loadConfig()

View File

@ -3,7 +3,10 @@ package net.corda.node.utilities.registration
import net.corda.core.crypto.Crypto
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.*
import net.corda.node.NodeRegistrationOption
import net.corda.node.services.config.NodeConfiguration
import net.corda.nodeapi.internal.DevIdentityGenerator
import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509KeyStore
import net.corda.nodeapi.internal.crypto.X509Utilities
@ -22,10 +25,18 @@ import java.security.cert.X509Certificate
* Helper for managing the node registration process, which checks for any existing certificates and requests them if
* needed.
*/
class NetworkRegistrationHelper(private val config: NodeConfiguration,
class NetworkRegistrationHelper(private val config: SSLConfiguration,
private val myLegalName: CordaX500Name,
private val emailAddress: String,
private val certService: NetworkRegistrationService,
networkRootTrustStorePath: Path,
networkRootTruststorePassword: String) {
private val networkRootTrustStorePath: Path,
networkRootTrustStorePassword: String,
private val certRole: CertRole) {
// Constructor for corda node, cert role is restricted to [CertRole.NODE_CA].
constructor(config: NodeConfiguration, certService: NetworkRegistrationService, regConfig: NodeRegistrationOption) :
this(config, config.myLegalName, config.emailAddress, certService, regConfig.networkRootTrustStorePath, regConfig.networkRootTrustStorePassword, CertRole.NODE_CA)
private companion object {
const val SELF_SIGNED_PRIVATE_KEY = "Self Signed Private Key"
}
@ -41,7 +52,7 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration,
"$networkRootTrustStorePath does not exist. This file must contain the root CA cert of your compatibility zone. " +
"Please contact your CZ operator."
}
rootTrustStore = X509KeyStore.fromFile(networkRootTrustStorePath, networkRootTruststorePassword)
rootTrustStore = X509KeyStore.fromFile(networkRootTrustStorePath, networkRootTrustStorePassword)
rootCert = rootTrustStore.getCertificate(CORDA_ROOT_CA)
}
@ -68,7 +79,7 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration,
// We use the self sign certificate to store the key temporarily in the keystore while waiting for the request approval.
if (SELF_SIGNED_PRIVATE_KEY !in nodeKeyStore) {
val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val selfSignCert = X509Utilities.createSelfSignedCACertificate(config.myLegalName.x500Principal, keyPair)
val selfSignCert = X509Utilities.createSelfSignedCACertificate(myLegalName.x500Principal, keyPair)
// Save to the key store.
nodeKeyStore.setPrivateKey(SELF_SIGNED_PRIVATE_KEY, keyPair.private, listOf(selfSignCert), keyPassword = privateKeyPassword)
nodeKeyStore.save()
@ -87,36 +98,59 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration,
throw certificateRequestException
}
val nodeCaCert = certificates[0]
val certificate = certificates.first()
val nodeCaSubject = try {
CordaX500Name.build(nodeCaCert.subjectX500Principal)
CordaX500Name.build(certificate.subjectX500Principal)
} catch (e: IllegalArgumentException) {
throw CertificateRequestException("Received node CA cert has invalid subject name: ${e.message}")
}
if (nodeCaSubject != config.myLegalName) {
if (nodeCaSubject != myLegalName) {
throw CertificateRequestException("Subject of received node CA cert doesn't match with node legal name: $nodeCaSubject")
}
val nodeCaCertRole = try {
CertRole.extract(nodeCaCert)
CertRole.extract(certificate)
} catch (e: IllegalArgumentException) {
throw CertificateRequestException("Unable to extract cert role from received node CA cert: ${e.message}")
}
if (nodeCaCertRole != CertRole.NODE_CA) {
throw CertificateRequestException("Received node CA cert has invalid role: $nodeCaCertRole")
}
// Validate certificate chain returned from the doorman with the root cert obtained via out-of-band process, to prevent MITM attack on doorman server.
X509Utilities.validateCertificateChain(rootCert, certificates)
println("Certificate signing request approved, storing private key with the certificate chain.")
when (nodeCaCertRole) {
CertRole.NODE_CA -> {
// Save private key and certificate chain to the key store.
nodeKeyStore.setPrivateKey(CORDA_CLIENT_CA, keyPair.private, certificates, keyPassword = privateKeyPassword)
nodeKeyStore.internal.deleteEntry(SELF_SIGNED_PRIVATE_KEY)
nodeKeyStore.save()
println("Node private key and certificate stored in ${config.nodeKeystore}.")
config.loadSslKeyStore(createNew = true).update {
println("Generating SSL certificate for node messaging service.")
val sslKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val sslCert = X509Utilities.createCertificate(
CertificateType.TLS,
certificate,
keyPair,
myLegalName.x500Principal,
sslKeyPair.public)
setPrivateKey(CORDA_CLIENT_TLS, sslKeyPair.private, listOf(sslCert) + certificates)
}
println("SSL private key and certificate stored in ${config.sslKeystore}.")
}
// TODO: Fix this, this is not needed in corda node.
CertRole.SERVICE_IDENTITY -> {
// Only create keystore containing notary's key for service identity role.
nodeKeyStore.setPrivateKey("${DevIdentityGenerator.DISTRIBUTED_NOTARY_ALIAS_PREFIX}-private-key", keyPair.private, certificates, keyPassword = privateKeyPassword)
nodeKeyStore.internal.deleteEntry(SELF_SIGNED_PRIVATE_KEY)
nodeKeyStore.save()
println("Service identity private key and certificate stored in ${config.nodeKeystore}.")
}
else -> throw CertificateRequestException("Received node CA cert has invalid role: $nodeCaCertRole")
}
// Save root certificates to trust store.
config.loadTrustStore(createNew = true).update {
println("Generating trust store for corda node.")
@ -124,20 +158,6 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration,
setCertificate(CORDA_ROOT_CA, certificates.last())
}
println("Node trust store stored in ${config.trustStoreFile}.")
config.loadSslKeyStore(createNew = true).update {
println("Generating SSL certificate for node messaging service.")
val sslKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val sslCert = X509Utilities.createCertificate(
CertificateType.TLS,
nodeCaCert,
keyPair,
config.myLegalName.x500Principal,
sslKeyPair.public)
setPrivateKey(CORDA_CLIENT_TLS, sslKeyPair.private, listOf(sslCert) + certificates)
}
println("SSL private key and certificate stored in ${config.sslKeystore}.")
// All done, clean up temp files.
requestIdStore.deleteIfExists()
}
@ -169,15 +189,15 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration,
private fun submitOrResumeCertificateSigningRequest(keyPair: KeyPair): String {
// Retrieve request id from file if exists, else post a request to server.
return if (!requestIdStore.exists()) {
val request = X509Utilities.createCertificateSigningRequest(config.myLegalName.x500Principal, config.emailAddress, keyPair)
val request = X509Utilities.createCertificateSigningRequest(myLegalName.x500Principal, emailAddress, keyPair, certRole)
val writer = StringWriter()
JcaPEMWriter(writer).use {
it.writeObject(PemObject("CERTIFICATE REQUEST", request.encoded))
}
println("Certificate signing request with the following information will be submitted to the Corda certificate signing server.")
println()
println("Legal Name: ${config.myLegalName}")
println("Email: ${config.emailAddress}")
println("Legal Name: $myLegalName")
println("Email: $emailAddress")
println()
println("Public Key: ${keyPair.public}")
println()

View File

@ -2,12 +2,14 @@ package net.corda.node
import joptsimple.OptionException
import net.corda.core.internal.div
import net.corda.nodeapi.internal.crypto.X509KeyStore
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test
import org.slf4j.event.Level
import java.nio.file.Paths
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
class ArgsParserTest {
private val parser = ArgsParser()
@ -21,14 +23,12 @@ class ArgsParserTest {
help = false,
logToConsole = false,
loggingLevel = Level.INFO,
isRegistration = false,
nodeRegistrationConfig = null,
isVersion = false,
noLocalShell = false,
sshdServer = false,
justGenerateNodeInfo = false,
bootstrapRaftCluster = false,
networkRootTruststorePassword = null,
networkRootTruststorePath = null))
bootstrapRaftCluster = false))
}
@Test
@ -113,11 +113,17 @@ class ArgsParserTest {
@Test
fun `initial-registration`() {
val truststorePath = Paths.get("truststore") / "file.jks"
val truststorePath = workingDirectory / "truststore" / "file.jks"
assertThatExceptionOfType(IllegalArgumentException::class.java).isThrownBy {
parser.parse("--initial-registration", "--network-root-truststore", "$truststorePath", "--network-root-truststore-password", "password-test")
}.withMessageContaining("Network root trust store path").withMessageContaining("doesn't exist")
X509KeyStore.fromFile(truststorePath, "dummy_password", createNew = true)
val cmdLineOptions = parser.parse("--initial-registration", "--network-root-truststore", "$truststorePath", "--network-root-truststore-password", "password-test")
assertThat(cmdLineOptions.isRegistration).isTrue()
assertEquals(truststorePath.toAbsolutePath(), cmdLineOptions.networkRootTruststorePath)
assertEquals("password-test", cmdLineOptions.networkRootTruststorePassword)
assertNotNull(cmdLineOptions.nodeRegistrationConfig)
assertEquals(truststorePath.toAbsolutePath(), cmdLineOptions.nodeRegistrationConfig?.networkRootTrustStorePath)
assertEquals("password-test", cmdLineOptions.nodeRegistrationConfig?.networkRootTrustStorePassword)
}
@Test

View File

@ -13,7 +13,9 @@ import net.corda.core.internal.createDirectories
import net.corda.core.internal.div
import net.corda.core.internal.x500Name
import net.corda.core.utilities.seconds
import net.corda.node.NodeRegistrationOption
import net.corda.node.services.config.NodeConfiguration
import net.corda.nodeapi.internal.DevIdentityGenerator
import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509KeyStore
import net.corda.nodeapi.internal.crypto.X509Utilities
@ -141,6 +143,38 @@ class NetworkRegistrationHelperTest {
}.isInstanceOf(CertPathValidatorException::class.java)
}
@Test
fun `create service identity cert`() {
assertThat(config.nodeKeystore).doesNotExist()
assertThat(config.sslKeystore).doesNotExist()
assertThat(config.trustStoreFile).doesNotExist()
val serviceIdentityCertPath = createServiceIdentityCertPath()
saveNetworkTrustStore(serviceIdentityCertPath.last())
createRegistrationHelper(serviceIdentityCertPath).buildKeystore()
val nodeKeystore = config.loadNodeKeyStore()
val trustStore = config.loadTrustStore()
assertThat(config.sslKeystore).doesNotExist()
val serviceIdentityAlias = "${DevIdentityGenerator.DISTRIBUTED_NOTARY_ALIAS_PREFIX}-private-key"
nodeKeystore.run {
assertFalse(contains(X509Utilities.CORDA_INTERMEDIATE_CA))
assertFalse(contains(X509Utilities.CORDA_ROOT_CA))
assertFalse(contains(X509Utilities.CORDA_CLIENT_TLS))
assertFalse(contains(X509Utilities.CORDA_CLIENT_CA))
assertThat(getCertificateChain(serviceIdentityAlias)).containsExactlyElementsOf(serviceIdentityCertPath)
}
trustStore.run {
assertFalse(contains(X509Utilities.CORDA_CLIENT_CA))
assertFalse(contains(X509Utilities.CORDA_INTERMEDIATE_CA))
assertThat(getCertificate(X509Utilities.CORDA_ROOT_CA)).isEqualTo(serviceIdentityCertPath.last())
}
}
private fun createNodeCaCertPath(type: CertificateType = CertificateType.NODE_CA,
legalName: CordaX500Name = nodeLegalName): List<X509Certificate> {
val (rootCa, intermediateCa) = createDevIntermediateCaCertPath()
@ -156,12 +190,25 @@ class NetworkRegistrationHelperTest {
return listOf(nodeCaCert, intermediateCa.certificate, rootCa.certificate)
}
private fun createServiceIdentityCertPath(type: CertificateType = CertificateType.SERVICE_IDENTITY,
legalName: CordaX500Name = nodeLegalName): List<X509Certificate> {
val (rootCa, intermediateCa) = createDevIntermediateCaCertPath()
val keyPair = Crypto.generateKeyPair()
val serviceIdentityCert = X509Utilities.createCertificate(
type,
intermediateCa.certificate,
intermediateCa.keyPair,
legalName.x500Principal,
keyPair.public)
return listOf(serviceIdentityCert, intermediateCa.certificate, rootCa.certificate)
}
private fun createRegistrationHelper(response: List<X509Certificate>): NetworkRegistrationHelper {
val certService = rigorousMock<NetworkRegistrationService>().also {
doReturn(requestId).whenever(it).submitRequest(any())
doReturn(CertificateResponse(5.seconds, response)).whenever(it).retrieveCertificates(eq(requestId))
}
return NetworkRegistrationHelper(config, certService, config.certificatesDirectory / networkRootTrustStoreFileName, networkRootTrustStorePassword)
return NetworkRegistrationHelper(config, certService, NodeRegistrationOption(config.certificatesDirectory / networkRootTrustStoreFileName, networkRootTrustStorePassword))
}
private fun saveNetworkTrustStore(rootCert: X509Certificate) {

View File

@ -23,6 +23,7 @@ import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.millis
import net.corda.node.NodeRegistrationOption
import net.corda.node.internal.Node
import net.corda.node.internal.NodeStartup
import net.corda.node.internal.StartedNode
@ -259,7 +260,7 @@ class DriverDSLImpl(
return if (startNodesInProcess) {
executorService.fork {
NetworkRegistrationHelper(config.corda, HTTPNetworkRegistrationService(compatibilityZoneURL), rootTruststorePath, rootTruststorePassword).buildKeystore()
NetworkRegistrationHelper(config.corda, HTTPNetworkRegistrationService(compatibilityZoneURL), NodeRegistrationOption(rootTruststorePath, rootTruststorePassword)).buildKeystore()
config
}
} else {