mirror of
https://github.com/corda/corda.git
synced 2025-06-19 15:43:52 +00:00
Change party to hold an X.500 name
Change the legal name of parties to be an X500 name. This ensures that we aren't converting between common names and X500 names in various places, eliminating substantial scope for error in the conversion process. As a result, all node names must now be full X500 names, which has impact on most configurations.
This commit is contained in:
@ -5,6 +5,7 @@ import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.commonName
|
||||
import net.corda.core.div
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
@ -19,6 +20,9 @@ import net.corda.node.services.transactions.BFTNonValidatingNotaryService
|
||||
import net.corda.node.utilities.ServiceIdentityGenerator
|
||||
import net.corda.node.utilities.transaction
|
||||
import net.corda.testing.node.NodeBasedTest
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x500.X500NameBuilder
|
||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
||||
import org.junit.Test
|
||||
import java.security.KeyPair
|
||||
import java.util.*
|
||||
@ -27,7 +31,19 @@ import kotlin.test.assertFailsWith
|
||||
|
||||
class BFTNotaryServiceTests : NodeBasedTest() {
|
||||
private companion object {
|
||||
val notaryCommonName = "BFT Notary Server"
|
||||
val notaryCommonName = X500Name("CN=BFT Notary Server,O=R3,OU=corda,L=Zurich,C=CH")
|
||||
|
||||
fun buildNodeName(it: Int, notaryName: X500Name): X500Name {
|
||||
val builder = X500NameBuilder()
|
||||
notaryName.rdNs.map { it.first }.forEach { attr ->
|
||||
if (attr.type == BCStyle.CN) {
|
||||
builder.addRDN(BCStyle.CN, "${attr.value}-$it")
|
||||
} else {
|
||||
builder.addRDN(attr)
|
||||
}
|
||||
}
|
||||
return builder.build()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -73,13 +89,13 @@ class BFTNotaryServiceTests : NodeBasedTest() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun startBFTNotaryCluster(notaryName: String,
|
||||
private fun startBFTNotaryCluster(notaryName: X500Name,
|
||||
clusterSize: Int,
|
||||
serviceType: ServiceType): List<Node> {
|
||||
require(clusterSize > 0)
|
||||
val quorum = (2 * clusterSize + 1) / 3
|
||||
ServiceIdentityGenerator.generateToDisk(
|
||||
(0 until clusterSize).map { tempFolder.root.toPath() / "$notaryName-$it" },
|
||||
(0 until clusterSize).map { tempFolder.root.toPath() / "${notaryName.commonName}-$it" },
|
||||
serviceType.id,
|
||||
notaryName,
|
||||
quorum)
|
||||
@ -87,7 +103,7 @@ class BFTNotaryServiceTests : NodeBasedTest() {
|
||||
val serviceInfo = ServiceInfo(serviceType, notaryName)
|
||||
val nodes = (0 until clusterSize).map {
|
||||
startNode(
|
||||
"$notaryName-$it",
|
||||
buildNodeName(it, notaryName),
|
||||
advertisedServices = setOf(serviceInfo),
|
||||
configOverrides = mapOf("notaryNodeId" to it)
|
||||
).getOrThrow()
|
||||
|
@ -15,6 +15,7 @@ import net.corda.flows.NotaryFlow
|
||||
import net.corda.node.internal.AbstractNode
|
||||
import net.corda.node.utilities.transaction
|
||||
import net.corda.testing.node.NodeBasedTest
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Test
|
||||
import java.security.KeyPair
|
||||
import java.util.*
|
||||
@ -22,7 +23,7 @@ import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
class RaftNotaryServiceTests : NodeBasedTest() {
|
||||
private val notaryName = "CN=RAFT Notary Service,O=R3,OU=corda,L=London,C=UK"
|
||||
private val notaryName = X500Name("CN=RAFT Notary Service,O=R3,OU=corda,L=London,C=UK")
|
||||
|
||||
@Test
|
||||
fun `detect double spend`() {
|
||||
|
@ -5,6 +5,8 @@ import com.google.common.util.concurrent.Futures
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.utilities.ALICE
|
||||
import net.corda.core.utilities.BOB
|
||||
import net.corda.core.utilities.unwrap
|
||||
import net.corda.testing.node.NodeBasedTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@ -14,8 +16,8 @@ class FlowVersioningTest : NodeBasedTest() {
|
||||
@Test
|
||||
fun `core flows receive platform version of initiator`() {
|
||||
val (alice, bob) = Futures.allAsList(
|
||||
startNode("Alice", platformVersion = 2),
|
||||
startNode("Bob", platformVersion = 3)).getOrThrow()
|
||||
startNode(ALICE.name, platformVersion = 2),
|
||||
startNode(BOB.name, platformVersion = 3)).getOrThrow()
|
||||
bob.installCoreFlow(ClientFlow::class, ::SendBackPlatformVersionFlow)
|
||||
val resultFuture = alice.services.startFlow(ClientFlow(bob.info.legalIdentity)).resultFuture
|
||||
assertThat(resultFuture.getOrThrow()).isEqualTo(2)
|
||||
|
@ -4,6 +4,7 @@ import com.google.common.util.concurrent.Futures
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import net.corda.core.*
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.crypto.commonName
|
||||
import net.corda.core.messaging.MessageRecipients
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
import net.corda.core.node.services.DEFAULT_SESSION_ID
|
||||
@ -18,6 +19,7 @@ import net.corda.node.services.transactions.RaftValidatingNotaryService
|
||||
import net.corda.node.services.transactions.SimpleNotaryService
|
||||
import net.corda.node.utilities.ServiceIdentityGenerator
|
||||
import net.corda.testing.freeLocalHostAndPort
|
||||
import net.corda.testing.getTestX509Name
|
||||
import net.corda.testing.node.NodeBasedTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
@ -30,8 +32,8 @@ import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class P2PMessagingTest : NodeBasedTest() {
|
||||
private companion object {
|
||||
val DISTRIBUTED_SERVICE_NAME = X509Utilities.getDevX509Name("DistributedService")
|
||||
val SERVICE_2_NAME = X509Utilities.getDevX509Name("Service Node 2")
|
||||
val DISTRIBUTED_SERVICE_NAME = getTestX509Name("DistributedService")
|
||||
val SERVICE_2_NAME = getTestX509Name("Service Node 2")
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -65,7 +67,7 @@ class P2PMessagingTest : NodeBasedTest() {
|
||||
|
||||
val root = tempFolder.root.toPath()
|
||||
ServiceIdentityGenerator.generateToDisk(
|
||||
listOf(root / DUMMY_MAP.name.toString(), root / SERVICE_2_NAME.toString()),
|
||||
listOf(root / DUMMY_MAP.name.commonName, root / SERVICE_2_NAME.commonName),
|
||||
RaftValidatingNotaryService.type.id,
|
||||
DISTRIBUTED_SERVICE_NAME)
|
||||
|
||||
@ -96,7 +98,7 @@ class P2PMessagingTest : NodeBasedTest() {
|
||||
|
||||
@Test
|
||||
fun `distributed service requests are retried if one of the nodes in the cluster goes down without sending a response`() {
|
||||
val distributedServiceNodes = startNotaryCluster("DistributedService", 2).getOrThrow()
|
||||
val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow()
|
||||
val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow()
|
||||
val serviceAddress = alice.services.networkMapCache.run {
|
||||
alice.net.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!)
|
||||
@ -121,7 +123,7 @@ class P2PMessagingTest : NodeBasedTest() {
|
||||
|
||||
@Test
|
||||
fun `distributed service request retries are persisted across client node restarts`() {
|
||||
val distributedServiceNodes = startNotaryCluster("DistributedService", 2).getOrThrow()
|
||||
val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow()
|
||||
val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow()
|
||||
val serviceAddress = alice.services.networkMapCache.run {
|
||||
alice.net.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!)
|
||||
@ -194,7 +196,7 @@ class P2PMessagingTest : NodeBasedTest() {
|
||||
node.respondWith(node.info)
|
||||
}
|
||||
val serviceAddress = originatingNode.services.networkMapCache.run {
|
||||
originatingNode.net.getAddressOfParty(getPartyInfo(getNotary(serviceName.toString())!!)!!)
|
||||
originatingNode.net.getAddressOfParty(getPartyInfo(getNotary(serviceName)!!)!!)
|
||||
}
|
||||
val participatingNodes = HashSet<Any>()
|
||||
// Try several times so that we can be fairly sure that any node not participating is not due to Artemis' selection
|
||||
|
@ -2,6 +2,7 @@ package net.corda.services.messaging
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.crypto.commonName
|
||||
import net.corda.core.div
|
||||
import net.corda.core.getOrThrow
|
||||
@ -33,22 +34,22 @@ class P2PSecurityTest : NodeBasedTest() {
|
||||
|
||||
@Test
|
||||
fun `incorrect legal name for the network map service config`() {
|
||||
val incorrectNetworkMapName = random63BitValue().toString()
|
||||
val incorrectNetworkMapName = X509Utilities.getDevX509Name(random63BitValue().toString())
|
||||
val node = startNode(BOB.name, configOverrides = mapOf(
|
||||
"networkMapService" to mapOf(
|
||||
"address" to networkMapNode.configuration.p2pAddress.toString(),
|
||||
"legalName" to incorrectNetworkMapName
|
||||
"legalName" to incorrectNetworkMapName.toString()
|
||||
)
|
||||
))
|
||||
// The connection will be rejected as the legal name doesn't match
|
||||
assertThatThrownBy { node.getOrThrow() }.hasMessageContaining(incorrectNetworkMapName)
|
||||
assertThatThrownBy { node.getOrThrow() }.hasMessageContaining(incorrectNetworkMapName.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `register with the network map service using a legal name different from the TLS CN`() {
|
||||
startSimpleNode(X500Name(DUMMY_BANK_A.name)).use {
|
||||
startSimpleNode(DUMMY_BANK_A.name).use {
|
||||
// Register with the network map using a different legal name
|
||||
val response = it.registerWithNetworkMap(X500Name(DUMMY_BANK_B.name))
|
||||
val response = it.registerWithNetworkMap(DUMMY_BANK_B.name)
|
||||
// We don't expect a response because the network map's host verification will prevent a connection back
|
||||
// to the attacker as the TLS CN will not match the legal name it has just provided
|
||||
assertThatExceptionOfType(TimeoutException::class.java).isThrownBy {
|
||||
|
@ -63,23 +63,6 @@ private val log: Logger = loggerFor<DriverDSL>()
|
||||
* This is the interface that's exposed to DSL users.
|
||||
*/
|
||||
interface DriverDSLExposedInterface {
|
||||
/**
|
||||
* Starts a [net.corda.node.internal.Node] in a separate process.
|
||||
*
|
||||
* @param providedName Name of the node, which will be its legal name in [Party].
|
||||
* Note that this must be unique as the driver uses it as a primary key!
|
||||
* @param advertisedServices The set of services to be advertised by the node. Defaults to empty set.
|
||||
* @param verifierType The type of transaction verifier to use. See: [VerifierType]
|
||||
* @param rpcUsers List of users who are authorised to use the RPC system. Defaults to empty list.
|
||||
* @return The [NodeInfo] of the started up node retrieved from the network map service.
|
||||
*/
|
||||
@Deprecated("To be removed once X500Name is used as legal name everywhere")
|
||||
fun startNode(providedName: String?,
|
||||
advertisedServices: Set<ServiceInfo> = emptySet(),
|
||||
rpcUsers: List<User> = emptyList(),
|
||||
verifierType: VerifierType = VerifierType.InMemory,
|
||||
customOverrides: Map<String, Any?> = emptyMap()): ListenableFuture<NodeHandle>
|
||||
|
||||
/**
|
||||
* Starts a [net.corda.node.internal.Node] in a separate process.
|
||||
*
|
||||
@ -107,7 +90,7 @@ interface DriverDSLExposedInterface {
|
||||
* @return The [Party] identity of the distributed notary service, and the [NodeInfo]s of the notaries in the cluster.
|
||||
*/
|
||||
fun startNotaryCluster(
|
||||
notaryName: String,
|
||||
notaryName: X500Name,
|
||||
clusterSize: Int = 3,
|
||||
type: ServiceType = RaftValidatingNotaryService.type,
|
||||
verifierType: VerifierType = VerifierType.InMemory,
|
||||
@ -444,25 +427,13 @@ class DriverDSL(
|
||||
verifierType: VerifierType,
|
||||
customOverrides: Map<String, Any?>
|
||||
): ListenableFuture<NodeHandle> {
|
||||
return startNode(providedName?.toString(), advertisedServices, rpcUsers, verifierType, customOverrides)
|
||||
}
|
||||
|
||||
override fun startNode(providedName: String?,
|
||||
advertisedServices: Set<ServiceInfo>,
|
||||
rpcUsers: List<User>,
|
||||
verifierType: VerifierType,
|
||||
customOverrides: Map<String, Any?>): ListenableFuture<NodeHandle> {
|
||||
val p2pAddress = portAllocation.nextHostAndPort()
|
||||
val rpcAddress = portAllocation.nextHostAndPort()
|
||||
val webAddress = portAllocation.nextHostAndPort()
|
||||
val debugPort = if (isDebug) debugPortAllocation.nextPort() else null
|
||||
val name = providedName.toString() ?: X509Utilities.getDevX509Name("${pickA(name).commonName}-${p2pAddress.port}").toString()
|
||||
val commonName = try {
|
||||
X500Name(name).commonName
|
||||
} catch(ex: IllegalArgumentException) {
|
||||
name
|
||||
}
|
||||
val baseDirectory = driverDirectory / commonName
|
||||
// TODO: Derive name from the full picked name, don't just wrap the common name
|
||||
val name = providedName ?: X509Utilities.getDevX509Name("${pickA(name).commonName}-${p2pAddress.port}")
|
||||
val baseDirectory = driverDirectory / name.commonName
|
||||
val configOverrides = mapOf(
|
||||
"myLegalName" to name.toString(),
|
||||
"p2pAddress" to p2pAddress.toString(),
|
||||
@ -471,7 +442,7 @@ class DriverDSL(
|
||||
"extraAdvertisedServiceIds" to advertisedServices.map { it.toString() },
|
||||
"networkMapService" to mapOf(
|
||||
"address" to networkMapAddress.toString(),
|
||||
"legalName" to networkMapLegalName
|
||||
"legalName" to networkMapLegalName.toString()
|
||||
),
|
||||
"useTestClock" to useTestClock,
|
||||
"rpcUsers" to rpcUsers.map {
|
||||
@ -503,14 +474,23 @@ class DriverDSL(
|
||||
}
|
||||
|
||||
override fun startNotaryCluster(
|
||||
notaryName: String,
|
||||
notaryName: X500Name,
|
||||
clusterSize: Int,
|
||||
type: ServiceType,
|
||||
verifierType: VerifierType,
|
||||
rpcUsers: List<User>
|
||||
): ListenableFuture<Pair<Party, List<NodeHandle>>> {
|
||||
val nodeNames = (1..clusterSize).map { "Notary Node $it" }
|
||||
val paths = nodeNames.map { driverDirectory / it }
|
||||
val nodeNames = (1..clusterSize).map {
|
||||
val nameBuilder = X500NameBuilder(BCStyle.INSTANCE)
|
||||
nameBuilder.addRDN(BCStyle.CN, "${DUMMY_NOTARY.name.commonName} $it")
|
||||
DUMMY_NOTARY.name.rdNs.forEach { rdn ->
|
||||
if (rdn.first.type != BCStyle.CN) {
|
||||
nameBuilder.addRDN(rdn.first)
|
||||
}
|
||||
}
|
||||
nameBuilder.build()
|
||||
}
|
||||
val paths = nodeNames.map { driverDirectory / it.commonName }
|
||||
ServiceIdentityGenerator.generateToDisk(paths, type.id, notaryName)
|
||||
|
||||
val serviceInfo = ServiceInfo(type, notaryName)
|
||||
@ -567,17 +547,12 @@ class DriverDSL(
|
||||
override fun startNetworkMapService() {
|
||||
val debugPort = if (isDebug) debugPortAllocation.nextPort() else null
|
||||
val apiAddress = portAllocation.nextHostAndPort().toString()
|
||||
val nodeDirectoryName = try {
|
||||
X500Name(networkMapLegalName).commonName
|
||||
} catch(ex: IllegalArgumentException) {
|
||||
networkMapLegalName
|
||||
}
|
||||
val baseDirectory = driverDirectory / nodeDirectoryName
|
||||
val baseDirectory = driverDirectory / networkMapLegalName.commonName
|
||||
val config = ConfigHelper.loadConfig(
|
||||
baseDirectory = baseDirectory,
|
||||
allowMissingConfig = true,
|
||||
configOverrides = mapOf(
|
||||
"myLegalName" to networkMapLegalName,
|
||||
"myLegalName" to networkMapLegalName.toString(),
|
||||
// TODO: remove the webAddress as NMS doesn't need to run a web server. This will cause all
|
||||
// node port numbers to be shifted, so all demos and docs need to be updated accordingly.
|
||||
"webAddress" to apiAddress,
|
||||
@ -593,9 +568,9 @@ class DriverDSL(
|
||||
|
||||
companion object {
|
||||
val name = arrayOf(
|
||||
X500Name(ALICE.name),
|
||||
X500Name(BOB.name),
|
||||
X500Name(DUMMY_BANK_A.name)
|
||||
ALICE.name,
|
||||
BOB.name,
|
||||
DUMMY_BANK_A.name
|
||||
)
|
||||
|
||||
fun <A> pickA(array: Array<A>): A = array[Math.abs(Random().nextInt()) % array.size]
|
||||
|
@ -58,6 +58,7 @@ import net.corda.node.utilities.AffinityExecutor
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.node.utilities.transaction
|
||||
import org.apache.activemq.artemis.utils.ReusableLatch
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.slf4j.Logger
|
||||
import java.io.IOException
|
||||
@ -338,7 +339,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
protected open fun makeServiceEntries(): List<ServiceEntry> {
|
||||
return advertisedServices.map {
|
||||
val serviceId = it.type.id
|
||||
val serviceName = it.name ?: "ou=$serviceId,${configuration.myLegalName}"
|
||||
val serviceName = it.name ?: X500Name("CN=$serviceId,${configuration.myLegalName}")
|
||||
val identity = obtainKeyPair(configuration.baseDirectory, serviceId + "-private-key", serviceId + "-public", serviceName).first
|
||||
ServiceEntry(it, identity)
|
||||
}
|
||||
@ -558,7 +559,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
protected fun obtainLegalIdentity(): Party = obtainKeyPair(configuration.baseDirectory, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).first
|
||||
protected fun obtainLegalIdentityKey(): KeyPair = obtainKeyPair(configuration.baseDirectory, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).second
|
||||
|
||||
private fun obtainKeyPair(dir: Path, privateKeyFileName: String, publicKeyFileName: String, serviceName: String? = null): Pair<Party, KeyPair> {
|
||||
private fun obtainKeyPair(dir: Path, privateKeyFileName: String, publicKeyFileName: String, serviceName: X500Name? = null): Pair<Party, KeyPair> {
|
||||
// Load the private identity key, creating it if necessary. The identity key is a long term well known key that
|
||||
// is distributed to other peers and we use it (or a key signed by it) when we need to do something
|
||||
// "permissioned". The identity file is what gets distributed and contains the node's legal name along with
|
||||
@ -566,13 +567,13 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
// the legal name is actually validated in some way.
|
||||
val privKeyFile = dir / privateKeyFileName
|
||||
val pubIdentityFile = dir / publicKeyFileName
|
||||
val identityName = serviceName ?: configuration.myLegalName.toString()
|
||||
val identityPrincipal: X500Name = serviceName ?: configuration.myLegalName
|
||||
|
||||
val identityAndKey = if (!privKeyFile.exists()) {
|
||||
log.info("Identity key not found, generating fresh key!")
|
||||
val keyPair: KeyPair = generateKeyPair()
|
||||
keyPair.serialize().writeToFile(privKeyFile)
|
||||
val myIdentity = Party(identityName, keyPair.public)
|
||||
val myIdentity = Party(identityPrincipal, keyPair.public)
|
||||
// We include the Party class with the file here to help catch mixups when admins provide files of the
|
||||
// wrong type by mistake.
|
||||
myIdentity.serialize().writeToFile(pubIdentityFile)
|
||||
@ -582,9 +583,9 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
// This is just a sanity check. It shouldn't fail unless the admin has fiddled with the files and messed
|
||||
// things up for us.
|
||||
val myIdentity = pubIdentityFile.readAll().deserialize<Party>()
|
||||
if (myIdentity.name != identityName)
|
||||
if (myIdentity.name != identityPrincipal)
|
||||
throw ConfigurationException("The legal name in the config file doesn't match the stored identity file:" +
|
||||
"$identityName vs ${myIdentity.name}")
|
||||
"$identityPrincipal vs ${myIdentity.name}")
|
||||
// Load the private key.
|
||||
val keyPair = privKeyFile.readAll().deserialize<KeyPair>()
|
||||
Pair(myIdentity, keyPair)
|
||||
|
@ -173,6 +173,7 @@ class CordaRPCOpsImpl(
|
||||
|
||||
override fun waitUntilRegisteredWithNetworkMap() = services.networkMapCache.mapServiceRegistered
|
||||
override fun partyFromKey(key: PublicKey) = services.identityService.partyFromKey(key)
|
||||
@Deprecated("Use partyFromX500Name instead")
|
||||
override fun partyFromName(name: String) = services.identityService.partyFromName(name)
|
||||
override fun partyFromX500Name(x500Name: X500Name)= services.identityService.partyFromX500Name(x500Name)
|
||||
|
||||
|
@ -30,6 +30,7 @@ import net.corda.node.services.transactions.RaftValidatingNotaryService
|
||||
import net.corda.node.utilities.AddressUtils
|
||||
import net.corda.node.utilities.AffinityExecutor
|
||||
import net.corda.nodeapi.ArtemisMessagingComponent.NetworkMapAddress
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.slf4j.Logger
|
||||
import java.io.RandomAccessFile
|
||||
import java.lang.management.ManagementFactory
|
||||
@ -317,4 +318,4 @@ class Node(override val configuration: FullNodeConfiguration,
|
||||
|
||||
class ConfigurationException(message: String) : Exception(message)
|
||||
|
||||
data class NetworkMapInfo(val address: HostAndPort, val legalName: String)
|
||||
data class NetworkMapInfo(val address: HostAndPort, val legalName: X500Name)
|
||||
|
@ -7,8 +7,8 @@ import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.core.utilities.trace
|
||||
import java.security.PublicKey
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.security.PublicKey
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
@ -23,20 +23,21 @@ class InMemoryIdentityService : SingletonSerializeAsToken(), IdentityService {
|
||||
}
|
||||
|
||||
private val keyToParties = ConcurrentHashMap<PublicKey, Party>()
|
||||
private val nameToParties = ConcurrentHashMap<String, Party>()
|
||||
private val principalToParties = ConcurrentHashMap<X500Name, Party>()
|
||||
|
||||
override fun registerIdentity(party: Party) {
|
||||
log.trace { "Registering identity $party" }
|
||||
keyToParties[party.owningKey] = party
|
||||
nameToParties[party.name] = party
|
||||
principalToParties[party.name] = party
|
||||
}
|
||||
|
||||
// We give the caller a copy of the data set to avoid any locking problems
|
||||
override fun getAllIdentities(): Iterable<Party> = ArrayList(keyToParties.values)
|
||||
|
||||
override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]
|
||||
override fun partyFromName(name: String): Party? = nameToParties[name]
|
||||
override fun partyFromX500Name(principal: X500Name): Party? = nameToParties[principal.toString()]
|
||||
@Deprecated("Use partyFromX500Name")
|
||||
override fun partyFromName(name: String): Party? = principalToParties[X500Name(name)]
|
||||
override fun partyFromX500Name(principal: X500Name): Party? = principalToParties[principal]
|
||||
override fun partyFromAnonymous(party: AnonymousParty): Party? = partyFromKey(party.owningKey)
|
||||
override fun partyFromAnonymous(partyRef: PartyAndReference) = partyFromAnonymous(partyRef.party)
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
.loadCertificateFromKeyStore(config.keyStoreFile, config.keyStorePassword, CORDA_CLIENT_CA)
|
||||
val ourSubjectDN = X500Name(ourCertificate.subjectDN.name)
|
||||
// This is a sanity check and should not fail unless things have been misconfigured
|
||||
require(ourSubjectDN.commonName == config.myLegalName.commonName) {
|
||||
require(ourSubjectDN == config.myLegalName) {
|
||||
"Legal name does not match with our subject CN: $ourSubjectDN"
|
||||
}
|
||||
val defaultCertPolicies = mapOf(
|
||||
@ -346,7 +346,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
}
|
||||
}
|
||||
|
||||
private fun deployBridge(address: ArtemisPeerAddress, legalName: String) {
|
||||
private fun deployBridge(address: ArtemisPeerAddress, legalName: X500Name) {
|
||||
deployBridge(address.queueName, address.hostAndPort, legalName)
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
* as defined by ArtemisAddress.queueName. A bridge is then created to forward messages from this queue to the node's
|
||||
* P2P address.
|
||||
*/
|
||||
private fun deployBridge(queueName: String, target: HostAndPort, legalName: String) {
|
||||
private fun deployBridge(queueName: String, target: HostAndPort, legalName: X500Name) {
|
||||
val connectionDirection = ConnectionDirection.Outbound(
|
||||
connectorFactoryClassName = VerifyingNettyConnectorFactory::class.java.name,
|
||||
expectedCommonName = legalName
|
||||
@ -401,7 +401,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
internal fun hostVerificationFail(peerLegalName: X500Name, expectedLegalName: X500Name) {
|
||||
log.error("Peer has wrong CN - expected $expectedLegalName but got $peerLegalName. This is either a fatal " +
|
||||
"misconfiguration by the remote peer or an SSL man-in-the-middle attack!")
|
||||
if (expectedLegalName.toString() == config.networkMapService?.legalName) {
|
||||
if (expectedLegalName == config.networkMapService?.legalName) {
|
||||
// If the peer that failed host verification was the network map node then we're in big trouble and need to bail!
|
||||
_networkMapConnectionFuture!!.setException(IOException("${config.networkMapService} failed host verification check"))
|
||||
}
|
||||
@ -409,7 +409,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
|
||||
// This is called on one of Artemis' background threads
|
||||
internal fun onTcpConnection(peerLegalName: X500Name) {
|
||||
if (peerLegalName.toString() == config.networkMapService?.legalName) {
|
||||
if (peerLegalName == config.networkMapService?.legalName) {
|
||||
_networkMapConnectionFuture!!.set(Unit)
|
||||
}
|
||||
}
|
||||
@ -437,14 +437,12 @@ private class VerifyingNettyConnector(configuration: MutableMap<String, Any>?,
|
||||
protocolManager: ClientProtocolManager?) :
|
||||
NettyConnector(configuration, handler, listener, closeExecutor, threadPool, scheduledThreadPool, protocolManager) {
|
||||
private val server = configuration?.get(ArtemisMessagingServer::class.java.name) as? ArtemisMessagingServer
|
||||
private val expectedCommonName = (configuration?.get(ArtemisTcpTransport.VERIFY_PEER_COMMON_NAME) as? String)?.let {
|
||||
X500Name(it)
|
||||
}
|
||||
private val expecteLegalName: X500Name? = configuration?.get(ArtemisTcpTransport.VERIFY_PEER_LEGAL_NAME) as X500Name?
|
||||
|
||||
override fun createConnection(): Connection? {
|
||||
val connection = super.createConnection() as NettyConnection?
|
||||
if (connection != null && expectedCommonName != null) {
|
||||
val peerLegalName = connection
|
||||
if (connection != null && expecteLegalName != null) {
|
||||
val peerLegalName: X500Name = connection
|
||||
.channel
|
||||
.pipeline()
|
||||
.get(SslHandler::class.java)
|
||||
@ -453,10 +451,9 @@ private class VerifyingNettyConnector(configuration: MutableMap<String, Any>?,
|
||||
.peerPrincipal
|
||||
.name
|
||||
.let(::X500Name)
|
||||
// TODO Verify on the entire principle (subject)
|
||||
if (peerLegalName.commonName != expectedCommonName.commonName) {
|
||||
if (peerLegalName != expecteLegalName) {
|
||||
connection.close()
|
||||
server!!.hostVerificationFail(peerLegalName, expectedCommonName)
|
||||
server!!.hostVerificationFail(peerLegalName, expecteLegalName)
|
||||
return null // Artemis will keep trying to reconnect until it's told otherwise
|
||||
} else {
|
||||
server!!.onTcpConnection(peerLegalName)
|
||||
|
@ -5,6 +5,7 @@ import net.corda.core.crypto.Party
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.node.utilities.*
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.jetbrains.exposed.sql.statements.InsertStatement
|
||||
import java.util.Collections.synchronizedMap
|
||||
@ -26,12 +27,13 @@ class PersistentNetworkMapService(services: ServiceHubInternal, minimumPlatformV
|
||||
}
|
||||
|
||||
override val nodeRegistrations: MutableMap<Party, NodeRegistrationInfo> = synchronizedMap(object : AbstractJDBCHashMap<Party, NodeRegistrationInfo, Table>(Table, loadOnInit = true) {
|
||||
override fun keyFromRow(row: ResultRow): Party = Party(row[table.nodeParty.name], row[table.nodeParty.owningKey])
|
||||
// TODO: We should understand an X500Name database field type, rather than manually doing the conversion ourselves
|
||||
override fun keyFromRow(row: ResultRow): Party = Party(X500Name(row[table.nodeParty.name]), row[table.nodeParty.owningKey])
|
||||
|
||||
override fun valueFromRow(row: ResultRow): NodeRegistrationInfo = deserializeFromBlob(row[table.registrationInfo])
|
||||
|
||||
override fun addKeyToInsert(insert: InsertStatement, entry: Map.Entry<Party, NodeRegistrationInfo>, finalizables: MutableList<() -> Unit>) {
|
||||
insert[table.nodeParty.name] = entry.key.name
|
||||
insert[table.nodeParty.name] = entry.key.name.toString()
|
||||
insert[table.nodeParty.owningKey] = entry.key.owningKey
|
||||
}
|
||||
|
||||
|
@ -281,8 +281,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
|
||||
|
||||
private fun onSessionMessage(message: ReceivedMessage) {
|
||||
val sessionMessage = message.data.deserialize<SessionMessage>()
|
||||
// TODO Look up the party with the full X.500 name instead of just the legal name
|
||||
val sender = serviceHub.networkMapCache.getNodeByLegalName(message.peer.commonName)?.legalIdentity
|
||||
val sender = serviceHub.networkMapCache.getNodeByLegalName(message.peer)?.legalIdentity
|
||||
if (sender != null) {
|
||||
when (sessionMessage) {
|
||||
is ExistingSessionMessage -> onExistingSessionMessage(sessionMessage, sender)
|
||||
|
@ -54,7 +54,7 @@ class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsTok
|
||||
finalizables: MutableList<() -> Unit>) {
|
||||
insert[table.consumingTxHash] = entry.value.id
|
||||
insert[table.consumingIndex] = entry.value.inputIndex
|
||||
insert[table.requestingParty.name] = entry.value.requestingParty.name
|
||||
insert[table.requestingParty.name] = entry.value.requestingParty.name.toString()
|
||||
insert[table.requestingParty.owningKey] = entry.value.requestingParty.owningKey
|
||||
}
|
||||
})
|
||||
|
@ -91,7 +91,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
|
||||
stateStatus = Vault.StateStatus.UNCONSUMED
|
||||
contractStateClassName = it.value.state.data.javaClass.name
|
||||
contractState = it.value.state.serialize(storageKryo()).bytes
|
||||
notaryName = it.value.state.notary.name
|
||||
notaryName = it.value.state.notary.name.toString()
|
||||
notaryKey = it.value.state.notary.owningKey.toBase58String()
|
||||
recordedTime = services.clock.instant()
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.core.utilities.trace
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
@ -23,7 +24,7 @@ object ServiceIdentityGenerator {
|
||||
* @param serviceName The legal name of the distributed service.
|
||||
* @param threshold The threshold for the generated group [CompositeKey].
|
||||
*/
|
||||
fun generateToDisk(dirs: List<Path>, serviceId: String, serviceName: String, threshold: Int = 1) {
|
||||
fun generateToDisk(dirs: List<Path>, serviceId: String, serviceName: X500Name, threshold: Int = 1) {
|
||||
log.trace { "Generating a group identity \"serviceName\" for nodes: ${dirs.joinToString()}" }
|
||||
|
||||
val keyPairs = (1..dirs.size).map { generateKeyPair() }
|
||||
@ -43,7 +44,7 @@ object ServiceIdentityGenerator {
|
||||
fun main(args: Array<String>) {
|
||||
val dirs = args[0].split("|").map { Paths.get(it) }
|
||||
val serviceId = args[1]
|
||||
val serviceName = args[2]
|
||||
val serviceName = X500Name(args[2])
|
||||
val quorumSize = args.getOrNull(3)?.toInt() ?: 1
|
||||
|
||||
println("Generating service identity for \"$serviceName\"")
|
||||
|
@ -12,6 +12,7 @@ import net.corda.core.serialization.*;
|
||||
import net.corda.core.transactions.*;
|
||||
import net.corda.node.services.vault.schemas.*;
|
||||
import net.corda.testing.node.*;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.jetbrains.annotations.*;
|
||||
import org.jetbrains.exposed.sql.*;
|
||||
import org.junit.*;
|
||||
@ -129,7 +130,7 @@ public class VaultQueryJavaTests {
|
||||
QueryCriteria vaultCriteria = new VaultQueryCriteria(status, null, contractStateTypes);
|
||||
|
||||
List<UniqueIdentifier> linearIds = Arrays.asList(uid);
|
||||
List<String> dealPartyNames = Arrays.asList(getMEGA_CORP().getName());
|
||||
List<X500Name> dealPartyNames = Arrays.asList(getMEGA_CORP().getName());
|
||||
QueryCriteria dealCriteriaAll = new LinearStateQueryCriteria(linearIds, false, dealIds, dealPartyNames);
|
||||
|
||||
QueryCriteria compositeCriteria = and(dealCriteriaAll, vaultCriteria);
|
||||
@ -198,7 +199,7 @@ public class VaultQueryJavaTests {
|
||||
QueryCriteria vaultCriteria = new VaultQueryCriteria(Vault.StateStatus.UNCONSUMED, null, contractStateTypes);
|
||||
|
||||
List<UniqueIdentifier> linearIds = Arrays.asList(uid);
|
||||
List<String> dealPartyNames = Arrays.asList(getMEGA_CORP().getName());
|
||||
List<X500Name> dealPartyNames = Arrays.asList(getMEGA_CORP().getName());
|
||||
QueryCriteria dealCriteriaAll = new LinearStateQueryCriteria(linearIds, false, dealIds, dealPartyNames);
|
||||
|
||||
QueryCriteria compositeCriteria = and(dealCriteriaAll, vaultCriteria);
|
||||
|
@ -29,7 +29,7 @@ class InteractiveShellTest {
|
||||
constructor(b: Int, c: String) : this(b.toString() + c)
|
||||
constructor(amount: Amount<Currency>) : this(amount.toString())
|
||||
constructor(pair: Pair<Amount<Currency>, SecureHash.SHA256>) : this(pair.toString())
|
||||
constructor(party: Party) : this(party.name)
|
||||
constructor(party: Party) : this(party.name.toString())
|
||||
override fun call() = a
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ class InteractiveShellTest {
|
||||
fun flowTooManyParams() = check("b: 12, c: Yo, d: Bar", "")
|
||||
|
||||
@Test
|
||||
fun party() = check("party: \"$someCorpLegalName\"", someCorpLegalName)
|
||||
fun party() = check("party: \"$someCorpLegalName\"", someCorpLegalName.toString())
|
||||
|
||||
class DummyFSM(val logic: FlowA) : FlowStateMachine<Any?> {
|
||||
override fun <T : Any> sendAndReceive(receiveType: Class<T>, otherParty: Party, payload: Any, sessionFlow: FlowLogic<*>, retrySend: Boolean): UntrustworthyData<T> {
|
||||
|
@ -266,7 +266,7 @@ class TwoPartyTradeFlowTests {
|
||||
|
||||
// Creates a mock node with an overridden storage service that uses a RecordingMap, that lets us test the order
|
||||
// of gets and puts.
|
||||
private fun makeNodeWithTracking(networkMapAddr: SingleMessageRecipient?, name: String, overrideServices: Map<ServiceInfo, KeyPair>? = null): MockNetwork.MockNode {
|
||||
private fun makeNodeWithTracking(networkMapAddr: SingleMessageRecipient?, name: X500Name, overrideServices: Map<ServiceInfo, KeyPair>? = null): MockNetwork.MockNode {
|
||||
// Create a node in the mock network ...
|
||||
return net.createNode(networkMapAddr, -1, object : MockNetwork.Factory {
|
||||
override fun create(config: NodeConfiguration,
|
||||
|
@ -12,7 +12,7 @@ class FullNodeConfigurationTest {
|
||||
@Test
|
||||
fun `Artemis special characters not permitted in RPC usernames`() {
|
||||
fun configWithRPCUsername(username: String): FullNodeConfiguration {
|
||||
return testConfiguration(Paths.get("."), X500Name(ALICE.name), 0).copy(
|
||||
return testConfiguration(Paths.get("."), ALICE.name, 0).copy(
|
||||
rpcUsers = listOf(User(username, "pass", emptySet())))
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ class RequeryConfigurationTest {
|
||||
stateStatus = Vault.StateStatus.UNCONSUMED
|
||||
contractStateClassName = DummyContract.SingleOwnerState::class.java.name
|
||||
contractState = DummyContract.SingleOwnerState(owner = DUMMY_PUBKEY_1).serialize(storageKryo()).bytes
|
||||
notaryName = txn.tx.notary!!.name
|
||||
notaryName = txn.tx.notary!!.name.toString()
|
||||
notaryKey = txn.tx.notary!!.owningKey.toBase58String()
|
||||
recordedTime = Instant.now()
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import net.corda.testing.node.MockKeyManagementService
|
||||
import net.corda.testing.node.TestClock
|
||||
import net.corda.testing.node.makeTestDataSourceProperties
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -79,7 +80,8 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
|
||||
database.transaction {
|
||||
val kms = MockKeyManagementService(ALICE_KEY)
|
||||
val mockMessagingService = InMemoryMessagingNetwork(false).InMemoryMessaging(false, InMemoryMessagingNetwork.PeerHandle(0, "None"), AffinityExecutor.ServiceAffinityExecutor("test", 1), database)
|
||||
val nullIdentity = X500Name("cn=None")
|
||||
val mockMessagingService = InMemoryMessagingNetwork(false).InMemoryMessaging(false, InMemoryMessagingNetwork.PeerHandle(0, nullIdentity), AffinityExecutor.ServiceAffinityExecutor("test", 1), database)
|
||||
services = object : MockServiceHubInternal(overrideClock = testClock, keyManagement = kms, net = mockMessagingService), TestReference {
|
||||
override val vaultService: VaultService = NodeVaultService(this, dataSourceProps)
|
||||
override val testReference = this@NodeSchedulerServiceTest
|
||||
|
@ -72,7 +72,7 @@ class ArtemisMessagingTests {
|
||||
userService = RPCUserServiceImpl(emptyList())
|
||||
config = TestNodeConfiguration(
|
||||
baseDirectory = baseDirectory,
|
||||
myLegalName = X500Name(ALICE.name),
|
||||
myLegalName = ALICE.name,
|
||||
networkMapService = null)
|
||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||
val dataSourceAndDatabase = configureDatabase(makeTestDataSourceProperties())
|
||||
|
@ -29,6 +29,7 @@ import net.corda.node.utilities.AddOrRemove.REMOVE
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.corda.testing.node.MockNetwork.MockNode
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@ -43,7 +44,7 @@ abstract class AbstractNetworkMapServiceTest<out S : AbstractNetworkMapService>
|
||||
lateinit var alice: MockNode
|
||||
|
||||
companion object {
|
||||
val subscriberLegalName = "CN=Subscriber,OU=Corda QA Department,O=R3 CEV,L=New York,C=US"
|
||||
val subscriberLegalName = X500Name("CN=Subscriber,OU=Corda QA Department,O=R3 CEV,L=New York,C=US")
|
||||
}
|
||||
|
||||
@Before
|
||||
@ -246,14 +247,14 @@ abstract class AbstractNetworkMapServiceTest<out S : AbstractNetworkMapService>
|
||||
network.runNetwork()
|
||||
}
|
||||
|
||||
private fun addNewNodeToNetworkMap(legalName: String): MockNode {
|
||||
private fun addNewNodeToNetworkMap(legalName: X500Name): MockNode {
|
||||
val node = network.createNode(networkMapAddress = mapServiceNode.info.address, legalName = legalName)
|
||||
network.runNetwork()
|
||||
lastSerial = System.currentTimeMillis()
|
||||
return node
|
||||
}
|
||||
|
||||
private fun newNodeSeparateFromNetworkMap(legalName: String): MockNode {
|
||||
private fun newNodeSeparateFromNetworkMap(legalName: X500Name): MockNode {
|
||||
return network.createNode(legalName = legalName, nodeFactory = NoNMSNodeFactory)
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ class InMemoryIdentityServiceTests {
|
||||
@Test
|
||||
fun `get identity by name with no registered identities`() {
|
||||
val service = InMemoryIdentityService()
|
||||
assertNull(service.partyFromName(ALICE.name))
|
||||
assertNull(service.partyFromX500Name(ALICE.name))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -54,8 +54,8 @@ class InMemoryIdentityServiceTests {
|
||||
val service = InMemoryIdentityService()
|
||||
val identities = listOf("Node A", "Node B", "Node C")
|
||||
.map { Party(X500Name("CN=$it,O=R3,OU=corda,L=London,C=UK"), generateKeyPair().public) }
|
||||
assertNull(service.partyFromName(identities.first().name))
|
||||
assertNull(service.partyFromX500Name(identities.first().name))
|
||||
identities.forEach { service.registerIdentity(it) }
|
||||
identities.forEach { assertEquals(it, service.partyFromName(it.name)) }
|
||||
identities.forEach { assertEquals(it, service.partyFromX500Name(it.name)) }
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import net.corda.node.services.transactions.ValidatingNotaryService
|
||||
import net.corda.node.utilities.transaction
|
||||
import net.corda.testing.expect
|
||||
import net.corda.testing.expectEvents
|
||||
import net.corda.testing.getTestX509Name
|
||||
import net.corda.testing.initiateSingleShotFlow
|
||||
import net.corda.testing.node.InMemoryMessagingNetwork
|
||||
import net.corda.testing.node.InMemoryMessagingNetwork.MessageTransfer
|
||||
@ -43,6 +44,7 @@ import net.corda.testing.sequence
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -74,7 +76,7 @@ class StateMachineManagerTests {
|
||||
node1 = nodes.first
|
||||
node2 = nodes.second
|
||||
val notaryKeyPair = generateKeyPair()
|
||||
val notaryService = ServiceInfo(ValidatingNotaryService.type, "CN=notary-service-2000,O=R3,OU=corda,L=London,C=UK")
|
||||
val notaryService = ServiceInfo(ValidatingNotaryService.type, getTestX509Name("notary-service-2000"))
|
||||
val overrideServices = mapOf(Pair(notaryService, notaryKeyPair))
|
||||
// Note that these notaries don't operate correctly as they don't share their state. They are only used for testing
|
||||
// service addressing.
|
||||
|
@ -184,7 +184,7 @@ class VaultQueryTests {
|
||||
|
||||
|
||||
val CASH_NOTARY_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(20)) }
|
||||
val CASH_NOTARY: Party get() = Party("Notary Service", CASH_NOTARY_KEY.public)
|
||||
val CASH_NOTARY: Party get() = Party(DUMMY_NOTARY.name, CASH_NOTARY_KEY.public)
|
||||
|
||||
@Test
|
||||
fun `unconsumed states by notary`() {
|
||||
|
@ -8,6 +8,7 @@ import net.corda.core.crypto.X509Utilities
|
||||
import net.corda.core.exists
|
||||
import net.corda.core.utilities.ALICE
|
||||
import net.corda.testing.TestNodeConfiguration
|
||||
import net.corda.testing.getTestX509Name
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@ -28,7 +29,7 @@ class NetworkRegistrationHelperTest {
|
||||
val identities = listOf("CORDA_CLIENT_CA",
|
||||
"CORDA_INTERMEDIATE_CA",
|
||||
"CORDA_ROOT_CA")
|
||||
.map { X500Name("CN=${it},O=R3,OU=corda,L=London,C=UK") }
|
||||
.map { getTestX509Name(it) }
|
||||
val certs = identities.map { X509Utilities.createSelfSignedCACert(it).certificate }
|
||||
.toTypedArray()
|
||||
|
||||
@ -39,7 +40,7 @@ class NetworkRegistrationHelperTest {
|
||||
|
||||
val config = TestNodeConfiguration(
|
||||
baseDirectory = tempFolder.root.toPath(),
|
||||
myLegalName = X500Name(ALICE.name),
|
||||
myLegalName = ALICE.name,
|
||||
networkMapService = null)
|
||||
|
||||
assertFalse(config.keyStoreFile.exists())
|
||||
|
Reference in New Issue
Block a user