Enforce X500Name format defined in design doc (#1427)

* Standardise X500Name format - WIP

* address PR issues

* failing test fix and replace X500Name with getX500Name

* gradle plugin fix

* Added country code validation
This commit is contained in:
Patrick Kuo
2017-09-07 14:47:42 +01:00
committed by GitHub
parent d9d17be284
commit 57412d4498
104 changed files with 1000 additions and 687 deletions

View File

@ -6,15 +6,15 @@ import net.corda.core.flows.StartableByRPC
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
import org.bouncycastle.asn1.x500.X500Name
import org.junit.Test
import kotlin.test.assertTrue
class AdvertisedServiceTests {
private val serviceName = X500Name("CN=Custom Service,O=R3,OU=corda,L=London,C=GB")
private val serviceName = getX500Name(O = "Custom Service", OU = "corda", L = "London", C = "GB")
private val serviceType = ServiceType.corda.getSubType("custom")
private val user = "bankA"
private val pass = "passA"

View File

@ -15,6 +15,7 @@ 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
@ -25,7 +26,6 @@ import net.corda.node.utilities.ServiceIdentityGenerator
import net.corda.testing.contracts.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.node.MockNetwork
import org.bouncycastle.asn1.x500.X500Name
import org.junit.After
import org.junit.Test
import java.nio.file.Files
@ -34,7 +34,7 @@ import kotlin.test.assertTrue
class BFTNotaryServiceTests {
companion object {
private val clusterName = X500Name("CN=BFT,O=R3,OU=corda,L=Zurich,C=CH")
private val clusterName = getX500Name(O = "BFT", OU = "corda", L = "Zurich", C = "CH")
private val serviceType = BFTNonValidatingNotaryService.type
}

View File

@ -10,19 +10,19 @@ 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.DummyContract
import net.corda.testing.dummyCommand
import net.corda.testing.node.NodeBasedTest
import org.bouncycastle.asn1.x500.X500Name
import org.junit.Test
import java.util.*
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class RaftNotaryServiceTests : NodeBasedTest() {
private val notaryName = X500Name("CN=RAFT Notary Service,O=R3,OU=corda,L=London,C=GB")
private val notaryName = getX500Name(O = "RAFT Notary Service", OU = "corda", L = "London", C = "GB")
@Test
fun `detect double spend`() {

View File

@ -12,6 +12,7 @@ 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.*
@ -30,8 +31,8 @@ import java.util.concurrent.atomic.AtomicInteger
class P2PMessagingTest : NodeBasedTest() {
private companion object {
val DISTRIBUTED_SERVICE_NAME = getTestX509Name("DistributedService")
val SERVICE_2_NAME = getTestX509Name("Service 2")
val DISTRIBUTED_SERVICE_NAME = getX500Name(O = "DistributedService", L = "London", C = "GB")
val SERVICE_2_NAME = getX500Name(O = "Service 2", L = "London", C = "GB")
}
@Test

View File

@ -2,12 +2,9 @@ package net.corda.services.messaging
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.concurrent.CordaFuture
import net.corda.core.utilities.cert
import net.corda.core.crypto.random63BitValue
import net.corda.core.node.NodeInfo
import net.corda.core.utilities.seconds
import net.corda.core.utilities.NonEmptySet
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.*
import net.corda.node.internal.NetworkMapInfo
import net.corda.node.services.config.configureWithDevSSLCertificate
import net.corda.node.services.messaging.sendRequest
@ -30,7 +27,7 @@ class P2PSecurityTest : NodeBasedTest() {
@Test
fun `incorrect legal name for the network map service config`() {
val incorrectNetworkMapName = getTestX509Name("NetworkMap-${random63BitValue()}")
val incorrectNetworkMapName = getX500Name(O = "NetworkMap-${random63BitValue()}", L = "London", C = "GB")
val node = startNode(BOB.name, configOverrides = mapOf(
"networkMapService" to mapOf(
"address" to networkMapNode.configuration.p2pAddress.toString(),

View File

@ -147,6 +147,10 @@ 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)
}
/** Fetch CordaPluginRegistry classes registered in META-INF/services/net.corda.core.node.CordaPluginRegistry files that exist in the classpath */
open val pluginRegistries: List<CordaPluginRegistry> by lazy {
ServiceLoader.load(CordaPluginRegistry::class.java).toList()
@ -414,7 +418,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
checkpointStorage = DBCheckpointStorage()
_services = ServiceHubInternalImpl()
attachments = NodeAttachmentService(services.monitoringService.metrics)
val legalIdentity = obtainIdentity("identity", configuration.myLegalName)
val legalIdentity = obtainIdentity()
network = makeMessagingService(legalIdentity)
info = makeInfo(legalIdentity)
@ -497,9 +501,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 ?: X500Name("${configuration.myLegalName},OU=$serviceId")
val identity = obtainIdentity(serviceId, serviceName)
val identity = obtainIdentity(it)
ServiceEntry(it, identity)
}
}
@ -525,12 +527,6 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
"or if you don't have one yet, fill out the config file and run corda.jar --initial-registration. " +
"Read more at: https://docs.corda.net/permissioning.html"
}
val identitiesKeystore = loadKeyStore(configuration.sslKeystore, configuration.keyStorePassword)
val tlsIdentity = identitiesKeystore.getX509Certificate(X509Utilities.CORDA_CLIENT_TLS).subject
require(tlsIdentity == configuration.myLegalName) {
"Expected '${configuration.myLegalName}' but got '$tlsIdentity' from the keystore."
}
}
// Specific class so that MockNode can catch it.
@ -692,15 +688,23 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
protected abstract fun startMessagingService(rpcOps: RPCOps)
private fun obtainIdentity(id: String, name: X500Name): PartyAndCertificate {
private fun obtainIdentity(serviceInfo: ServiceInfo? = null): PartyAndCertificate {
// 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
// the public key. Obviously in a real system this would need to be a certificate chain of some kind to ensure
// the legal name is actually validated in some way.
val keyStore = KeyStoreWrapper(configuration.nodeKeystore, configuration.keyStorePassword)
val (id, name) = if (serviceInfo == null) {
// Create node identity if service info = null
Pair("identity", myLegalName.withCommonName(null))
} else {
val name = serviceInfo.name ?: myLegalName.withCommonName(serviceInfo.type.id)
Pair(serviceInfo.type.id, name)
}
// TODO: Integrate with Key management service?
val keyStore = KeyStoreWrapper(configuration.nodeKeystore, configuration.keyStorePassword)
val privateKeyAlias = "$id-private-key"
val compositeKeyAlias = "$id-composite-key"
@ -715,7 +719,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
migrateKeysFromFile(keyStore, name, pubIdentityFile, privKeyFile, compositeKeyFile, privateKeyAlias, compositeKeyAlias)
} else {
log.info("$privateKeyAlias not found in key store ${configuration.nodeKeystore}, generating fresh key!")
keyStore.saveNewKeyPair(name, privateKeyAlias, generateKeyPair())
keyStore.signAndSaveNewKeyPair(name, privateKeyAlias, generateKeyPair())
}
}
@ -751,7 +755,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
// Load the private key.
val publicKey = Crypto.decodePublicKey(pubKeyFile.readAll())
val privateKey = Crypto.decodePrivateKey(privKeyFile.readAll())
keyStore.saveNewKeyPair(serviceName, privateKeyAlias, KeyPair(publicKey, privateKey))
keyStore.signAndSaveNewKeyPair(serviceName, privateKeyAlias, KeyPair(publicKey, privateKey))
// Store composite key separately.
if (compositeKeyFile.exists()) {
keyStore.savePublicKey(serviceName, compositeKeyAlias, Crypto.decodePublicKey(compositeKeyFile.readAll()))

View File

@ -3,14 +3,11 @@ package net.corda.node.internal
import com.jcabi.manifests.Manifests
import com.typesafe.config.ConfigException
import joptsimple.OptionException
import net.corda.core.utilities.commonName
import net.corda.core.utilities.orgName
import net.corda.core.internal.concurrent.thenMatch
import net.corda.core.internal.createDirectories
import net.corda.core.internal.div
import net.corda.core.internal.*
import net.corda.core.internal.concurrent.thenMatch
import net.corda.core.node.services.ServiceInfo
import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.organisation
import net.corda.node.*
import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.services.transactions.bftSMaRtSerialFilter
@ -102,8 +99,7 @@ open class NodeStartup(val args: Array<String>) {
node.nodeReadyFuture.thenMatch({
val elapsed = (System.currentTimeMillis() - startTime) / 10 / 100.0
// TODO: Replace this with a standard function to get an unambiguous rendering of the X.500 name.
val name = node.info.legalIdentity.name.orgName ?: node.info.legalIdentity.name.commonName
val name = node.info.legalIdentity.name.organisation
Node.printBasicNodeInfo("Node for \"$name\" started up and registered in $elapsed sec")
// Don't start the shell if there's no console attached.

View File

@ -11,6 +11,8 @@ 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
@ -86,11 +88,18 @@ fun createKeystoreForCordaNode(sslKeyStorePath: Path,
val (intermediateCACert, intermediateCAKeyPair) = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, caKeyPassword)
val clientKey = Crypto.generateKeyPair(signatureScheme)
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, legalName))), arrayOf())
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCACert, intermediateCAKeyPair, legalName, clientKey.public, nameConstraints = nameConstraints)
val clientName = legalName.toWellFormattedName().withCommonName(null)
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, clientName))), arrayOf())
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA,
intermediateCACert,
intermediateCAKeyPair,
clientName.withCommonName(X509Utilities.CORDA_CLIENT_CA_CN),
clientKey.public,
nameConstraints = nameConstraints)
val tlsKey = Crypto.generateKeyPair(signatureScheme)
val clientTLSCert = X509Utilities.createCertificate(CertificateType.TLS, clientCACert, clientKey, legalName, tlsKey.public)
val clientTLSCert = X509Utilities.createCertificate(CertificateType.TLS, clientCACert, clientKey, clientName, tlsKey.public)
val keyPass = keyPassword.toCharArray()

