[CORDA-2218] CryptoService signingCertificateStore alias match (#4227)

This commit is contained in:
Konstantinos Chalkias 2018-11-20 13:52:10 +00:00 committed by GitHub
parent bbd5369e04
commit e14ade58e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 9 deletions

View File

@ -844,11 +844,14 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
private fun obtainIdentity(): Pair<PartyAndCertificate, KeyPair> {
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!")
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) }
// 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)
}
// 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. */
private fun loadNotaryClusterIdentity(serviceLegalName: CordaX500Name): Pair<PartyAndCertificate, KeyPair> {
val privateKeyAlias = "$DISTRIBUTED_NOTARY_ALIAS_PREFIX-private-key"
val compositeKeyAlias = "$DISTRIBUTED_NOTARY_ALIAS_PREFIX-composite-key"
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.
val certificates = if (cryptoService.containsKey(compositeKeyAlias)) {
val certificates = if (cryptoService.containsKey(compositeKeyAlias) && signingCertificateStore.contains(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
// 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.
listOf(certificate) + signingCertificateStore.query { getCertificateChain(privateKeyAlias) }.drop(1)
listOf(certificate) + privateKeyAliasCertChain.drop(1)
} else {
// We assume the notary is CFT, and each cluster member shares the same notary key pair.
signingCertificateStore.query { getCertificateChain(privateKeyAlias) }
checkAliasMismatch(compositeKeyAlias, signingCertificateStore)
// 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)
@ -899,12 +916,12 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
return Pair(PartyAndCertificate(certPath), keyPair)
}
private fun storeLegalIdentity(alias: String): PartyAndCertificate {
private fun createAndStoreLegalIdentity(alias: String): PartyAndCertificate {
val legalIdentityPublicKey = generateKeyPair(alias)
val signingCertificateStore = configuration.signingCertificateStore.get()
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(
CertificateType.LEGAL_IDENTITY,

View File

@ -233,6 +233,9 @@ data class NodeConfigurationImpl(
if (cryptoServiceName == null && cryptoServiceConf != null) {
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
}