mirror of
https://github.com/corda/corda.git
synced 2024-12-28 08:48:57 +00:00
Doorman generates trust store file, containing the root cert, instead of the .pem file (#241)
This commit is contained in:
parent
269a4ba79d
commit
2a0eefd351
@ -9,7 +9,7 @@ To build a fat jar containing all the doorman code you can simply invoke:
|
|||||||
|
|
||||||
The built file will appear in:
|
The built file will appear in:
|
||||||
```
|
```
|
||||||
network-management/capsule/build/libs/doorman-<VERSION>.jar
|
network-management/capsule/build/libs/doorman-<version>.jar
|
||||||
```
|
```
|
||||||
## HSM signing server
|
## HSM signing server
|
||||||
To build a fat jar containing all the HSM signer code you can simply invoke:
|
To build a fat jar containing all the HSM signer code you can simply invoke:
|
||||||
@ -19,7 +19,7 @@ To build a fat jar containing all the HSM signer code you can simply invoke:
|
|||||||
|
|
||||||
The built file will appear in:
|
The built file will appear in:
|
||||||
```
|
```
|
||||||
network-management/capsule-hsm/build/libs/hsm-<VERSION>.jar
|
network-management/capsule-hsm/build/libs/hsm-<version>.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
The binaries can also be obtained from artifactory after deployment in TeamCity.
|
The binaries can also be obtained from artifactory after deployment in TeamCity.
|
||||||
@ -28,12 +28,13 @@ To run the HSM signing server:
|
|||||||
|
|
||||||
```
|
```
|
||||||
cd network-management
|
cd network-management
|
||||||
java -jar capsule-hsm/build/libs/hsm-3.0-NETWORKMAP-20171204.134345-6.jar --configFile hsm.conf
|
java -jar capsule-hsm/build/libs/hsm-<version>.jar --configFile hsm.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
For a list of options the HSM signing server takes, run with the `--help` option:
|
For a list of options the HSM signing server takes, run with the `--help` option:
|
||||||
|
```
|
||||||
java -jar capsule-hsm/build/libs/hsm-3.0-NETWORKMAP-20171204.134345-6.jar --help
|
java -jar capsule-hsm/build/libs/hsm-3.0-<version>.jar --help
|
||||||
|
```
|
||||||
|
|
||||||
#Configuring network management service
|
#Configuring network management service
|
||||||
### Local signing
|
### Local signing
|
||||||
@ -143,8 +144,9 @@ networkMapConfig {
|
|||||||
java -jar doorman-<version>.jar --mode CA_KEYGEN
|
java -jar doorman-<version>.jar --mode CA_KEYGEN
|
||||||
```
|
```
|
||||||
|
|
||||||
A root certificate `pem` file will also be created, this will be distributed to the client via a "out-of-band" process.
|
A trust store file containing the root trust certificate will be produced in the location `distribute-nodes / truststore.jks`
|
||||||
Note: We will be distributing a trust store instead of the pem file in future updates.
|
(relative to `rootStorePath`). `truststore.jks` must be copied to the `certificates` directory of each node before
|
||||||
|
they attempt to register. The trust store password is `trustpass`.
|
||||||
|
|
||||||
### 2. Start Doorman service for notary registration
|
### 2. Start Doorman service for notary registration
|
||||||
Start the network management server with the doorman service for initial bootstrapping. Network map service should be disabled at this point.
|
Start the network management server with the doorman service for initial bootstrapping. Network map service should be disabled at this point.
|
||||||
@ -154,11 +156,11 @@ networkMapConfig {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 3. Create notary node and register with the doorman
|
### 3. Create notary node and register with the doorman
|
||||||
After the doorman service is started, copy the `rootcert.pem` file to the notaries' certificates folder and start the `initial-registration` process.
|
After the doorman service is started, start the notary node for the `initial-registration` process.
|
||||||
|
|
||||||
### 4. Add notary identities to the network parameter
|
### 4. Add notary identities to the network parameters
|
||||||
The network parameter should contain the name and public key of the newly created notaries.
|
The network parameters should contain the name and public key of the newly created notaries.
|
||||||
Example network parameter file:
|
Example network parameters file:
|
||||||
|
|
||||||
notaries : [{
|
notaries : [{
|
||||||
name: "O=Notary A, L=Port Louis, C=MU, OU=Org Unit, CN=Service Name"
|
name: "O=Notary A, L=Port Louis, C=MU, OU=Org Unit, CN=Service Name"
|
||||||
@ -173,11 +175,11 @@ networkMapConfig {
|
|||||||
maxMessageSize = 100
|
maxMessageSize = 100
|
||||||
maxTransactionSize = 100
|
maxTransactionSize = 100
|
||||||
|
|
||||||
Save the parameters to `parameter.conf`
|
Save the parameters to `network-parameters.conf`
|
||||||
|
|
||||||
### 5. Load initial network parameters file for network map service
|
### 5. Load initial network parameters file for network map service
|
||||||
A network parameters file is required to start the network map service for the first time. The initial network parameters file can be loaded using the `--update-network-parameter` flag.
|
A network parameters file is required to start the network map service for the first time. The initial network parameters file can be loaded using the `--update-network-parameter` flag.
|
||||||
We can now restart the network management server with both doorman and network map service.
|
We can now restart the network management server with both doorman and network map service.
|
||||||
```
|
```
|
||||||
java -jar doorman-<version>.jar --update-network-parameter parameter.conf
|
java -jar doorman-<version>.jar --update-network-parameter network-parameters.conf
|
||||||
```
|
```
|
@ -39,6 +39,7 @@ fun Array<out String>.toConfigWithOptions(registerOptions: OptionParser.() -> Un
|
|||||||
|
|
||||||
class ShowHelpException(val parser: OptionParser, val errorMessage: String? = null) : Exception()
|
class ShowHelpException(val parser: OptionParser, val errorMessage: String? = null) : Exception()
|
||||||
|
|
||||||
|
// TODO Remove this as we already have InternalUtils.cert
|
||||||
fun X509CertificateHolder.toX509Certificate(): X509Certificate = X509CertificateFactory().generateCertificate(encoded.inputStream())
|
fun X509CertificateHolder.toX509Certificate(): X509Certificate = X509CertificateFactory().generateCertificate(encoded.inputStream())
|
||||||
|
|
||||||
fun buildCertPath(vararg certificates: Certificate): CertPath = X509CertificateFactory().delegate.generateCertPath(certificates.asList())
|
fun buildCertPath(vararg certificates: Certificate): CertPath = X509CertificateFactory().delegate.generateCertPath(certificates.asList())
|
||||||
|
@ -34,7 +34,6 @@ data class NetworkManagementServerParameters(// TODO: Move local signing to sign
|
|||||||
val rootKeystorePassword: String?,
|
val rootKeystorePassword: String?,
|
||||||
// TODO Should be part of a localSigning sub-config
|
// TODO Should be part of a localSigning sub-config
|
||||||
val rootPrivateKeyPassword: String?
|
val rootPrivateKeyPassword: String?
|
||||||
|
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
// TODO: Do we really need these defaults?
|
// TODO: Do we really need these defaults?
|
||||||
@ -79,7 +78,6 @@ fun parseParameters(vararg args: String): NetworkManagementServerParameters {
|
|||||||
.describedAs("filepath")
|
.describedAs("filepath")
|
||||||
accepts("update-network-parameters", "Update network parameters filepath. Currently only network parameters initialisation is supported.")
|
accepts("update-network-parameters", "Update network parameters filepath. Currently only network parameters initialisation is supported.")
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
.describedAs("The new network map")
|
|
||||||
.describedAs("filepath")
|
.describedAs("filepath")
|
||||||
accepts("mode", "Set the mode of this application")
|
accepts("mode", "Set the mode of this application")
|
||||||
.withRequiredArg()
|
.withRequiredArg()
|
||||||
|
@ -5,7 +5,6 @@ import com.r3.corda.networkmanage.common.persistence.*
|
|||||||
import com.r3.corda.networkmanage.common.persistence.CertificationRequestStorage.Companion.DOORMAN_SIGNATURE
|
import com.r3.corda.networkmanage.common.persistence.CertificationRequestStorage.Companion.DOORMAN_SIGNATURE
|
||||||
import com.r3.corda.networkmanage.common.signer.NetworkMapSigner
|
import com.r3.corda.networkmanage.common.signer.NetworkMapSigner
|
||||||
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
import com.r3.corda.networkmanage.common.utils.ShowHelpException
|
||||||
import com.r3.corda.networkmanage.common.utils.toX509Certificate
|
|
||||||
import com.r3.corda.networkmanage.doorman.signer.DefaultCsrHandler
|
import com.r3.corda.networkmanage.doorman.signer.DefaultCsrHandler
|
||||||
import com.r3.corda.networkmanage.doorman.signer.JiraCsrHandler
|
import com.r3.corda.networkmanage.doorman.signer.JiraCsrHandler
|
||||||
import com.r3.corda.networkmanage.doorman.signer.LocalSigner
|
import com.r3.corda.networkmanage.doorman.signer.LocalSigner
|
||||||
@ -14,6 +13,7 @@ import com.r3.corda.networkmanage.doorman.webservice.NodeInfoWebService
|
|||||||
import com.r3.corda.networkmanage.doorman.webservice.RegistrationWebService
|
import com.r3.corda.networkmanage.doorman.webservice.RegistrationWebService
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.core.internal.cert
|
||||||
import net.corda.core.internal.createDirectories
|
import net.corda.core.internal.createDirectories
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
|
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
|
||||||
@ -169,52 +169,58 @@ internal fun readPassword(fmt: String): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Keygen utilities.
|
// Keygen utilities.
|
||||||
// TODO: Move keygen methods to Utilities.kt
|
fun generateRootKeyPair(rootStoreFile: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?) {
|
||||||
fun generateRootKeyPair(rootStorePath: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?) {
|
|
||||||
println("Generating Root CA keypair and certificate.")
|
println("Generating Root CA keypair and certificate.")
|
||||||
// Get password from console if not in config.
|
// Get password from console if not in config.
|
||||||
val rootKeystorePassword = rootKeystorePass ?: readPassword("Root Keystore Password: ")
|
val rootKeystorePassword = rootKeystorePass ?: readPassword("Root Keystore Password: ")
|
||||||
// Ensure folder exists.
|
// Ensure folder exists.
|
||||||
rootStorePath.parent.createDirectories()
|
rootStoreFile.parent.createDirectories()
|
||||||
val rootStore = loadOrCreateKeyStore(rootStorePath, rootKeystorePassword)
|
val rootStore = loadOrCreateKeyStore(rootStoreFile, rootKeystorePassword)
|
||||||
val rootPrivateKeyPassword = rootPrivateKeyPass ?: readPassword("Root Private Key Password: ")
|
val rootPrivateKeyPassword = rootPrivateKeyPass ?: readPassword("Root Private Key Password: ")
|
||||||
|
|
||||||
if (rootStore.containsAlias(X509Utilities.CORDA_ROOT_CA)) {
|
if (rootStore.containsAlias(X509Utilities.CORDA_ROOT_CA)) {
|
||||||
val oldKey = loadOrCreateKeyStore(rootStorePath, rootKeystorePassword).getCertificate(X509Utilities.CORDA_ROOT_CA).publicKey
|
val oldKey = loadOrCreateKeyStore(rootStoreFile, rootKeystorePassword).getCertificate(X509Utilities.CORDA_ROOT_CA).publicKey
|
||||||
println("Key ${X509Utilities.CORDA_ROOT_CA} already exists in keystore, process will now terminate.")
|
println("Key ${X509Utilities.CORDA_ROOT_CA} already exists in keystore, process will now terminate.")
|
||||||
println(oldKey)
|
println(oldKey)
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val selfSignKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
val selfSignKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||||
val selfSignCert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Root CA", organisation = "R3 Ltd", locality = "London", country = "GB", organisationUnit = "Corda", state = null), selfSignKey)
|
// TODO Make the cert subject configurable
|
||||||
|
val selfSignCert = X509Utilities.createSelfSignedCACertificate(
|
||||||
|
CordaX500Name(commonName = "Corda Root CA", organisation = "R3 Ltd", locality = "London", country = "GB", organisationUnit = "Corda", state = null),
|
||||||
|
selfSignKey).cert
|
||||||
rootStore.addOrReplaceKey(X509Utilities.CORDA_ROOT_CA, selfSignKey.private, rootPrivateKeyPassword.toCharArray(), arrayOf(selfSignCert))
|
rootStore.addOrReplaceKey(X509Utilities.CORDA_ROOT_CA, selfSignKey.private, rootPrivateKeyPassword.toCharArray(), arrayOf(selfSignCert))
|
||||||
rootStore.save(rootStorePath, rootKeystorePassword)
|
rootStore.save(rootStoreFile, rootKeystorePassword)
|
||||||
|
|
||||||
// TODO: remove this once we create truststore for nodes.
|
val nodeTrustStoreFile = (rootStoreFile.parent / "distribute-nodes").createDirectories() / "truststore.jks"
|
||||||
X509Utilities.saveCertificateAsPEMFile(selfSignCert.toX509Certificate(), rootStorePath.parent / "rootcert.pem")
|
// TODO The password for trust store must be a config option
|
||||||
|
val nodeTrustStore = loadOrCreateKeyStore(nodeTrustStoreFile, "trustpass")
|
||||||
|
nodeTrustStore.addOrReplaceCertificate(X509Utilities.CORDA_ROOT_CA, selfSignCert)
|
||||||
|
nodeTrustStore.save(nodeTrustStoreFile, "trustpass")
|
||||||
|
println("Trust store for distribution to nodes created in $nodeTrustStore")
|
||||||
|
|
||||||
println("Root CA keypair and certificate stored in ${rootStorePath.toAbsolutePath()}.")
|
println("Root CA keypair and certificate stored in ${rootStoreFile.toAbsolutePath()}.")
|
||||||
println(loadKeyStore(rootStorePath, rootKeystorePassword).getCertificate(X509Utilities.CORDA_ROOT_CA).publicKey)
|
println(loadKeyStore(rootStoreFile, rootKeystorePassword).getCertificate(X509Utilities.CORDA_ROOT_CA).publicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateCAKeyPair(keystorePath: Path, rootStorePath: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?, keystorePass: String?, caPrivateKeyPass: String?) {
|
fun generateCAKeyPair(keystoreFile: Path, rootStoreFile: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?, keystorePass: String?, caPrivateKeyPass: String?) {
|
||||||
println("Generating Intermediate CA keypair and certificate using root keystore $rootStorePath.")
|
println("Generating Intermediate CA keypair and certificate using root keystore $rootStoreFile.")
|
||||||
// Get password from console if not in config.
|
// Get password from console if not in config.
|
||||||
val rootKeystorePassword = rootKeystorePass ?: readPassword("Root Keystore Password: ")
|
val rootKeystorePassword = rootKeystorePass ?: readPassword("Root Keystore Password: ")
|
||||||
val rootPrivateKeyPassword = rootPrivateKeyPass ?: readPassword("Root Private Key Password: ")
|
val rootPrivateKeyPassword = rootPrivateKeyPass ?: readPassword("Root Private Key Password: ")
|
||||||
val rootKeyStore = loadKeyStore(rootStorePath, rootKeystorePassword)
|
val rootKeyStore = loadKeyStore(rootStoreFile, rootKeystorePassword)
|
||||||
|
|
||||||
val rootKeyAndCert = rootKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_ROOT_CA, rootPrivateKeyPassword)
|
val rootKeyAndCert = rootKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_ROOT_CA, rootPrivateKeyPassword)
|
||||||
|
|
||||||
val keystorePassword = keystorePass ?: readPassword("Keystore Password: ")
|
val keystorePassword = keystorePass ?: readPassword("Keystore Password: ")
|
||||||
val caPrivateKeyPassword = caPrivateKeyPass ?: readPassword("CA Private Key Password: ")
|
val caPrivateKeyPassword = caPrivateKeyPass ?: readPassword("CA Private Key Password: ")
|
||||||
// Ensure folder exists.
|
// Ensure folder exists.
|
||||||
keystorePath.parent.createDirectories()
|
keystoreFile.parent.createDirectories()
|
||||||
val keyStore = loadOrCreateKeyStore(keystorePath, keystorePassword)
|
val keyStore = loadOrCreateKeyStore(keystoreFile, keystorePassword)
|
||||||
|
|
||||||
if (keyStore.containsAlias(X509Utilities.CORDA_INTERMEDIATE_CA)) {
|
if (keyStore.containsAlias(X509Utilities.CORDA_INTERMEDIATE_CA)) {
|
||||||
val oldKey = loadOrCreateKeyStore(keystorePath, rootKeystorePassword).getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA).publicKey
|
val oldKey = loadOrCreateKeyStore(keystoreFile, rootKeystorePassword).getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA).publicKey
|
||||||
println("Key ${X509Utilities.CORDA_INTERMEDIATE_CA} already exists in keystore, process will now terminate.")
|
println("Key ${X509Utilities.CORDA_INTERMEDIATE_CA} already exists in keystore, process will now terminate.")
|
||||||
println(oldKey)
|
println(oldKey)
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
@ -225,9 +231,9 @@ fun generateCAKeyPair(keystorePath: Path, rootStorePath: Path, rootKeystorePass:
|
|||||||
CordaX500Name(commonName = "Corda Intermediate CA", organisation = "R3 Ltd", organisationUnit = "Corda", locality = "London", country = "GB", state = null), intermediateKey.public)
|
CordaX500Name(commonName = "Corda Intermediate CA", organisation = "R3 Ltd", organisationUnit = "Corda", locality = "London", country = "GB", state = null), intermediateKey.public)
|
||||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_INTERMEDIATE_CA, intermediateKey.private,
|
keyStore.addOrReplaceKey(X509Utilities.CORDA_INTERMEDIATE_CA, intermediateKey.private,
|
||||||
caPrivateKeyPassword.toCharArray(), arrayOf(intermediateCert, rootKeyAndCert.certificate))
|
caPrivateKeyPassword.toCharArray(), arrayOf(intermediateCert, rootKeyAndCert.certificate))
|
||||||
keyStore.save(keystorePath, keystorePassword)
|
keyStore.save(keystoreFile, keystorePassword)
|
||||||
println("Intermediate CA keypair and certificate stored in $keystorePath.")
|
println("Intermediate CA keypair and certificate stored in $keystoreFile.")
|
||||||
println(loadKeyStore(keystorePath, keystorePassword).getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA).publicKey)
|
println(loadKeyStore(keystoreFile, keystorePassword).getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA).publicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user