CORDA-1986 Ensure key alias format is supported by the major HSM vendors ()

This commit is contained in:
Konstantinos Chalkias 2018-09-17 10:19:34 +01:00 committed by GitHub
parent 0b2e0b04ec
commit 137f7664c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 8 deletions
node-api/src/main/kotlin/net/corda/nodeapi/internal/crypto
node/src/main/kotlin/net/corda/node
internal
utilities/registration

View File

@ -41,15 +41,21 @@ object X509Utilities {
val DEFAULT_IDENTITY_SIGNATURE_SCHEME = Crypto.EDDSA_ED25519_SHA512 val DEFAULT_IDENTITY_SIGNATURE_SCHEME = Crypto.EDDSA_ED25519_SHA512
val DEFAULT_TLS_SIGNATURE_SCHEME = Crypto.ECDSA_SECP256R1_SHA256 val DEFAULT_TLS_SIGNATURE_SCHEME = Crypto.ECDSA_SECP256R1_SHA256
// TODO This class is more of a general purpose utility class and as such these constants belong elsewhere // TODO This class is more of a general purpose utility class and as such these constants belong elsewhere.
// Aliases for private keys and certificates. // Aliases for private keys and certificates.
const val CORDA_ROOT_CA = "cordarootca" const val CORDA_ROOT_CA = "cordarootca"
const val CORDA_INTERMEDIATE_CA = "cordaintermediateca" const val CORDA_INTERMEDIATE_CA = "cordaintermediateca"
const val CORDA_CLIENT_TLS = "cordaclienttls" const val CORDA_CLIENT_TLS = "cordaclienttls"
const val CORDA_CLIENT_CA = "cordaclientca" const val CORDA_CLIENT_CA = "cordaclientca"
// TODO These don't need to be prefixes, but can be the full aliases. // TODO These don't need to be prefixes, but can be the full aliases. However, because they are used as key aliases
// we should ensure that:
// a) they always contain valid characters, preferably [A-Za-z0-9] in order to be supported by the majority of
// crypto service implementations (i.e., HSMs).
// b) they are at most 127 chars in length (i.e., as of 2018, Azure Key Vault does not support bigger aliases).
const val NODE_IDENTITY_ALIAS_PREFIX = "identity" const val NODE_IDENTITY_ALIAS_PREFIX = "identity"
// TODO Hyphen (-) seems to be supported by the major HSM vendors, but we should consider remove it in the
// future and stick to [A-Za-z0-9].
const val DISTRIBUTED_NOTARY_ALIAS_PREFIX = "distributed-notary" const val DISTRIBUTED_NOTARY_ALIAS_PREFIX = "distributed-notary"
val DEFAULT_VALIDITY_WINDOW = Pair(0.millis, 3650.days) val DEFAULT_VALIDITY_WINDOW = Pair(0.millis, 3650.days)

View File

@ -852,11 +852,11 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
val privateKeyAlias = "$id-private-key" val privateKeyAlias = "$id-private-key"
if (privateKeyAlias !in keyStore) { if (privateKeyAlias !in keyStore) {
singleName ?: throw IllegalArgumentException( // We shouldn't have a distributed notary at this stage, so singleName should NOT be null.
"Unable to find in the key store the identity of the distributed notary the node is part of") requireNotNull(singleName) {
"Unable to find in the key store the identity of the distributed notary the node is part of"
}
log.info("$privateKeyAlias not found in key store, generating fresh key!") log.info("$privateKeyAlias not found in key store, generating fresh key!")
// TODO This check shouldn't be needed
check(singleName == configuration.myLegalName)
keyStore.storeLegalIdentity(privateKeyAlias, generateKeyPair()) keyStore.storeLegalIdentity(privateKeyAlias, generateKeyPair())
} }
@ -865,7 +865,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
// 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.
val compositeKeyAlias = "$id-composite-key" val compositeKeyAlias = "$id-composite-key"
val certificates = if (compositeKeyAlias in keyStore) { val certificates = if (compositeKeyAlias in keyStore) {
// Use composite key instead if it exists // Use composite key instead if it exists.
val certificate = keyStore[compositeKeyAlias] val certificate = keyStore[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 +

View File

@ -46,7 +46,7 @@ open class NetworkRegistrationHelper(private val certificatesDirectory: Path,
private val nextIdleDuration: (Duration?) -> Duration? = FixedPeriodLimitedRetrialStrategy(10, Duration.ofMinutes(1))) { private val nextIdleDuration: (Duration?) -> Duration? = FixedPeriodLimitedRetrialStrategy(10, Duration.ofMinutes(1))) {
companion object { companion object {
const val SELF_SIGNED_PRIVATE_KEY = "Self Signed Private Key" const val SELF_SIGNED_PRIVATE_KEY = "SelfSignedPrivateKey"
val logger = contextLogger() val logger = contextLogger()
} }
@ -154,6 +154,8 @@ open class NetworkRegistrationHelper(private val certificatesDirectory: Path,
// Save private key and certificate chain to the key store. // Save private key and certificate chain to the key store.
with(nodeKeystore.value) { with(nodeKeystore.value) {
setPrivateKey(keyAlias, keyPair.private, certificates, keyPassword = keyPassword) setPrivateKey(keyAlias, keyPair.private, certificates, keyPassword = keyPassword)
// The key was temporarily stored as SELF_SIGNED_PRIVATE_KEY, but now that it's signed by the Doorman we
// can delete this old record.
internal.deleteEntry(SELF_SIGNED_PRIVATE_KEY) internal.deleteEntry(SELF_SIGNED_PRIVATE_KEY)
save() save()
} }
@ -164,6 +166,7 @@ open class NetworkRegistrationHelper(private val certificatesDirectory: Path,
// Create or load self signed keypair from the key store. // Create or load self signed keypair from the key store.
// We use the self sign certificate to store the key temporarily in the keystore while waiting for the request approval. // We use the self sign certificate to store the key temporarily in the keystore while waiting for the request approval.
if (alias !in this) { if (alias !in this) {
// NODE_CA should be TLS compatible due to the cert hierarchy structure.
val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val selfSignCert = X509Utilities.createSelfSignedCACertificate(myLegalName.x500Principal, keyPair) val selfSignCert = X509Utilities.createSelfSignedCACertificate(myLegalName.x500Principal, keyPair)
// Save to the key store. // Save to the key store.