mirror of
https://github.com/corda/corda.git
synced 2025-01-13 00:09:57 +00:00
Clean up of network-management to make more use of the existing X509 utilities (#419)
This commit is contained in:
parent
3d32760dcc
commit
2432b1380e
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@ -17,6 +17,8 @@
|
||||
<module name="business-network-demo_integrationTest" target="1.8" />
|
||||
<module name="business-network-demo_main" target="1.8" />
|
||||
<module name="business-network-demo_test" target="1.8" />
|
||||
<module name="capsule-hsm-cert-generator_main" target="1.8" />
|
||||
<module name="capsule-hsm-cert-generator_test" target="1.8" />
|
||||
<module name="capsule-hsm_main" target="1.8" />
|
||||
<module name="capsule-hsm_test" target="1.8" />
|
||||
<module name="client_main" target="1.8" />
|
||||
|
@ -6,7 +6,7 @@ import com.r3.corda.networkmanage.hsm.authentication.createProvider
|
||||
import com.r3.corda.networkmanage.hsm.generator.run
|
||||
import com.r3.corda.networkmanage.hsm.persistence.ApprovedCertificateRequestData
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmCsrSigner
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmNetworkMapSigner
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmSigner
|
||||
import net.corda.core.crypto.Crypto.generateKeyPair
|
||||
import net.corda.core.crypto.secureRandomBytes
|
||||
import net.corda.core.identity.CordaX500Name.Companion.parse
|
||||
@ -48,7 +48,7 @@ class HsmSigningServiceTest : HsmCertificateTest() {
|
||||
val userInput = givenHsmUserAuthenticationInput()
|
||||
|
||||
// given HSM network map signer
|
||||
val signer = HsmNetworkMapSigner(Authenticator(
|
||||
val signer = HsmSigner(Authenticator(
|
||||
provider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.networkMapKeyGroup),
|
||||
inputReader = userInput))
|
||||
|
||||
|
@ -2,7 +2,6 @@ package com.r3.corda.networkmanage.hsm
|
||||
|
||||
import com.nhaarman.mockito_kotlin.*
|
||||
import com.r3.corda.networkmanage.common.persistence.configureDatabase
|
||||
import com.r3.corda.networkmanage.common.utils.buildCertPath
|
||||
import com.r3.corda.networkmanage.doorman.DoormanConfig
|
||||
import com.r3.corda.networkmanage.doorman.NetworkManagementServer
|
||||
import com.r3.corda.networkmanage.hsm.persistence.ApprovedCertificateRequestData
|
||||
@ -19,7 +18,9 @@ import net.corda.node.services.config.NodeConfiguration
|
||||
import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
|
||||
import net.corda.node.utilities.registration.NetworkRegistrationHelper
|
||||
import net.corda.nodeapi.internal.createDevNodeCa
|
||||
import net.corda.nodeapi.internal.crypto.*
|
||||
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||
import net.corda.testing.core.ALICE_NAME
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
@ -76,7 +77,7 @@ class SigningServiceIntegrationTest {
|
||||
for (approvedRequest in approvedRequests) {
|
||||
JcaPKCS10CertificationRequest(approvedRequest.request).run {
|
||||
val nodeCa = createDevNodeCa(intermediateCa, CordaX500Name.parse(subject.toString()))
|
||||
approvedRequest.certPath = buildCertPath(nodeCa.certificate, intermediateCa.certificate, rootCaCert)
|
||||
approvedRequest.certPath = X509Utilities.buildCertPath(nodeCa.certificate, intermediateCa.certificate, rootCaCert)
|
||||
}
|
||||
}
|
||||
storage.store(approvedRequests, listOf("TEST"))
|
||||
|
@ -4,11 +4,11 @@ import com.r3.corda.networkmanage.common.persistence.CertificateData
|
||||
import com.r3.corda.networkmanage.common.persistence.CertificateSigningRequest
|
||||
import com.r3.corda.networkmanage.common.persistence.CertificateStatus
|
||||
import com.r3.corda.networkmanage.common.persistence.RequestStatus
|
||||
import com.r3.corda.networkmanage.common.utils.buildCertPath
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||
import org.hibernate.envers.Audited
|
||||
import java.security.cert.CertPath
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.time.Instant
|
||||
import javax.persistence.*
|
||||
|
||||
@ -114,5 +114,5 @@ class CertificateDataEntity(
|
||||
)
|
||||
}
|
||||
|
||||
private fun toCertificatePath(): CertPath = CertificateFactory.getInstance("X.509").generateCertPath(certificatePathBytes.inputStream())
|
||||
private fun toCertificatePath(): CertPath = buildCertPath(certificatePathBytes)
|
||||
}
|
@ -8,6 +8,7 @@ import joptsimple.OptionParser
|
||||
import net.corda.core.crypto.sha256
|
||||
import net.corda.core.internal.SignedDataWithCert
|
||||
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.network.NetworkMap
|
||||
import net.corda.nodeapi.internal.network.NetworkParameters
|
||||
import java.security.KeyPair
|
||||
@ -50,10 +51,12 @@ fun Array<out String>.toConfigWithOptions(registerOptions: OptionParser.() -> Un
|
||||
|
||||
class ShowHelpException(val parser: OptionParser, val errorMessage: String? = null) : Exception()
|
||||
|
||||
fun buildCertPath(vararg certificates: X509Certificate): CertPath = X509CertificateFactory().generateCertPath(certificates.asList())
|
||||
|
||||
fun buildCertPath(certPathBytes: ByteArray): CertPath = X509CertificateFactory().delegate.generateCertPath(certPathBytes.inputStream())
|
||||
|
||||
fun X509KeyStore.getCertPathAndKey(alias: String, privateKeyPassword: String): CertPathAndKey {
|
||||
return CertPathAndKey(getCertificateChain(alias), getPrivateKey(alias, privateKeyPassword))
|
||||
}
|
||||
|
||||
private fun String.toCamelcase(): String {
|
||||
return if (contains('_') || contains('-')) {
|
||||
CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, this.replace("-", "_"))
|
||||
|
@ -94,6 +94,7 @@ fun parseParameters(vararg args: String): NetworkManagementServerParameters {
|
||||
val configFile = if (argConfig.hasPath("configFile")) {
|
||||
Paths.get(argConfig.getString("configFile"))
|
||||
} else {
|
||||
// TODO Remove this default
|
||||
Paths.get(".") / "network-management.conf"
|
||||
}
|
||||
require(configFile.isRegularFile()) { "Config file $configFile does not exist" }
|
||||
|
@ -6,20 +6,18 @@ import com.r3.corda.networkmanage.common.persistence.configureDatabase
|
||||
import com.r3.corda.networkmanage.common.utils.CORDA_NETWORK_MAP
|
||||
import com.r3.corda.networkmanage.common.utils.CertPathAndKey
|
||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||
import com.r3.corda.networkmanage.common.utils.getCertPathAndKey
|
||||
import com.r3.corda.networkmanage.doorman.signer.LocalSigner
|
||||
import com.r3.corda.networkmanage.hsm.configuration.Parameters.Companion.DEFAULT_CSR_CERTIFICATE_NAME
|
||||
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
|
||||
import net.corda.core.serialization.internal.nodeSerializationEnv
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.nodeapi.internal.crypto.getCertificateAndKeyPair
|
||||
import net.corda.nodeapi.internal.crypto.getSupportedKey
|
||||
import net.corda.nodeapi.internal.crypto.loadOrCreateKeyStore
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.network.NetworkParameters
|
||||
import net.corda.nodeapi.internal.serialization.AMQP_P2P_CONTEXT
|
||||
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
|
||||
import net.corda.nodeapi.internal.serialization.amqp.AMQPClientSerializationScheme
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||
import java.security.cert.X509Certificate
|
||||
import java.time.Instant
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
@ -33,17 +31,9 @@ private fun processKeyStore(parameters: NetworkManagementServerParameters): Pair
|
||||
// Get password from console if not in config.
|
||||
val keyStorePassword = parameters.keystorePassword ?: readPassword("Key store password: ")
|
||||
val privateKeyPassword = parameters.caPrivateKeyPassword ?: readPassword("Private key password: ")
|
||||
val keyStore = loadOrCreateKeyStore(parameters.keystorePath, keyStorePassword)
|
||||
|
||||
val csrCertPathAndKey = keyStore.run {
|
||||
CertPathAndKey(
|
||||
keyStore.getCertificateChain(DEFAULT_CSR_CERTIFICATE_NAME).map { it as X509Certificate },
|
||||
keyStore.getSupportedKey(DEFAULT_CSR_CERTIFICATE_NAME, privateKeyPassword)
|
||||
)
|
||||
}
|
||||
|
||||
val keyStore = X509KeyStore.fromFile(parameters.keystorePath, keyStorePassword)
|
||||
val csrCertPathAndKey = keyStore.getCertPathAndKey(DEFAULT_CSR_CERTIFICATE_NAME, privateKeyPassword)
|
||||
val networkMapSigner = LocalSigner(keyStore.getCertificateAndKeyPair(CORDA_NETWORK_MAP, privateKeyPassword))
|
||||
|
||||
return Pair(csrCertPathAndKey, networkMapSigner)
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,8 @@ import java.nio.file.Path
|
||||
import javax.security.auth.x500.X500Principal
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
private val cordaX500Name = "OU=Corda,O=R3 Ltd,L=London,C=GB"
|
||||
|
||||
// TODO The cert subjects need to be configurable
|
||||
private const val CORDA_X500_BASE = "O=R3 HoldCo LLC,OU=Corda,L=New York,C=US"
|
||||
const val NETWORK_ROOT_TRUSTSTORE_FILENAME = "network-root-truststore.jks"
|
||||
|
||||
/** Read password from console, do a readLine instead if console is null (e.g. when debugging in IDE). */
|
||||
@ -32,10 +32,10 @@ fun generateRootKeyPair(rootStoreFile: Path, rootKeystorePass: String?, rootPriv
|
||||
val rootKeystorePassword = rootKeystorePass ?: readPassword("Root Keystore Password: ")
|
||||
// Ensure folder exists.
|
||||
rootStoreFile.parent.createDirectories()
|
||||
val rootStore = loadOrCreateKeyStore(rootStoreFile, rootKeystorePassword)
|
||||
val rootStore = X509KeyStore.fromFile(rootStoreFile, rootKeystorePassword, createNew = true)
|
||||
val rootPrivateKeyPassword = rootPrivateKeyPass ?: readPassword("Root Private Key Password: ")
|
||||
|
||||
if (rootStore.containsAlias(X509Utilities.CORDA_ROOT_CA)) {
|
||||
if (X509Utilities.CORDA_ROOT_CA in rootStore) {
|
||||
println("${X509Utilities.CORDA_ROOT_CA} already exists in keystore, process will now terminate.")
|
||||
println(rootStore.getCertificate(X509Utilities.CORDA_ROOT_CA))
|
||||
exitProcess(1)
|
||||
@ -43,22 +43,24 @@ fun generateRootKeyPair(rootStoreFile: Path, rootKeystorePass: String?, rootPriv
|
||||
|
||||
val selfSignKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
// TODO Make the cert subject configurable
|
||||
val selfSignCert = X509Utilities.createSelfSignedCACertificate(
|
||||
X500Principal("CN=Corda Root CA,$cordaX500Name"),
|
||||
val rootCert = X509Utilities.createSelfSignedCACertificate(
|
||||
X500Principal("CN=Corda Root CA,$CORDA_X500_BASE"),
|
||||
selfSignKey)
|
||||
rootStore.addOrReplaceKey(X509Utilities.CORDA_ROOT_CA, selfSignKey.private, rootPrivateKeyPassword.toCharArray(), arrayOf(selfSignCert))
|
||||
rootStore.save(rootStoreFile, rootKeystorePassword)
|
||||
rootStore.update {
|
||||
setPrivateKey(X509Utilities.CORDA_ROOT_CA, selfSignKey.private, listOf(rootCert), rootPrivateKeyPassword)
|
||||
}
|
||||
|
||||
val trustStorePath = (rootStoreFile.parent / "distribute-nodes").createDirectories() / NETWORK_ROOT_TRUSTSTORE_FILENAME
|
||||
|
||||
val networkRootTrustPassword = networkRootTrustPass ?: readPassword("Network Root Trust Store Password: ")
|
||||
val networkRootTrustStore = loadOrCreateKeyStore(trustStorePath, networkRootTrustPassword)
|
||||
networkRootTrustStore.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, selfSignCert)
|
||||
networkRootTrustStore.save(trustStorePath, networkRootTrustPassword)
|
||||
println("Trust store for distribution to nodes created in $networkRootTrustStore")
|
||||
|
||||
X509KeyStore.fromFile(trustStorePath, networkRootTrustPassword, createNew = true).update {
|
||||
setCertificate(X509Utilities.CORDA_ROOT_CA, rootCert)
|
||||
}
|
||||
|
||||
println("Trust store for distribution to nodes created in $trustStorePath")
|
||||
println("Root CA keypair and certificate stored in ${rootStoreFile.toAbsolutePath()}.")
|
||||
println(selfSignCert)
|
||||
println(rootCert)
|
||||
}
|
||||
|
||||
fun generateSigningKeyPairs(keystoreFile: Path, rootStoreFile: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?, keystorePass: String?, caPrivateKeyPass: String?) {
|
||||
@ -66,7 +68,7 @@ fun generateSigningKeyPairs(keystoreFile: Path, rootStoreFile: Path, rootKeystor
|
||||
// Get password from console if not in config.
|
||||
val rootKeystorePassword = rootKeystorePass ?: readPassword("Root key store password: ")
|
||||
val rootPrivateKeyPassword = rootPrivateKeyPass ?: readPassword("Root private key password: ")
|
||||
val rootKeyStore = loadKeyStore(rootStoreFile, rootKeystorePassword)
|
||||
val rootKeyStore = X509KeyStore.fromFile(rootStoreFile, rootKeystorePassword)
|
||||
|
||||
val rootKeyPairAndCert = rootKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_ROOT_CA, rootPrivateKeyPassword)
|
||||
|
||||
@ -74,10 +76,10 @@ fun generateSigningKeyPairs(keystoreFile: Path, rootStoreFile: Path, rootKeystor
|
||||
val privateKeyPassword = caPrivateKeyPass ?: readPassword("Private key Password: ")
|
||||
// Ensure folder exists.
|
||||
keystoreFile.parent.createDirectories()
|
||||
val keyStore = loadOrCreateKeyStore(keystoreFile, keyStorePassword)
|
||||
val keyStore = X509KeyStore.fromFile(keystoreFile, keyStorePassword, createNew = true)
|
||||
|
||||
fun storeCertIfAbsent(alias: String, certificateType: CertificateType, subject: X500Principal, signatureScheme: SignatureScheme) {
|
||||
if (keyStore.containsAlias(alias)) {
|
||||
if (alias in keyStore) {
|
||||
println("$alias already exists in keystore:")
|
||||
println(keyStore.getCertificate(alias))
|
||||
return
|
||||
@ -91,13 +93,10 @@ fun generateSigningKeyPairs(keystoreFile: Path, rootStoreFile: Path, rootKeystor
|
||||
subject,
|
||||
keyPair.public
|
||||
)
|
||||
keyStore.addOrReplaceKey(
|
||||
alias,
|
||||
keyPair.private,
|
||||
privateKeyPassword.toCharArray(),
|
||||
arrayOf(cert, rootKeyPairAndCert.certificate)
|
||||
)
|
||||
keyStore.save(keystoreFile, keyStorePassword)
|
||||
|
||||
keyStore.update {
|
||||
setPrivateKey(alias, keyPair.private, listOf(cert, rootKeyPairAndCert.certificate), privateKeyPassword)
|
||||
}
|
||||
|
||||
println("$certificateType key pair and certificate stored in $keystoreFile.")
|
||||
println(cert)
|
||||
@ -106,12 +105,12 @@ fun generateSigningKeyPairs(keystoreFile: Path, rootStoreFile: Path, rootKeystor
|
||||
storeCertIfAbsent(
|
||||
DEFAULT_CSR_CERTIFICATE_NAME,
|
||||
CertificateType.INTERMEDIATE_CA,
|
||||
X500Principal("CN=Corda Intermediate CA,$cordaX500Name"),
|
||||
X500Principal("CN=Corda Doorman CA,$CORDA_X500_BASE"),
|
||||
X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
|
||||
storeCertIfAbsent(
|
||||
CORDA_NETWORK_MAP,
|
||||
CertificateType.NETWORK_MAP,
|
||||
X500Principal("CN=Corda Network Map,$cordaX500Name"),
|
||||
X500Principal("CN=Corda Network Map,$CORDA_X500_BASE"),
|
||||
Crypto.EDDSA_ED25519_SHA512)
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import com.r3.corda.networkmanage.hsm.menu.Menu
|
||||
import com.r3.corda.networkmanage.hsm.persistence.ApprovedCertificateRequestData
|
||||
import com.r3.corda.networkmanage.hsm.persistence.DBSignedCertificateRequestStorage
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmCsrSigner
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmNetworkMapSigner
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmSigner
|
||||
import com.r3.corda.networkmanage.hsm.utils.mapCryptoServerException
|
||||
import net.corda.core.utilities.minutes
|
||||
import org.apache.logging.log4j.LogManager
|
||||
@ -56,7 +56,7 @@ fun run(parameters: Parameters) {
|
||||
checkNotNull(dataSourceProperties)
|
||||
val database = configureDatabase(dataSourceProperties, databaseConfig)
|
||||
val csrStorage = DBSignedCertificateRequestStorage(database)
|
||||
val hsmSigner = HsmNetworkMapSigner(
|
||||
val hsmSigner = HsmSigner(
|
||||
Authenticator(
|
||||
AuthMode.KEY_FILE,
|
||||
autoUsername,
|
||||
@ -123,7 +123,7 @@ fun run(parameters: Parameters) {
|
||||
}
|
||||
|
||||
private fun startNetworkingMapSigningPolling(networkMapStorage: NetworkMapStorage,
|
||||
signer: HsmNetworkMapSigner,
|
||||
signer: HsmSigner,
|
||||
executor: ScheduledExecutorService,
|
||||
signingPeriod: Duration) {
|
||||
val networkMapSigner = NetworkMapSigner(networkMapStorage, signer)
|
||||
|
@ -4,23 +4,21 @@ import CryptoServerCXI.CryptoServerCXI.KEY_ALGO_ECDSA
|
||||
import CryptoServerCXI.CryptoServerCXI.KeyAttributes
|
||||
import CryptoServerJCE.CryptoServerProvider
|
||||
import com.r3.corda.networkmanage.common.utils.CORDA_NETWORK_MAP
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.cleanEcdsaPublicKey
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.createIntermediateCert
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.createSelfSignedCACert
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.createSelfSignedCert
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.getAndInitializeKeyStore
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.getCleanEcdsaKeyPair
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.retrieveKeysAndCertificateChain
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.retrieveCertAndKeyPair
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.internal.isDirectory
|
||||
import net.corda.core.internal.x500Name
|
||||
import net.corda.core.utilities.contextLogger
|
||||
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
||||
import net.corda.nodeapi.internal.crypto.CertificateType.*
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_INTERMEDIATE_CA
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
|
||||
import net.corda.nodeapi.internal.crypto.addOrReplaceCertificate
|
||||
import net.corda.nodeapi.internal.crypto.loadOrCreateKeyStore
|
||||
import net.corda.nodeapi.internal.crypto.save
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.nio.file.Path
|
||||
import java.security.Key
|
||||
import java.security.KeyPair
|
||||
@ -50,10 +48,10 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) {
|
||||
val keyStore = getAndInitializeKeyStore(provider)
|
||||
val keyPair = certConfig.generateEcdsaKeyPair(keyName, provider, keyStore)
|
||||
val certChain = if (rootProvider == null) {
|
||||
certConfig.generateRootCert(provider, keyPair, trustStoreDirectory, trustStorePassword)
|
||||
arrayOf(certConfig.generateRootCert(provider, keyPair, trustStoreDirectory, trustStorePassword))
|
||||
} else {
|
||||
val rootKeyStore = getAndInitializeKeyStore(rootProvider)
|
||||
certConfig.generateIntermediateCert(rootProvider, keyPair, rootKeyStore)
|
||||
certConfig.generateIntermediateCertChain(rootProvider, keyPair, rootKeyStore)
|
||||
}
|
||||
keyStore.addOrReplaceKey(keyName, keyPair.private, null, certChain)
|
||||
logger.info("New certificate and key pair named $keyName have been generated and stored in HSM")
|
||||
@ -71,43 +69,41 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) {
|
||||
private fun CertificateConfiguration.generateRootCert(provider: CryptoServerProvider,
|
||||
keyPair: KeyPair,
|
||||
networkRootTrustStoreDirectory: Path,
|
||||
networkRootTrustStorePassword: String): Array<X509Certificate> {
|
||||
val certificate = createSelfSignedCACert(ROOT_CA,
|
||||
networkRootTrustStorePassword: String): X509Certificate {
|
||||
val rootCert = createSelfSignedCert(
|
||||
ROOT_CA,
|
||||
CordaX500Name.parse(subject).x500Name,
|
||||
keyPair,
|
||||
validDays,
|
||||
provider,
|
||||
crlDistributionUrl,
|
||||
crlIssuer).certificate
|
||||
logger.info("Certificate for $subject created.")
|
||||
crlIssuer?.let { X500Name(it) })
|
||||
logger.info("Created root cert:\n$rootCert")
|
||||
val trustStorePath = networkRootTrustStoreDirectory / "truststore.jks"
|
||||
val trustStore = loadOrCreateKeyStore(trustStorePath, networkRootTrustStorePassword)
|
||||
logger.info("Trust store for distribution to nodes created in $trustStore")
|
||||
trustStore.addOrReplaceCertificate(CORDA_ROOT_CA, certificate)
|
||||
logger.info("Certificate $CORDA_ROOT_CA has been added to $trustStore")
|
||||
trustStore.save(trustStorePath, networkRootTrustStorePassword)
|
||||
logger.info("Trust store has been persisted. Ready for distribution.")
|
||||
return arrayOf(certificate)
|
||||
X509KeyStore.fromFile(trustStorePath, networkRootTrustStorePassword, createNew = true).update {
|
||||
setCertificate(CORDA_ROOT_CA, rootCert)
|
||||
}
|
||||
logger.info("Trust store containing the root for distribution to the nodes created in $trustStorePath")
|
||||
return rootCert
|
||||
}
|
||||
|
||||
private fun CertificateConfiguration.generateIntermediateCert(
|
||||
private fun CertificateConfiguration.generateIntermediateCertChain(
|
||||
provider: CryptoServerProvider,
|
||||
keyPair: KeyPair,
|
||||
rootKeyStore: KeyStore): Array<X509Certificate> {
|
||||
logger.info("Retrieving the root key pair.")
|
||||
val rootKeysAndCertChain = retrieveKeysAndCertificateChain(CORDA_ROOT_CA,
|
||||
rootKeyStore)
|
||||
val rootKeysAndCertChain = retrieveCertAndKeyPair(CORDA_ROOT_CA, rootKeyStore)
|
||||
val certificateAndKeyPair = createIntermediateCert(
|
||||
certificateType,
|
||||
CordaX500Name.parse(subject).x500Name,
|
||||
CertificateAndKeyPair(rootKeysAndCertChain.certificateChain.first(), rootKeysAndCertChain.keyPair),
|
||||
rootKeysAndCertChain,
|
||||
keyPair,
|
||||
validDays,
|
||||
provider,
|
||||
crlDistributionUrl,
|
||||
crlIssuer)
|
||||
crlIssuer?.let { X500Name(it) })
|
||||
logger.info("Certificate for $subject created.")
|
||||
return arrayOf(certificateAndKeyPair.certificate, *rootKeysAndCertChain.certificateChain)
|
||||
return arrayOf(certificateAndKeyPair.certificate, rootKeysAndCertChain.certificate)
|
||||
}
|
||||
|
||||
private fun CertificateConfiguration.generateECDSAKey(keyName: String, provider: CryptoServerProvider) {
|
||||
@ -129,6 +125,6 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) {
|
||||
generateECDSAKey(keyName, provider)
|
||||
val privateKey = keyStore.getKey(keyName, null) as PrivateKey
|
||||
val publicKey = keyStore.getCertificate(keyName).publicKey
|
||||
return getCleanEcdsaKeyPair(publicKey, privateKey)
|
||||
return KeyPair(cleanEcdsaPublicKey(publicKey), privateKey)
|
||||
}
|
||||
}
|
@ -3,11 +3,13 @@ package com.r3.corda.networkmanage.hsm.signer
|
||||
import com.r3.corda.networkmanage.hsm.authentication.Authenticator
|
||||
import com.r3.corda.networkmanage.hsm.persistence.ApprovedCertificateRequestData
|
||||
import com.r3.corda.networkmanage.hsm.persistence.SignedCertificateRequestStorage
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.buildCertPath
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.createClientCertificate
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.getAndInitializeKeyStore
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.retrieveCertificateAndKeys
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.retrieveCertAndKeyPair
|
||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||
import net.corda.nodeapi.internal.crypto.getX509Certificate
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
|
||||
/**
|
||||
* Encapsulates certificate signing logic
|
||||
@ -33,20 +35,19 @@ class HsmCsrSigner(private val storage: SignedCertificateRequestStorage,
|
||||
override fun sign(toSign: List<ApprovedCertificateRequestData>) {
|
||||
authenticator.connectAndAuthenticate { provider, rootProvider, signers ->
|
||||
val rootKeyStore = getAndInitializeKeyStore(rootProvider!!)
|
||||
// This should be changed once we allow for more certificates in the chain. Preferably we should use
|
||||
// keyStore.getCertificateChain(String) and assume entire chain is stored in the HSM (depending on the support).
|
||||
val rootCert = rootKeyStore.getCertificate(rootCertAlias)
|
||||
val rootCert = rootKeyStore.getX509Certificate(rootCertAlias)
|
||||
val keyStore = getAndInitializeKeyStore(provider)
|
||||
val doormanCertAndKey = retrieveCertificateAndKeys(intermediateCertAlias, keyStore)
|
||||
val doormanCertAndKey = retrieveCertAndKeyPair(intermediateCertAlias, keyStore)
|
||||
toSign.forEach {
|
||||
it.certPath = buildCertPath(createClientCertificate(
|
||||
val nodeCaCert = createClientCertificate(
|
||||
CertificateType.NODE_CA,
|
||||
doormanCertAndKey,
|
||||
it.request,
|
||||
validDays,
|
||||
provider,
|
||||
csrCertCrlDistPoint,
|
||||
csrCertCrlIssuer), doormanCertAndKey.certificate, rootCert)
|
||||
csrCertCrlIssuer?.let { X500Name(it) })
|
||||
it.certPath = X509Utilities.buildCertPath(nodeCaCert, doormanCertAndKey.certificate, rootCert)
|
||||
}
|
||||
storage.store(toSign, signers)
|
||||
println("The following certificates have been signed by $signers:")
|
||||
|
@ -14,8 +14,7 @@ import java.security.Signature
|
||||
/**
|
||||
* Signer which connects to a HSM using the given [authenticator] to sign bytes.
|
||||
*/
|
||||
// TODO Rename this to HsmSigner
|
||||
class HsmNetworkMapSigner(private val authenticator: Authenticator) : Signer {
|
||||
class HsmSigner(private val authenticator: Authenticator) : Signer {
|
||||
/**
|
||||
* Signs given data using [CryptoServerJCE.CryptoServerProvider], which connects to the underlying HSM.
|
||||
*/
|
@ -24,8 +24,6 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
|
||||
import java.math.BigInteger
|
||||
import java.security.*
|
||||
import java.security.cert.Certificate
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.X509Certificate
|
||||
import java.security.spec.X509EncodedKeySpec
|
||||
import java.time.Instant
|
||||
@ -34,7 +32,7 @@ import java.util.*
|
||||
|
||||
object HsmX509Utilities {
|
||||
|
||||
val SIGNATURE_ALGORITHM = "SHA256withECDSA"
|
||||
const val SIGNATURE_ALGORITHM = "SHA256withECDSA"
|
||||
|
||||
/**
|
||||
* Create a de novo root self-signed X509 v3 CA cert for the specified [KeyPair].
|
||||
@ -45,27 +43,26 @@ object HsmX509Utilities {
|
||||
* @param provider provider to be used during the certificate signing process
|
||||
* @param crlDistPoint url to the certificate revocation list of this certificate
|
||||
* @param crlIssuer issuer of the certificate revocation list of this certificate
|
||||
* @return an instance of [CertificateAndKeyPair] class is returned containing the new root CA Cert and its [KeyPair] for signing downstream certificates.
|
||||
* @return the new root cert.
|
||||
* Note the generated certificate tree is capped at max depth of 2 to be in line with commercially available certificates
|
||||
*/
|
||||
fun createSelfSignedCACert(type: CertificateType,
|
||||
subject: X500Name,
|
||||
keyPair: KeyPair,
|
||||
validDays: Int,
|
||||
provider: Provider,
|
||||
crlDistPoint: String? = null,
|
||||
crlIssuer: String? = null): CertificateAndKeyPair {
|
||||
// TODO this needs to be chaneged
|
||||
fun createSelfSignedCert(type: CertificateType,
|
||||
subject: X500Name,
|
||||
keyPair: KeyPair,
|
||||
validDays: Int,
|
||||
provider: Provider,
|
||||
crlDistPoint: String? = null,
|
||||
crlIssuer: X500Name? = null): X509Certificate {
|
||||
// TODO this needs to be changed
|
||||
val serial = BigInteger.valueOf(random63BitValue(provider))
|
||||
val pubKey = keyPair.public
|
||||
|
||||
// Ten year certificate validity
|
||||
// TODO how do we manage certificate expiry, revocation and loss
|
||||
val window = getCertificateValidityWindow(0, validDays)
|
||||
val keyPurposes = DERSequence(ASN1EncodableVector().apply { type.purposes.forEach { add(it) } })
|
||||
|
||||
val builder = JcaX509v3CertificateBuilder(subject, serial, window.first, window.second, subject, pubKey)
|
||||
builder.addExtension(Extension.subjectKeyIdentifier, false, createSubjectKeyIdentifier(pubKey))
|
||||
val builder = JcaX509v3CertificateBuilder(subject, serial, window.first, window.second, subject, keyPair.public)
|
||||
builder.addExtension(Extension.subjectKeyIdentifier, false, createSubjectKeyIdentifier(keyPair.public))
|
||||
builder.addExtension(Extension.basicConstraints, true, BasicConstraints(type.isCA))
|
||||
builder.addExtension(Extension.keyUsage, false, type.keyUsage)
|
||||
builder.addExtension(Extension.extendedKeyUsage, false, keyPurposes)
|
||||
@ -77,52 +74,33 @@ object HsmX509Utilities {
|
||||
|
||||
val cert = signCertificate(builder, keyPair.private, provider)
|
||||
|
||||
cert.checkValidity(Date())
|
||||
cert.verify(pubKey)
|
||||
cert.checkValidity()
|
||||
cert.verify(keyPair.public)
|
||||
|
||||
return CertificateAndKeyPair(cert, KeyPair(pubKey, keyPair.private))
|
||||
return cert
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a helper function, which purpose is to workaround a bug in the bouncycastle library
|
||||
* that is associated with the incorrect encoded byte production when the EC algorithm is used with the passed keys.
|
||||
* @param publicKey public key
|
||||
* @param privateKey private key
|
||||
* @return cleaned [KeyPair] instance
|
||||
* @return cleaned [PublicKey] instance
|
||||
*/
|
||||
fun getCleanEcdsaKeyPair(publicKey: PublicKey, privateKey: PrivateKey): KeyPair {
|
||||
val rawPublicKeyBytes = publicKey.encoded
|
||||
val kf = KeyFactory.getInstance("EC")
|
||||
val cleanPublicKey = kf.generatePublic(X509EncodedKeySpec(rawPublicKeyBytes))
|
||||
return KeyPair(cleanPublicKey, privateKey)
|
||||
fun cleanEcdsaPublicKey(publicKey: PublicKey): PublicKey {
|
||||
return KeyFactory.getInstance("EC").generatePublic(X509EncodedKeySpec(publicKey.encoded))
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a certificate and keys from the given key store. Also, the keys retrieved are cleaned in a sense of the
|
||||
* [getCleanEcdsaKeyPair] method.
|
||||
* @param certificateKeyName certificate and key name (alias) to be used when querying the key store.
|
||||
* Retrieves key pair and certificate from the given key store. Also, the keys retrieved are cleaned in a sense of the
|
||||
* [cleanEcdsaPublicKey] method.
|
||||
* @param alias certificate and key name (alias) to be used when querying the key store.
|
||||
* @param keyStore key store that holds the certificate with its keys.
|
||||
* @return instance of [CertificateAndKeyPair] holding the retrieved certificate with its keys.
|
||||
* @return instance of [CertificateAndKeyPair] holding the key pair and the certificate.
|
||||
*/
|
||||
fun retrieveCertificateAndKeys(certificateKeyName: String, keyStore: KeyStore): CertificateAndKeyPair {
|
||||
val privateKey = keyStore.getKey(certificateKeyName, null) as PrivateKey
|
||||
val publicKey = keyStore.getCertificate(certificateKeyName).publicKey
|
||||
val certificate = keyStore.getX509Certificate(certificateKeyName)
|
||||
return CertificateAndKeyPair(certificate, getCleanEcdsaKeyPair(publicKey, privateKey))
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves key pair and certificate chain from the given key store. Also, the keys retrieved are cleaned in a sense of the
|
||||
* [getCleanEcdsaKeyPair] method.
|
||||
* @param certificateKeyName certificate and key name (alias) to be used when querying the key store.
|
||||
* @param keyStore key store that holds the certificate with its keys.
|
||||
* @return instance of [KeyPairAndCertificateChain] holding the key pair and the certificate chain.
|
||||
*/
|
||||
fun retrieveKeysAndCertificateChain(certificateKeyName: String, keyStore: KeyStore): KeyPairAndCertificateChain {
|
||||
val privateKey = keyStore.getKey(certificateKeyName, null) as PrivateKey
|
||||
val publicKey = keyStore.getCertificate(certificateKeyName).publicKey
|
||||
val certificateChain = keyStore.getCertificateChain(certificateKeyName).map { it as X509Certificate }
|
||||
return KeyPairAndCertificateChain(getCleanEcdsaKeyPair(publicKey, privateKey), certificateChain.toTypedArray())
|
||||
fun retrieveCertAndKeyPair(alias: String, keyStore: KeyStore): CertificateAndKeyPair {
|
||||
val privateKey = keyStore.getKey(alias, null) as PrivateKey
|
||||
val certificate = keyStore.getX509Certificate(alias)
|
||||
return CertificateAndKeyPair(certificate, KeyPair(cleanEcdsaPublicKey(certificate.publicKey), privateKey))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,7 +123,7 @@ object HsmX509Utilities {
|
||||
validDays: Int,
|
||||
provider: Provider,
|
||||
crlDistPoint: String?,
|
||||
crlIssuer: String?): CertificateAndKeyPair {
|
||||
crlIssuer: X500Name?): CertificateAndKeyPair {
|
||||
|
||||
val issuer = X509CertificateHolder(certificateAuthority.certificate.encoded).subject
|
||||
val serial = BigInteger.valueOf(random63BitValue(provider))
|
||||
@ -192,7 +170,7 @@ object HsmX509Utilities {
|
||||
validDays: Int,
|
||||
provider: Provider,
|
||||
crlDistPoint: String?,
|
||||
crlIssuer: String?): Certificate {
|
||||
crlIssuer: X500Name?): X509Certificate {
|
||||
val jcaRequest = JcaPKCS10CertificationRequest(request)
|
||||
// This can be adjusted more to our future needs.
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, CordaX500Name.parse(jcaRequest.subject.toString()).copy(commonName = null).x500Name))), arrayOf())
|
||||
@ -249,13 +227,6 @@ object HsmX509Utilities {
|
||||
return Pair(notBefore, notAfter)
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method for transforming number of certificates into the [CertPath] instance.
|
||||
* The certificates passed should be ordered starting with the leaf certificate and ending with the root one.
|
||||
* @param certificates ordered certficates
|
||||
*/
|
||||
fun buildCertPath(vararg certificates: Certificate) = CertificateFactory.getInstance("X509").generateCertPath(certificates.asList())
|
||||
|
||||
/**
|
||||
* Creates and initializes a key store from the given crypto server provider.
|
||||
* @param provider crypto server provider to be used for the key store creation
|
||||
@ -312,11 +283,11 @@ object HsmX509Utilities {
|
||||
return certificateBuilder.build(signer).toJca()
|
||||
}
|
||||
|
||||
private fun addCrlInfo(builder: X509v3CertificateBuilder, crlDistPoint: String?, crlIssuer: String?) {
|
||||
private fun addCrlInfo(builder: X509v3CertificateBuilder, crlDistPoint: String?, crlIssuer: X500Name?) {
|
||||
if (crlDistPoint != null) {
|
||||
val distPointName = DistributionPointName(GeneralNames(GeneralName(GeneralName.uniformResourceIdentifier, crlDistPoint)))
|
||||
val crlIssuerGeneralNames = crlIssuer?.let {
|
||||
GeneralNames(GeneralName(CordaX500Name.parse(crlIssuer).x500Name))
|
||||
GeneralNames(GeneralName(crlIssuer))
|
||||
}
|
||||
// The second argument is flag that allows you to define what reason of certificate revocation is served by this distribution point see [ReasonFlags].
|
||||
// The idea is that you have different revocation per revocation reason. Since we won't go into such a granularity, we can skip that parameter.
|
||||
@ -327,5 +298,3 @@ object HsmX509Utilities {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class KeyPairAndCertificateChain(val keyPair: KeyPair, val certificateChain: Array<X509Certificate>)
|
@ -3,14 +3,13 @@ package com.r3.corda.networkmanage.common.persistence
|
||||
import com.r3.corda.networkmanage.TestBase
|
||||
import com.r3.corda.networkmanage.common.persistence.CertificationRequestStorage.Companion.DOORMAN_SIGNATURE
|
||||
import com.r3.corda.networkmanage.common.persistence.entity.CertificateSigningRequestEntity
|
||||
import com.r3.corda.networkmanage.common.utils.buildCertPath
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||
import net.corda.nodeapi.internal.persistence.CordaPersistence
|
||||
import net.corda.testing.internal.createDevNodeCaCertPath
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||
import net.corda.testing.internal.createDevNodeCaCertPath
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
|
||||
@ -228,9 +227,8 @@ class PersistentCertificateRequestStorageTest : TestBase() {
|
||||
|
||||
private fun generateSignedCertPath(csr: PKCS10CertificationRequest, keyPair: KeyPair): CertPath {
|
||||
return JcaPKCS10CertificationRequest(csr).run {
|
||||
// TODO We need a utility in InternalUtils for converting X500Name -> CordaX500Name
|
||||
val (rootCa, intermediateCa, nodeCa) = createDevNodeCaCertPath(CordaX500Name.build(X500Principal(subject.encoded)), keyPair)
|
||||
buildCertPath(nodeCa.certificate, intermediateCa.certificate, rootCa.certificate)
|
||||
X509Utilities.buildCertPath(nodeCa.certificate, intermediateCa.certificate, rootCa.certificate)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.r3.corda.networkmanage.common.persistence
|
||||
|
||||
import com.r3.corda.networkmanage.TestBase
|
||||
import com.r3.corda.networkmanage.common.utils.buildCertPath
|
||||
import com.r3.corda.networkmanage.common.utils.hashString
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SecureHash
|
||||
@ -71,7 +70,7 @@ class PersistentNodeInfoStorageTest : TestBase() {
|
||||
|
||||
requestStorage.putCertificatePath(
|
||||
requestId,
|
||||
buildCertPath(nodeCaCert, intermediateCa.certificate, rootCaCert),
|
||||
X509Utilities.buildCertPath(nodeCaCert, intermediateCa.certificate, rootCaCert),
|
||||
listOf(CertificationRequestStorage.DOORMAN_SIGNATURE))
|
||||
|
||||
val storedCertPath = nodeInfoStorage.getCertificatePath(SecureHash.parse(keyPair.public.hashString()))
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.r3.corda.networkmanage.doorman
|
||||
|
||||
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory
|
||||
import com.r3.corda.networkmanage.common.utils.buildCertPath
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
@ -10,6 +9,7 @@ import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.net.URI
|
||||
import javax.security.auth.x500.X500Principal
|
||||
|
||||
@Ignore
|
||||
// This is manual test for testing Jira API.
|
||||
@ -41,8 +41,10 @@ class JiraClientTest {
|
||||
@Test
|
||||
fun updateSignedRequests() {
|
||||
val requests = jiraClient.getApprovedRequests()
|
||||
val selfSignedCA = X509Utilities.createSelfSignedCACertificate(CordaX500Name("test", "london", "GB").x500Principal, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME))
|
||||
jiraClient.updateSignedRequests(requests.map { it.requestId to buildCertPath(selfSignedCA) }.toMap())
|
||||
val selfSignedCaCertPath = X509Utilities.buildCertPath(X509Utilities.createSelfSignedCACertificate(
|
||||
X500Principal("O=test,L=london,C=GB"),
|
||||
Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)))
|
||||
jiraClient.updateSignedRequests(requests.associateBy({ it.requestId }, { selfSignedCaCertPath }))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -29,14 +29,17 @@ class DefaultCsrHandlerTest : TestBase() {
|
||||
|
||||
val requestStorage: CertificationRequestStorage = mock {
|
||||
on { getRequest("New") }.thenReturn(certificateSigningRequest())
|
||||
on { getRequest("Signed") }.thenReturn(certificateSigningRequest(status = RequestStatus.SIGNED, certData = certificateData(CertificateStatus.VALID, buildCertPath(cert))))
|
||||
on { getRequest("Signed") }.thenReturn(certificateSigningRequest(
|
||||
status = RequestStatus.SIGNED,
|
||||
certData = certificateData(CertificateStatus.VALID, X509Utilities.buildCertPath(cert))
|
||||
))
|
||||
on { getRequest("Rejected") }.thenReturn(certificateSigningRequest(status = RequestStatus.REJECTED, remark = "Random reason"))
|
||||
}
|
||||
val requestProcessor = DefaultCsrHandler(requestStorage, null)
|
||||
|
||||
assertEquals(CertificateResponse.NotReady, requestProcessor.getResponse("random"))
|
||||
assertEquals(CertificateResponse.NotReady, requestProcessor.getResponse("New"))
|
||||
assertEquals(CertificateResponse.Ready(buildCertPath(cert)), requestProcessor.getResponse("Signed"))
|
||||
assertEquals(CertificateResponse.Ready(X509Utilities.buildCertPath(cert)), requestProcessor.getResponse("Signed"))
|
||||
assertEquals(CertificateResponse.Unauthorised("Random reason"), requestProcessor.getResponse("Rejected"))
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package com.r3.corda.networkmanage.doorman.webservice
|
||||
import com.nhaarman.mockito_kotlin.*
|
||||
import com.r3.corda.networkmanage.TestBase
|
||||
import com.r3.corda.networkmanage.common.persistence.CertificateResponse
|
||||
import com.r3.corda.networkmanage.common.utils.buildCertPath
|
||||
import com.r3.corda.networkmanage.doorman.NetworkManagementWebServer
|
||||
import com.r3.corda.networkmanage.doorman.signer.CsrHandler
|
||||
import net.corda.core.crypto.Crypto
|
||||
@ -109,7 +108,7 @@ class RegistrationWebServiceTest : TestBase() {
|
||||
intermediateCa.keyPair,
|
||||
X500Principal(subject.encoded),
|
||||
publicKey)
|
||||
buildCertPath(tlsCert, intermediateCa.certificate, rootCaCert)
|
||||
X509Utilities.buildCertPath(tlsCert, intermediateCa.certificate, rootCaCert)
|
||||
}
|
||||
null
|
||||
}
|
||||
@ -157,7 +156,7 @@ class RegistrationWebServiceTest : TestBase() {
|
||||
X500Principal(subject.encoded),
|
||||
publicKey,
|
||||
nameConstraints = nameConstraints)
|
||||
buildCertPath(clientCert, intermediateCa.certificate, rootCaCert)
|
||||
X509Utilities.buildCertPath(clientCert, intermediateCa.certificate, rootCaCert)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user