Use network map objects from corda instead of stubs (#146)

* * change corda dependencies to 3.0-NETWORKMAP_SNAPSHOT
* packages move fix

* fix up after rebase

* rename test

* address PR issues

* address PR issues

* fix failing test
This commit is contained in:
Patrick Kuo 2017-12-07 13:22:41 +00:00 committed by GitHub
parent 60fca0bf16
commit b3ca36132f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 191 additions and 263 deletions

2
.idea/compiler.xml generated
View File

@ -15,6 +15,8 @@
<module name="business-network-demo_integrationTest" target="1.8" />
<module name="business-network-demo_main" target="1.8" />
<module name="business-network-demo_test" target="1.8" />
<module name="capsule-hsm_main" target="1.8" />
<module name="capsule-hsm_test" target="1.8" />
<module name="client_main" target="1.8" />
<module name="client_test" target="1.8" />
<module name="confidential-identities_main" target="1.8" />

View File

@ -56,9 +56,7 @@ dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "net.corda:corda-core:$corda_dependency_version"
compile "net.corda:corda-node-api:$corda_dependency_version"
testCompile "net.corda:corda-test-utils:$corda_dependency_version"
testCompile "net.corda:corda-node-driver:$corda_dependency_version"
testCompile "net.corda:corda-test-common:$corda_dependency_version"

View File

@ -92,9 +92,7 @@ class DoormanIntegrationTest {
doorman.close()
}
//TODO remove @Ignore once PR https://github.com/corda/corda/pull/2054 is merged
@Test
@Ignore
fun `nodeInfo is published to the network map`() {
// Given
val rootCertAndKey = createDoormanRootCertificateAndKeyPair()
@ -111,6 +109,8 @@ class DoormanIntegrationTest {
whenever(it.compatibilityZoneURL).thenReturn(URL("http://${doormanHostAndPort.host}:${doormanHostAndPort.port}"))
whenever(it.emailAddress).thenReturn("iTest@R3.com")
}
config.rootCaCertFile.parent.createDirectories()
X509Utilities.saveCertificateAsPEMFile(rootCertAndKey.certificate, config.rootCaCertFile)
NetworkRegistrationHelper(config, HTTPNetworkRegistrationService(config.compatibilityZoneURL!!)).buildKeystore()

View File

@ -1,8 +1,8 @@
package com.r3.corda.networkmanage.common.persistence
import com.r3.corda.networkmanage.common.signer.SignedNetworkMap
import net.corda.core.crypto.SecureHash
import net.corda.nodeapi.internal.NetworkParameters
import net.corda.nodeapi.internal.SignedNetworkMap
/**
* Data access object interface for NetworkMap persistence layer
@ -15,16 +15,13 @@ interface NetworkMapStorage {
fun getCurrentNetworkMap(): SignedNetworkMap?
/**
* Retrieves current map node info hashes only. Hashes are further filtered by the [certificateStatuses] parameter
* that restricts considered node info to only those which [CertificateStatus] value corresponds to one in the passed
* collection. If null or empty list is passed then filtering has no effect and all node info hashes from the current
* network map are returned.
* @param certificateStatuses certificate statuses to be used in the node info filtering. Node info hash is returned
* in the result collection only if it is in the current network map and its certificate status belongs to the
* [certificateStatuses] collection or if [certificateStatuses] collection is null or empty.
* @return list of current network map node info hashes satisfying the filtering criteria given by [certificateStatuses].
* Retrieves node info hashes where the certificate status matches [certificateStatus].
*
* @param certificateStatus certificate status to be used in the node info filtering. Node info hash is returned
* in the result collection if its certificate status matches [certificateStatus].
* @return list of node info hashes satisfying the filtering criteria given by [certificateStatus].
*/
fun getCurrentNetworkMapNodeInfoHashes(certificateStatuses: List<CertificateStatus>): List<SecureHash>
fun getNodeInfoHashes(certificateStatus: CertificateStatus): List<SecureHash>
/**
* Persists a new instance of the signed network map.
@ -32,17 +29,11 @@ interface NetworkMapStorage {
*/
fun saveNetworkMap(signedNetworkMap: SignedNetworkMap)
/**
* Retrieve all node info hashes for all node info with valid certificates,
* that are not associated with any network map yet.
*/
fun getDetachedAndValidNodeInfoHashes(): List<SecureHash>
/**
* Retrieve network parameters by their hash.
* @return network parameters corresponding to the given hash or null if it does not exist
*/
fun getNetworkParameters(parameterHash: SecureHash): NetworkParameters
fun getNetworkParameters(parameterHash: SecureHash): NetworkParameters?
/**
* Retrieve network map parameters.
@ -54,7 +45,7 @@ interface NetworkMapStorage {
* Persists given network parameters.
* @return hash corresponding to newly create network parameters entry
*/
fun putNetworkParameters(networkParameters: NetworkParameters): SecureHash
fun saveNetworkParameters(networkParameters: NetworkParameters): SecureHash
/**
* Retrieves the latest (i.e. most recently inserted) network parameters

View File

@ -1,77 +1,64 @@
package com.r3.corda.networkmanage.common.persistence
import com.r3.corda.networkmanage.common.persistence.entity.NetworkMapEntity
import com.r3.corda.networkmanage.common.persistence.entity.NetworkParametersEntity
import com.r3.corda.networkmanage.common.persistence.entity.NodeInfoEntity
import com.r3.corda.networkmanage.common.signer.NetworkMap
import com.r3.corda.networkmanage.common.signer.SignedNetworkMap
import com.r3.corda.networkmanage.common.persistence.entity.*
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.sha256
import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize
import net.corda.nodeapi.internal.NetworkMap
import net.corda.nodeapi.internal.NetworkParameters
import net.corda.nodeapi.internal.SignedNetworkMap
import net.corda.nodeapi.internal.persistence.CordaPersistence
import org.hibernate.Session
import org.hibernate.jpa.QueryHints
/**
* Database implementation of the [NetworkMapStorage] interface
*/
class PersistentNetworkMapStorage(private val database: CordaPersistence) : NetworkMapStorage {
override fun getCurrentNetworkMap(): SignedNetworkMap? = database.transaction {
val networkMapEntity = getCurrentNetworkMapEntity(getNetworkMapWithNodeInfoAndParametersHint(session))
val networkMapEntity = getCurrentNetworkMapEntity()
networkMapEntity?.let {
val nodeInfoHashes = it.nodeInfoList.map { it.nodeInfoHash }
val networkParameterHash = it.parameters.parametersHash
val signatureAndCertPath = it.signatureAndCertificate()
SignedNetworkMap(NetworkMap(nodeInfoHashes, networkParameterHash), signatureAndCertPath!!)
SignedNetworkMap(SerializedBytes(it.networkMap), signatureAndCertPath)
}
}
override fun getCurrentNetworkParameters(): NetworkParameters? = database.transaction {
getCurrentNetworkMapEntity(getNetworkMapWithParametersHint(session))?.parameters?.networkParameters()
getCurrentNetworkMapEntity()?.let {
val parameterHash = it.networkMap.deserialize<NetworkMap>().networkParameterHash
getNetworkParameters(parameterHash)
}
}
override fun saveNetworkMap(signedNetworkMap: SignedNetworkMap) {
database.transaction {
val networkMap = signedNetworkMap.networkMap
val signatureAndCertPath = signedNetworkMap.signatureData
val signature = signatureAndCertPath.signature
val networkParametersEntity = getNetworkParametersEntity(networkMap.parametersHash)
networkParametersEntity ?: throw IllegalArgumentException("Error when retrieving network parameters entity for network map signing! - Entity does not exist")
val networkMapEntity = NetworkMapEntity(
parameters = networkParametersEntity,
signatureBytes = signature.bytes,
certificatePathBytes = signatureAndCertPath.certPath.serialize().bytes
networkMap = signedNetworkMap.raw.bytes,
signature = signedNetworkMap.sig.signatureBytes,
certificate = signedNetworkMap.sig.by.encoded
)
session.save(networkMapEntity)
networkMap.nodeInfoHashes.forEach {
val nodeInfoEntity = session.find(NodeInfoEntity::class.java, it)
session.merge(nodeInfoEntity.copy(networkMap = networkMapEntity))
}
}
}
override fun getNetworkParameters(parameterHash: SecureHash): NetworkParameters {
val entity = getNetworkParametersEntity(parameterHash.toString())
if (entity != null) {
return entity.networkParameters()
} else {
throw NoSuchElementException("Network parameters with $parameterHash do not exist")
}
}
override fun getCurrentNetworkMapNodeInfoHashes(certificateStatuses: List<CertificateStatus>): List<SecureHash> = database.transaction {
val networkMapEntity = getCurrentNetworkMapEntity(getNetworkMapWithNodeInfoAndCsrHint(session))
if (networkMapEntity != null) {
networkMapEntity.nodeInfoList.filter({
certificateStatuses.isEmpty() || certificateStatuses.contains(it.certificateSigningRequest?.certificateData?.certificateStatus)
}).map { SecureHash.parse(it.nodeInfoHash) }
} else {
emptyList()
}
override fun getNetworkParameters(parameterHash: SecureHash): NetworkParameters? {
return getNetworkParametersEntity(parameterHash.toString())?.networkParameters()
}
override fun putNetworkParameters(networkParameters: NetworkParameters): SecureHash = database.transaction {
override fun getNodeInfoHashes(certificateStatus: CertificateStatus): List<SecureHash> = database.transaction {
val builder = session.criteriaBuilder
val query = builder.createQuery(String::class.java).run {
from(NodeInfoEntity::class.java).run {
select(get<String>(NodeInfoEntity::nodeInfoHash.name))
.where(builder.equal(get<CertificateSigningRequestEntity>(NodeInfoEntity::certificateSigningRequest.name)
.get<CertificateDataEntity>(CertificateSigningRequestEntity::certificateData.name)
.get<CertificateStatus>(CertificateDataEntity::certificateStatus.name), certificateStatus))
}
}
session.createQuery(query).resultList.map { SecureHash.parse(it) }
}
override fun saveNetworkParameters(networkParameters: NetworkParameters): SecureHash = database.transaction {
val bytes = networkParameters.serialize().bytes
val hash = bytes.sha256()
session.save(NetworkParametersEntity(
@ -94,29 +81,16 @@ class PersistentNetworkMapStorage(private val database: CordaPersistence) : Netw
session.createQuery(query).resultList.first()
}
override fun getDetachedAndValidNodeInfoHashes(): List<SecureHash> = database.transaction {
val builder = session.criteriaBuilder
// Get signed NodeInfoEntities
val query = builder.createQuery(NodeInfoEntity::class.java).run {
from(NodeInfoEntity::class.java).run {
where(builder.and(
builder.isNull(get<ByteArray>(NodeInfoEntity::networkMap.name)),
builder.isNotNull(get<ByteArray>(NodeInfoEntity::signatureBytes.name))))
}
}
session.createQuery(query).resultList.map { SecureHash.parse(it.nodeInfoHash) }
}
private fun getCurrentNetworkMapEntity(hint: Pair<String, Any>): NetworkMapEntity? = database.transaction {
private fun getCurrentNetworkMapEntity(): NetworkMapEntity? = database.transaction {
val builder = session.criteriaBuilder
val query = builder.createQuery(NetworkMapEntity::class.java).run {
from(NetworkMapEntity::class.java).run {
where(builder.isNotNull(get<ByteArray?>(NetworkMapEntity::signatureBytes.name)))
where(builder.isNotNull(get<ByteArray?>(NetworkMapEntity::signature.name)))
orderBy(builder.desc(get<String>(NetworkMapEntity::version.name)))
}
}
// We just want the last signed entry
session.createQuery(query).setHint(hint.first, hint.second).resultList.firstOrNull()
session.createQuery(query).resultList.firstOrNull()
}
private fun getNetworkParametersEntity(parameterHash: String): NetworkParametersEntity? = database.transaction {
@ -124,33 +98,4 @@ class PersistentNetworkMapStorage(private val database: CordaPersistence) : Netw
builder.equal(path.get<String>(NetworkParametersEntity::parametersHash.name), parameterHash)
}
}
/**
* Creates Hibernate query hint for pulling [NetworkParametersEntity] when querying for [NetworkMapEntity]
*/
private fun getNetworkMapWithParametersHint(session: Session): Pair<String, Any> {
val graph = session.createEntityGraph(NetworkMapEntity::class.java)
graph.addAttributeNodes(NetworkMapEntity::parameters.name)
return QueryHints.HINT_LOADGRAPH to graph
}
/**
* Creates Hibernate query hint for pulling [NodeInfoEntity] and [CertificateSigningRequestEntity] when querying for [NetworkMapEntity]
*/
private fun getNetworkMapWithNodeInfoAndCsrHint(session: Session): Pair<String, Any> {
val graph = session.createEntityGraph(NetworkMapEntity::class.java)
val subGraph = graph.addSubgraph(NetworkMapEntity::nodeInfoList.name, NodeInfoEntity::class.java)
subGraph.addAttributeNodes(NodeInfoEntity::certificateSigningRequest.name)
return QueryHints.HINT_LOADGRAPH to graph
}
/**
* Creates Hibernate query hint for pulling [NodeInfoEntity] and [NetworkParametersEntity] when querying for [NetworkMapEntity]
*/
private fun getNetworkMapWithNodeInfoAndParametersHint(session: Session): Pair<String, Any> {
val graph = session.createEntityGraph(NetworkMapEntity::class.java)
graph.addAttributeNodes(NetworkMapEntity::nodeInfoList.name)
graph.addAttributeNodes(NetworkMapEntity::parameters.name)
return QueryHints.HINT_LOADGRAPH to graph
}
}

View File

@ -1,8 +1,7 @@
package com.r3.corda.networkmanage.common.persistence.entity
import com.r3.corda.networkmanage.common.signer.SignatureAndCertPath
import net.corda.core.crypto.DigitalSignature
import net.corda.core.serialization.deserialize
import net.corda.nodeapi.internal.DigitalSignatureWithCert
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
import javax.persistence.*
@Entity
@ -12,27 +11,23 @@ class NetworkMapEntity(
@GeneratedValue(strategy = GenerationType.SEQUENCE)
val version: Long? = null,
// Reverting relation ownership due to (potentially) unlimited number of node info items.
@OneToMany(mappedBy = "networkMap", fetch = FetchType.LAZY)
val nodeInfoList: List<NodeInfoEntity> = mutableListOf(),
@OneToOne
@JoinColumn(name = "network_parameters")
val parameters: NetworkParametersEntity,
@Lob
@Column(name = "serialized_network_map")
val networkMap: ByteArray,
@Lob
@Column(name = "signature_bytes")
val signatureBytes: ByteArray,
@Column(name = "signature")
val signature: ByteArray,
@Lob
@Column(name = "certificate_path_bytes")
val certificatePathBytes: ByteArray
@Column(name = "certificate")
val certificate: ByteArray
) {
/**
* Deserializes NetworkMapEntity.signatureBytes into the [SignatureAndCertPath] instance
*/
fun signatureAndCertificate(): SignatureAndCertPath? {
return SignatureAndCertPath(DigitalSignature(signatureBytes), certificatePathBytes.deserialize())
fun signatureAndCertificate(): DigitalSignatureWithCert {
return DigitalSignatureWithCert(X509CertificateFactory().generateCertificate(certificate.inputStream()), signature)
}
}

View File

@ -18,10 +18,6 @@ class NodeInfoEntity(
@JoinColumn(name = "certificate_signing_request", nullable = true)
val certificateSigningRequest: CertificateSigningRequestEntity? = null,
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "network_map", nullable = true)
val networkMap: NetworkMapEntity? = null,
@Lob
@Column(name = "node_info_bytes")
val nodeInfoBytes: ByteArray,
@ -55,7 +51,6 @@ class NodeInfoEntity(
}
fun copy(nodeInfoHash: String = this.nodeInfoHash,
networkMap: NetworkMapEntity? = this.networkMap,
certificateSigningRequest: CertificateSigningRequestEntity? = this.certificateSigningRequest,
nodeInfoBytes: ByteArray = this.nodeInfoBytes,
signatureBytes: ByteArray? = this.signatureBytes,
@ -68,8 +63,7 @@ class NodeInfoEntity(
nodeInfoBytes = nodeInfoBytes,
signatureBytes = signatureBytes,
signaturePublicKeyBytes = signaturePublicKeyBytes,
signaturePublicKeyAlgorithm = signaturePublicKeyAlgorithm,
networkMap = networkMap
signaturePublicKeyAlgorithm = signaturePublicKeyAlgorithm
)
}
}

View File

@ -2,43 +2,22 @@ package com.r3.corda.networkmanage.common.signer
import com.r3.corda.networkmanage.common.persistence.CertificateStatus
import com.r3.corda.networkmanage.common.persistence.NetworkMapStorage
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.serialize
import net.corda.nodeapi.internal.NetworkMap
import net.corda.nodeapi.internal.SignedNetworkMap
/**
* Encapsulates the network map signing procedure.
* To sign a network map following steps need to be done:
* 1) Collect all node info data that has been signed and has valid certificates
* 2) Retrieve most up-to-date network parameters
* 3) Sign hashed version of the network map
* 4) Persist network map data together with its signature
* Once the network map is signed it is considered to be the current network map.
*
* This class resides in the common package as it is intended to be used in both local and distributed deployments.
* This means that it can be executed by a remote (e.g. HSM) signing service or locally by Doorman.
*/
@CordaSerializable
data class NetworkMap(val nodeInfoHashes: List<String>, val parametersHash: String)
@CordaSerializable
data class SignedNetworkMap(val networkMap: NetworkMap, val signatureData: SignatureAndCertPath)
class NetworkMapSigner(private val networkMapStorage: NetworkMapStorage,
private val signer: Signer) {
class NetworkMapSigner(private val networkMapStorage: NetworkMapStorage, private val signer: Signer) {
/**
* Signs the network map.
*/
fun signNetworkMap() {
val currentSignedNetworkMap = networkMapStorage.getCurrentNetworkMap()
val currentNetworkMapValidNodeInfo = networkMapStorage.getCurrentNetworkMapNodeInfoHashes(listOf(CertificateStatus.VALID))
val detachedValidNodeInfo = networkMapStorage.getDetachedAndValidNodeInfoHashes()
val nodeInfoHashes = currentNetworkMapValidNodeInfo + detachedValidNodeInfo
val nodeInfoHashes = networkMapStorage.getNodeInfoHashes(CertificateStatus.VALID)
val networkParameters = networkMapStorage.getLatestNetworkParameters()
val networkMap = NetworkMap(nodeInfoHashes.map { it.toString() }, networkParameters.serialize().hash.toString())
if (networkMap != currentSignedNetworkMap?.networkMap) {
val networkMap = NetworkMap(nodeInfoHashes, networkParameters.serialize().hash)
if (networkMap != currentSignedNetworkMap?.verified()) {
val digitalSignature = signer.sign(networkMap.serialize().bytes)
require(digitalSignature != null) { "Error while signing network map." }
val signedHashedNetworkMap = SignedNetworkMap(networkMap, digitalSignature!!)
val signedHashedNetworkMap = SignedNetworkMap(networkMap.serialize(), digitalSignature)
networkMapStorage.saveNetworkMap(signedHashedNetworkMap)
}
}

View File

@ -2,19 +2,19 @@ package com.r3.corda.networkmanage.common.signer
import net.corda.core.crypto.DigitalSignature
import net.corda.core.serialization.CordaSerializable
import net.corda.nodeapi.internal.DigitalSignatureWithCert
import java.security.cert.CertPath
@CordaSerializable
data class SignatureAndCertPath(val signature: DigitalSignature, val certPath: CertPath)
/**
* An interface for arbitrary data signing functionality.
*/
interface Signer {
/**
* Signs given [data]. The signing key selction strategy is left to the implementing class.
* @return [SignatureAndCertPath] that encapsulates the signature and the certificate path used in the signing process.
* @throws [AuthenticationException] if fails authentication
*/
fun sign(data: ByteArray): SignatureAndCertPath?
fun sign(data: ByteArray): DigitalSignatureWithCert
}
class AuthenticationException : Exception()

View File

@ -4,7 +4,9 @@ import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import joptsimple.ArgumentAcceptingOptionSpec
import joptsimple.OptionParser
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.sha256
import net.corda.nodeapi.internal.DigitalSignatureWithCert
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
import org.bouncycastle.cert.X509CertificateHolder
import java.security.PublicKey
@ -41,3 +43,5 @@ fun X509CertificateHolder.toX509Certificate(): X509Certificate = X509Certificate
fun buildCertPath(vararg certificates: Certificate): CertPath = X509CertificateFactory().delegate.generateCertPath(certificates.asList())
fun buildCertPath(certPathBytes: ByteArray): CertPath = X509CertificateFactory().delegate.generateCertPath(certPathBytes.inputStream())
fun DigitalSignature.WithKey.withCert(cert: X509Certificate): DigitalSignatureWithCert = DigitalSignatureWithCert(cert, bytes)

View File

@ -11,7 +11,6 @@ import com.r3.corda.networkmanage.doorman.signer.JiraCsrHandler
import com.r3.corda.networkmanage.doorman.signer.LocalSigner
import com.r3.corda.networkmanage.doorman.webservice.NodeInfoWebService
import com.r3.corda.networkmanage.doorman.webservice.RegistrationWebService
import com.typesafe.config.ConfigFactory
import net.corda.core.crypto.Crypto
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.createDirectories
@ -32,6 +31,7 @@ import java.io.Closeable
import java.net.InetSocketAddress
import java.net.URI
import java.nio.file.Path
import java.security.cert.X509Certificate
import java.time.Instant
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
@ -190,7 +190,7 @@ fun startDoorman(hostAndPort: NetworkHostAndPort,
// Persisting new network parameters
val currentNetworkParameters = networkMapStorage.getCurrentNetworkParameters()
if (currentNetworkParameters == null) {
networkMapStorage.putNetworkParameters(networkMapParameters)
networkMapStorage.saveNetworkParameters(networkMapParameters)
} else {
throw UnsupportedOperationException("Network parameters already exist. Updating them via the file config is not supported yet.")
}
@ -242,8 +242,8 @@ private fun buildLocalSigner(parameters: DoormanParameters): LocalSigner? {
val caPrivateKeyPassword = parameters.caPrivateKeyPassword ?: readPassword("CA Private Key Password: ")
val keystore = loadOrCreateKeyStore(parameters.keystorePath, keystorePassword)
val caKeyPair = keystore.getKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, caPrivateKeyPassword)
val caCertPath = keystore.getCertificateChain(X509Utilities.CORDA_INTERMEDIATE_CA)
LocalSigner(caKeyPair, caCertPath)
val caCertPath = keystore.getCertificateChain(X509Utilities.CORDA_INTERMEDIATE_CA).map { it as X509Certificate }
LocalSigner(caKeyPair, caCertPath.toTypedArray())
}
}

View File

@ -71,7 +71,7 @@ class JiraCsrHandler(private val jiraClient: JiraClient, private val storage: Ce
jiraClient.getApprovedRequests().forEach { (id, approvedBy) -> storage.approveRequest(id, approvedBy) }
delegate.processApprovedRequests()
val signedRequests = storage.getRequests(RequestStatus.SIGNED).mapNotNull {
it.certData?.certPath.let { certs -> it.requestId to certs!! }
it.certData?.certPath?.let { certs -> it.requestId to certs }
}.toMap()
jiraClient.updateSignedRequests(signedRequests)
}

View File

@ -1,12 +1,13 @@
package com.r3.corda.networkmanage.doorman.signer
import com.r3.corda.networkmanage.common.signer.SignatureAndCertPath
import com.r3.corda.networkmanage.common.signer.Signer
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.sign
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.toX509CertHolder
import net.corda.nodeapi.internal.DigitalSignatureWithCert
import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509Utilities
import org.bouncycastle.asn1.x509.GeneralName
@ -16,13 +17,13 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
import java.security.KeyPair
import java.security.cert.CertPath
import java.security.cert.Certificate
import java.security.cert.X509Certificate
/**
* The [LocalSigner] class signs [PKCS10CertificationRequest] using provided CA key pair and certificate path.
* This is intended to be used in testing environment where hardware signing module is not available.
*/
class LocalSigner(private val caKeyPair: KeyPair, private val caCertPath: Array<Certificate>) : Signer {
class LocalSigner(private val caKeyPair: KeyPair, private val caCertPath: Array<X509Certificate>) : Signer {
fun createSignedClientCertificate(certificationRequest: PKCS10CertificationRequest): CertPath {
// The sub certs issued by the client must satisfy this directory name (or legal name in Corda) constraints, sub certs' directory name must be within client CA's name's subtree,
// please see [sun.security.x509.X500Name.isWithinSubtree()] for more information.
@ -41,7 +42,7 @@ class LocalSigner(private val caKeyPair: KeyPair, private val caCertPath: Array<
return buildCertPath(clientCertificate, *caCertPath)
}
override fun sign(data: ByteArray): SignatureAndCertPath {
return SignatureAndCertPath(caKeyPair.sign(data), buildCertPath(*caCertPath))
override fun sign(data: ByteArray): DigitalSignatureWithCert {
return caKeyPair.sign(data).withCert(caCertPath.first())
}
}

View File

@ -74,7 +74,7 @@ class NodeInfoWebService(private val nodeInfoStorage: NodeInfoStorage,
}
@GET
@Path("{nodeInfoHash}")
@Path("node-info/{nodeInfoHash}")
fun getNodeInfo(@PathParam("nodeInfoHash") nodeInfoHash: String): Response {
val nodeInfo = nodeInfoStorage.getNodeInfo(SecureHash.parse(nodeInfoHash))
return if (nodeInfo != null) {

View File

@ -1,6 +1,7 @@
package com.r3.corda.networkmanage.hsm.authentication
import CryptoServerJCE.CryptoServerProvider
import com.r3.corda.networkmanage.common.signer.AuthenticationException
import com.r3.corda.networkmanage.hsm.configuration.Parameters
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
@ -25,8 +26,8 @@ class Authenticator(private val provider: CryptoServerProvider,
* 1) [CryptoServerProvider] instance
* 2) List of strings that corresponds to user names authenticated against the HSM.
*/
fun connectAndAuthenticate(block: (CryptoServerProvider, List<String>) -> Unit) {
try {
fun <T : Any> connectAndAuthenticate(block: (CryptoServerProvider, List<String>) -> T): T {
return try {
val authenticated = mutableListOf<String>()
loop@ while (true) {
val user = if (autoUsername.isNullOrEmpty()) {
@ -78,6 +79,8 @@ class Authenticator(private val provider: CryptoServerProvider,
}
if (!authenticated.isEmpty()) {
block(provider, authenticated)
} else {
throw AuthenticationException()
}
} finally {
try {
@ -89,8 +92,8 @@ class Authenticator(private val provider: CryptoServerProvider,
}
}
}
/*
* Configuration class for [CryptoServerProvider]
*/
data class CryptoServerProviderConfig(

View File

@ -3,15 +3,17 @@ package com.r3.corda.networkmanage.hsm.signer
import com.google.common.util.concurrent.MoreExecutors
import com.r3.corda.networkmanage.common.persistence.NetworkMapStorage
import com.r3.corda.networkmanage.common.signer.NetworkMapSigner
import com.r3.corda.networkmanage.common.signer.SignatureAndCertPath
import com.r3.corda.networkmanage.common.signer.Signer
import com.r3.corda.networkmanage.common.utils.buildCertPath
import com.r3.corda.networkmanage.common.utils.withCert
import com.r3.corda.networkmanage.hsm.authentication.Authenticator
import com.r3.corda.networkmanage.hsm.utils.X509Utilities.getAndInitializeKeyStore
import com.r3.corda.networkmanage.hsm.utils.X509Utilities.signData
import com.r3.corda.networkmanage.hsm.utils.X509Utilities.verify
import net.corda.core.internal.cert
import net.corda.core.internal.toX509CertHolder
import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.minutes
import net.corda.nodeapi.internal.DigitalSignatureWithCert
import java.security.KeyPair
import java.security.PrivateKey
import java.time.Duration
@ -59,16 +61,14 @@ class HsmNetworkMapSigner(networkMapStorage: NetworkMapStorage,
/**
* Signs given data using [CryptoServerJCE.CryptoServerProvider], which connects to the underlying HSM.
*/
override fun sign(data: ByteArray): SignatureAndCertPath? {
var result: SignatureAndCertPath? = null
authenticator.connectAndAuthenticate { provider, _ ->
override fun sign(data: ByteArray): DigitalSignatureWithCert {
return authenticator.connectAndAuthenticate { provider, _ ->
val keyStore = getAndInitializeKeyStore(provider)
val caCertificateChain = keyStore.getCertificateChain(caCertificateKeyName)
val caKey = keyStore.getKey(caCertificateKeyName, caPrivateKeyPass.toCharArray()) as PrivateKey
val signature = signData(data, KeyPair(caCertificateChain.first().publicKey, caKey), provider)
verify(data, signature, caCertificateChain.first().publicKey)
result = SignatureAndCertPath(signature, buildCertPath(*caCertificateChain))
signature.withCert(caCertificateChain.first().toX509CertHolder().cert)
}
return result
}
}

View File

@ -11,7 +11,6 @@ import net.corda.core.identity.CordaX500Name
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 org.assertj.core.api.Assertions.assertThat
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.pkcs.PKCS10CertificationRequest

View File

@ -1,30 +1,30 @@
package com.r3.corda.networkmanage.common.persistence
import com.r3.corda.networkmanage.TestBase
import com.r3.corda.networkmanage.common.signer.NetworkMap
import com.r3.corda.networkmanage.common.signer.SignatureAndCertPath
import com.r3.corda.networkmanage.common.signer.SignedNetworkMap
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
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.NetworkMap
import net.corda.nodeapi.internal.SignedNetworkMap
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.common.internal.testNetworkParameters
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class DBNetworkMapStorageTest : TestBase() {
private lateinit var networkMapStorage: NetworkMapStorage
@ -57,7 +57,7 @@ class DBNetworkMapStorageTest : TestBase() {
val requestId = requestStorage.saveRequest(createRequest(organisation).first)
requestStorage.markRequestTicketCreated(requestId)
requestStorage.approveRequest(requestId, "TestUser")
val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val keyPair = Crypto.generateKeyPair()
val clientCert = X509Utilities.createCertificate(CertificateType.CLIENT_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = organisation, locality = "London", country = "GB"), keyPair.public)
val certPath = buildCertPath(clientCert.toX509Certificate(), intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate())
requestStorage.putCertificatePath(requestId, certPath, emptyList())
@ -67,25 +67,28 @@ class DBNetworkMapStorageTest : TestBase() {
val nodeInfoHash = nodeInfoStorage.putNodeInfo(SignedData(nodeInfoBytes, keyPair.sign(nodeInfoBytes)))
// Create network parameters
val networkParametersHash = networkMapStorage.putNetworkParameters(testNetworkParameters(emptyList()))
val networkParametersHash = networkMapStorage.saveNetworkParameters(testNetworkParameters(emptyList()))
val networkMap = NetworkMap(listOf(nodeInfoHash.toString()), networkParametersHash.toString())
val signatureData = SignatureAndCertPath(keyPair.sign(networkMap.serialize()), certPath)
val signedNetworkMap = SignedNetworkMap(NetworkMap(listOf(nodeInfoHash.toString()), networkParametersHash.toString()), signatureData)
val networkMap = NetworkMap(listOf(nodeInfoHash), networkParametersHash)
val serializedNetworkMap = networkMap.serialize()
val signatureData = intermediateCAKey.sign(serializedNetworkMap).withCert(intermediateCACert.cert)
val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, signatureData)
// when
networkMapStorage.saveNetworkMap(signedNetworkMap)
// then
val persistedSignedNetworkMap = networkMapStorage.getCurrentNetworkMap()
assertEquals(signedNetworkMap, persistedSignedNetworkMap)
assertEquals(signedNetworkMap.sig, persistedSignedNetworkMap?.sig)
assertEquals(signedNetworkMap.verified(), persistedSignedNetworkMap?.verified())
}
@Test
fun `getLatestNetworkParameters returns last inserted`() {
// given
networkMapStorage.putNetworkParameters(createNetworkParameters(minimumPlatformVersion = 1))
networkMapStorage.putNetworkParameters(createNetworkParameters(minimumPlatformVersion = 2))
networkMapStorage.saveNetworkParameters(createNetworkParameters(minimumPlatformVersion = 1))
networkMapStorage.saveNetworkParameters(createNetworkParameters(minimumPlatformVersion = 2))
// when
val latest = networkMapStorage.getLatestNetworkParameters()
@ -98,20 +101,20 @@ class DBNetworkMapStorageTest : TestBase() {
fun `getCurrentNetworkParameters returns current network map parameters`() {
// given
// Create network parameters
val networkMapParametersHash = networkMapStorage.putNetworkParameters(createNetworkParameters(1))
val networkMapParametersHash = networkMapStorage.saveNetworkParameters(createNetworkParameters(1))
// Create empty network map
val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val intermediateCert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCACert, intermediateCAKey, CordaX500Name(organisation = "Corda", locality = "London", country = "GB"), keyPair.public)
val certPath = buildCertPath(intermediateCert.toX509Certificate(), intermediateCACert.toX509Certificate(), rootCACert.toX509Certificate())
// Sign network map making it current network map
val hashedNetworkMap = NetworkMap(emptyList(), networkMapParametersHash.toString())
val signatureData = SignatureAndCertPath(keyPair.sign(hashedNetworkMap.serialize()), certPath)
val signedNetworkMap = SignedNetworkMap(hashedNetworkMap, signatureData)
val networkMap = NetworkMap(emptyList(), networkMapParametersHash)
val serializedNetworkMap = networkMap.serialize()
val signatureData = keyPair.sign(serializedNetworkMap).withCert(intermediateCert.cert)
val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, signatureData)
networkMapStorage.saveNetworkMap(signedNetworkMap)
// Create new network parameters
networkMapStorage.putNetworkParameters(createNetworkParameters(2))
networkMapStorage.saveNetworkParameters(createNetworkParameters(2))
// when
val result = networkMapStorage.getCurrentNetworkParameters()
@ -121,7 +124,7 @@ class DBNetworkMapStorageTest : TestBase() {
}
@Test
fun `getDetachedAndValidNodeInfoHashes returns only valid and signed node info hashes`() {
fun `getValidNodeInfoHashes returns only valid and signed node info hashes`() {
// given
// Create node info.
val organisationA = "TestA"
@ -148,19 +151,19 @@ class DBNetworkMapStorageTest : TestBase() {
val nodeInfoHashB = nodeInfoStorage.putNodeInfo(SignedData(nodeInfoBBytes, keyPair.sign(nodeInfoBBytes)))
// Create network parameters
val networkParametersHash = networkMapStorage.putNetworkParameters(createNetworkParameters())
val networkMap = NetworkMap(listOf(nodeInfoHashA.toString()), networkParametersHash.toString())
val signatureData = SignatureAndCertPath(keyPair.sign(networkMap.serialize()), certPathA)
val signedNetworkMap = SignedNetworkMap(networkMap, signatureData)
val networkParametersHash = networkMapStorage.saveNetworkParameters(createNetworkParameters())
val networkMap = NetworkMap(listOf(nodeInfoHashA), networkParametersHash)
val serializedNetworkMap = networkMap.serialize()
val signatureData = keyPair.sign(serializedNetworkMap).withCert(clientCertA.cert)
val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, signatureData)
// Sign network map
networkMapStorage.saveNetworkMap(signedNetworkMap)
// when
val detachedHashes = networkMapStorage.getDetachedAndValidNodeInfoHashes()
val validNodeInfoHash = networkMapStorage.getNodeInfoHashes(CertificateStatus.VALID)
// then
assertEquals(1, detachedHashes.size)
assertTrue(detachedHashes.contains(nodeInfoHashB))
assertThat(validNodeInfoHash).containsOnly(nodeInfoHashA, nodeInfoHashB)
}
}

View File

@ -3,9 +3,18 @@ package com.r3.corda.networkmanage.common.signer
import com.nhaarman.mockito_kotlin.*
import com.r3.corda.networkmanage.TestBase
import com.r3.corda.networkmanage.common.persistence.NetworkMapStorage
import com.r3.corda.networkmanage.common.utils.withCert
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.sha256
import net.corda.core.crypto.sign
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.cert
import net.corda.core.serialization.serialize
import net.corda.nodeapi.internal.NetworkMap
import net.corda.nodeapi.internal.SignedNetworkMap
import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509Utilities
import org.junit.Before
import org.junit.Test
import kotlin.test.assertEquals
@ -15,7 +24,10 @@ class NetworkMapSignerTest : TestBase() {
private lateinit var signer: Signer
private lateinit var networkMapStorage: NetworkMapStorage
private lateinit var networkMapSigner: NetworkMapSigner
private val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
private val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Node Root CA", locality = "London", organisation = "R3 LTD", country = "GB"), rootCAKey)
private val intermediateCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
private val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, CordaX500Name(commonName = "Corda Node Intermediate CA", locality = "London", organisation = "R3 LTD", country = "GB"), intermediateCAKey.public)
@Before
fun setUp() {
signer = mock()
@ -27,30 +39,29 @@ class NetworkMapSignerTest : TestBase() {
fun `signNetworkMap builds and signs network map`() {
// given
val signedNodeInfoHashes = listOf(SecureHash.randomSHA256(), SecureHash.randomSHA256())
val detachedNodeInfoHashes = listOf(SecureHash.randomSHA256())
val networkMapParameters = createNetworkParameters()
val serializedNetworkMap = NetworkMap(signedNodeInfoHashes, SecureHash.randomSHA256()).serialize()
whenever(networkMapStorage.getCurrentNetworkMap())
.thenReturn(SignedNetworkMap(NetworkMap(signedNodeInfoHashes.map { it.toString() }, "Dummy"), mock()))
whenever(networkMapStorage.getCurrentNetworkMapNodeInfoHashes(any())).thenReturn(signedNodeInfoHashes)
whenever(networkMapStorage.getDetachedAndValidNodeInfoHashes()).thenReturn(detachedNodeInfoHashes)
.thenReturn(SignedNetworkMap(serializedNetworkMap, intermediateCAKey.sign(serializedNetworkMap).withCert(intermediateCACert.cert)))
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(signedNodeInfoHashes)
whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkMapParameters)
whenever(signer.sign(any())).thenReturn(mock())
whenever(signer.sign(any())).then {
intermediateCAKey.sign(it.arguments.first() as ByteArray).withCert(intermediateCACert.cert)
}
// when
networkMapSigner.signNetworkMap()
// then
// Verify networkMapStorage calls
verify(networkMapStorage).getCurrentNetworkMapNodeInfoHashes(any())
verify(networkMapStorage).getDetachedAndValidNodeInfoHashes()
verify(networkMapStorage).getNodeInfoHashes(any())
verify(networkMapStorage).getLatestNetworkParameters()
argumentCaptor<SignedNetworkMap>().apply {
verify(networkMapStorage).saveNetworkMap(capture())
val networkMap = firstValue.networkMap
assertEquals(networkMapParameters.serialize().hash.toString(), networkMap.parametersHash)
assertEquals(signedNodeInfoHashes.size + detachedNodeInfoHashes.size, networkMap.nodeInfoHashes.size)
assertTrue(networkMap.nodeInfoHashes.containsAll(signedNodeInfoHashes.map { it.toString() }))
assertTrue(networkMap.nodeInfoHashes.containsAll(detachedNodeInfoHashes.map { it.toString() }))
val networkMap = firstValue.verified()
assertEquals(networkMapParameters.serialize().hash, networkMap.networkParameterHash)
assertEquals(signedNodeInfoHashes.size, networkMap.nodeInfoHashes.size)
assertTrue(networkMap.nodeInfoHashes.containsAll(signedNodeInfoHashes))
}
}
@ -59,11 +70,11 @@ class NetworkMapSignerTest : TestBase() {
// given
val networkMapParameters = createNetworkParameters()
val networkMapParametersHash = networkMapParameters.serialize().bytes.sha256()
val networkMap = NetworkMap(emptyList(), networkMapParametersHash.toString())
val signedNetworkMap = SignedNetworkMap(networkMap, mock())
val networkMap = NetworkMap(emptyList(), networkMapParametersHash)
val serializedNetworkMap = networkMap.serialize()
val signedNetworkMap = SignedNetworkMap(serializedNetworkMap, intermediateCAKey.sign(serializedNetworkMap).withCert(intermediateCACert.cert))
whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(signedNetworkMap)
whenever(networkMapStorage.getCurrentNetworkMapNodeInfoHashes(any())).thenReturn(emptyList())
whenever(networkMapStorage.getDetachedAndValidNodeInfoHashes()).thenReturn(emptyList())
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(emptyList())
whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkMapParameters)
// when
@ -79,23 +90,22 @@ class NetworkMapSignerTest : TestBase() {
// given
val networkMapParameters = createNetworkParameters()
whenever(networkMapStorage.getCurrentNetworkMap()).thenReturn(null)
whenever(networkMapStorage.getCurrentNetworkMapNodeInfoHashes(any())).thenReturn(emptyList())
whenever(networkMapStorage.getDetachedAndValidNodeInfoHashes()).thenReturn(emptyList())
whenever(networkMapStorage.getNodeInfoHashes(any())).thenReturn(emptyList())
whenever(networkMapStorage.getLatestNetworkParameters()).thenReturn(networkMapParameters)
whenever(signer.sign(any())).thenReturn(mock())
whenever(signer.sign(any())).then {
intermediateCAKey.sign(it.arguments.first() as ByteArray).withCert(intermediateCACert.cert)
}
// when
networkMapSigner.signNetworkMap()
// then
// Verify networkMapStorage calls
verify(networkMapStorage).getCurrentNetworkMapNodeInfoHashes(any())
verify(networkMapStorage).getDetachedAndValidNodeInfoHashes()
verify(networkMapStorage).getNodeInfoHashes(any())
verify(networkMapStorage).getLatestNetworkParameters()
argumentCaptor<SignedNetworkMap>().apply {
verify(networkMapStorage).saveNetworkMap(capture())
val networkMap = firstValue.networkMap
assertEquals(networkMapParameters.serialize().hash.toString(), networkMap.parametersHash)
val networkMap = firstValue.verified()
assertEquals(networkMapParameters.serialize().hash, networkMap.networkParameterHash)
}
}
}

View File

@ -6,18 +6,20 @@ import com.nhaarman.mockito_kotlin.times
import com.nhaarman.mockito_kotlin.verify
import com.r3.corda.networkmanage.common.persistence.NetworkMapStorage
import com.r3.corda.networkmanage.common.persistence.NodeInfoStorage
import com.r3.corda.networkmanage.common.signer.NetworkMap
import com.r3.corda.networkmanage.common.signer.SignedNetworkMap
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 com.r3.corda.networkmanage.doorman.webservice.NodeInfoWebService
import net.corda.core.crypto.*
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.cert
import net.corda.core.node.NodeInfo
import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.internal.NetworkMap
import net.corda.nodeapi.internal.SignedNetworkMap
import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.testing.SerializationEnvironmentRule
@ -97,16 +99,17 @@ class NodeInfoWebServiceTest {
@Test
fun `get network map`() {
val hashedNetworkMap = NetworkMap(listOf(SecureHash.randomSHA256().toString(), SecureHash.randomSHA256().toString()), SecureHash.randomSHA256().toString())
val networkMap = NetworkMap(listOf(SecureHash.randomSHA256(), SecureHash.randomSHA256()), SecureHash.randomSHA256())
val serializedNetworkMap = networkMap.serialize()
val networkMapStorage: NetworkMapStorage = mock {
on { getCurrentNetworkMap() }.thenReturn(SignedNetworkMap(hashedNetworkMap, mock()))
on { getCurrentNetworkMap() }.thenReturn(SignedNetworkMap(serializedNetworkMap, intermediateCAKey.sign(serializedNetworkMap).withCert(intermediateCACert.cert)))
}
DoormanServer(NetworkHostAndPort("localhost", 0), NodeInfoWebService(mock(), networkMapStorage)).use {
it.start()
val conn = URL("http://${it.hostAndPort}/${NodeInfoWebService.NETWORK_MAP_PATH}").openConnection() as HttpURLConnection
val signedHashedNetworkMap = conn.inputStream.readBytes().deserialize<SignedNetworkMap>()
val signedNetworkMap = conn.inputStream.readBytes().deserialize<SignedNetworkMap>()
verify(networkMapStorage, times(1)).getCurrentNetworkMap()
assertEquals(signedHashedNetworkMap.networkMap, hashedNetworkMap)
assertEquals(signedNetworkMap.verified(), networkMap)
}
}
@ -126,7 +129,7 @@ class NodeInfoWebServiceTest {
DoormanServer(NetworkHostAndPort("localhost", 0), NodeInfoWebService(nodeInfoStorage, mock())).use {
it.start()
val nodeInfoURL = URL("http://${it.hostAndPort}/${NodeInfoWebService.NETWORK_MAP_PATH}/$nodeInfoHash")
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>>()
verify(nodeInfoStorage, times(1)).getNodeInfo(nodeInfoHash)

View File

@ -3,9 +3,10 @@ package com.r3.corda.networkmanage.hsm.authentication
import CryptoServerJCE.CryptoServerProvider
import com.nhaarman.mockito_kotlin.*
import com.r3.corda.networkmanage.TestBase
import com.r3.corda.networkmanage.common.signer.AuthenticationException
import org.junit.Before
import org.junit.Test
import kotlin.test.assertFalse
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
class AuthenticatorTest : TestBase() {
@ -24,15 +25,15 @@ class AuthenticatorTest : TestBase() {
fun `connectAndAuthenticate aborts when user inputs Q`() {
// given
givenUserConsoleInputOnReadLine("Q")
var executed = false
// when
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _ -> executed = true }
assertFailsWith<AuthenticationException> {
Authenticator(provider = provider, inputReader = inputReader).connectAndAuthenticate { _, _ -> }
}
// then
assertFalse(executed)
verify(provider, never()).loginPassword(any<String>(), any<String>())
verify(provider, never()).loginSign(any<String>(), any<String>(), any<String>())
//then
verify(provider, never()).loginPassword(any(), any<String>())
verify(provider, never()).loginSign(any(), any(), any())
}
@Test
@ -50,7 +51,7 @@ class AuthenticatorTest : TestBase() {
// then
verify(provider).loginPassword(username, password)
verify(provider, never()).loginSign(any<String>(), any<String>(), any<String>())
verify(provider, never()).loginSign(any(), any(), any())
assertTrue(executed)
}
@ -67,7 +68,7 @@ class AuthenticatorTest : TestBase() {
// then
verify(provider).loginSign(username, ":cs2:cyb:USB0", null)
verify(provider, never()).loginPassword(any<String>(), any<String>())
verify(provider, never()).loginPassword(any(), any<String>())
assertTrue(executed)
}
@ -86,7 +87,7 @@ class AuthenticatorTest : TestBase() {
// then
verify(provider, times(3)).loginPassword(username, password)
verify(provider, never()).loginSign(any<String>(), any<String>(), any<String>())
verify(provider, never()).loginSign(any(), any(), any())
assertTrue(executed)
}
@ -98,7 +99,7 @@ class AuthenticatorTest : TestBase() {
}
private fun givenUserConsoleInputOnReadPassword(input: String) {
whenever(inputReader.readPassword(any<String>())).thenReturn(input)
whenever(inputReader.readPassword(any())).thenReturn(input)
}
private fun givenUserConsoleInputOnReadLine(input: String) {