mirror of
https://github.com/corda/corda.git
synced 2024-12-26 16:11:12 +00:00
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:
parent
c171237556
commit
4e80a33dea
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@ -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" />
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
@ -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())
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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'
|
||||
|
Loading…
Reference in New Issue
Block a user