mirror of
https://github.com/corda/corda.git
synced 2024-12-27 00:21:12 +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:
|
||||
```
|
||||
network-management/capsule/build/libs/doorman-<VERSION>.jar
|
||||
network-management/capsule/build/libs/doorman-<version>.jar
|
||||
```
|
||||
## HSM signing server
|
||||
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:
|
||||
```
|
||||
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.
|
||||
@ -28,12 +28,13 @@ To run the HSM signing server:
|
||||
|
||||
```
|
||||
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:
|
||||
|
||||
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
|
||||
### Local signing
|
||||
@ -143,8 +144,9 @@ networkMapConfig {
|
||||
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.
|
||||
Note: We will be distributing a trust store instead of the pem file in future updates.
|
||||
A trust store file containing the root trust certificate will be produced in the location `distribute-nodes / truststore.jks`
|
||||
(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
|
||||
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
|
||||
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
|
||||
The network parameter should contain the name and public key of the newly created notaries.
|
||||
Example network parameter file:
|
||||
### 4. Add notary identities to the network parameters
|
||||
The network parameters should contain the name and public key of the newly created notaries.
|
||||
Example network parameters file:
|
||||
|
||||
notaries : [{
|
||||
name: "O=Notary A, L=Port Louis, C=MU, OU=Org Unit, CN=Service Name"
|
||||
@ -173,11 +175,11 @@ networkMapConfig {
|
||||
maxMessageSize = 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
|
||||
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.
|
||||
```
|
||||
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()
|
||||
|
||||
// TODO Remove this as we already have InternalUtils.cert
|
||||
fun X509CertificateHolder.toX509Certificate(): X509Certificate = X509CertificateFactory().generateCertificate(encoded.inputStream())
|
||||
|
||||
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?,
|
||||
// TODO Should be part of a localSigning sub-config
|
||||
val rootPrivateKeyPassword: String?
|
||||
|
||||
) {
|
||||
companion object {
|
||||
// TODO: Do we really need these defaults?
|
||||
@ -79,7 +78,6 @@ fun parseParameters(vararg args: String): NetworkManagementServerParameters {
|
||||
.describedAs("filepath")
|
||||
accepts("update-network-parameters", "Update network parameters filepath. Currently only network parameters initialisation is supported.")
|
||||
.withRequiredArg()
|
||||
.describedAs("The new network map")
|
||||
.describedAs("filepath")
|
||||
accepts("mode", "Set the mode of this application")
|
||||
.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.signer.NetworkMapSigner
|
||||
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.JiraCsrHandler
|
||||
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 net.corda.core.crypto.Crypto
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.cert
|
||||
import net.corda.core.internal.createDirectories
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.serialization.internal.SerializationEnvironmentImpl
|
||||
@ -169,52 +169,58 @@ internal fun readPassword(fmt: String): String {
|
||||
}
|
||||
|
||||
// Keygen utilities.
|
||||
// TODO: Move keygen methods to Utilities.kt
|
||||
fun generateRootKeyPair(rootStorePath: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?) {
|
||||
fun generateRootKeyPair(rootStoreFile: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?) {
|
||||
println("Generating Root CA keypair and certificate.")
|
||||
// Get password from console if not in config.
|
||||
val rootKeystorePassword = rootKeystorePass ?: readPassword("Root Keystore Password: ")
|
||||
// Ensure folder exists.
|
||||
rootStorePath.parent.createDirectories()
|
||||
val rootStore = loadOrCreateKeyStore(rootStorePath, rootKeystorePassword)
|
||||
rootStoreFile.parent.createDirectories()
|
||||
val rootStore = loadOrCreateKeyStore(rootStoreFile, rootKeystorePassword)
|
||||
val rootPrivateKeyPassword = rootPrivateKeyPass ?: readPassword("Root Private Key Password: ")
|
||||
|
||||
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(oldKey)
|
||||
exitProcess(1)
|
||||
}
|
||||
|
||||
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.save(rootStorePath, rootKeystorePassword)
|
||||
rootStore.save(rootStoreFile, rootKeystorePassword)
|
||||
|
||||
// TODO: remove this once we create truststore for nodes.
|
||||
X509Utilities.saveCertificateAsPEMFile(selfSignCert.toX509Certificate(), rootStorePath.parent / "rootcert.pem")
|
||||
val nodeTrustStoreFile = (rootStoreFile.parent / "distribute-nodes").createDirectories() / "truststore.jks"
|
||||
// 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(loadKeyStore(rootStorePath, rootKeystorePassword).getCertificate(X509Utilities.CORDA_ROOT_CA).publicKey)
|
||||
println("Root CA keypair and certificate stored in ${rootStoreFile.toAbsolutePath()}.")
|
||||
println(loadKeyStore(rootStoreFile, rootKeystorePassword).getCertificate(X509Utilities.CORDA_ROOT_CA).publicKey)
|
||||
}
|
||||
|
||||
fun generateCAKeyPair(keystorePath: Path, rootStorePath: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?, keystorePass: String?, caPrivateKeyPass: String?) {
|
||||
println("Generating Intermediate CA keypair and certificate using root keystore $rootStorePath.")
|
||||
fun generateCAKeyPair(keystoreFile: Path, rootStoreFile: Path, rootKeystorePass: String?, rootPrivateKeyPass: String?, keystorePass: String?, caPrivateKeyPass: String?) {
|
||||
println("Generating Intermediate CA keypair and certificate using root keystore $rootStoreFile.")
|
||||
// Get password from console if not in config.
|
||||
val rootKeystorePassword = rootKeystorePass ?: readPassword("Root Keystore 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 keystorePassword = keystorePass ?: readPassword("Keystore Password: ")
|
||||
val caPrivateKeyPassword = caPrivateKeyPass ?: readPassword("CA Private Key Password: ")
|
||||
// Ensure folder exists.
|
||||
keystorePath.parent.createDirectories()
|
||||
val keyStore = loadOrCreateKeyStore(keystorePath, keystorePassword)
|
||||
keystoreFile.parent.createDirectories()
|
||||
val keyStore = loadOrCreateKeyStore(keystoreFile, keystorePassword)
|
||||
|
||||
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(oldKey)
|
||||
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)
|
||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_INTERMEDIATE_CA, intermediateKey.private,
|
||||
caPrivateKeyPassword.toCharArray(), arrayOf(intermediateCert, rootKeyAndCert.certificate))
|
||||
keyStore.save(keystorePath, keystorePassword)
|
||||
println("Intermediate CA keypair and certificate stored in $keystorePath.")
|
||||
println(loadKeyStore(keystorePath, keystorePassword).getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA).publicKey)
|
||||
keyStore.save(keystoreFile, keystorePassword)
|
||||
println("Intermediate CA keypair and certificate stored in $keystoreFile.")
|
||||
println(loadKeyStore(keystoreFile, keystorePassword).getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA).publicKey)
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user