mirror of
https://github.com/corda/corda.git
synced 2025-06-12 20:28:18 +00:00
CORDA-3979: Support for multiple trust roots (#6772)
This commit is contained in:
@ -105,6 +105,17 @@ fun createDevNodeCa(intermediateCa: CertificateAndKeyPair,
|
||||
return CertificateAndKeyPair(cert, nodeKeyPair)
|
||||
}
|
||||
|
||||
fun createDevNodeIdentity(nodeCa: CertificateAndKeyPair, legalName: CordaX500Name): CertificateAndKeyPair {
|
||||
val keyPair = generateKeyPair()
|
||||
val cert = X509Utilities.createCertificate(
|
||||
CertificateType.LEGAL_IDENTITY,
|
||||
nodeCa.certificate,
|
||||
nodeCa.keyPair,
|
||||
legalName.x500Principal,
|
||||
keyPair.public)
|
||||
return CertificateAndKeyPair(cert, keyPair)
|
||||
}
|
||||
|
||||
val DEV_INTERMEDIATE_CA: CertificateAndKeyPair get() = DevCaHelper.loadDevCa(X509Utilities.CORDA_INTERMEDIATE_CA)
|
||||
val DEV_ROOT_CA: CertificateAndKeyPair get() = DevCaHelper.loadDevCa(X509Utilities.CORDA_ROOT_CA)
|
||||
const val DEV_CA_PRIVATE_KEY_PASS: String = "cordacadevkeypass"
|
||||
|
@ -124,17 +124,17 @@ object X509Utilities {
|
||||
return createCertificate(CertificateType.ROOT_CA, subject, keyPair, subject, keyPair.public, window)
|
||||
}
|
||||
|
||||
fun validateCertificateChain(trustedRoot: X509Certificate, vararg certificates: X509Certificate) {
|
||||
validateCertificateChain(trustedRoot, certificates.asList())
|
||||
fun validateCertificateChain(trustedRoots: Set<X509Certificate>, vararg certificates: X509Certificate) {
|
||||
validateCertificateChain(trustedRoots, certificates.asList())
|
||||
}
|
||||
|
||||
fun validateCertificateChain(trustedRoot: X509Certificate, certificates: List<X509Certificate>) {
|
||||
fun validateCertificateChain(trustedRoots: Set<X509Certificate>, certificates: List<X509Certificate>) {
|
||||
require(certificates.isNotEmpty()) { "Certificate path must contain at least one certificate" }
|
||||
validateCertPath(trustedRoot, buildCertPath(certificates))
|
||||
validateCertPath(trustedRoots, buildCertPath(certificates))
|
||||
}
|
||||
|
||||
fun validateCertPath(trustedRoot: X509Certificate, certPath: CertPath) {
|
||||
certPath.validate(TrustAnchor(trustedRoot, null))
|
||||
fun validateCertPath(trustedRoots: Set<X509Certificate>, certPath: CertPath) {
|
||||
certPath.validate(trustedRoots.map { TrustAnchor(it, null) }.toSet())
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -399,7 +399,7 @@ constructor(private val initSerEnv: Boolean,
|
||||
|
||||
when (netParamsFilesGrouped.size) {
|
||||
0 -> return null
|
||||
1 -> return netParamsFilesGrouped.keys.first().deserialize().verifiedNetworkParametersCert(DEV_ROOT_CA.certificate)
|
||||
1 -> return netParamsFilesGrouped.keys.first().deserialize().verifiedNetworkParametersCert(setOf(DEV_ROOT_CA.certificate))
|
||||
}
|
||||
|
||||
val msg = StringBuilder("Differing sets of network parameters were found. Make sure all the nodes have the same " +
|
||||
@ -409,7 +409,7 @@ constructor(private val initSerEnv: Boolean,
|
||||
netParamsFiles.map { it.parent.fileName }.joinTo(msg, ", ")
|
||||
msg.append(":\n")
|
||||
val netParamsString = try {
|
||||
bytes.deserialize().verifiedNetworkParametersCert(DEV_ROOT_CA.certificate).toString()
|
||||
bytes.deserialize().verifiedNetworkParametersCert(setOf(DEV_ROOT_CA.certificate)).toString()
|
||||
} catch (e: Exception) {
|
||||
"Invalid network parameters file: $e"
|
||||
}
|
||||
|
@ -55,25 +55,26 @@ data class ParametersUpdate(
|
||||
)
|
||||
|
||||
/** Verify that a certificate path and its [CertRole] is correct. */
|
||||
fun <T : Any> SignedDataWithCert<T>.verifiedCertWithRole(rootCert: X509Certificate, vararg certRoles: CertRole): T {
|
||||
fun <T : Any> SignedDataWithCert<T>.verifiedCertWithRole(rootCerts: Set<X509Certificate>, vararg certRoles: CertRole): T {
|
||||
require(CertRole.extract(sig.by) in certRoles) { "Incorrect cert role: ${CertRole.extract(sig.by)}" }
|
||||
val path = if (sig.parentCertsChain.isEmpty()) {
|
||||
listOf(sig.by, rootCert)
|
||||
val rootCandidate = rootCerts.firstOrNull { it.subjectX500Principal == sig.by.issuerX500Principal }
|
||||
listOf(sig.by, rootCandidate ?: rootCerts.first())
|
||||
} else {
|
||||
sig.fullCertChain
|
||||
}
|
||||
X509Utilities.validateCertificateChain(rootCert, path)
|
||||
X509Utilities.validateCertificateChain(rootCerts, path)
|
||||
return verified()
|
||||
}
|
||||
|
||||
/** Verify that a Network Map certificate path and its [CertRole] is correct. */
|
||||
fun <T : Any> SignedDataWithCert<T>.verifiedNetworkMapCert(rootCert: X509Certificate): T {
|
||||
return verifiedCertWithRole(rootCert, CertRole.NETWORK_MAP)
|
||||
fun <T : Any> SignedDataWithCert<T>.verifiedNetworkMapCert(rootCerts: Set<X509Certificate>): T {
|
||||
return verifiedCertWithRole(rootCerts, CertRole.NETWORK_MAP)
|
||||
}
|
||||
|
||||
/** Verify that a Network Parameters certificate path and its [CertRole] is correct. */
|
||||
fun <T : Any> SignedDataWithCert<T>.verifiedNetworkParametersCert(rootCert: X509Certificate): T {
|
||||
fun <T : Any> SignedDataWithCert<T>.verifiedNetworkParametersCert(rootCerts: Set<X509Certificate>): T {
|
||||
// for backwards compatibility we allow network parameters to be signed with
|
||||
// the networkmap cert, but going forwards we also accept the specific netparams cert as well
|
||||
return verifiedCertWithRole(rootCert, CertRole.NETWORK_PARAMETERS, CertRole.NETWORK_MAP)
|
||||
return verifiedCertWithRole(rootCerts, CertRole.NETWORK_PARAMETERS, CertRole.NETWORK_MAP)
|
||||
}
|
@ -33,7 +33,7 @@ class DevCertificatesTest {
|
||||
val certPath = X509Utilities.buildCertPath(*oldX509Certificates)
|
||||
|
||||
// when
|
||||
certPath.validate(newTrustAnchor)
|
||||
certPath.validate(setOf(newTrustAnchor))
|
||||
|
||||
// then no exception is thrown
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ class TlsDiffAlgorithmsTest(private val serverAlgo: String, private val clientAl
|
||||
val peerChain = peerChainTry.getOrThrow()
|
||||
val peerX500Principal = peerChain[0].subjectX500Principal
|
||||
assertEquals(serverCa.certificate.subjectX500Principal, peerX500Principal)
|
||||
X509Utilities.validateCertificateChain(rootCa, peerChain)
|
||||
X509Utilities.validateCertificateChain(setOf(rootCa), peerChain)
|
||||
with(DataOutputStream(clientSocket.outputStream)) {
|
||||
writeUTF(testPhrase)
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ class TlsDiffProtocolsTest(private val serverAlgo: String, private val clientAlg
|
||||
val peerChain = peerChainTry.getOrThrow()
|
||||
val peerX500Principal = peerChain[0].subjectX500Principal
|
||||
assertEquals(serverCa.certificate.subjectX500Principal, peerX500Principal)
|
||||
X509Utilities.validateCertificateChain(rootCa, peerChain)
|
||||
X509Utilities.validateCertificateChain(setOf(rootCa), peerChain)
|
||||
with(DataOutputStream(clientSocket.outputStream)) {
|
||||
writeUTF(testPhrase)
|
||||
}
|
||||
|
Reference in New Issue
Block a user