mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
HSM signing of network parameters (#363)
Add HSM signing of network parameters
This commit is contained in:
parent
af21f6065d
commit
f2f803ecd5
@ -3,6 +3,7 @@ package com.r3.corda.networkmanage.common.persistence
|
|||||||
import com.r3.corda.networkmanage.common.utils.SignedNetworkMap
|
import com.r3.corda.networkmanage.common.utils.SignedNetworkMap
|
||||||
import com.r3.corda.networkmanage.common.utils.SignedNetworkParameters
|
import com.r3.corda.networkmanage.common.utils.SignedNetworkParameters
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
|
import net.corda.core.internal.DigitalSignatureWithCert
|
||||||
import net.corda.nodeapi.internal.network.NetworkParameters
|
import net.corda.nodeapi.internal.network.NetworkParameters
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,26 +32,28 @@ interface NetworkMapStorage {
|
|||||||
fun saveNetworkMap(signedNetworkMap: SignedNetworkMap)
|
fun saveNetworkMap(signedNetworkMap: SignedNetworkMap)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the signed network parameters object which matches the given hash. The hash is that of the underlying
|
* Retrieve the signed with certificate network parameters by their hash. The hash is that of the underlying
|
||||||
* [NetworkParameters] object and not the `SignedData<NetworkParameters>` object that's returned.
|
* [NetworkParameters] object and not the `SignedWithCert<NetworkParameters>` object that's returned.
|
||||||
|
* @return signed network parameters corresponding to the given hash or null if it does not exist (parameters don't exist or they haven't been signed yet)
|
||||||
*/
|
*/
|
||||||
fun getSignedNetworkParameters(hash: SecureHash): SignedNetworkParameters?
|
fun getSignedNetworkParameters(hash: SecureHash): SignedNetworkParameters?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve network map parameters.
|
* Retrieve network map parameters.
|
||||||
* @return current network map parameters or null if they don't exist
|
* @return signed current network map parameters or null if they don't exist
|
||||||
*/
|
*/
|
||||||
fun getCurrentNetworkParameters(): NetworkParameters?
|
fun getCurrentSignedNetworkParameters(): SignedNetworkParameters?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persists given network parameters.
|
* Persists given network parameters with signature if provided.
|
||||||
* @return hash corresponding to newly create network parameters entry
|
* @return hash corresponding to newly created network parameters entry
|
||||||
*/
|
*/
|
||||||
fun saveNetworkParameters(networkParameters: NetworkParameters): SecureHash
|
fun saveNetworkParameters(networkParameters: NetworkParameters, sig: DigitalSignatureWithCert?): SecureHash
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the latest (i.e. most recently inserted) network parameters
|
* Retrieves the latest (i.e. most recently inserted) network parameters
|
||||||
|
* Note that they may not have been signed up yet.
|
||||||
* @return latest network parameters
|
* @return latest network parameters
|
||||||
*/
|
*/
|
||||||
fun getLatestNetworkParameters(): NetworkParameters
|
fun getLatestUnsignedNetworkParameters(): NetworkParameters
|
||||||
}
|
}
|
@ -3,9 +3,9 @@ package com.r3.corda.networkmanage.common.persistence
|
|||||||
import com.r3.corda.networkmanage.common.persistence.entity.*
|
import com.r3.corda.networkmanage.common.persistence.entity.*
|
||||||
import com.r3.corda.networkmanage.common.utils.SignedNetworkMap
|
import com.r3.corda.networkmanage.common.utils.SignedNetworkMap
|
||||||
import com.r3.corda.networkmanage.common.utils.SignedNetworkParameters
|
import com.r3.corda.networkmanage.common.utils.SignedNetworkParameters
|
||||||
import com.r3.corda.networkmanage.doorman.signer.LocalSigner
|
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.sha256
|
import net.corda.core.crypto.sha256
|
||||||
|
import net.corda.core.internal.DigitalSignatureWithCert
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
@ -16,7 +16,7 @@ import net.corda.nodeapi.internal.persistence.CordaPersistence
|
|||||||
/**
|
/**
|
||||||
* Database implementation of the [NetworkMapStorage] interface
|
* Database implementation of the [NetworkMapStorage] interface
|
||||||
*/
|
*/
|
||||||
class PersistentNetworkMapStorage(private val database: CordaPersistence, private val localSigner: LocalSigner?) : NetworkMapStorage {
|
class PersistentNetworkMapStorage(private val database: CordaPersistence) : NetworkMapStorage {
|
||||||
override fun getCurrentNetworkMap(): SignedNetworkMap? {
|
override fun getCurrentNetworkMap(): SignedNetworkMap? {
|
||||||
return database.transaction {
|
return database.transaction {
|
||||||
getCurrentNetworkMapEntity()?.let {
|
getCurrentNetworkMapEntity()?.let {
|
||||||
@ -26,11 +26,11 @@ class PersistentNetworkMapStorage(private val database: CordaPersistence, privat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCurrentNetworkParameters(): NetworkParameters? {
|
override fun getCurrentSignedNetworkParameters(): SignedNetworkParameters? {
|
||||||
return database.transaction {
|
return database.transaction {
|
||||||
getCurrentNetworkMapEntity()?.let {
|
getCurrentNetworkMapEntity()?.let {
|
||||||
val netParamsHash = it.networkMap.deserialize<NetworkMap>().networkParameterHash
|
val netParamsHash = it.networkMap.deserialize<NetworkMap>().networkParameterHash
|
||||||
getNetworkParametersEntity(netParamsHash.toString())?.networkParameters()
|
getSignedNetworkParameters(netParamsHash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,12 +46,8 @@ class PersistentNetworkMapStorage(private val database: CordaPersistence, privat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO The signing cannot occur here as it won't work with an HSM. The signed network parameters needs to be persisted
|
|
||||||
// into the database.
|
|
||||||
override fun getSignedNetworkParameters(hash: SecureHash): SignedNetworkParameters? {
|
override fun getSignedNetworkParameters(hash: SecureHash): SignedNetworkParameters? {
|
||||||
val netParamsBytes = getNetworkParametersEntity(hash.toString())?.parametersBytes ?: return null
|
return getNetworkParametersEntity(hash.toString())?.signedParameters()
|
||||||
val sigWithCert = localSigner!!.signBytes(netParamsBytes)
|
|
||||||
return SignedNetworkParameters(SerializedBytes(netParamsBytes), sigWithCert)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNodeInfoHashes(certificateStatus: CertificateStatus): List<SecureHash> {
|
override fun getNodeInfoHashes(certificateStatus: CertificateStatus): List<SecureHash> {
|
||||||
@ -69,31 +65,32 @@ class PersistentNetworkMapStorage(private val database: CordaPersistence, privat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveNetworkParameters(networkParameters: NetworkParameters): SecureHash {
|
override fun saveNetworkParameters(networkParameters: NetworkParameters, sig: DigitalSignatureWithCert?): SecureHash {
|
||||||
return database.transaction {
|
return database.transaction {
|
||||||
val bytes = networkParameters.serialize().bytes
|
val bytes = networkParameters.serialize().bytes
|
||||||
val hash = bytes.sha256()
|
val hash = bytes.sha256()
|
||||||
session.save(NetworkParametersEntity(
|
session.saveOrUpdate(NetworkParametersEntity(
|
||||||
parametersBytes = bytes,
|
parametersBytes = bytes,
|
||||||
parametersHash = hash.toString()
|
parametersHash = hash.toString(),
|
||||||
|
signature = sig?.bytes,
|
||||||
|
certificate = sig?.by?.encoded
|
||||||
))
|
))
|
||||||
hash
|
hash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLatestNetworkParameters(): NetworkParameters = getLatestNetworkParametersEntity().networkParameters()
|
override fun getLatestUnsignedNetworkParameters(): NetworkParameters = getLatestNetworkParametersEntity().networkParameters()
|
||||||
|
|
||||||
private fun getLatestNetworkParametersEntity(): NetworkParametersEntity {
|
private fun getLatestNetworkParametersEntity(): NetworkParametersEntity {
|
||||||
return database.transaction {
|
return database.transaction {
|
||||||
val builder = session.criteriaBuilder
|
val builder = session.criteriaBuilder
|
||||||
val query = builder.createQuery(NetworkParametersEntity::class.java).run {
|
val query = builder.createQuery(NetworkParametersEntity::class.java).run {
|
||||||
// TODO a limit of 1 since we only need the first result
|
|
||||||
from(NetworkParametersEntity::class.java).run {
|
from(NetworkParametersEntity::class.java).run {
|
||||||
orderBy(builder.desc(get<String>(NetworkParametersEntity::version.name)))
|
orderBy(builder.desc(get<String>(NetworkParametersEntity::created.name)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We just want the last signed entry
|
// We just want the last entry
|
||||||
session.createQuery(query).resultList.first()
|
session.createQuery(query).setMaxResults(1).resultList.singleOrNull() ?: throw IllegalArgumentException("No network parameters found in network map storage")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,22 +1,47 @@
|
|||||||
package com.r3.corda.networkmanage.common.persistence.entity
|
package com.r3.corda.networkmanage.common.persistence.entity
|
||||||
|
|
||||||
|
import com.r3.corda.networkmanage.common.utils.SignedNetworkParameters
|
||||||
|
import net.corda.core.internal.DigitalSignatureWithCert
|
||||||
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
|
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
||||||
import net.corda.nodeapi.internal.network.NetworkParameters
|
import net.corda.nodeapi.internal.network.NetworkParameters
|
||||||
|
import org.hibernate.annotations.CreationTimestamp
|
||||||
|
import java.time.Instant
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "network_parameters")
|
@Table(name = "network_parameters", indexes = arrayOf(Index(name = "IDX_NET_PARAMS_HASH", columnList = "hash")))
|
||||||
class NetworkParametersEntity(
|
class NetworkParametersEntity(
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
|
||||||
val version: Long? = null,
|
|
||||||
|
|
||||||
@Column(name = "hash", length = 64, unique = true)
|
@Column(name = "hash", length = 64, unique = true)
|
||||||
val parametersHash: String,
|
val parametersHash: String,
|
||||||
|
|
||||||
|
@CreationTimestamp
|
||||||
|
val created: Instant = Instant.now(),
|
||||||
|
|
||||||
@Lob
|
@Lob
|
||||||
@Column(name = "bytes")
|
@Column(name = "parameters_bytes")
|
||||||
val parametersBytes: ByteArray
|
val parametersBytes: ByteArray,
|
||||||
|
|
||||||
|
// Both of the fields below are nullable, because of the way we sign network map data. NetworkParameters can be
|
||||||
|
// inserted into database without signature. Then signing service will sign them.
|
||||||
|
@Lob
|
||||||
|
@Column(name = "signature")
|
||||||
|
val signature: ByteArray?,
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
@Column(name = "certificate")
|
||||||
|
val certificate: ByteArray?
|
||||||
) {
|
) {
|
||||||
fun networkParameters(): NetworkParameters = parametersBytes.deserialize()
|
fun networkParameters(): NetworkParameters = parametersBytes.deserialize()
|
||||||
|
|
||||||
|
// Return signed network parameters or null if they haven't been signed yet.
|
||||||
|
fun signedParameters(): SignedNetworkParameters? {
|
||||||
|
return if (certificate != null && signature != null) {
|
||||||
|
val sigWithCert = DigitalSignatureWithCert(X509CertificateFactory().generateCertificate(certificate.inputStream()), signature)
|
||||||
|
SignedDataWithCert(SerializedBytes(parametersBytes), sigWithCert)
|
||||||
|
} else null
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,19 +5,33 @@ import com.r3.corda.networkmanage.common.persistence.NetworkMapStorage
|
|||||||
import net.corda.core.internal.SignedDataWithCert
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.nodeapi.internal.network.NetworkMap
|
import net.corda.nodeapi.internal.network.NetworkMap
|
||||||
|
import net.corda.nodeapi.internal.network.NetworkParameters
|
||||||
|
|
||||||
class NetworkMapSigner(private val networkMapStorage: NetworkMapStorage, private val signer: Signer) {
|
class NetworkMapSigner(private val networkMapStorage: NetworkMapStorage, private val signer: Signer) {
|
||||||
/**
|
/**
|
||||||
* Signs the network map.
|
* Signs the network map and latest network parameters if they haven't been signed yet.
|
||||||
*/
|
*/
|
||||||
fun signNetworkMap() {
|
fun signNetworkMap() {
|
||||||
|
// TODO There is no network parameters update process in place yet. We assume that latest parameters are to be used
|
||||||
|
// in current network map.
|
||||||
|
val latestNetworkParameters = networkMapStorage.getLatestUnsignedNetworkParameters()
|
||||||
|
val currentNetworkParameters = networkMapStorage.getCurrentSignedNetworkParameters()
|
||||||
|
if (currentNetworkParameters?.verified() != latestNetworkParameters)
|
||||||
|
signNetworkParameters(latestNetworkParameters)
|
||||||
val currentSignedNetworkMap = networkMapStorage.getCurrentNetworkMap()
|
val currentSignedNetworkMap = networkMapStorage.getCurrentNetworkMap()
|
||||||
val nodeInfoHashes = networkMapStorage.getNodeInfoHashes(CertificateStatus.VALID)
|
val nodeInfoHashes = networkMapStorage.getNodeInfoHashes(CertificateStatus.VALID)
|
||||||
val networkParameters = networkMapStorage.getLatestNetworkParameters()
|
val serialisedNetworkMap = NetworkMap(nodeInfoHashes, latestNetworkParameters.serialize().hash).serialize()
|
||||||
val serialisedNetworkMap = NetworkMap(nodeInfoHashes, networkParameters.serialize().hash).serialize()
|
|
||||||
if (serialisedNetworkMap != currentSignedNetworkMap?.raw) {
|
if (serialisedNetworkMap != currentSignedNetworkMap?.raw) {
|
||||||
val newSignedNetworkMap = SignedDataWithCert(serialisedNetworkMap, signer.signBytes(serialisedNetworkMap.bytes))
|
val newSignedNetworkMap = SignedDataWithCert(serialisedNetworkMap, signer.signBytes(serialisedNetworkMap.bytes))
|
||||||
networkMapStorage.saveNetworkMap(newSignedNetworkMap)
|
networkMapStorage.saveNetworkMap(newSignedNetworkMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signs latest inserted network parameters.
|
||||||
|
*/
|
||||||
|
fun signNetworkParameters(networkParameters: NetworkParameters) {
|
||||||
|
val digitalSignature = signer.signObject(networkParameters).sig
|
||||||
|
networkMapStorage.saveNetworkParameters(networkParameters, digitalSignature)
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ import net.corda.core.serialization.serialize
|
|||||||
*/
|
*/
|
||||||
interface Signer {
|
interface Signer {
|
||||||
/**
|
/**
|
||||||
* Signs given bytes. The signing key selction strategy is left to the implementing class.
|
* Signs given bytes. The signing key selection strategy is left to the implementing class.
|
||||||
* @return [DigitalSignatureWithCert] that encapsulates the signature and the certificate path used in the signing process.
|
* @return [DigitalSignatureWithCert] that encapsulates the signature and the certificate path used in the signing process.
|
||||||
* @throws [AuthenticationException] if fails authentication
|
* @throws [AuthenticationException] if fails authentication
|
||||||
*/
|
*/
|
||||||
|
@ -52,14 +52,15 @@ class NetworkManagementServer : Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getNetworkMapService(config: NetworkMapConfig, database: CordaPersistence, signer: LocalSigner?, updateNetworkParameters: NetworkParameters?): NodeInfoWebService {
|
private fun getNetworkMapService(config: NetworkMapConfig, database: CordaPersistence, signer: LocalSigner?, updateNetworkParameters: NetworkParameters?): NodeInfoWebService {
|
||||||
val networkMapStorage = PersistentNetworkMapStorage(database, signer)
|
val networkMapStorage = PersistentNetworkMapStorage(database)
|
||||||
val nodeInfoStorage = PersistentNodeInfoStorage(database)
|
val nodeInfoStorage = PersistentNodeInfoStorage(database)
|
||||||
|
val localNetworkMapSigner = if (signer != null) NetworkMapSigner(networkMapStorage, signer) else null
|
||||||
|
|
||||||
updateNetworkParameters?.let {
|
updateNetworkParameters?.let {
|
||||||
// Persisting new network parameters
|
// Persisting new network parameters
|
||||||
val currentNetworkParameters = networkMapStorage.getCurrentNetworkParameters()
|
val currentNetworkParameters = networkMapStorage.getCurrentSignedNetworkParameters()
|
||||||
if (currentNetworkParameters == null) {
|
if (currentNetworkParameters == null) {
|
||||||
networkMapStorage.saveNetworkParameters(it)
|
localNetworkMapSigner?.signNetworkParameters(it) ?: networkMapStorage.saveNetworkParameters(it, null)
|
||||||
} else {
|
} else {
|
||||||
throw UnsupportedOperationException("Network parameters already exist. Updating them via the file config is not supported yet.")
|
throw UnsupportedOperationException("Network parameters already exist. Updating them via the file config is not supported yet.")
|
||||||
}
|
}
|
||||||
@ -67,21 +68,19 @@ class NetworkManagementServer : Closeable {
|
|||||||
|
|
||||||
// This call will fail if parameter is null in DB.
|
// This call will fail if parameter is null in DB.
|
||||||
try {
|
try {
|
||||||
val latestParameter = networkMapStorage.getLatestNetworkParameters()
|
val latestParameter = networkMapStorage.getLatestUnsignedNetworkParameters()
|
||||||
logger.info("Starting network map service with network parameters : $latestParameter")
|
logger.info("Starting network map service with network parameters : $latestParameter")
|
||||||
} catch (e: NoSuchElementException) {
|
} catch (e: NoSuchElementException) {
|
||||||
logger.error("No network parameter found, please upload new network parameter before starting network map service. The server will now exit.")
|
logger.error("No network parameter found, please upload new network parameter before starting network map service. The server will now exit.")
|
||||||
exitProcess(-1)
|
exitProcess(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val networkMapSigner = if (signer != null) NetworkMapSigner(networkMapStorage, signer) else null
|
|
||||||
|
|
||||||
// Thread sign network map in case of change (i.e. a new node info has been added or a node info has been removed).
|
// Thread sign network map in case of change (i.e. a new node info has been added or a node info has been removed).
|
||||||
if (networkMapSigner != null) {
|
if (localNetworkMapSigner != null) {
|
||||||
val scheduledExecutor = Executors.newScheduledThreadPool(1)
|
val scheduledExecutor = Executors.newScheduledThreadPool(1)
|
||||||
val signingThread = Runnable {
|
val signingThread = Runnable {
|
||||||
try {
|
try {
|
||||||
networkMapSigner.signNetworkMap()
|
localNetworkMapSigner.signNetworkMap()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// Log the error and carry on.
|
// Log the error and carry on.
|
||||||
logger.error("Error encountered when processing node info changes.", e)
|
logger.error("Error encountered when processing node info changes.", e)
|
||||||
@ -141,7 +140,6 @@ class NetworkManagementServer : Closeable {
|
|||||||
val services = mutableListOf<Any>()
|
val services = mutableListOf<Any>()
|
||||||
val serverStatus = NetworkManagementServerStatus()
|
val serverStatus = NetworkManagementServerStatus()
|
||||||
|
|
||||||
// TODO: move signing to signing server.
|
|
||||||
startNetworkMap?.let { services += getNetworkMapService(it.config, database, it.signer, it.updateNetworkParameters) }
|
startNetworkMap?.let { services += getNetworkMapService(it.config, database, it.signer, it.updateNetworkParameters) }
|
||||||
doormanServiceParameter?.let { services += getDoormanService(it, database, doormanSigner, serverStatus) }
|
doormanServiceParameter?.let { services += getDoormanService(it, database, doormanSigner, serverStatus) }
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import com.r3.corda.networkmanage.common.persistence.NetworkMapStorage
|
|||||||
import com.r3.corda.networkmanage.common.persistence.NodeInfoStorage
|
import com.r3.corda.networkmanage.common.persistence.NodeInfoStorage
|
||||||
import com.r3.corda.networkmanage.common.persistence.NodeInfoWithSigned
|
import com.r3.corda.networkmanage.common.persistence.NodeInfoWithSigned
|
||||||
import com.r3.corda.networkmanage.common.utils.SignedNetworkMap
|
import com.r3.corda.networkmanage.common.utils.SignedNetworkMap
|
||||||
|
import com.r3.corda.networkmanage.common.utils.SignedNetworkParameters
|
||||||
import com.r3.corda.networkmanage.doorman.NetworkMapConfig
|
import com.r3.corda.networkmanage.doorman.NetworkMapConfig
|
||||||
import com.r3.corda.networkmanage.doorman.webservice.NodeInfoWebService.Companion.NETWORK_MAP_PATH
|
import com.r3.corda.networkmanage.doorman.webservice.NodeInfoWebService.Companion.NETWORK_MAP_PATH
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
@ -41,7 +42,7 @@ class NodeInfoWebService(private val nodeInfoStorage: NodeInfoStorage,
|
|||||||
|
|
||||||
private val networkMapCache: LoadingCache<Boolean, Pair<SignedNetworkMap?, NetworkParameters?>> = CacheBuilder.newBuilder()
|
private val networkMapCache: LoadingCache<Boolean, Pair<SignedNetworkMap?, NetworkParameters?>> = CacheBuilder.newBuilder()
|
||||||
.expireAfterWrite(config.cacheTimeout, TimeUnit.MILLISECONDS)
|
.expireAfterWrite(config.cacheTimeout, TimeUnit.MILLISECONDS)
|
||||||
.build(CacheLoader.from { _ -> Pair(networkMapStorage.getCurrentNetworkMap(), networkMapStorage.getCurrentNetworkParameters()) })
|
.build(CacheLoader.from { _ -> Pair(networkMapStorage.getCurrentNetworkMap(), networkMapStorage.getCurrentSignedNetworkParameters()?.verified()) })
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("publish")
|
@Path("publish")
|
||||||
|
@ -46,8 +46,7 @@ fun run(parameters: Parameters) {
|
|||||||
checkNotNull(dataSourceProperties)
|
checkNotNull(dataSourceProperties)
|
||||||
val database = configureDatabase(dataSourceProperties, databaseConfig)
|
val database = configureDatabase(dataSourceProperties, databaseConfig)
|
||||||
val csrStorage = DBSignedCertificateRequestStorage(database)
|
val csrStorage = DBSignedCertificateRequestStorage(database)
|
||||||
// TODO Remove the dependency for a local signer to make signing of network parameters work with an HSM
|
val networkMapStorage = PersistentNetworkMapStorage(database)
|
||||||
val networkMapStorage = PersistentNetworkMapStorage(database, localSigner = null)
|
|
||||||
val hsmNetworkMapSigningThread = HsmNetworkMapSigner(
|
val hsmNetworkMapSigningThread = HsmNetworkMapSigner(
|
||||||
networkMapStorage,
|
networkMapStorage,
|
||||||
networkMapCertificateName,
|
networkMapCertificateName,
|
||||||
|
@ -93,11 +93,13 @@
|
|||||||
</changeSet>
|
</changeSet>
|
||||||
<changeSet author="R3.Corda" id="1513267683777-8">
|
<changeSet author="R3.Corda" id="1513267683777-8">
|
||||||
<createTable tableName="network_parameters">
|
<createTable tableName="network_parameters">
|
||||||
<column name="version" type="BIGINT">
|
<column name="hash" type="NVARCHAR(64)">
|
||||||
<constraints nullable="false"/>
|
<constraints nullable="false"/>
|
||||||
</column>
|
</column>
|
||||||
<column name="bytes" type="BLOB"/>
|
<column name="certificate" type="BLOB"/>
|
||||||
<column name="hash" type="NVARCHAR(64)"/>
|
<column name="created" type="TIMESTAMP"/>
|
||||||
|
<column name="parameters_bytes" type="BLOB"/>
|
||||||
|
<column name="signature" type="BLOB"/>
|
||||||
</createTable>
|
</createTable>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
<changeSet author="R3.Corda" id="1513267683777-9">
|
<changeSet author="R3.Corda" id="1513267683777-9">
|
||||||
@ -120,7 +122,7 @@
|
|||||||
</createTable>
|
</createTable>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
<changeSet author="R3.Corda" id="1513267683777-11">
|
<changeSet author="R3.Corda" id="1513267683777-11">
|
||||||
<addPrimaryKey columnNames="version" constraintName="CONSTRAINT_3" tableName="network_parameters"/>
|
<addPrimaryKey columnNames="hash" constraintName="CONSTRAINT_3" tableName="network_parameters"/>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
<changeSet author="R3.Corda" id="1513267683777-12">
|
<changeSet author="R3.Corda" id="1513267683777-12">
|
||||||
<addPrimaryKey columnNames="id" constraintName="CONSTRAINT_7" tableName="certificate_data"/>
|
<addPrimaryKey columnNames="id" constraintName="CONSTRAINT_7" tableName="certificate_data"/>
|
||||||
@ -167,6 +169,11 @@
|
|||||||
<column name="public_key_hash"/>
|
<column name="public_key_hash"/>
|
||||||
</createIndex>
|
</createIndex>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
<changeSet author="R3.Corda" id="network-parameters-idx">
|
||||||
|
<createIndex indexName="IDX_NET_PARAMS_HASH" tableName="network_parameters">
|
||||||
|
<column name="hash"/>
|
||||||
|
</createIndex>
|
||||||
|
</changeSet>
|
||||||
<changeSet author="R3.Corda" id="1513267683777-24">
|
<changeSet author="R3.Corda" id="1513267683777-24">
|
||||||
<addForeignKeyConstraint baseColumnNames="rev" baseTableName="certificate_signing_request_AUD"
|
<addForeignKeyConstraint baseColumnNames="rev" baseTableName="certificate_signing_request_AUD"
|
||||||
constraintName="FK5g5cagcrx7siu8lwtavirunxd"
|
constraintName="FK5g5cagcrx7siu8lwtavirunxd"
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.r3.corda.networkmanage.common.persistence
|
package com.r3.corda.networkmanage.common.persistence
|
||||||
|
|
||||||
import com.r3.corda.networkmanage.TestBase
|
import com.r3.corda.networkmanage.TestBase
|
||||||
import com.r3.corda.networkmanage.doorman.signer.LocalSigner
|
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.signWithCert
|
import net.corda.core.internal.signWithCert
|
||||||
import net.corda.nodeapi.internal.createDevNetworkMapCa
|
import net.corda.nodeapi.internal.createDevNetworkMapCa
|
||||||
@ -37,7 +36,7 @@ class PersistentNetworkMapStorageTest : TestBase() {
|
|||||||
rootCaCert = rootCa.certificate
|
rootCaCert = rootCa.certificate
|
||||||
networkMapCa = createDevNetworkMapCa(rootCa)
|
networkMapCa = createDevNetworkMapCa(rootCa)
|
||||||
persistence = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true))
|
persistence = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true))
|
||||||
networkMapStorage = PersistentNetworkMapStorage(persistence, LocalSigner(networkMapCa.keyPair, arrayOf(networkMapCa.certificate, rootCaCert)))
|
networkMapStorage = PersistentNetworkMapStorage(persistence)
|
||||||
nodeInfoStorage = PersistentNodeInfoStorage(persistence)
|
nodeInfoStorage = PersistentNodeInfoStorage(persistence)
|
||||||
requestStorage = PersistentCertificateRequestStorage(persistence)
|
requestStorage = PersistentCertificateRequestStorage(persistence)
|
||||||
}
|
}
|
||||||
@ -48,15 +47,16 @@ class PersistentNetworkMapStorageTest : TestBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `signNetworkMap creates current network map`() {
|
fun `saveNetworkMap and saveNetworkParameters create current network map and parameters`() {
|
||||||
// given
|
// given
|
||||||
// Create node info.
|
// Create node info.
|
||||||
val signedNodeInfo = createValidSignedNodeInfo("Test")
|
val signedNodeInfo = createValidSignedNodeInfo("Test")
|
||||||
val nodeInfoHash = nodeInfoStorage.putNodeInfo(signedNodeInfo)
|
val nodeInfoHash = nodeInfoStorage.putNodeInfo(signedNodeInfo)
|
||||||
|
|
||||||
|
val networkParameters = testNetworkParameters(emptyList())
|
||||||
|
val parametersSignature = networkParameters.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate).sig
|
||||||
// Create network parameters
|
// Create network parameters
|
||||||
val networkParametersHash = networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList()))
|
val networkParametersHash = networkMapStorage.saveNetworkParameters(networkParameters, parametersSignature)
|
||||||
|
|
||||||
val networkMap = NetworkMap(listOf(nodeInfoHash), networkParametersHash)
|
val networkMap = NetworkMap(listOf(nodeInfoHash), networkParametersHash)
|
||||||
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
|
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
|
||||||
|
|
||||||
@ -65,20 +65,26 @@ class PersistentNetworkMapStorageTest : TestBase() {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
val persistedSignedNetworkMap = networkMapStorage.getCurrentNetworkMap()
|
val persistedSignedNetworkMap = networkMapStorage.getCurrentNetworkMap()
|
||||||
|
val persistedSignedParameters = networkMapStorage.getCurrentSignedNetworkParameters()
|
||||||
|
|
||||||
|
assertEquals(networkParameters, persistedSignedParameters?.verifiedNetworkMapCert(rootCaCert))
|
||||||
|
assertEquals(parametersSignature, persistedSignedParameters?.sig)
|
||||||
assertEquals(signedNetworkMap.sig, persistedSignedNetworkMap?.sig)
|
assertEquals(signedNetworkMap.sig, persistedSignedNetworkMap?.sig)
|
||||||
assertEquals(signedNetworkMap.verifiedNetworkMapCert(rootCaCert), persistedSignedNetworkMap?.verifiedNetworkMapCert(rootCaCert))
|
assertEquals(signedNetworkMap.verifiedNetworkMapCert(rootCaCert), persistedSignedNetworkMap?.verifiedNetworkMapCert(rootCaCert))
|
||||||
|
assertEquals(signedNetworkMap.verifiedNetworkMapCert(rootCaCert).networkParameterHash, persistedSignedParameters?.raw?.hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getLatestNetworkParameters returns last inserted`() {
|
fun `getLatestNetworkParameters returns last inserted`() {
|
||||||
|
val params1 = testNetworkParameters(emptyList(), minimumPlatformVersion = 1)
|
||||||
|
val params2 = testNetworkParameters(emptyList(), minimumPlatformVersion = 2)
|
||||||
// given
|
// given
|
||||||
networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList(), minimumPlatformVersion = 1))
|
networkMapStorage.saveNetworkParameters(params1, params1.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate).sig)
|
||||||
networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList(), minimumPlatformVersion = 2))
|
// We may have not signed them yet.
|
||||||
|
networkMapStorage.saveNetworkParameters(params2, null)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
val latest = networkMapStorage.getLatestNetworkParameters()
|
val latest = networkMapStorage.getLatestUnsignedNetworkParameters()
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(2, latest.minimumPlatformVersion)
|
assertEquals(2, latest.minimumPlatformVersion)
|
||||||
}
|
}
|
||||||
@ -87,7 +93,8 @@ class PersistentNetworkMapStorageTest : TestBase() {
|
|||||||
fun `getCurrentNetworkParameters returns current network map parameters`() {
|
fun `getCurrentNetworkParameters returns current network map parameters`() {
|
||||||
// given
|
// given
|
||||||
// Create network parameters
|
// Create network parameters
|
||||||
val networkParametersHash = networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList()))
|
val testParameters1 = testNetworkParameters(emptyList())
|
||||||
|
val networkParametersHash = networkMapStorage.saveNetworkParameters(testParameters1, testParameters1.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate).sig)
|
||||||
// Create empty network map
|
// Create empty network map
|
||||||
|
|
||||||
// Sign network map making it current network map
|
// Sign network map making it current network map
|
||||||
@ -96,25 +103,16 @@ class PersistentNetworkMapStorageTest : TestBase() {
|
|||||||
networkMapStorage.saveNetworkMap(signedNetworkMap)
|
networkMapStorage.saveNetworkMap(signedNetworkMap)
|
||||||
|
|
||||||
// Create new network parameters
|
// Create new network parameters
|
||||||
networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList(), minimumPlatformVersion = 2))
|
val testParameters2 = testNetworkParameters(emptyList(), minimumPlatformVersion = 2)
|
||||||
|
networkMapStorage.saveNetworkParameters(testParameters2, testParameters2.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate).sig)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
val result = networkMapStorage.getCurrentNetworkParameters()
|
val result = networkMapStorage.getCurrentSignedNetworkParameters()?.verifiedNetworkMapCert(rootCaCert)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(1, result?.minimumPlatformVersion)
|
assertEquals(1, result?.minimumPlatformVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test will probably won't be needed when we remove the explicit use of LocalSigner
|
|
||||||
@Test
|
|
||||||
fun `getSignedNetworkParameters uses the local signer to return a signed object`() {
|
|
||||||
val networkParameters = testNetworkParameters(emptyList())
|
|
||||||
val netParamsHash = networkMapStorage.saveNetworkParameters(networkParameters)
|
|
||||||
val signedNetworkParameters = networkMapStorage.getSignedNetworkParameters(netParamsHash)
|
|
||||||
assertThat(signedNetworkParameters?.verifiedNetworkMapCert(rootCaCert)).isEqualTo(networkParameters)
|
|
||||||
assertThat(signedNetworkParameters?.sig?.by).isEqualTo(networkMapCa.certificate)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getValidNodeInfoHashes returns only valid and signed node info hashes`() {
|
fun `getValidNodeInfoHashes returns only valid and signed node info hashes`() {
|
||||||
// given
|
// given
|
||||||
@ -127,7 +125,8 @@ class PersistentNetworkMapStorageTest : TestBase() {
|
|||||||
val nodeInfoHashB = nodeInfoStorage.putNodeInfo(signedNodeInfoB)
|
val nodeInfoHashB = nodeInfoStorage.putNodeInfo(signedNodeInfoB)
|
||||||
|
|
||||||
// Create network parameters
|
// Create network parameters
|
||||||
val networkParametersHash = networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList()))
|
val testParameters = testNetworkParameters(emptyList())
|
||||||
|
val networkParametersHash = networkMapStorage.saveNetworkParameters(testParameters, testParameters.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate).sig)
|
||||||
val networkMap = NetworkMap(listOf(nodeInfoHashA), networkParametersHash)
|
val networkMap = NetworkMap(listOf(nodeInfoHashA), networkParametersHash)
|
||||||
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
|
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
|
||||||
|
|
||||||
|
@ -6,9 +6,7 @@ import com.r3.corda.networkmanage.common.utils.hashString
|
|||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.node.NodeInfo
|
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.nodeapi.internal.SignedNodeInfo
|
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
|
||||||
import net.corda.nodeapi.internal.crypto.CertificateType
|
import net.corda.nodeapi.internal.crypto.CertificateType
|
||||||
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
||||||
@ -33,7 +31,6 @@ class PersistentNodeInfoStorageTest : TestBase() {
|
|||||||
private lateinit var requestStorage: CertificationRequestStorage
|
private lateinit var requestStorage: CertificationRequestStorage
|
||||||
private lateinit var nodeInfoStorage: PersistentNodeInfoStorage
|
private lateinit var nodeInfoStorage: PersistentNodeInfoStorage
|
||||||
private lateinit var persistence: CordaPersistence
|
private lateinit var persistence: CordaPersistence
|
||||||
|
|
||||||
private lateinit var rootCaCert: X509Certificate
|
private lateinit var rootCaCert: X509Certificate
|
||||||
private lateinit var intermediateCa: CertificateAndKeyPair
|
private lateinit var intermediateCa: CertificateAndKeyPair
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import net.corda.core.crypto.Crypto
|
|||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.sha256
|
import net.corda.core.crypto.sha256
|
||||||
import net.corda.core.internal.DigitalSignatureWithCert
|
import net.corda.core.internal.DigitalSignatureWithCert
|
||||||
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
import net.corda.core.internal.signWithCert
|
import net.corda.core.internal.signWithCert
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.nodeapi.internal.createDevNetworkMapCa
|
import net.corda.nodeapi.internal.createDevNetworkMapCa
|
||||||
@ -16,10 +17,10 @@ import net.corda.nodeapi.internal.network.NetworkMap
|
|||||||
import net.corda.nodeapi.internal.network.verifiedNetworkMapCert
|
import net.corda.nodeapi.internal.network.verifiedNetworkMapCert
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.internal.createDevIntermediateCaCertPath
|
import net.corda.testing.internal.createDevIntermediateCaCertPath
|
||||||
|
import java.security.cert.X509Certificate
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.security.cert.X509Certificate
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class NetworkMapSignerTest : TestBase() {
|
class NetworkMapSignerTest : TestBase() {
|
||||||
@ -41,18 +42,24 @@ class NetworkMapSignerTest : TestBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `signNetworkMap builds and signs network map`() {
|
fun `signNetworkMap builds and signs network map and network parameters`() {
|
||||||
// given
|
// given
|
||||||
val signedNodeInfoHashes = listOf(SecureHash.randomSHA256(), SecureHash.randomSHA256())
|
val signedNodeInfoHashes = listOf(SecureHash.randomSHA256(), SecureHash.randomSHA256())
|
||||||
val networkParameters = testNetworkParameters(emptyList())
|
val currentParameters = testNetworkParameters(emptyList(), minimumPlatformVersion = 1)
|
||||||
val networkMap = NetworkMap(signedNodeInfoHashes, SecureHash.randomSHA256())
|
val latestNetworkParameters = testNetworkParameters(emptyList(), minimumPlatformVersion = 2)
|
||||||
|
val networkMap = NetworkMap(signedNodeInfoHashes, currentParameters.serialize().hash)
|
||||||
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
|
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
|
||||||
whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(signedNetworkMap)
|
whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(signedNetworkMap)
|
||||||
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(signedNodeInfoHashes)
|
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(signedNodeInfoHashes)
|
||||||
whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkParameters)
|
whenever(networkMapStorage.getLatestUnsignedNetworkParameters()).thenReturn(latestNetworkParameters)
|
||||||
|
whenever(networkMapStorage.getCurrentSignedNetworkParameters()).thenReturn(currentParameters.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate))
|
||||||
whenever(signer.signBytes(any())).then {
|
whenever(signer.signBytes(any())).then {
|
||||||
DigitalSignatureWithCert(networkMapCa.certificate, Crypto.doSign(networkMapCa.keyPair.private, it.arguments[0] as ByteArray))
|
DigitalSignatureWithCert(networkMapCa.certificate, Crypto.doSign(networkMapCa.keyPair.private, it.arguments[0] as ByteArray))
|
||||||
}
|
}
|
||||||
|
whenever(signer.signObject(latestNetworkParameters)).then {
|
||||||
|
val serialised = latestNetworkParameters.serialize()
|
||||||
|
SignedDataWithCert(serialised, signer.signBytes(serialised.bytes))
|
||||||
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
networkMapSigner.signNetworkMap()
|
networkMapSigner.signNetworkMap()
|
||||||
@ -60,11 +67,12 @@ class NetworkMapSignerTest : TestBase() {
|
|||||||
// then
|
// then
|
||||||
// Verify networkMapStorage calls
|
// Verify networkMapStorage calls
|
||||||
verify(networkMapStorage).getNodeInfoHashes(any())
|
verify(networkMapStorage).getNodeInfoHashes(any())
|
||||||
verify(networkMapStorage).getLatestNetworkParameters()
|
verify(networkMapStorage).getLatestUnsignedNetworkParameters()
|
||||||
|
verify(networkMapStorage).getCurrentSignedNetworkParameters()
|
||||||
argumentCaptor<SignedNetworkMap>().apply {
|
argumentCaptor<SignedNetworkMap>().apply {
|
||||||
verify(networkMapStorage).saveNetworkMap(capture())
|
verify(networkMapStorage).saveNetworkMap(capture())
|
||||||
val capturedNetworkMap = firstValue.verifiedNetworkMapCert(rootCaCert)
|
val capturedNetworkMap = firstValue.verifiedNetworkMapCert(rootCaCert)
|
||||||
assertEquals(networkParameters.serialize().hash, capturedNetworkMap.networkParameterHash)
|
assertEquals(latestNetworkParameters.serialize().hash, capturedNetworkMap.networkParameterHash)
|
||||||
assertEquals(signedNodeInfoHashes.size, capturedNetworkMap.nodeInfoHashes.size)
|
assertEquals(signedNodeInfoHashes.size, capturedNetworkMap.nodeInfoHashes.size)
|
||||||
assertThat(capturedNetworkMap.nodeInfoHashes).containsAll(signedNodeInfoHashes)
|
assertThat(capturedNetworkMap.nodeInfoHashes).containsAll(signedNodeInfoHashes)
|
||||||
}
|
}
|
||||||
@ -79,7 +87,8 @@ class NetworkMapSignerTest : TestBase() {
|
|||||||
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
|
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
|
||||||
whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(signedNetworkMap)
|
whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(signedNetworkMap)
|
||||||
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(emptyList())
|
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(emptyList())
|
||||||
whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkParameters)
|
whenever(networkMapStorage.getLatestUnsignedNetworkParameters()).thenReturn(networkParameters)
|
||||||
|
whenever(networkMapStorage.getCurrentSignedNetworkParameters()).thenReturn(networkParameters.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
networkMapSigner.signNetworkMap()
|
networkMapSigner.signNetworkMap()
|
||||||
@ -95,17 +104,21 @@ class NetworkMapSignerTest : TestBase() {
|
|||||||
val networkParameters = testNetworkParameters(emptyList())
|
val networkParameters = testNetworkParameters(emptyList())
|
||||||
whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(null)
|
whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(null)
|
||||||
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(emptyList())
|
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(emptyList())
|
||||||
whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkParameters)
|
whenever(networkMapStorage.getLatestUnsignedNetworkParameters()).thenReturn(networkParameters)
|
||||||
whenever(signer.signBytes(any())).then {
|
whenever(signer.signBytes(any())).then {
|
||||||
DigitalSignatureWithCert(networkMapCa.certificate, Crypto.doSign(networkMapCa.keyPair.private, it.arguments[0] as ByteArray))
|
DigitalSignatureWithCert(networkMapCa.certificate, Crypto.doSign(networkMapCa.keyPair.private, it.arguments[0] as ByteArray))
|
||||||
}
|
}
|
||||||
|
whenever(signer.signObject(networkParameters)).then {
|
||||||
|
val serialised = networkParameters.serialize()
|
||||||
|
SignedDataWithCert(serialised, signer.signBytes(serialised.bytes))
|
||||||
|
}
|
||||||
// when
|
// when
|
||||||
networkMapSigner.signNetworkMap()
|
networkMapSigner.signNetworkMap()
|
||||||
|
|
||||||
// then
|
// then
|
||||||
// Verify networkMapStorage calls
|
// Verify networkMapStorage calls
|
||||||
verify(networkMapStorage).getNodeInfoHashes(any())
|
verify(networkMapStorage).getNodeInfoHashes(any())
|
||||||
verify(networkMapStorage).getLatestNetworkParameters()
|
verify(networkMapStorage).getLatestUnsignedNetworkParameters()
|
||||||
argumentCaptor<SignedNetworkMap>().apply {
|
argumentCaptor<SignedNetworkMap>().apply {
|
||||||
verify(networkMapStorage).saveNetworkMap(capture())
|
verify(networkMapStorage).saveNetworkMap(capture())
|
||||||
val networkMap = firstValue.verifiedNetworkMapCert(rootCaCert)
|
val networkMap = firstValue.verifiedNetworkMapCert(rootCaCert)
|
||||||
|
@ -56,7 +56,7 @@ class NodeInfoWebServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `submit nodeInfo`() {
|
fun `submit nodeInfo`() {
|
||||||
val networkMapStorage: NetworkMapStorage = mock {
|
val networkMapStorage: NetworkMapStorage = mock {
|
||||||
on { getCurrentNetworkParameters() }.thenReturn(testNetworkParameters(emptyList()))
|
on { getCurrentSignedNetworkParameters() }.thenReturn(testNetworkParameters(emptyList()).signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate))
|
||||||
}
|
}
|
||||||
// Create node info.
|
// Create node info.
|
||||||
val (_, signedNodeInfo) = createNodeInfoAndSigned(CordaX500Name("Test", "London", "GB"))
|
val (_, signedNodeInfo) = createNodeInfoAndSigned(CordaX500Name("Test", "London", "GB"))
|
||||||
@ -72,7 +72,7 @@ class NodeInfoWebServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `submit old nodeInfo`() {
|
fun `submit old nodeInfo`() {
|
||||||
val networkMapStorage: NetworkMapStorage = mock {
|
val networkMapStorage: NetworkMapStorage = mock {
|
||||||
on { getCurrentNetworkParameters() }.thenReturn(testNetworkParameters(emptyList(), minimumPlatformVersion = 2))
|
on { getCurrentSignedNetworkParameters() }.thenReturn(testNetworkParameters(emptyList(), minimumPlatformVersion = 2).signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate))
|
||||||
}
|
}
|
||||||
// Create node info.
|
// Create node info.
|
||||||
val (_, signedNodeInfo) = createNodeInfoAndSigned(CordaX500Name("Test", "London", "GB"), platformVersion = 1)
|
val (_, signedNodeInfo) = createNodeInfoAndSigned(CordaX500Name("Test", "London", "GB"), platformVersion = 1)
|
||||||
@ -88,7 +88,7 @@ class NodeInfoWebServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `submit nodeInfo when no network parameters`() {
|
fun `submit nodeInfo when no network parameters`() {
|
||||||
val networkMapStorage: NetworkMapStorage = mock {
|
val networkMapStorage: NetworkMapStorage = mock {
|
||||||
on { getCurrentNetworkParameters() }.thenReturn(null)
|
on { getCurrentSignedNetworkParameters() }.thenReturn(null)
|
||||||
}
|
}
|
||||||
// Create node info.
|
// Create node info.
|
||||||
val (_, signedNodeInfo) = createNodeInfoAndSigned(CordaX500Name("Test", "London", "GB"), platformVersion = 1)
|
val (_, signedNodeInfo) = createNodeInfoAndSigned(CordaX500Name("Test", "London", "GB"), platformVersion = 1)
|
||||||
@ -155,7 +155,6 @@ class NodeInfoWebServiceTest {
|
|||||||
verify(networkMapStorage, times(1)).getSignedNetworkParameters(networkParametersHash)
|
verify(networkMapStorage, times(1)).getSignedNetworkParameters(networkParametersHash)
|
||||||
assertThat(netParamsResponse.verified()).isEqualTo(networkParameters)
|
assertThat(netParamsResponse.verified()).isEqualTo(networkParameters)
|
||||||
assertThat(netParamsResponse.sig.by).isEqualTo(networkMapCa.certificate)
|
assertThat(netParamsResponse.sig.by).isEqualTo(networkMapCa.certificate)
|
||||||
|
|
||||||
assertThatExceptionOfType(IOException::class.java)
|
assertThatExceptionOfType(IOException::class.java)
|
||||||
.isThrownBy { it.doGet<SignedNetworkParameters>("network-parameters/${randomSHA256()}") }
|
.isThrownBy { it.doGet<SignedNetworkParameters>("network-parameters/${randomSHA256()}") }
|
||||||
.withMessageContaining("404")
|
.withMessageContaining("404")
|
||||||
|
@ -41,9 +41,9 @@ import javax.ws.rs.core.MediaType
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class RegistrationWebServiceTest : TestBase() {
|
class RegistrationWebServiceTest : TestBase() {
|
||||||
|
private lateinit var webServer: NetworkManagementWebServer
|
||||||
private lateinit var rootCaCert: X509Certificate
|
private lateinit var rootCaCert: X509Certificate
|
||||||
private lateinit var intermediateCa: CertificateAndKeyPair
|
private lateinit var intermediateCa: CertificateAndKeyPair
|
||||||
private lateinit var webServer: NetworkManagementWebServer
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun init() {
|
fun init() {
|
||||||
|
Loading…
Reference in New Issue
Block a user