Removed X509CertificateHolder from public API, using java.security.X509Certificate instead (#1510)

This commit is contained in:
Shams Asari 2017-09-14 15:48:33 +01:00 committed by josecoll
parent 943e873ff0
commit 573987d929
25 changed files with 52 additions and 74 deletions

View File

@ -22,7 +22,6 @@ import org.bouncycastle.asn1.sec.SECObjectIdentifiers
import org.bouncycastle.asn1.x509.AlgorithmIdentifier
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers
import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateKey
@ -920,8 +919,7 @@ object Crypto {
}
/**
* Convert a public key to a supported implementation. This method is usually required to retrieve a key from an
* [X509CertificateHolder].
* Convert a public key to a supported implementation.
*
* @param key a public key.
* @return a supported implementation of the input public key.

View File

@ -4,10 +4,8 @@ import net.corda.core.contracts.PartyAndReference
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.Crypto
import net.corda.core.utilities.OpaqueBytes
import org.bouncycastle.cert.X509CertificateHolder
import java.security.PublicKey
import java.security.cert.X509Certificate
import javax.security.auth.x500.X500Principal
/**
* The [Party] class represents an entity on the network, which is typically identified by a legal [name] and public key
@ -29,8 +27,8 @@ import javax.security.auth.x500.X500Principal
* @see CompositeKey
*/
class Party(val name: CordaX500Name, owningKey: PublicKey) : AbstractParty(owningKey) {
constructor(certificate: X509Certificate) : this(CordaX500Name.build(certificate.subjectX500Principal), Crypto.toSupportedPublicKey(certificate.publicKey))
constructor(certificate: X509CertificateHolder) : this(CordaX500Name.build(X500Principal(certificate.subject.encoded)), Crypto.toSupportedPublicKey(certificate.subjectPublicKeyInfo))
constructor(certificate: X509Certificate)
: this(CordaX500Name.build(certificate.subjectX500Principal), Crypto.toSupportedPublicKey(certificate.publicKey))
override fun nameOrNull(): CordaX500Name = name
fun anonymise(): AnonymousParty = AnonymousParty(owningKey)
override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this, bytes)

View File

@ -1,7 +1,5 @@
package net.corda.core.identity
import net.corda.core.internal.toX509CertHolder
import org.bouncycastle.cert.X509CertificateHolder
import java.security.PublicKey
import java.security.cert.*
@ -10,14 +8,13 @@ import java.security.cert.*
* [PartyAndCertificate] instances is based on the party only, as certificate and path are data associated with the party,
* not part of the identifier themselves.
*/
//TODO Is VerifiableIdentity a better name?
class PartyAndCertificate(val certPath: CertPath) {
@Transient val certificate: X509CertificateHolder
@Transient val certificate: X509Certificate
init {
require(certPath.type == "X.509") { "Only X.509 certificates supported" }
val certs = certPath.certificates
require(certs.size >= 2) { "Certificate path must at least include subject and issuing certificates" }
certificate = certs[0].toX509CertHolder()
certificate = certs[0] as X509Certificate
}
@Transient val party: Party = Party(certificate)
@ -26,7 +23,7 @@ class PartyAndCertificate(val certPath: CertPath) {
val name: CordaX500Name get() = party.name
operator fun component1(): Party = party
operator fun component2(): X509CertificateHolder = certificate
operator fun component2(): X509Certificate = certificate
override fun equals(other: Any?): Boolean = other === this || other is PartyAndCertificate && other.party == party
override fun hashCode(): Int = party.hashCode()

View File

@ -10,6 +10,7 @@ import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.security.CodeSigner
import java.security.cert.X509Certificate
import java.util.jar.JarInputStream
abstract class AbstractAttachment(dataLoader: () -> ByteArray) : Attachment {
@ -44,7 +45,7 @@ abstract class AbstractAttachment(dataLoader: () -> ByteArray) : Attachment {
}
}
(attachmentSigners ?: emptySet<CodeSigner>()).map {
Party(it.signerCertPath.certificates[0].toX509CertHolder())
Party(it.signerCertPath.certificates[0] as X509Certificate)
}.sortedBy { it.name.toString() } // Determinism.
}

View File

@ -3,6 +3,7 @@ package net.corda.core.internal
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.sha256
import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import org.slf4j.Logger
import rx.Observable
import rx.Observer
@ -15,6 +16,8 @@ import java.nio.charset.Charset
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.*
import java.nio.file.attribute.FileAttribute
import java.security.cert.Certificate
import java.security.cert.X509Certificate
import java.time.Duration
import java.time.temporal.Temporal
import java.util.*
@ -167,8 +170,8 @@ fun <T> logElapsedTime(label: String, logger: Logger? = null, body: () -> T): T
}
}
fun java.security.cert.Certificate.toX509CertHolder() = X509CertificateHolder(encoded)
fun javax.security.cert.Certificate.toX509CertHolder() = X509CertificateHolder(encoded)
fun Certificate.toX509CertHolder() = X509CertificateHolder(encoded)
val X509CertificateHolder.cert: X509Certificate get() = JcaX509CertificateConverter().getCertificate(this)
/** Convert a [ByteArrayOutputStream] to [InputStreamAndHash]. */
fun ByteArrayOutputStream.toInputStreamAndHash(): InputStreamAndHash {

View File

@ -2,7 +2,6 @@ package net.corda.core.node.services
import net.corda.core.contracts.PartyAndReference
import net.corda.core.identity.*
import org.bouncycastle.cert.X509CertificateHolder
import java.security.InvalidAlgorithmParameterException
import java.security.PublicKey
import java.security.cert.*
@ -14,7 +13,6 @@ import java.security.cert.*
*/
interface IdentityService {
val trustRoot: X509Certificate
val trustRootHolder: X509CertificateHolder
val trustAnchor: TrustAnchor
val caCertStore: CertStore

View File

@ -1,12 +0,0 @@
@file:JvmName("X509Utils")
package net.corda.core.utilities
import net.corda.core.internal.toX509CertHolder
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import java.security.cert.X509Certificate
val X509Certificate.subject: X500Name get() = toX509CertHolder().subject
val X509CertificateHolder.cert: X509Certificate get() = JcaX509CertificateConverter().getCertificate(this)

View File

@ -7,11 +7,10 @@ import net.corda.core.internal.declaredField
import net.corda.core.internal.div
import net.corda.core.serialization.serialize
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.cert
import net.corda.core.internal.cert
import net.corda.core.utilities.toBase58String
import net.corda.node.utilities.*
import net.corda.testing.TestDependencyInjectionBase
import net.corda.testing.getX500Name
import net.corda.testing.kryoSpecific
import org.junit.Rule
import org.junit.Test

View File

@ -2,9 +2,8 @@ package net.corda.core.crypto
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.toTypedArray
import net.corda.core.utilities.cert
import net.corda.core.internal.cert
import net.corda.node.utilities.*
import net.corda.testing.getX500Name
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x509.GeneralName
import org.bouncycastle.asn1.x509.GeneralSubtree

View File

@ -150,6 +150,8 @@ UNRELEASED
* Removed ``PluginServiceHub``. Replace with ``ServiceHub`` for ``@CordaService`` constructors.
* ``X509CertificateHolder`` has been removed from the public API, replaced by ``java.security.X509Certificate``.
Milestone 14
------------

View File

@ -8,6 +8,7 @@ import net.corda.core.contracts.TransactionState
import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowException
import net.corda.core.identity.AbstractParty
import net.corda.core.internal.toX509CertHolder
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializationFactory
import net.corda.core.transactions.LedgerTransaction
@ -742,7 +743,7 @@ class SerializationOutputTests {
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.X509CertificateHolderSerializer)
val obj = BOB_IDENTITY.certificate
val obj = BOB_IDENTITY.certificate.toX509CertHolder()
serdes(obj, factory, factory2)
}

View File

@ -6,7 +6,7 @@ import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name
import net.corda.core.node.NodeInfo
import net.corda.core.utilities.NonEmptySet
import net.corda.core.utilities.cert
import net.corda.core.internal.cert
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds
import net.corda.node.internal.NetworkMapInfo

View File

@ -29,7 +29,6 @@ import net.corda.core.serialization.SerializeAsToken
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.cert
import net.corda.core.utilities.debug
import net.corda.node.internal.classloading.requireAnnotation
import net.corda.node.internal.cordapp.CordappLoader
@ -546,7 +545,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
protected open fun makeIdentityService(trustRoot: X509Certificate,
clientCa: CertificateAndKeyPair?,
legalIdentity: PartyAndCertificate): IdentityService {
val caCertificates: Array<X509Certificate> = listOf(legalIdentity.certificate.cert, clientCa?.certificate?.cert)
val caCertificates: Array<X509Certificate> = listOf(legalIdentity.certificate, clientCa?.certificate?.cert)
.filterNotNull()
.toTypedArray()
val service = PersistentIdentityService(setOf(info.legalIdentityAndCert), trustRoot = trustRoot, caCertificates = *caCertificates)
@ -631,11 +630,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
}
}
val nodeCertificate: X509Certificate = if (certificates[0] is X509Certificate)
certificates[0] as X509Certificate
else
throw ConfigurationException("Node certificate must be an X.509 certificate")
val subject: CordaX500Name? = CordaX500Name.build(nodeCertificate.subjectX500Principal)
val nodeCert = certificates[0] as? X509Certificate ?: throw ConfigurationException("Node certificate must be an X.509 certificate")
val subject = CordaX500Name.build(nodeCert.subjectX500Principal)
if (subject != name)
throw ConfigurationException("The name for $id doesn't match what's in the key store: $name vs $subject")

