mirror of
https://github.com/corda/corda.git
synced 2025-06-19 15:43:52 +00:00
Support signing and storing EdDSA key and certificate in java keystore. (#601)
This commit is contained in:
@ -8,6 +8,7 @@ import com.google.common.util.concurrent.SettableFuture
|
||||
import net.corda.core.*
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.PartyAndReference
|
||||
import net.corda.core.crypto.KeyStoreUtilities
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.flows.FlowInitiator
|
||||
@ -71,7 +72,6 @@ import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.TimeUnit.SECONDS
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.reflect.KClass
|
||||
import net.corda.core.crypto.generateKeyPair as cryptoGenerateKeyPair
|
||||
|
||||
@ -351,7 +351,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
private fun hasSSLCertificates(): Boolean {
|
||||
val keyStore = try {
|
||||
// This will throw IOException if key file not found or KeyStoreException if keystore password is incorrect.
|
||||
X509Utilities.loadKeyStore(configuration.keyStoreFile, configuration.keyStorePassword)
|
||||
KeyStoreUtilities.loadKeyStore(configuration.keyStoreFile, configuration.keyStorePassword)
|
||||
} catch (e: IOException) {
|
||||
null
|
||||
} catch (e: KeyStoreException) {
|
||||
|
@ -9,6 +9,7 @@ import com.typesafe.config.ConfigParseOptions
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
import net.corda.core.copyTo
|
||||
import net.corda.core.createDirectories
|
||||
import net.corda.core.crypto.KeyStoreUtilities
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.div
|
||||
import net.corda.core.exists
|
||||
@ -52,9 +53,7 @@ fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: X500Name) {
|
||||
javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordatruststore.jks").copyTo(trustStoreFile)
|
||||
}
|
||||
if (!keyStoreFile.exists()) {
|
||||
val caKeyStore = X509Utilities.loadKeyStore(
|
||||
javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordadevcakeys.jks"),
|
||||
"cordacadevpass")
|
||||
val caKeyStore = KeyStoreUtilities.loadKeyStore(javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordadevcakeys.jks"), "cordacadevpass")
|
||||
X509Utilities.createKeystoreForSSL(keyStoreFile, keyStorePassword, keyStorePassword, caKeyStore, "cordacadevkeypass", myLegalName)
|
||||
}
|
||||
}
|
||||
|
@ -246,8 +246,10 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
|
||||
@Throws(IOException::class, KeyStoreException::class)
|
||||
private fun createArtemisSecurityManager(): ActiveMQJAASSecurityManager {
|
||||
val ourCertificate = X509Utilities
|
||||
.loadCertificateFromKeyStore(config.keyStoreFile, config.keyStorePassword, CORDA_CLIENT_CA)
|
||||
val keyStore = KeyStoreUtilities.loadKeyStore(config.keyStoreFile, config.keyStorePassword)
|
||||
val trustStore = KeyStoreUtilities.loadKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
val ourCertificate = keyStore.getX509Certificate(CORDA_CLIENT_CA)
|
||||
|
||||
val ourSubjectDN = X500Name(ourCertificate.subjectDN.name)
|
||||
// This is a sanity check and should not fail unless things have been misconfigured
|
||||
require(ourSubjectDN == config.myLegalName) {
|
||||
@ -258,8 +260,6 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
NODE_ROLE to CertificateChainCheckPolicy.LeafMustMatch,
|
||||
VERIFIER_ROLE to CertificateChainCheckPolicy.RootMustMatch
|
||||
)
|
||||
val keyStore = X509Utilities.loadKeyStore(config.keyStoreFile, config.keyStorePassword)
|
||||
val trustStore = X509Utilities.loadKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
val certChecks = defaultCertPolicies.mapValues { (role, defaultPolicy) ->
|
||||
val configPolicy = config.certificateChainCheckPolicies.noneOrSingle { it.role == role }?.certificateChainCheckPolicy
|
||||
(configPolicy ?: defaultPolicy).createCheck(keyStore, trustStore)
|
||||
|
@ -1,11 +1,9 @@
|
||||
package net.corda.node.utilities.registration
|
||||
|
||||
import net.corda.core.*
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_CLIENT_CA
|
||||
import net.corda.core.crypto.X509Utilities.CORDA_ROOT_CA
|
||||
import net.corda.core.crypto.X509Utilities.addOrReplaceCertificate
|
||||
import net.corda.core.crypto.X509Utilities.addOrReplaceKey
|
||||
import net.corda.node.services.config.NodeConfiguration
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMWriter
|
||||
import org.bouncycastle.util.io.pem.PemObject
|
||||
@ -33,7 +31,7 @@ class NetworkRegistrationHelper(val config: NodeConfiguration, val certService:
|
||||
|
||||
fun buildKeystore() {
|
||||
config.certificatesDirectory.createDirectories()
|
||||
val caKeyStore = X509Utilities.loadOrCreateKeyStore(config.keyStoreFile, keystorePassword)
|
||||
val caKeyStore = KeyStoreUtilities.loadOrCreateKeyStore(config.keyStoreFile, keystorePassword)
|
||||
if (!caKeyStore.containsAlias(CORDA_CLIENT_CA)) {
|
||||
// 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.
|
||||
@ -41,9 +39,9 @@ class NetworkRegistrationHelper(val config: NodeConfiguration, val certService:
|
||||
val selfSignCert = X509Utilities.createSelfSignedCACert(config.myLegalName)
|
||||
// Save to the key store.
|
||||
caKeyStore.addOrReplaceKey(SELF_SIGNED_PRIVATE_KEY, selfSignCert.keyPair.private, privateKeyPassword.toCharArray(), arrayOf(selfSignCert.certificate))
|
||||
X509Utilities.saveKeyStore(caKeyStore, config.keyStoreFile, keystorePassword)
|
||||
caKeyStore.save(config.keyStoreFile, keystorePassword)
|
||||
}
|
||||
val keyPair = X509Utilities.loadKeyPairFromKeyStore(config.keyStoreFile, keystorePassword, privateKeyPassword, SELF_SIGNED_PRIVATE_KEY)
|
||||
val keyPair = caKeyStore.getKeyPair(SELF_SIGNED_PRIVATE_KEY, privateKeyPassword)
|
||||
val requestId = submitOrResumeCertificateSigningRequest(keyPair)
|
||||
|
||||
val certificates = try {
|
||||
@ -60,12 +58,12 @@ class NetworkRegistrationHelper(val config: NodeConfiguration, val certService:
|
||||
// Save private key and certificate chain to the key store.
|
||||
caKeyStore.addOrReplaceKey(CORDA_CLIENT_CA, keyPair.private, privateKeyPassword.toCharArray(), certificates)
|
||||
caKeyStore.deleteEntry(SELF_SIGNED_PRIVATE_KEY)
|
||||
X509Utilities.saveKeyStore(caKeyStore, config.keyStoreFile, keystorePassword)
|
||||
caKeyStore.save(config.keyStoreFile, keystorePassword)
|
||||
// Save root certificates to trust store.
|
||||
val trustStore = X509Utilities.loadOrCreateKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
val trustStore = KeyStoreUtilities.loadOrCreateKeyStore(config.trustStoreFile, config.trustStorePassword)
|
||||
// Assumes certificate chain always starts with client certificate and end with root certificate.
|
||||
trustStore.addOrReplaceCertificate(CORDA_ROOT_CA, certificates.last())
|
||||
X509Utilities.saveKeyStore(trustStore, config.trustStoreFile, config.trustStorePassword)
|
||||
trustStore.save(config.trustStoreFile, config.trustStorePassword)
|
||||
println("Certificate and private key stored in ${config.keyStoreFile}.")
|
||||
// All done, clean up temp files.
|
||||
requestIdStore.deleteIfExists()
|
||||
|
@ -3,6 +3,7 @@ package net.corda.node.utilities.registration
|
||||
import com.nhaarman.mockito_kotlin.any
|
||||
import com.nhaarman.mockito_kotlin.eq
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import net.corda.core.crypto.KeyStoreUtilities
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.exists
|
||||
@ -51,7 +52,7 @@ class NetworkRegistrationHelperTest {
|
||||
assertTrue(config.keyStoreFile.exists())
|
||||
assertTrue(config.trustStoreFile.exists())
|
||||
|
||||
X509Utilities.loadKeyStore(config.keyStoreFile, config.keyStorePassword).run {
|
||||
KeyStoreUtilities.loadKeyStore(config.keyStoreFile, config.keyStorePassword).run {
|
||||
assertFalse(containsAlias(X509Utilities.CORDA_CLIENT_CA_PRIVATE_KEY))
|
||||
val certificateChain = getCertificateChain(X509Utilities.CORDA_CLIENT_CA)
|
||||
assertEquals(3, certificateChain.size)
|
||||
@ -62,7 +63,7 @@ class NetworkRegistrationHelperTest {
|
||||
assertFalse(containsAlias(X509Utilities.CORDA_ROOT_CA_PRIVATE_KEY))
|
||||
}
|
||||
|
||||
X509Utilities.loadKeyStore(config.trustStoreFile, config.trustStorePassword).run {
|
||||
KeyStoreUtilities.loadKeyStore(config.trustStoreFile, config.trustStorePassword).run {
|
||||
assertFalse(containsAlias(X509Utilities.CORDA_CLIENT_CA_PRIVATE_KEY))
|
||||
assertFalse(containsAlias(X509Utilities.CORDA_CLIENT_CA))
|
||||
assertFalse(containsAlias(X509Utilities.CORDA_INTERMEDIATE_CA))
|
||||
|
Reference in New Issue
Block a user