mirror of
https://github.com/corda/corda.git
synced 2025-04-08 11:54:44 +00:00
Switching to reading the root certificate from the truststore (#449)
* Switching to reading the root certificate from the truststore * Addressing review comments
This commit is contained in:
parent
b092b6b547
commit
3baa15960f
@ -28,7 +28,9 @@ Allowed parameters are:
|
||||
:device: HSM connection string. It is of the following format 3001@127.0.0.1, where 3001 is the port number.
|
||||
Default value: "3001@127.0.0.1"
|
||||
|
||||
:rootKeyGroup: HSM key group for the root certificate key. This parameter is vendor specific (see Utimaco docs).
|
||||
:rootKeyStoreFile: Location of the key store (trust store) containing the root certificate.
|
||||
|
||||
:rootKeyStorePassword: Password for the key store (trust store) containing the root certificate.
|
||||
|
||||
:networkMapKeyGroup: HSM key group for the network map certificate key. This parameter is vendor specific (see Utimaco docs).
|
||||
|
||||
@ -38,12 +40,8 @@ Allowed parameters are:
|
||||
|
||||
:rootPrivateKeyPassword: Private key password for the root certificate.
|
||||
|
||||
:rootCertificateName: Root certificate name. Default value: "cordarootca".
|
||||
|
||||
:csrPrivateKeyPassword: Private key password for the intermediate certificate used to sign certficate signing requests.
|
||||
|
||||
:csrCertificateName: Certificate signing requests intermediate certificate name. Default value: "cordaintermediateca".
|
||||
|
||||
:csrCertCrlDistPoint: Certificate revocation list location for the node CA certificate.
|
||||
|
||||
:csrCertCrlIssuer: Certificate revocation list issuer. The expected value is of the X500 name format - e.g. "L=London, C=GB, OU=Org Unit, CN=Service Name".
|
||||
@ -53,8 +51,6 @@ Allowed parameters are:
|
||||
|
||||
:dataSourceProperties: Data source properties. It should describe (or point to) the Doorman database.
|
||||
|
||||
:networkMapCertificateName: Network map intermediate certificate name. Default value: "cordaintermediateca_nm"
|
||||
|
||||
:networkMapPrivateKeyPassword: Private key password for the intermediate certificate used to sign the network map.
|
||||
|
||||
:validDays: Number of days issued signatures are valid for.
|
||||
|
@ -2,11 +2,9 @@ basedir = "."
|
||||
device = "3001@192.168.0.1"
|
||||
keySpecifier = -1
|
||||
authMode = PASSWORD
|
||||
rootCertificateName = "corda_root_ca"
|
||||
csrCertificateName = "intermediate_ca"
|
||||
rootKeyStoreFile = "dummyfile.jks"
|
||||
rootKeyStorePassword = "trustpass"
|
||||
csrCertCrlDistPoint = "http://test.com/revoked.crl"
|
||||
networkMapCertificateName = "intermediate_ca"
|
||||
rootKeyGroup = "DEV.CORDACONNECT.ROOT"
|
||||
doormanKeyGroup = "DEV.CORDACONNECT.OPS.CERT"
|
||||
networkMapKeyGroup = "DEV.CORDACONNECT.OPS.NETMAP"
|
||||
validDays = 3650
|
||||
|
@ -11,27 +11,32 @@ import com.r3.corda.networkmanage.hsm.generator.CertificateConfiguration
|
||||
import com.r3.corda.networkmanage.hsm.generator.GeneratorParameters
|
||||
import com.r3.corda.networkmanage.hsm.generator.UserAuthenticationParameters
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
abstract class HsmBaseTest {
|
||||
companion object {
|
||||
val ROOT_CERT_KEY_GROUP = "DEV.CORDACONNECT.ROOT"
|
||||
val NETWORK_MAP_CERT_KEY_GROUP = "DEV.CORDACONNECT.OPS.NETMAP"
|
||||
val DOORMAN_CERT_KEY_GROUP = "DEV.CORDACONNECT.OPS.CERT"
|
||||
val ROOT_CERT_SUBJECT = "CN=Corda Root CA, O=R3 HoldCo LLC, OU=Corda, L=New York, C=US"
|
||||
val NETWORK_MAP_CERT_SUBJECT = "CN=Corda Network Map, O=R3 HoldCo LLC, OU=Corda, L=New York, C=US"
|
||||
val DOORMAN_CERT_SUBJECT = "CN=Corda Doorman CA, O=R3 HoldCo LLC, OU=Corda, L=New York, C=US"
|
||||
const val ROOT_CERT_KEY_GROUP = "DEV.CORDACONNECT.ROOT"
|
||||
const val NETWORK_MAP_CERT_KEY_GROUP = "DEV.CORDACONNECT.OPS.NETMAP"
|
||||
const val DOORMAN_CERT_KEY_GROUP = "DEV.CORDACONNECT.OPS.CERT"
|
||||
const val ROOT_CERT_SUBJECT = "CN=Corda Root CA, O=R3 HoldCo LLC, OU=Corda, L=New York, C=US"
|
||||
const val NETWORK_MAP_CERT_SUBJECT = "CN=Corda Network Map, O=R3 HoldCo LLC, OU=Corda, L=New York, C=US"
|
||||
const val DOORMAN_CERT_SUBJECT = "CN=Corda Doorman CA, O=R3 HoldCo LLC, OU=Corda, L=New York, C=US"
|
||||
val HSM_USER_CONFIGS = listOf(UserAuthenticationParameters(
|
||||
username = "INTEGRATION_TEST",
|
||||
authMode = AuthMode.PASSWORD,
|
||||
authToken = "INTEGRATION_TEST",
|
||||
keyFilePassword = null))
|
||||
const val ROOT_KEYSTORE_PASSWORD: String = "trustpass"
|
||||
}
|
||||
|
||||
protected lateinit var rootKeyStoreFile: Path
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val tempFolder = TemporaryFolder()
|
||||
@ -43,7 +48,8 @@ abstract class HsmBaseTest {
|
||||
private lateinit var dbName: String
|
||||
|
||||
@Before
|
||||
fun generateRandomDbName() {
|
||||
fun generateDbName() {
|
||||
rootKeyStoreFile = tempFolder.root.toPath() / "truststore.jks"
|
||||
dbName = random63BitValue().toString()
|
||||
}
|
||||
|
||||
@ -51,8 +57,8 @@ abstract class HsmBaseTest {
|
||||
return GeneratorParameters(
|
||||
hsmHost = hsmSimulator.host,
|
||||
hsmPort = hsmSimulator.port,
|
||||
trustStoreDirectory = tempFolder.root.toPath(),
|
||||
trustStorePassword = "",
|
||||
trustStoreDirectory = rootKeyStoreFile.parent,
|
||||
trustStorePassword = ROOT_KEYSTORE_PASSWORD,
|
||||
userConfigs = HSM_USER_CONFIGS,
|
||||
certConfig = certConfig
|
||||
)
|
||||
@ -79,16 +85,19 @@ abstract class HsmBaseTest {
|
||||
))
|
||||
}
|
||||
|
||||
protected val hsmSigningServiceConfig = Parameters(
|
||||
dataSourceProperties = mock(),
|
||||
device = "${hsmSimulator.port}@${hsmSimulator.host}",
|
||||
keySpecifier = 1,
|
||||
rootKeyGroup = ROOT_CERT_KEY_GROUP,
|
||||
doormanKeyGroup = DOORMAN_CERT_KEY_GROUP,
|
||||
networkMapKeyGroup = NETWORK_MAP_CERT_KEY_GROUP,
|
||||
validDays = 3650,
|
||||
csrCertCrlDistPoint = "http://test.com/revoked.crl"
|
||||
)
|
||||
protected fun createHsmSigningServiceConfig(): Parameters {
|
||||
return Parameters(
|
||||
dataSourceProperties = mock(),
|
||||
device = "${hsmSimulator.port}@${hsmSimulator.host}",
|
||||
keySpecifier = 1,
|
||||
rootKeyStoreFile = rootKeyStoreFile,
|
||||
rootKeyStorePassword = ROOT_KEYSTORE_PASSWORD,
|
||||
doormanKeyGroup = DOORMAN_CERT_KEY_GROUP,
|
||||
networkMapKeyGroup = NETWORK_MAP_CERT_KEY_GROUP,
|
||||
validDays = 3650,
|
||||
csrCertCrlDistPoint = "http://test.com/revoked.crl"
|
||||
)
|
||||
}
|
||||
|
||||
protected fun givenHsmUserAuthenticationInput(): InputReader {
|
||||
val inputReader = mock<InputReader>()
|
||||
@ -97,7 +106,7 @@ abstract class HsmBaseTest {
|
||||
return inputReader
|
||||
}
|
||||
|
||||
protected fun makeTestDataSourceProperties(): Properties {
|
||||
fun makeTestDataSourceProperties(): Properties {
|
||||
return makeTestDataSourceProperties(dbName)
|
||||
}
|
||||
}
|
@ -13,11 +13,12 @@ class HsmAuthenticatorTest : HsmBaseTest() {
|
||||
fun `Authenticator executes the block once user is successfully authenticated`() {
|
||||
// given
|
||||
val userInput = givenHsmUserAuthenticationInput()
|
||||
val authenticator = Authenticator(provider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.rootKeyGroup), inputReader = userInput)
|
||||
val hsmSigningServiceConfig = createHsmSigningServiceConfig()
|
||||
val authenticator = Authenticator(provider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.doormanKeyGroup), inputReader = userInput)
|
||||
val executed = AtomicBoolean(false)
|
||||
|
||||
// when
|
||||
authenticator.connectAndAuthenticate { _, _, _ -> executed.set(true) }
|
||||
authenticator.connectAndAuthenticate { _, _ -> executed.set(true) }
|
||||
|
||||
// then
|
||||
assertTrue(executed.get())
|
||||
|
@ -16,19 +16,24 @@ import net.corda.core.crypto.Crypto.generateKeyPair
|
||||
import net.corda.core.identity.CordaX500Name.Companion.parse
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_INTERMEDIATE_CA
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities.createCertificateSigningRequest
|
||||
import net.corda.nodeapi.internal.crypto.loadOrCreateKeyStore
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||
import net.corda.testing.common.internal.testNetworkParameters
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class HsmSigningServiceTest : HsmBaseTest() {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
loadOrCreateKeyStore(rootKeyStoreFile, ROOT_KEYSTORE_PASSWORD)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `HSM signing service can sign CSR data`() {
|
||||
// when root cert is created
|
||||
@ -56,16 +61,15 @@ class HsmSigningServiceTest : HsmBaseTest() {
|
||||
val userInput = givenHsmUserAuthenticationInput()
|
||||
|
||||
// given HSM CSR signer
|
||||
val hsmSigningServiceConfig = createHsmSigningServiceConfig()
|
||||
val signer = HsmCsrSigner(
|
||||
mock(),
|
||||
CORDA_INTERMEDIATE_CA,
|
||||
hsmSigningServiceConfig.loadRootKeyStore(),
|
||||
"",
|
||||
null,
|
||||
CORDA_ROOT_CA,
|
||||
3650,
|
||||
Authenticator(
|
||||
provider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.doormanKeyGroup),
|
||||
rootProvider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.rootKeyGroup),
|
||||
inputReader = userInput)
|
||||
)
|
||||
|
||||
@ -114,6 +118,7 @@ class HsmSigningServiceTest : HsmBaseTest() {
|
||||
val userInput = givenHsmUserAuthenticationInput()
|
||||
|
||||
// given HSM network map signer
|
||||
val hsmSigningServiceConfig = createHsmSigningServiceConfig()
|
||||
val hsmDataSigner = HsmSigner(Authenticator(
|
||||
provider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.networkMapKeyGroup),
|
||||
inputReader = userInput))
|
||||
|
@ -10,6 +10,7 @@ import com.r3.corda.networkmanage.hsm.persistence.ApprovedCertificateRequestData
|
||||
import com.r3.corda.networkmanage.hsm.persistence.DBSignedCertificateRequestStorage
|
||||
import com.r3.corda.networkmanage.hsm.persistence.SignedCertificateRequestStorage
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmCsrSigner
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.createDirectories
|
||||
import net.corda.core.internal.div
|
||||
@ -49,8 +50,11 @@ class SigningServiceIntegrationTest : HsmBaseTest() {
|
||||
private lateinit var rootCaCert: X509Certificate
|
||||
private lateinit var intermediateCa: CertificateAndKeyPair
|
||||
|
||||
private lateinit var dbName: String
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
dbName = random63BitValue().toString()
|
||||
timer = Timer()
|
||||
val (rootCa, intermediateCa) = createDevIntermediateCaCertPath()
|
||||
rootCaCert = rootCa.certificate
|
||||
|
@ -5,9 +5,9 @@ import com.r3.corda.networkmanage.common.persistence.CertificationRequestStorage
|
||||
import com.r3.corda.networkmanage.common.persistence.configureDatabase
|
||||
import com.r3.corda.networkmanage.common.utils.*
|
||||
import com.r3.corda.networkmanage.doorman.signer.LocalSigner
|
||||
import com.r3.corda.networkmanage.hsm.configuration.Parameters.Companion.DEFAULT_CSR_CERTIFICATE_NAME
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||
import net.corda.nodeapi.internal.network.NetworkParameters
|
||||
import org.bouncycastle.pkcs.PKCS10CertificationRequest
|
||||
import java.time.Instant
|
||||
@ -24,7 +24,7 @@ private fun processKeyStore(parameters: NetworkManagementServerParameters): Pair
|
||||
val keyStorePassword = parameters.keystorePassword ?: readPassword("Key store password: ")
|
||||
val privateKeyPassword = parameters.caPrivateKeyPassword ?: readPassword("Private key password: ")
|
||||
val keyStore = X509KeyStore.fromFile(parameters.keystorePath, keyStorePassword)
|
||||
val csrCertPathAndKey = keyStore.getCertPathAndKey(DEFAULT_CSR_CERTIFICATE_NAME, privateKeyPassword)
|
||||
val csrCertPathAndKey = keyStore.getCertPathAndKey(X509Utilities.CORDA_INTERMEDIATE_CA, privateKeyPassword)
|
||||
val networkMapSigner = LocalSigner(keyStore.getCertificateAndKeyPair(CORDA_NETWORK_MAP, privateKeyPassword))
|
||||
return Pair(csrCertPathAndKey, networkMapSigner)
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
package com.r3.corda.networkmanage.doorman
|
||||
|
||||
import com.r3.corda.networkmanage.common.utils.CORDA_NETWORK_MAP
|
||||
import com.r3.corda.networkmanage.hsm.configuration.Parameters.Companion.DEFAULT_CSR_CERTIFICATE_NAME
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SignatureScheme
|
||||
import net.corda.core.internal.createDirectories
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.nodeapi.internal.crypto.*
|
||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||
import java.nio.file.Path
|
||||
import javax.security.auth.x500.X500Principal
|
||||
import kotlin.system.exitProcess
|
||||
@ -103,7 +104,7 @@ fun generateSigningKeyPairs(keystoreFile: Path, rootStoreFile: Path, rootKeystor
|
||||
}
|
||||
|
||||
storeCertIfAbsent(
|
||||
DEFAULT_CSR_CERTIFICATE_NAME,
|
||||
X509Utilities.CORDA_INTERMEDIATE_CA,
|
||||
CertificateType.INTERMEDIATE_CA,
|
||||
X500Principal("CN=Corda Doorman CA,$CORDA_X500_BASE"),
|
||||
X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
|
@ -18,7 +18,6 @@ import com.r3.corda.networkmanage.hsm.persistence.DBSignedCertificateRequestStor
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmCsrSigner
|
||||
import com.r3.corda.networkmanage.hsm.signer.HsmSigner
|
||||
import com.r3.corda.networkmanage.hsm.utils.mapCryptoServerException
|
||||
import net.corda.core.utilities.minutes
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import java.security.Security
|
||||
@ -74,10 +73,9 @@ fun run(parameters: Parameters) {
|
||||
val sign: (List<ApprovedCertificateRequestData>) -> Unit = {
|
||||
val signer = HsmCsrSigner(
|
||||
csrStorage,
|
||||
csrCertificateName,
|
||||
loadRootKeyStore(),
|
||||
csrCertCrlDistPoint,
|
||||
csrCertCrlIssuer,
|
||||
rootCertificateName,
|
||||
validDays,
|
||||
Authenticator(
|
||||
authMode,
|
||||
@ -85,8 +83,7 @@ fun run(parameters: Parameters) {
|
||||
authKeyFilePath,
|
||||
authKeyFilePassword,
|
||||
signAuthThreshold,
|
||||
provider = createProvider(doormanKeyGroup),
|
||||
rootProvider = createProvider(rootKeyGroup)))
|
||||
provider = createProvider(doormanKeyGroup)))
|
||||
signer.sign(it)
|
||||
}
|
||||
Menu().withExceptionHandler(::processError).addItem("1", "Sign all approved and unsigned CSRs", {
|
||||
|
@ -17,18 +17,16 @@ class Authenticator(private val mode: AuthMode = AuthMode.PASSWORD,
|
||||
private val authKeyFilePass: String? = null,
|
||||
private val authStrengthThreshold: Int = 2,
|
||||
inputReader: InputReader = ConsoleInputReader(),
|
||||
private val provider: CryptoServerProvider,
|
||||
private val rootProvider: CryptoServerProvider? = null) : InputReader by inputReader {
|
||||
private val provider: CryptoServerProvider) : InputReader by inputReader {
|
||||
|
||||
/**
|
||||
* Interactively (using console) authenticates a user against the HSM. Once authentication is successful the
|
||||
* [block] is executed.
|
||||
* @param block to be executed once the authentication process succeeds. The block should take 3 parameters:
|
||||
* 1) [CryptoServerProvider] instance of the certificate provider
|
||||
* 2) [CryptoServerProvider] instance of the root certificate provider
|
||||
* 2) List of strings that corresponds to user names authenticated against the HSM.
|
||||
*/
|
||||
fun <T : Any> connectAndAuthenticate(block: (CryptoServerProvider, CryptoServerProvider?, List<String>) -> T): T {
|
||||
fun <T : Any> connectAndAuthenticate(block: (CryptoServerProvider, List<String>) -> T): T {
|
||||
return try {
|
||||
val authenticated = mutableListOf<String>()
|
||||
loop@ while (true) {
|
||||
@ -49,10 +47,6 @@ class Authenticator(private val mode: AuthMode = AuthMode.PASSWORD,
|
||||
println("Authenticating using card reader")
|
||||
println("Accessing the certificate key group data...")
|
||||
provider.loginSign(user, ":cs2:cyb:USB0", null)
|
||||
if (rootProvider != null) {
|
||||
println("Accessing the root certificate key group data...")
|
||||
rootProvider.loginSign(user, ":cs2:cyb:USB0", null)
|
||||
}
|
||||
}
|
||||
AuthMode.KEY_FILE -> {
|
||||
println("Authenticating using preconfigured key file $authKeyFilePath")
|
||||
@ -69,10 +63,6 @@ class Authenticator(private val mode: AuthMode = AuthMode.PASSWORD,
|
||||
}
|
||||
println("Accessing the certificate key group data...")
|
||||
provider.loginSign(user, authKeyFilePath.toString(), password)
|
||||
if (rootProvider != null) {
|
||||
println("Accessing the root certificate key group data...")
|
||||
rootProvider.loginSign(user, authKeyFilePath.toString(), password)
|
||||
}
|
||||
}
|
||||
AuthMode.PASSWORD -> {
|
||||
println("Authenticating using password")
|
||||
@ -83,10 +73,6 @@ class Authenticator(private val mode: AuthMode = AuthMode.PASSWORD,
|
||||
}
|
||||
println("Accessing the certificate key group data...")
|
||||
provider.loginPassword(user, password)
|
||||
if (rootProvider != null) {
|
||||
println("Accessing the root certificate key group data...")
|
||||
rootProvider.loginPassword(user, password)
|
||||
}
|
||||
}
|
||||
}
|
||||
authenticated.add(user!!)
|
||||
@ -99,7 +85,7 @@ class Authenticator(private val mode: AuthMode = AuthMode.PASSWORD,
|
||||
}
|
||||
}
|
||||
if (!authenticated.isEmpty()) {
|
||||
block(provider, rootProvider, authenticated)
|
||||
block(provider, authenticated)
|
||||
} else {
|
||||
throw AuthenticationException()
|
||||
}
|
||||
@ -113,8 +99,8 @@ class Authenticator(private val mode: AuthMode = AuthMode.PASSWORD,
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
/*
|
||||
* Configuration class for [CryptoServerProvider]
|
||||
*/
|
||||
data class CryptoServerProviderConfig(
|
||||
|
@ -8,7 +8,7 @@ import net.corda.core.internal.div
|
||||
import net.corda.core.internal.isRegularFile
|
||||
import net.corda.core.utilities.minutes
|
||||
import net.corda.nodeapi.internal.config.parseAs
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.persistence.DatabaseConfig
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
@ -21,15 +21,14 @@ data class Parameters(val dataSourceProperties: Properties,
|
||||
val databaseConfig: DatabaseConfig = DatabaseConfig(),
|
||||
val device: String = DEFAULT_DEVICE,
|
||||
// TODO this needs cleaning up after the config-file-only support is implemented
|
||||
val rootKeyGroup: String,
|
||||
val doormanKeyGroup:String,
|
||||
val rootKeyStoreFile: Path,
|
||||
val rootKeyStorePassword: String,
|
||||
val doormanKeyGroup: String,
|
||||
val networkMapKeyGroup: String,
|
||||
val keySpecifier: Int = DEFAULT_KEY_SPECIFIER,
|
||||
val csrCertificateName: String = DEFAULT_CSR_CERTIFICATE_NAME,
|
||||
val csrCertCrlDistPoint: String,
|
||||
val csrCertCrlIssuer: String? = DEFAULT_CSR_CERT_CRL_ISSUER, // X500 name of the issuing authority e.g. "L=New York, C=US, OU=Org Unit, CN=Service Name",
|
||||
// if null parent CA is is considered as an issuer.
|
||||
val rootCertificateName: String = DEFAULT_ROOT_CERTIFICATE_NAME,
|
||||
val validDays: Int,
|
||||
val signAuthThreshold: Int = DEFAULT_SIGN_AUTH_THRESHOLD,
|
||||
val keyGenAuthThreshold: Int = DEFAULT_KEY_GEN_AUTH_THRESHOLD,
|
||||
@ -44,8 +43,6 @@ data class Parameters(val dataSourceProperties: Properties,
|
||||
val DEFAULT_AUTH_MODE = AuthMode.PASSWORD
|
||||
val DEFAULT_SIGN_AUTH_THRESHOLD = 2
|
||||
val DEFAULT_KEY_GEN_AUTH_THRESHOLD = 2
|
||||
val DEFAULT_CSR_CERTIFICATE_NAME = X509Utilities.CORDA_INTERMEDIATE_CA
|
||||
val DEFAULT_ROOT_CERTIFICATE_NAME = X509Utilities.CORDA_ROOT_CA
|
||||
val DEFAULT_KEY_SPECIFIER = 1
|
||||
val DEFAULT_KEY_FILE_PATH: Path? = null //Paths.get("/Users/michalkit/WinDev1706Eval/Shared/TEST4.key")
|
||||
val DEFAULT_KEY_FILE_PASSWORD: String? = null
|
||||
@ -53,6 +50,10 @@ data class Parameters(val dataSourceProperties: Properties,
|
||||
val DEFAULT_SIGN_INTERVAL = 1.minutes.toMillis()
|
||||
val DEFAULT_CSR_CERT_CRL_ISSUER: String? = null
|
||||
}
|
||||
|
||||
fun loadRootKeyStore(createNew: Boolean = false): X509KeyStore {
|
||||
return X509KeyStore.fromFile(rootKeyStoreFile, rootKeyStorePassword, createNew)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,18 +7,17 @@ import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.createClientCertifi
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.getAndInitializeKeyStore
|
||||
import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.retrieveCertAndKeyPair
|
||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||
import net.corda.nodeapi.internal.crypto.X509KeyStore
|
||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||
import net.corda.nodeapi.internal.crypto.getX509Certificate
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
|
||||
/**
|
||||
* Encapsulates certificate signing logic
|
||||
*/
|
||||
class HsmCsrSigner(private val storage: SignedCertificateRequestStorage,
|
||||
private val intermediateCertAlias: String,
|
||||
private val rootKeyStore: X509KeyStore,
|
||||
private val csrCertCrlDistPoint: String,
|
||||
private val csrCertCrlIssuer: String?,
|
||||
private val rootCertAlias: String,
|
||||
private val validDays: Int,
|
||||
private val authenticator: Authenticator) : CertificateSigningRequestSigner {
|
||||
|
||||
@ -33,11 +32,12 @@ class HsmCsrSigner(private val storage: SignedCertificateRequestStorage,
|
||||
* @param toSign list of approved certificates to be signed
|
||||
*/
|
||||
override fun sign(toSign: List<ApprovedCertificateRequestData>) {
|
||||
authenticator.connectAndAuthenticate { provider, rootProvider, signers ->
|
||||
val rootKeyStore = getAndInitializeKeyStore(rootProvider!!)
|
||||
val rootCert = rootKeyStore.getX509Certificate(rootCertAlias)
|
||||
authenticator.connectAndAuthenticate { provider, signers ->
|
||||
// This should be changed once we allow for more certificates in the chain. Preferably we should use
|
||||
// keyStore.getCertificateChain(String) and assume entire chain is stored in the HSM (depending on the support).
|
||||
val rootCert = rootKeyStore.getCertificate(X509Utilities.CORDA_ROOT_CA)
|
||||
val keyStore = getAndInitializeKeyStore(provider)
|
||||
val doormanCertAndKey = retrieveCertAndKeyPair(intermediateCertAlias, keyStore)
|
||||
val doormanCertAndKey = retrieveCertAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, keyStore)
|
||||
toSign.forEach {
|
||||
val nodeCaCert = createClientCertificate(
|
||||
CertificateType.NODE_CA,
|
||||
|
@ -19,7 +19,7 @@ class HsmSigner(private val authenticator: Authenticator) : Signer {
|
||||
* Signs given data using [CryptoServerJCE.CryptoServerProvider], which connects to the underlying HSM.
|
||||
*/
|
||||
override fun signBytes(data: ByteArray): DigitalSignatureWithCert {
|
||||
return authenticator.connectAndAuthenticate { provider, _, _ ->
|
||||
return authenticator.connectAndAuthenticate { provider, _ ->
|
||||
val keyStore = getAndInitializeKeyStore(provider)
|
||||
val certificate = keyStore.getX509Certificate(CORDA_NETWORK_MAP)
|
||||
// Don't worry this is not a real private key but a pointer to one that resides in the HSM. It only works
|
||||
|
@ -28,7 +28,7 @@ class AuthenticatorTest : TestBase() {
|
||||
|
||||
// when
|
||||
assertFailsWith<AuthenticationException> {
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _, _ -> }
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _ -> }
|
||||
}
|
||||
|
||||
//then
|
||||
@ -47,7 +47,7 @@ class AuthenticatorTest : TestBase() {
|
||||
var executed = false
|
||||
|
||||
// when
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _, _ -> executed = true }
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _ -> executed = true }
|
||||
|
||||
// then
|
||||
verify(provider).loginPassword(username, password)
|
||||
@ -64,7 +64,7 @@ class AuthenticatorTest : TestBase() {
|
||||
var executed = false
|
||||
|
||||
// when
|
||||
Authenticator(provider = provider, inputReader = inputReader, mode = AuthMode.CARD_READER).connectAndAuthenticate { _, _, _ -> executed = true }
|
||||
Authenticator(provider = provider, inputReader = inputReader, mode = AuthMode.CARD_READER).connectAndAuthenticate { _, _ -> executed = true }
|
||||
|
||||
// then
|
||||
verify(provider).loginSign(username, ":cs2:cyb:USB0", null)
|
||||
@ -83,7 +83,7 @@ class AuthenticatorTest : TestBase() {
|
||||
var executed = false
|
||||
|
||||
// when
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _, _ -> executed = true }
|
||||
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _ -> executed = true }
|
||||
|
||||
// then
|
||||
verify(provider, times(3)).loginPassword(username, password)
|
||||
|
Loading…
x
Reference in New Issue
Block a user