Fixes after os -> ent merge to networkManagement (#214)

* Quick fixes

* Fix SignedNodeInfo

Introduce network-management schema changes to reflect that NodeInfos
can have multiple signatures.

* Address Shams comments

Store SignedNodeInfo as a blob for network management tool.
This commit is contained in:
Katarzyna Streich 2017-12-19 21:36:30 +00:00 committed by Shams Asari
parent c171237556
commit 4e80a33dea
15 changed files with 61 additions and 96 deletions

2
.idea/compiler.xml generated
View File

@ -23,6 +23,8 @@
<module name="client_test" target="1.8" />
<module name="confidential-identities_main" target="1.8" />
<module name="confidential-identities_test" target="1.8" />
<module name="corda-cordform-common_main" target="1.8" />
<module name="corda-cordform-common_test" target="1.8" />
<module name="corda-core_integrationTest" target="1.8" />
<module name="corda-core_smokeTest" target="1.8" />
<module name="corda-finance_integrationTest" target="1.8" />

View File

@ -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
}
}

View File

@ -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<NodeInfo>?
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<NodeInfo>): SecureHash
fun putNodeInfo(signedNodeInfo: SignedNodeInfo): SecureHash
}

View File

@ -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<NodeInfo>): 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<CertificateSigningRequestEntity>(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<NodeInfo>? = 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()
}
}
}

View File

@ -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<NodeInfo>()
/**
* 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<SignedNodeInfo>()
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
)
}
}

View File

@ -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)

View File

@ -39,7 +39,6 @@ internal data class NotaryConfiguration(private val name: CordaX500Name,
*/
internal data class NetworkParametersConfiguration(val minimumPlatformVersion: Int,
val notaries: List<NotaryConfiguration>,
val eventHorizonDays: Int,
val maxMessageSize: Int,
val maxTransactionSize: Int)

View File

@ -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<SignedData<NodeInfo>>()
val registrationData = input.readBytes().deserialize<SignedNodeInfo>()
return try {
// Store the NodeInfo
nodeInfoStorage.putNodeInfo(registrationData)

View File

@ -96,10 +96,7 @@
<column name="node_info_hash" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>
<column name="node_info_bytes" type="BLOB"/>
<column name="signature_bytes" type="BLOB"/>
<column name="signature_public_key_algorithm" type="CLOB"/>
<column name="signature_public_key_bytes" type="BLOB"/>
<column name="signed_node_info_bytes" type="BLOB"/>
<column name="certificate_signing_request" type="VARCHAR(64)">
<constraints nullable="false"/>
</column>

View File

@ -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<NotaryInfo> = 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(

View File

@ -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

View File

@ -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())
}
}

View File

@ -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<SignedData<NodeInfo>>()
val nodeInfoResponse = conn.inputStream.readBytes().deserialize<SignedNodeInfo>()
verify(nodeInfoStorage, times(1)).getNodeInfo(nodeInfoHash)
assertEquals(nodeInfo, nodeInfoResponse.verified())

View File

@ -70,8 +70,8 @@ class SignedNetworkMap(val raw: SerializedBytes<NetworkMap>, 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()

View File

@ -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'