View File

@ -19,6 +19,8 @@ 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 networkMapService: NetworkMapInfo?
val minimumPlatformVersion: Int

View File

@ -1,7 +1,6 @@
package net.corda.node.services.identity
import net.corda.core.contracts.PartyAndReference
import net.corda.core.utilities.cert
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty
@ -11,7 +10,9 @@ import net.corda.core.internal.toX509CertHolder
import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.UnknownAnonymousPartyException
import net.corda.core.serialization.SingletonSerializeAsToken
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
@ -65,8 +66,17 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
@Throws(CertificateExpiredException::class, CertificateNotYetValidException::class, InvalidAlgorithmParameterException::class)
override fun verifyAndRegisterIdentity(identity: PartyAndCertificate): PartyAndCertificate? {
// Validate the chain first, before we do anything clever with it
identity.verify(trustAnchor)
try {
identity.verify(trustAnchor)
} catch (e: CertPathValidatorException) {
log.error("Certificate validation failed for ${identity.name} against trusted root ${trustAnchor.trustedCert.subject}.")
log.error("Certificate path :")
identity.certPath.certificates.reversed().forEachIndexed { index, certificate ->
val space = (0 until index).map { " " }.joinToString("")
log.error("$space${certificate.toX509CertHolder().subject}")
}
throw e
}
log.trace { "Registering identity $identity" }
keyToParties[identity.owningKey] = identity
// Always keep the first party we registered, as that's the well known identity

View File

@ -244,7 +244,8 @@ class NodeMessagingClient(override val config: NodeConfiguration,
}
}, {})
rpcServer = RPCServer(rpcOps, NODE_USER, NODE_USER, locator, userService, config.myLegalName)
val myLegalName = loadKeyStore(config.sslKeystore, config.keyStorePassword).getX509Certificate(X509Utilities.CORDA_CLIENT_TLS).subject
rpcServer = RPCServer(rpcOps, NODE_USER, NODE_USER, locator, userService, myLegalName)
fun checkVerifierCount() {
if (session.queueQuery(SimpleString(VERIFICATION_REQUESTS_QUEUE_NAME)).consumerCount == 0) {

View File

@ -1,6 +1,6 @@
package net.corda.node.shell
import net.corda.core.utilities.commonName
import net.corda.core.utilities.organisation
import net.corda.core.flows.FlowInitiator
import net.corda.core.flows.StateMachineRunId
import net.corda.core.internal.concurrent.openFuture
@ -110,7 +110,7 @@ class FlowWatchPrintingSubscriber(private val toStream: RenderPrintWriter) : Sub
return when (flowInitiator) {
is FlowInitiator.Scheduled -> flowInitiator.scheduledState.ref.toString()
is FlowInitiator.Shell -> "Shell" // TODO Change when we will have more information on shell user.
is FlowInitiator.Peer -> flowInitiator.party.name.commonName
is FlowInitiator.Peer -> flowInitiator.party.name.organisation
is FlowInitiator.RPC -> "RPC: " + flowInitiator.username
}
}

View File

@ -183,10 +183,11 @@ class KeyStoreWrapper(private val storePath: Path, private val storePassword: St
val cert = X509Utilities.createCertificate(CertificateType.IDENTITY, clientCA.certificate, clientCA.keyPair, serviceName, 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 saveNewKeyPair(serviceName: X500Name, privateKeyAlias: String, keyPair: KeyPair) {
fun signAndSaveNewKeyPair(serviceName: X500Name, 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())

View File

@ -1,13 +1,17 @@
package net.corda.node.utilities
import net.corda.core.crypto.*
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SignatureScheme
import net.corda.core.crypto.random63BitValue
import net.corda.core.utilities.cert
import net.corda.core.utilities.days
import net.corda.core.utilities.millis
import org.bouncycastle.asn1.ASN1EncodableVector
import org.bouncycastle.asn1.ASN1Sequence
import org.bouncycastle.asn1.DERSequence
import org.bouncycastle.asn1.DERUTF8String
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x500.style.BCStyle
import org.bouncycastle.asn1.x509.*
import org.bouncycastle.asn1.x509.Extension
import org.bouncycastle.cert.X509CertificateHolder
@ -44,6 +48,8 @@ object X509Utilities {
val CORDA_CLIENT_TLS = "cordaclienttls"
val CORDA_CLIENT_CA = "cordaclientca"
val CORDA_CLIENT_CA_CN = "Corda Client CA Certificate"
private val DEFAULT_VALIDITY_WINDOW = Pair(0.millis, 3650.days)
/**
* Helper function to return the latest out of an instant and an optional date.
@ -107,6 +113,7 @@ object X509Utilities {
return createCertificate(certificateType, issuerCertificate.subject, issuerKeyPair, subject, subjectPublicKey, window, nameConstraints)
}
@Throws(CertPathValidatorException::class)
fun validateCertificateChain(trustedRoot: X509CertificateHolder, vararg certificates: Certificate) {
require(certificates.isNotEmpty()) { "Certificate path must contain at least one certificate" }
val certFactory = CertificateFactory.getInstance("X509")
@ -225,12 +232,12 @@ object X509Utilities {
/**
* Create certificate signing request using provided information.
*/
fun createCertificateSigningRequest(subject: X500Name, keyPair: KeyPair, signatureScheme: SignatureScheme): PKCS10CertificationRequest {
fun createCertificateSigningRequest(subject: X500Name, email: String, keyPair: KeyPair, signatureScheme: SignatureScheme): PKCS10CertificationRequest {
val signer = ContentSignerBuilder.build(signatureScheme, keyPair.private, Crypto.findProvider(signatureScheme.providerName))
return JcaPKCS10CertificationRequestBuilder(subject, keyPair.public).build(signer)
return JcaPKCS10CertificationRequestBuilder(subject, keyPair.public).addAttribute(BCStyle.E, DERUTF8String(email)).build(signer)
}
fun createCertificateSigningRequest(subject: X500Name, keyPair: KeyPair) = createCertificateSigningRequest(subject, keyPair, DEFAULT_TLS_SIGNATURE_SCHEME)
fun createCertificateSigningRequest(subject: X500Name, email: String, keyPair: KeyPair) = createCertificateSigningRequest(subject, email, keyPair, DEFAULT_TLS_SIGNATURE_SCHEME)
}

View File

@ -22,7 +22,7 @@ import kotlin.system.exitProcess
* Helper for managing the node registration process, which checks for any existing certificates and requests them if
* needed.
*/
class NetworkRegistrationHelper(val config: NodeConfiguration, val certService: NetworkRegistrationService) {
class NetworkRegistrationHelper(private val config: NodeConfiguration, private val certService: NetworkRegistrationService) {
companion object {
val pollInterval = 10.seconds
val SELF_SIGNED_PRIVATE_KEY = "Self Signed Private Key"
@ -100,7 +100,6 @@ class NetworkRegistrationHelper(val config: NodeConfiguration, val certService:
}
}
/**
* Poll Certificate Signing Server for approved certificate,
* enter a slow polling loop if server return null.
@ -127,7 +126,7 @@ class NetworkRegistrationHelper(val config: NodeConfiguration, val certService:
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, keyPair)
val request = X509Utilities.createCertificateSigningRequest(config.myLegalName, config.emailAddress, keyPair)
val writer = StringWriter()
JcaPEMWriter(writer).use {
it.writeObject(PemObject("CERTIFICATE REQUEST", request.encoded))

View File

@ -9,11 +9,11 @@ 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.nodeapi.User
import net.corda.smoketesting.NodeConfig
import net.corda.smoketesting.NodeProcess
import org.assertj.core.api.Assertions.assertThat
import org.bouncycastle.asn1.x500.X500Name
import org.junit.Test
import java.nio.file.Paths
import java.util.concurrent.atomic.AtomicInteger
@ -28,7 +28,7 @@ class CordappSmokeTest {
private val factory = NodeProcess.Factory()
private val aliceConfig = NodeConfig(
legalName = X500Name("CN=Alice Corp,O=Alice Corp,L=Madrid,C=ES"),
legalName = getX500Name(O = "Alice Corp", L = "Madrid", C = "ES"),
p2pPort = port.andIncrement,
rpcPort = port.andIncrement,
webPort = port.andIncrement,

View File

@ -9,6 +9,7 @@ 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
@ -86,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(X500Name("CN=Evil Notary,O=Evil R3,OU=corda,L=London,C=GB"), generateKeyPair().public)
val newEvilNotary = getTestPartyAndCertificate(getX500Name(OU="Evil Notary",O="Evil R3",L="London",C="GB"), generateKeyPair().public)
val flow = NotaryChangeFlow(state, newEvilNotary.party)
val future = clientNodeA.services.startFlow(flow)

View File

@ -1,9 +1,9 @@
package net.corda.node.services.config
import net.corda.core.utilities.commonName
import net.corda.core.utilities.organisation
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.testing.ALICE
import net.corda.nodeapi.User
import net.corda.testing.ALICE
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
import org.assertj.core.api.Assertions.assertThatThrownBy
@ -21,7 +21,7 @@ class FullNodeConfigurationTest {
emailAddress = "",
keyStorePassword = "cordacadevpass",
trustStorePassword = "trustpass",
dataSourceProperties = makeTestDataSourceProperties(ALICE.name.commonName),
dataSourceProperties = makeTestDataSourceProperties(ALICE.name.organisation),
database = makeTestDatabaseProperties(),
certificateSigningService = URL("http://localhost"),
rpcUsers = emptyList(),

View File

@ -12,6 +12,7 @@ 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
@ -24,6 +25,9 @@ import net.corda.node.utilities.configureDatabase
import net.corda.testing.*
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.MockKeyManagementService
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
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
@ -31,16 +35,12 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import java.nio.file.Paths
import java.security.PublicKey
import java.time.Clock
import java.time.Instant
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import kotlin.test.assertTrue
import net.corda.testing.node.MockServices.Companion.makeTestDatabaseProperties
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
val realClock: Clock = Clock.systemUTC()
@ -89,7 +89,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
database)
services = object : MockServiceHubInternal(
database,
testNodeConfiguration(Paths.get("."), getTestX509Name("Alice")),
testNodeConfiguration(Paths.get("."), getX500Name(O = "Alice", L = "London", C = "GB")),
overrideClock = testClock,
keyManagement = kms,
network = mockMessagingService), TestReference {

View File

@ -6,6 +6,7 @@ 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
@ -46,7 +47,7 @@ abstract class AbstractNetworkMapServiceTest<out S : AbstractNetworkMapService>
lateinit var alice: MockNode
companion object {
val subscriberLegalName = X500Name("CN=Subscriber,OU=Corda QA Department,O=R3 CEV,L=New York,C=US")
val subscriberLegalName = getX500Name(O="Subscriber",L="New York",C="US")
}
@Before

View File

@ -1,13 +1,14 @@
package net.corda.node.services.network
import net.corda.core.utilities.CertificateAndKeyPair
import net.corda.core.crypto.Crypto
import net.corda.core.utilities.cert
import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.services.UnknownAnonymousPartyException
import net.corda.core.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
@ -62,7 +63,7 @@ class InMemoryIdentityServiceTests {
val service = InMemoryIdentityService(trustRoot = trustRoot.certificate)
service.verifyAndRegisterIdentity(ALICE_IDENTITY)
service.verifyAndRegisterIdentity(BOB_IDENTITY)
val alicente = getTestPartyAndCertificate(X500Name("O=Alicente Worldwide,L=London,C=GB"), generateKeyPair().public)
val alicente = getTestPartyAndCertificate(getX500Name(O = "Alicente Worldwide", L = "London", C = "GB"), generateKeyPair().public)
service.verifyAndRegisterIdentity(alicente)
assertEquals(setOf(ALICE, alicente.party), service.partiesFromName("Alice", false))
assertEquals(setOf(ALICE), service.partiesFromName("Alice Corp", true))
@ -73,7 +74,7 @@ class InMemoryIdentityServiceTests {
fun `get identity by name`() {
val service = InMemoryIdentityService(trustRoot = DUMMY_CA.certificate)
val identities = listOf("Node A", "Node B", "Node C")
.map { getTestPartyAndCertificate(X500Name("CN=$it,O=R3,OU=corda,L=London,C=GB"), generateKeyPair().public) }
.map { getTestPartyAndCertificate(getX500Name(O = it, OU = "corda", L = "London", C = "GB"), generateKeyPair().public) }
assertNull(service.partyFromX500Name(identities.first().name))
identities.forEach { service.verifyAndRegisterIdentity(it) }
identities.forEach { assertEquals(it.party, service.partyFromX500Name(it.name)) }

View File

@ -9,6 +9,7 @@ import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.UnknownAnonymousPartyException
import net.corda.core.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
@ -96,7 +97,7 @@ class PersistentIdentityServiceTests {
identityService.verifyAndRegisterIdentity(ALICE_IDENTITY)
identityService.verifyAndRegisterIdentity(BOB_IDENTITY)
}
val alicente = getTestPartyAndCertificate(X500Name("O=Alicente Worldwide,L=London,C=GB"), generateKeyPair().public)
val alicente = getTestPartyAndCertificate(getX500Name(O = "Alicente Worldwide", L = "London", C = "GB"), generateKeyPair().public)
database.transaction {
identityService.verifyAndRegisterIdentity(alicente)
assertEquals(setOf(ALICE, alicente.party), identityService.partiesFromName("Alice", false))
@ -108,7 +109,7 @@ class PersistentIdentityServiceTests {
@Test
fun `get identity by name`() {
val identities = listOf("Node A", "Node B", "Node C")
.map { getTestPartyAndCertificate(X500Name("CN=$it,O=R3,OU=corda,L=London,C=GB"), generateKeyPair().public) }
.map { getTestPartyAndCertificate(getX500Name(O = it, OU = "corda", L = "London", C = "GB"), generateKeyPair().public) }
database.transaction {
assertNull(identityService.partyFromX500Name(identities.first().name))
}

View File

@ -21,11 +21,8 @@ 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.OpaqueBytes
import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.*
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
@ -79,7 +76,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, getTestX509Name("notary-service-2000"))
val notaryService = ServiceInfo(ValidatingNotaryService.type, getX500Name(O = "notary-service-2000", L = "London", C = "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.

View File

@ -32,7 +32,6 @@ import net.corda.testing.schemas.DummyLinearStateSchemaV1
import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.bouncycastle.asn1.x500.X500Name
import org.junit.*
import org.junit.rules.ExpectedException
import java.lang.Thread.sleep
@ -55,7 +54,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
// test cash notary
val CASH_NOTARY_KEY: KeyPair by lazy { entropyToKeyPair(BigInteger.valueOf(21)) }
val CASH_NOTARY: Party get() = Party(X500Name("CN=Cash Notary Service,O=R3,OU=corda,L=Zurich,C=CH"), CASH_NOTARY_KEY.public)
val CASH_NOTARY: Party get() = Party(getX500Name(O = "Cash Notary Service", OU = "corda", L = "Zurich", C = "CH"), CASH_NOTARY_KEY.public)
val CASH_NOTARY_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(CASH_NOTARY.nameOrNull(), CASH_NOTARY_KEY.public)
@Before
@ -278,7 +277,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
val sortAttributeTxnId = SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID)
val sortAttributeIndex = SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_INDEX)
val sortBy = Sort(setOf(Sort.SortColumn(sortAttributeTxnId, Sort.Direction.ASC),
Sort.SortColumn(sortAttributeIndex, Sort.Direction.ASC)))
Sort.SortColumn(sortAttributeIndex, Sort.Direction.ASC)))
val criteria = VaultQueryCriteria()
val results = vaultQuerySvc.queryBy<Cash.State>(criteria, sortBy)
@ -295,11 +294,11 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed states for state refs`() {
val stateRefs =
database.transaction {
services.fillWithSomeTestLinearStates(8)
val issuedStates = services.fillWithSomeTestLinearStates(2)
issuedStates.states.map { it.ref }.toList()
}
database.transaction {
services.fillWithSomeTestLinearStates(8)
val issuedStates = services.fillWithSomeTestLinearStates(2)
issuedStates.states.map { it.ref }.toList()
}
database.transaction {
// DOCSTART VaultQueryExample2
val sortAttribute = SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID)
@ -472,15 +471,15 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed states with soft locking`() {
val (lockId1, lockId2) =
database.transaction {
val issuedStates = services.fillWithSomeTestCash(100.DOLLARS, notaryServices, CASH_NOTARY, 10, 10, Random(0L)).states.toList()
vaultSvc.softLockReserve(UUID.randomUUID(), NonEmptySet.of(issuedStates[1].ref, issuedStates[2].ref, issuedStates[3].ref))
val lockId1 = UUID.randomUUID()
vaultSvc.softLockReserve(lockId1, NonEmptySet.of(issuedStates[4].ref, issuedStates[5].ref))
val lockId2 = UUID.randomUUID()
vaultSvc.softLockReserve(lockId2, NonEmptySet.of(issuedStates[6].ref))
Pair(lockId1, lockId2)
}
database.transaction {
val issuedStates = services.fillWithSomeTestCash(100.DOLLARS, notaryServices, CASH_NOTARY, 10, 10, Random(0L)).states.toList()
vaultSvc.softLockReserve(UUID.randomUUID(), NonEmptySet.of(issuedStates[1].ref, issuedStates[2].ref, issuedStates[3].ref))
val lockId1 = UUID.randomUUID()
vaultSvc.softLockReserve(lockId1, NonEmptySet.of(issuedStates[4].ref, issuedStates[5].ref))
val lockId2 = UUID.randomUUID()
vaultSvc.softLockReserve(lockId2, NonEmptySet.of(issuedStates[6].ref))
Pair(lockId1, lockId2)
}
database.transaction {
// excluding soft locked states
val criteriaExclusive = VaultQueryCriteria(softLockingCondition = SoftLockingCondition(SoftLockingType.UNLOCKED_ONLY))
@ -739,10 +738,10 @@ class VaultQueryTests : TestDependencyInjectionBase() {
val avgCriteria = VaultCustomQueryCriteria(avg)
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(sumCriteria
.and(countCriteria)
.and(maxCriteria)
.and(minCriteria)
.and(avgCriteria))
.and(countCriteria)
.and(maxCriteria)
.and(minCriteria)
.and(avgCriteria))
// DOCEND VaultQueryExample21
assertThat(results.otherResults).hasSize(5)
@ -778,9 +777,9 @@ class VaultQueryTests : TestDependencyInjectionBase() {
val avgCriteria = VaultCustomQueryCriteria(avg)
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(sumCriteria
.and(maxCriteria)
.and(minCriteria)
.and(avgCriteria))
.and(maxCriteria)
.and(minCriteria)
.and(avgCriteria))
// DOCEND VaultQueryExample22
assertThat(results.otherResults).hasSize(24)
@ -826,9 +825,10 @@ class VaultQueryTests : TestDependencyInjectionBase() {
}
database.transaction {
// DOCSTART VaultQueryExample23
val sum = builder { CashSchemaV1.PersistentCashState::pennies.sum(groupByColumns = listOf(CashSchemaV1.PersistentCashState::issuerParty,
CashSchemaV1.PersistentCashState::currency),
orderBy = Sort.Direction.DESC)
val sum = builder {
CashSchemaV1.PersistentCashState::pennies.sum(groupByColumns = listOf(CashSchemaV1.PersistentCashState::issuerParty,
CashSchemaV1.PersistentCashState::currency),
orderBy = Sort.Direction.DESC)
}
val results = vaultQuerySvc.queryBy<FungibleAsset<*>>(VaultCustomQueryCriteria(sum))
@ -880,16 +880,16 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `aggregate functions count by contract type and state status`() {
val (linearStatesJKL,linearStatesXYZ,dealStates) =
database.transaction {
// create new states
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 10, 10, Random(0L))
val linearStatesXYZ = services.fillWithSomeTestLinearStates(1, "XYZ")
val linearStatesJKL = services.fillWithSomeTestLinearStates(2, "JKL")
services.fillWithSomeTestLinearStates(3, "ABC")
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789"))
Triple(linearStatesJKL,linearStatesXYZ,dealStates)
}
val (linearStatesJKL, linearStatesXYZ, dealStates) =
database.transaction {
// create new states
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 10, 10, Random(0L))
val linearStatesXYZ = services.fillWithSomeTestLinearStates(1, "XYZ")
val linearStatesJKL = services.fillWithSomeTestLinearStates(2, "JKL")
services.fillWithSomeTestLinearStates(3, "ABC")
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789"))
Triple(linearStatesJKL, linearStatesXYZ, dealStates)
}
val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() }
database.transaction {
// count fungible assets
@ -906,15 +906,15 @@ class VaultQueryTests : TestDependencyInjectionBase() {
assertThat(dealStateCount).isEqualTo(3L)
}
val cashUpdates =
database.transaction {
// consume some states
services.consumeLinearStates(linearStatesXYZ.states.toList(), DUMMY_NOTARY)
services.consumeLinearStates(linearStatesJKL.states.toList(), DUMMY_NOTARY)
services.consumeDeals(dealStates.states.filter { it.state.data.linearId.externalId == "456" }, DUMMY_NOTARY)
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
database.transaction {
// consume some states
services.consumeLinearStates(linearStatesXYZ.states.toList(), DUMMY_NOTARY)
services.consumeLinearStates(linearStatesJKL.states.toList(), DUMMY_NOTARY)
services.consumeDeals(dealStates.states.filter { it.state.data.linearId.externalId == "456" }, DUMMY_NOTARY)
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
// UNCONSUMED states (default)
}
// UNCONSUMED states (default)
}
database.transaction {
// count fungible assets
val countCriteriaUnconsumed = QueryCriteria.VaultCustomQueryCriteria(count, Vault.StateStatus.UNCONSUMED)
@ -1228,9 +1228,9 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed linear heads for linearId without external Id`() {
val issuedStates =
database.transaction {
services.fillWithSomeTestLinearStates(10)
}
database.transaction {
services.fillWithSomeTestLinearStates(10)
}
database.transaction {
// DOCSTART VaultQueryExample8
val linearIds = issuedStates.states.map { it.state.data.linearId }.toList()
@ -1244,12 +1244,12 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed linear heads by linearId`() {
val (linearState1, linearState3) =
database.transaction {
val linearState1 = services.fillWithSomeTestLinearStates(1, "ID1")
services.fillWithSomeTestLinearStates(1, "ID2")
val linearState3 = services.fillWithSomeTestLinearStates(1, "ID3")
Pair(linearState1, linearState3)
}
database.transaction {
val linearState1 = services.fillWithSomeTestLinearStates(1, "ID1")
services.fillWithSomeTestLinearStates(1, "ID2")
val linearState3 = services.fillWithSomeTestLinearStates(1, "ID3")
Pair(linearState1, linearState3)
}
database.transaction {
val linearIds = listOf(linearState1.states.first().state.data.linearId, linearState3.states.first().state.data.linearId)
val criteria = LinearStateQueryCriteria(linearId = linearIds)
@ -1278,14 +1278,14 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `all linear states for a given linear id`() {
val linearId =
database.transaction {
val txns = services.fillWithSomeTestLinearStates(1, "TEST")
val linearState = txns.states.first()
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
linearState.state.data.linearId
}
database.transaction {
val txns = services.fillWithSomeTestLinearStates(1, "TEST")
val linearState = txns.states.first()
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
linearState.state.data.linearId
}
database.transaction {
// should now have 1 UNCONSUMED & 3 CONSUMED state refs for Linear State with "TEST"
// DOCSTART VaultQueryExample9
@ -1300,14 +1300,14 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `all linear states for a given id sorted by uuid`() {
val linearStates =
database.transaction {
val txns = services.fillWithSomeTestLinearStates(2, "TEST")
val linearStates = txns.states.toList()
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
linearStates
}
database.transaction {
val txns = services.fillWithSomeTestLinearStates(2, "TEST")
val linearStates = txns.states.toList()
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
linearStates
}
database.transaction {
// should now have 1 UNCONSUMED & 3 CONSUMED state refs for Linear State with "TEST"
val linearStateCriteria = LinearStateQueryCriteria(uuid = linearStates.map { it.state.data.linearId.id }, status = Vault.StateStatus.ALL)
@ -1340,11 +1340,11 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed deal states sorted`() {
val uid =
database.transaction {
val linearStates = services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
linearStates.states.first().state.data.linearId.id
}
database.transaction {
val linearStates = services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
linearStates.states.first().state.data.linearId.id
}
database.transaction {
val linearStateCriteria = LinearStateQueryCriteria(uuid = listOf(uid))
val dealStateCriteria = LinearStateQueryCriteria(externalId = listOf("123", "456", "789"))
@ -1378,14 +1378,14 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `return consumed linear states for a given linear id`() {
val txns =
database.transaction {
val txns = services.fillWithSomeTestLinearStates(1, "TEST")
val linearState = txns.states.first()
val linearState2 = services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
val linearState3 = services.evolveLinearState(linearState2, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState3, DUMMY_NOTARY) // consume current and produce new state reference
txns
}
database.transaction {
val txns = services.fillWithSomeTestLinearStates(1, "TEST")
val linearState = txns.states.first()
val linearState2 = services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
val linearState3 = services.evolveLinearState(linearState2, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState3, DUMMY_NOTARY) // consume current and produce new state reference
txns
}
database.transaction {
// should now have 1 UNCONSUMED & 3 CONSUMED state refs for Linear State with "TEST"
val linearStateCriteria = LinearStateQueryCriteria(linearId = txns.states.map { it.state.data.linearId }, status = Vault.StateStatus.CONSUMED)
@ -1484,15 +1484,15 @@ class VaultQueryTests : TestDependencyInjectionBase() {
fun `unconsumed fungible assets for selected issuer parties`() {
// GBP issuer
val gbpCashIssuerKey = entropyToKeyPair(BigInteger.valueOf(1001))
val gbpCashIssuer = Party(X500Name("CN=British Pounds Cash Issuer,O=R3,OU=corda,L=London,C=GB"), gbpCashIssuerKey.public).ref(1)
val gbpCashIssuer = Party(getX500Name(O = "British Pounds Cash Issuer", OU = "corda", L = "London", C = "GB"), gbpCashIssuerKey.public).ref(1)
val gbpCashIssuerServices = MockServices(gbpCashIssuerKey)
// USD issuer
val usdCashIssuerKey = entropyToKeyPair(BigInteger.valueOf(1002))
val usdCashIssuer = Party(X500Name("CN=US Dollars Cash Issuer,O=R3,OU=corda,L=New York,C=US"), usdCashIssuerKey.public).ref(1)
val usdCashIssuer = Party(getX500Name(O = "US Dollars Cash Issuer", OU = "corda", L = "New York", C = "US"), usdCashIssuerKey.public).ref(1)
val usdCashIssuerServices = MockServices(usdCashIssuerKey)
// CHF issuer
val chfCashIssuerKey = entropyToKeyPair(BigInteger.valueOf(1003))
val chfCashIssuer = Party(X500Name("CN=Swiss Francs Cash Issuer,O=R3,OU=corda,L=Zurich,C=CH"), chfCashIssuerKey.public).ref(1)
val chfCashIssuer = Party(getX500Name(O = "Swiss Francs Cash Issuer", OU = "corda", L = "Zurich", C = "CH"), chfCashIssuerKey.public).ref(1)
val chfCashIssuerServices = MockServices(chfCashIssuerKey)
database.transaction {
@ -1871,14 +1871,14 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun `unconsumed linear heads for a given external id or uuid`() {
val uuid =
database.transaction {
services.fillWithSomeTestLinearStates(1, "TEST1")
val aState = services.fillWithSomeTestLinearStates(1, "TEST2").states
services.consumeLinearStates(aState.toList(), DUMMY_NOTARY)
services.fillWithSomeTestLinearStates(1, "TEST1").states.first().state.data.linearId.id
database.transaction {
services.fillWithSomeTestLinearStates(1, "TEST1")
val aState = services.fillWithSomeTestLinearStates(1, "TEST2").states
services.consumeLinearStates(aState.toList(), DUMMY_NOTARY)
services.fillWithSomeTestLinearStates(1, "TEST1").states.first().state.data.linearId.id
// 2 unconsumed states with same external ID, 1 consumed with different external ID
}
// 2 unconsumed states with same external ID, 1 consumed with different external ID
}
database.transaction {
val results = builder {
val externalIdCondition = VaultSchemaV1.VaultLinearStates::externalId.equal("TEST1")
@ -1919,12 +1919,12 @@ class VaultQueryTests : TestDependencyInjectionBase() {
identitySvc.verifyAndRegisterIdentity(BOB_IDENTITY)
identitySvc.verifyAndRegisterIdentity(CHARLIE_IDENTITY)
services.fillWithSomeTestLinearStates(1, "TEST1", listOf(ALICE,BOB,CHARLIE))
services.fillWithSomeTestLinearStates(1, "TEST1", listOf(ALICE, BOB, CHARLIE))
services.fillWithSomeTestLinearStates(1)
services.fillWithSomeTestLinearStates(1, "TEST3")
}
database.transaction {
val linearStateCriteria = LinearStateQueryCriteria(participants = listOf(ALICE,BOB,CHARLIE))
val linearStateCriteria = LinearStateQueryCriteria(participants = listOf(ALICE, BOB, CHARLIE))
val results = vaultQuerySvc.queryBy<LinearState>(linearStateCriteria)
assertThat(results.states).hasSize(1)
@ -1984,12 +1984,12 @@ class VaultQueryTests : TestDependencyInjectionBase() {
database.transaction {
// Base criteria
val baseCriteria = VaultQueryCriteria(notary = listOf(DUMMY_NOTARY),
status = Vault.StateStatus.CONSUMED)
status = Vault.StateStatus.CONSUMED)
// Enrich and override QueryCriteria with additional default attributes (such as soft locks)
val enrichedCriteria = VaultQueryCriteria(contractStateTypes = setOf(DealState::class.java), // enrich
softLockingCondition = QueryCriteria.SoftLockingCondition(QueryCriteria.SoftLockingType.UNLOCKED_AND_SPECIFIED, listOf(UUID.randomUUID())),
status = Vault.StateStatus.UNCONSUMED) // override
val enrichedCriteria = VaultQueryCriteria(contractStateTypes = setOf(DealState::class.java), // enrich
softLockingCondition = QueryCriteria.SoftLockingCondition(QueryCriteria.SoftLockingType.UNLOCKED_AND_SPECIFIED, listOf(UUID.randomUUID())),
status = Vault.StateStatus.UNCONSUMED) // override
// Sorting
val sortAttribute = SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF)
val sorter = Sort(setOf(Sort.SortColumn(sortAttribute, Sort.Direction.ASC)))
@ -2007,28 +2007,28 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun trackCashStates_unconsumed() {
val updates =
database.transaction {
// DOCSTART VaultQueryExample15
vaultQuerySvc.trackBy<Cash.State>().updates // UNCONSUMED default
// DOCEND VaultQueryExample15
}
val (linearStates,dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates,dealStates)
}
database.transaction {
// DOCSTART VaultQueryExample15
vaultQuerySvc.trackBy<Cash.State>().updates // UNCONSUMED default
// DOCEND VaultQueryExample15
}
val (linearStates, dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates, dealStates)
}
database.transaction {
// consume stuff
services.consumeCash(100.DOLLARS, notary = DUMMY_NOTARY)
services.consumeDeals(dealStates.toList(), DUMMY_NOTARY)
services.consumeLinearStates(linearStates.toList(), DUMMY_NOTARY)
}
}
updates.expectEvents {
sequence(
@ -2049,22 +2049,22 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun trackCashStates_consumed() {
val updates =
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.CONSUMED)
vaultQuerySvc.trackBy<Cash.State>(criteria).updates
}
val (linearStates,dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.CONSUMED)
vaultQuerySvc.trackBy<Cash.State>(criteria).updates
}
val (linearStates, dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates,dealStates)
}
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates, dealStates)
}
database.transaction {
// consume stuff
services.consumeCash(100.POUNDS, notary = DUMMY_NOTARY)
@ -2095,21 +2095,21 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun trackCashStates_all() {
val updates =
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
vaultQuerySvc.trackBy<Cash.State>(criteria).updates
}
val (linearStates,dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates,dealStates)
}
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
vaultQuerySvc.trackBy<Cash.State>(criteria).updates
}
val (linearStates, dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates, dealStates)
}
database.transaction {
// consume stuff
services.consumeCash(99.POUNDS, notary = DUMMY_NOTARY)
@ -2150,24 +2150,24 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun trackLinearStates() {
val updates =
database.transaction {
// DOCSTART VaultQueryExample16
val (snapshot, updates) = vaultQuerySvc.trackBy<LinearState>()
// DOCEND VaultQueryExample16
assertThat(snapshot.states).hasSize(0)
updates
}
val (linearStates,dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates,dealStates)
}
database.transaction {
// DOCSTART VaultQueryExample16
val (snapshot, updates) = vaultQuerySvc.trackBy<LinearState>()
// DOCEND VaultQueryExample16
assertThat(snapshot.states).hasSize(0)
updates
}
val (linearStates, dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates, dealStates)
}
database.transaction {
// consume stuff
services.consumeCash(100.DOLLARS, notary = DUMMY_NOTARY)
@ -2199,24 +2199,24 @@ class VaultQueryTests : TestDependencyInjectionBase() {
@Test
fun trackDealStates() {
val updates =
database.transaction {
// DOCSTART VaultQueryExample17
val (snapshot, updates) = vaultQuerySvc.trackBy<DealState>()
// DOCEND VaultQueryExample17
assertThat(snapshot.states).hasSize(0)
updates
}
val (linearStates,dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates,dealStates)
}
database.transaction {
// DOCSTART VaultQueryExample17
val (snapshot, updates) = vaultQuerySvc.trackBy<DealState>()
// DOCEND VaultQueryExample17
assertThat(snapshot.states).hasSize(0)
updates
}
val (linearStates, dealStates) =
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
val linearStates = services.fillWithSomeTestLinearStates(10).states
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789")).states
// add more cash
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
// add another deal
services.fillWithSomeTestDeals(listOf("SAMPLE DEAL"))
Pair(linearStates, dealStates)
}
database.transaction {
// consume stuff
services.consumeCash(100.DOLLARS, notary = DUMMY_NOTARY)

View File

@ -3,21 +3,25 @@ package net.corda.node.utilities
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.Crypto.EDDSA_ED25519_SHA512
import net.corda.core.crypto.Crypto.generateKeyPair
import net.corda.core.utilities.cert
import net.corda.core.utilities.commonName
import net.corda.core.utilities.getX509Name
import net.corda.core.internal.div
import net.corda.core.internal.toTypedArray
import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.deserialize
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
import net.corda.nodeapi.internal.serialization.KryoHeaderV0_1
import net.corda.nodeapi.internal.serialization.SerializationContextImpl
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
import net.corda.testing.*
import net.corda.testing.ALICE
import net.corda.testing.BOB
import net.corda.testing.BOB_PUBKEY
import net.corda.testing.MEGA_CORP
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x509.BasicConstraints
import org.bouncycastle.asn1.x509.Extension
@ -54,7 +58,7 @@ class X509UtilitiesTest {
@Test
fun `create valid self-signed CA certificate`() {
val caKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val caCert = X509Utilities.createSelfSignedCACertificate(getTestX509Name("Test Cert"), caKey)
val caCert = X509Utilities.createSelfSignedCACertificate(getX500Name(CN = "Test Cert", O = "R3 Ltd", L = "London", C = "GB"), caKey)
assertTrue { caCert.subject.commonName == "Test Cert" } // using our subject common name
assertEquals(caCert.issuer, caCert.subject) //self-signed
caCert.isValidOn(Date()) // throws on verification problems
@ -69,7 +73,7 @@ class X509UtilitiesTest {
fun `load and save a PEM file certificate`() {
val tmpCertificateFile = tempFile("cacert.pem")
val caKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val caCert = X509Utilities.createSelfSignedCACertificate(getTestX509Name("Test Cert"), caKey)
val caCert = X509Utilities.createSelfSignedCACertificate(getX500Name(CN = "Test Cert", O = "R3 Ltd", L = "London", C = "GB"), caKey)
X509Utilities.saveCertificateAsPEMFile(caCert, tmpCertificateFile)
val readCertificate = X509Utilities.loadCertificateFromPEMFile(tmpCertificateFile)
assertEquals(caCert, readCertificate)
@ -78,8 +82,8 @@ class X509UtilitiesTest {
@Test
fun `create valid server certificate chain`() {
val caKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val caCert = X509Utilities.createSelfSignedCACertificate(getTestX509Name("Test CA Cert"), caKey)
val subject = getTestX509Name("Server Cert")
val caCert = X509Utilities.createSelfSignedCACertificate(getX500Name(CN = "Test CA Cert", O = "R3 Ltd", L = "London", C = "GB"), caKey)
val subject = getX500Name(CN = "Server Cert", O = "R3 Ltd", L = "London", C = "GB")
val keyPair = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val serverCert = X509Utilities.createCertificate(CertificateType.TLS, caCert, caKey, subject, keyPair.public)
assertTrue { serverCert.subject.toString().contains("CN=Server Cert") } // using our subject common name
@ -208,7 +212,7 @@ class X509UtilitiesTest {
serverCertAndKey.certificate.isValidOn(Date())
serverCertAndKey.certificate.isSignatureValid(JcaContentVerifierProviderBuilder().build(caCertAndKey.certificate.subjectPublicKeyInfo))
assertTrue { serverCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.commonName) }
assertTrue { serverCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.organisation) }
// Load back server certificate
val sslKeyStore = loadKeyStore(tmpSSLKeyStore, "serverstorepass")
@ -217,7 +221,7 @@ class X509UtilitiesTest {
sslCertAndKey.certificate.isValidOn(Date())
sslCertAndKey.certificate.isSignatureValid(JcaContentVerifierProviderBuilder().build(serverCertAndKey.certificate.subjectPublicKeyInfo))
assertTrue { sslCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.commonName) }
assertTrue { sslCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.organisation) }
// Now sign something with private key and verify against certificate public key
val testData = "123456".toByteArray()
val signature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, serverCertAndKey.keyPair.private, testData)
@ -355,10 +359,10 @@ class X509UtilitiesTest {
trustStorePassword: String
): KeyStore {
val rootCAKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val rootCACert = X509Utilities.createSelfSignedCACertificate(getX509Name("Corda Node Root CA", "London", "demo@r3.com", null), rootCAKey)
val rootCACert = X509Utilities.createSelfSignedCACertificate(getX500Name(CN = "Corda Node Root CA", O = "R3CEV", L = "London", C = "GB"), rootCAKey)
val intermediateCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, getX509Name("Corda Node Intermediate CA", "London", "demo@r3.com", null), intermediateCAKeyPair.public)
val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, getX500Name(CN = "Corda Node Intermediate CA", O = "R3CEV", L = "London", C = "GB"), intermediateCAKeyPair.public)
val keyPass = keyPassword.toCharArray()
val keyStore = loadOrCreateKeyStore(keyStoreFilePath, storePassword)

View File

@ -5,15 +5,15 @@ 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.utilities.cert
import net.corda.core.utilities.commonName
import net.corda.core.internal.exists
import net.corda.core.internal.toTypedArray
import net.corda.core.internal.toX509CertHolder
import net.corda.core.utilities.cert
import net.corda.core.utilities.commonName
import net.corda.core.utilities.getX500Name
import net.corda.node.utilities.X509Utilities
import net.corda.node.utilities.loadKeyStore
import net.corda.testing.ALICE
import net.corda.testing.getTestX509Name
import net.corda.testing.testNodeConfiguration
import org.junit.Rule
import org.junit.Test
@ -34,7 +34,7 @@ class NetworkRegistrationHelperTest {
val identities = listOf("CORDA_CLIENT_CA",
"CORDA_INTERMEDIATE_CA",
"CORDA_ROOT_CA")
.map { getTestX509Name(it) }
.map { getX500Name(CN = it, O = "R3 Ltd", L = "London", C = "GB") }
val certs = identities.stream().map { X509Utilities.createSelfSignedCACertificate(it, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) }
.map { it.cert }.toTypedArray()