Move certificate builder code from core to node utilities.

Address PR comments

Fixup dead reference
This commit is contained in:
Matthew Nesbit
2017-08-10 10:11:16 +01:00
parent 4602739e93
commit af13371510
24 changed files with 325 additions and 285 deletions

View File

@ -14,19 +14,19 @@ import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec
import org.bouncycastle.asn1.* import org.bouncycastle.asn1.ASN1Integer
import org.bouncycastle.asn1.ASN1ObjectIdentifier
import org.bouncycastle.asn1.DERNull
import org.bouncycastle.asn1.DLSequence
import org.bouncycastle.asn1.bc.BCObjectIdentifiers import org.bouncycastle.asn1.bc.BCObjectIdentifiers
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers import org.bouncycastle.asn1.nist.NISTObjectIdentifiers
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo import org.bouncycastle.asn1.pkcs.PrivateKeyInfo
import org.bouncycastle.asn1.sec.SECObjectIdentifiers import org.bouncycastle.asn1.sec.SECObjectIdentifiers
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x509.AlgorithmIdentifier
import org.bouncycastle.asn1.x509.* import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers import org.bouncycastle.asn1.x9.X9ObjectIdentifiers
import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.cert.X509v3CertificateBuilder
import org.bouncycastle.cert.bc.BcX509ExtensionUtils
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateKey import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateKey
@ -40,10 +40,6 @@ import org.bouncycastle.jce.spec.ECPublicKeySpec
import org.bouncycastle.math.ec.ECConstants import org.bouncycastle.math.ec.ECConstants
import org.bouncycastle.math.ec.FixedPointCombMultiplier import org.bouncycastle.math.ec.FixedPointCombMultiplier
import org.bouncycastle.math.ec.WNafUtil import org.bouncycastle.math.ec.WNafUtil
import org.bouncycastle.operator.ContentSigner
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder
import org.bouncycastle.pkcs.PKCS10CertificationRequest
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider
import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PrivateKey import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PrivateKey
import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PublicKey import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PublicKey
@ -53,7 +49,6 @@ import java.security.*
import java.security.spec.InvalidKeySpecException import java.security.spec.InvalidKeySpecException
import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec import java.security.spec.X509EncodedKeySpec
import java.util.*
import javax.crypto.Mac import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec import javax.crypto.spec.SecretKeySpec
@ -196,7 +191,7 @@ object Crypto {
// that could cause unexpected and suspicious behaviour. // that could cause unexpected and suspicious behaviour.
// i.e. if someone removes a Provider and then he/she adds a new one with the same name. // i.e. if someone removes a Provider and then he/she adds a new one with the same name.
// The val is private to avoid any harmful state changes. // The val is private to avoid any harmful state changes.
private val providerMap: Map<String, Provider> = mapOf( val providerMap: Map<String, Provider> = mapOf(
BouncyCastleProvider.PROVIDER_NAME to getBouncyCastleProvider(), BouncyCastleProvider.PROVIDER_NAME to getBouncyCastleProvider(),
CordaSecurityProvider.PROVIDER_NAME to CordaSecurityProvider(), CordaSecurityProvider.PROVIDER_NAME to CordaSecurityProvider(),
"BCPQC" to BouncyCastlePQCProvider()) // unfortunately, provider's name is not final in BouncyCastlePQCProvider, so we explicitly set it. "BCPQC" to BouncyCastlePQCProvider()) // unfortunately, provider's name is not final in BouncyCastlePQCProvider, so we explicitly set it.
@ -770,90 +765,6 @@ object Crypto {
return mac.doFinal(seed) return mac.doFinal(seed)
} }
/**
* Build a partial X.509 certificate ready for signing.
*
* @param issuer name of the issuing entity.
* @param subject name of the certificate subject.
* @param subjectPublicKey public key of the certificate subject.
* @param validityWindow the time period the certificate is valid for.
* @param nameConstraints any name constraints to impose on certificates signed by the generated certificate.
*/
fun createCertificate(certificateType: CertificateType, issuer: X500Name,
subject: X500Name, subjectPublicKey: PublicKey,
validityWindow: Pair<Date, Date>,
nameConstraints: NameConstraints? = null): X509v3CertificateBuilder {
val serial = BigInteger.valueOf(random63BitValue())
val keyPurposes = DERSequence(ASN1EncodableVector().apply { certificateType.purposes.forEach { add(it) } })
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(subjectPublicKey.encoded))
val builder = JcaX509v3CertificateBuilder(issuer, serial, validityWindow.first, validityWindow.second, subject, subjectPublicKey)
.addExtension(Extension.subjectKeyIdentifier, false, BcX509ExtensionUtils().createSubjectKeyIdentifier(subjectPublicKeyInfo))
.addExtension(Extension.basicConstraints, certificateType.isCA, BasicConstraints(certificateType.isCA))
.addExtension(Extension.keyUsage, false, certificateType.keyUsage)
.addExtension(Extension.extendedKeyUsage, false, keyPurposes)
if (nameConstraints != null) {
builder.addExtension(Extension.nameConstraints, true, nameConstraints)
}
return builder
}
/**
* Build and sign an X.509 certificate with the given signer.
*
* @param issuer name of the issuing entity.
* @param issuerSigner content signer to sign the certificate with.
* @param subject name of the certificate subject.
* @param subjectPublicKey public key of the certificate subject.
* @param validityWindow the time period the certificate is valid for.
* @param nameConstraints any name constraints to impose on certificates signed by the generated certificate.
*/
fun createCertificate(certificateType: CertificateType, issuer: X500Name, issuerSigner: ContentSigner,
subject: X500Name, subjectPublicKey: PublicKey,
validityWindow: Pair<Date, Date>,
nameConstraints: NameConstraints? = null): X509CertificateHolder {
val builder = createCertificate(certificateType, issuer, subject, subjectPublicKey, validityWindow, nameConstraints)
return builder.build(issuerSigner).apply {
require(isValidOn(Date()))
}
}
/**
* Build and sign an X.509 certificate with CA cert private key.
*
* @param issuer name of the issuing entity.
* @param issuerKeyPair the public & private key to sign the certificate with.
* @param subject name of the certificate subject.
* @param subjectPublicKey public key of the certificate subject.
* @param validityWindow the time period the certificate is valid for.
* @param nameConstraints any name constraints to impose on certificates signed by the generated certificate.
*/
fun createCertificate(certificateType: CertificateType, issuer: X500Name, issuerKeyPair: KeyPair,
subject: X500Name, subjectPublicKey: PublicKey,
validityWindow: Pair<Date, Date>,
nameConstraints: NameConstraints? = null): X509CertificateHolder {
val signatureScheme = findSignatureScheme(issuerKeyPair.private)
val provider = providerMap[signatureScheme.providerName]
val builder = createCertificate(certificateType, issuer, subject, subjectPublicKey, validityWindow, nameConstraints)
val signer = ContentSignerBuilder.build(signatureScheme, issuerKeyPair.private, provider)
return builder.build(signer).apply {
require(isValidOn(Date()))
require(isSignatureValid(JcaContentVerifierProviderBuilder().build(issuerKeyPair.public)))
}
}
/**
* Create certificate signing request using provided information.
*/
fun createCertificateSigningRequest(subject: X500Name, keyPair: KeyPair, signatureScheme: SignatureScheme): PKCS10CertificationRequest {
val signer = ContentSignerBuilder.build(signatureScheme, keyPair.private, providerMap[signatureScheme.providerName])
return JcaPKCS10CertificationRequestBuilder(subject, keyPair.public).build(signer)
}
private class KeyInfoConverter(val signatureScheme: SignatureScheme) : AsymmetricKeyInfoConverter { private class KeyInfoConverter(val signatureScheme: SignatureScheme) : AsymmetricKeyInfoConverter {
override fun generatePublic(keyInfo: SubjectPublicKeyInfo?): PublicKey? = keyInfo?.let { decodePublicKey(signatureScheme, it.encoded) } override fun generatePublic(keyInfo: SubjectPublicKeyInfo?): PublicKey? = keyInfo?.let { decodePublicKey(signatureScheme, it.encoded) }
override fun generatePrivate(keyInfo: PrivateKeyInfo?): PrivateKey? = keyInfo?.let { decodePrivateKey(signatureScheme, it.encoded) } override fun generatePrivate(keyInfo: PrivateKeyInfo?): PrivateKey? = keyInfo?.let { decodePrivateKey(signatureScheme, it.encoded) }

View File

@ -0,0 +1,77 @@
@file:JvmName("X500NameUtils")
package net.corda.core.crypto
import org.bouncycastle.asn1.ASN1Encodable
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x500.X500NameBuilder
import org.bouncycastle.asn1.x500.style.BCStyle
import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import java.security.KeyPair
import java.security.cert.X509Certificate
/**
* Rebuild the distinguished name, adding a postfix to the common name. If no common name is present.
* @throws IllegalArgumentException if the distinguished name does not contain a common name element.
*/
fun X500Name.appendToCommonName(commonName: String): X500Name = mutateCommonName { attr -> attr.toString() + commonName }
/**
* Rebuild the distinguished name, replacing the common name with the given value. If no common name is present, this
* adds one.
* @throws IllegalArgumentException if the distinguished name does not contain a common name element.
*/
fun X500Name.replaceCommonName(commonName: String): X500Name = mutateCommonName { _ -> commonName }
/**
* Rebuild the distinguished name, replacing the common name with a value generated from the provided function.
*
* @param mutator a function to generate the new value from the previous one.
* @throws IllegalArgumentException if the distinguished name does not contain a common name element.
*/
private fun X500Name.mutateCommonName(mutator: (ASN1Encodable) -> String): X500Name {
val builder = X500NameBuilder(BCStyle.INSTANCE)
var matched = false
this.rdNs.forEach { rdn ->
rdn.typesAndValues.forEach { typeAndValue ->
when (typeAndValue.type) {
BCStyle.CN -> {
matched = true
builder.addRDN(typeAndValue.type, mutator(typeAndValue.value))
}
else -> {
builder.addRDN(typeAndValue)
}
}
}
}
require(matched) { "Input X.500 name must include a common name (CN) attribute: ${this}" }
return builder.build()
}
val X500Name.commonName: String get() = getRDNs(BCStyle.CN).first().first.value.toString()
val X500Name.orgName: String? get() = getRDNs(BCStyle.O).firstOrNull()?.first?.value?.toString()
val X500Name.location: String get() = getRDNs(BCStyle.L).first().first.value.toString()
val X500Name.locationOrNull: String? get() = try {
location
} catch (e: Exception) {
null
}
val X509Certificate.subject: X500Name get() = X509CertificateHolder(encoded).subject
val X509CertificateHolder.cert: X509Certificate get() = JcaX509CertificateConverter().getCertificate(this)
/**
* Generate a distinguished name from the provided values.
*/
@JvmOverloads
fun getX509Name(myLegalName: String, nearestCity: String, email: String, country: String? = null): X500Name {
return X500NameBuilder(BCStyle.INSTANCE).let { builder ->
builder.addRDN(BCStyle.CN, myLegalName)
builder.addRDN(BCStyle.L, nearestCity)
country?.let { builder.addRDN(BCStyle.C, it) }
builder.addRDN(BCStyle.E, email)
builder.build()
}
}
data class CertificateAndKeyPair(val certificate: X509CertificateHolder, val keyPair: KeyPair)

View File

@ -8,9 +8,7 @@ import net.corda.core.internal.declaredField
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.node.utilities.loadKeyStore import net.corda.node.utilities.*
import net.corda.node.utilities.loadOrCreateKeyStore
import net.corda.node.utilities.save
import net.corda.testing.TestDependencyInjectionBase import net.corda.testing.TestDependencyInjectionBase
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
import org.junit.Rule import org.junit.Rule

View File

@ -1,9 +1,7 @@
package net.corda.core.crypto package net.corda.core.crypto
import net.corda.core.internal.toTypedArray import net.corda.core.internal.toTypedArray
import net.corda.node.utilities.KEYSTORE_TYPE import net.corda.node.utilities.*
import net.corda.node.utilities.addOrReplaceCertificate
import net.corda.node.utilities.addOrReplaceKey
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x509.GeneralName import org.bouncycastle.asn1.x509.GeneralName
import org.bouncycastle.asn1.x509.GeneralSubtree import org.bouncycastle.asn1.x509.GeneralSubtree
@ -20,13 +18,13 @@ class X509NameConstraintsTest {
private fun makeKeyStores(subjectName: X500Name, nameConstraints: NameConstraints): Pair<KeyStore, KeyStore> { private fun makeKeyStores(subjectName: X500Name, nameConstraints: NameConstraints): Pair<KeyStore, KeyStore> {
val rootKeys = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val rootKeys = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val rootCACert = X509Utilities.createSelfSignedCACertificate(X509Utilities.getX509Name("Corda Root CA","London","demo@r3.com",null), rootKeys) val rootCACert = X509Utilities.createSelfSignedCACertificate(getX509Name("Corda Root CA", "London", "demo@r3.com", null), rootKeys)
val intermediateCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val intermediateCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootKeys, X509Utilities.getX509Name("Corda Intermediate CA","London","demo@r3.com",null), intermediateCAKeyPair.public) val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootKeys, getX509Name("Corda Intermediate CA", "London", "demo@r3.com", null), intermediateCAKeyPair.public)
val clientCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val clientCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCACert, intermediateCAKeyPair, X509Utilities.getX509Name("Corda Client CA","London","demo@r3.com",null), clientCAKeyPair.public, nameConstraints = nameConstraints) val clientCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, intermediateCACert, intermediateCAKeyPair, getX509Name("Corda Client CA", "London", "demo@r3.com", null), clientCAKeyPair.public, nameConstraints = nameConstraints)
val keyPass = "password" val keyPass = "password"
val trustStore = KeyStore.getInstance(KEYSTORE_TYPE) val trustStore = KeyStore.getInstance(KEYSTORE_TYPE)

View File

@ -11,20 +11,14 @@ import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.sequence import net.corda.core.utilities.sequence
import net.corda.node.serialization.KryoServerSerializationScheme import net.corda.node.serialization.KryoServerSerializationScheme
import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.services.persistence.NodeAttachmentService
import net.corda.testing.ALICE
import net.corda.testing.ALICE_PUBKEY import net.corda.testing.ALICE_PUBKEY
import net.corda.testing.BOB
import net.corda.testing.BOB_PUBKEY
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.bouncycastle.cert.X509CertificateHolder
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.InputStream import java.io.InputStream
import java.security.cert.CertPath
import java.security.cert.CertificateFactory
import java.time.Instant import java.time.Instant
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -150,26 +144,6 @@ class KryoTests {
assertEquals(-1, readRubbishStream.read()) assertEquals(-1, readRubbishStream.read())
} }
@Test
fun `serialize - deserialize X509CertififcateHolder`() {
val expected: X509CertificateHolder = X509Utilities.createSelfSignedCACertificate(ALICE.name, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME))
val serialized = expected.serialize(factory, context).bytes
val actual: X509CertificateHolder = serialized.deserialize(factory, context)
assertEquals(expected, actual)
}
@Test
fun `serialize - deserialize X509CertPath`() {
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 expected = certFactory.generateCertPath(listOf(certificate.cert, rootCACert.cert))
val serialized = expected.serialize(factory, context).bytes
val actual: CertPath = serialized.deserialize(factory, context)
assertEquals(expected, actual)
}
@CordaSerializable @CordaSerializable
private data class Person(val name: String, val birthday: Instant?) private data class Person(val name: String, val birthday: Instant?)

