Skip to content

Commit 849d51c

Browse files
authored
INFRA-505: Move integration tests to unit tests (corda#6530)
1 parent 02b7184 commit 849d51c

File tree

5 files changed

+240
-134
lines changed

5 files changed

+240
-134
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,7 @@ virtualenv/
103103
# Files you may find useful to have in your working directory.
104104
PLAN
105105
NOTES
106-
TODO
106+
TODO
107+
108+
# gradle-dependx plugin
109+
.dependx/

node/src/integration-test/kotlin/net/corda/node/NodeKeystoreCheckTest.kt

-62
This file was deleted.

node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt

+3-71
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ import net.corda.node.services.api.VaultServiceInternal
9494
import net.corda.node.services.api.WritableTransactionStorage
9595
import net.corda.node.services.attachments.NodeAttachmentTrustCalculator
9696
import net.corda.node.services.config.NodeConfiguration
97-
import net.corda.node.services.config.configureWithDevSSLCertificate
9897
import net.corda.node.services.config.rpc.NodeRpcOptions
9998
import net.corda.node.services.config.shell.determineUnsafeUsers
10099
import net.corda.node.services.config.shell.toShellConfig
@@ -149,8 +148,6 @@ import net.corda.nodeapi.internal.cordapp.CordappLoader
149148
import net.corda.nodeapi.internal.crypto.CertificateType
150149
import net.corda.nodeapi.internal.crypto.X509Utilities
151150
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_CLIENT_CA
152-
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_CLIENT_TLS
153-
import net.corda.nodeapi.internal.crypto.X509Utilities.CORDA_ROOT_CA
154151
import net.corda.nodeapi.internal.crypto.X509Utilities.DEFAULT_VALIDITY_WINDOW
155152
import net.corda.nodeapi.internal.crypto.X509Utilities.DISTRIBUTED_NOTARY_COMPOSITE_KEY_ALIAS
156153
import net.corda.nodeapi.internal.crypto.X509Utilities.DISTRIBUTED_NOTARY_KEY_ALIAS
@@ -176,10 +173,8 @@ import org.jolokia.jvmagent.JolokiaServer
176173
import org.jolokia.jvmagent.JolokiaServerConfig
177174
import org.slf4j.Logger
178175
import rx.Scheduler
179-
import java.io.IOException
180176
import java.lang.reflect.InvocationTargetException
181177
import java.security.KeyPair
182-
import java.security.KeyStoreException
183178
import java.security.cert.X509Certificate
184179
import java.sql.Connection
185180
import java.sql.Savepoint
@@ -434,18 +429,6 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
434429
return proxies.fold(ops) { delegate, decorate -> decorate(delegate) }
435430
}
436431

437-
private fun initKeyStores(): X509Certificate {
438-
if (configuration.devMode) {
439-
configuration.configureWithDevSSLCertificate(cryptoService)
440-
// configureWithDevSSLCertificate is a devMode process that writes directly to keystore files, so
441-
// we should re-synchronise BCCryptoService with the updated keystore file.
442-
if (cryptoService is BCCryptoService) {
443-
cryptoService.resyncKeystore()
444-
}
445-
}
446-
return validateKeyStores()
447-
}
448-
449432
private fun quasarExcludePackages(nodeConfiguration: NodeConfiguration) {
450433
val quasarInstrumentor = Retransform.getInstrumentor()
451434

@@ -457,7 +440,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
457440
open fun generateAndSaveNodeInfo(): NodeInfo {
458441
check(started == null) { "Node has already been started" }
459442
log.info("Generating nodeInfo ...")
460-
val trustRoot = initKeyStores()
443+
val trustRoot = configuration.initKeyStores(cryptoService)
461444
startDatabase()
462445
val (identity, identityKeyPair) = obtainIdentity()
463446
val nodeCa = configuration.signingCertificateStore.get()[CORDA_CLIENT_CA]
@@ -497,7 +480,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
497480
logVendorString(database, log)
498481
if (allowHibernateToManageAppSchema) {
499482
Node.printBasicNodeInfo("Initialising CorDapps to get schemas created by hibernate")
500-
val trustRoot = initKeyStores()
483+
val trustRoot = configuration.initKeyStores(cryptoService)
501484
networkMapClient?.start(trustRoot)
502485
val (netParams, signedNetParams) = NetworkParametersReader(trustRoot, networkMapClient, configuration.baseDirectory).read()
503486
log.info("Loaded network parameters: $netParams")
@@ -536,7 +519,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
536519
nodeLifecycleEventsDistributor.distributeEvent(NodeLifecycleEvent.BeforeNodeStart(nodeServicesContext))
537520
log.info("Node starting up ...")
538521

539-
val trustRoot = initKeyStores()
522+
val trustRoot = configuration.initKeyStores(cryptoService)
540523
initialiseJolokia()
541524

542525
schemaService.mappedSchemasWarnings().forEach {
@@ -980,57 +963,6 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
980963
@VisibleForTesting
981964
protected open fun acceptableLiveFiberCountOnStop(): Int = 0
982965

983-
private fun getCertificateStores(): AllCertificateStores? {
984-
return try {
985-
// The following will throw IOException if key file not found or KeyStoreException if keystore password is incorrect.
986-
val sslKeyStore = configuration.p2pSslOptions.keyStore.get()
987-
val signingCertificateStore = configuration.signingCertificateStore.get()
988-
val trustStore = configuration.p2pSslOptions.trustStore.get()
989-
AllCertificateStores(trustStore, sslKeyStore, signingCertificateStore)
990-
} catch (e: IOException) {
991-
log.error("IO exception while trying to validate keystores and truststore", e)
992-
null
993-
}
994-
}
995-
996-
private data class AllCertificateStores(val trustStore: CertificateStore, val sslKeyStore: CertificateStore, val identitiesKeyStore: CertificateStore)
997-
998-
private fun validateKeyStores(): X509Certificate {
999-
// Step 1. Check trustStore, sslKeyStore and identitiesKeyStore exist.
1000-
val certStores = try {
1001-
requireNotNull(getCertificateStores()) {
1002-
"One or more keyStores (identity or TLS) or trustStore not found. " +
1003-
"Please either copy your existing keys and certificates from another node, " +
1004-
"or if you don't have one yet, fill out the config file and run corda.jar initial-registration."
1005-
}
1006-
} catch (e: KeyStoreException) {
1007-
throw IllegalArgumentException("At least one of the keystores or truststore passwords does not match configuration.")
1008-
}
1009-
// Step 2. Check that trustStore contains the correct key-alias entry.
1010-
require(CORDA_ROOT_CA in certStores.trustStore) {
1011-
"Alias for trustRoot key not found. Please ensure you have an updated trustStore file."
1012-
}
1013-
// Step 3. Check that tls keyStore contains the correct key-alias entry.
1014-
require(CORDA_CLIENT_TLS in certStores.sslKeyStore) {
1015-
"Alias for TLS key not found. Please ensure you have an updated TLS keyStore file."
1016-
}
1017-
1018-
// Step 4. Check that identity keyStores contain the correct key-alias entry for Node CA.
1019-
require(CORDA_CLIENT_CA in certStores.identitiesKeyStore) {
1020-
"Alias for Node CA key not found. Please ensure you have an updated identity keyStore file."
1021-
}
1022-
1023-
// Step 5. Check all cert paths chain to the trusted root.
1024-
val trustRoot = certStores.trustStore[CORDA_ROOT_CA]
1025-
val sslCertChainRoot = certStores.sslKeyStore.query { getCertificateChain(CORDA_CLIENT_TLS) }.last()
1026-
val nodeCaCertChainRoot = certStores.identitiesKeyStore.query { getCertificateChain(CORDA_CLIENT_CA) }.last()
1027-
1028-
require(sslCertChainRoot == trustRoot) { "TLS certificate must chain to the trusted root." }
1029-
require(nodeCaCertChainRoot == trustRoot) { "Client CA certificate must chain to the trusted root." }
1030-
1031-
return trustRoot
1032-
}
1033-
1034966
// Specific class so that MockNode can catch it.
1035967
class DatabaseConfigurationException(message: String) : CordaException(message)
1036968

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package net.corda.node.internal
2+
3+
import net.corda.core.utilities.loggerFor
4+
import net.corda.node.services.config.NodeConfiguration
5+
import net.corda.node.services.config.configureWithDevSSLCertificate
6+
import net.corda.nodeapi.internal.config.CertificateStore
7+
import net.corda.nodeapi.internal.crypto.X509Utilities
8+
import net.corda.nodeapi.internal.cryptoservice.CryptoService
9+
import net.corda.nodeapi.internal.cryptoservice.bouncycastle.BCCryptoService
10+
import java.io.IOException
11+
import java.security.KeyStoreException
12+
import java.security.cert.X509Certificate
13+
14+
private data class AllCertificateStores(val trustStore: CertificateStore, val sslKeyStore: CertificateStore, val identitiesKeyStore: CertificateStore)
15+
16+
17+
internal fun NodeConfiguration.initKeyStores(cryptoService: CryptoService): X509Certificate {
18+
if (devMode) {
19+
configureWithDevSSLCertificate(cryptoService)
20+
// configureWithDevSSLCertificate is a devMode process that writes directly to keystore files, so
21+
// we should re-synchronise BCCryptoService with the updated keystore file.
22+
if (cryptoService is BCCryptoService) {
23+
cryptoService.resyncKeystore()
24+
}
25+
}
26+
return validateKeyStores()
27+
}
28+
29+
private fun NodeConfiguration.validateKeyStores(): X509Certificate {
30+
// Step 1. Check trustStore, sslKeyStore and identitiesKeyStore exist.
31+
val certStores = try {
32+
requireNotNull(getCertificateStores()) {
33+
"One or more keyStores (identity or TLS) or trustStore not found. " +
34+
"Please either copy your existing keys and certificates from another node, " +
35+
"or if you don't have one yet, fill out the config file and run corda.jar initial-registration."
36+
}
37+
} catch (e: KeyStoreException) {
38+
throw IllegalArgumentException("At least one of the keystores or truststore passwords does not match configuration.")
39+
}
40+
// Step 2. Check that trustStore contains the correct key-alias entry.
41+
require(X509Utilities.CORDA_ROOT_CA in certStores.trustStore) {
42+
"Alias for trustRoot key not found. Please ensure you have an updated trustStore file."
43+
}
44+
// Step 3. Check that tls keyStore contains the correct key-alias entry.
45+
require(X509Utilities.CORDA_CLIENT_TLS in certStores.sslKeyStore) {
46+
"Alias for TLS key not found. Please ensure you have an updated TLS keyStore file."
47+
}
48+
49+
// Step 4. Check that identity keyStores contain the correct key-alias entry for Node CA.
50+
require(X509Utilities.CORDA_CLIENT_CA in certStores.identitiesKeyStore) {
51+
"Alias for Node CA key not found. Please ensure you have an updated identity keyStore file."
52+
}
53+
54+
// Step 5. Check all cert paths chain to the trusted root.
55+
val trustRoot = certStores.trustStore[X509Utilities.CORDA_ROOT_CA]
56+
val sslCertChainRoot = certStores.sslKeyStore.query { getCertificateChain(X509Utilities.CORDA_CLIENT_TLS) }.last()
57+
val nodeCaCertChainRoot = certStores.identitiesKeyStore.query { getCertificateChain(X509Utilities.CORDA_CLIENT_CA) }.last()
58+
59+
require(sslCertChainRoot == trustRoot) { "TLS certificate must chain to the trusted root." }
60+
require(nodeCaCertChainRoot == trustRoot) { "Client CA certificate must chain to the trusted root." }
61+
62+
return trustRoot
63+
}
64+
65+
private fun NodeConfiguration.getCertificateStores(): AllCertificateStores? {
66+
return try {
67+
// The following will throw IOException if key file not found or KeyStoreException if keystore password is incorrect.
68+
val sslKeyStore = p2pSslOptions.keyStore.get()
69+
val signingCertificateStore = signingCertificateStore.get()
70+
val trustStore = p2pSslOptions.trustStore.get()
71+
AllCertificateStores(trustStore, sslKeyStore, signingCertificateStore)
72+
} catch (e: IOException) {
73+
loggerFor<NodeConfiguration>().error("IO exception while trying to validate keystores and truststore", e)
74+
null
75+
}
76+
}

0 commit comments

Comments
 (0)