mirror of
https://github.com/corda/corda.git
synced 2025-06-01 15:10:54 +00:00
ENT-9583 Public key caching of encoded form (OS) (#7332)
This commit is contained in:
parent
f4917e08e1
commit
9ba3919980
@ -82,6 +82,7 @@ def patchCore = tasks.register('patchCore', Zip) {
|
|||||||
exclude 'net/corda/core/serialization/internal/CheckpointSerializationFactory*.class'
|
exclude 'net/corda/core/serialization/internal/CheckpointSerializationFactory*.class'
|
||||||
exclude 'net/corda/core/internal/rules/*.class'
|
exclude 'net/corda/core/internal/rules/*.class'
|
||||||
exclude 'net/corda/core/internal/utilities/PrivateInterner*.class'
|
exclude 'net/corda/core/internal/utilities/PrivateInterner*.class'
|
||||||
|
exclude 'net/corda/core/crypto/internal/PublicKeyCache*.class'
|
||||||
exclude 'net/corda/core/internal/ContractStateClassCache*.class'
|
exclude 'net/corda/core/internal/ContractStateClassCache*.class'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package net.corda.core.crypto.internal
|
||||||
|
|
||||||
|
import net.corda.core.utilities.ByteSequence
|
||||||
|
import java.security.PublicKey
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
object PublicKeyCache {
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
|
fun bytesForCachedPublicKey(key: PublicKey): ByteSequence? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
|
fun publicKeyForCachedBytes(bytes: ByteSequence): PublicKey? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cachePublicKey(key: PublicKey): PublicKey {
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,14 @@ import net.corda.core.KeepForDJVM
|
|||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.core.utilities.exactAdd
|
import net.corda.core.utilities.exactAdd
|
||||||
import net.corda.core.utilities.sequence
|
import net.corda.core.utilities.sequence
|
||||||
import org.bouncycastle.asn1.*
|
import org.bouncycastle.asn1.ASN1EncodableVector
|
||||||
|
import org.bouncycastle.asn1.ASN1Encoding
|
||||||
|
import org.bouncycastle.asn1.ASN1Integer
|
||||||
|
import org.bouncycastle.asn1.ASN1Object
|
||||||
|
import org.bouncycastle.asn1.ASN1Primitive
|
||||||
|
import org.bouncycastle.asn1.ASN1Sequence
|
||||||
|
import org.bouncycastle.asn1.DERBitString
|
||||||
|
import org.bouncycastle.asn1.DERSequence
|
||||||
import org.bouncycastle.asn1.x509.AlgorithmIdentifier
|
import org.bouncycastle.asn1.x509.AlgorithmIdentifier
|
||||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
@ -162,7 +169,7 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
|
|||||||
|
|
||||||
override fun toASN1Primitive(): ASN1Primitive {
|
override fun toASN1Primitive(): ASN1Primitive {
|
||||||
val vector = ASN1EncodableVector()
|
val vector = ASN1EncodableVector()
|
||||||
vector.add(DERBitString(node.encoded))
|
vector.add(DERBitString(Crypto.encodePublicKey(node)))
|
||||||
vector.add(ASN1Integer(weight.toLong()))
|
vector.add(ASN1Integer(weight.toLong()))
|
||||||
return DERSequence(vector)
|
return DERSequence(vector)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import net.corda.core.DeleteForDJVM
|
|||||||
import net.corda.core.KeepForDJVM
|
import net.corda.core.KeepForDJVM
|
||||||
import net.corda.core.crypto.internal.AliasPrivateKey
|
import net.corda.core.crypto.internal.AliasPrivateKey
|
||||||
import net.corda.core.crypto.internal.Instances.withSignature
|
import net.corda.core.crypto.internal.Instances.withSignature
|
||||||
|
import net.corda.core.crypto.internal.PublicKeyCache
|
||||||
import net.corda.core.crypto.internal.bouncyCastlePQCProvider
|
import net.corda.core.crypto.internal.bouncyCastlePQCProvider
|
||||||
import net.corda.core.crypto.internal.cordaBouncyCastleProvider
|
import net.corda.core.crypto.internal.cordaBouncyCastleProvider
|
||||||
import net.corda.core.crypto.internal.cordaSecurityProvider
|
import net.corda.core.crypto.internal.cordaSecurityProvider
|
||||||
@ -12,6 +13,7 @@ import net.corda.core.crypto.internal.`id-Curve25519ph`
|
|||||||
import net.corda.core.crypto.internal.providerMap
|
import net.corda.core.crypto.internal.providerMap
|
||||||
import net.corda.core.internal.utilities.PrivateInterner
|
import net.corda.core.internal.utilities.PrivateInterner
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
|
import net.corda.core.utilities.ByteSequence
|
||||||
import net.i2p.crypto.eddsa.EdDSAEngine
|
import net.i2p.crypto.eddsa.EdDSAEngine
|
||||||
import net.i2p.crypto.eddsa.EdDSAPrivateKey
|
import net.i2p.crypto.eddsa.EdDSAPrivateKey
|
||||||
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
||||||
@ -281,7 +283,7 @@ object Crypto {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun findSignatureScheme(key: PublicKey): SignatureScheme {
|
fun findSignatureScheme(key: PublicKey): SignatureScheme {
|
||||||
val keyInfo = SubjectPublicKeyInfo.getInstance(key.encoded)
|
val keyInfo = SubjectPublicKeyInfo.getInstance(encodePublicKey(key))
|
||||||
return findSignatureScheme(keyInfo.algorithm)
|
return findSignatureScheme(keyInfo.algorithm)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,10 +375,17 @@ object Crypto {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun decodePublicKey(encodedKey: ByteArray): PublicKey {
|
fun decodePublicKey(encodedKey: ByteArray): PublicKey {
|
||||||
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(encodedKey)
|
return PublicKeyCache.publicKeyForCachedBytes(ByteSequence.of(encodedKey)) ?: {
|
||||||
val signatureScheme = findSignatureScheme(subjectPublicKeyInfo.algorithm)
|
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(encodedKey)
|
||||||
val keyFactory = keyFactory(signatureScheme)
|
val signatureScheme = findSignatureScheme(subjectPublicKeyInfo.algorithm)
|
||||||
return convertIfBCEdDSAPublicKey(keyFactory.generatePublic(X509EncodedKeySpec(encodedKey)))
|
val keyFactory = keyFactory(signatureScheme)
|
||||||
|
convertIfBCEdDSAPublicKey(keyFactory.generatePublic(X509EncodedKeySpec(encodedKey)))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun encodePublicKey(key: PublicKey): ByteArray {
|
||||||
|
return PublicKeyCache.bytesForCachedPublicKey(key)?.bytes ?: key.encoded
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -993,7 +1002,8 @@ object Crypto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val interner = PrivateInterner<PublicKey>()
|
private val interner = PrivateInterner<PublicKey>()
|
||||||
private fun internPublicKey(key: PublicKey): PublicKey = interner.intern(key)
|
private fun internPublicKey(key: PublicKey): PublicKey = PublicKeyCache.cachePublicKey(interner.intern(key))
|
||||||
|
|
||||||
|
|
||||||
private fun convertIfBCEdDSAPublicKey(key: PublicKey): PublicKey {
|
private fun convertIfBCEdDSAPublicKey(key: PublicKey): PublicKey {
|
||||||
return internPublicKey(when (key) {
|
return internPublicKey(when (key) {
|
||||||
|
@ -13,7 +13,6 @@ import net.corda.core.serialization.CordaSerializable
|
|||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.parseAsHex
|
import net.corda.core.utilities.parseAsHex
|
||||||
import net.corda.core.utilities.toHexString
|
import net.corda.core.utilities.toHexString
|
||||||
import java.nio.ByteBuffer
|
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.ConcurrentMap
|
import java.util.concurrent.ConcurrentMap
|
||||||
@ -39,9 +38,10 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an efficient hashCode, because there is no point in performing a hash calculation on a cryptographic hash.
|
override fun hashCode(): Int {
|
||||||
// It just takes the first 4 bytes and transforms them into an Int.
|
// Hash code not overridden on purpose (super class impl will do), but don't delete or have to deal with detekt and API checker.
|
||||||
override fun hashCode() = ByteBuffer.wrap(bytes).int
|
return super.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the hash value to an uppercase hexadecimal [String].
|
* Convert the hash value to an uppercase hexadecimal [String].
|
||||||
@ -62,7 +62,10 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode() = ByteBuffer.wrap(bytes).int
|
override fun hashCode(): Int {
|
||||||
|
// Hash code not overridden on purpose (super class impl will do), but don't delete or have to deal with detekt and API checker.
|
||||||
|
return super.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "$algorithm$DELIMITER${toHexString()}"
|
return "$algorithm$DELIMITER${toHexString()}"
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
package net.corda.core.crypto.internal
|
||||||
|
|
||||||
|
import net.corda.core.utilities.ByteSequence
|
||||||
|
import java.lang.ref.ReferenceQueue
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
import java.security.PublicKey
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
object PublicKeyCache {
|
||||||
|
private val collectedWeakPubKeys = ReferenceQueue<PublicKey>()
|
||||||
|
|
||||||
|
private class WeakPubKey(key: PublicKey, val bytes: ByteSequence? = null) : WeakReference<PublicKey>(key, collectedWeakPubKeys) {
|
||||||
|
private val hashCode = key.hashCode()
|
||||||
|
|
||||||
|
override fun hashCode(): Int = hashCode
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if(this === other) return true
|
||||||
|
if(other !is WeakPubKey) return false
|
||||||
|
if(this.hashCode != other.hashCode) return false
|
||||||
|
val thisGet = this.get()
|
||||||
|
val otherGet = other.get()
|
||||||
|
if(thisGet == null || otherGet == null) return false
|
||||||
|
return thisGet == otherGet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val pubKeyToBytes = ConcurrentHashMap<WeakPubKey, ByteSequence>()
|
||||||
|
private val bytesToPubKey = ConcurrentHashMap<ByteSequence, WeakPubKey>()
|
||||||
|
|
||||||
|
private fun reapCollectedWeakPubKeys() {
|
||||||
|
while(true) {
|
||||||
|
val weakPubKey = (collectedWeakPubKeys.poll() as? WeakPubKey) ?: break
|
||||||
|
pubKeyToBytes.remove(weakPubKey)
|
||||||
|
bytesToPubKey.remove(weakPubKey.bytes!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bytesForCachedPublicKey(key: PublicKey): ByteSequence? {
|
||||||
|
val weakPubKey = WeakPubKey(key)
|
||||||
|
return pubKeyToBytes[weakPubKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun publicKeyForCachedBytes(bytes: ByteSequence): PublicKey? {
|
||||||
|
return bytesToPubKey[bytes]?.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cachePublicKey(key: PublicKey): PublicKey {
|
||||||
|
reapCollectedWeakPubKeys()
|
||||||
|
val weakPubKey = WeakPubKey(key, ByteSequence.of(key.encoded))
|
||||||
|
pubKeyToBytes.putIfAbsent(weakPubKey, weakPubKey.bytes!!)
|
||||||
|
bytesToPubKey.putIfAbsent(weakPubKey.bytes, weakPubKey)
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
}
|
@ -555,7 +555,7 @@ fun <T : Any> SerializedBytes<T>.sign(keyPair: KeyPair): SignedData<T> = SignedD
|
|||||||
|
|
||||||
fun ByteBuffer.copyBytes(): ByteArray = ByteArray(remaining()).also { get(it) }
|
fun ByteBuffer.copyBytes(): ByteArray = ByteArray(remaining()).also { get(it) }
|
||||||
|
|
||||||
val PublicKey.hash: SecureHash get() = encoded.sha256()
|
val PublicKey.hash: SecureHash get() = Crypto.encodePublicKey(this).sha256()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension method for providing a sumBy method that processes and returns a Long
|
* Extension method for providing a sumBy method that processes and returns a Long
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
package net.corda.core.internal
|
package net.corda.core.internal
|
||||||
|
|
||||||
import net.corda.core.DeleteForDJVM
|
import net.corda.core.DeleteForDJVM
|
||||||
|
import net.corda.core.crypto.Crypto
|
||||||
import net.i2p.crypto.eddsa.EdDSAEngine
|
import net.i2p.crypto.eddsa.EdDSAEngine
|
||||||
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
||||||
import java.security.*
|
import java.security.AlgorithmParameters
|
||||||
|
import java.security.InvalidKeyException
|
||||||
|
import java.security.MessageDigest
|
||||||
|
import java.security.PrivateKey
|
||||||
|
import java.security.PublicKey
|
||||||
|
import java.security.SecureRandom
|
||||||
|
import java.security.Signature
|
||||||
import java.security.spec.AlgorithmParameterSpec
|
import java.security.spec.AlgorithmParameterSpec
|
||||||
import java.security.spec.X509EncodedKeySpec
|
import java.security.spec.X509EncodedKeySpec
|
||||||
|
|
||||||
@ -30,7 +37,7 @@ class X509EdDSAEngine : Signature {
|
|||||||
|
|
||||||
override fun engineInitVerify(publicKey: PublicKey) {
|
override fun engineInitVerify(publicKey: PublicKey) {
|
||||||
val parsedKey = try {
|
val parsedKey = try {
|
||||||
publicKey as? EdDSAPublicKey ?: EdDSAPublicKey(X509EncodedKeySpec(publicKey.encoded))
|
publicKey as? EdDSAPublicKey ?: EdDSAPublicKey(X509EncodedKeySpec(Crypto.encodePublicKey(publicKey)))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw (InvalidKeyException(e.message))
|
throw (InvalidKeyException(e.message))
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
|
|||||||
fun data(): ByteArray? {
|
fun data(): ByteArray? {
|
||||||
return when (type()) {
|
return when (type()) {
|
||||||
Type.HASH -> (constraint as HashAttachmentConstraint).attachmentId.bytes
|
Type.HASH -> (constraint as HashAttachmentConstraint).attachmentId.bytes
|
||||||
Type.SIGNATURE -> (constraint as SignatureAttachmentConstraint).key.encoded
|
Type.SIGNATURE -> Crypto.encodePublicKey((constraint as SignatureAttachmentConstraint).key)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ sealed class ByteSequence(private val _bytes: ByteArray, val offset: Int, val si
|
|||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other !is ByteSequence) return false
|
if (other !is ByteSequence) return false
|
||||||
if (this.size != other.size) return false
|
if (this.size != other.size) return false
|
||||||
|
if (this.hashCode() != other.hashCode()) return false
|
||||||
return subArraysEqual(this._bytes, this.offset, this.size, other._bytes, other.offset)
|
return subArraysEqual(this._bytes, this.offset, this.size, other._bytes, other.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,13 +126,18 @@ sealed class ByteSequence(private val _bytes: ByteArray, val offset: Int, val si
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var _hashCode: Int = 0;
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
val thisBytes = _bytes
|
return if (_hashCode == 0) {
|
||||||
var result = 1
|
val thisBytes = _bytes
|
||||||
for (index in offset until (offset + size)) {
|
var result = 1
|
||||||
result = 31 * result + thisBytes[index]
|
for (index in offset until (offset + size)) {
|
||||||
}
|
result = 31 * result + thisBytes[index]
|
||||||
return result
|
}
|
||||||
|
_hashCode = result
|
||||||
|
result
|
||||||
|
} else _hashCode
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = "[${copyBytes().toHexString()}]"
|
override fun toString(): String = "[${copyBytes().toHexString()}]"
|
||||||
|
@ -9,7 +9,7 @@ import net.corda.core.crypto.Crypto
|
|||||||
import net.corda.core.internal.hash
|
import net.corda.core.internal.hash
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.util.*
|
import java.util.Base64
|
||||||
|
|
||||||
// This file includes useful encoding methods and extension functions for the most common encoding/decoding operations.
|
// This file includes useful encoding methods and extension functions for the most common encoding/decoding operations.
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ fun String.hexToBase64(): String = hexToByteArray().toBase64()
|
|||||||
fun parsePublicKeyBase58(base58String: String): PublicKey = Crypto.decodePublicKey(base58String.base58ToByteArray())
|
fun parsePublicKeyBase58(base58String: String): PublicKey = Crypto.decodePublicKey(base58String.base58ToByteArray())
|
||||||
|
|
||||||
/** Return the Base58 representation of the serialised public key. */
|
/** Return the Base58 representation of the serialised public key. */
|
||||||
fun PublicKey.toBase58String(): String = this.encoded.toBase58()
|
fun PublicKey.toBase58String(): String = Crypto.encodePublicKey(this).toBase58()
|
||||||
|
|
||||||
/** Return the bytes of the SHA-256 output for this public key. */
|
/** Return the bytes of the SHA-256 output for this public key. */
|
||||||
fun PublicKey.toSHA256Bytes(): ByteArray = this.hash.bytes
|
fun PublicKey.toSHA256Bytes(): ByteArray = this.hash.bytes
|
||||||
|
@ -3,14 +3,33 @@ package net.corda.nodeapi.internal.crypto
|
|||||||
import net.corda.core.CordaOID
|
import net.corda.core.CordaOID
|
||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.newSecureRandom
|
import net.corda.core.crypto.newSecureRandom
|
||||||
import net.corda.core.internal.*
|
import net.corda.core.internal.CertRole
|
||||||
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
|
import net.corda.core.internal.reader
|
||||||
|
import net.corda.core.internal.signWithCert
|
||||||
|
import net.corda.core.internal.uncheckedCast
|
||||||
|
import net.corda.core.internal.validate
|
||||||
|
import net.corda.core.internal.writer
|
||||||
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.*
|
import org.bouncycastle.asn1.ASN1EncodableVector
|
||||||
|
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
||||||
|
import org.bouncycastle.asn1.ASN1Sequence
|
||||||
|
import org.bouncycastle.asn1.DERSequence
|
||||||
|
import org.bouncycastle.asn1.DERUTF8String
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.bouncycastle.asn1.x500.style.BCStyle
|
import org.bouncycastle.asn1.x500.style.BCStyle
|
||||||
import org.bouncycastle.asn1.x509.*
|
import org.bouncycastle.asn1.x509.BasicConstraints
|
||||||
|
import org.bouncycastle.asn1.x509.CRLDistPoint
|
||||||
|
import org.bouncycastle.asn1.x509.DistributionPoint
|
||||||
|
import org.bouncycastle.asn1.x509.DistributionPointName
|
||||||
import org.bouncycastle.asn1.x509.Extension
|
import org.bouncycastle.asn1.x509.Extension
|
||||||
|
import org.bouncycastle.asn1.x509.GeneralName
|
||||||
|
import org.bouncycastle.asn1.x509.GeneralNames
|
||||||
|
import org.bouncycastle.asn1.x509.KeyPurposeId
|
||||||
|
import org.bouncycastle.asn1.x509.KeyUsage
|
||||||
|
import org.bouncycastle.asn1.x509.NameConstraints
|
||||||
|
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
||||||
import org.bouncycastle.cert.X509CertificateHolder
|
import org.bouncycastle.cert.X509CertificateHolder
|
||||||
import org.bouncycastle.cert.X509v3CertificateBuilder
|
import org.bouncycastle.cert.X509v3CertificateBuilder
|
||||||
import org.bouncycastle.cert.bc.BcX509ExtensionUtils
|
import org.bouncycastle.cert.bc.BcX509ExtensionUtils
|
||||||
@ -28,12 +47,18 @@ import java.nio.file.Path
|
|||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.security.SignatureException
|
import java.security.SignatureException
|
||||||
import java.security.cert.*
|
import java.security.cert.CertPath
|
||||||
import java.security.cert.Certificate
|
import java.security.cert.Certificate
|
||||||
|
import java.security.cert.CertificateException
|
||||||
|
import java.security.cert.CertificateFactory
|
||||||
|
import java.security.cert.TrustAnchor
|
||||||
|
import java.security.cert.X509CRL
|
||||||
|
import java.security.cert.X509Certificate
|
||||||
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
|
||||||
import java.util.*
|
import java.util.ArrayList
|
||||||
|
import java.util.Date
|
||||||
import javax.security.auth.x500.X500Principal
|
import javax.security.auth.x500.X500Principal
|
||||||
import kotlin.experimental.and
|
import kotlin.experimental.and
|
||||||
import kotlin.experimental.or
|
import kotlin.experimental.or
|
||||||
@ -189,7 +214,7 @@ object X509Utilities {
|
|||||||
crlIssuer: X500Name? = null): X509v3CertificateBuilder {
|
crlIssuer: X500Name? = null): X509v3CertificateBuilder {
|
||||||
val serial = generateCertificateSerialNumber()
|
val serial = generateCertificateSerialNumber()
|
||||||
val keyPurposes = DERSequence(ASN1EncodableVector().apply { certificateType.purposes.forEach { add(it) } })
|
val keyPurposes = DERSequence(ASN1EncodableVector().apply { certificateType.purposes.forEach { add(it) } })
|
||||||
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(subjectPublicKey.encoded))
|
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(Crypto.encodePublicKey(subjectPublicKey)))
|
||||||
val role = certificateType.role
|
val role = certificateType.role
|
||||||
|
|
||||||
val builder = JcaX509v3CertificateBuilder(issuer, serial, validityWindow.first, validityWindow.second, subject, subjectPublicKey)
|
val builder = JcaX509v3CertificateBuilder(issuer, serial, validityWindow.first, validityWindow.second, subject, subjectPublicKey)
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package net.corda.nodeapi.internal.serialization.kryo
|
package net.corda.nodeapi.internal.serialization.kryo
|
||||||
|
|
||||||
import com.esotericsoftware.kryo.*
|
import com.esotericsoftware.kryo.ClassResolver
|
||||||
|
import com.esotericsoftware.kryo.Kryo
|
||||||
|
import com.esotericsoftware.kryo.KryoException
|
||||||
|
import com.esotericsoftware.kryo.Registration
|
||||||
|
import com.esotericsoftware.kryo.Serializer
|
||||||
import com.esotericsoftware.kryo.factories.ReflectionSerializerFactory
|
import com.esotericsoftware.kryo.factories.ReflectionSerializerFactory
|
||||||
import com.esotericsoftware.kryo.io.Input
|
import com.esotericsoftware.kryo.io.Input
|
||||||
import com.esotericsoftware.kryo.io.Output
|
import com.esotericsoftware.kryo.io.Output
|
||||||
@ -17,7 +21,13 @@ import net.corda.core.internal.LazyMappedList
|
|||||||
import net.corda.core.internal.uncheckedCast
|
import net.corda.core.internal.uncheckedCast
|
||||||
import net.corda.core.serialization.SerializeAsTokenContext
|
import net.corda.core.serialization.SerializeAsTokenContext
|
||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.transactions.*
|
import net.corda.core.transactions.ComponentGroup
|
||||||
|
import net.corda.core.transactions.ContractUpgradeFilteredTransaction
|
||||||
|
import net.corda.core.transactions.ContractUpgradeWireTransaction
|
||||||
|
import net.corda.core.transactions.CoreTransaction
|
||||||
|
import net.corda.core.transactions.NotaryChangeWireTransaction
|
||||||
|
import net.corda.core.transactions.SignedTransaction
|
||||||
|
import net.corda.core.transactions.WireTransaction
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.SgxSupport
|
import net.corda.core.utilities.SgxSupport
|
||||||
import net.corda.serialization.internal.serializationContextKey
|
import net.corda.serialization.internal.serializationContextKey
|
||||||
@ -302,7 +312,7 @@ object PrivateKeySerializer : Serializer<PrivateKey>() {
|
|||||||
object PublicKeySerializer : Serializer<PublicKey>() {
|
object PublicKeySerializer : Serializer<PublicKey>() {
|
||||||
override fun write(kryo: Kryo, output: Output, obj: PublicKey) {
|
override fun write(kryo: Kryo, output: Output, obj: PublicKey) {
|
||||||
// TODO: Instead of encoding to the default X509 format, we could have a custom per key type (space-efficient) serialiser.
|
// TODO: Instead of encoding to the default X509 format, we could have a custom per key type (space-efficient) serialiser.
|
||||||
output.writeBytesWithLength(obj.encoded)
|
output.writeBytesWithLength(Crypto.encodePublicKey(obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(kryo: Kryo, input: Input, type: Class<PublicKey>): PublicKey {
|
override fun read(kryo: Kryo, input: Input, type: Class<PublicKey>): PublicKey {
|
||||||
|
@ -47,7 +47,9 @@ import java.security.cert.CertificateNotYetValidException
|
|||||||
import java.security.cert.CollectionCertStoreParameters
|
import java.security.cert.CollectionCertStoreParameters
|
||||||
import java.security.cert.TrustAnchor
|
import java.security.cert.TrustAnchor
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import java.util.*
|
import java.util.HashSet
|
||||||
|
import java.util.Optional
|
||||||
|
import java.util.UUID
|
||||||
import java.util.concurrent.ExecutorService
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
@ -136,7 +138,7 @@ class PersistentIdentityService(cacheFactory: NamedCacheFactory) : SingletonSeri
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
toPersistentEntity = { key: String, value: PublicKey ->
|
toPersistentEntity = { key: String, value: PublicKey ->
|
||||||
PersistentHashToPublicKey(key, value.encoded)
|
PersistentHashToPublicKey(key, Crypto.encodePublicKey(value))
|
||||||
},
|
},
|
||||||
persistentEntityClass = PersistentHashToPublicKey::class.java)
|
persistentEntityClass = PersistentHashToPublicKey::class.java)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
package net.corda.node.services.keys
|
package net.corda.node.services.keys
|
||||||
|
|
||||||
import net.corda.core.crypto.*
|
import net.corda.core.crypto.Crypto
|
||||||
|
import net.corda.core.crypto.DigitalSignature
|
||||||
|
import net.corda.core.crypto.SignableData
|
||||||
|
import net.corda.core.crypto.SignatureScheme
|
||||||
|
import net.corda.core.crypto.TransactionSignature
|
||||||
|
import net.corda.core.crypto.generateKeyPair
|
||||||
|
import net.corda.core.crypto.keys
|
||||||
|
import net.corda.core.crypto.sign
|
||||||
|
import net.corda.core.crypto.toStringShort
|
||||||
import net.corda.core.internal.NamedCacheFactory
|
import net.corda.core.internal.NamedCacheFactory
|
||||||
import net.corda.core.internal.telemetry.TelemetryServiceImpl
|
import net.corda.core.internal.telemetry.TelemetryServiceImpl
|
||||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||||
@ -16,9 +24,12 @@ import org.bouncycastle.operator.ContentSigner
|
|||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
import java.security.PrivateKey
|
import java.security.PrivateKey
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
import javax.persistence.*
|
import javax.persistence.Column
|
||||||
import kotlin.collections.LinkedHashSet
|
import javax.persistence.Entity
|
||||||
|
import javax.persistence.Id
|
||||||
|
import javax.persistence.Lob
|
||||||
|
import javax.persistence.Table
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A persistent implementation of [KeyManagementServiceInternal] to support CryptoService for initial keys and
|
* A persistent implementation of [KeyManagementServiceInternal] to support CryptoService for initial keys and
|
||||||
@ -52,7 +63,7 @@ class BasicHSMKeyManagementService(
|
|||||||
var privateKey: ByteArray = EMPTY_BYTE_ARRAY
|
var privateKey: ByteArray = EMPTY_BYTE_ARRAY
|
||||||
) {
|
) {
|
||||||
constructor(publicKey: PublicKey, privateKey: PrivateKey)
|
constructor(publicKey: PublicKey, privateKey: PrivateKey)
|
||||||
: this(publicKey.toStringShort(), publicKey.encoded, privateKey.encoded)
|
: this(publicKey.toStringShort(), Crypto.encodePublicKey(publicKey), privateKey.encoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
@ -13,6 +13,6 @@ import javax.persistence.Converter
|
|||||||
*/
|
*/
|
||||||
@Converter(autoApply = true)
|
@Converter(autoApply = true)
|
||||||
class PublicKeyToTextConverter : AttributeConverter<PublicKey, String> {
|
class PublicKeyToTextConverter : AttributeConverter<PublicKey, String> {
|
||||||
override fun convertToDatabaseColumn(key: PublicKey?): String? = key?.encoded?.toHex()
|
override fun convertToDatabaseColumn(key: PublicKey?): String? = key?.let { Crypto.encodePublicKey(key).toHex() }
|
||||||
override fun convertToEntityAttribute(text: String?): PublicKey? = text?.let { Crypto.decodePublicKey(it.hexToByteArray()) }
|
override fun convertToEntityAttribute(text: String?): PublicKey? = text?.let { Crypto.decodePublicKey(it.hexToByteArray()) }
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package sandbox.net.corda.core.crypto
|
package sandbox.net.corda.core.crypto
|
||||||
|
|
||||||
import sandbox.net.corda.core.crypto.DJVM.fromDJVM
|
import sandbox.java.lang.Object
|
||||||
import sandbox.net.corda.core.crypto.DJVM.toDJVM
|
|
||||||
import sandbox.java.lang.String
|
import sandbox.java.lang.String
|
||||||
import sandbox.java.lang.doCatch
|
import sandbox.java.lang.doCatch
|
||||||
import sandbox.java.math.BigInteger
|
import sandbox.java.math.BigInteger
|
||||||
@ -10,7 +9,8 @@ import sandbox.java.security.PrivateKey
|
|||||||
import sandbox.java.security.PublicKey
|
import sandbox.java.security.PublicKey
|
||||||
import sandbox.java.util.ArrayList
|
import sandbox.java.util.ArrayList
|
||||||
import sandbox.java.util.List
|
import sandbox.java.util.List
|
||||||
import sandbox.java.lang.Object
|
import sandbox.net.corda.core.crypto.DJVM.fromDJVM
|
||||||
|
import sandbox.net.corda.core.crypto.DJVM.toDJVM
|
||||||
import sandbox.org.bouncycastle.asn1.x509.AlgorithmIdentifier
|
import sandbox.org.bouncycastle.asn1.x509.AlgorithmIdentifier
|
||||||
import sandbox.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
import sandbox.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
||||||
import java.security.GeneralSecurityException
|
import java.security.GeneralSecurityException
|
||||||
@ -149,6 +149,11 @@ object Crypto : Object() {
|
|||||||
return decodePublicKey(signatureScheme.schemeCodeName, encodedKey)
|
return decodePublicKey(signatureScheme.schemeCodeName, encodedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun encodePublicKey(key: java.security.PublicKey): ByteArray {
|
||||||
|
return key.encoded
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun deriveKeyPair(signatureScheme: SignatureScheme, privateKey: PrivateKey, seed: ByteArray): KeyPair {
|
fun deriveKeyPair(signatureScheme: SignatureScheme, privateKey: PrivateKey, seed: ByteArray): KeyPair {
|
||||||
throw sandbox.java.lang.failApi("Crypto.deriveKeyPair(SignatureScheme, PrivateKey, byte[])")
|
throw sandbox.java.lang.failApi("Crypto.deriveKeyPair(SignatureScheme, PrivateKey, byte[])")
|
||||||
|
@ -3,7 +3,13 @@ package net.corda.serialization.internal.amqp.custom
|
|||||||
import net.corda.core.crypto.Crypto
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.serialization.DESERIALIZATION_CACHE_PROPERTY
|
import net.corda.core.serialization.DESERIALIZATION_CACHE_PROPERTY
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.serialization.internal.amqp.*
|
import net.corda.serialization.internal.amqp.AMQPTypeIdentifiers
|
||||||
|
import net.corda.serialization.internal.amqp.CustomSerializer
|
||||||
|
import net.corda.serialization.internal.amqp.DeserializationInput
|
||||||
|
import net.corda.serialization.internal.amqp.RestrictedType
|
||||||
|
import net.corda.serialization.internal.amqp.Schema
|
||||||
|
import net.corda.serialization.internal.amqp.SerializationOutput
|
||||||
|
import net.corda.serialization.internal.amqp.SerializationSchemas
|
||||||
import org.apache.qpid.proton.codec.Data
|
import org.apache.qpid.proton.codec.Data
|
||||||
import java.lang.reflect.Type
|
import java.lang.reflect.Type
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
@ -28,7 +34,7 @@ object PublicKeySerializer
|
|||||||
context: SerializationContext
|
context: SerializationContext
|
||||||
) {
|
) {
|
||||||
// TODO: Instead of encoding to the default X509 format, we could have a custom per key type (space-efficient) serialiser.
|
// TODO: Instead of encoding to the default X509 format, we could have a custom per key type (space-efficient) serialiser.
|
||||||
output.writeObject(obj.encoded, data, clazz, context)
|
output.writeObject(Crypto.encodePublicKey(obj), data, clazz, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readObject(obj: Any, schemas: SerializationSchemas, input: DeserializationInput,
|
override fun readObject(obj: Any, schemas: SerializationSchemas, input: DeserializationInput,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user