View File

@ -3,13 +3,12 @@ package net.corda.node.services.identity
import net.corda.core.contracts.PartyAndReference
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.*
import net.corda.core.internal.cert
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.cert.X509CertificateHolder
import java.security.InvalidAlgorithmParameterException
@ -39,7 +38,6 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
* Certificate store for certificate authority and intermediary certificates.
*/
override val caCertStore: CertStore
override val trustRootHolder = trustRoot.toX509CertHolder()
override val trustAnchor: TrustAnchor = TrustAnchor(trustRoot, null)
private val keyToParties = ConcurrentHashMap<PublicKey, PartyAndCertificate>()
private val principalToParties = ConcurrentHashMap<CordaX500Name, PartyAndCertificate>()
@ -61,7 +59,7 @@ class InMemoryIdentityService(identities: Iterable<PartyAndCertificate> = emptyS
try {
identity.verify(trustAnchor)
} catch (e: CertPathValidatorException) {
log.error("Certificate validation failed for ${identity.name} against trusted root ${trustAnchor.trustedCert.subject}.")
log.error("Certificate validation failed for ${identity.name} against trusted root ${trustAnchor.trustedCert.subjectX500Principal}.")
log.error("Certificate path :")
identity.certPath.certificates.reversed().forEachIndexed { index, certificate ->
val space = (0 until index).map { " " }.joinToString("")

View File

@ -4,11 +4,10 @@ import net.corda.core.contracts.PartyAndReference
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.*
import net.corda.core.internal.toX509CertHolder
import net.corda.core.internal.cert
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.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.NODE_DATABASE_PREFIX
@ -91,7 +90,6 @@ class PersistentIdentityService(identities: Iterable<PartyAndCertificate> = empt
)
override val caCertStore: CertStore
override val trustRootHolder = trustRoot.toX509CertHolder()
override val trustAnchor: TrustAnchor = TrustAnchor(trustRoot, null)
private val keyToParties = createPKMap()

View File

@ -2,8 +2,9 @@ package net.corda.node.services.keys
import net.corda.core.crypto.Crypto
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.cert
import net.corda.core.internal.toX509CertHolder
import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.cert
import net.corda.core.utilities.days
import net.corda.node.utilities.CertificateType
import net.corda.node.utilities.ContentSignerBuilder
@ -32,9 +33,9 @@ fun freshCertificate(identityService: IdentityService,
issuer: PartyAndCertificate,
issuerSigner: ContentSigner,
revocationEnabled: Boolean = false): PartyAndCertificate {
val issuerCertificate = issuer.certificate
val window = X509Utilities.getCertificateValidityWindow(Duration.ZERO, 3650.days, issuerCertificate)
val ourCertificate = X509Utilities.createCertificate(CertificateType.IDENTITY, issuerCertificate.subject,
val issuerCert = issuer.certificate.toX509CertHolder()
val window = X509Utilities.getCertificateValidityWindow(Duration.ZERO, 3650.days, issuerCert)
val ourCertificate = X509Utilities.createCertificate(CertificateType.IDENTITY, issuerCert.subject,
issuerSigner, issuer.name, subjectPublicKey, window)
val certFactory = CertificateFactory.getInstance("X509")
val ourCertPath = certFactory.generateCertPath(listOf(ourCertificate.cert) + issuer.certPath.certificates)

View File

@ -2,11 +2,7 @@ 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 net.corda.core.internal.*
import org.bouncycastle.cert.X509CertificateHolder
import java.io.IOException
import java.io.InputStream

View File

@ -5,7 +5,6 @@ import net.corda.core.crypto.SignatureScheme
import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.x500Name
import net.corda.core.utilities.cert
import net.corda.core.utilities.days
import net.corda.core.utilities.millis
import org.bouncycastle.asn1.ASN1EncodableVector
@ -247,7 +246,8 @@ object X509Utilities {
internal fun createCertificate(certificateType: CertificateType,
issuer: X500Name,
issuerSigner: ContentSigner,
subject: CordaX500Name, subjectPublicKey: PublicKey,
subject: CordaX500Name,
subjectPublicKey: PublicKey,
validityWindow: Pair<Date, Date>,
nameConstraints: NameConstraints? = null): X509CertificateHolder {
val builder = createCertificate(certificateType, issuer, subject.x500Name, subjectPublicKey, validityWindow, nameConstraints)

View File

@ -2,7 +2,7 @@ package net.corda.node.utilities.registration
import net.corda.core.crypto.Crypto
import net.corda.core.internal.*
import net.corda.core.utilities.cert
import net.corda.core.internal.cert
import net.corda.core.utilities.seconds
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.utilities.*

View File

@ -6,8 +6,9 @@ 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.internal.toX509CertHolder
import net.corda.core.node.services.UnknownAnonymousPartyException
import net.corda.core.utilities.cert
import net.corda.core.internal.cert
import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.utilities.CertificateAndKeyPair
import net.corda.node.utilities.CertificateType
@ -91,7 +92,7 @@ class InMemoryIdentityServiceTests {
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
val identity = Party(rootCert)
val identity = Party(rootCert.cert)
val txIdentity = AnonymousParty(txKey.public)
assertFailsWith<UnknownAnonymousPartyException> {
@ -163,7 +164,7 @@ class InMemoryIdentityServiceTests {
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.toX509CertHolder(), issuerKeyPair, x500Name, txKey.public)
val txCertPath = certFactory.generateCertPath(listOf(txCert.cert) + issuer.certPath.certificates)
return Pair(issuer, PartyAndCertificate(txCertPath))
}

View File

@ -6,9 +6,10 @@ 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.internal.toX509CertHolder
import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.UnknownAnonymousPartyException
import net.corda.core.utilities.cert
import net.corda.core.internal.cert
import net.corda.node.services.identity.PersistentIdentityService
import net.corda.node.utilities.CertificateAndKeyPair
import net.corda.node.utilities.CertificateType
@ -134,7 +135,7 @@ class PersistentIdentityServiceTests {
val rootKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val rootCert = X509Utilities.createSelfSignedCACertificate(ALICE.name, rootKey)
val txKey = Crypto.generateKeyPair(X509Utilities.DEFAULT_IDENTITY_SIGNATURE_SCHEME)
val identity = Party(rootCert)
val identity = Party(rootCert.cert)
val txIdentity = AnonymousParty(txKey.public)
assertFailsWith<UnknownAnonymousPartyException> {
@ -262,7 +263,7 @@ class PersistentIdentityServiceTests {
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.toX509CertHolder(), issuerKeyPair, x500Name, txKey.public)
val txCertPath = certFactory.generateCertPath(listOf(txCert.cert) + issuer.certPath.certificates)
return Pair(issuer, PartyAndCertificate(txCertPath))
}

View File

@ -4,13 +4,13 @@ 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.identity.CordaX500Name
import net.corda.core.internal.cert
import net.corda.core.internal.div
import net.corda.core.internal.toTypedArray
import net.corda.core.internal.x500Name
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.node.serialization.KryoServerSerializationScheme
import net.corda.node.services.config.createKeystoreForCordaNode
import net.corda.nodeapi.internal.serialization.AllWhitelist

View File

@ -9,11 +9,10 @@ import net.corda.core.identity.CordaX500Name
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.internal.cert
import net.corda.node.utilities.X509Utilities
import net.corda.node.utilities.loadKeyStore
import net.corda.testing.ALICE
import net.corda.testing.getX500Name
import net.corda.testing.testNodeConfiguration
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x500.style.BCStyle

View File

@ -7,6 +7,7 @@ import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.random63BitValue
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.cert
import net.corda.core.internal.concurrent.doneFuture
import net.corda.core.internal.createDirectories
import net.corda.core.internal.createDirectory
@ -18,7 +19,9 @@ import net.corda.core.node.CordaPluginRegistry
import net.corda.core.node.ServiceEntry
import net.corda.core.node.WorldMapLocation
import net.corda.core.node.services.*
import net.corda.core.utilities.*
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.loggerFor
import net.corda.node.internal.AbstractNode
import net.corda.node.internal.StartedNode
import net.corda.node.services.config.NodeConfiguration
@ -170,7 +173,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
override fun makeIdentityService(trustRoot: X509Certificate,
clientCa: CertificateAndKeyPair?,
legalIdentity: PartyAndCertificate): IdentityService {
val caCertificates: Array<X509Certificate> = listOf(legalIdentity.certificate.cert, clientCa?.certificate?.cert)
val caCertificates: Array<X509Certificate> = listOf(legalIdentity.certificate, clientCa?.certificate?.cert)
.filterNotNull()
.toTypedArray()
val identityService = PersistentIdentityService(setOf(legalIdentity),
@ -414,7 +417,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
return when (msgRecipient) {
is SingleMessageRecipient -> nodes.single { it.started!!.network.myAddress == msgRecipient }
is InMemoryMessagingNetwork.ServiceHandle -> {
nodes.filter { it.advertisedServices.any { it == msgRecipient.service.info } }.firstOrNull()
nodes.firstOrNull { it.advertisedServices.any { it == msgRecipient.service.info } }
?: throw IllegalArgumentException("Couldn't find node advertising service with info: ${msgRecipient.service.info} ")
}
else -> throw IllegalArgumentException("Method not implemented for different type of message recipients")

View File

@ -9,6 +9,7 @@ import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.cert
import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.*
import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER