mirror of
https://github.com/corda/corda.git
synced 2025-02-22 18:12:53 +00:00
[CORDA-2218] CryptoService signingCertificateStore alias match (#4227)
This commit is contained in:
parent
bbd5369e04
commit
e14ade58e3
@ -844,11 +844,14 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
private fun obtainIdentity(): Pair<PartyAndCertificate, KeyPair> {
|
private fun obtainIdentity(): Pair<PartyAndCertificate, KeyPair> {
|
||||||
val legalIdentityPrivateKeyAlias = "$NODE_IDENTITY_ALIAS_PREFIX-private-key"
|
val legalIdentityPrivateKeyAlias = "$NODE_IDENTITY_ALIAS_PREFIX-private-key"
|
||||||
|
|
||||||
if (!cryptoService.containsKey(legalIdentityPrivateKeyAlias)) {
|
var signingCertificateStore = configuration.signingCertificateStore.get()
|
||||||
|
if (!cryptoService.containsKey(legalIdentityPrivateKeyAlias) && !signingCertificateStore.contains(legalIdentityPrivateKeyAlias)) {
|
||||||
log.info("$legalIdentityPrivateKeyAlias not found in key store, generating fresh key!")
|
log.info("$legalIdentityPrivateKeyAlias not found in key store, generating fresh key!")
|
||||||
storeLegalIdentity(legalIdentityPrivateKeyAlias)
|
createAndStoreLegalIdentity(legalIdentityPrivateKeyAlias)
|
||||||
|
signingCertificateStore = configuration.signingCertificateStore.get() // We need to resync after [createAndStoreLegalIdentity].
|
||||||
|
} else {
|
||||||
|
checkAliasMismatch(legalIdentityPrivateKeyAlias, signingCertificateStore)
|
||||||
}
|
}
|
||||||
val signingCertificateStore = configuration.signingCertificateStore.get()
|
|
||||||
val x509Cert = signingCertificateStore.query { getCertificate(legalIdentityPrivateKeyAlias) }
|
val x509Cert = signingCertificateStore.query { getCertificate(legalIdentityPrivateKeyAlias) }
|
||||||
|
|
||||||
// TODO: Use configuration to indicate composite key should be used instead of public key for the identity.
|
// TODO: Use configuration to indicate composite key should be used instead of public key for the identity.
|
||||||
@ -866,22 +869,36 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
return getPartyAndCertificatePlusAliasKeyPair(certificates, legalIdentityPrivateKeyAlias)
|
return getPartyAndCertificatePlusAliasKeyPair(certificates, legalIdentityPrivateKeyAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if a key alias exists only in one of the cryptoService and certSigningStore.
|
||||||
|
private fun checkAliasMismatch(alias: String, certificateStore: CertificateStore) {
|
||||||
|
if (cryptoService.containsKey(alias) != certificateStore.contains(alias)) {
|
||||||
|
val keyExistsIn: String = if (cryptoService.containsKey(alias)) "CryptoService" else "signingCertificateStore"
|
||||||
|
throw IllegalStateException("CryptoService and signingCertificateStore are not aligned, the entry for key-alias: $alias is only found in $keyExistsIn")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Loads pre-generated notary service cluster identity. */
|
/** Loads pre-generated notary service cluster identity. */
|
||||||
private fun loadNotaryClusterIdentity(serviceLegalName: CordaX500Name): Pair<PartyAndCertificate, KeyPair> {
|
private fun loadNotaryClusterIdentity(serviceLegalName: CordaX500Name): Pair<PartyAndCertificate, KeyPair> {
|
||||||
val privateKeyAlias = "$DISTRIBUTED_NOTARY_ALIAS_PREFIX-private-key"
|
val privateKeyAlias = "$DISTRIBUTED_NOTARY_ALIAS_PREFIX-private-key"
|
||||||
val compositeKeyAlias = "$DISTRIBUTED_NOTARY_ALIAS_PREFIX-composite-key"
|
val compositeKeyAlias = "$DISTRIBUTED_NOTARY_ALIAS_PREFIX-composite-key"
|
||||||
|
|
||||||
val signingCertificateStore = configuration.signingCertificateStore.get()
|
val signingCertificateStore = configuration.signingCertificateStore.get()
|
||||||
|
val privateKeyAliasCertChain = try {
|
||||||
|
signingCertificateStore.query { getCertificateChain(privateKeyAlias) }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw IllegalStateException("Certificate-chain for $privateKeyAlias cannot be found", e)
|
||||||
|
}
|
||||||
// A composite key is only required for BFT notaries.
|
// A composite key is only required for BFT notaries.
|
||||||
val certificates = if (cryptoService.containsKey(compositeKeyAlias)) {
|
val certificates = if (cryptoService.containsKey(compositeKeyAlias) && signingCertificateStore.contains(compositeKeyAlias)) {
|
||||||
val certificate = signingCertificateStore[compositeKeyAlias]
|
val certificate = signingCertificateStore[compositeKeyAlias]
|
||||||
// We have to create the certificate chain for the composite key manually, this is because we don't have a keystore
|
// We have to create the certificate chain for the composite key manually, this is because we don't have a keystore
|
||||||
// provider that understand compositeKey-privateKey combo. The cert chain is created using the composite key certificate +
|
// provider that understand compositeKey-privateKey combo. The cert chain is created using the composite key certificate +
|
||||||
// the tail of the private key certificates, as they are both signed by the same certificate chain.
|
// the tail of the private key certificates, as they are both signed by the same certificate chain.
|
||||||
listOf(certificate) + signingCertificateStore.query { getCertificateChain(privateKeyAlias) }.drop(1)
|
listOf(certificate) + privateKeyAliasCertChain.drop(1)
|
||||||
} else {
|
} else {
|
||||||
// We assume the notary is CFT, and each cluster member shares the same notary key pair.
|
checkAliasMismatch(compositeKeyAlias, signingCertificateStore)
|
||||||
signingCertificateStore.query { getCertificateChain(privateKeyAlias) }
|
// If [compositeKeyAlias] does not exist, we assume the notary is CFT, and each cluster member shares the same notary key pair.
|
||||||
|
privateKeyAliasCertChain
|
||||||
}
|
}
|
||||||
|
|
||||||
val subject = CordaX500Name.build(certificates.first().subjectX500Principal)
|
val subject = CordaX500Name.build(certificates.first().subjectX500Principal)
|
||||||
@ -899,12 +916,12 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
|||||||
return Pair(PartyAndCertificate(certPath), keyPair)
|
return Pair(PartyAndCertificate(certPath), keyPair)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun storeLegalIdentity(alias: String): PartyAndCertificate {
|
private fun createAndStoreLegalIdentity(alias: String): PartyAndCertificate {
|
||||||
val legalIdentityPublicKey = generateKeyPair(alias)
|
val legalIdentityPublicKey = generateKeyPair(alias)
|
||||||
val signingCertificateStore = configuration.signingCertificateStore.get()
|
val signingCertificateStore = configuration.signingCertificateStore.get()
|
||||||
|
|
||||||
val nodeCaCertPath = signingCertificateStore.value.getCertificateChain(X509Utilities.CORDA_CLIENT_CA)
|
val nodeCaCertPath = signingCertificateStore.value.getCertificateChain(X509Utilities.CORDA_CLIENT_CA)
|
||||||
val nodeCaCert = nodeCaCertPath[0] // This should be the same with signingCertificateStore[alias]
|
val nodeCaCert = nodeCaCertPath[0] // This should be the same with signingCertificateStore[alias].
|
||||||
|
|
||||||
val identityCert = X509Utilities.createCertificate(
|
val identityCert = X509Utilities.createCertificate(
|
||||||
CertificateType.LEGAL_IDENTITY,
|
CertificateType.LEGAL_IDENTITY,
|
||||||
|
@ -233,6 +233,9 @@ data class NodeConfigurationImpl(
|
|||||||
if (cryptoServiceName == null && cryptoServiceConf != null) {
|
if (cryptoServiceName == null && cryptoServiceConf != null) {
|
||||||
errors += "'cryptoServiceName' is mandatory when 'cryptoServiceConf' is specified"
|
errors += "'cryptoServiceName' is mandatory when 'cryptoServiceConf' is specified"
|
||||||
}
|
}
|
||||||
|
if (notary != null && !(cryptoServiceName == null || cryptoServiceName == SupportedCryptoServices.BC_SIMPLE)) {
|
||||||
|
errors += "Notary node with a non supported 'cryptoServiceName' has been detected"
|
||||||
|
}
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user