diff --git a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/doorman/DoormanIntegrationTest.kt b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/doorman/DoormanIntegrationTest.kt index 5993cef210..207a524aba 100644 --- a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/doorman/DoormanIntegrationTest.kt +++ b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/doorman/DoormanIntegrationTest.kt @@ -3,14 +3,11 @@ package com.r3.corda.networkmanage.doorman import com.nhaarman.mockito_kotlin.doReturn import com.nhaarman.mockito_kotlin.whenever import com.r3.corda.networkmanage.common.persistence.configureDatabase -import com.r3.corda.networkmanage.common.utils.toX509Certificate import com.r3.corda.networkmanage.doorman.signer.LocalSigner import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash import net.corda.core.crypto.sign -import net.corda.core.identity.CordaX500Name import net.corda.core.identity.PartyAndCertificate -import net.corda.core.internal.cert import net.corda.core.internal.createDirectories import net.corda.core.internal.div import net.corda.core.node.NodeInfo @@ -28,12 +25,13 @@ import net.corda.testing.ALICE_NAME import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.internal.rigorousMock -import org.bouncycastle.cert.X509CertificateHolder import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder import java.net.URL +import java.security.cert.X509Certificate import java.util.* +import javax.security.auth.x500.X500Principal import kotlin.test.assertEquals import kotlin.test.assertNotNull @@ -60,7 +58,7 @@ class DoormanIntegrationTest { } config.trustStoreFile.parent.createDirectories() loadOrCreateKeyStore(config.trustStoreFile, config.trustStorePassword).also { - it.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCertAndKey.certificate.cert) + it.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCertAndKey.certificate) it.save(config.trustStoreFile, config.trustStorePassword) } @@ -77,18 +75,18 @@ class DoormanIntegrationTest { loadKeyStore(config.nodeKeystore, config.keyStorePassword).apply { assert(containsAlias(X509Utilities.CORDA_CLIENT_CA)) assertEquals(ALICE_NAME.x500Principal, getX509Certificate(X509Utilities.CORDA_CLIENT_CA).subjectX500Principal) - assertEquals(listOf(intermediateCACert.cert, rootCACert.cert), getCertificateChain(X509Utilities.CORDA_CLIENT_CA).drop(1).toList()) + assertEquals(listOf(intermediateCACert, rootCACert), getCertificateChain(X509Utilities.CORDA_CLIENT_CA).drop(1).toList()) } loadKeyStore(config.sslKeystore, config.keyStorePassword).apply { assert(containsAlias(X509Utilities.CORDA_CLIENT_TLS)) assertEquals(ALICE_NAME.x500Principal, getX509Certificate(X509Utilities.CORDA_CLIENT_TLS).subjectX500Principal) - assertEquals(listOf(intermediateCACert.cert, rootCACert.cert), getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).drop(2).toList()) + assertEquals(listOf(intermediateCACert, rootCACert), getCertificateChain(X509Utilities.CORDA_CLIENT_TLS).drop(2).toList()) } loadKeyStore(config.trustStoreFile, config.trustStorePassword).apply { assert(containsAlias(X509Utilities.CORDA_ROOT_CA)) - assertEquals(rootCACert.cert.subjectX500Principal, getX509Certificate(X509Utilities.CORDA_ROOT_CA).subjectX500Principal) + assertEquals(rootCACert.subjectX500Principal, getX509Certificate(X509Utilities.CORDA_ROOT_CA).subjectX500Principal) } doorman.close() @@ -110,21 +108,26 @@ class DoormanIntegrationTest { } config.trustStoreFile.parent.createDirectories() loadOrCreateKeyStore(config.trustStoreFile, config.trustStorePassword).also { - it.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCertAndKey.certificate.cert) + it.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCertAndKey.certificate) it.save(config.trustStoreFile, config.trustStorePassword) } NetworkRegistrationHelper(config, HTTPNetworkRegistrationService(config.compatibilityZoneURL!!)).buildKeystore() // Publish NodeInfo - val networkMapClient = NetworkMapClient(config.compatibilityZoneURL!!, rootCertAndKey.certificate.cert) + val networkMapClient = NetworkMapClient(config.compatibilityZoneURL!!, rootCertAndKey.certificate) val keyStore = loadKeyStore(config.nodeKeystore, config.keyStorePassword) val clientCertPath = keyStore.getCertificateChain(X509Utilities.CORDA_CLIENT_CA) val clientCA = keyStore.getCertificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA, config.keyStorePassword) val identityKeyPair = Crypto.generateKeyPair() - val identityCert = X509Utilities.createCertificate(CertificateType.LEGAL_IDENTITY, clientCA.certificate, clientCA.keyPair, ALICE_NAME, identityKeyPair.public) - val certPath = X509CertificateFactory().generateCertPath(identityCert.cert, *clientCertPath) + val identityCert = X509Utilities.createCertificate( + CertificateType.LEGAL_IDENTITY, + clientCA.certificate, + clientCA.keyPair, + ALICE_NAME.x500Principal, + identityKeyPair.public) + val certPath = X509CertificateFactory().generateCertPath(identityCert, *clientCertPath) val nodeInfo = NodeInfo(listOf(NetworkHostAndPort("my.company.com", 1234)), listOf(PartyAndCertificate(certPath)), 1, serial = 1L) val nodeInfoBytes = nodeInfo.serialize() @@ -156,23 +159,23 @@ class DoormanIntegrationTest { } -fun createDoormanIntermediateCertificateAndKeyPair(rootCertificateAndKeyPair: CertificateAndKeyPair): CertificateAndKeyPair { - val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCertificateAndKeyPair.certificate, rootCertificateAndKeyPair.keyPair, - CordaX500Name(commonName = "Integration Test Corda Node Intermediate CA", - locality = "London", - country = "GB", - organisation = "R3 Ltd"), intermediateCAKey.public) - return CertificateAndKeyPair(intermediateCACert, intermediateCAKey) +fun createDoormanIntermediateCertificateAndKeyPair(rootCa: CertificateAndKeyPair): CertificateAndKeyPair { + val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) + val intermediateCACert = X509Utilities.createCertificate( + CertificateType.INTERMEDIATE_CA, + rootCa.certificate, + rootCa.keyPair, + X500Principal("CN=Integration Test Corda Node Intermediate CA,O=R3 Ltd,L=London,C=GB"), + keyPair.public) + return CertificateAndKeyPair(intermediateCACert, keyPair) } fun createDoormanRootCertificateAndKeyPair(): CertificateAndKeyPair { - val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val rootCACert = X509Utilities.createSelfSignedCACertificate( - CordaX500Name(commonName = "Integration Test Corda Node Root CA", - organisation = "R3 Ltd", locality = "London", - country = "GB"), rootCAKey) - return CertificateAndKeyPair(rootCACert, rootCAKey) + val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) + val rootCaCert = X509Utilities.createSelfSignedCACertificate( + X500Principal("CN=Integration Test Corda Node Root CA,O=R3 Ltd,L=London,C=GB"), + keyPair) + return CertificateAndKeyPair(rootCaCert, keyPair) } fun makeTestDataSourceProperties(nodeName: String = SecureHash.randomSHA256().toString()): Properties { @@ -184,9 +187,8 @@ fun makeTestDataSourceProperties(nodeName: String = SecureHash.randomSHA256().to return props } -fun startDoorman(intermediateCACertAndKey: CertificateAndKeyPair, rootCACert: X509CertificateHolder): NetworkManagementServer { - val signer = LocalSigner(intermediateCACertAndKey.keyPair, - arrayOf(intermediateCACertAndKey.certificate.toX509Certificate(), rootCACert.toX509Certificate())) +fun startDoorman(intermediateCACertAndKey: CertificateAndKeyPair, rootCACert: X509Certificate): NetworkManagementServer { + val signer = LocalSigner(intermediateCACertAndKey.keyPair, arrayOf(intermediateCACertAndKey.certificate, rootCACert)) //Start doorman server return startDoorman(signer) } diff --git a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/SigningServiceIntegrationTest.kt b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/SigningServiceIntegrationTest.kt index 1c0bef94f2..b2e7298de1 100644 --- a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/SigningServiceIntegrationTest.kt +++ b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/SigningServiceIntegrationTest.kt @@ -10,7 +10,6 @@ import com.r3.corda.networkmanage.hsm.persistence.DBSignedCertificateRequestStor import com.r3.corda.networkmanage.hsm.persistence.SignedCertificateRequestStorage import com.r3.corda.networkmanage.hsm.signer.HsmCsrSigner import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.cert import net.corda.core.internal.createDirectories import net.corda.core.internal.div import net.corda.core.internal.uncheckedCast @@ -28,12 +27,12 @@ import net.corda.testing.CHARLIE_NAME import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.internal.createDevIntermediateCaCertPath import net.corda.testing.internal.rigorousMock -import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest import org.h2.tools.Server import org.junit.* import org.junit.rules.TemporaryFolder import java.net.URL +import java.security.cert.X509Certificate import java.util.* import javax.persistence.PersistenceException import kotlin.concurrent.scheduleAtFixedRate @@ -55,7 +54,7 @@ class SigningServiceIntegrationTest { val testSerialization = SerializationEnvironmentRule(true) private lateinit var timer: Timer - private lateinit var rootCaCert: X509CertificateHolder + private lateinit var rootCaCert: X509Certificate private lateinit var intermediateCa: CertificateAndKeyPair @Before @@ -79,7 +78,7 @@ class SigningServiceIntegrationTest { for (approvedRequest in approvedRequests) { JcaPKCS10CertificationRequest(approvedRequest.request).run { val nodeCa = createDevNodeCa(intermediateCa, CordaX500Name.parse(subject.toString())) - approvedRequest.certPath = buildCertPath(nodeCa.certificate.cert, intermediateCa.certificate.cert, rootCaCert.cert) + approvedRequest.certPath = buildCertPath(nodeCa.certificate, intermediateCa.certificate, rootCaCert) } } storage.store(approvedRequests, listOf("TEST")) @@ -124,7 +123,7 @@ class SigningServiceIntegrationTest { } config.certificatesDirectory.createDirectories() loadOrCreateKeyStore(config.trustStoreFile, config.trustStorePassword).also { - it.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCaCert.cert) + it.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCaCert) it.save(config.trustStoreFile, config.trustStorePassword) } NetworkRegistrationHelper(config, HTTPNetworkRegistrationService(config.compatibilityZoneURL!!)).buildKeystore() @@ -168,7 +167,7 @@ class SigningServiceIntegrationTest { } config.certificatesDirectory.createDirectories() loadOrCreateKeyStore(config.trustStoreFile, config.trustStorePassword).also { - it.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCaCert.cert) + it.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, rootCaCert) it.save(config.trustStoreFile, config.trustStorePassword) } NetworkRegistrationHelper(config, HTTPNetworkRegistrationService(config.compatibilityZoneURL!!)).buildKeystore() diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentCertificateRequestStorage.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentCertificateRequestStorage.kt index f134727fac..566729a239 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentCertificateRequestStorage.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentCertificateRequestStorage.kt @@ -5,15 +5,14 @@ import com.r3.corda.networkmanage.common.persistence.entity.CertificateSigningRe import com.r3.corda.networkmanage.common.utils.hashString import net.corda.core.crypto.SecureHash import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.x500Name import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.DatabaseTransaction import net.corda.nodeapi.internal.persistence.TransactionIsolationLevel -import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.pkcs.PKCS10CertificationRequest import org.hibernate.Session import java.security.cert.CertPath import java.time.Instant +import javax.security.auth.x500.X500Principal /** * Database implementation of the [CertificationRequestStorage] interface. @@ -48,7 +47,7 @@ class PersistentCertificateRequestStorage(private val database: CordaPersistence val (legalName, rejectReason) = parseAndValidateLegalName(request, session) session.save(CertificateSigningRequestEntity( requestId = requestId, - legalName = legalName.toString(), + legalName = legalName, requestBytes = request.encoded, remark = rejectReason, modifiedBy = emptyList(), @@ -126,25 +125,27 @@ class PersistentCertificateRequestStorage(private val database: CordaPersistence } } - private fun parseAndValidateLegalName(request: PKCS10CertificationRequest, session: Session): Pair { + private fun parseAndValidateLegalName(request: PKCS10CertificationRequest, session: Session): Pair { + // It's important that we always use the toString() output of CordaX500Name as it standardises the string format + // to make querying possible. val legalName = try { - CordaX500Name.parse(request.subject.toString()) + CordaX500Name.build(X500Principal(request.subject.encoded)).toString() } catch (e: IllegalArgumentException) { - return Pair(request.subject, "Name validation failed with exception : ${e.message}") + return Pair(request.subject.toString(), "Name validation failed: ${e.message}") } + val query = session.criteriaBuilder.run { val criteriaQuery = createQuery(CertificateSigningRequestEntity::class.java) criteriaQuery.from(CertificateSigningRequestEntity::class.java).run { - criteriaQuery.where(equal(get(CertificateSigningRequestEntity::legalName.name), legalName.toString())) + criteriaQuery.where(equal(get(CertificateSigningRequestEntity::legalName.name), legalName)) } } + val duplicates = session.createQuery(query).resultList.filter { - it.status in setOf(RequestStatus.NEW, RequestStatus.TICKET_CREATED, RequestStatus.APPROVED) || it.certificateData?.certificateStatus == CertificateStatus.VALID - } - return if (duplicates.isEmpty()) { - Pair(legalName.x500Name, null) - } else { - Pair(legalName.x500Name, "Duplicate legal name") + it.status in setOf(RequestStatus.NEW, RequestStatus.TICKET_CREATED, RequestStatus.APPROVED) || + it.certificateData?.certificateStatus == CertificateStatus.VALID } + + return Pair(legalName, if (duplicates.isEmpty()) null else "Duplicate legal name") } } \ No newline at end of file diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/JiraCient.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/JiraCient.kt index e53a927b14..d7ebf4abc0 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/JiraCient.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/JiraCient.kt @@ -6,9 +6,7 @@ import com.atlassian.jira.rest.client.api.domain.Issue import com.atlassian.jira.rest.client.api.domain.IssueType import com.atlassian.jira.rest.client.api.domain.input.IssueInputBuilder import com.atlassian.jira.rest.client.api.domain.input.TransitionInput -import net.corda.core.internal.country -import net.corda.core.internal.locality -import net.corda.core.internal.organisation +import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.loggerFor import net.corda.nodeapi.internal.crypto.X509Utilities import org.bouncycastle.asn1.x500.style.BCStyle @@ -17,6 +15,7 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest import org.bouncycastle.util.io.pem.PemObject import java.io.StringWriter import java.security.cert.CertPath +import javax.security.auth.x500.X500Principal class JiraClient(private val restClient: JiraRestClient, private val projectCode: String, private val doneTransitionCode: Int) { companion object { @@ -39,16 +38,17 @@ class JiraClient(private val restClient: JiraRestClient, private val projectCode JcaPEMWriter(request).use { it.writeObject(PemObject("CERTIFICATE REQUEST", signingRequest.encoded)) } - val organisation = signingRequest.subject.organisation - val nearestCity = signingRequest.subject.locality - val country = signingRequest.subject.country + + // TODO The subject of the signing request has already been validated and parsed into a CordaX500Name. We shouldn't + // have to do it again here. + val subject = CordaX500Name.build(X500Principal(signingRequest.subject.encoded)) val email = signingRequest.getAttributes(BCStyle.E).firstOrNull()?.attrValues?.firstOrNull()?.toString() val issue = IssueInputBuilder().setIssueTypeId(taskIssueType.id) .setProjectKey(projectCode) - .setDescription("Organisation: $organisation\nNearest City: $nearestCity\nCountry: $country\nEmail: $email\n\n{code}$request{code}") - .setSummary(organisation) + .setDescription("Organisation: ${subject.organisation}\nNearest City: ${subject.locality}\nCountry: ${subject.country}\nEmail: $email\n\n{code}$request{code}") + .setSummary(subject.organisation) .setFieldValue(requestIdField.id, requestId) // This will block until the issue is created. restClient.issueClient.createIssue(issue.build()).fail { logger.error("Exception when creating JIRA issue.", it) }.claim() diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/Main.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/Main.kt index 2a4db95100..6b5f3636f3 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/Main.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/Main.kt @@ -13,7 +13,6 @@ import com.r3.corda.networkmanage.doorman.webservice.NodeInfoWebService import com.r3.corda.networkmanage.doorman.webservice.RegistrationWebService import net.corda.core.crypto.Crypto import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.cert import net.corda.core.internal.createDirectories import net.corda.core.internal.div import net.corda.core.serialization.internal.SerializationEnvironmentImpl @@ -188,8 +187,8 @@ 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( - CordaX500Name(commonName = "Corda Root CA", organisation = "R3 Ltd", locality = "London", country = "GB", organisationUnit = "Corda", state = null), - selfSignKey).cert + CordaX500Name(commonName = "Corda Root CA", organisation = "R3 Ltd", locality = "London", country = "GB", organisationUnit = "Corda", state = null).x500Principal, + selfSignKey) rootStore.addOrReplaceKey(X509Utilities.CORDA_ROOT_CA, selfSignKey.private, rootPrivateKeyPassword.toCharArray(), arrayOf(selfSignCert)) rootStore.save(rootStoreFile, rootKeystorePassword) @@ -226,11 +225,20 @@ fun generateCAKeyPair(keystoreFile: Path, rootStoreFile: Path, rootKeystorePass: exitProcess(1) } - val intermediateKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val intermediateCert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootKeyAndCert.certificate, rootKeyAndCert.keyPair, - CordaX500Name(commonName = "Corda Intermediate CA", organisation = "R3 Ltd", organisationUnit = "Corda", locality = "London", country = "GB", state = null), intermediateKey.public) - keyStore.addOrReplaceKey(X509Utilities.CORDA_INTERMEDIATE_CA, intermediateKey.private, - caPrivateKeyPassword.toCharArray(), arrayOf(intermediateCert, rootKeyAndCert.certificate)) + val intermediateKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) + val intermediateCert = X509Utilities.createCertificate( + CertificateType.INTERMEDIATE_CA, + rootKeyAndCert.certificate, + rootKeyAndCert.keyPair, + CordaX500Name(commonName = "Corda Intermediate CA", organisation = "R3 Ltd", organisationUnit = "Corda", locality = "London", country = "GB", state = null).x500Principal, + intermediateKeyPair.public + ) + keyStore.addOrReplaceKey( + X509Utilities.CORDA_INTERMEDIATE_CA, + intermediateKeyPair.private, + caPrivateKeyPassword.toCharArray(), + arrayOf(intermediateCert, rootKeyAndCert.certificate) + ) keyStore.save(keystoreFile, keystorePassword) println("Intermediate CA keypair and certificate stored in $keystoreFile.") println(loadKeyStore(keystoreFile, keystorePassword).getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA).publicKey) diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/signer/LocalSigner.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/signer/LocalSigner.kt index 50a7b7f971..aa7ceaa742 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/signer/LocalSigner.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/signer/LocalSigner.kt @@ -4,9 +4,6 @@ import com.r3.corda.networkmanage.common.signer.Signer import com.r3.corda.networkmanage.common.utils.buildCertPath import com.r3.corda.networkmanage.common.utils.withCert import net.corda.core.crypto.sign -import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.cert -import net.corda.core.internal.toX509CertHolder import net.corda.nodeapi.internal.crypto.CertificateType import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.network.DigitalSignatureWithCert @@ -18,6 +15,7 @@ import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest import java.security.KeyPair import java.security.cert.CertPath import java.security.cert.X509Certificate +import javax.security.auth.x500.X500Principal /** * The [LocalSigner] class signs [PKCS10CertificationRequest] using provided CA key pair and certificate path. @@ -35,12 +33,12 @@ class LocalSigner(private val caKeyPair: KeyPair, private val caCertPath: Array< arrayOf()) val nodeCaCert = X509Utilities.createCertificate( CertificateType.NODE_CA, - caCertPath.first().toX509CertHolder(), + caCertPath[0], caKeyPair, - CordaX500Name.parse(request.subject.toString()), + X500Principal(request.subject.encoded), request.publicKey, nameConstraints = nameConstraints) - return buildCertPath(nodeCaCert.cert, *caCertPath) + return buildCertPath(nodeCaCert, *caCertPath) } override fun sign(data: ByteArray): DigitalSignatureWithCert { diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmNetworkMapSigner.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmNetworkMapSigner.kt index 2fec2a234c..0465a3621a 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmNetworkMapSigner.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmNetworkMapSigner.kt @@ -9,13 +9,12 @@ import com.r3.corda.networkmanage.hsm.authentication.Authenticator import com.r3.corda.networkmanage.hsm.utils.X509Utilities.getAndInitializeKeyStore import com.r3.corda.networkmanage.hsm.utils.X509Utilities.signData import com.r3.corda.networkmanage.hsm.utils.X509Utilities.verify -import net.corda.core.internal.cert -import net.corda.core.internal.toX509CertHolder import net.corda.core.utilities.loggerFor import net.corda.core.utilities.minutes import net.corda.nodeapi.internal.network.DigitalSignatureWithCert import java.security.KeyPair import java.security.PrivateKey +import java.security.cert.X509Certificate import java.time.Duration import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService @@ -68,7 +67,7 @@ class HsmNetworkMapSigner(networkMapStorage: NetworkMapStorage, val caKey = keyStore.getKey(caCertificateKeyName, caPrivateKeyPass.toCharArray()) as PrivateKey val signature = signData(data, KeyPair(caCertificateChain.first().publicKey, caKey), provider) verify(data, signature, caCertificateChain.first().publicKey) - signature.withCert(caCertificateChain.first().toX509CertHolder().cert) + signature.withCert(caCertificateChain[0] as X509Certificate) } } } diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/utils/X509Utils.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/utils/X509Utils.kt index 22e94ec1b5..dc4354fe0b 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/utils/X509Utils.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/utils/X509Utils.kt @@ -3,7 +3,6 @@ package com.r3.corda.networkmanage.hsm.utils import CryptoServerJCE.CryptoServerProvider import net.corda.core.crypto.DigitalSignature import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.toX509CertHolder import net.corda.core.internal.x500Name import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair import net.corda.nodeapi.internal.crypto.CertificateType @@ -81,7 +80,7 @@ object X509Utilities { cert.checkValidity(Date()) cert.verify(pubKey) - return CertificateAndKeyPair(cert.toX509CertHolder(), KeyPair(pubKey, keyPair.private)) + return CertificateAndKeyPair(cert, KeyPair(pubKey, keyPair.private)) } /** @@ -109,7 +108,7 @@ object X509Utilities { fun retrieveCertificateAndKeys(certificateKeyName: String, privateKeyPassword: String, keyStore: KeyStore): CertificateAndKeyPair { val privateKey = keyStore.getKey(certificateKeyName, privateKeyPassword.toCharArray()) as PrivateKey val publicKey = keyStore.getCertificate(certificateKeyName).publicKey - val certificate = keyStore.getX509Certificate(certificateKeyName).toX509CertHolder() + val certificate = keyStore.getX509Certificate(certificateKeyName) return CertificateAndKeyPair(certificate, getCleanEcdsaKeyPair(publicKey, privateKey)) } @@ -160,7 +159,7 @@ object X509Utilities { cert.checkValidity(Date()) cert.verify(certificateAuthority.keyPair.public) - return CertificateAndKeyPair(cert.toX509CertHolder(), KeyPair(pubKey, keyPair.private)) + return CertificateAndKeyPair(cert, KeyPair(pubKey, keyPair.private)) } /** @@ -186,7 +185,7 @@ object X509Utilities { val subject = CordaX500Name.parse(jcaRequest.subject.toString()).x500Name val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(jcaRequest.publicKey.encoded)) val keyPurposes = DERSequence(ASN1EncodableVector().apply { certificateType.purposes.forEach { add(it) } }) - val builder = JcaX509v3CertificateBuilder(issuerCertificate.subject, serial, validityWindow.first, validityWindow.second, subject, jcaRequest.publicKey) + val builder = JcaX509v3CertificateBuilder(issuerCertificate, serial, validityWindow.first, validityWindow.second, subject, jcaRequest.publicKey) .addExtension(Extension.subjectKeyIdentifier, false, BcX509ExtensionUtils().createSubjectKeyIdentifier(subjectPublicKeyInfo)) .addExtension(Extension.basicConstraints, certificateType.isCA, BasicConstraints(certificateType.isCA)) .addExtension(Extension.keyUsage, false, certificateType.keyUsage) diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/DBCertificateRequestStorageTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentCertificateRequestStorageTest.kt similarity index 71% rename from network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/DBCertificateRequestStorageTest.kt rename to network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentCertificateRequestStorageTest.kt index 56ee6f2d26..df80ebdd6e 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/DBCertificateRequestStorageTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentCertificateRequestStorageTest.kt @@ -4,15 +4,13 @@ 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 com.r3.corda.networkmanage.common.utils.toX509Certificate import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash import net.corda.core.identity.CordaX500Name -import net.corda.nodeapi.internal.crypto.CertificateType import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.persistence.CordaPersistence +import net.corda.testing.internal.createDevNodeCaCertPath import org.assertj.core.api.Assertions.assertThat -import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.pkcs.PKCS10CertificationRequest import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest import org.hibernate.envers.AuditReaderFactory @@ -21,9 +19,10 @@ import org.junit.Before import org.junit.Test import java.security.KeyPair import java.util.* +import javax.security.auth.x500.X500Principal import kotlin.test.* -class DBCertificateRequestStorageTest : TestBase() { +class PersistentCertificateRequestStorageTest : TestBase() { private lateinit var storage: PersistentCertificateRequestStorage private lateinit var persistence: CordaPersistence @@ -84,14 +83,15 @@ class DBCertificateRequestStorageTest : TestBase() { // New request should be empty. assertTrue(storage.getRequests(RequestStatus.NEW).isEmpty()) // Sign certificate - storage.putCertificatePath(requestId, JcaPKCS10CertificationRequest(csr).run { - val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Root CA", locality = "London", organisation = "R3 LTD", country = "GB"), rootCAKey) - val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, X500Name("CN=Corda Node Intermediate CA,L=London"), intermediateCAKey.public) - val ourCertificate = X509Utilities.createCertificate(CertificateType.TLS, intermediateCACert, intermediateCAKey, subject, publicKey).toX509Certificate() - buildCertPath(ourCertificate, intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) - }, listOf(DOORMAN_SIGNATURE)) + storage.putCertificatePath( + requestId, + JcaPKCS10CertificationRequest(csr).run { + // TODO We need a utility in InternalUtils for converting X500Name -> CordaX500Name + val (rootCa, intermediateCa, nodeCa) = createDevNodeCaCertPath(CordaX500Name.build(X500Principal(subject.encoded))) + buildCertPath(nodeCa.certificate, intermediateCa.certificate, rootCa.certificate) + }, + listOf(DOORMAN_SIGNATURE) + ) // Check request is ready assertNotNull(storage.getRequest(requestId)!!.certData) } @@ -104,25 +104,24 @@ class DBCertificateRequestStorageTest : TestBase() { // Store certificate to DB. storage.markRequestTicketCreated(requestId) storage.approveRequest(requestId, DOORMAN_SIGNATURE) - storage.putCertificatePath(requestId, JcaPKCS10CertificationRequest(csr).run { - val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Root CA", locality = "London", organisation = "R3 LTD", country = "GB"), rootCAKey) - val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, X500Name("CN=Corda Node Intermediate CA,L=London"), intermediateCAKey.public) - val ourCertificate = X509Utilities.createCertificate(CertificateType.TLS, intermediateCACert, intermediateCAKey, subject, publicKey).toX509Certificate() - buildCertPath(ourCertificate, intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) - }, listOf(DOORMAN_SIGNATURE)) + storage.putCertificatePath( + requestId, + JcaPKCS10CertificationRequest(csr).run { + val (rootCa, intermediateCa, nodeCa) = createDevNodeCaCertPath(CordaX500Name.build(X500Principal(subject.encoded))) + buildCertPath(nodeCa.certificate, intermediateCa.certificate, rootCa.certificate) + }, + listOf(DOORMAN_SIGNATURE) + ) // Sign certificate // When subsequent signature requested assertFailsWith(IllegalArgumentException::class) { - storage.putCertificatePath(requestId, JcaPKCS10CertificationRequest(csr).run { - val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Root CA", locality = "London", organisation = "R3 LTD", country = "GB"), rootCAKey) - val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, X500Name("CN=Corda Node Intermediate CA,L=London"), intermediateCAKey.public) - val ourCertificate = X509Utilities.createCertificate(CertificateType.TLS, intermediateCACert, intermediateCAKey, subject, publicKey).toX509Certificate() - buildCertPath(ourCertificate, intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) - }, listOf(DOORMAN_SIGNATURE)) + storage.putCertificatePath( + requestId, + JcaPKCS10CertificationRequest(csr).run { + val (rootCa, intermediateCa, nodeCa) = createDevNodeCaCertPath(CordaX500Name.build(X500Principal(subject.encoded))) + buildCertPath(nodeCa.certificate, intermediateCa.certificate, rootCa.certificate) + }, + listOf(DOORMAN_SIGNATURE)) } } @@ -207,6 +206,6 @@ class DBCertificateRequestStorageTest : TestBase() { internal fun createRequest(organisation: String): Pair { val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val request = X509Utilities.createCertificateSigningRequest(CordaX500Name(organisation = organisation, locality = "London", country = "GB"), "my@mail.com", keyPair) + val request = X509Utilities.createCertificateSigningRequest(X500Principal("O=$organisation,L=London,C=GB"), "my@mail.com", keyPair) return Pair(request, keyPair) } diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentNetworkMapStorageTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentNetworkMapStorageTest.kt index 832c124d79..de5ef7e27b 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentNetworkMapStorageTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentNetworkMapStorageTest.kt @@ -3,25 +3,24 @@ package com.r3.corda.networkmanage.common.persistence import com.r3.corda.networkmanage.TestBase import com.r3.corda.networkmanage.common.utils.withCert import com.r3.corda.networkmanage.doorman.signer.LocalSigner -import net.corda.core.crypto.Crypto import net.corda.core.crypto.sign import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.cert import net.corda.core.serialization.serialize import net.corda.nodeapi.internal.SignedNodeInfo -import net.corda.nodeapi.internal.crypto.CertificateType +import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair import net.corda.nodeapi.internal.crypto.X509CertificateFactory -import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.network.NetworkMap import net.corda.nodeapi.internal.network.SignedNetworkMap import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.internal.TestNodeInfoBuilder +import net.corda.testing.internal.createDevIntermediateCaCertPath import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties import org.assertj.core.api.Assertions.assertThat import org.junit.After import org.junit.Before import org.junit.Test +import java.security.cert.X509Certificate import kotlin.test.assertEquals class PersistentNetworkMapStorageTest : TestBase() { @@ -30,15 +29,16 @@ class PersistentNetworkMapStorageTest : TestBase() { private lateinit var nodeInfoStorage: PersistentNodeInfoStorage private lateinit var requestStorage: PersistentCertificateRequestStorage - private val rootCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val rootCaCert = X509Utilities.createSelfSignedCACertificate(CordaX500Name("Corda Node Root CA", "R3 LTD", "London", "GB"), rootCaKeyPair) - private val intermediateCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val intermediateCaCert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCaCert, rootCaKeyPair, CordaX500Name("Corda Node Intermediate CA", "R3 LTD", "London", "GB"), intermediateCaKeyPair.public) + private lateinit var rootCaCert: X509Certificate + private lateinit var intermediateCa: CertificateAndKeyPair @Before fun startDb() { + val (rootCa, intermediateCa) = createDevIntermediateCaCertPath() + rootCaCert = rootCa.certificate + this.intermediateCa = intermediateCa persistence = configureDatabase(makeTestDataSourceProperties()) - networkMapStorage = PersistentNetworkMapStorage(persistence, LocalSigner(intermediateCaKeyPair, arrayOf(intermediateCaCert.cert, rootCaCert.cert))) + networkMapStorage = PersistentNetworkMapStorage(persistence, LocalSigner(intermediateCa.keyPair, arrayOf(intermediateCa.certificate, rootCaCert))) nodeInfoStorage = PersistentNodeInfoStorage(persistence) requestStorage = PersistentCertificateRequestStorage(persistence) } @@ -60,7 +60,7 @@ class PersistentNetworkMapStorageTest : TestBase() { val networkMap = NetworkMap(listOf(nodeInfoHash), networkParametersHash) val serializedNetworkMap = networkMap.serialize() - val signatureData = intermediateCaKeyPair.sign(serializedNetworkMap).withCert(intermediateCaCert.cert) + val signatureData = intermediateCa.keyPair.sign(serializedNetworkMap).withCert(intermediateCa.certificate) val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, signatureData) // when @@ -70,7 +70,7 @@ class PersistentNetworkMapStorageTest : TestBase() { val persistedSignedNetworkMap = networkMapStorage.getCurrentNetworkMap() assertEquals(signedNetworkMap.signature, persistedSignedNetworkMap?.signature) - assertEquals(signedNetworkMap.verified(rootCaCert.cert), persistedSignedNetworkMap?.verified(rootCaCert.cert)) + assertEquals(signedNetworkMap.verified(rootCaCert), persistedSignedNetworkMap?.verified(rootCaCert)) } @Test @@ -96,7 +96,7 @@ class PersistentNetworkMapStorageTest : TestBase() { // Sign network map making it current network map val networkMap = NetworkMap(emptyList(), networkParametersHash) val serializedNetworkMap = networkMap.serialize() - val signatureData = intermediateCaKeyPair.sign(serializedNetworkMap).withCert(intermediateCaCert.cert) + val signatureData = intermediateCa.keyPair.sign(serializedNetworkMap).withCert(intermediateCa.certificate) val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, signatureData) networkMapStorage.saveNetworkMap(signedNetworkMap) @@ -117,7 +117,7 @@ class PersistentNetworkMapStorageTest : TestBase() { val netParamsHash = networkMapStorage.saveNetworkParameters(netParams) val signedNetParams = networkMapStorage.getSignedNetworkParameters(netParamsHash) assertThat(signedNetParams?.verified()).isEqualTo(netParams) - assertThat(signedNetParams?.sig?.by).isEqualTo(intermediateCaKeyPair.public) + assertThat(signedNetParams?.sig?.by).isEqualTo(intermediateCa.keyPair.public) } @Test @@ -135,7 +135,7 @@ class PersistentNetworkMapStorageTest : TestBase() { val networkParametersHash = networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList())) val networkMap = NetworkMap(listOf(nodeInfoHashA), networkParametersHash) val serializedNetworkMap = networkMap.serialize() - val signatureData = intermediateCaKeyPair.sign(serializedNetworkMap).withCert(intermediateCaCert.cert) + val signatureData = intermediateCa.keyPair.sign(serializedNetworkMap).withCert(intermediateCa.certificate) val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, signatureData) // Sign network map diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersitenceNodeInfoStorageTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersitenceNodeInfoStorageTest.kt index e5b2e37699..c8df5a3a3d 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersitenceNodeInfoStorageTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersitenceNodeInfoStorageTest.kt @@ -6,15 +6,16 @@ import com.r3.corda.networkmanage.common.utils.hashString import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.cert import net.corda.core.node.NodeInfo import net.corda.core.serialization.serialize import net.corda.nodeapi.internal.SignedNodeInfo +import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair import net.corda.nodeapi.internal.crypto.CertificateType import net.corda.nodeapi.internal.crypto.X509CertificateFactory import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.testing.internal.TestNodeInfoBuilder +import net.corda.testing.internal.createDevIntermediateCaCertPath import net.corda.testing.internal.signWith import net.corda.testing.node.MockServices import org.assertj.core.api.Assertions.assertThat @@ -22,6 +23,7 @@ import org.junit.After import org.junit.Before import org.junit.Test import java.security.PrivateKey +import java.security.cert.X509Certificate import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertNull @@ -31,13 +33,14 @@ class PersitenceNodeInfoStorageTest : TestBase() { private lateinit var nodeInfoStorage: PersistentNodeInfoStorage private lateinit var persistence: CordaPersistence - private val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Root CA", locality = "London", organisation = "R3 LTD", country = "GB"), rootCAKey) - private val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, CordaX500Name(commonName = "Corda Node Intermediate CA", locality = "London", organisation = "R3 LTD", country = "GB"), intermediateCAKey.public) + private lateinit var rootCaCert: X509Certificate + private lateinit var intermediateCa: CertificateAndKeyPair @Before fun startDb() { + val (rootCa, intermediateCa) = createDevIntermediateCaCertPath() + rootCaCert = rootCa.certificate + this.intermediateCa = intermediateCa persistence = configureDatabase(MockServices.makeTestDataSourceProperties()) nodeInfoStorage = PersistentNodeInfoStorage(persistence) requestStorage = PersistentCertificateRequestStorage(persistence) @@ -53,9 +56,14 @@ class PersitenceNodeInfoStorageTest : TestBase() { // Create node info. val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val name = CordaX500Name(organisation = "Test", locality = "London", country = "GB") - val nodeCaCert = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, name, keyPair.public) + val nodeCaCert = X509Utilities.createCertificate( + CertificateType.NODE_CA, + intermediateCa.certificate, + intermediateCa.keyPair, + name.x500Principal, + keyPair.public) - val request = X509Utilities.createCertificateSigningRequest(name, "my@mail.com", keyPair) + val request = X509Utilities.createCertificateSigningRequest(name.x500Principal, "my@mail.com", keyPair) val requestId = requestStorage.saveRequest(request) requestStorage.markRequestTicketCreated(requestId) @@ -63,12 +71,15 @@ class PersitenceNodeInfoStorageTest : TestBase() { assertNull(nodeInfoStorage.getCertificatePath(SecureHash.parse(keyPair.public.hashString()))) - requestStorage.putCertificatePath(requestId, buildCertPath(nodeCaCert.cert, intermediateCACert.cert, rootCACert.cert), listOf(CertificationRequestStorage.DOORMAN_SIGNATURE)) + requestStorage.putCertificatePath( + requestId, + buildCertPath(nodeCaCert, intermediateCa.certificate, rootCaCert), + listOf(CertificationRequestStorage.DOORMAN_SIGNATURE)) val storedCertPath = nodeInfoStorage.getCertificatePath(SecureHash.parse(keyPair.public.hashString())) assertNotNull(storedCertPath) - assertEquals(nodeCaCert.cert, storedCertPath!!.certificates.first()) + assertEquals(nodeCaCert, storedCertPath!!.certificates.first()) } @Test diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/signer/NetworkMapSignerTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/signer/NetworkMapSignerTest.kt index 92b17f107f..71926c7fac 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/signer/NetworkMapSignerTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/signer/NetworkMapSignerTest.kt @@ -4,20 +4,18 @@ import com.nhaarman.mockito_kotlin.* import com.r3.corda.networkmanage.TestBase import com.r3.corda.networkmanage.common.persistence.NetworkMapStorage import com.r3.corda.networkmanage.common.utils.withCert -import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash import net.corda.core.crypto.sha256 import net.corda.core.crypto.sign -import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.cert import net.corda.core.serialization.serialize -import net.corda.nodeapi.internal.crypto.CertificateType -import net.corda.nodeapi.internal.crypto.X509Utilities +import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair import net.corda.nodeapi.internal.network.NetworkMap import net.corda.nodeapi.internal.network.SignedNetworkMap import net.corda.testing.common.internal.testNetworkParameters +import net.corda.testing.internal.createDevIntermediateCaCertPath import org.junit.Before import org.junit.Test +import java.security.cert.X509Certificate import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -25,12 +23,15 @@ class NetworkMapSignerTest : TestBase() { private lateinit var signer: Signer private lateinit var networkMapStorage: NetworkMapStorage private lateinit var networkMapSigner: NetworkMapSigner - private val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Root CA", locality = "London", organisation = "R3 LTD", country = "GB"), rootCAKey) - private val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, CordaX500Name(commonName = "Corda Node Intermediate CA", locality = "London", organisation = "R3 LTD", country = "GB"), intermediateCAKey.public) + + private lateinit var rootCaCert: X509Certificate + private lateinit var intermediateCa: CertificateAndKeyPair + @Before fun setUp() { + val (rootCa, intermediateCa) = createDevIntermediateCaCertPath() + rootCaCert = rootCa.certificate + this.intermediateCa = intermediateCa signer = mock() networkMapStorage = mock() networkMapSigner = NetworkMapSigner(networkMapStorage, signer) @@ -43,11 +44,11 @@ class NetworkMapSignerTest : TestBase() { val networkParameters = testNetworkParameters(emptyList()) val serializedNetworkMap = NetworkMap(signedNodeInfoHashes, SecureHash.randomSHA256()).serialize() whenever(networkMapStorage.getCurrentNetworkMap()) - .thenReturn(SignedNetworkMap(serializedNetworkMap, intermediateCAKey.sign(serializedNetworkMap).withCert(intermediateCACert.cert))) + .thenReturn(SignedNetworkMap(serializedNetworkMap, intermediateCa.keyPair.sign(serializedNetworkMap).withCert(intermediateCa.certificate))) whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(signedNodeInfoHashes) whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkParameters) whenever(signer.sign(any())).then { - intermediateCAKey.sign(it.arguments.first() as ByteArray).withCert(intermediateCACert.cert) + intermediateCa.keyPair.sign(it.arguments[0] as ByteArray).withCert(intermediateCa.certificate) } // when @@ -59,7 +60,7 @@ class NetworkMapSignerTest : TestBase() { verify(networkMapStorage).getLatestNetworkParameters() argumentCaptor().apply { verify(networkMapStorage).saveNetworkMap(capture()) - val networkMap = firstValue.verified(rootCACert.cert) + val networkMap = firstValue.verified(rootCaCert) assertEquals(networkParameters.serialize().hash, networkMap.networkParameterHash) assertEquals(signedNodeInfoHashes.size, networkMap.nodeInfoHashes.size) assertTrue(networkMap.nodeInfoHashes.containsAll(signedNodeInfoHashes)) @@ -73,7 +74,7 @@ class NetworkMapSignerTest : TestBase() { val networkMapParametersHash = networkParameters.serialize().bytes.sha256() val networkMap = NetworkMap(emptyList(), networkMapParametersHash) val serializedNetworkMap = networkMap.serialize() - val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, intermediateCAKey.sign(serializedNetworkMap).withCert(intermediateCACert.cert)) + val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, intermediateCa.keyPair.sign(serializedNetworkMap).withCert(intermediateCa.certificate)) whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(signedNetworkMap) whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(emptyList()) whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkParameters) @@ -94,7 +95,7 @@ class NetworkMapSignerTest : TestBase() { whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(emptyList()) whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkParameters) whenever(signer.sign(any())).then { - intermediateCAKey.sign(it.arguments.first() as ByteArray).withCert(intermediateCACert.cert) + intermediateCa.keyPair.sign(it.arguments[0] as ByteArray).withCert(intermediateCa.certificate) } // when networkMapSigner.signNetworkMap() @@ -105,7 +106,7 @@ class NetworkMapSignerTest : TestBase() { verify(networkMapStorage).getLatestNetworkParameters() argumentCaptor().apply { verify(networkMapStorage).saveNetworkMap(capture()) - val networkMap = firstValue.verified(rootCACert.cert) + val networkMap = firstValue.verified(rootCaCert) assertEquals(networkParameters.serialize().hash, networkMap.networkParameterHash) } } diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/DefaultRequestProcessorTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/DefaultRequestProcessorTest.kt index 3029723e79..b0091a4cf6 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/DefaultRequestProcessorTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/DefaultRequestProcessorTest.kt @@ -10,24 +10,23 @@ import com.r3.corda.networkmanage.common.persistence.CertificateStatus import com.r3.corda.networkmanage.common.persistence.CertificationRequestStorage import com.r3.corda.networkmanage.common.persistence.RequestStatus import com.r3.corda.networkmanage.common.utils.buildCertPath -import com.r3.corda.networkmanage.common.utils.toX509Certificate import com.r3.corda.networkmanage.doorman.signer.DefaultCsrHandler import com.r3.corda.networkmanage.doorman.signer.LocalSigner import net.corda.core.crypto.Crypto -import net.corda.core.identity.CordaX500Name import net.corda.nodeapi.internal.crypto.X509Utilities import org.junit.Test +import javax.security.auth.x500.X500Principal import kotlin.test.assertEquals class DefaultRequestProcessorTest : TestBase() { @Test fun `get response`() { val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val cert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(locality = "London", organisation = "Test", country = "GB"), keyPair) + val cert = X509Utilities.createSelfSignedCACertificate(X500Principal("O=Test,L=London,C=GB"), keyPair) val requestStorage: CertificationRequestStorage = mock { on { getRequest("New") }.thenReturn(certificateSigningRequest()) - on { getRequest("Signed") }.thenReturn(certificateSigningRequest(status = RequestStatus.SIGNED, certData = certificateData("", CertificateStatus.VALID, buildCertPath(cert.toX509Certificate())))) + on { getRequest("Signed") }.thenReturn(certificateSigningRequest(status = RequestStatus.SIGNED, certData = certificateData("", CertificateStatus.VALID, buildCertPath(cert)))) on { getRequest("Rejected") }.thenReturn(certificateSigningRequest(status = RequestStatus.REJECTED, remark = "Random reason")) } val signer: LocalSigner = mock() @@ -35,15 +34,15 @@ class DefaultRequestProcessorTest : TestBase() { assertEquals(CertificateResponse.NotReady, requestProcessor.getResponse("random")) assertEquals(CertificateResponse.NotReady, requestProcessor.getResponse("New")) - assertEquals(CertificateResponse.Ready(buildCertPath(cert.toX509Certificate())), requestProcessor.getResponse("Signed")) + assertEquals(CertificateResponse.Ready(buildCertPath(cert)), requestProcessor.getResponse("Signed")) assertEquals(CertificateResponse.Unauthorised("Random reason"), requestProcessor.getResponse("Rejected")) } @Test fun `process request`() { - val request1 = X509Utilities.createCertificateSigningRequest(CordaX500Name(locality = "London", organisation = "Test1", country = "GB"), "my@email.com", Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) - val request2 = X509Utilities.createCertificateSigningRequest(CordaX500Name(locality = "London", organisation = "Test2", country = "GB"), "my@email.com", Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) - val request3 = X509Utilities.createCertificateSigningRequest(CordaX500Name(locality = "London", organisation = "Test3", country = "GB"), "my@email.com", Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) + val (request1, request2, request3) = (1..3).map { + X509Utilities.createCertificateSigningRequest(X500Principal("O=Test1,L=London,C=GB"), "my@email.com", Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) + } val requestStorage: CertificationRequestStorage = mock { on { getRequests(RequestStatus.APPROVED) }.thenReturn(listOf( diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/NodeInfoWebServiceTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/NodeInfoWebServiceTest.kt index 939c901c65..b376833aa1 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/NodeInfoWebServiceTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/NodeInfoWebServiceTest.kt @@ -7,33 +7,32 @@ import com.r3.corda.networkmanage.common.persistence.NetworkMapStorage import com.r3.corda.networkmanage.common.persistence.NodeInfoStorage import com.r3.corda.networkmanage.common.utils.withCert import com.r3.corda.networkmanage.doorman.webservice.NodeInfoWebService -import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash.Companion.randomSHA256 import net.corda.core.crypto.SignedData import net.corda.core.crypto.sign import net.corda.core.identity.CordaX500Name -import net.corda.core.internal.cert import net.corda.core.internal.openHttpConnection import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.seconds import net.corda.nodeapi.internal.SignedNodeInfo -import net.corda.nodeapi.internal.crypto.CertificateType -import net.corda.nodeapi.internal.crypto.X509Utilities +import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair import net.corda.nodeapi.internal.network.NetworkMap import net.corda.nodeapi.internal.network.NetworkParameters import net.corda.nodeapi.internal.network.SignedNetworkMap import net.corda.testing.SerializationEnvironmentRule import net.corda.testing.common.internal.testNetworkParameters +import net.corda.testing.internal.createDevIntermediateCaCertPath import net.corda.testing.internal.createNodeInfoAndSigned import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatExceptionOfType -import org.bouncycastle.asn1.x500.X500Name +import org.junit.Before import org.junit.Rule import org.junit.Test import java.io.FileNotFoundException import java.net.URL +import java.security.cert.X509Certificate import javax.ws.rs.core.MediaType import kotlin.test.assertEquals @@ -42,12 +41,18 @@ class NodeInfoWebServiceTest { @JvmField val testSerialization = SerializationEnvironmentRule(true) - private val rootCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val rootCaCert = X509Utilities.createSelfSignedCACertificate(CordaX500Name("Corda Node Root CA", "R3 LTD", "London", "GB"), rootCaKeyPair) - private val intermediateCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val intermediateCaCert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCaCert, rootCaKeyPair, X500Name("CN=Corda Node Intermediate CA,L=London"), intermediateCaKeyPair.public) + private lateinit var rootCaCert: X509Certificate + private lateinit var intermediateCa: CertificateAndKeyPair + private val testNetworkMapConfig = NetworkMapConfig(10.seconds.toMillis(), 10.seconds.toMillis()) + @Before + fun init() { + val (rootCa, intermediateCa) = createDevIntermediateCaCertPath() + rootCaCert = rootCa.certificate + this.intermediateCa = intermediateCa + } + @Test fun `submit nodeInfo`() { // Create node info. @@ -65,7 +70,7 @@ class NodeInfoWebServiceTest { fun `get network map`() { val networkMap = NetworkMap(listOf(randomSHA256(), randomSHA256()), randomSHA256()) val serializedNetworkMap = networkMap.serialize() - val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, intermediateCaKeyPair.sign(serializedNetworkMap).withCert(intermediateCaCert.cert)) + val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, intermediateCa.keyPair.sign(serializedNetworkMap).withCert(intermediateCa.certificate)) val networkMapStorage: NetworkMapStorage = mock { on { getCurrentNetworkMap() }.thenReturn(signedNetworkMap) @@ -75,7 +80,7 @@ class NodeInfoWebServiceTest { it.start() val signedNetworkMapResponse = it.doGet("") verify(networkMapStorage, times(1)).getCurrentNetworkMap() - assertEquals(signedNetworkMapResponse.verified(rootCaCert.cert), networkMap) + assertEquals(signedNetworkMapResponse.verified(rootCaCert), networkMap) } } @@ -104,7 +109,7 @@ class NodeInfoWebServiceTest { fun `get network parameters`() { val netParams = testNetworkParameters(emptyList()) val serializedNetParams = netParams.serialize() - val signedNetParams = SignedData(serializedNetParams, intermediateCaKeyPair.sign(serializedNetParams)) + val signedNetParams = SignedData(serializedNetParams, intermediateCa.keyPair.sign(serializedNetParams)) val netParamsHash = serializedNetParams.hash val networkMapStorage: NetworkMapStorage = mock { @@ -116,7 +121,7 @@ class NodeInfoWebServiceTest { val netParamsResponse = it.doGet>("network-parameter/$netParamsHash") verify(networkMapStorage, times(1)).getSignedNetworkParameters(netParamsHash) assertThat(netParamsResponse.verified()).isEqualTo(netParams) - assertThat(netParamsResponse.sig.by).isEqualTo(intermediateCaKeyPair.public) + assertThat(netParamsResponse.sig.by).isEqualTo(intermediateCa.keyPair.public) assertThatExceptionOfType(FileNotFoundException::class.java).isThrownBy { it.doGet>("network-parameter/${randomSHA256()}") diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/RegistrationWebServiceTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/RegistrationWebServiceTest.kt index 0f5bdec26b..39a6d58630 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/RegistrationWebServiceTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/RegistrationWebServiceTest.kt @@ -4,46 +4,54 @@ 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.common.utils.toX509Certificate import com.r3.corda.networkmanage.doorman.signer.CsrHandler import com.r3.corda.networkmanage.doorman.webservice.RegistrationWebService import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.NetworkHostAndPort +import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair import net.corda.nodeapi.internal.crypto.CertificateType import net.corda.nodeapi.internal.crypto.X509CertificateFactory import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME +import net.corda.testing.internal.createDevIntermediateCaCertPath import org.apache.commons.io.IOUtils import org.assertj.core.api.Assertions.assertThat import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x509.GeneralName import org.bouncycastle.asn1.x509.GeneralSubtree import org.bouncycastle.asn1.x509.NameConstraints -import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.pkcs.PKCS10CertificationRequest import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest import org.junit.After +import org.junit.Before import org.junit.Test import java.io.IOException import java.net.HttpURLConnection import java.net.HttpURLConnection.* import java.net.URL +import java.nio.charset.StandardCharsets.UTF_8 import java.security.cert.CertPath import java.security.cert.X509Certificate import java.util.* import java.util.zip.ZipInputStream +import javax.security.auth.x500.X500Principal import javax.ws.rs.core.MediaType import kotlin.test.assertEquals class RegistrationWebServiceTest : TestBase() { - private val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Root CA", locality = "London", organisation = "R3 Ltd", country = "GB"), rootCAKey) - private val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, X500Name("CN=Corda Node Intermediate CA,L=London"), intermediateCAKey.public) + private lateinit var rootCaCert: X509Certificate + private lateinit var intermediateCa: CertificateAndKeyPair private lateinit var webServer: NetworkManagementWebServer + @Before + fun init() { + val (rootCa, intermediateCa) = createDevIntermediateCaCertPath() + rootCaCert = rootCa.certificate + this.intermediateCa = intermediateCa + } + private fun startSigningServer(csrHandler: CsrHandler) { webServer = NetworkManagementWebServer(NetworkHostAndPort("localhost", 0), RegistrationWebService(csrHandler)) webServer.start() @@ -65,7 +73,10 @@ class RegistrationWebServiceTest : TestBase() { startSigningServer(requestProcessor) val keyPair = Crypto.generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) - val request = X509Utilities.createCertificateSigningRequest(CordaX500Name(locality = "London", organisation = "Legal Name", country = "GB"), "my@mail.com", keyPair) + val request = X509Utilities.createCertificateSigningRequest( + CordaX500Name(locality = "London", organisation = "Legal Name", country = "GB").x500Principal, + "my@mail.com", + keyPair) // Post request to signing server via http. assertEquals(id, submitRequest(request)) @@ -79,6 +90,8 @@ class RegistrationWebServiceTest : TestBase() { val keyPair = Crypto.generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) val id = SecureHash.randomSHA256().toString() + val subject = CordaX500Name(locality = "London", organisation = "LegalName", country = "GB").x500Principal + // Mock Storage behaviour. val certificateStore = mutableMapOf() val requestProcessor = mock { @@ -88,10 +101,15 @@ class RegistrationWebServiceTest : TestBase() { } ?: CertificateResponse.NotReady } on { processApprovedRequests() }.then { - val request = X509Utilities.createCertificateSigningRequest(CordaX500Name(locality = "London", organisation = "LegalName", country = "GB"), "my@mail.com", keyPair) + val request = X509Utilities.createCertificateSigningRequest(subject, "my@mail.com", keyPair) certificateStore[id] = JcaPKCS10CertificationRequest(request).run { - val tlsCert = X509Utilities.createCertificate(CertificateType.TLS, intermediateCACert, intermediateCAKey, subject, publicKey).toX509Certificate() - buildCertPath(tlsCert, intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) + val tlsCert = X509Utilities.createCertificate( + CertificateType.TLS, + intermediateCa.certificate, + intermediateCa.keyPair, + X500Principal(subject.encoded), + publicKey) + buildCertPath(tlsCert, intermediateCa.certificate, rootCaCert) } null } @@ -104,22 +122,15 @@ class RegistrationWebServiceTest : TestBase() { val certificates = (pollForResponse(id) as PollResponse.Ready).certChain verify(requestProcessor, times(2)).getResponse(any()) - assertEquals(3, certificates.size) - certificates.first().run { - assertThat(subjectDN.name).contains("O=LegalName") - assertThat(subjectDN.name).contains("L=London") - } - - certificates.last().run { - assertThat(subjectDN.name).contains("CN=Corda Node Root CA") - assertThat(subjectDN.name).contains("L=London") - } + assertThat(certificates).hasSize(3) + assertThat(certificates[0].subjectX500Principal).isEqualTo(subject) + assertThat(certificates).endsWith(intermediateCa.certificate, rootCaCert) } @Test fun `retrieve certificate and create valid TLS certificate`() { - val keyPair = Crypto.generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) + val nodeCaKeyPair = Crypto.generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) val id = SecureHash.randomSHA256().toString() // Mock Storage behaviour. @@ -131,11 +142,22 @@ class RegistrationWebServiceTest : TestBase() { } ?: CertificateResponse.NotReady } on { processApprovedRequests() }.then { - val request = X509Utilities.createCertificateSigningRequest(CordaX500Name(locality = "London", organisation = "Legal Name", country = "GB"), "my@mail.com", keyPair) + val request = X509Utilities.createCertificateSigningRequest( + CordaX500Name(locality = "London", organisation = "Legal Name", country = "GB").x500Principal, + "my@mail.com", + nodeCaKeyPair) certificateStore[id] = JcaPKCS10CertificationRequest(request).run { - val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, X500Name("CN=LegalName, L=London")))), arrayOf()) - val clientCert = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, subject, publicKey, nameConstraints = nameConstraints).toX509Certificate() - buildCertPath(clientCert, intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) + val nameConstraints = NameConstraints( + arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, X500Name("CN=LegalName, L=London")))), + arrayOf()) + val clientCert = X509Utilities.createCertificate( + CertificateType.NODE_CA, + intermediateCa.certificate, + intermediateCa.keyPair, + X500Principal(subject.encoded), + publicKey, + nameConstraints = nameConstraints) + buildCertPath(clientCert, intermediateCa.certificate, rootCaCert) } true } @@ -149,11 +171,17 @@ class RegistrationWebServiceTest : TestBase() { verify(storage, times(2)).getResponse(any()) assertEquals(3, certificates.size) - val sslKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val sslCert = X509Utilities.createCertificate(CertificateType.TLS, X509CertificateHolder(certificates.first().encoded), keyPair, X500Name("CN=LegalName,L=London"), sslKey.public).toX509Certificate() + val sslKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) + val sslCert = X509Utilities.createCertificate( + CertificateType.TLS, + certificates[0], + nodeCaKeyPair, + // TODO Investigate why X500Principal("CN=LegalName, L=London") results in a name constraints violation + X500Principal(X500Name("CN=LegalName, L=London").encoded), + sslKeyPair.public) // TODO: This is temporary solution, remove all certificate re-shaping after identity refactoring is done. - X509Utilities.validateCertificateChain(certificates.last(), sslCert, *certificates.toTypedArray()) + X509Utilities.validateCertificateChain(rootCaCert, sslCert, *certificates.toTypedArray()) } @Test @@ -192,7 +220,7 @@ class RegistrationWebServiceTest : TestBase() { PollResponse.Ready(certificates) } HTTP_NO_CONTENT -> PollResponse.NotReady - HTTP_UNAUTHORIZED -> PollResponse.Unauthorised(IOUtils.toString(conn.errorStream)) + HTTP_UNAUTHORIZED -> PollResponse.Unauthorised(IOUtils.toString(conn.errorStream, UTF_8)) else -> throw IOException("Cannot connect to Certificate Signing Server, HTTP response code : ${conn.responseCode}") } } diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/signer/CsrHandlerTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/signer/CsrHandlerTest.kt index 21d3ed1375..42314f4b38 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/signer/CsrHandlerTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/signer/CsrHandlerTest.kt @@ -39,7 +39,10 @@ class JiraCsrHandlerTest { private lateinit var certificateResponse: CertificateResponse.Ready private val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - private val pkcS10CertificationRequest = X509Utilities.createCertificateSigningRequest(CordaX500Name(locality = "London", organisation = "LegalName", country = "GB"), "my@mail.com", keyPair) + private val pkcS10CertificationRequest = X509Utilities.createCertificateSigningRequest( + CordaX500Name(locality = "London", organisation = "LegalName", country = "GB").x500Principal, + "my@mail.com", + keyPair) @Before fun setup() {