diff --git a/docs/source/running-hsm-cert-generator.rst b/docs/source/running-hsm-cert-generator.rst index 0b41f0ac21..8b84b1488a 100644 --- a/docs/source/running-hsm-cert-generator.rst +++ b/docs/source/running-hsm-cert-generator.rst @@ -46,6 +46,8 @@ Certificate Configuration :certificateType: Type of the certificate to be created. Allowed values are: ROOT_CA, INTERMEDIATE_CA, NETWORK_MAP. +:rootKeyGroup: This is an HSM specific parameter that corresponds to key name spacing for the root key. It is ignored if the certificateType value is ROOT_CA. See Utimaco documentation for more details. + :subject: X500Name formatted string to be used as the certificate public key subject. :validDays: Days number for certificate validity. @@ -64,7 +66,7 @@ Certificate Configuration :keySpecifier: This is an HSM specific parameter that corresponds to key name spacing. See Utimaco documentation for more details. -:keyGroup: This is an HSM specific parameter that corresponds to key name spacing. See Utimaco documentation for more details. +:keyGroup: This is an HSM specific parameter that corresponds to key name spacing for the generated key. See Utimaco documentation for more details. User Authentication Configuration @@ -78,6 +80,6 @@ Allowed parameters are: CARD_READER - Smart card reader authentication KEY_FILE - Key file based authentication. -:authToken: Depending on the authMode it is either user's password or path to the authentication key file. +:authToken: Depending on the authMode it is either user's password or path to the authentication key file. In case of the CARD_READER authMode value, this can be omitted. :keyFilePassword: Only relevant, if authMode == KEY_FILE. It is the key file password. \ No newline at end of file diff --git a/docs/source/running-signing-service.rst b/docs/source/running-signing-service.rst index 61a2997c8b..6e6bb1a1aa 100644 --- a/docs/source/running-signing-service.rst +++ b/docs/source/running-signing-service.rst @@ -28,7 +28,11 @@ 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" -:keyGroup: HSM key group. This parameter is vendor specific (see Utimaco docs). +:rootKeyGroup: HSM key group for the root certificate key. This parameter is vendor specific (see Utimaco docs). + +:networkMapKeyGroup: HSM key group for the network map certificate key. This parameter is vendor specific (see Utimaco docs). + +:doormanKeyGroup: HSM key group for the doorman certificate key. This parameter is vendor specific (see Utimaco docs). :keySpecifier: HSM key specifier. This parameter is vendor specific (see Utimaco docs). Default value: 1. diff --git a/network-management/generator.conf b/network-management/generator.conf index 660ce68e8d..6af78434b3 100644 --- a/network-management/generator.conf +++ b/network-management/generator.conf @@ -4,7 +4,7 @@ trustStoreDirectory = "." trustStorePassword = "trustpass" certConfig { - subject = "CN=Corda Root, O=R3Cev, L=London, C=GB" + subject = "CN=Corda Root, O=R3 HoldCo LLC, OU=Corda, L=New York, C=US" certificateType = ROOT_CA validDays = 3650 keyOverride = 0 diff --git a/network-management/hsm.conf b/network-management/hsm.conf index 124222d894..7677176671 100644 --- a/network-management/hsm.conf +++ b/network-management/hsm.conf @@ -1,15 +1,14 @@ basedir = "." -device = "3001@127.0.0.1" -keyGroup = "DEV.DOORMAN" +device = "3001@192.168.0.1" keySpecifier = -1 authMode = PASSWORD rootCertificateName = "corda_root_ca" -rootPrivateKeyPassword = "Password" -csrPrivateKeyPassword = "Password" csrCertificateName = "intermediate_ca" csrCertCrlDistPoint = "http://test.com/revoked.crl" networkMapCertificateName = "intermediate_ca" -networkMapPrivateKeyPassword = "Password" +rootKeyGroup = "DEV.CORDACONNECT.ROOT" +doormanKeyGroup = "DEV.CORDACONNECT.OPS.CERT" +networkMapKeyGroup = "DEV.CORDACONNECT.OPS.NETMAP" validDays = 3650 signAuthThreshold = 2 keyGenAuthThreshold = 2 diff --git a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmAuthenticatorTest.kt b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmAuthenticatorTest.kt new file mode 100644 index 0000000000..122f93f611 --- /dev/null +++ b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmAuthenticatorTest.kt @@ -0,0 +1,24 @@ +package com.r3.corda.networkmanage.hsm + +import com.r3.corda.networkmanage.hsm.authentication.Authenticator +import com.r3.corda.networkmanage.hsm.authentication.createProvider +import org.junit.Test +import java.util.concurrent.atomic.AtomicBoolean +import kotlin.test.assertTrue + +class HsmAuthenticatorTest : HsmCertificateTest() { + + @Test + 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 executed = AtomicBoolean(false) + + // when + authenticator.connectAndAuthenticate { _, _, _ -> executed.set(true) } + + // then + assertTrue(executed.get()) + } +} \ No newline at end of file diff --git a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmCertificateTest.kt b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmCertificateTest.kt new file mode 100644 index 0000000000..38aed44498 --- /dev/null +++ b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmCertificateTest.kt @@ -0,0 +1,91 @@ +package com.r3.corda.networkmanage.hsm + +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.whenever +import com.r3.corda.networkmanage.HsmSimulator +import com.r3.corda.networkmanage.hsm.authentication.CryptoServerProviderConfig +import com.r3.corda.networkmanage.hsm.authentication.InputReader +import com.r3.corda.networkmanage.hsm.configuration.Parameters +import com.r3.corda.networkmanage.hsm.generator.AuthMode +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.nodeapi.internal.crypto.CertificateType +import org.junit.Rule +import org.junit.rules.TemporaryFolder + +abstract class HsmCertificateTest { + 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" + } + + @Rule + @JvmField + val tempFolder = TemporaryFolder() + + @Rule + @JvmField + val hsmSimulator: HsmSimulator = HsmSimulator() + + protected val rootCertParameters: GeneratorParameters by lazy { + GeneratorParameters( + hsmHost = hsmSimulator.host, + hsmPort = hsmSimulator.port, + trustStoreDirectory = tempFolder.root.toPath(), + trustStorePassword = "", + userConfigs = listOf(UserAuthenticationParameters( + username = "INTEGRATION_TEST", + authMode = AuthMode.PASSWORD, + authToken = "INTEGRATION_TEST", + keyFilePassword = null + )), + certConfig = CertificateConfiguration( + keySpecifier = 1, + keyGroup = ROOT_CERT_KEY_GROUP, + storeKeysExternal = false, + rootKeyGroup = null, + subject = ROOT_CERT_SUBJECT, + validDays = 3650, + keyCurve = "NIST-P256", + certificateType = CertificateType.ROOT_CA, + keyExport = 0, + keyGenMechanism = 4, + keyOverride = 0, + crlIssuer = null, + crlDistributionUrl = null + ) + ) + } + + protected val providerConfig: CryptoServerProviderConfig by lazy { + CryptoServerProviderConfig( + Device = "${rootCertParameters.hsmPort}@${rootCertParameters.hsmHost}", + KeySpecifier = rootCertParameters.certConfig.keySpecifier, + KeyGroup = rootCertParameters.certConfig.keyGroup, + StoreKeysExternal = rootCertParameters.certConfig.storeKeysExternal) + } + + 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 givenHsmUserAuthenticationInput(): InputReader { + val inputReader = mock() + whenever(inputReader.readLine()).thenReturn(hsmSimulator.cryptoUserCredentials().username) + whenever(inputReader.readPassword(any())).thenReturn(hsmSimulator.cryptoUserCredentials().password) + return inputReader + } +} \ No newline at end of file diff --git a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmKeyGenerationTest.kt b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmKeyGenerationTest.kt index 4fc4248523..95fb091545 100644 --- a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmKeyGenerationTest.kt +++ b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmKeyGenerationTest.kt @@ -1,111 +1,82 @@ package com.r3.corda.networkmanage.hsm -import com.r3.corda.networkmanage.HsmSimulator +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.whenever import com.r3.corda.networkmanage.common.utils.CORDA_NETWORK_MAP -import com.r3.corda.networkmanage.hsm.authentication.CryptoServerProviderConfig -import com.r3.corda.networkmanage.hsm.generator.* +import com.r3.corda.networkmanage.hsm.authentication.InputReader +import com.r3.corda.networkmanage.hsm.generator.AutoAuthenticator +import com.r3.corda.networkmanage.hsm.generator.run import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities +import net.corda.core.identity.CordaX500Name 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 org.junit.Rule +import org.junit.Before import org.junit.Test -import org.junit.rules.TemporaryFolder import java.security.cert.X509Certificate import kotlin.test.assertEquals import kotlin.test.assertNotNull -class HsmKeyGenerationTest { +class HsmKeyGenerationTest : HsmCertificateTest() { - @Rule - @JvmField - val tempFolder = TemporaryFolder() + private lateinit var inputReader: InputReader - @Rule - @JvmField - val hsmSimulator: HsmSimulator = HsmSimulator() - - private val rootCertParameters: GeneratorParameters by lazy { - GeneratorParameters( - hsmHost = hsmSimulator.host, - hsmPort = hsmSimulator.port, - trustStoreDirectory = tempFolder.root.toPath(), - trustStorePassword = "", - userConfigs = listOf(UserAuthenticationParameters( - username = "INTEGRATION_TEST", - authMode = AuthMode.PASSWORD, - authToken = "INTEGRATION_TEST", - keyFilePassword = null - )), - certConfig = CertificateConfiguration( - keySpecifier = 1, - keyGroup = "DEV.DOORMAN", - storeKeysExternal = false, - subject = "CN=Corda Root, O=R3Cev, L=London, C=GB", - validDays = 3650, - keyCurve = "NIST-P256", - certificateType = CertificateType.ROOT_CA, - keyExport = 0, - keyGenMechanism = 4, - keyOverride = 0, - crlIssuer = null, - crlDistributionUrl = null - ) - ) - } - - private val providerConfig: CryptoServerProviderConfig by lazy { - CryptoServerProviderConfig( - Device = "${rootCertParameters.hsmPort}@${rootCertParameters.hsmHost}", - KeySpecifier = rootCertParameters.certConfig.keySpecifier, - KeyGroup = rootCertParameters.certConfig.keyGroup, - StoreKeysExternal = rootCertParameters.certConfig.storeKeysExternal) + @Before + fun setUp() { + inputReader = mock() + whenever(inputReader.readLine()).thenReturn(hsmSimulator.cryptoUserCredentials().username) + whenever(inputReader.readPassword(any())).thenReturn(hsmSimulator.cryptoUserCredentials().password) } @Test - fun `Authenticator executes the block once user is successfully authenticated`() { - // given - val authenticator = AutoAuthenticator(providerConfig, rootCertParameters.userConfigs) - val rootCertGenerator = KeyCertificateGenerator(rootCertParameters) + fun `Root and network map certificates have different namespace`() { // when root cert is created - authenticator.connectAndAuthenticate { provider -> - rootCertGenerator.generate(provider) - // then + run(rootCertParameters) + // when network map cert is created + run(rootCertParameters.copy( + certConfig = rootCertParameters.certConfig.copy( + keyGroup = NETWORK_MAP_CERT_KEY_GROUP, + rootKeyGroup = ROOT_CERT_KEY_GROUP, + certificateType = CertificateType.NETWORK_MAP, + subject = NETWORK_MAP_CERT_SUBJECT + ) + )) + // when doorman cert is created + run(rootCertParameters.copy( + certConfig = rootCertParameters.certConfig.copy( + keyGroup = DOORMAN_CERT_KEY_GROUP, + rootKeyGroup = ROOT_CERT_KEY_GROUP, + certificateType = CertificateType.INTERMEDIATE_CA, + subject = DOORMAN_CERT_SUBJECT + ) + )) + + // then root cert is persisted in the HSM + AutoAuthenticator(providerConfig, rootCertParameters.userConfigs).connectAndAuthenticate { provider -> val keyStore = HsmX509Utilities.getAndInitializeKeyStore(provider) val rootCert = keyStore.getCertificate(CORDA_ROOT_CA) as X509Certificate assertEquals(rootCert.issuerX500Principal, rootCert.subjectX500Principal) } - // when network map cert is created - val networkMapCertGenerator = KeyCertificateGenerator(rootCertParameters.copy( - certConfig = rootCertParameters.certConfig.copy( - certificateType = CertificateType.NETWORK_MAP, - subject = "CN=Corda NM, O=R3Cev, L=London, C=GB" - ) - )) - authenticator.connectAndAuthenticate { provider -> - networkMapCertGenerator.generate(provider) - // then - val keyStore = HsmX509Utilities.getAndInitializeKeyStore(provider) - val rootCert = keyStore.getCertificate(CORDA_ROOT_CA) as X509Certificate - val networkMapCert = keyStore.getCertificate(CORDA_NETWORK_MAP) as X509Certificate - assertNotNull(networkMapCert) - assertEquals(rootCert.subjectX500Principal, networkMapCert.issuerX500Principal) - } - // when csr cert is created - val csrCertGenerator = KeyCertificateGenerator(rootCertParameters.copy( - certConfig = rootCertParameters.certConfig.copy( - certificateType = CertificateType.INTERMEDIATE_CA, - subject = "CN=Corda CSR, O=R3Cev, L=London, C=GB" - ) - )) - authenticator.connectAndAuthenticate { provider -> - csrCertGenerator.generate(provider) - // then - val keyStore = HsmX509Utilities.getAndInitializeKeyStore(provider) - val rootCert = keyStore.getCertificate(CORDA_ROOT_CA) as X509Certificate - val csrCert = keyStore.getCertificate(CORDA_INTERMEDIATE_CA) as X509Certificate - assertNotNull(csrCert) - assertEquals(rootCert.subjectX500Principal, csrCert.issuerX500Principal) - } + + // then network map cert is persisted in the HSM + + AutoAuthenticator(providerConfig.copy(KeyGroup = NETWORK_MAP_CERT_KEY_GROUP), rootCertParameters.userConfigs) + .connectAndAuthenticate { provider -> + val keyStore = HsmX509Utilities.getAndInitializeKeyStore(provider) + val networkMapCert = keyStore.getCertificate(CORDA_NETWORK_MAP) as X509Certificate + assertNotNull(networkMapCert) + assertEquals(CordaX500Name.parse(ROOT_CERT_SUBJECT).x500Principal, networkMapCert.issuerX500Principal) + } + + // then doorman cert is persisted in the HSM + + AutoAuthenticator(providerConfig.copy(KeyGroup = DOORMAN_CERT_KEY_GROUP), rootCertParameters.userConfigs) + .connectAndAuthenticate { provider -> + val keyStore = HsmX509Utilities.getAndInitializeKeyStore(provider) + val networkMapCert = keyStore.getCertificate(CORDA_INTERMEDIATE_CA) as X509Certificate + assertNotNull(networkMapCert) + assertEquals(CordaX500Name.parse(ROOT_CERT_SUBJECT).x500Principal, networkMapCert.issuerX500Principal) + } } } \ No newline at end of file diff --git a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmSigningServiceTest.kt b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmSigningServiceTest.kt new file mode 100644 index 0000000000..2602a8b137 --- /dev/null +++ b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmSigningServiceTest.kt @@ -0,0 +1,120 @@ +package com.r3.corda.networkmanage.hsm + +import com.nhaarman.mockito_kotlin.mock +import com.r3.corda.networkmanage.hsm.authentication.Authenticator +import com.r3.corda.networkmanage.hsm.authentication.createProvider +import com.r3.corda.networkmanage.hsm.generator.run +import com.r3.corda.networkmanage.hsm.persistence.ApprovedCertificateRequestData +import com.r3.corda.networkmanage.hsm.signer.HsmCsrSigner +import com.r3.corda.networkmanage.hsm.signer.HsmNetworkMapSigner +import net.corda.core.crypto.Crypto.generateKeyPair +import net.corda.core.crypto.secureRandomBytes +import net.corda.core.identity.CordaX500Name.Companion.parse +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 org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + +class HsmSigningServiceTest : HsmCertificateTest() { + + @Test + fun `HSM signing service can sign network map data`() { + // when root cert is created + run(rootCertParameters) + // when network map cert is created + run(rootCertParameters.copy( + certConfig = rootCertParameters.certConfig.copy( + keyGroup = NETWORK_MAP_CERT_KEY_GROUP, + rootKeyGroup = ROOT_CERT_KEY_GROUP, + certificateType = CertificateType.NETWORK_MAP, + subject = NETWORK_MAP_CERT_SUBJECT + ) + )) + // when doorman cert is created + run(rootCertParameters.copy( + certConfig = rootCertParameters.certConfig.copy( + keyGroup = DOORMAN_CERT_KEY_GROUP, + rootKeyGroup = ROOT_CERT_KEY_GROUP, + certificateType = CertificateType.INTERMEDIATE_CA, + subject = DOORMAN_CERT_SUBJECT + ) + )) + + // given authenticated user + val userInput = givenHsmUserAuthenticationInput() + + // given HSM network map signer + val signer = HsmNetworkMapSigner(Authenticator( + provider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.networkMapKeyGroup), + inputReader = userInput)) + + // give random data to sign + val toSign = secureRandomBytes(10) + + // when + signer.signBytes(toSign) + + // No exception is thrown + } + + @Test + fun `HSM signing service can sign CSR data`() { + // when root cert is created + run(rootCertParameters) + // when network map cert is created + run(rootCertParameters.copy( + certConfig = rootCertParameters.certConfig.copy( + keyGroup = NETWORK_MAP_CERT_KEY_GROUP, + rootKeyGroup = ROOT_CERT_KEY_GROUP, + certificateType = CertificateType.NETWORK_MAP, + subject = NETWORK_MAP_CERT_SUBJECT + ) + )) + // when doorman cert is created + run(rootCertParameters.copy( + certConfig = rootCertParameters.certConfig.copy( + keyGroup = DOORMAN_CERT_KEY_GROUP, + rootKeyGroup = ROOT_CERT_KEY_GROUP, + certificateType = CertificateType.INTERMEDIATE_CA, + subject = DOORMAN_CERT_SUBJECT + ) + )) + + // given authenticated user + val userInput = givenHsmUserAuthenticationInput() + + // given HSM CSR signer + val signer = HsmCsrSigner( + mock(), + CORDA_INTERMEDIATE_CA, + "", + null, + CORDA_ROOT_CA, + 3650, + Authenticator( + provider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.doormanKeyGroup), + rootProvider = hsmSigningServiceConfig.createProvider(hsmSigningServiceConfig.rootKeyGroup), + inputReader = userInput) + ) + + // give random data to sign + val toSign = ApprovedCertificateRequestData( + "test", + createCertificateSigningRequest( + parse("O=R3Cev,L=London,C=GB").x500Principal, + "my@mail.com", + generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME))) + + // when + signer.sign(listOf(toSign)) + + // then + assertNotNull(toSign.certPath) + val certificates = toSign.certPath!!.certificates + assertEquals(3, certificates.size) + } +} \ No newline at end of file diff --git a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmTest.kt b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmTest.kt deleted file mode 100644 index 24e6f9909d..0000000000 --- a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/hsm/HsmTest.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.r3.corda.networkmanage.hsm - -import com.nhaarman.mockito_kotlin.any -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.whenever -import com.r3.corda.networkmanage.HsmSimulator -import com.r3.corda.networkmanage.hsm.authentication.Authenticator -import com.r3.corda.networkmanage.hsm.authentication.InputReader -import com.r3.corda.networkmanage.hsm.authentication.createProvider -import com.r3.corda.networkmanage.hsm.configuration.Parameters -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TemporaryFolder -import java.util.concurrent.atomic.AtomicBoolean -import kotlin.test.assertTrue - -class HsmTest { - - @Rule - @JvmField - val hsmSimulator: HsmSimulator = HsmSimulator() - - @Rule - @JvmField - val tempFolder = TemporaryFolder() - - private val testParameters = Parameters( - dataSourceProperties = mock(), - device = "${hsmSimulator.port}@${hsmSimulator.host}", - keySpecifier = 1, - csrPrivateKeyPassword = "", - networkMapPrivateKeyPassword = "", - rootPrivateKeyPassword = "", - keyGroup = "DEV.DOORMAN", - validDays = 3650, - csrCertCrlDistPoint = "http://test.com/revoked.crl" - ) - - private lateinit var inputReader: InputReader - - @Before - fun setUp() { - inputReader = mock() - whenever(inputReader.readLine()).thenReturn(hsmSimulator.cryptoUserCredentials().username) - whenever(inputReader.readPassword(any())).thenReturn(hsmSimulator.cryptoUserCredentials().password) - } - - @Test - fun `Authenticator executes the block once user is successfully authenticated`() { - // given - val authenticator = Authenticator(testParameters.createProvider(), inputReader = inputReader) - val executed = AtomicBoolean(false) - - // when - authenticator.connectAndAuthenticate { _, _ -> executed.set(true) } - - // then - assertTrue(executed.get()) - } -} \ No newline at end of file diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/Main.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/Main.kt index d1a08f1ded..fb77d45e51 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/Main.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/Main.kt @@ -57,8 +57,13 @@ fun run(parameters: Parameters) { val database = configureDatabase(dataSourceProperties, databaseConfig) val csrStorage = DBSignedCertificateRequestStorage(database) val hsmSigner = HsmNetworkMapSigner( - networkMapPrivateKeyPassword, - Authenticator(createProvider(), AuthMode.KEY_FILE, autoUsername, authKeyFilePath, authKeyFilePassword, signAuthThreshold)) + Authenticator( + AuthMode.KEY_FILE, + autoUsername, + authKeyFilePath, + authKeyFilePassword, + signAuthThreshold, + provider = createProvider(networkMapKeyGroup))) val networkMapStorage = PersistentNetworkMapStorage(database) val scheduler = Executors.newSingleThreadScheduledExecutor() @@ -68,12 +73,18 @@ fun run(parameters: Parameters) { val signer = HsmCsrSigner( csrStorage, csrCertificateName, - csrPrivateKeyPassword, csrCertCrlDistPoint, csrCertCrlIssuer, rootCertificateName, validDays, - Authenticator(createProvider(), authMode, autoUsername, authKeyFilePath, authKeyFilePassword, signAuthThreshold)) + Authenticator( + authMode, + autoUsername, + authKeyFilePath, + authKeyFilePassword, + signAuthThreshold, + provider = createProvider(doormanKeyGroup), + rootProvider = createProvider(rootKeyGroup))) signer.sign(it) } Menu().withExceptionHandler(::processError).addItem("1", "Sign all approved and unsigned CSRs", { @@ -141,13 +152,6 @@ private fun confirmedSign(selectedItems: List): return result } -private fun confirmedKeyGen(): Boolean { - println("Are you sure you want to generate new keys/certificates (it will overwrite the existing ones):") - var result = false - Menu().addItem("Y", "Yes", { result = true }, true).setExitOption("N", "No").showMenu() - return result -} - private fun getSelection(toSelect: List): List { print("CSRs to be signed (comma separated list): ") val line = readLine() diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/authentication/Authenticator.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/authentication/Authenticator.kt index 90d626e4c8..d8438091c1 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/authentication/Authenticator.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/authentication/Authenticator.kt @@ -11,22 +11,24 @@ import kotlin.reflect.full.memberProperties /** * Performs user authentication against the HSM */ -class Authenticator(private val provider: CryptoServerProvider, - private val mode: AuthMode = AuthMode.PASSWORD, +class Authenticator(private val mode: AuthMode = AuthMode.PASSWORD, private val autoUsername: String? = null, private val authKeyFilePath: Path? = null, private val authKeyFilePass: String? = null, private val authStrengthThreshold: Int = 2, - inputReader: InputReader = ConsoleInputReader()) : InputReader by inputReader { + inputReader: InputReader = ConsoleInputReader(), + private val provider: CryptoServerProvider, + private val rootProvider: CryptoServerProvider? = null) : 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 2 parameters: - * 1) [CryptoServerProvider] instance + * @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 connectAndAuthenticate(block: (CryptoServerProvider, List) -> T): T { + fun connectAndAuthenticate(block: (CryptoServerProvider, CryptoServerProvider?, List) -> T): T { return try { val authenticated = mutableListOf() loop@ while (true) { @@ -45,7 +47,12 @@ class Authenticator(private val provider: CryptoServerProvider, when (mode) { AuthMode.CARD_READER -> { 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") @@ -60,7 +67,12 @@ class Authenticator(private val provider: CryptoServerProvider, } else { authKeyFilePass } + 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") @@ -69,7 +81,12 @@ class Authenticator(private val provider: CryptoServerProvider, authenticated.clear() break@loop } + 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!!) @@ -82,7 +99,7 @@ class Authenticator(private val provider: CryptoServerProvider, } } if (!authenticated.isEmpty()) { - block(provider, authenticated) + block(provider, rootProvider, authenticated) } else { throw AuthenticationException() } @@ -114,7 +131,7 @@ data class CryptoServerProviderConfig( /** * Creates an instance of [CryptoServerProvider] that corresponds to the HSM. */ -fun Parameters.createProvider(): CryptoServerProvider { +fun Parameters.createProvider(keyGroup: String): CryptoServerProvider { val config = CryptoServerProviderConfig( Device = device, KeyGroup = keyGroup, diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/configuration/Configuration.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/configuration/Configuration.kt index 75f331b828..bdcccff9b6 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/configuration/Configuration.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/configuration/Configuration.kt @@ -20,15 +20,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 keyGroup: String, + val rootKeyGroup: String, + val doormanKeyGroup:String, + val networkMapKeyGroup: String, val keySpecifier: Int = DEFAULT_KEY_SPECIFIER, - val rootPrivateKeyPassword: String, - val csrPrivateKeyPassword: String, 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 networkMapPrivateKeyPassword: String, val rootCertificateName: String = DEFAULT_ROOT_CERTIFICATE_NAME, val validDays: Int, val signAuthThreshold: Int = DEFAULT_SIGN_AUTH_THRESHOLD, diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/AutoAuthenticator.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/AutoAuthenticator.kt index a0004ab30e..4e751f324e 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/AutoAuthenticator.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/AutoAuthenticator.kt @@ -19,7 +19,7 @@ class AutoAuthenticator(providerConfig: CryptoServerProviderConfig, fun connectAndAuthenticate(block: (CryptoServerProvider) -> Unit) { try { for (userConfig in userConfigs) { - when(userConfig.authMode) { + when (userConfig.authMode) { AuthMode.PASSWORD -> provider.loginPassword(userConfig.username, userConfig.authToken) AuthMode.CARD_READER -> provider.loginSign(userConfig.username, ":cs2:cyb:USB0", null) AuthMode.KEY_FILE -> provider.loginSign(userConfig.username, userConfig.keyFilePassword, userConfig.authToken) diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/GeneratorParameters.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/GeneratorParameters.kt index 5e459a9c14..a12c5a442b 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/GeneratorParameters.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/GeneratorParameters.kt @@ -15,7 +15,7 @@ import java.nio.file.Paths */ data class UserAuthenticationParameters(val username: String, val authMode: AuthMode, - val authToken: String, // password or path to the key file, depending on the [authMode] + val authToken: String?, // password or path to the key file, depending on the [authMode] val keyFilePassword: String?) // used only if authMode == [AuthMode.KEY_FILE] /** @@ -42,6 +42,7 @@ data class CertificateConfiguration(val keyGroup: String, val keySpecifier: Int, val storeKeysExternal: Boolean, val certificateType: CertificateType, + val rootKeyGroup: String?, val subject: String, // it is certificate [X500Name] subject val validDays: Int, val crlDistributionUrl: String?, diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/KeyCertificateGenerator.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/KeyCertificateGenerator.kt index 4475f46c5a..2ddcdfdce5 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/KeyCertificateGenerator.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/KeyCertificateGenerator.kt @@ -4,7 +4,6 @@ import CryptoServerCXI.CryptoServerCXI.KEY_ALGO_ECDSA import CryptoServerCXI.CryptoServerCXI.KeyAttributes import CryptoServerJCE.CryptoServerProvider import com.r3.corda.networkmanage.common.utils.CORDA_NETWORK_MAP -import com.r3.corda.networkmanage.doorman.NETWORK_ROOT_TRUSTSTORE_FILENAME import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.createIntermediateCert import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.createSelfSignedCACert import com.r3.corda.networkmanage.hsm.utils.HsmX509Utilities.getAndInitializeKeyStore @@ -15,10 +14,13 @@ import net.corda.core.internal.div import net.corda.core.internal.isDirectory import net.corda.core.internal.x500Name import net.corda.core.utilities.contextLogger -import net.corda.nodeapi.internal.crypto.* +import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair 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.addOrReplaceCertificate +import net.corda.nodeapi.internal.crypto.loadOrCreateKeyStore +import net.corda.nodeapi.internal.crypto.save import java.nio.file.Path import java.security.Key import java.security.KeyPair @@ -27,7 +29,6 @@ import java.security.PrivateKey import java.security.cert.Certificate import java.security.cert.X509Certificate -data class CertificateNameAndPass(val certificateName: String, val privateKeyPassword: String) /** * Encapsulates logic for key and certificate generation. * @@ -37,7 +38,7 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) { val logger = contextLogger() } - fun generate(provider: CryptoServerProvider) { + fun generate(provider: CryptoServerProvider, rootProvider: CryptoServerProvider? = null) { parameters.run { require(trustStoreDirectory.isDirectory()) { "trustStoreDirectory must point to a directory." } val keyName = when (certConfig.certificateType) { @@ -48,10 +49,11 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) { } val keyStore = getAndInitializeKeyStore(provider) val keyPair = certConfig.generateEcdsaKeyPair(keyName, provider, keyStore) - val certChain = if (certConfig.certificateType == ROOT_CA) { + val certChain = if (rootProvider == null) { certConfig.generateRootCert(provider, keyPair, trustStoreDirectory, trustStorePassword) } else { - certConfig.generateIntermediateCert(provider, keyPair, keyStore) + val rootKeyStore = getAndInitializeKeyStore(rootProvider) + certConfig.generateIntermediateCert(rootProvider, keyPair, rootKeyStore) } keyStore.addOrReplaceKey(keyName, keyPair.private, null, certChain) logger.info("New certificate and key pair named $keyName have been generated and stored in HSM") @@ -77,12 +79,13 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) { provider, crlDistributionUrl, crlIssuer).certificate - val networkRootTruststorePath = networkRootTrustStoreDirectory / NETWORK_ROOT_TRUSTSTORE_FILENAME - val networkRootTruststore = loadOrCreateKeyStore(networkRootTruststorePath, networkRootTrustStorePassword) - logger.info("Trust store for distribution to nodes created in $networkRootTruststorePath") - networkRootTruststore.addOrReplaceCertificate(CORDA_ROOT_CA, certificate) - logger.info("Certificate $CORDA_ROOT_CA has been added to $networkRootTruststorePath") - networkRootTruststore.save(networkRootTruststorePath, networkRootTrustStorePassword) + logger.info("Certificate for $subject created.") + val trustStorePath = networkRootTrustStoreDirectory / "truststore.jks" + val trustStore = loadOrCreateKeyStore(trustStorePath, networkRootTrustStorePassword) + logger.info("Trust store for distribution to nodes created in $trustStore") + trustStore.addOrReplaceCertificate(CORDA_ROOT_CA, certificate) + logger.info("Certificate $CORDA_ROOT_CA has been added to $trustStore") + trustStore.save(trustStorePath, networkRootTrustStorePassword) logger.info("Trust store has been persisted. Ready for distribution.") return arrayOf(certificate) } @@ -90,8 +93,10 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) { private fun CertificateConfiguration.generateIntermediateCert( provider: CryptoServerProvider, keyPair: KeyPair, - keyStore: KeyStore): Array { - val rootKeysAndCertChain = retrieveKeysAndCertificateChain(CORDA_ROOT_CA, keyStore) + rootKeyStore: KeyStore): Array { + logger.info("Retrieving the root key pair.") + val rootKeysAndCertChain = retrieveKeysAndCertificateChain(CORDA_ROOT_CA, + rootKeyStore) val certificateAndKeyPair = createIntermediateCert( certificateType, CordaX500Name.parse(subject).x500Name, @@ -101,6 +106,7 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) { provider, crlDistributionUrl, crlIssuer) + logger.info("Certificate for $subject created.") return arrayOf(certificateAndKeyPair.certificate, *rootKeysAndCertChain.certificateChain) } @@ -114,8 +120,9 @@ class KeyCertificateGenerator(private val parameters: GeneratorParameters) { name = keyName setCurve(keyCurve) } - logger.info("Generating key $keyName") + logger.info("Generating key $keyName.") provider.cryptoServer.generateKey(keyOverride, keyAttributes, keyGenMechanism) + logger.info("$keyName key generated.") } private fun CertificateConfiguration.generateEcdsaKeyPair(keyName: String, provider: CryptoServerProvider, keyStore: KeyStore): KeyPair { diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/Main.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/Main.kt index 61dbc9d732..28804146c0 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/Main.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/generator/Main.kt @@ -2,24 +2,40 @@ package com.r3.corda.networkmanage.hsm.generator import com.r3.corda.networkmanage.hsm.authentication.CryptoServerProviderConfig import com.r3.corda.networkmanage.hsm.utils.mapCryptoServerException +import net.corda.nodeapi.internal.crypto.CertificateType.ROOT_CA import org.apache.logging.log4j.LogManager -import java.nio.file.Paths private val log = LogManager.getLogger("com.r3.corda.networkmanage.hsm.generator.Main") fun main(args: Array) { - val commandLineOptions = parseCommandLine(*args) - parseParameters(commandLineOptions.configFile).run { + run(parseParameters(parseCommandLine(*args).configFile)) +} + +fun run(parameters: GeneratorParameters) { + parameters.run { val providerConfig = CryptoServerProviderConfig( Device = "$hsmPort@$hsmHost", KeySpecifier = certConfig.keySpecifier, KeyGroup = certConfig.keyGroup, StoreKeysExternal = certConfig.storeKeysExternal) try { - val authenticator = AutoAuthenticator(providerConfig, userConfigs) - authenticator.connectAndAuthenticate { provider -> + AutoAuthenticator(providerConfig, userConfigs).connectAndAuthenticate { provider -> val generator = KeyCertificateGenerator(this) - generator.generate(provider) + if (certConfig.certificateType == ROOT_CA) { + generator.generate(provider) + } else { + requireNotNull(certConfig.rootKeyGroup) + val rootProviderConfig = CryptoServerProviderConfig( + Device = "$hsmPort@$hsmHost", + KeySpecifier = certConfig.keySpecifier, + KeyGroup = certConfig.rootKeyGroup!!, + StoreKeysExternal = certConfig.storeKeysExternal) + AutoAuthenticator(rootProviderConfig, userConfigs).connectAndAuthenticate { rootProvider -> + generator.generate(provider, rootProvider) + rootProvider.logoff() + } + } + provider.logoff() } } catch (e: Exception) { log.error(mapCryptoServerException(e)) diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmCsrSigner.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmCsrSigner.kt index 13f6d465e7..e0580bb629 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmCsrSigner.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmCsrSigner.kt @@ -14,7 +14,6 @@ import net.corda.nodeapi.internal.crypto.CertificateType */ class HsmCsrSigner(private val storage: SignedCertificateRequestStorage, private val intermediateCertAlias: String, - private val intermediateCertPrivateKeyPass: String?, private val csrCertCrlDistPoint: String, private val csrCertCrlIssuer: String?, private val rootCertAlias: String, @@ -32,22 +31,22 @@ class HsmCsrSigner(private val storage: SignedCertificateRequestStorage, * @param toSign list of approved certificates to be signed */ override fun sign(toSign: List) { - authenticator.connectAndAuthenticate { provider, signers -> - val keyStore = getAndInitializeKeyStore(provider) + authenticator.connectAndAuthenticate { provider, rootProvider, signers -> + val rootKeyStore = getAndInitializeKeyStore(rootProvider!!) // 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 = keyStore.getCertificate(rootCertAlias) - val intermediatePrivateKeyPass = intermediateCertPrivateKeyPass ?: authenticator.readPassword("CA Private Key Password: ") - val intermediateCertAndKey = retrieveCertificateAndKeys(intermediateCertAlias, intermediatePrivateKeyPass, keyStore) + val rootCert = rootKeyStore.getCertificate(rootCertAlias) + val keyStore = getAndInitializeKeyStore(provider) + val doormanCertAndKey = retrieveCertificateAndKeys(intermediateCertAlias, keyStore) toSign.forEach { it.certPath = buildCertPath(createClientCertificate( CertificateType.NODE_CA, - intermediateCertAndKey, + doormanCertAndKey, it.request, validDays, provider, csrCertCrlDistPoint, - csrCertCrlIssuer), rootCert) + csrCertCrlIssuer), doormanCertAndKey.certificate, rootCert) } storage.store(toSign, signers) println("The following certificates have been signed by $signers:") diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmNetworkMapSigner.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmNetworkMapSigner.kt index 3cf98d681e..a165f1492a 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmNetworkMapSigner.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/signer/HsmNetworkMapSigner.kt @@ -15,18 +15,17 @@ import java.security.Signature * Signer which connects to a HSM using the given [authenticator] to sign bytes. */ // TODO Rename this to HsmSigner -class HsmNetworkMapSigner(private val privateKeyPassword: String, - private val authenticator: Authenticator) : Signer { +class HsmNetworkMapSigner(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 // when used with the given provider. - val key = keyStore.getKey(CORDA_NETWORK_MAP, privateKeyPassword.toCharArray()) as PrivateKey + val key = keyStore.getKey(CORDA_NETWORK_MAP, null) as PrivateKey val signature = Signature.getInstance(HsmX509Utilities.SIGNATURE_ALGORITHM, provider).run { initSign(key) update(data) diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/utils/HsmX509Utilities.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/utils/HsmX509Utilities.kt index 3702ae43dd..32a155a331 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/utils/HsmX509Utilities.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/hsm/utils/HsmX509Utilities.kt @@ -101,12 +101,11 @@ object HsmX509Utilities { * Retrieves a certificate and keys from the given key store. Also, the keys retrieved are cleaned in a sense of the * [getCleanEcdsaKeyPair] method. * @param certificateKeyName certificate and key name (alias) to be used when querying the key store. - * @param privateKeyPassword password for the private key. * @param keyStore key store that holds the certificate with its keys. * @return instance of [CertificateAndKeyPair] holding the retrieved certificate with its keys. */ - fun retrieveCertificateAndKeys(certificateKeyName: String, privateKeyPassword: String, keyStore: KeyStore): CertificateAndKeyPair { - val privateKey = keyStore.getKey(certificateKeyName, privateKeyPassword.toCharArray()) as PrivateKey + fun retrieveCertificateAndKeys(certificateKeyName: String, keyStore: KeyStore): CertificateAndKeyPair { + val privateKey = keyStore.getKey(certificateKeyName, null) as PrivateKey val publicKey = keyStore.getCertificate(certificateKeyName).publicKey val certificate = keyStore.getX509Certificate(certificateKeyName) return CertificateAndKeyPair(certificate, getCleanEcdsaKeyPair(publicKey, privateKey)) diff --git a/network-management/src/main/resources/hsm.conf b/network-management/src/main/resources/hsm.conf deleted file mode 100644 index aa82cd030b..0000000000 --- a/network-management/src/main/resources/hsm.conf +++ /dev/null @@ -1,17 +0,0 @@ -device = "3001@127.0.0.1" -keyGroup = "*" -keySpecifier = -1 -authMode = PASSWORD -csrPrivateKeyPassword = "" -networkMapPrivateKeyPassword = "" -rootPrivateKeyPassword = "" -keyGroup = "DEV.DOORMAN" -validDays = 3650 - -h2port = 0 -dataSourceProperties { - "dataSourceClassName" = org.h2.jdbcx.JdbcDataSource - "dataSource.url" = "jdbc:h2:file:"${basedir}"/persistence;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;WRITE_DELAY=0;AUTO_SERVER_PORT="${h2port} - "dataSource.user" = sa - "dataSource.password" = "" -} diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/hsm/authentication/AuthenticatorTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/hsm/authentication/AuthenticatorTest.kt index bb920779f9..42b222814e 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/hsm/authentication/AuthenticatorTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/hsm/authentication/AuthenticatorTest.kt @@ -28,7 +28,7 @@ class AuthenticatorTest : TestBase() { // when assertFailsWith { - 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) diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/hsm/configuration/ConfigurationTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/hsm/configuration/ConfigurationTest.kt index 2da083f760..e9a9f81ad8 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/hsm/configuration/ConfigurationTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/hsm/configuration/ConfigurationTest.kt @@ -10,7 +10,7 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class ConfigurationTest : TestBase() { - private val validConfigPath = File(javaClass.getResource("/hsm.conf").toURI()).absolutePath + private val validConfigPath = File("./hsm.conf").absolutePath private val invalidConfigPath = File(javaClass.getResource("/hsm_fail.conf").toURI()).absolutePath @Test diff --git a/network-management/src/test/resources/hsm.conf b/network-management/src/test/resources/hsm.conf deleted file mode 100644 index def056018f..0000000000 --- a/network-management/src/test/resources/hsm.conf +++ /dev/null @@ -1,18 +0,0 @@ -device = "3001@192.168.0.1" -keyGroup = "DEV.DOORMAN" -keySpecifier = -1 -authMode = PASSWORD -csrPrivateKeyPassword = "" -csrCertCrlDistPoint = "http://test.com/revoked.crl" -networkMapPrivateKeyPassword = "" -rootPrivateKeyPassword = "" -keyGroup = "DEV.DOORMAN" -validDays = 3650 - -h2port = 0 -dataSourceProperties { - "dataSourceClassName" = org.h2.jdbcx.JdbcDataSource - "dataSource.url" = "jdbc:h2:file:"${basedir}"/persistence;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;WRITE_DELAY=0;AUTO_SERVER_PORT="${h2port} - "dataSource.user" = sa - "dataSource.password" = "" -} \ No newline at end of file