mirror of
https://github.com/corda/corda.git
synced 2025-06-16 22:28:15 +00:00
Replace X500Name with CordaX500Name (#1447)
Replace X500Name with CordaX500Name, which enforces the specific constraints Corda expects on legal/service identity names.
This commit is contained in:
@ -3,10 +3,10 @@ package net.corda.node.services
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.messaging.startFlow
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.node.services.ServiceType
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
|
||||
import net.corda.nodeapi.User
|
||||
import net.corda.testing.driver.driver
|
||||
@ -14,7 +14,7 @@ import org.junit.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class AdvertisedServiceTests {
|
||||
private val serviceName = getX500Name(O = "Custom Service", OU = "corda", L = "London", C = "GB")
|
||||
private val serviceName = CordaX500Name(organisation = "Custom Service", locality = "London", country = "GB")
|
||||
private val serviceType = ServiceType.corda.getSubType("custom")
|
||||
private val user = "bankA"
|
||||
private val pass = "passA"
|
||||
|
@ -7,6 +7,7 @@ import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.flows.NotaryException
|
||||
import net.corda.core.flows.NotaryFlow
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
@ -15,7 +16,6 @@ import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.Try
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.node.internal.AbstractNode
|
||||
import net.corda.node.services.config.BFTSMaRtConfiguration
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
@ -35,7 +35,7 @@ import kotlin.test.assertTrue
|
||||
|
||||
class BFTNotaryServiceTests {
|
||||
companion object {
|
||||
private val clusterName = getX500Name(O = "BFT", OU = "corda", L = "Zurich", C = "CH")
|
||||
private val clusterName = CordaX500Name(organisation = "BFT", locality = "Zurich", country = "CH")
|
||||
private val serviceType = BFTNonValidatingNotaryService.type
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,12 @@ import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.flows.NotaryException
|
||||
import net.corda.core.flows.NotaryFlow
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.concurrent.map
|
||||
import net.corda.core.internal.concurrent.transpose
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.node.internal.AbstractNode
|
||||
import net.corda.testing.DUMMY_BANK_A
|
||||
import net.corda.testing.contracts.DUMMY_PROGRAM_ID
|
||||
@ -23,7 +23,7 @@ import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
class RaftNotaryServiceTests : NodeBasedTest() {
|
||||
private val notaryName = getX500Name(O = "RAFT Notary Service", OU = "corda", L = "London", C = "GB")
|
||||
private val notaryName = CordaX500Name(organisation = "RAFT Notary Service", locality = "London", country = "GB")
|
||||
|
||||
@Test
|
||||
fun `detect double spend`() {
|
||||
|
@ -103,7 +103,7 @@ class MQSecurityAsNodeTest : MQSecurityTest() {
|
||||
val clientKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
|
||||
// Set name constrain to the legal name.
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName))), arrayOf())
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName.x500Name))), arrayOf())
|
||||
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCA.certificate,
|
||||
intermediateCA.keyPair, legalName, clientKey.public, nameConstraints = nameConstraints)
|
||||
val tlsKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
|
@ -2,6 +2,7 @@ package net.corda.services.messaging
|
||||
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.concurrent.transpose
|
||||
import net.corda.core.internal.elapsedTime
|
||||
import net.corda.core.internal.times
|
||||
@ -12,7 +13,6 @@ import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.node.internal.Node
|
||||
import net.corda.node.services.messaging.*
|
||||
@ -22,7 +22,6 @@ import net.corda.node.utilities.ServiceIdentityGenerator
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.NodeBasedTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
import java.util.concurrent.CountDownLatch
|
||||
@ -31,8 +30,8 @@ import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class P2PMessagingTest : NodeBasedTest() {
|
||||
private companion object {
|
||||
val DISTRIBUTED_SERVICE_NAME = getX500Name(O = "DistributedService", L = "London", C = "GB")
|
||||
val SERVICE_2_NAME = getX500Name(O = "Service 2", L = "London", C = "GB")
|
||||
val DISTRIBUTED_SERVICE_NAME = CordaX500Name(organisation = "DistributedService", locality = "London", country = "GB")
|
||||
val SERVICE_2_NAME = CordaX500Name(organisation = "Service 2", locality = "London", country = "GB")
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -65,7 +64,7 @@ class P2PMessagingTest : NodeBasedTest() {
|
||||
@Test
|
||||
fun `communicating with a distributed service which the network map node is part of`() {
|
||||
ServiceIdentityGenerator.generateToDisk(
|
||||
listOf(DUMMY_MAP.name, SERVICE_2_NAME).map { baseDirectory(it) },
|
||||
listOf(DUMMY_MAP.name, SERVICE_2_NAME).map { baseDirectory(it.x500Name) },
|
||||
RaftValidatingNotaryService.type.id,
|
||||
DISTRIBUTED_SERVICE_NAME)
|
||||
|
||||
@ -204,7 +203,7 @@ class P2PMessagingTest : NodeBasedTest() {
|
||||
return crashingNodes
|
||||
}
|
||||
|
||||
private fun assertAllNodesAreUsed(participatingServiceNodes: List<Node>, serviceName: X500Name, originatingNode: Node) {
|
||||
private fun assertAllNodesAreUsed(participatingServiceNodes: List<Node>, serviceName: CordaX500Name, originatingNode: Node) {
|
||||
// Setup each node in the distributed service to return back it's NodeInfo so that we can know which node is being used
|
||||
participatingServiceNodes.forEach { node ->
|
||||
node.respondWith(node.info)
|
||||
|
@ -3,6 +3,7 @@ package net.corda.services.messaging
|
||||
import com.nhaarman.mockito_kotlin.whenever
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.node.internal.NetworkMapInfo
|
||||
@ -17,7 +18,6 @@ import net.corda.testing.node.NodeBasedTest
|
||||
import net.corda.testing.node.SimpleNode
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Test
|
||||
import java.security.cert.X509Certificate
|
||||
import java.time.Instant
|
||||
@ -51,10 +51,10 @@ class P2PSecurityTest : NodeBasedTest() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun startSimpleNode(legalName: X500Name,
|
||||
private fun startSimpleNode(legalName: CordaX500Name,
|
||||
trustRoot: X509Certificate): SimpleNode {
|
||||
val config = testNodeConfiguration(
|
||||
baseDirectory = baseDirectory(legalName),
|
||||
baseDirectory = baseDirectory(legalName.x500Name),
|
||||
myLegalName = legalName).also {
|
||||
whenever(it.networkMapService).thenReturn(NetworkMapInfo(networkMapNode.configuration.p2pAddress, networkMapNode.info.legalIdentity.name))
|
||||
}
|
||||
@ -62,7 +62,7 @@ class P2PSecurityTest : NodeBasedTest() {
|
||||
return SimpleNode(config, trustRoot = trustRoot).apply { start() }
|
||||
}
|
||||
|
||||
private fun SimpleNode.registerWithNetworkMap(registrationName: X500Name): CordaFuture<NetworkMapService.RegistrationResponse> {
|
||||
private fun SimpleNode.registerWithNetworkMap(registrationName: CordaX500Name): CordaFuture<NetworkMapService.RegistrationResponse> {
|
||||
val legalIdentity = getTestPartyAndCertificate(registrationName, identity.public)
|
||||
val nodeInfo = NodeInfo(listOf(MOCK_HOST_AND_PORT), legalIdentity, NonEmptySet.of(legalIdentity), 1, serial = 1)
|
||||
val registration = NodeRegistration(nodeInfo, System.currentTimeMillis(), AddOrRemove.ADD, Instant.MAX)
|
||||
|
@ -10,6 +10,7 @@ import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.flows.*
|
||||
import net.corda.core.flows.ContractUpgradeFlow.Acceptor
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.internal.*
|
||||
@ -28,7 +29,9 @@ import net.corda.core.node.services.NetworkMapCache.MapChange
|
||||
import net.corda.core.serialization.SerializeAsToken
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.cert
|
||||
import net.corda.core.utilities.debug
|
||||
import net.corda.node.services.NotaryChangeHandler
|
||||
import net.corda.node.services.NotifyTransactionHandler
|
||||
import net.corda.node.services.TransactionKeyHandler
|
||||
@ -65,7 +68,6 @@ import net.corda.node.services.vault.VaultSoftLockManager
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.node.utilities.AddOrRemove.ADD
|
||||
import org.apache.activemq.artemis.utils.ReusableLatch
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.slf4j.Logger
|
||||
import rx.Observable
|
||||
import java.io.IOException
|
||||
@ -148,8 +150,9 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
val nodeReadyFuture: CordaFuture<Unit>
|
||||
get() = _nodeReadyFuture
|
||||
|
||||
protected val myLegalName: X500Name by lazy {
|
||||
loadKeyStore(configuration.nodeKeystore, configuration.keyStorePassword).getX509Certificate(X509Utilities.CORDA_CLIENT_CA).subject.withCommonName(null)
|
||||
protected val myLegalName: CordaX500Name by lazy {
|
||||
val cert = loadKeyStore(configuration.nodeKeystore, configuration.keyStorePassword).getX509Certificate(X509Utilities.CORDA_CLIENT_CA)
|
||||
CordaX500Name.build(cert.subject).copy(commonName = null)
|
||||
}
|
||||
|
||||
/** Fetch CordaPluginRegistry classes registered in META-INF/services/net.corda.core.node.CordaPluginRegistry files that exist in the classpath */
|
||||
@ -693,9 +696,9 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
|
||||
val (id, name) = if (serviceInfo == null) {
|
||||
// Create node identity if service info = null
|
||||
Pair("identity", myLegalName.withCommonName(null))
|
||||
Pair("identity", myLegalName.copy(commonName = null))
|
||||
} else {
|
||||
val name = serviceInfo.name ?: myLegalName.withCommonName(serviceInfo.type.id)
|
||||
val name = serviceInfo.name ?: myLegalName.copy(commonName = serviceInfo.type.id)
|
||||
Pair(serviceInfo.type.id, name)
|
||||
}
|
||||
|
||||
@ -735,14 +738,14 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
}
|
||||
|
||||
val subject = certificates[0].toX509CertHolder().subject
|
||||
if (subject != name)
|
||||
if (subject != name.x500Name)
|
||||
throw ConfigurationException("The name for $id doesn't match what's in the key store: $name vs $subject")
|
||||
|
||||
partyKeys += keys
|
||||
return PartyAndCertificate(CertificateFactory.getInstance("X509").generateCertPath(certificates))
|
||||
}
|
||||
|
||||
private fun migrateKeysFromFile(keyStore: KeyStoreWrapper, serviceName: X500Name,
|
||||
private fun migrateKeysFromFile(keyStore: KeyStoreWrapper, serviceName: CordaX500Name,
|
||||
pubKeyFile: Path, privKeyFile: Path, compositeKeyFile:Path,
|
||||
privateKeyAlias: String, compositeKeyAlias: String) {
|
||||
log.info("Migrating $privateKeyAlias from file to key store...")
|
||||
|
@ -3,13 +3,12 @@ package net.corda.node.internal
|
||||
import net.corda.client.rpc.notUsed
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.UpgradedContract
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.FlowInitiator
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.messaging.*
|
||||
import net.corda.core.node.NodeInfo
|
||||
@ -26,7 +25,6 @@ import net.corda.node.services.messaging.requirePermission
|
||||
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
||||
import net.corda.node.services.statemachine.StateMachineManager
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import rx.Observable
|
||||
import java.io.InputStream
|
||||
import java.security.PublicKey
|
||||
@ -191,7 +189,7 @@ class CordaRPCOpsImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override fun partyFromX500Name(x500Name: X500Name): Party? {
|
||||
override fun partyFromX500Name(x500Name: CordaX500Name): Party? {
|
||||
return database.transaction {
|
||||
services.identityService.partyFromX500Name(x500Name)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.corda.node.internal
|
||||
|
||||
import com.codahale.metrics.JmxReporter
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.internal.concurrent.doneFuture
|
||||
import net.corda.core.internal.concurrent.flatMap
|
||||
@ -39,7 +40,6 @@ import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
||||
import org.apache.activemq.artemis.api.core.RoutingType
|
||||
import org.apache.activemq.artemis.api.core.client.ActiveMQClient
|
||||
import org.apache.activemq.artemis.api.core.client.ClientMessage
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.IOException
|
||||
@ -378,4 +378,4 @@ open class Node(override val configuration: FullNodeConfiguration,
|
||||
|
||||
class ConfigurationException(message: String) : Exception(message)
|
||||
|
||||
data class NetworkMapInfo(val address: NetworkHostAndPort, val legalName: X500Name)
|
||||
data class NetworkMapInfo(val address: NetworkHostAndPort, val legalName: CordaX500Name)
|
||||
|
@ -6,16 +6,14 @@ import com.typesafe.config.ConfigParseOptions
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SignatureScheme
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.copyTo
|
||||
import net.corda.core.internal.createDirectories
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.internal.exists
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.core.utilities.toWellFormattedName
|
||||
import net.corda.core.utilities.withCommonName
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.nodeapi.config.SSLConfiguration
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x509.GeneralName
|
||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||
import org.bouncycastle.asn1.x509.NameConstraints
|
||||
@ -53,7 +51,7 @@ object ConfigHelper {
|
||||
*/
|
||||
fun NodeConfiguration.configureWithDevSSLCertificate() = configureDevKeyAndTrustStores(myLegalName)
|
||||
|
||||
fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: X500Name) {
|
||||
fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500Name) {
|
||||
certificatesDirectory.createDirectories()
|
||||
if (!trustStoreFile.exists()) {
|
||||
javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordatruststore.jks").copyTo(trustStoreFile)
|
||||
@ -81,25 +79,25 @@ fun createKeystoreForCordaNode(sslKeyStorePath: Path,
|
||||
keyPassword: String,
|
||||
caKeyStore: KeyStore,
|
||||
caKeyPassword: String,
|
||||
legalName: X500Name,
|
||||
legalName: CordaX500Name,
|
||||
signatureScheme: SignatureScheme = X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) {
|
||||
|
||||
val rootCACert = caKeyStore.getX509Certificate(X509Utilities.CORDA_ROOT_CA)
|
||||
val (intermediateCACert, intermediateCAKeyPair) = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, caKeyPassword)
|
||||
|
||||
val clientKey = Crypto.generateKeyPair(signatureScheme)
|
||||
val clientName = legalName.toWellFormattedName().withCommonName(null)
|
||||
val clientName = legalName.copy(commonName = null)
|
||||
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, clientName))), arrayOf())
|
||||
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, clientName.x500Name))), arrayOf())
|
||||
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA,
|
||||
intermediateCACert,
|
||||
intermediateCAKeyPair,
|
||||
clientName.withCommonName(X509Utilities.CORDA_CLIENT_CA_CN),
|
||||
clientName.copy(commonName = X509Utilities.CORDA_CLIENT_CA_CN).x500Name,
|
||||
clientKey.public,
|
||||
nameConstraints = nameConstraints)
|
||||
|
||||
val tlsKey = Crypto.generateKeyPair(signatureScheme)
|
||||
val clientTLSCert = X509Utilities.createCertificate(CertificateType.TLS, clientCACert, clientKey, clientName, tlsKey.public)
|
||||
val clientTLSCert = X509Utilities.createCertificate(CertificateType.TLS, clientCACert, clientKey, clientName.x500Name, tlsKey.public)
|
||||
|
||||
val keyPass = keyPassword.toCharArray()
|
||||
|
||||
@ -118,4 +116,4 @@ fun createKeystoreForCordaNode(sslKeyStorePath: Path,
|
||||
keyPass,
|
||||
arrayOf(clientTLSCert, clientCACert, intermediateCACert, rootCACert))
|
||||
tlsKeystore.save(sslKeyStorePath, storePassword)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.node.services.config
|
||||
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.node.internal.NetworkMapInfo
|
||||
@ -8,7 +9,6 @@ import net.corda.node.services.network.NetworkMapService
|
||||
import net.corda.nodeapi.User
|
||||
import net.corda.nodeapi.config.NodeSSLConfiguration
|
||||
import net.corda.nodeapi.config.OldConfig
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.net.URL
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
@ -21,7 +21,7 @@ data class BFTSMaRtConfiguration(val replicaId: Int, val debug: Boolean, val exp
|
||||
interface NodeConfiguration : NodeSSLConfiguration {
|
||||
// myLegalName should be only used in the initial network registration, we should use the name from the certificate instead of this.
|
||||
// TODO: Remove this so we don't accidentally use this identity in the code?
|
||||
val myLegalName: X500Name
|
||||
val myLegalName: CordaX500Name
|
||||
val networkMapService: NetworkMapInfo?
|
||||
val minimumPlatformVersion: Int
|
||||
val emailAddress: String
|
||||
@ -42,10 +42,10 @@ interface NodeConfiguration : NodeSSLConfiguration {
|
||||
data class FullNodeConfiguration(
|
||||
// TODO Remove this subsitution value and use baseDirectory as the subsitution instead
|
||||
@Deprecated(
|
||||
"This is a subsitution value which points to the baseDirectory and is manually added into the config before parsing",
|
||||
"This is a substitution value which points to the baseDirectory and is manually added into the config before parsing",
|
||||
ReplaceWith("baseDirectory"))
|
||||
val basedir: Path,
|
||||
override val myLegalName: X500Name,
|
||||
override val myLegalName: CordaX500Name,
|
||||
override val emailAddress: String,
|
||||
override val keyStorePassword: String,
|
||||
override val trustStorePassword: String,
|
||||
|
@ -2,10 +2,7 @@ package net.corda.node.services.identity
|
||||
|
||||
import net.corda.core.contracts.PartyAndReference
|
||||
import net.corda.core.crypto.toStringShort
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.identity.*
|
||||
import net.corda.core.internal.toX509CertHolder
|
||||
import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.node.services.UnknownAnonymousPartyException
|
||||
@ -14,7 +11,6 @@ import net.corda.core.utilities.cert
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.core.utilities.subject
|
||||
import net.corda.core.utilities.trace
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.cert.X509CertificateHolder
|
||||
import java.security.InvalidAlgorithmParameterException
|
||||
import java.security.PublicKey
|
||||
@ -46,7 +42,7 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
|
||||
override val trustRootHolder = trustRoot.toX509CertHolder()
|
||||
override val trustAnchor: TrustAnchor = TrustAnchor(trustRoot, null)
|
||||
private val keyToParties = ConcurrentHashMap<PublicKey, PartyAndCertificate>()
|
||||
private val principalToParties = ConcurrentHashMap<X500Name, PartyAndCertificate>()
|
||||
private val principalToParties = ConcurrentHashMap<CordaX500Name, PartyAndCertificate>()
|
||||
|
||||
init {
|
||||
val caCertificatesWithRoot: Set<X509Certificate> = caCertificates.toSet() + trustRoot
|
||||
@ -91,7 +87,7 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
|
||||
override fun getAllIdentities(): Iterable<PartyAndCertificate> = ArrayList(keyToParties.values)
|
||||
|
||||
override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]?.party
|
||||
override fun partyFromX500Name(principal: X500Name): Party? = principalToParties[principal]?.party
|
||||
override fun partyFromX500Name(name: CordaX500Name): Party? = principalToParties[name]?.party
|
||||
override fun partyFromAnonymous(party: AbstractParty): Party? {
|
||||
// Expand the anonymous party to a full party (i.e. has a name) if possible
|
||||
val candidate = party as? Party ?: keyToParties[party.owningKey]?.party
|
||||
@ -114,7 +110,7 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
|
||||
val results = LinkedHashSet<Party>()
|
||||
for ((x500name, partyAndCertificate) in principalToParties) {
|
||||
val party = partyAndCertificate.party
|
||||
for (rdn in x500name.rdNs) {
|
||||
for (rdn in x500name.x500Name.rdNs) {
|
||||
val component = rdn.first.value.toString()
|
||||
if (exactMatch && component == query) {
|
||||
results += party
|
||||
|
@ -3,10 +3,7 @@ package net.corda.node.services.identity
|
||||
import net.corda.core.contracts.PartyAndReference
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.toStringShort
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.identity.*
|
||||
import net.corda.core.internal.toX509CertHolder
|
||||
import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.node.services.UnknownAnonymousPartyException
|
||||
@ -15,7 +12,6 @@ import net.corda.core.utilities.cert
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.node.utilities.AppendOnlyPersistentMap
|
||||
import net.corda.node.utilities.NODE_DATABASE_PREFIX
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.cert.X509CertificateHolder
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.security.InvalidAlgorithmParameterException
|
||||
@ -56,11 +52,11 @@ class PersistentIdentityService(identities: Iterable<PartyAndCertificate> = empt
|
||||
)
|
||||
}
|
||||
|
||||
fun createX500Map(): AppendOnlyPersistentMap<X500Name, SecureHash, PersistentIdentityNames, String> {
|
||||
fun createX500Map(): AppendOnlyPersistentMap<CordaX500Name, SecureHash, PersistentIdentityNames, String> {
|
||||
return AppendOnlyPersistentMap(
|
||||
toPersistentEntityKey = { it.toString() },
|
||||
fromPersistentEntity = { Pair(X500Name(it.name), SecureHash.parse(it.publicKeyHash)) },
|
||||
toPersistentEntity = { key: X500Name, value: SecureHash ->
|
||||
fromPersistentEntity = { Pair(CordaX500Name.parse(it.name), SecureHash.parse(it.publicKeyHash)) },
|
||||
toPersistentEntity = { key: CordaX500Name, value: SecureHash ->
|
||||
PersistentIdentityNames(key.toString(), value.toString())
|
||||
},
|
||||
persistentEntityClass = PersistentIdentityNames::class.java
|
||||
@ -134,20 +130,20 @@ class PersistentIdentityService(identities: Iterable<PartyAndCertificate> = empt
|
||||
}
|
||||
|
||||
override fun certificateFromKey(owningKey: PublicKey): PartyAndCertificate? = keyToParties[mapToKey(owningKey)]
|
||||
private fun certificateFromX500Name(name: X500Name): PartyAndCertificate? {
|
||||
private fun certificateFromCordaX500Name(name: CordaX500Name): PartyAndCertificate? {
|
||||
val partyId = principalToParties[name]
|
||||
return if (partyId != null) {
|
||||
keyToParties[partyId]
|
||||
} else null
|
||||
}
|
||||
|
||||
override fun certificateFromParty(party: Party): PartyAndCertificate = certificateFromX500Name(party.name) ?: throw IllegalArgumentException("Unknown identity ${party.name}")
|
||||
override fun certificateFromParty(party: Party): PartyAndCertificate = certificateFromCordaX500Name(party.name) ?: throw IllegalArgumentException("Unknown identity ${party.name}")
|
||||
|
||||
// We give the caller a copy of the data set to avoid any locking problems
|
||||
override fun getAllIdentities(): Iterable<PartyAndCertificate> = keyToParties.allPersisted().map { it.second }.asIterable()
|
||||
|
||||
override fun partyFromKey(key: PublicKey): Party? = certificateFromKey(key)?.party
|
||||
override fun partyFromX500Name(principal: X500Name): Party? = certificateFromX500Name(principal)?.party
|
||||
override fun partyFromX500Name(name: CordaX500Name): Party? = certificateFromCordaX500Name(name)?.party
|
||||
override fun partyFromAnonymous(party: AbstractParty): Party? {
|
||||
// Expand the anonymous party to a full party (i.e. has a name) if possible
|
||||
val candidate = party as? Party ?: partyFromKey(party.owningKey)
|
||||
@ -172,7 +168,7 @@ class PersistentIdentityService(identities: Iterable<PartyAndCertificate> = empt
|
||||
val results = LinkedHashSet<Party>()
|
||||
for ((x500name, partyId) in principalToParties.allPersisted()) {
|
||||
val party = keyToParties[partyId]!!.party
|
||||
for (rdn in x500name.rdNs) {
|
||||
for (rdn in x500name.x500Name.rdNs) {
|
||||
val component = rdn.first.value.toString()
|
||||
if (exactMatch && component == query) {
|
||||
results += party
|
||||
@ -200,4 +196,4 @@ class PersistentIdentityService(identities: Iterable<PartyAndCertificate> = empt
|
||||
"Issuing certificate's public key must match the party key ${party.owningKey.toStringShort()}."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ fun freshCertificate(identityService: IdentityService,
|
||||
val issuerCertificate = issuer.certificate
|
||||
val window = X509Utilities.getCertificateValidityWindow(Duration.ZERO, 3650.days, issuerCertificate)
|
||||
val ourCertificate = X509Utilities.createCertificate(CertificateType.IDENTITY, issuerCertificate.subject,
|
||||
issuerSigner, issuer.name, subjectPublicKey, window)
|
||||
issuerSigner, issuer.name.x500Name, subjectPublicKey, window)
|
||||
val certFactory = CertificateFactory.getInstance("X509")
|
||||
val ourCertPath = certFactory.generateCertPath(listOf(ourCertificate.cert) + issuer.certPath.certificates)
|
||||
val anonymisedIdentity = PartyAndCertificate(ourCertPath)
|
||||
|
@ -5,8 +5,8 @@ import io.netty.handler.ssl.SslHandler
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.crypto.AddressFormatException
|
||||
import net.corda.core.crypto.newSecureRandom
|
||||
import net.corda.core.utilities.parsePublicKeyBase58
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.ThreadBox
|
||||
import net.corda.core.internal.concurrent.openFuture
|
||||
import net.corda.core.internal.div
|
||||
@ -51,7 +51,6 @@ import org.apache.activemq.artemis.spi.core.security.jaas.CertificateCallback
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal
|
||||
import org.apache.activemq.artemis.spi.core.security.jaas.UserPrincipal
|
||||
import org.apache.activemq.artemis.utils.ConfigurationHelper
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import rx.Subscription
|
||||
import java.io.IOException
|
||||
import java.math.BigInteger
|
||||
@ -373,7 +372,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
}
|
||||
}
|
||||
|
||||
private fun deployBridge(address: ArtemisPeerAddress, legalName: X500Name) {
|
||||
private fun deployBridge(address: ArtemisPeerAddress, legalName: CordaX500Name) {
|
||||
deployBridge(address.queueName, address.hostAndPort, legalName)
|
||||
}
|
||||
|
||||
@ -386,7 +385,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: NetworkHostAndPort, legalName: X500Name) {
|
||||
private fun deployBridge(queueName: String, target: NetworkHostAndPort, legalName: CordaX500Name) {
|
||||
val connectionDirection = ConnectionDirection.Outbound(
|
||||
connectorFactoryClassName = VerifyingNettyConnectorFactory::class.java.name,
|
||||
expectedCommonName = legalName
|
||||
@ -425,7 +424,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
private fun getBridgeName(queueName: String, hostAndPort: NetworkHostAndPort): String = "$queueName -> $hostAndPort"
|
||||
|
||||
// This is called on one of Artemis' background threads
|
||||
internal fun hostVerificationFail(expectedLegalName: X500Name, errorMsg: String?) {
|
||||
internal fun hostVerificationFail(expectedLegalName: CordaX500Name, errorMsg: String?) {
|
||||
log.error(errorMsg)
|
||||
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!
|
||||
@ -434,7 +433,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
}
|
||||
|
||||
// This is called on one of Artemis' background threads
|
||||
internal fun onTcpConnection(peerLegalName: X500Name) {
|
||||
internal fun onTcpConnection(peerLegalName: CordaX500Name) {
|
||||
if (peerLegalName == config.networkMapService?.legalName) {
|
||||
_networkMapConnectionFuture!!.set(Unit)
|
||||
}
|
||||
@ -493,7 +492,7 @@ private class VerifyingNettyConnector(configuration: MutableMap<String, Any>,
|
||||
override fun createConnection(): Connection? {
|
||||
val connection = super.createConnection() as? NettyConnection
|
||||
if (sslEnabled && connection != null) {
|
||||
val expectedLegalName = configuration[ArtemisTcpTransport.VERIFY_PEER_LEGAL_NAME] as X500Name
|
||||
val expectedLegalName = configuration[ArtemisTcpTransport.VERIFY_PEER_LEGAL_NAME] as CordaX500Name
|
||||
try {
|
||||
val session = connection.channel
|
||||
.pipeline()
|
||||
@ -501,14 +500,14 @@ private class VerifyingNettyConnector(configuration: MutableMap<String, Any>,
|
||||
.engine()
|
||||
.session
|
||||
// Checks the peer name is the one we are expecting.
|
||||
val peerLegalName = session.peerPrincipal.name.let(::X500Name)
|
||||
val peerLegalName = CordaX500Name.parse(session.peerPrincipal.name)
|
||||
require(peerLegalName == expectedLegalName) {
|
||||
"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!"
|
||||
}
|
||||
// Make sure certificate has the same name.
|
||||
val peerCertificate = session.peerCertificateChain[0].toX509CertHolder()
|
||||
require(peerCertificate.subject == expectedLegalName) {
|
||||
require(peerCertificate.subject == expectedLegalName.x500Name) {
|
||||
"Peer has wrong subject name in the certificate - expected $expectedLegalName but got ${peerCertificate.subject}. This is either a fatal " +
|
||||
"misconfiguration by the remote peer or an SSL man-in-the-middle attack!"
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.corda.node.services.messaging
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.concurrent.openFuture
|
||||
import net.corda.core.messaging.MessageRecipients
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
@ -9,7 +10,6 @@ import net.corda.core.node.services.PartyInfo
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
@ -225,7 +225,7 @@ interface Message {
|
||||
// or something like that.
|
||||
interface ReceivedMessage : Message {
|
||||
/** The authenticated sender. */
|
||||
val peer: X500Name
|
||||
val peer: CordaX500Name
|
||||
/** Platform version of the sender's node. */
|
||||
val platformVersion: Int
|
||||
}
|
||||
|
@ -2,9 +2,10 @@ package net.corda.node.services.messaging
|
||||
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.ThreadBox
|
||||
import net.corda.core.internal.concurrent.andForget
|
||||
import net.corda.core.internal.concurrent.thenMatch
|
||||
import net.corda.core.internal.ThreadBox
|
||||
import net.corda.core.messaging.CordaRPCOps
|
||||
import net.corda.core.messaging.MessageRecipients
|
||||
import net.corda.core.messaging.RPCOps
|
||||
@ -38,13 +39,15 @@ import org.apache.activemq.artemis.api.core.SimpleString
|
||||
import org.apache.activemq.artemis.api.core.client.*
|
||||
import org.apache.activemq.artemis.api.core.client.ActiveMQClient.DEFAULT_ACK_BATCH_SIZE
|
||||
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
import java.util.concurrent.*
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
import javax.persistence.*
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.Lob
|
||||
|
||||
// TODO: Stop the wallet explorer and other clients from using this class and get rid of persistentInbox
|
||||
|
||||
@ -245,7 +248,7 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
||||
}, {})
|
||||
|
||||
val myLegalName = loadKeyStore(config.sslKeystore, config.keyStorePassword).getX509Certificate(X509Utilities.CORDA_CLIENT_TLS).subject
|
||||
rpcServer = RPCServer(rpcOps, NODE_USER, NODE_USER, locator, userService, myLegalName)
|
||||
rpcServer = RPCServer(rpcOps, NODE_USER, NODE_USER, locator, userService, CordaX500Name.build(myLegalName))
|
||||
|
||||
fun checkVerifierCount() {
|
||||
if (session.queueQuery(SimpleString(VERIFICATION_REQUESTS_QUEUE_NAME)).consumerCount == 0) {
|
||||
@ -377,7 +380,7 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
||||
val uuid = message.required(HDR_DUPLICATE_DETECTION_ID) { UUID.fromString(message.getStringProperty(it)) }
|
||||
log.trace { "Received message from: ${message.address} user: $user topic: $topic sessionID: $sessionID uuid: $uuid" }
|
||||
|
||||
return ArtemisReceivedMessage(TopicSession(topic, sessionID), X500Name(user), platformVersion, uuid, message)
|
||||
return ArtemisReceivedMessage(TopicSession(topic, sessionID), CordaX500Name.parse(user), platformVersion, uuid, message)
|
||||
} catch (e: Exception) {
|
||||
log.error("Unable to process message, ignoring it: $message", e)
|
||||
return null
|
||||
@ -390,7 +393,7 @@ class NodeMessagingClient(override val config: NodeConfiguration,
|
||||
}
|
||||
|
||||
private class ArtemisReceivedMessage(override val topicSession: TopicSession,
|
||||
override val peer: X500Name,
|
||||
override val peer: CordaX500Name,
|
||||
override val platformVersion: Int,
|
||||
override val uniqueMessageId: UUID,
|
||||
private val message: ClientMessage) : ReceivedMessage {
|
||||
|
@ -12,13 +12,16 @@ import com.google.common.collect.Multimaps
|
||||
import com.google.common.collect.SetMultimap
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.LazyStickyPool
|
||||
import net.corda.core.internal.LifeCycle
|
||||
import net.corda.core.messaging.RPCOps
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.SerializationDefaults.RPC_SERVER_CONTEXT
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.core.utilities.Try
|
||||
import net.corda.core.utilities.debug
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.node.services.RPCUserService
|
||||
import net.corda.nodeapi.*
|
||||
import net.corda.nodeapi.ArtemisMessagingComponent.Companion.NODE_USER
|
||||
@ -32,7 +35,6 @@ import org.apache.activemq.artemis.api.core.client.ServerLocator
|
||||
import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl
|
||||
import org.apache.activemq.artemis.api.core.management.CoreNotificationType
|
||||
import org.apache.activemq.artemis.api.core.management.ManagementHelper
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import rx.Notification
|
||||
import rx.Observable
|
||||
import rx.Subscriber
|
||||
@ -76,7 +78,7 @@ class RPCServer(
|
||||
private val rpcServerPassword: String,
|
||||
private val serverLocator: ServerLocator,
|
||||
private val userService: RPCUserService,
|
||||
private val nodeLegalName: X500Name,
|
||||
private val nodeLegalName: CordaX500Name,
|
||||
private val rpcConfiguration: RPCServerConfiguration = RPCServerConfiguration.default
|
||||
) {
|
||||
private companion object {
|
||||
@ -341,7 +343,7 @@ class RPCServer(
|
||||
val rpcUser = userService.getUser(validatedUser)
|
||||
if (rpcUser != null) {
|
||||
return rpcUser
|
||||
} else if (X500Name(validatedUser) == nodeLegalName) {
|
||||
} else if (CordaX500Name.parse(validatedUser) == nodeLegalName) {
|
||||
return nodeUser
|
||||
} else {
|
||||
throw IllegalArgumentException("Validated user '$validatedUser' is not an RPC user nor the NODE user")
|
||||
|
@ -2,6 +2,7 @@ package net.corda.node.services.network
|
||||
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.VisibleForTesting
|
||||
import net.corda.core.internal.bufferUntilSubscribed
|
||||
@ -32,7 +33,6 @@ import net.corda.node.utilities.AddOrRemove
|
||||
import net.corda.node.utilities.DatabaseTransactionManager
|
||||
import net.corda.node.utilities.bufferUntilDatabaseCommit
|
||||
import net.corda.node.utilities.wrapWithDatabaseTransaction
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.hibernate.Session
|
||||
import rx.Observable
|
||||
import rx.subjects.PublishSubject
|
||||
@ -90,7 +90,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
|
||||
}
|
||||
|
||||
// TODO See comment to queryByLegalName why it's left like that.
|
||||
override fun getNodeByLegalName(principal: X500Name): NodeInfo? = partyNodes.singleOrNull { it.legalIdentity.name == principal }
|
||||
override fun getNodeByLegalName(principal: CordaX500Name): NodeInfo? = partyNodes.singleOrNull { it.legalIdentity.name == principal }
|
||||
//serviceHub!!.database.transaction { queryByLegalName(principal).firstOrNull() }
|
||||
override fun getNodeByLegalIdentityKey(identityKey: PublicKey): NodeInfo? =
|
||||
serviceHub.database.transaction { queryByIdentityKey(identityKey).firstOrNull() }
|
||||
@ -288,10 +288,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO It's useless for now, because toString on X500 names is inconsistent and we have:
|
||||
// C=ES,L=Madrid,O=Alice Corp,CN=Alice Corp
|
||||
// CN=Alice Corp,O=Alice Corp,L=Madrid,C=ES
|
||||
private fun queryByLegalName(name: X500Name): List<NodeInfo> {
|
||||
private fun queryByLegalName(name: CordaX500Name): List<NodeInfo> {
|
||||
createSession {
|
||||
val query = it.createQuery(
|
||||
"SELECT n FROM ${NodeInfoSchemaV1.PersistentNodeInfo::class.java.name} n JOIN n.legalIdentitiesAndCerts l WHERE l.name = :name",
|
||||
|
@ -1,15 +1,15 @@
|
||||
package net.corda.node.services.persistence
|
||||
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import javax.persistence.AttributeConverter
|
||||
import javax.persistence.Converter
|
||||
|
||||
/**
|
||||
* Converter to persist a party as its's well known identity (where resolvable)
|
||||
* Completely anonymous parties are stored as null (to preserve privacy)
|
||||
* Converter to persist a party as its' well known identity (where resolvable).
|
||||
* Completely anonymous parties are stored as null (to preserve privacy).
|
||||
*/
|
||||
@Converter(autoApply = true)
|
||||
class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityService) : AttributeConverter<AbstractParty, String> {
|
||||
@ -30,7 +30,7 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic
|
||||
|
||||
override fun convertToEntityAttribute(dbData: String?): AbstractParty? {
|
||||
if (dbData != null) {
|
||||
val party = identityService.partyFromX500Name(X500Name(dbData))
|
||||
val party = identityService.partyFromX500Name(CordaX500Name.parse(dbData))
|
||||
if (party != null) return party
|
||||
log.warn ("Identity service unable to resolve X500name: $dbData")
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ package net.corda.node.services.transactions
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import com.google.common.util.concurrent.SettableFuture
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.NotaryException
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.NotaryService
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
@ -18,7 +20,6 @@ import net.corda.core.utilities.*
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.node.utilities.AppendOnlyPersistentMap
|
||||
import net.corda.node.utilities.NODE_DATABASE_PREFIX
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import javax.persistence.Entity
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
@ -106,7 +107,7 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, c
|
||||
id = SecureHash.parse(it.consumingTxHash),
|
||||
inputIndex = it.consumingIndex,
|
||||
requestingParty = Party(
|
||||
name = X500Name(it.party.name),
|
||||
name = CordaX500Name.parse(it.party.name),
|
||||
owningKey = parsePublicKeyBase58(it.party.owningKey))))
|
||||
},
|
||||
toPersistentEntity = { (txHash, index) : StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx ->
|
||||
|
@ -2,8 +2,7 @@ package net.corda.node.services.transactions
|
||||
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.utilities.parsePublicKeyBase58
|
||||
import net.corda.core.utilities.toBase58String
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.ThreadBox
|
||||
import net.corda.core.node.services.UniquenessException
|
||||
@ -11,8 +10,10 @@ import net.corda.core.node.services.UniquenessProvider
|
||||
import net.corda.core.schemas.PersistentStateRef
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.node.utilities.*
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import net.corda.core.utilities.parsePublicKeyBase58
|
||||
import net.corda.core.utilities.toBase58String
|
||||
import net.corda.node.utilities.AppendOnlyPersistentMap
|
||||
import net.corda.node.utilities.NODE_DATABASE_PREFIX
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
@ -73,7 +74,7 @@ class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsTok
|
||||
id = SecureHash.parse(it.consumingTxHash),
|
||||
inputIndex = it.consumingIndex,
|
||||
requestingParty = Party(
|
||||
name = X500Name(it.party.name),
|
||||
name = CordaX500Name.parse(it.party.name),
|
||||
owningKey = parsePublicKeyBase58(it.party.owningKey))))
|
||||
},
|
||||
toPersistentEntity = { (txHash, index) : StateRef, (id, inputIndex, requestingParty) : UniquenessProvider.ConsumingTx ->
|
||||
|
@ -1,12 +1,12 @@
|
||||
package net.corda.node.utilities
|
||||
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.exists
|
||||
import net.corda.core.internal.read
|
||||
import net.corda.core.internal.toX509CertHolder
|
||||
import net.corda.core.internal.write
|
||||
import net.corda.core.utilities.cert
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.cert.X509CertificateHolder
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
@ -174,26 +174,26 @@ fun KeyStore.getSupportedKey(alias: String, keyPassword: String): PrivateKey {
|
||||
class KeyStoreWrapper(private val storePath: Path, private val storePassword: String) {
|
||||
private val keyStore = storePath.read { loadKeyStore(it, storePassword) }
|
||||
|
||||
private fun createCertificate(serviceName: X500Name, pubKey: PublicKey): CertPath {
|
||||
private fun createCertificate(serviceName: CordaX500Name, pubKey: PublicKey): CertPath {
|
||||
val clientCertPath = keyStore.getCertificateChain(X509Utilities.CORDA_CLIENT_CA)
|
||||
// Assume key password = store password.
|
||||
val clientCA = certificateAndKeyPair(X509Utilities.CORDA_CLIENT_CA)
|
||||
// Create new keys and store in keystore.
|
||||
val cert = X509Utilities.createCertificate(CertificateType.IDENTITY, clientCA.certificate, clientCA.keyPair, serviceName, pubKey)
|
||||
val cert = X509Utilities.createCertificate(CertificateType.IDENTITY, clientCA.certificate, clientCA.keyPair, serviceName.x500Name, pubKey)
|
||||
val certPath = CertificateFactory.getInstance("X509").generateCertPath(listOf(cert.cert) + clientCertPath)
|
||||
require(certPath.certificates.isNotEmpty()) { "Certificate path cannot be empty" }
|
||||
// TODO: X509Utilities.validateCertificateChain()
|
||||
return certPath
|
||||
}
|
||||
|
||||
fun signAndSaveNewKeyPair(serviceName: X500Name, privateKeyAlias: String, keyPair: KeyPair) {
|
||||
fun signAndSaveNewKeyPair(serviceName: CordaX500Name, privateKeyAlias: String, keyPair: KeyPair) {
|
||||
val certPath = createCertificate(serviceName, keyPair.public)
|
||||
// Assume key password = store password.
|
||||
keyStore.addOrReplaceKey(privateKeyAlias, keyPair.private, storePassword.toCharArray(), certPath.certificates.toTypedArray())
|
||||
keyStore.save(storePath, storePassword)
|
||||
}
|
||||
|
||||
fun savePublicKey(serviceName: X500Name, pubKeyAlias: String, pubKey: PublicKey) {
|
||||
fun savePublicKey(serviceName: CordaX500Name, pubKeyAlias: String, pubKey: PublicKey) {
|
||||
val certPath = createCertificate(serviceName, pubKey)
|
||||
// Assume key password = store password.
|
||||
keyStore.addOrReplaceCertificate(pubKeyAlias, certPath.certificates.first())
|
||||
|
@ -2,10 +2,10 @@ package net.corda.node.utilities
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
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
|
||||
|
||||
@ -25,7 +25,7 @@ object ServiceIdentityGenerator {
|
||||
// TODO: This needs to write out to the key store, not just files on disk
|
||||
fun generateToDisk(dirs: List<Path>,
|
||||
serviceId: String,
|
||||
serviceName: X500Name,
|
||||
serviceName: CordaX500Name,
|
||||
threshold: Int = 1): Party {
|
||||
log.trace { "Generating a group identity \"serviceName\" for nodes: ${dirs.joinToString()}" }
|
||||
val keyPairs = (1..dirs.size).map { generateKeyPair() }
|
||||
|
@ -3,6 +3,7 @@ package net.corda.node.utilities
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SignatureScheme
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.utilities.cert
|
||||
import net.corda.core.utilities.days
|
||||
import net.corda.core.utilities.millis
|
||||
@ -106,7 +107,29 @@ object X509Utilities {
|
||||
@JvmStatic
|
||||
fun createCertificate(certificateType: CertificateType,
|
||||
issuerCertificate: X509CertificateHolder, issuerKeyPair: KeyPair,
|
||||
subject: X500Name, subjectPublicKey: PublicKey,
|
||||
subject: CordaX500Name, subjectPublicKey: PublicKey,
|
||||
validityWindow: Pair<Duration, Duration> = DEFAULT_VALIDITY_WINDOW,
|
||||
nameConstraints: NameConstraints? = null): X509CertificateHolder {
|
||||
val window = getCertificateValidityWindow(validityWindow.first, validityWindow.second, issuerCertificate)
|
||||
return createCertificate(certificateType, issuerCertificate.subject, issuerKeyPair, subject.x500Name, subjectPublicKey, window, nameConstraints)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a X509 v3 cert.
|
||||
* @param issuerCertificate The Public certificate of the root CA above this used to sign it.
|
||||
* @param issuerKeyPair The KeyPair of the root CA above this used to sign it.
|
||||
* @param subject subject of the generated certificate.
|
||||
* @param subjectPublicKey subject 's public key.
|
||||
* @param validityWindow The certificate's validity window. Default to [DEFAULT_VALIDITY_WINDOW] if not provided.
|
||||
* @return A data class is returned containing the new intermediate CA Cert and its KeyPair for signing downstream certificates.
|
||||
* Note the generated certificate tree is capped at max depth of 1 below this to be in line with commercially available certificates.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun createCertificate(certificateType: CertificateType,
|
||||
issuerCertificate: X509CertificateHolder,
|
||||
issuerKeyPair: KeyPair,
|
||||
subject: X500Name,
|
||||
subjectPublicKey: PublicKey,
|
||||
validityWindow: Pair<Duration, Duration> = DEFAULT_VALIDITY_WINDOW,
|
||||
nameConstraints: NameConstraints? = null): X509CertificateHolder {
|
||||
val window = getCertificateValidityWindow(validityWindow.first, validityWindow.second, issuerCertificate)
|
||||
|
@ -4,7 +4,6 @@ import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.utilities.cert
|
||||
import net.corda.core.internal.*
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.core.utilities.validateX500Name
|
||||
import net.corda.node.services.config.NodeConfiguration
|
||||
import net.corda.node.utilities.*
|
||||
import net.corda.node.utilities.X509Utilities.CORDA_CLIENT_CA
|
||||
@ -45,7 +44,6 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration, private v
|
||||
*/
|
||||
// TODO: Stop killing the calling process from within a called function.
|
||||
fun buildKeystore() {
|
||||
validateX500Name(config.myLegalName)
|
||||
config.certificatesDirectory.createDirectories()
|
||||
val caKeyStore = loadOrCreateKeyStore(config.nodeKeystore, keystorePassword)
|
||||
if (!caKeyStore.containsAlias(CORDA_CLIENT_CA)) {
|
||||
@ -53,7 +51,7 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration, private v
|
||||
// We use the self sign certificate to store the key temporarily in the keystore while waiting for the request approval.
|
||||
if (!caKeyStore.containsAlias(SELF_SIGNED_PRIVATE_KEY)) {
|
||||
val keyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val selfSignCert = X509Utilities.createSelfSignedCACertificate(config.myLegalName, keyPair)
|
||||
val selfSignCert = X509Utilities.createSelfSignedCACertificate(config.myLegalName.x500Name, keyPair)
|
||||
// Save to the key store.
|
||||
caKeyStore.addOrReplaceKey(SELF_SIGNED_PRIVATE_KEY, keyPair.private, privateKeyPassword.toCharArray(),
|
||||
arrayOf(selfSignCert))
|
||||
@ -126,7 +124,7 @@ class NetworkRegistrationHelper(private val config: NodeConfiguration, private v
|
||||
private fun submitOrResumeCertificateSigningRequest(keyPair: KeyPair): String {
|
||||
// Retrieve request id from file if exists, else post a request to server.
|
||||
return if (!requestIdStore.exists()) {
|
||||
val request = X509Utilities.createCertificateSigningRequest(config.myLegalName, config.emailAddress, keyPair)
|
||||
val request = X509Utilities.createCertificateSigningRequest(config.myLegalName.x500Name, config.emailAddress, keyPair)
|
||||
val writer = StringWriter()
|
||||
JcaPEMWriter(writer).use {
|
||||
it.writeObject(PemObject("CERTIFICATE REQUEST", request.encoded))
|
||||
|
@ -2,6 +2,7 @@ package net.corda.node
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.flows.*
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.copyToDirectory
|
||||
import net.corda.core.internal.createDirectories
|
||||
@ -9,7 +10,6 @@ import net.corda.core.internal.div
|
||||
import net.corda.core.internal.list
|
||||
import net.corda.core.messaging.startFlow
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.core.utilities.unwrap
|
||||
import net.corda.nodeapi.User
|
||||
import net.corda.smoketesting.NodeConfig
|
||||
@ -29,7 +29,7 @@ class CordappSmokeTest {
|
||||
private val factory = NodeProcess.Factory()
|
||||
|
||||
private val aliceConfig = NodeConfig(
|
||||
legalName = getX500Name(O = "Alice Corp", L = "Madrid", C = "ES"),
|
||||
legalName = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"),
|
||||
p2pPort = port.andIncrement,
|
||||
rpcPort = port.andIncrement,
|
||||
webPort = port.andIncrement,
|
||||
|
@ -10,6 +10,7 @@ import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.StateMachineRunId
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.FlowStateMachine
|
||||
import net.corda.core.internal.concurrent.map
|
||||
@ -46,7 +47,6 @@ import net.corda.testing.contracts.fillWithSomeTestCash
|
||||
import net.corda.testing.node.InMemoryMessagingNetwork
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -307,7 +307,7 @@ class TwoPartyTradeFlowTests {
|
||||
// of gets and puts.
|
||||
private fun makeNodeWithTracking(
|
||||
networkMapAddress: SingleMessageRecipient?,
|
||||
name: X500Name): MockNetwork.MockNode {
|
||||
name: CordaX500Name): MockNetwork.MockNode {
|
||||
// Create a node in the mock network ...
|
||||
return mockNet.createNode(networkMapAddress, nodeFactory = object : MockNetwork.Factory<MockNetwork.MockNode> {
|
||||
override fun create(config: NodeConfiguration,
|
||||
|
@ -4,12 +4,12 @@ import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.flows.NotaryChangeFlow
|
||||
import net.corda.core.flows.StateReplacementException
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.node.internal.AbstractNode
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
@ -21,7 +21,6 @@ import net.corda.testing.dummyCommand
|
||||
import net.corda.testing.getTestPartyAndCertificate
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -88,7 +87,7 @@ class NotaryChangeTests {
|
||||
@Test
|
||||
fun `should throw when a participant refuses to change Notary`() {
|
||||
val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode)
|
||||
val newEvilNotary = getTestPartyAndCertificate(getX500Name(OU="Evil Notary",O="Evil R3",L="London",C="GB"), generateKeyPair().public)
|
||||
val newEvilNotary = getTestPartyAndCertificate(CordaX500Name(organisation = "Evil R3", locality = "London", country = "GB"), generateKeyPair().public)
|
||||
val flow = NotaryChangeFlow(state, newEvilNotary.party)
|
||||
val future = clientNodeA.services.startFlow(flow)
|
||||
|
||||
|
@ -6,13 +6,13 @@ import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.FlowLogicRef
|
||||
import net.corda.core.flows.FlowLogicRefFactory
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.days
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.node.services.identity.InMemoryIdentityService
|
||||
import net.corda.node.services.persistence.DBCheckpointStorage
|
||||
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
|
||||
@ -31,7 +31,6 @@ import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
|
||||
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
|
||||
import net.corda.testing.node.TestClock
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -82,7 +81,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
val kms = MockKeyManagementService(identityService, ALICE_KEY)
|
||||
|
||||
database.transaction {
|
||||
val nullIdentity = X500Name("cn=None")
|
||||
val nullIdentity = CordaX500Name(organisation = "None", locality = "None", country = "GB")
|
||||
val mockMessagingService = InMemoryMessagingNetwork(false).InMemoryMessaging(
|
||||
false,
|
||||
InMemoryMessagingNetwork.PeerHandle(0, nullIdentity),
|
||||
@ -90,7 +89,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
database)
|
||||
services = object : MockServiceHubInternal(
|
||||
database,
|
||||
testNodeConfiguration(Paths.get("."), getX500Name(O = "Alice", L = "London", C = "GB")),
|
||||
testNodeConfiguration(Paths.get("."), CordaX500Name(organisation = "Alice", locality = "London", country = "GB")),
|
||||
overrideClock = testClock,
|
||||
keyManagement = kms,
|
||||
network = mockMessagingService), TestReference {
|
||||
|
@ -1,12 +1,12 @@
|
||||
package net.corda.node.services.network
|
||||
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.node.services.config.NodeConfiguration
|
||||
import net.corda.node.services.messaging.MessagingService
|
||||
import net.corda.node.services.messaging.send
|
||||
@ -31,7 +31,6 @@ import net.corda.testing.DUMMY_MAP
|
||||
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.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -47,7 +46,7 @@ abstract class AbstractNetworkMapServiceTest<out S : AbstractNetworkMapService>
|
||||
lateinit var alice: MockNode
|
||||
|
||||
companion object {
|
||||
val subscriberLegalName = getX500Name(O="Subscriber",L="New York",C="US")
|
||||
val subscriberLegalName = CordaX500Name(organisation ="Subscriber", locality ="New York", country ="US")
|
||||
}
|
||||
|
||||
@Before
|
||||
@ -251,14 +250,14 @@ abstract class AbstractNetworkMapServiceTest<out S : AbstractNetworkMapService>
|
||||
mockNet.runNetwork()
|
||||
}
|
||||
|
||||
private fun addNewNodeToNetworkMap(legalName: X500Name): MockNode {
|
||||
private fun addNewNodeToNetworkMap(legalName: CordaX500Name): MockNode {
|
||||
val node = mockNet.createNode(mapServiceNode.network.myAddress, legalName = legalName)
|
||||
mockNet.runNetwork()
|
||||
lastSerial = System.currentTimeMillis()
|
||||
return node
|
||||
}
|
||||
|
||||
private fun newNodeSeparateFromNetworkMap(legalName: X500Name): MockNode {
|
||||
private fun newNodeSeparateFromNetworkMap(legalName: CordaX500Name): MockNode {
|
||||
return mockNet.createNode(legalName = legalName, nodeFactory = NoNMSNodeFactory)
|
||||
}
|
||||
|
||||
|
@ -3,17 +3,16 @@ package net.corda.node.services.network
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.node.services.UnknownAnonymousPartyException
|
||||
import net.corda.node.utilities.CertificateAndKeyPair
|
||||
import net.corda.core.utilities.cert
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.node.services.identity.InMemoryIdentityService
|
||||
import net.corda.node.utilities.CertificateType
|
||||
import net.corda.node.utilities.X509Utilities
|
||||
import net.corda.testing.*
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Test
|
||||
import java.security.cert.CertificateFactory
|
||||
import kotlin.test.assertEquals
|
||||
@ -63,7 +62,7 @@ class InMemoryIdentityServiceTests {
|
||||
val service = InMemoryIdentityService(trustRoot = trustRoot.certificate)
|
||||
service.verifyAndRegisterIdentity(ALICE_IDENTITY)
|
||||
service.verifyAndRegisterIdentity(BOB_IDENTITY)
|
||||
val alicente = getTestPartyAndCertificate(getX500Name(O = "Alicente Worldwide", L = "London", C = "GB"), generateKeyPair().public)
|
||||
val alicente = getTestPartyAndCertificate(CordaX500Name(organisation = "Alicente Worldwide", locality = "London", country = "GB"), generateKeyPair().public)
|
||||
service.verifyAndRegisterIdentity(alicente)
|
||||
assertEquals(setOf(ALICE, alicente.party), service.partiesFromName("Alice", false))
|
||||
assertEquals(setOf(ALICE), service.partiesFromName("Alice Corp", true))
|
||||
@ -73,8 +72,8 @@ class InMemoryIdentityServiceTests {
|
||||
@Test
|
||||
fun `get identity by name`() {
|
||||
val service = InMemoryIdentityService(trustRoot = DUMMY_CA.certificate)
|
||||
val identities = listOf("Node A", "Node B", "Node C")
|
||||
.map { getTestPartyAndCertificate(getX500Name(O = it, OU = "corda", L = "London", C = "GB"), generateKeyPair().public) }
|
||||
val identities = listOf("Org A", "Org B", "Org C")
|
||||
.map { getTestPartyAndCertificate(CordaX500Name(organisation = it, locality = "London", country = "GB"), generateKeyPair().public) }
|
||||
assertNull(service.partyFromX500Name(identities.first().name))
|
||||
identities.forEach { service.verifyAndRegisterIdentity(it) }
|
||||
identities.forEach { assertEquals(it.party, service.partyFromX500Name(it.name)) }
|
||||
@ -87,7 +86,7 @@ class InMemoryIdentityServiceTests {
|
||||
fun `assert unknown anonymous key is unrecognised`() {
|
||||
withTestSerialization {
|
||||
val rootKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val rootCert = X509Utilities.createSelfSignedCACertificate(ALICE.name, rootKey)
|
||||
val rootCert = X509Utilities.createSelfSignedCACertificate(ALICE.name.x500Name, rootKey)
|
||||
val txKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val service = InMemoryIdentityService(trustRoot = DUMMY_CA.certificate)
|
||||
// TODO: Generate certificate with an EdDSA key rather than ECDSA
|
||||
@ -152,17 +151,18 @@ class InMemoryIdentityServiceTests {
|
||||
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val owningKey = Crypto.decodePublicKey(trustRoot.certificate.subjectPublicKeyInfo.encoded)
|
||||
service.assertOwnership(Party(trustRoot.certificate.subject, owningKey), anonymousAlice.party.anonymise())
|
||||
val subject = CordaX500Name.build(trustRoot.certificate.subject)
|
||||
service.assertOwnership(Party(subject, owningKey), anonymousAlice.party.anonymise())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createParty(x500Name: X500Name, ca: CertificateAndKeyPair): Pair<PartyAndCertificate, PartyAndCertificate> {
|
||||
private fun createParty(x500Name: CordaX500Name, ca: CertificateAndKeyPair): Pair<PartyAndCertificate, PartyAndCertificate> {
|
||||
val certFactory = CertificateFactory.getInstance("X509")
|
||||
val issuerKeyPair = generateKeyPair()
|
||||
val issuer = getTestPartyAndCertificate(x500Name, issuerKeyPair.public, ca)
|
||||
val txKey = Crypto.generateKeyPair()
|
||||
val txCert = X509Utilities.createCertificate(CertificateType.IDENTITY, issuer.certificate, issuerKeyPair, x500Name, txKey.public)
|
||||
val txCert = X509Utilities.createCertificate(CertificateType.IDENTITY, issuer.certificate, issuerKeyPair, x500Name.x500Name, txKey.public)
|
||||
val txCertPath = certFactory.generateCertPath(listOf(txCert.cert) + issuer.certPath.certificates)
|
||||
return Pair(issuer, PartyAndCertificate(txCertPath))
|
||||
}
|
||||
|
@ -3,20 +3,19 @@ package net.corda.node.services.network
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.node.services.UnknownAnonymousPartyException
|
||||
import net.corda.node.utilities.CertificateAndKeyPair
|
||||
import net.corda.core.utilities.cert
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.node.services.identity.PersistentIdentityService
|
||||
import net.corda.node.utilities.CertificateType
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.X509Utilities
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.node.MockServices
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@ -97,7 +96,7 @@ class PersistentIdentityServiceTests {
|
||||
identityService.verifyAndRegisterIdentity(ALICE_IDENTITY)
|
||||
identityService.verifyAndRegisterIdentity(BOB_IDENTITY)
|
||||
}
|
||||
val alicente = getTestPartyAndCertificate(getX500Name(O = "Alicente Worldwide", L = "London", C = "GB"), generateKeyPair().public)
|
||||
val alicente = getTestPartyAndCertificate(CordaX500Name(organisation = "Alicente Worldwide", locality = "London", country = "GB"), generateKeyPair().public)
|
||||
database.transaction {
|
||||
identityService.verifyAndRegisterIdentity(alicente)
|
||||
assertEquals(setOf(ALICE, alicente.party), identityService.partiesFromName("Alice", false))
|
||||
@ -108,8 +107,8 @@ class PersistentIdentityServiceTests {
|
||||
|
||||
@Test
|
||||
fun `get identity by name`() {
|
||||
val identities = listOf("Node A", "Node B", "Node C")
|
||||
.map { getTestPartyAndCertificate(getX500Name(O = it, OU = "corda", L = "London", C = "GB"), generateKeyPair().public) }
|
||||
val identities = listOf("Organisation A", "Organisation B", "Organisation C")
|
||||
.map { getTestPartyAndCertificate(CordaX500Name(organisation = it, locality = "London", country = "GB"), generateKeyPair().public) }
|
||||
database.transaction {
|
||||
assertNull(identityService.partyFromX500Name(identities.first().name))
|
||||
}
|
||||
@ -132,7 +131,7 @@ class PersistentIdentityServiceTests {
|
||||
fun `assert unknown anonymous key is unrecognised`() {
|
||||
withTestSerialization {
|
||||
val rootKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val rootCert = X509Utilities.createSelfSignedCACertificate(ALICE.name, rootKey)
|
||||
val rootCert = X509Utilities.createSelfSignedCACertificate(ALICE.name.x500Name, rootKey)
|
||||
val txKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_IDENTITY_SIGNATURE_SCHEME)
|
||||
val identity = Party(rootCert)
|
||||
val txIdentity = AnonymousParty(txKey.public)
|
||||
@ -214,7 +213,8 @@ class PersistentIdentityServiceTests {
|
||||
assertFailsWith<IllegalArgumentException> {
|
||||
val owningKey = Crypto.decodePublicKey(trustRoot.certificate.subjectPublicKeyInfo.encoded)
|
||||
database.transaction {
|
||||
identityService.assertOwnership(Party(trustRoot.certificate.subject, owningKey), anonymousAlice.party.anonymise())
|
||||
val subject = CordaX500Name.build(trustRoot.certificate.subject)
|
||||
identityService.assertOwnership(Party(subject, owningKey), anonymousAlice.party.anonymise())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,12 +256,12 @@ class PersistentIdentityServiceTests {
|
||||
assertEquals(anonymousBob, bobReload!!)
|
||||
}
|
||||
|
||||
private fun createParty(x500Name: X500Name, ca: CertificateAndKeyPair): Pair<PartyAndCertificate, PartyAndCertificate> {
|
||||
private fun createParty(x500Name: CordaX500Name, ca: CertificateAndKeyPair): Pair<PartyAndCertificate, PartyAndCertificate> {
|
||||
val certFactory = CertificateFactory.getInstance("X509")
|
||||
val issuerKeyPair = generateKeyPair()
|
||||
val issuer = getTestPartyAndCertificate(x500Name, issuerKeyPair.public, ca)
|
||||
val txKey = Crypto.generateKeyPair()
|
||||
val txCert = X509Utilities.createCertificate(CertificateType.IDENTITY, issuer.certificate, issuerKeyPair, x500Name, txKey.public)
|
||||
val txCert = X509Utilities.createCertificate(CertificateType.IDENTITY, issuer.certificate, issuerKeyPair, x500Name.x500Name, txKey.public)
|
||||
val txCertPath = certFactory.generateCertPath(listOf(txCert.cert) + issuer.certPath.certificates)
|
||||
return Pair(issuer, PartyAndCertificate(txCertPath))
|
||||
}
|
||||
|
@ -4,13 +4,10 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.InitiatedBy
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.core.utilities.toBase58String
|
||||
import net.corda.core.utilities.unwrap
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.node.internal.Node
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.testing.BOB
|
||||
@ -18,7 +15,6 @@ import net.corda.testing.CHARLIE
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.node.NodeBasedTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
@ -26,7 +22,7 @@ import kotlin.test.assertFails
|
||||
|
||||
class PersistentNetworkMapCacheTest : NodeBasedTest() {
|
||||
val partiesList = listOf(DUMMY_NOTARY, ALICE, BOB)
|
||||
val addressesMap: HashMap<X500Name, NetworkHostAndPort> = HashMap()
|
||||
val addressesMap: HashMap<CordaX500Name, NetworkHostAndPort> = HashMap()
|
||||
val infos: MutableSet<NodeInfo> = HashSet()
|
||||
|
||||
@Before
|
||||
|
@ -9,6 +9,7 @@ import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.flows.*
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.internal.concurrent.flatMap
|
||||
import net.corda.core.internal.concurrent.map
|
||||
@ -21,8 +22,11 @@ import net.corda.core.serialization.serialize
|
||||
import net.corda.core.toFuture
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.core.utilities.ProgressTracker.Change
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.unwrap
|
||||
import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.flows.CashIssueFlow
|
||||
import net.corda.finance.flows.CashPaymentFlow
|
||||
@ -77,7 +81,7 @@ class FlowFrameworkTests {
|
||||
|
||||
// We intentionally create our own notary and ignore the one provided by the network
|
||||
val notaryKeyPair = generateKeyPair()
|
||||
val notaryService = ServiceInfo(ValidatingNotaryService.type, getX500Name(O = "notary-service-2000", L = "London", C = "GB"))
|
||||
val notaryService = ServiceInfo(ValidatingNotaryService.type, CordaX500Name(organisation = "Notary service 2000", locality = "London", country = "GB"))
|
||||
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.
|
||||
|
@ -3,6 +3,7 @@ package net.corda.node.services.vault
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.entropyToKeyPair
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.node.services.*
|
||||
@ -54,7 +55,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
||||
|
||||
// test cash notary
|
||||
val CASH_NOTARY_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(21)) }
|
||||
val CASH_NOTARY: Party get() = Party(getX500Name(O = "Cash Notary Service", OU = "corda", L = "Zurich", C = "CH"), CASH_NOTARY_KEY.public)
|
||||
val CASH_NOTARY: Party get() = Party(CordaX500Name(organisation = "Cash Notary Service", locality = "Zurich", country = "CH"), CASH_NOTARY_KEY.public)
|
||||
val CASH_NOTARY_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(CASH_NOTARY.nameOrNull(), CASH_NOTARY_KEY.public)
|
||||
|
||||
@Before
|
||||
@ -1484,15 +1485,15 @@ class VaultQueryTests : TestDependencyInjectionBase() {
|
||||
fun `unconsumed fungible assets for selected issuer parties`() {
|
||||
// GBP issuer
|
||||
val gbpCashIssuerKey = entropyToKeyPair(BigInteger.valueOf(1001))
|
||||
val gbpCashIssuer = Party(getX500Name(O = "British Pounds Cash Issuer", OU = "corda", L = "London", C = "GB"), gbpCashIssuerKey.public).ref(1)
|
||||
val gbpCashIssuer = Party(CordaX500Name(organisation = "British Pounds Cash Issuer", locality = "London", country = "GB"), gbpCashIssuerKey.public).ref(1)
|
||||
val gbpCashIssuerServices = MockServices(gbpCashIssuerKey)
|
||||
// USD issuer
|
||||
val usdCashIssuerKey = entropyToKeyPair(BigInteger.valueOf(1002))
|
||||
val usdCashIssuer = Party(getX500Name(O = "US Dollars Cash Issuer", OU = "corda", L = "New York", C = "US"), usdCashIssuerKey.public).ref(1)
|
||||
val usdCashIssuer = Party(CordaX500Name(organisation = "US Dollars Cash Issuer", locality = "New York", country = "US"), usdCashIssuerKey.public).ref(1)
|
||||
val usdCashIssuerServices = MockServices(usdCashIssuerKey)
|
||||
// CHF issuer
|
||||
val chfCashIssuerKey = entropyToKeyPair(BigInteger.valueOf(1003))
|
||||
val chfCashIssuer = Party(getX500Name(O = "Swiss Francs Cash Issuer", OU = "corda", L = "Zurich", C = "CH"), chfCashIssuerKey.public).ref(1)
|
||||
val chfCashIssuer = Party(CordaX500Name(organisation = "Swiss Francs Cash Issuer", locality = "Zurich", country = "CH"), chfCashIssuerKey.public).ref(1)
|
||||
val chfCashIssuerServices = MockServices(chfCashIssuerKey)
|
||||
|
||||
database.transaction {
|
||||
|
@ -11,7 +11,6 @@ import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.cert
|
||||
import net.corda.core.utilities.commonName
|
||||
import net.corda.core.utilities.getX500Name
|
||||
import net.corda.core.utilities.organisation
|
||||
import net.corda.node.serialization.KryoServerSerializationScheme
|
||||
import net.corda.node.services.config.createKeystoreForCordaNode
|
||||
import net.corda.nodeapi.internal.serialization.AllWhitelist
|
||||
@ -318,7 +317,7 @@ class X509UtilitiesTest {
|
||||
val peerChain = clientSocket.session.peerCertificates
|
||||
val peerX500Principal = (peerChain[0] as X509Certificate).subjectX500Principal
|
||||
val x500name = X500Name(peerX500Principal.name)
|
||||
assertEquals(MEGA_CORP.name, x500name)
|
||||
assertEquals(MEGA_CORP.name.x500Name, x500name)
|
||||
X509Utilities.validateCertificateChain(trustStore.getX509Certificate(X509Utilities.CORDA_ROOT_CA), *peerChain)
|
||||
val output = DataOutputStream(clientSocket.outputStream)
|
||||
output.writeUTF("Hello World")
|
||||
@ -409,7 +408,7 @@ class X509UtilitiesTest {
|
||||
emptyMap(),
|
||||
true,
|
||||
SerializationContext.UseCase.P2P)
|
||||
val expected: X509CertificateHolder = X509Utilities.createSelfSignedCACertificate(ALICE.name, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME))
|
||||
val expected: X509CertificateHolder = X509Utilities.createSelfSignedCACertificate(ALICE.name.x500Name, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME))
|
||||
val serialized = expected.serialize(factory, context).bytes
|
||||
val actual: X509CertificateHolder = serialized.deserialize(factory, context)
|
||||
assertEquals(expected, actual)
|
||||
@ -426,8 +425,8 @@ class X509UtilitiesTest {
|
||||
SerializationContext.UseCase.P2P)
|
||||
val certFactory = CertificateFactory.getInstance("X509")
|
||||
val rootCAKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
|
||||
val rootCACert = X509Utilities.createSelfSignedCACertificate(ALICE.name, rootCAKey)
|
||||
val certificate = X509Utilities.createCertificate(CertificateType.TLS, rootCACert, rootCAKey, BOB.name, BOB_PUBKEY)
|
||||
val rootCACert = X509Utilities.createSelfSignedCACertificate(ALICE.name.x500Name, rootCAKey)
|
||||
val certificate = X509Utilities.createCertificate(CertificateType.TLS, rootCACert, rootCAKey, BOB.name.x500Name, BOB_PUBKEY)
|
||||
val expected = certFactory.generateCertPath(listOf(certificate.cert, rootCACert.cert))
|
||||
val serialized = expected.serialize(factory, context).bytes
|
||||
val actual: CertPath = serialized.deserialize(factory, context)
|
||||
|
@ -5,6 +5,7 @@ import com.nhaarman.mockito_kotlin.eq
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.exists
|
||||
import net.corda.core.internal.toTypedArray
|
||||
import net.corda.core.internal.toX509CertHolder
|
||||
@ -15,6 +16,7 @@ import net.corda.node.utilities.X509Utilities
|
||||
import net.corda.node.utilities.loadKeyStore
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.testing.testNodeConfiguration
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
|
Reference in New Issue
Block a user