View File

@ -1,10 +1,8 @@
package net.corda.services.messaging package net.corda.services.messaging
import net.corda.core.crypto.Crypto
import net.corda.core.internal.copyTo import net.corda.core.internal.copyTo
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.crypto.CertificateType
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.X509Utilities
import net.corda.core.internal.exists import net.corda.core.internal.exists
import net.corda.node.utilities.* import net.corda.node.utilities.*
import net.corda.nodeapi.ArtemisMessagingComponent.Companion.NODE_USER import net.corda.nodeapi.ArtemisMessagingComponent.Companion.NODE_USER

View File

@ -4,9 +4,10 @@ import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigParseOptions import com.typesafe.config.ConfigParseOptions
import com.typesafe.config.ConfigRenderOptions import com.typesafe.config.ConfigRenderOptions
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SignatureScheme
import net.corda.core.internal.copyTo import net.corda.core.internal.copyTo
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.crypto.*
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.exists import net.corda.core.internal.exists
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor

View File

@ -1,10 +1,14 @@
package net.corda.node.services.keys package net.corda.node.services.keys
import net.corda.core.crypto.* import net.corda.core.crypto.ContentSignerBuilder
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.cert
import net.corda.core.identity.AnonymousPartyAndPath import net.corda.core.identity.AnonymousPartyAndPath
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.days import net.corda.core.utilities.days
import net.corda.node.utilities.CertificateType
import net.corda.node.utilities.X509Utilities
import org.bouncycastle.operator.ContentSigner import org.bouncycastle.operator.ContentSigner
import java.security.KeyPair import java.security.KeyPair
import java.security.PublicKey import java.security.PublicKey
@ -31,7 +35,7 @@ fun freshCertificate(identityService: IdentityService,
revocationEnabled: Boolean = false): AnonymousPartyAndPath { revocationEnabled: Boolean = false): AnonymousPartyAndPath {
val issuerCertificate = issuer.certificate val issuerCertificate = issuer.certificate
val window = X509Utilities.getCertificateValidityWindow(Duration.ZERO, 3650.days, issuerCertificate) val window = X509Utilities.getCertificateValidityWindow(Duration.ZERO, 3650.days, issuerCertificate)
val ourCertificate = Crypto.createCertificate(CertificateType.IDENTITY, issuerCertificate.subject, issuerSigner, issuer.name, subjectPublicKey, window) val ourCertificate = X509Utilities.createCertificate(CertificateType.IDENTITY, issuerCertificate.subject, issuerSigner, issuer.name, subjectPublicKey, window)
val certFactory = CertificateFactory.getInstance("X509") val certFactory = CertificateFactory.getInstance("X509")
val ourCertPath = certFactory.generateCertPath(listOf(ourCertificate.cert) + issuer.certPath.certificates) val ourCertPath = certFactory.generateCertPath(listOf(ourCertificate.cert) + issuer.certPath.certificates)
val anonymisedIdentity = AnonymousPartyAndPath(subjectPublicKey, ourCertPath) val anonymisedIdentity = AnonymousPartyAndPath(subjectPublicKey, ourCertPath)

View File

@ -2,13 +2,13 @@ package net.corda.node.services.messaging
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
import io.netty.handler.ssl.SslHandler import io.netty.handler.ssl.SslHandler
import net.corda.core.*
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.* import net.corda.core.crypto.AddressFormatException
import net.corda.core.crypto.X509Utilities.CORDA_CLIENT_TLS import net.corda.core.crypto.newSecureRandom
import net.corda.core.crypto.X509Utilities.CORDA_ROOT_CA import net.corda.core.crypto.parsePublicKeyBase58
import net.corda.core.internal.concurrent.openFuture import net.corda.core.crypto.random63BitValue
import net.corda.core.internal.ThreadBox import net.corda.core.internal.ThreadBox
import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.noneOrSingle import net.corda.core.internal.noneOrSingle
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
@ -22,6 +22,9 @@ import net.corda.node.services.messaging.NodeLoginModule.Companion.NODE_ROLE
import net.corda.node.services.messaging.NodeLoginModule.Companion.PEER_ROLE import net.corda.node.services.messaging.NodeLoginModule.Companion.PEER_ROLE
import net.corda.node.services.messaging.NodeLoginModule.Companion.RPC_ROLE import net.corda.node.services.messaging.NodeLoginModule.Companion.RPC_ROLE
import net.corda.node.services.messaging.NodeLoginModule.Companion.VERIFIER_ROLE import net.corda.node.services.messaging.NodeLoginModule.Companion.VERIFIER_ROLE
import net.corda.node.utilities.X509Utilities
import net.corda.node.utilities.X509Utilities.CORDA_CLIENT_TLS
import net.corda.node.utilities.X509Utilities.CORDA_ROOT_CA
import net.corda.node.utilities.getX509Certificate import net.corda.node.utilities.getX509Certificate
import net.corda.node.utilities.loadKeyStore import net.corda.node.utilities.loadKeyStore
import net.corda.nodeapi.* import net.corda.nodeapi.*

View File

@ -1,25 +1,33 @@
package net.corda.core.crypto package net.corda.node.utilities
import net.corda.core.crypto.*
import net.corda.core.utilities.days import net.corda.core.utilities.days
import net.corda.core.utilities.millis import net.corda.core.utilities.millis
import org.bouncycastle.asn1.ASN1Encodable import org.bouncycastle.asn1.ASN1EncodableVector
import org.bouncycastle.asn1.ASN1Sequence
import org.bouncycastle.asn1.DERSequence
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x500.X500NameBuilder import org.bouncycastle.asn1.x509.*
import org.bouncycastle.asn1.x500.style.BCStyle import org.bouncycastle.asn1.x509.Extension
import org.bouncycastle.asn1.x509.KeyPurposeId
import org.bouncycastle.asn1.x509.KeyUsage
import org.bouncycastle.asn1.x509.NameConstraints
import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter import org.bouncycastle.cert.X509v3CertificateBuilder
import org.bouncycastle.cert.bc.BcX509ExtensionUtils
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder
import org.bouncycastle.openssl.jcajce.JcaPEMWriter import org.bouncycastle.openssl.jcajce.JcaPEMWriter
import org.bouncycastle.operator.ContentSigner
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder
import org.bouncycastle.pkcs.PKCS10CertificationRequest
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder
import org.bouncycastle.util.io.pem.PemReader import org.bouncycastle.util.io.pem.PemReader
import java.io.FileReader import java.io.FileReader
import java.io.FileWriter import java.io.FileWriter
import java.io.InputStream import java.io.InputStream
import java.math.BigInteger
import java.nio.file.Path import java.nio.file.Path
import java.security.KeyPair import java.security.KeyPair
import java.security.PublicKey import java.security.PublicKey
import java.security.cert.* import java.security.cert.*
import java.security.cert.Certificate
import java.time.Duration import java.time.Duration
import java.time.Instant import java.time.Instant
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
@ -69,44 +77,13 @@ object X509Utilities {
return Pair(notBefore, notAfter) return Pair(notBefore, notAfter)
} }
/**
* Return a bogus X509 for dev purposes. Use [getX509Name] for something more real.
*/
@Deprecated("Full legal names should be specified in all configurations")
fun getDevX509Name(commonName: String): X500Name {
val nameBuilder = X500NameBuilder(BCStyle.INSTANCE)
nameBuilder.addRDN(BCStyle.CN, commonName)
nameBuilder.addRDN(BCStyle.O, "R3")
nameBuilder.addRDN(BCStyle.OU, "corda")
nameBuilder.addRDN(BCStyle.L, "London")
nameBuilder.addRDN(BCStyle.C, "GB")
return nameBuilder.build()
}
/**
* Generate a distinguished name from the provided values.
*
* @see [CoreTestUtils.getTestX509Name] for generating distinguished names for test cases.
*/
@JvmOverloads
@JvmStatic
fun getX509Name(myLegalName: String, nearestCity: String, email: String, country: String? = null): X500Name {
return X500NameBuilder(BCStyle.INSTANCE).let { builder ->
builder.addRDN(BCStyle.CN, myLegalName)
builder.addRDN(BCStyle.L, nearestCity)
country?.let { builder.addRDN(BCStyle.C, it) }
builder.addRDN(BCStyle.E, email)
builder.build()
}
}
/* /*
* Create a de novo root self-signed X509 v3 CA cert. * Create a de novo root self-signed X509 v3 CA cert.
*/ */
@JvmStatic @JvmStatic
fun createSelfSignedCACertificate(subject: X500Name, keyPair: KeyPair, validityWindow: Pair<Duration, Duration> = DEFAULT_VALIDITY_WINDOW): X509CertificateHolder { fun createSelfSignedCACertificate(subject: X500Name, keyPair: KeyPair, validityWindow: Pair<Duration, Duration> = DEFAULT_VALIDITY_WINDOW): X509CertificateHolder {
val window = getCertificateValidityWindow(validityWindow.first, validityWindow.second) val window = getCertificateValidityWindow(validityWindow.first, validityWindow.second)
return Crypto.createCertificate(CertificateType.ROOT_CA, subject, keyPair, subject, keyPair.public, window) return createCertificate(CertificateType.ROOT_CA, subject, keyPair, subject, keyPair.public, window)
} }
/** /**
@ -126,7 +103,7 @@ object X509Utilities {
validityWindow: Pair<Duration, Duration> = DEFAULT_VALIDITY_WINDOW, validityWindow: Pair<Duration, Duration> = DEFAULT_VALIDITY_WINDOW,
nameConstraints: NameConstraints? = null): X509CertificateHolder { nameConstraints: NameConstraints? = null): X509CertificateHolder {
val window = getCertificateValidityWindow(validityWindow.first, validityWindow.second, issuerCertificate) val window = getCertificateValidityWindow(validityWindow.first, validityWindow.second, issuerCertificate)
return Crypto.createCertificate(certificateType, issuerCertificate.subject, issuerKeyPair, subject, subjectPublicKey, window, nameConstraints) return createCertificate(certificateType, issuerCertificate.subject, issuerKeyPair, subject, subjectPublicKey, window, nameConstraints)
} }
fun validateCertificateChain(trustedRoot: X509CertificateHolder, vararg certificates: Certificate) { fun validateCertificateChain(trustedRoot: X509CertificateHolder, vararg certificates: Certificate) {
@ -168,54 +145,93 @@ object X509Utilities {
} }
} }
fun createCertificateSigningRequest(subject: X500Name, keyPair: KeyPair, signatureScheme: SignatureScheme = DEFAULT_TLS_SIGNATURE_SCHEME) = Crypto.createCertificateSigningRequest(subject, keyPair, signatureScheme)
}
/** /**
* Rebuild the distinguished name, adding a postfix to the common name. If no common name is present. * Build a partial X.509 certificate ready for signing.
* @throws IllegalArgumentException if the distinguished name does not contain a common name element.
*/
fun X500Name.appendToCommonName(commonName: String): X500Name = mutateCommonName { attr -> attr.toString() + commonName }
/**
* Rebuild the distinguished name, replacing the common name with the given value. If no common name is present, this
* adds one.
* @throws IllegalArgumentException if the distinguished name does not contain a common name element.
*/
fun X500Name.replaceCommonName(commonName: String): X500Name = mutateCommonName { _ -> commonName }
/**
* Rebuild the distinguished name, replacing the common name with a value generated from the provided function.
* *
* @param mutator a function to generate the new value from the previous one. * @param issuer name of the issuing entity.
* @throws IllegalArgumentException if the distinguished name does not contain a common name element. * @param subject name of the certificate subject.
* @param subjectPublicKey public key of the certificate subject.
* @param validityWindow the time period the certificate is valid for.
* @param nameConstraints any name constraints to impose on certificates signed by the generated certificate.
*/ */
private fun X500Name.mutateCommonName(mutator: (ASN1Encodable) -> String): X500Name { fun createCertificate(certificateType: CertificateType, issuer: X500Name,
val builder = X500NameBuilder(BCStyle.INSTANCE) subject: X500Name, subjectPublicKey: PublicKey,
var matched = false validityWindow: Pair<Date, Date>,
this.rdNs.forEach { rdn -> nameConstraints: NameConstraints? = null): X509v3CertificateBuilder {
rdn.typesAndValues.forEach { typeAndValue ->
when (typeAndValue.type) { val serial = BigInteger.valueOf(random63BitValue())
BCStyle.CN -> { val keyPurposes = DERSequence(ASN1EncodableVector().apply { certificateType.purposes.forEach { add(it) } })
matched = true val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(subjectPublicKey.encoded))
builder.addRDN(typeAndValue.type, mutator(typeAndValue.value))
val builder = JcaX509v3CertificateBuilder(issuer, serial, validityWindow.first, validityWindow.second, subject, subjectPublicKey)
.addExtension(Extension.subjectKeyIdentifier, false, BcX509ExtensionUtils().createSubjectKeyIdentifier(subjectPublicKeyInfo))
.addExtension(Extension.basicConstraints, certificateType.isCA, BasicConstraints(certificateType.isCA))
.addExtension(Extension.keyUsage, false, certificateType.keyUsage)
.addExtension(Extension.extendedKeyUsage, false, keyPurposes)
if (nameConstraints != null) {
builder.addExtension(Extension.nameConstraints, true, nameConstraints)
} }
else -> { return builder
builder.addRDN(typeAndValue) }
}
} /**
} * Build and sign an X.509 certificate with the given signer.
} *
require(matched) { "Input X.500 name must include a common name (CN) attribute: ${this}" } * @param issuer name of the issuing entity.
return builder.build() * @param issuerSigner content signer to sign the certificate with.
* @param subject name of the certificate subject.
* @param subjectPublicKey public key of the certificate subject.
* @param validityWindow the time period the certificate is valid for.
* @param nameConstraints any name constraints to impose on certificates signed by the generated certificate.
*/
fun createCertificate(certificateType: CertificateType, issuer: X500Name, issuerSigner: ContentSigner,
subject: X500Name, subjectPublicKey: PublicKey,
validityWindow: Pair<Date, Date>,
nameConstraints: NameConstraints? = null): X509CertificateHolder {
val builder = createCertificate(certificateType, issuer, subject, subjectPublicKey, validityWindow, nameConstraints)
return builder.build(issuerSigner).apply {
require(isValidOn(Date()))
}
}
/**
* Build and sign an X.509 certificate with CA cert private key.
*
* @param issuer name of the issuing entity.
* @param issuerKeyPair the public & private key to sign the certificate with.
* @param subject name of the certificate subject.
* @param subjectPublicKey public key of the certificate subject.
* @param validityWindow the time period the certificate is valid for.
* @param nameConstraints any name constraints to impose on certificates signed by the generated certificate.
*/
fun createCertificate(certificateType: CertificateType, issuer: X500Name, issuerKeyPair: KeyPair,
subject: X500Name, subjectPublicKey: PublicKey,
validityWindow: Pair<Date, Date>,
nameConstraints: NameConstraints? = null): X509CertificateHolder {
val signatureScheme = Crypto.findSignatureScheme(issuerKeyPair.private)
val provider = Crypto.providerMap[signatureScheme.providerName]
val builder = createCertificate(certificateType, issuer, subject, subjectPublicKey, validityWindow, nameConstraints)
val signer = ContentSignerBuilder.build(signatureScheme, issuerKeyPair.private, provider)
return builder.build(signer).apply {
require(isValidOn(Date()))
require(isSignatureValid(JcaContentVerifierProviderBuilder().build(issuerKeyPair.public)))
}
}
/**
* Create certificate signing request using provided information.
*/
fun createCertificateSigningRequest(subject: X500Name, keyPair: KeyPair, signatureScheme: SignatureScheme): PKCS10CertificationRequest {
val signer = ContentSignerBuilder.build(signatureScheme, keyPair.private, Crypto.providerMap[signatureScheme.providerName])
return JcaPKCS10CertificationRequestBuilder(subject, keyPair.public).build(signer)
}
fun createCertificateSigningRequest(subject: X500Name, keyPair: KeyPair) = createCertificateSigningRequest(subject, keyPair, DEFAULT_TLS_SIGNATURE_SCHEME)
} }
val X500Name.commonName: String get() = getRDNs(BCStyle.CN).first().first.value.toString()
val X500Name.orgName: String? get() = getRDNs(BCStyle.O).firstOrNull()?.first?.value?.toString()
val X500Name.location: String get() = getRDNs(BCStyle.L).first().first.value.toString()
val X500Name.locationOrNull: String? get() = try { location } catch (e: Exception) { null }
val X509Certificate.subject: X500Name get() = X509CertificateHolder(encoded).subject
val X509CertificateHolder.cert: X509Certificate get() = JcaX509CertificateConverter().getCertificate(this)
class CertificateStream(val input: InputStream) { class CertificateStream(val input: InputStream) {
private val certificateFactory = CertificateFactory.getInstance("X.509") private val certificateFactory = CertificateFactory.getInstance("X.509")
@ -223,8 +239,6 @@ class CertificateStream(val input: InputStream) {
fun nextCertificate(): X509Certificate = certificateFactory.generateCertificate(input) as X509Certificate fun nextCertificate(): X509Certificate = certificateFactory.generateCertificate(input) as X509Certificate
} }
data class CertificateAndKeyPair(val certificate: X509CertificateHolder, val keyPair: KeyPair)
enum class CertificateType(val keyUsage: KeyUsage, vararg val purposes: KeyPurposeId, val isCA: Boolean) { enum class CertificateType(val keyUsage: KeyUsage, vararg val purposes: KeyPurposeId, val isCA: Boolean) {
ROOT_CA(KeyUsage(KeyUsage.digitalSignature or KeyUsage.keyCertSign or KeyUsage.cRLSign), KeyPurposeId.id_kp_serverAuth, KeyPurposeId.id_kp_clientAuth, KeyPurposeId.anyExtendedKeyUsage, isCA = true), ROOT_CA(KeyUsage(KeyUsage.digitalSignature or KeyUsage.keyCertSign or KeyUsage.cRLSign), KeyPurposeId.id_kp_serverAuth, KeyPurposeId.id_kp_clientAuth, KeyPurposeId.anyExtendedKeyUsage, isCA = true),
INTERMEDIATE_CA(KeyUsage(KeyUsage.digitalSignature or KeyUsage.keyCertSign or KeyUsage.cRLSign), KeyPurposeId.id_kp_serverAuth, KeyPurposeId.id_kp_clientAuth, KeyPurposeId.anyExtendedKeyUsage, isCA = true), INTERMEDIATE_CA(KeyUsage(KeyUsage.digitalSignature or KeyUsage.keyCertSign or KeyUsage.cRLSign), KeyPurposeId.id_kp_serverAuth, KeyPurposeId.id_kp_clientAuth, KeyPurposeId.anyExtendedKeyUsage, isCA = true),

View File

@ -1,7 +1,7 @@
package net.corda.node.utilities.registration package net.corda.node.utilities.registration
import com.google.common.net.MediaType import com.google.common.net.MediaType
import net.corda.core.crypto.CertificateStream import net.corda.node.utilities.CertificateStream
import org.apache.commons.io.IOUtils import org.apache.commons.io.IOUtils
import org.bouncycastle.pkcs.PKCS10CertificationRequest import org.bouncycastle.pkcs.PKCS10CertificationRequest
import java.io.IOException import java.io.IOException

View File

@ -1,17 +1,15 @@
package net.corda.node.utilities.registration package net.corda.node.utilities.registration
import net.corda.core.crypto.CertificateType
import net.corda.core.crypto.Crypto import net.corda.core.crypto.Crypto
import net.corda.core.crypto.X509Utilities
import net.corda.core.crypto.X509Utilities.CORDA_CLIENT_CA
import net.corda.core.crypto.X509Utilities.CORDA_CLIENT_TLS
import net.corda.core.crypto.X509Utilities.CORDA_ROOT_CA
import net.corda.core.crypto.cert import net.corda.core.crypto.cert
import net.corda.core.internal.* import net.corda.core.internal.*
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.core.utilities.validateX500Name import net.corda.core.utilities.validateX500Name
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.utilities.* import net.corda.node.utilities.*
import net.corda.node.utilities.X509Utilities.CORDA_CLIENT_CA
import net.corda.node.utilities.X509Utilities.CORDA_CLIENT_TLS
import net.corda.node.utilities.X509Utilities.CORDA_ROOT_CA
import org.bouncycastle.openssl.jcajce.JcaPEMWriter import org.bouncycastle.openssl.jcajce.JcaPEMWriter
import org.bouncycastle.util.io.pem.PemObject import org.bouncycastle.util.io.pem.PemObject
import java.io.StringWriter import java.io.StringWriter

View File

@ -1,12 +1,17 @@
package net.corda.node.services.network package net.corda.node.services.network
import net.corda.core.crypto.* import net.corda.core.crypto.CertificateAndKeyPair
import net.corda.core.identity.AnonymousPartyAndPath import net.corda.core.crypto.Crypto
import net.corda.core.crypto.cert
import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.AnonymousParty import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.AnonymousPartyAndPath
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.utilities.CertificateType
import net.corda.node.utilities.X509Utilities
import net.corda.testing.* import net.corda.testing.*
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
import org.junit.Test import org.junit.Test

View File

@ -1,19 +1,28 @@
package net.corda.core.crypto 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.EDDSA_ED25519_SHA512
import net.corda.core.crypto.Crypto.generateKeyPair import net.corda.core.crypto.Crypto.generateKeyPair
import net.corda.core.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME import net.corda.core.crypto.cert
import net.corda.core.crypto.X509Utilities.createSelfSignedCACertificate import net.corda.core.crypto.commonName
import net.corda.core.crypto.getX509Name
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.toTypedArray 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.node.serialization.KryoServerSerializationScheme
import net.corda.node.services.config.createKeystoreForCordaNode import net.corda.node.services.config.createKeystoreForCordaNode
import net.corda.node.utilities.* import net.corda.nodeapi.internal.serialization.AllWhitelist
import net.corda.testing.MEGA_CORP import net.corda.nodeapi.internal.serialization.KryoHeaderV0_1
import net.corda.testing.getTestX509Name import net.corda.nodeapi.internal.serialization.SerializationContextImpl
import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
import net.corda.testing.*
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x509.BasicConstraints import org.bouncycastle.asn1.x509.BasicConstraints
import org.bouncycastle.asn1.x509.Extension import org.bouncycastle.asn1.x509.Extension
import org.bouncycastle.asn1.x509.KeyUsage import org.bouncycastle.asn1.x509.KeyUsage
import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -27,7 +36,9 @@ import java.nio.file.Path
import java.security.KeyStore import java.security.KeyStore
import java.security.PrivateKey import java.security.PrivateKey
import java.security.SecureRandom import java.security.SecureRandom
import java.security.cert.CertPath
import java.security.cert.Certificate import java.security.cert.Certificate
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
import java.util.* import java.util.*
import java.util.stream.Stream import java.util.stream.Stream
@ -42,8 +53,8 @@ class X509UtilitiesTest {
@Test @Test
fun `create valid self-signed CA certificate`() { fun `create valid self-signed CA certificate`() {
val caKey = generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) val caKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val caCert = createSelfSignedCACertificate(getTestX509Name("Test Cert"), caKey) val caCert = X509Utilities.createSelfSignedCACertificate(getTestX509Name("Test Cert"), caKey)
assertTrue { caCert.subject.commonName == "Test Cert" } // using our subject common name assertTrue { caCert.subject.commonName == "Test Cert" } // using our subject common name
assertEquals(caCert.issuer, caCert.subject) //self-signed assertEquals(caCert.issuer, caCert.subject) //self-signed
caCert.isValidOn(Date()) // throws on verification problems caCert.isValidOn(Date()) // throws on verification problems
@ -57,8 +68,8 @@ class X509UtilitiesTest {
@Test @Test
fun `load and save a PEM file certificate`() { fun `load and save a PEM file certificate`() {
val tmpCertificateFile = tempFile("cacert.pem") val tmpCertificateFile = tempFile("cacert.pem")
val caKey = generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) val caKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val caCert = createSelfSignedCACertificate(getTestX509Name("Test Cert"), caKey) val caCert = X509Utilities.createSelfSignedCACertificate(getTestX509Name("Test Cert"), caKey)
X509Utilities.saveCertificateAsPEMFile(caCert, tmpCertificateFile) X509Utilities.saveCertificateAsPEMFile(caCert, tmpCertificateFile)
val readCertificate = X509Utilities.loadCertificateFromPEMFile(tmpCertificateFile) val readCertificate = X509Utilities.loadCertificateFromPEMFile(tmpCertificateFile)
assertEquals(caCert, readCertificate) assertEquals(caCert, readCertificate)
@ -66,10 +77,10 @@ class X509UtilitiesTest {
@Test @Test
fun `create valid server certificate chain`() { fun `create valid server certificate chain`() {
val caKey = generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) val caKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val caCert = createSelfSignedCACertificate(getTestX509Name("Test CA Cert"), caKey) val caCert = X509Utilities.createSelfSignedCACertificate(getTestX509Name("Test CA Cert"), caKey)
val subject = getTestX509Name("Server Cert") val subject = getTestX509Name("Server Cert")
val keyPair = generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) val keyPair = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val serverCert = X509Utilities.createCertificate(CertificateType.TLS, caCert, caKey, subject, keyPair.public) val serverCert = X509Utilities.createCertificate(CertificateType.TLS, caCert, caKey, subject, keyPair.public)
assertTrue { serverCert.subject.toString().contains("CN=Server Cert") } // using our subject common name assertTrue { serverCert.subject.toString().contains("CN=Server Cert") } // using our subject common name
assertEquals(caCert.issuer, serverCert.issuer) // Issued by our CA cert assertEquals(caCert.issuer, serverCert.issuer) // Issued by our CA cert
@ -86,7 +97,7 @@ class X509UtilitiesTest {
val tmpKeyStore = tempFile("keystore.jks") val tmpKeyStore = tempFile("keystore.jks")
val keyPair = generateKeyPair(EDDSA_ED25519_SHA512) val keyPair = generateKeyPair(EDDSA_ED25519_SHA512)
val selfSignCert = createSelfSignedCACertificate(X500Name("CN=Test"), keyPair) val selfSignCert = X509Utilities.createSelfSignedCACertificate(X500Name("CN=Test"), keyPair)
assertTrue(Arrays.equals(selfSignCert.subjectPublicKeyInfo.encoded, keyPair.public.encoded)) assertTrue(Arrays.equals(selfSignCert.subjectPublicKeyInfo.encoded, keyPair.public.encoded))
@ -111,7 +122,7 @@ class X509UtilitiesTest {
fun `signing EdDSA key with EcDSA certificate`() { fun `signing EdDSA key with EcDSA certificate`() {
val tmpKeyStore = tempFile("keystore.jks") val tmpKeyStore = tempFile("keystore.jks")
val ecDSAKey = generateKeyPair(Crypto.ECDSA_SECP256R1_SHA256) val ecDSAKey = generateKeyPair(Crypto.ECDSA_SECP256R1_SHA256)
val ecDSACert = createSelfSignedCACertificate(X500Name("CN=Test"), ecDSAKey) val ecDSACert = X509Utilities.createSelfSignedCACertificate(X500Name("CN=Test"), ecDSAKey)
val edDSAKeypair = generateKeyPair(EDDSA_ED25519_SHA512) val edDSAKeypair = generateKeyPair(EDDSA_ED25519_SHA512)
val edDSACert = X509Utilities.createCertificate(CertificateType.TLS, ecDSACert, ecDSAKey, X500Name("CN=TestEdDSA"), edDSAKeypair.public) val edDSACert = X509Utilities.createCertificate(CertificateType.TLS, ecDSACert, ecDSAKey, X500Name("CN=TestEdDSA"), edDSAKeypair.public)
@ -155,8 +166,8 @@ class X509UtilitiesTest {
// Now sign something with private key and verify against certificate public key // Now sign something with private key and verify against certificate public key
val testData = "12345".toByteArray() val testData = "12345".toByteArray()
val caSignature = Crypto.doSign(DEFAULT_TLS_SIGNATURE_SCHEME, rootCaPrivateKey, testData) val caSignature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, rootCaPrivateKey, testData)
assertTrue { Crypto.isValid(DEFAULT_TLS_SIGNATURE_SCHEME, rootCaCert.publicKey, caSignature, testData) } assertTrue { Crypto.isValid(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, rootCaCert.publicKey, caSignature, testData) }
// Load back generated intermediate CA Cert and private key // Load back generated intermediate CA Cert and private key
val intermediateCaCert = keyStore.getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA) as X509Certificate val intermediateCaCert = keyStore.getCertificate(X509Utilities.CORDA_INTERMEDIATE_CA) as X509Certificate
@ -165,8 +176,8 @@ class X509UtilitiesTest {
intermediateCaCert.verify(rootCaCert.publicKey) intermediateCaCert.verify(rootCaCert.publicKey)
// Now sign something with private key and verify against certificate public key // Now sign something with private key and verify against certificate public key
val intermediateSignature = Crypto.doSign(DEFAULT_TLS_SIGNATURE_SCHEME, intermediateCaCertPrivateKey, testData) val intermediateSignature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, intermediateCaCertPrivateKey, testData)
assertTrue { Crypto.isValid(DEFAULT_TLS_SIGNATURE_SCHEME, intermediateCaCert.publicKey, intermediateSignature, testData) } assertTrue { Crypto.isValid(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, intermediateCaCert.publicKey, intermediateSignature, testData) }
} }
@Test @Test
@ -209,9 +220,9 @@ class X509UtilitiesTest {
assertTrue { sslCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.commonName) } assertTrue { sslCertAndKey.certificate.subject.toString().contains(MEGA_CORP.name.commonName) }
// Now sign something with private key and verify against certificate public key // Now sign something with private key and verify against certificate public key
val testData = "123456".toByteArray() val testData = "123456".toByteArray()
val signature = Crypto.doSign(DEFAULT_TLS_SIGNATURE_SCHEME, serverCertAndKey.keyPair.private, testData) val signature = Crypto.doSign(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, serverCertAndKey.keyPair.private, testData)
val publicKey = Crypto.toSupportedPublicKey(serverCertAndKey.certificate.subjectPublicKeyInfo) val publicKey = Crypto.toSupportedPublicKey(serverCertAndKey.certificate.subjectPublicKeyInfo)
assertTrue { Crypto.isValid(DEFAULT_TLS_SIGNATURE_SCHEME, publicKey, signature, testData) } assertTrue { Crypto.isValid(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME, publicKey, signature, testData) }
} }
@Test @Test
@ -343,11 +354,11 @@ class X509UtilitiesTest {
trustStoreFilePath: Path, trustStoreFilePath: Path,
trustStorePassword: String trustStorePassword: String
): KeyStore { ): KeyStore {
val rootCAKey = generateKeyPair(DEFAULT_TLS_SIGNATURE_SCHEME) val rootCAKey = generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val rootCACert = createSelfSignedCACertificate(X509Utilities.getX509Name("Corda Node Root CA","London","demo@r3.com",null), rootCAKey) val rootCACert = X509Utilities.createSelfSignedCACertificate(getX509Name("Corda Node Root CA", "London", "demo@r3.com", null), rootCAKey)
val intermediateCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val intermediateCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, X509Utilities.getX509Name("Corda Node Intermediate CA","London","demo@r3.com",null), intermediateCAKeyPair.public) val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootCAKey, getX509Name("Corda Node Intermediate CA", "London", "demo@r3.com", null), intermediateCAKeyPair.public)
val keyPass = keyPassword.toCharArray() val keyPass = keyPassword.toCharArray()
val keyStore = loadOrCreateKeyStore(keyStoreFilePath, storePassword) val keyStore = loadOrCreateKeyStore(keyStoreFilePath, storePassword)
@ -374,7 +385,7 @@ class X509UtilitiesTest {
@Test @Test
fun `Get correct private key type from Keystore`() { fun `Get correct private key type from Keystore`() {
val keyPair = generateKeyPair(Crypto.ECDSA_SECP256R1_SHA256) val keyPair = generateKeyPair(Crypto.ECDSA_SECP256R1_SHA256)
val selfSignCert = createSelfSignedCACertificate(X500Name("CN=Test"), keyPair) val selfSignCert = X509Utilities.createSelfSignedCACertificate(X500Name("CN=Test"), keyPair)
val keyStore = loadOrCreateKeyStore(tempFile("testKeystore.jks"), "keystorepassword") val keyStore = loadOrCreateKeyStore(tempFile("testKeystore.jks"), "keystorepassword")
keyStore.setKeyEntry("Key", keyPair.private, "keypassword".toCharArray(), arrayOf(selfSignCert.cert)) keyStore.setKeyEntry("Key", keyPair.private, "keypassword".toCharArray(), arrayOf(selfSignCert.cert))
@ -384,4 +395,38 @@ class X509UtilitiesTest {
assertTrue(keyFromKeystore is java.security.interfaces.ECPrivateKey) // by default JKS returns SUN EC key assertTrue(keyFromKeystore is java.security.interfaces.ECPrivateKey) // by default JKS returns SUN EC key
assertTrue(keyFromKeystoreCasted is org.bouncycastle.jce.interfaces.ECPrivateKey) assertTrue(keyFromKeystoreCasted is org.bouncycastle.jce.interfaces.ECPrivateKey)
} }
@Test
fun `serialize - deserialize X509CertififcateHolder`() {
val factory = SerializationFactoryImpl().apply { registerScheme(KryoServerSerializationScheme()) }
val context = SerializationContextImpl(KryoHeaderV0_1,
javaClass.classLoader,
AllWhitelist,
emptyMap(),
true,
SerializationContext.UseCase.P2P)
val expected: X509CertificateHolder = X509Utilities.createSelfSignedCACertificate(ALICE.name, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME))
val serialized = expected.serialize(factory, context).bytes
val actual: X509CertificateHolder = serialized.deserialize(factory, context)
assertEquals(expected, actual)
}
@Test
fun `serialize - deserialize X509CertPath`() {
val factory = SerializationFactoryImpl().apply { registerScheme(KryoServerSerializationScheme()) }
val context = SerializationContextImpl(KryoHeaderV0_1,
javaClass.classLoader,
AllWhitelist,
emptyMap(),
true,
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 expected = certFactory.generateCertPath(listOf(certificate.cert, rootCACert.cert))
val serialized = expected.serialize(factory, context).bytes
val actual: CertPath = serialized.deserialize(factory, context)
assertEquals(expected, actual)
}
} }

View File

@ -3,9 +3,13 @@ package net.corda.node.utilities.registration
import com.nhaarman.mockito_kotlin.any import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.eq import com.nhaarman.mockito_kotlin.eq
import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.mock
import net.corda.core.crypto.* import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.cert
import net.corda.core.crypto.commonName
import net.corda.core.internal.exists import net.corda.core.internal.exists
import net.corda.core.internal.toTypedArray import net.corda.core.internal.toTypedArray
import net.corda.node.utilities.X509Utilities
import net.corda.node.utilities.loadKeyStore import net.corda.node.utilities.loadKeyStore
import net.corda.testing.ALICE import net.corda.testing.ALICE
import net.corda.testing.getTestX509Name import net.corda.testing.getTestX509Name

View File

@ -11,13 +11,15 @@ import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.IdentityService import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.OpaqueBytes
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.VerifierType import net.corda.node.services.config.VerifierType
import net.corda.node.services.config.configureDevKeyAndTrustStores import net.corda.node.services.config.configureDevKeyAndTrustStores
import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.utilities.CertificateType
import net.corda.node.utilities.X509Utilities
import net.corda.nodeapi.config.SSLConfiguration import net.corda.nodeapi.config.SSLConfiguration
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.makeTestDataSourceProperties import net.corda.testing.node.makeTestDataSourceProperties
@ -67,9 +69,9 @@ val ALICE_PUBKEY: PublicKey get() = ALICE_KEY.public
val BOB_PUBKEY: PublicKey get() = BOB_KEY.public val BOB_PUBKEY: PublicKey get() = BOB_KEY.public
val CHARLIE_PUBKEY: PublicKey get() = CHARLIE_KEY.public val CHARLIE_PUBKEY: PublicKey get() = CHARLIE_KEY.public
val MEGA_CORP_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(X509Utilities.getX509Name("MegaCorp","London","demo@r3.com",null), MEGA_CORP_PUBKEY) val MEGA_CORP_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(getX509Name("MegaCorp", "London", "demo@r3.com", null), MEGA_CORP_PUBKEY)
val MEGA_CORP: Party get() = MEGA_CORP_IDENTITY.party val MEGA_CORP: Party get() = MEGA_CORP_IDENTITY.party
val MINI_CORP_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(X509Utilities.getX509Name("MiniCorp","London","demo@r3.com",null), MINI_CORP_PUBKEY) val MINI_CORP_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(getX509Name("MiniCorp", "London", "demo@r3.com", null), MINI_CORP_PUBKEY)
val MINI_CORP: Party get() = MINI_CORP_IDENTITY.party val MINI_CORP: Party get() = MINI_CORP_IDENTITY.party
val BOC_KEY: KeyPair by lazy { generateKeyPair() } val BOC_KEY: KeyPair by lazy { generateKeyPair() }
@ -80,7 +82,7 @@ val BOC_PARTY_REF = BOC.ref(OpaqueBytes.of(1)).reference
val BIG_CORP_KEY: KeyPair by lazy { generateKeyPair() } val BIG_CORP_KEY: KeyPair by lazy { generateKeyPair() }
val BIG_CORP_PUBKEY: PublicKey get() = BIG_CORP_KEY.public val BIG_CORP_PUBKEY: PublicKey get() = BIG_CORP_KEY.public
val BIG_CORP_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(X509Utilities.getX509Name("BigCorporation","London","demo@r3.com",null), BIG_CORP_PUBKEY) val BIG_CORP_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(getX509Name("BigCorporation", "London", "demo@r3.com", null), BIG_CORP_PUBKEY)
val BIG_CORP: Party get() = BIG_CORP_IDENTITY.party val BIG_CORP: Party get() = BIG_CORP_IDENTITY.party
val BIG_CORP_PARTY_REF = BIG_CORP.ref(OpaqueBytes.of(1)).reference val BIG_CORP_PARTY_REF = BIG_CORP.ref(OpaqueBytes.of(1)).reference

View File

@ -4,7 +4,9 @@ package net.corda.testing
import net.corda.core.contracts.Command import net.corda.core.contracts.Command
import net.corda.core.contracts.TypeOnlyCommandData import net.corda.core.contracts.TypeOnlyCommandData
import net.corda.core.crypto.* import net.corda.core.crypto.CertificateAndKeyPair
import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.testing.DummyPublicKey import net.corda.core.crypto.testing.DummyPublicKey
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
@ -12,6 +14,7 @@ import net.corda.core.internal.concurrent.transpose
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.ServiceInfo
import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.node.utilities.X509Utilities
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.driver.DriverDSLExposedInterface import net.corda.testing.driver.DriverDSLExposedInterface
import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.asn1.x500.X500Name

View File

@ -11,12 +11,12 @@ import net.corda.cordform.CordformNode
import net.corda.cordform.NodeDefinition import net.corda.cordform.NodeDefinition
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.concurrent.firstOf import net.corda.core.concurrent.firstOf
import net.corda.core.crypto.X509Utilities
import net.corda.core.crypto.appendToCommonName import net.corda.core.crypto.appendToCommonName
import net.corda.core.crypto.commonName import net.corda.core.crypto.commonName
import net.corda.core.crypto.getX509Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.*
import net.corda.core.internal.ThreadBox import net.corda.core.internal.ThreadBox
import net.corda.core.internal.concurrent.*
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.times import net.corda.core.internal.times
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
@ -53,9 +53,12 @@ import java.time.Instant
import java.time.ZoneOffset.UTC import java.time.ZoneOffset.UTC
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.* import java.util.*
import java.util.concurrent.* import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit.MILLISECONDS import java.util.concurrent.TimeUnit.MILLISECONDS
import java.util.concurrent.TimeUnit.SECONDS import java.util.concurrent.TimeUnit.SECONDS
import java.util.concurrent.TimeoutException
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import kotlin.concurrent.thread import kotlin.concurrent.thread
@ -566,7 +569,7 @@ class DriverDSL(
val rpcAddress = portAllocation.nextHostAndPort() val rpcAddress = portAllocation.nextHostAndPort()
val webAddress = portAllocation.nextHostAndPort() val webAddress = portAllocation.nextHostAndPort()
// TODO: Derive name from the full picked name, don't just wrap the common name // TODO: Derive name from the full picked name, don't just wrap the common name
val name = providedName ?: X509Utilities.getX509Name("${oneOf(names).commonName}-${p2pAddress.port}","London","demo@r3.com",null) val name = providedName ?: getX509Name("${oneOf(names).commonName}-${p2pAddress.port}", "London", "demo@r3.com", null)
val networkMapServiceConfigLookup = networkMapServiceConfigLookup(listOf(object : NodeDefinition { val networkMapServiceConfigLookup = networkMapServiceConfigLookup(listOf(object : NodeDefinition {
override fun getName() = name.toString() override fun getName() = name.toString()
override fun getConfig() = configOf("p2pAddress" to p2pAddress.toString()) override fun getConfig() = configOf("p2pAddress" to p2pAddress.toString())

View File

@ -3,8 +3,8 @@ package net.corda.testing.node
import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.SettableFuture import com.google.common.util.concurrent.SettableFuture
import net.corda.core.crypto.getX509Name
import net.corda.core.internal.ThreadBox import net.corda.core.internal.ThreadBox
import net.corda.core.crypto.X509Utilities
import net.corda.core.messaging.AllPossibleRecipients import net.corda.core.messaging.AllPossibleRecipients
import net.corda.core.messaging.MessageRecipientGroup import net.corda.core.messaging.MessageRecipientGroup
import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.MessageRecipients
@ -128,7 +128,7 @@ class InMemoryMessagingNetwork(
id: Int, id: Int,
executor: AffinityExecutor, executor: AffinityExecutor,
advertisedServices: List<ServiceEntry>, advertisedServices: List<ServiceEntry>,
description: X500Name = X509Utilities.getX509Name("In memory node $id","London","demo@r3.com",null), description: X500Name = getX509Name("In memory node $id", "London", "demo@r3.com", null),
database: CordaPersistence) database: CordaPersistence)
: MessagingServiceBuilder<InMemoryMessaging> { : MessagingServiceBuilder<InMemoryMessaging> {
val peerHandle = PeerHandle(id, description) val peerHandle = PeerHandle(id, description)

View File

@ -1,10 +1,13 @@
package net.corda.testing.node package net.corda.testing.node
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.X509Utilities
import net.corda.core.crypto.appendToCommonName import net.corda.core.crypto.appendToCommonName
import net.corda.core.crypto.commonName import net.corda.core.crypto.commonName
import net.corda.core.internal.concurrent.* import net.corda.core.crypto.getX509Name
import net.corda.core.internal.concurrent.flatMap
import net.corda.core.internal.concurrent.fork
import net.corda.core.internal.concurrent.map
import net.corda.core.internal.concurrent.transpose
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.ServiceInfo
@ -120,13 +123,13 @@ abstract class NodeBasedTest : TestDependencyInjectionBase() {
val nodeAddresses = getFreeLocalPorts("localhost", clusterSize).map { it.toString() } val nodeAddresses = getFreeLocalPorts("localhost", clusterSize).map { it.toString() }
val masterNodeFuture = startNode( val masterNodeFuture = startNode(
X509Utilities.getX509Name("${notaryName.commonName}-0","London","demo@r3.com",null), getX509Name("${notaryName.commonName}-0", "London", "demo@r3.com", null),
advertisedServices = setOf(serviceInfo), advertisedServices = setOf(serviceInfo),
configOverrides = mapOf("notaryNodeAddress" to nodeAddresses[0])) configOverrides = mapOf("notaryNodeAddress" to nodeAddresses[0]))
val remainingNodesFutures = (1 until clusterSize).map { val remainingNodesFutures = (1 until clusterSize).map {
startNode( startNode(
X509Utilities.getX509Name("${notaryName.commonName}-$it","London","demo@r3.com",null), getX509Name("${notaryName.commonName}-$it", "London", "demo@r3.com", null),
advertisedServices = setOf(serviceInfo), advertisedServices = setOf(serviceInfo),
configOverrides = mapOf( configOverrides = mapOf(
"notaryNodeAddress" to nodeAddresses[it], "notaryNodeAddress" to nodeAddresses[it],

View File

@ -1,6 +1,6 @@
package net.corda.demobench.model package net.corda.demobench.model
import net.corda.core.crypto.X509Utilities.getX509Name import net.corda.core.crypto.getX509Name
import net.corda.demobench.plugin.PluginController import net.corda.demobench.plugin.PluginController
import net.corda.demobench.pty.R3Pty import net.corda.demobench.pty.R3Pty
import tornadofx.* import tornadofx.*

View File

@ -1,8 +1,8 @@
package net.corda.demobench.model package net.corda.demobench.model
import net.corda.core.crypto.X509Utilities.getX509Name import net.corda.core.crypto.getX509Name
import net.corda.testing.DUMMY_NOTARY
import net.corda.nodeapi.User import net.corda.nodeapi.User
import net.corda.testing.DUMMY_NOTARY
import org.junit.Test import org.junit.Test
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths

View File

@ -3,7 +3,6 @@ package net.corda.verifier
import net.corda.client.mock.* import net.corda.client.mock.*
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.X509Utilities
import net.corda.core.crypto.entropyToKeyPair import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.sha256 import net.corda.core.crypto.sha256
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
@ -12,6 +11,7 @@ import net.corda.core.identity.Party
import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.WireTransaction import net.corda.core.transactions.WireTransaction
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.getTestX509Name
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.math.BigInteger import java.math.BigInteger
import java.security.PublicKey import java.security.PublicKey
@ -179,7 +179,7 @@ fun commandGenerator(partiesToPickFrom: Collection<Party>): Generator<Pair<Comma
} }
val partyGenerator: Generator<Party> = Generator.int().combine(publicKeyGenerator) { n, key -> val partyGenerator: Generator<Party> = Generator.int().combine(publicKeyGenerator) { n, key ->
Party(X509Utilities.getDevX509Name("Party$n"), key) Party(getTestX509Name("Party$n"), key)
} }
fun <A> pickOneOrMaybeNew(from: Collection<A>, generator: Generator<A>): Generator<A> { fun <A> pickOneOrMaybeNew(from: Collection<A>, generator: Generator<A>): Generator<A> {

View File

@ -2,15 +2,13 @@ package net.corda.verifier
import com.typesafe.config.Config import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import net.corda.core.concurrent.* import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.X509Utilities
import net.corda.core.crypto.commonName import net.corda.core.crypto.commonName
import net.corda.core.internal.div
import net.corda.core.crypto.random63BitValue import net.corda.core.crypto.random63BitValue
import net.corda.core.internal.concurrent.* import net.corda.core.internal.concurrent.*
import net.corda.core.internal.div
import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.LedgerTransaction
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.testing.driver.ProcessUtilities
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.node.services.config.configureDevKeyAndTrustStores import net.corda.node.services.config.configureDevKeyAndTrustStores
import net.corda.nodeapi.ArtemisMessagingComponent.Companion.NODE_USER import net.corda.nodeapi.ArtemisMessagingComponent.Companion.NODE_USER
@ -20,6 +18,7 @@ import net.corda.nodeapi.VerifierApi
import net.corda.nodeapi.config.NodeSSLConfiguration import net.corda.nodeapi.config.NodeSSLConfiguration
import net.corda.nodeapi.config.SSLConfiguration import net.corda.nodeapi.config.SSLConfiguration
import net.corda.testing.driver.* import net.corda.testing.driver.*
import net.corda.testing.getTestX509Name
import org.apache.activemq.artemis.api.core.SimpleString import org.apache.activemq.artemis.api.core.SimpleString
import org.apache.activemq.artemis.api.core.client.ActiveMQClient import org.apache.activemq.artemis.api.core.client.ActiveMQClient
import org.apache.activemq.artemis.api.core.client.ClientProducer import org.apache.activemq.artemis.api.core.client.ClientProducer
@ -250,7 +249,7 @@ data class VerifierDriverDSL(
val id = verifierCount.andIncrement val id = verifierCount.andIncrement
val jdwpPort = if (driverDSL.isDebug) driverDSL.debugPortAllocation.nextPort() else null val jdwpPort = if (driverDSL.isDebug) driverDSL.debugPortAllocation.nextPort() else null
val processFuture = driverDSL.executorService.fork { val processFuture = driverDSL.executorService.fork {
val verifierName = X509Utilities.getDevX509Name("verifier$id") val verifierName = getTestX509Name("verifier$id")
val baseDirectory = driverDSL.driverDirectory / verifierName.commonName val baseDirectory = driverDSL.driverDirectory / verifierName.commonName
val config = createConfiguration(baseDirectory, address) val config = createConfiguration(baseDirectory, address)
val configFilename = "verifier.conf" val configFilename = "verifier.conf"