diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 4471dd86d8..35e599ce38 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -23,6 +23,8 @@ + + diff --git a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/doorman/DoormanIntegrationTest.kt b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/doorman/DoormanIntegrationTest.kt index fe7633cfa6..fe919f6114 100644 --- a/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/doorman/DoormanIntegrationTest.kt +++ b/network-management/src/integration-test/kotlin/com/r3/corda/networkmanage/doorman/DoormanIntegrationTest.kt @@ -8,7 +8,6 @@ import com.r3.corda.networkmanage.common.utils.toX509Certificate import com.r3.corda.networkmanage.doorman.signer.LocalSigner import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash -import net.corda.core.crypto.SignedData import net.corda.core.crypto.sign import net.corda.core.identity.CordaX500Name import net.corda.core.identity.PartyAndCertificate @@ -97,7 +96,6 @@ class DoormanIntegrationTest { doorman.close() } - @Ignore @Test fun `nodeInfo is published to the network map`() { // Given @@ -149,7 +147,6 @@ class DoormanIntegrationTest { doReturn(it.certificatesDirectory / "sslkeystore.jks").whenever(it).sslKeystore doReturn("trustpass").whenever(it).trustStorePassword doReturn("cordacadevpass").whenever(it).keyStorePassword -// doReturn(URL("http://${doormanHostAndPort.host}:${doormanHostAndPort.port}")).whenever(it).compatibilityZoneURL doReturn("iTest@R3.com").whenever(it).emailAddress } } diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/NodeInfoStorage.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/NodeInfoStorage.kt index d64dd092e9..3f44d27df0 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/NodeInfoStorage.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/NodeInfoStorage.kt @@ -3,6 +3,7 @@ package com.r3.corda.networkmanage.common.persistence import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SignedData import net.corda.core.node.NodeInfo +import net.corda.nodeapi.internal.SignedNodeInfo import java.security.cert.CertPath /** @@ -19,12 +20,12 @@ interface NodeInfoStorage { * Retrieve node info together with its signature using nodeInfo's hash * @return [NodeInfo] or null if the node info is not registered. */ - fun getNodeInfo(nodeInfoHash: SecureHash): SignedData? + fun getNodeInfo(nodeInfoHash: SecureHash): SignedNodeInfo? /** * The [nodeInfo] is keyed by the public key, old node info with the same public key will be replaced by the new node info. * @param signedNodeInfo signed node info data to be stored * @return hash for the newly created node info entry */ - fun putNodeInfo(signedNodeInfo: SignedData): SecureHash + fun putNodeInfo(signedNodeInfo: SignedNodeInfo): SecureHash } \ No newline at end of file diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentNodeInfoStorage.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentNodeInfoStorage.kt index e1685b678a..7f1d331877 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentNodeInfoStorage.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/PersistentNodeInfoStorage.kt @@ -1,15 +1,13 @@ package com.r3.corda.networkmanage.common.persistence -import com.r3.corda.networkmanage.common.persistence.entity.CertificateDataEntity -import com.r3.corda.networkmanage.common.persistence.entity.CertificateSigningRequestEntity -import com.r3.corda.networkmanage.common.persistence.entity.NodeInfoEntity +import com.r3.corda.networkmanage.common.persistence.entity.* import com.r3.corda.networkmanage.common.utils.buildCertPath import net.corda.core.crypto.SecureHash -import net.corda.core.crypto.SignedData import net.corda.core.crypto.sha256 import net.corda.core.identity.CordaX500Name -import net.corda.core.node.NodeInfo import net.corda.core.serialization.SerializedBytes +import net.corda.core.serialization.serialize +import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.nodeapi.internal.persistence.TransactionIsolationLevel import java.security.cert.CertPath @@ -19,7 +17,7 @@ import java.security.cert.X509Certificate * Database implementation of the [NetworkMapStorage] interface */ class PersistentNodeInfoStorage(private val database: CordaPersistence) : NodeInfoStorage { - override fun putNodeInfo(signedNodeInfo: SignedData): SecureHash = database.transaction(TransactionIsolationLevel.SERIALIZABLE) { + override fun putNodeInfo(signedNodeInfo: SignedNodeInfo): SecureHash = database.transaction(TransactionIsolationLevel.SERIALIZABLE) { val nodeInfo = signedNodeInfo.verified() val orgName = nodeInfo.legalIdentities.first().name.organisation // TODO: use cert extension to identify NodeCA cert when Ross's work is in. @@ -45,23 +43,23 @@ class PersistentNodeInfoStorage(private val database: CordaPersistence) : NodeIn builder.equal(path.get(NodeInfoEntity::certificateSigningRequest.name), request.certificateSigningRequest) } val hash = signedNodeInfo.raw.hash + val hashedNodeInfo = NodeInfoEntity( nodeInfoHash = hash.toString(), certificateSigningRequest = request.certificateSigningRequest, - nodeInfoBytes = signedNodeInfo.raw.bytes, - signatureBytes = signedNodeInfo.sig.bytes, - signaturePublicKeyBytes = signedNodeInfo.sig.by.encoded, - signaturePublicKeyAlgorithm = signedNodeInfo.sig.by.algorithm) + signedNodeInfoBytes = signedNodeInfo.serialize().bytes) session.save(hashedNodeInfo) hash } - override fun getNodeInfo(nodeInfoHash: SecureHash): SignedData? = database.transaction { - val nodeInfoEntity = session.find(NodeInfoEntity::class.java, nodeInfoHash.toString()) - if (nodeInfoEntity?.signatureBytes == null) { - null - } else { - SignedData(SerializedBytes(nodeInfoEntity.nodeInfoBytes), nodeInfoEntity.signature()!!) + override fun getNodeInfo(nodeInfoHash: SecureHash): SignedNodeInfo? { + return database.transaction { + val nodeInfoEntity = session.find(NodeInfoEntity::class.java, nodeInfoHash.toString()) + if (nodeInfoEntity == null) { + null + } else { + nodeInfoEntity.signedNodeInfo() + } } } diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/entity/NodeInfoEntity.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/entity/NodeInfoEntity.kt index 78e450aea9..140ef08585 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/entity/NodeInfoEntity.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/persistence/entity/NodeInfoEntity.kt @@ -1,15 +1,13 @@ package com.r3.corda.networkmanage.common.persistence.entity -import net.corda.core.crypto.DigitalSignature -import net.corda.core.node.NodeInfo import net.corda.core.serialization.deserialize -import java.security.KeyFactory -import java.security.spec.X509EncodedKeySpec +import net.corda.nodeapi.internal.SignedNodeInfo import javax.persistence.* @Entity @Table(name = "node_info") class NodeInfoEntity( + // Hash of serialized [NodeInfo] without signatures. @Id @Column(name = "node_info_hash", length = 64) val nodeInfoHash: String = "", @@ -19,53 +17,22 @@ class NodeInfoEntity( val certificateSigningRequest: CertificateSigningRequestEntity? = null, @Lob - @Column(name = "node_info_bytes") - val nodeInfoBytes: ByteArray, - - @Lob - @Column(name = "signature_bytes", nullable = true) - val signatureBytes: ByteArray? = null, - - @Lob - @Column(name = "signature_public_key_bytes", nullable = true) - val signaturePublicKeyBytes: ByteArray? = null, - - @Lob - @Column(name = "signature_public_key_algorithm", nullable = true) - val signaturePublicKeyAlgorithm: String? = null + @Column(name = "signed_node_info_bytes") + val signedNodeInfoBytes: ByteArray ) { /** - * Deserializes NodeInfoEntity.nodeInfoBytes into the [NodeInfo] instance + * Deserializes NodeInfoEntity.soignedNodeInfoBytes into the [SignedNodeInfo] instance */ - fun nodeInfo() = nodeInfoBytes.deserialize() - - /** - * Deserializes NodeInfoEntity.signatureBytes into the [DigitalSignature.WithKey] instance together with its public key - */ - fun signature(): DigitalSignature.WithKey? { - return if (signatureBytes != null && signaturePublicKeyBytes != null && !signaturePublicKeyAlgorithm.isNullOrEmpty()) { - DigitalSignature.WithKey(KeyFactory.getInstance(signaturePublicKeyAlgorithm).generatePublic(X509EncodedKeySpec(signaturePublicKeyBytes)), signatureBytes) - } else { - null - } - } + fun signedNodeInfo() = signedNodeInfoBytes.deserialize() fun copy(nodeInfoHash: String = this.nodeInfoHash, certificateSigningRequest: CertificateSigningRequestEntity? = this.certificateSigningRequest, - nodeInfoBytes: ByteArray = this.nodeInfoBytes, - signatureBytes: ByteArray? = this.signatureBytes, - signaturePublicKeyBytes: ByteArray? = this.signaturePublicKeyBytes, - signaturePublicKeyAlgorithm: String? = this.signaturePublicKeyAlgorithm + signedNodeInfoBytes: ByteArray = this.signedNodeInfoBytes ): NodeInfoEntity { return NodeInfoEntity( nodeInfoHash = nodeInfoHash, certificateSigningRequest = certificateSigningRequest, - nodeInfoBytes = nodeInfoBytes, - signatureBytes = signatureBytes, - signaturePublicKeyBytes = signaturePublicKeyBytes, - signaturePublicKeyAlgorithm = signaturePublicKeyAlgorithm + signedNodeInfoBytes = signedNodeInfoBytes ) } } - - diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/signer/NetworkMapSigner.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/signer/NetworkMapSigner.kt index b3913936b3..05f0111d42 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/signer/NetworkMapSigner.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/common/signer/NetworkMapSigner.kt @@ -15,6 +15,7 @@ class NetworkMapSigner(private val networkMapStorage: NetworkMapStorage, private val nodeInfoHashes = networkMapStorage.getNodeInfoHashes(CertificateStatus.VALID) val networkParameters = networkMapStorage.getLatestNetworkParameters() val networkMap = NetworkMap(nodeInfoHashes, networkParameters.serialize().hash) + // We wan only check if the data structure is same. if (networkMap != currentSignedNetworkMap?.verified(null)) { val digitalSignature = signer.sign(networkMap.serialize().bytes) val signedHashedNetworkMap = SignedNetworkMap(networkMap.serialize(), digitalSignature) diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/NetworkParametersConfiguration.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/NetworkParametersConfiguration.kt index 7186c4572e..65e1dc7c61 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/NetworkParametersConfiguration.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/NetworkParametersConfiguration.kt @@ -39,7 +39,6 @@ internal data class NotaryConfiguration(private val name: CordaX500Name, */ internal data class NetworkParametersConfiguration(val minimumPlatformVersion: Int, val notaries: List, - val eventHorizonDays: Int, val maxMessageSize: Int, val maxTransactionSize: Int) diff --git a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/webservice/NodeInfoWebService.kt b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/webservice/NodeInfoWebService.kt index 81b4249b33..3f6f339ed6 100644 --- a/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/webservice/NodeInfoWebService.kt +++ b/network-management/src/main/kotlin/com/r3/corda/networkmanage/doorman/webservice/NodeInfoWebService.kt @@ -12,6 +12,7 @@ import net.corda.core.crypto.SignedData import net.corda.core.node.NodeInfo import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize +import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.network.SignedNetworkMap import java.io.InputStream import java.security.InvalidKeyException @@ -44,7 +45,7 @@ class NodeInfoWebService(private val nodeInfoStorage: NodeInfoStorage, @Path("publish") @Consumes(MediaType.APPLICATION_OCTET_STREAM) fun registerNode(input: InputStream): Response { - val registrationData = input.readBytes().deserialize>() + val registrationData = input.readBytes().deserialize() return try { // Store the NodeInfo nodeInfoStorage.putNodeInfo(registrationData) diff --git a/network-management/src/main/resources/migration/network-manager.changelog-init.xml b/network-management/src/main/resources/migration/network-manager.changelog-init.xml index 87dee6bd37..31fa6acd1b 100644 --- a/network-management/src/main/resources/migration/network-manager.changelog-init.xml +++ b/network-management/src/main/resources/migration/network-manager.changelog-init.xml @@ -96,10 +96,7 @@ - - - - + diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/TestBase.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/TestBase.kt index 4b9c35f990..98e2ada703 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/TestBase.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/TestBase.kt @@ -6,14 +6,12 @@ import com.r3.corda.networkmanage.common.persistence.CertificateSigningRequest import com.r3.corda.networkmanage.common.persistence.CertificateStatus import com.r3.corda.networkmanage.common.persistence.RequestStatus import net.corda.core.crypto.SecureHash -import net.corda.core.utilities.seconds import net.corda.nodeapi.internal.network.NetworkParameters import net.corda.nodeapi.internal.network.NotaryInfo import net.corda.testing.SerializationEnvironmentRule import org.bouncycastle.pkcs.PKCS10CertificationRequest import org.junit.Rule import java.security.cert.CertPath -import java.time.Duration import java.time.Instant abstract class TestBase { @@ -54,9 +52,8 @@ abstract class TestBase { // TODO remove this once testNetworkParameters are updated with default parameters protected fun createNetworkParameters(minimumPlatformVersion: Int = 1, notaries: List = emptyList(), - eventHorizon: Duration = 1.seconds, - maxMessageSize: Int = 0, - maxTransactionSize: Int = 0, + maxMessageSize: Int = 10485760, + maxTransactionSize: Int = 40000, modifiedTime: Instant = Instant.now(), epoch: Int = 1): NetworkParameters { return NetworkParameters( diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/DBNetworkMapStorageTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/DBNetworkMapStorageTest.kt index 5e65e3d28a..062d4c5c5a 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/DBNetworkMapStorageTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/DBNetworkMapStorageTest.kt @@ -5,7 +5,6 @@ import com.r3.corda.networkmanage.common.utils.buildCertPath import com.r3.corda.networkmanage.common.utils.toX509Certificate import com.r3.corda.networkmanage.common.utils.withCert import net.corda.core.crypto.Crypto -import net.corda.core.crypto.SignedData import net.corda.core.crypto.sign import net.corda.core.identity.CordaX500Name import net.corda.core.identity.PartyAndCertificate @@ -13,6 +12,7 @@ import net.corda.core.internal.cert import net.corda.core.node.NodeInfo import net.corda.core.serialization.serialize import net.corda.core.utilities.NetworkHostAndPort +import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.crypto.CertificateType import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.network.NetworkMap @@ -64,7 +64,7 @@ class DBNetworkMapStorageTest : TestBase() { val nodeInfo = NodeInfo(listOf(NetworkHostAndPort("my.company.com", 1234)), listOf(PartyAndCertificate(certPath)), 1, serial = 1L) // Put signed node info data val nodeInfoBytes = nodeInfo.serialize() - val nodeInfoHash = nodeInfoStorage.putNodeInfo(SignedData(nodeInfoBytes, keyPair.sign(nodeInfoBytes))) + val nodeInfoHash = nodeInfoStorage.putNodeInfo(SignedNodeInfo(nodeInfoBytes, listOf(keyPair.sign(nodeInfoBytes)))) // Create network parameters val networkParametersHash = networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList())) @@ -131,15 +131,16 @@ class DBNetworkMapStorageTest : TestBase() { val requestIdA = requestStorage.saveRequest(createRequest(organisationA).first) requestStorage.markRequestTicketCreated(requestIdA) requestStorage.approveRequest(requestIdA, "TestUser") - val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val clientCertA = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisationA, locality = "London", country = "GB"), keyPair.public) + val keyPairA = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) + val clientCertA = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisationA, locality = "London", country = "GB"), keyPairA.public) val certPathA = buildCertPath(clientCertA.toX509Certificate(), intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) requestStorage.putCertificatePath(requestIdA, certPathA, emptyList()) val organisationB = "TestB" val requestIdB = requestStorage.saveRequest(createRequest(organisationB).first) requestStorage.markRequestTicketCreated(requestIdB) requestStorage.approveRequest(requestIdB, "TestUser") - val clientCertB = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisationB, locality = "London", country = "GB"), Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME).public) + val keyPairB = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) + val clientCertB = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisationB, locality = "London", country = "GB"), keyPairB.public) val certPathB = buildCertPath(clientCertB.toX509Certificate(), intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) requestStorage.putCertificatePath(requestIdB, certPathB, emptyList()) val nodeInfoA = NodeInfo(listOf(NetworkHostAndPort("my.companyA.com", 1234)), listOf(PartyAndCertificate(certPathA)), 1, serial = 1L) @@ -147,14 +148,14 @@ class DBNetworkMapStorageTest : TestBase() { // Put signed node info data val nodeInfoABytes = nodeInfoA.serialize() val nodeInfoBBytes = nodeInfoB.serialize() - val nodeInfoHashA = nodeInfoStorage.putNodeInfo(SignedData(nodeInfoABytes, keyPair.sign(nodeInfoABytes))) - val nodeInfoHashB = nodeInfoStorage.putNodeInfo(SignedData(nodeInfoBBytes, keyPair.sign(nodeInfoBBytes))) + val nodeInfoHashA = nodeInfoStorage.putNodeInfo(SignedNodeInfo(nodeInfoABytes, listOf(keyPairA.sign(nodeInfoABytes)))) + val nodeInfoHashB = nodeInfoStorage.putNodeInfo(SignedNodeInfo(nodeInfoBBytes, listOf(keyPairB.sign(nodeInfoBBytes)))) // Create network parameters val networkParametersHash = networkMapStorage.saveNetworkParameters(createNetworkParameters()) val networkMap = NetworkMap(listOf(nodeInfoHashA), networkParametersHash) val serializedNetworkMap = networkMap.serialize() - val signatureData = keyPair.sign(serializedNetworkMap).withCert(clientCertA.cert) + val signatureData = keyPairA.sign(serializedNetworkMap).withCert(clientCertA.cert) val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, signatureData) // Sign network map diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersitenceNodeInfoStorageTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersitenceNodeInfoStorageTest.kt index 017dc7e58f..1014cde074 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersitenceNodeInfoStorageTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/common/persistence/PersitenceNodeInfoStorageTest.kt @@ -6,17 +6,16 @@ import com.r3.corda.networkmanage.common.utils.hashString import com.r3.corda.networkmanage.common.utils.toX509Certificate import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash -import net.corda.core.crypto.SignedData import net.corda.core.crypto.sign import net.corda.core.identity.CordaX500Name import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.NodeInfo import net.corda.core.serialization.serialize import net.corda.core.utilities.NetworkHostAndPort +import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.crypto.CertificateType import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.persistence.CordaPersistence -import net.corda.nodeapi.internal.persistence.DatabaseConfig import net.corda.testing.node.MockServices import org.junit.After import org.junit.Before @@ -77,15 +76,16 @@ class PersitenceNodeInfoStorageTest : TestBase() { val requestIdA = requestStorage.saveRequest(createRequest(organisationA).first) requestStorage.markRequestTicketCreated(requestIdA) requestStorage.approveRequest(requestIdA, "TestUser") - val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val clientCertA = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisationA, locality = "London", country = "GB"), keyPair.public) + val keyPairA = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) + val clientCertA = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisationA, locality = "London", country = "GB"), keyPairA.public) val certPathA = buildCertPath(clientCertA.toX509Certificate(), intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) requestStorage.putCertificatePath(requestIdA, certPathA, emptyList()) val organisationB = "TestB" val requestIdB = requestStorage.saveRequest(createRequest(organisationB).first) requestStorage.markRequestTicketCreated(requestIdB) requestStorage.approveRequest(requestIdB, "TestUser") - val clientCertB = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisationB, locality = "London", country = "GB"), Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME).public) + val keyPairB = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) + val clientCertB = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisationB, locality = "London", country = "GB"), keyPairB.public) val certPathB = buildCertPath(clientCertB.toX509Certificate(), intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate()) requestStorage.putCertificatePath(requestIdB, certPathB, emptyList()) val nodeInfoA = NodeInfo(listOf(NetworkHostAndPort("my.company.com", 1234)), listOf(PartyAndCertificate(certPathA)), 1, serial = 1L) @@ -94,8 +94,8 @@ class PersitenceNodeInfoStorageTest : TestBase() { // Put signed node info data val nodeInfoABytes = nodeInfoA.serialize() val nodeInfoBBytes = nodeInfoB.serialize() - nodeInfoStorage.putNodeInfo(SignedData(nodeInfoABytes, keyPair.sign(nodeInfoABytes))) - nodeInfoStorage.putNodeInfo(SignedData(nodeInfoBBytes, keyPair.sign(nodeInfoBBytes))) + nodeInfoStorage.putNodeInfo(SignedNodeInfo(nodeInfoABytes, listOf(keyPairA.sign(nodeInfoABytes)))) + nodeInfoStorage.putNodeInfo(SignedNodeInfo(nodeInfoBBytes, listOf(keyPairB.sign(nodeInfoBBytes)))) // when val persistedNodeInfoA = nodeInfoStorage.getNodeInfo(nodeInfoABytes.hash) @@ -123,12 +123,12 @@ class PersitenceNodeInfoStorageTest : TestBase() { val nodeInfo = NodeInfo(listOf(NetworkHostAndPort("my.company.com", 1234)), listOf(PartyAndCertificate(certPath)), 1, serial = 1L) val nodeInfoSamePubKey = NodeInfo(listOf(NetworkHostAndPort("my.company2.com", 1234)), listOf(PartyAndCertificate(certPath)), 1, serial = 1L) val nodeInfoBytes = nodeInfo.serialize() - val nodeInfoHash = nodeInfoStorage.putNodeInfo(SignedData(nodeInfoBytes, keyPair.sign(nodeInfoBytes))) + val nodeInfoHash = nodeInfoStorage.putNodeInfo(SignedNodeInfo(nodeInfoBytes, listOf(keyPair.sign(nodeInfoBytes)))) assertEquals(nodeInfo, nodeInfoStorage.getNodeInfo(nodeInfoHash)?.verified()) val nodeInfoSamePubKeyBytes = nodeInfoSamePubKey.serialize() // This should replace the node info. - nodeInfoStorage.putNodeInfo(SignedData(nodeInfoSamePubKeyBytes, keyPair.sign(nodeInfoSamePubKeyBytes))) + nodeInfoStorage.putNodeInfo(SignedNodeInfo(nodeInfoSamePubKeyBytes, listOf(keyPair.sign(nodeInfoSamePubKeyBytes)))) // Old node info should be removed. assertNull(nodeInfoStorage.getNodeInfo(nodeInfoHash)) @@ -153,12 +153,12 @@ class PersitenceNodeInfoStorageTest : TestBase() { val signature = keyPair.sign(nodeInfoBytes) // when - val nodeInfoHash = nodeInfoStorage.putNodeInfo(SignedData(nodeInfoBytes, signature)) + val nodeInfoHash = nodeInfoStorage.putNodeInfo(SignedNodeInfo(nodeInfoBytes, listOf(signature))) // then val persistedNodeInfo = nodeInfoStorage.getNodeInfo(nodeInfoHash) assertNotNull(persistedNodeInfo) assertEquals(nodeInfo, persistedNodeInfo!!.verified()) - assertEquals(signature, persistedNodeInfo.sig) + assertEquals(signature, persistedNodeInfo.signatures.firstOrNull()) } } \ No newline at end of file diff --git a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/NodeInfoWebServiceTest.kt b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/NodeInfoWebServiceTest.kt index 856c15fdae..096a05534f 100644 --- a/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/NodeInfoWebServiceTest.kt +++ b/network-management/src/test/kotlin/com/r3/corda/networkmanage/doorman/NodeInfoWebServiceTest.kt @@ -19,6 +19,7 @@ import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.seconds +import net.corda.nodeapi.internal.SignedNodeInfo import net.corda.nodeapi.internal.crypto.CertificateType import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.network.NetworkMap @@ -64,7 +65,7 @@ class NodeInfoWebServiceTest { NetworkManagementWebServer(NetworkHostAndPort("localhost", 0), NodeInfoWebService(nodeInfoStorage, mock(), testNetwotkMapConfig)).use { it.start() val registerURL = URL("http://${it.hostAndPort}/${NodeInfoWebService.NETWORK_MAP_PATH}/publish") - val nodeInfoAndSignature = SignedData(nodeInfo.serialize(), digitalSignature).serialize().bytes + val nodeInfoAndSignature = SignedNodeInfo(nodeInfo.serialize(), listOf(digitalSignature)).serialize().bytes // Post node info and signature to doorman, this should pass without any exception. doPost(registerURL, nodeInfoAndSignature) } @@ -97,14 +98,14 @@ class NodeInfoWebServiceTest { val nodeInfoStorage: NodeInfoStorage = mock { val serializedNodeInfo = nodeInfo.serialize() - on { getNodeInfo(nodeInfoHash) }.thenReturn(SignedData(serializedNodeInfo, keyPair.sign(serializedNodeInfo))) + on { getNodeInfo(nodeInfoHash) }.thenReturn(SignedNodeInfo(serializedNodeInfo, listOf(keyPair.sign(serializedNodeInfo)))) } NetworkManagementWebServer(NetworkHostAndPort("localhost", 0), NodeInfoWebService(nodeInfoStorage, mock(), testNetwotkMapConfig)).use { it.start() val nodeInfoURL = URL("http://${it.hostAndPort}/${NodeInfoWebService.NETWORK_MAP_PATH}/node-info/$nodeInfoHash") val conn = nodeInfoURL.openConnection() - val nodeInfoResponse = conn.inputStream.readBytes().deserialize>() + val nodeInfoResponse = conn.inputStream.readBytes().deserialize() verify(nodeInfoStorage, times(1)).getNodeInfo(nodeInfoHash) assertEquals(nodeInfo, nodeInfoResponse.verified()) diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt index 046b5ee7be..bcacf72865 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt @@ -70,8 +70,8 @@ class SignedNetworkMap(val raw: SerializedBytes, val signature: Digi @Throws(SignatureException::class, CertPathValidatorException::class) fun verified(trustedRoot: X509Certificate?): NetworkMap { signature.by.publicKey.verify(raw.bytes, signature) - // Assume network map cert is under the default trust root. if (trustedRoot != null) { + // Assume network map cert is under the default trust root. X509Utilities.validateCertificateChain(trustedRoot, signature.by, trustedRoot) } return raw.deserialize() diff --git a/settings.gradle b/settings.gradle index 408fd292e7..1341d72878 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,6 +31,9 @@ include 'perftestcordapp' ['test-common', 'test-utils', 'smoke-test-utils', 'node-driver'].each { project(":$it").projectDir = new File("$settingsDir/testing/$it") } +include 'network-management' +include 'network-management:capsule' +include 'network-management:capsule-hsm' include 'tools:jmeter' include 'tools:explorer' include 'tools:explorer:capsule'