mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +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/internal/rules/*.class'
|
||||
exclude 'net/corda/core/internal/utilities/PrivateInterner*.class'
|
||||
exclude 'net/corda/core/crypto/internal/PublicKeyCache*.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.utilities.exactAdd
|
||||
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.SubjectPublicKeyInfo
|
||||
import java.security.PublicKey
|
||||
@ -162,7 +169,7 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
|
||||
|
||||
override fun toASN1Primitive(): ASN1Primitive {
|
||||
val vector = ASN1EncodableVector()
|
||||
vector.add(DERBitString(node.encoded))
|
||||
vector.add(DERBitString(Crypto.encodePublicKey(node)))
|
||||
vector.add(ASN1Integer(weight.toLong()))
|
||||
return DERSequence(vector)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import net.corda.core.DeleteForDJVM
|
||||
import net.corda.core.KeepForDJVM
|
||||
import net.corda.core.crypto.internal.AliasPrivateKey
|
||||
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.cordaBouncyCastleProvider
|
||||
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.internal.utilities.PrivateInterner
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.ByteSequence
|
||||
import net.i2p.crypto.eddsa.EdDSAEngine
|
||||
import net.i2p.crypto.eddsa.EdDSAPrivateKey
|
||||
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
||||
@ -281,7 +283,7 @@ object Crypto {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun findSignatureScheme(key: PublicKey): SignatureScheme {
|
||||
val keyInfo = SubjectPublicKeyInfo.getInstance(key.encoded)
|
||||
val keyInfo = SubjectPublicKeyInfo.getInstance(encodePublicKey(key))
|
||||
return findSignatureScheme(keyInfo.algorithm)
|
||||
}
|
||||
|
||||
@ -373,10 +375,17 @@ object Crypto {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun decodePublicKey(encodedKey: ByteArray): PublicKey {
|
||||
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(encodedKey)
|
||||
val signatureScheme = findSignatureScheme(subjectPublicKeyInfo.algorithm)
|
||||
val keyFactory = keyFactory(signatureScheme)
|
||||
return convertIfBCEdDSAPublicKey(keyFactory.generatePublic(X509EncodedKeySpec(encodedKey)))
|
||||
return PublicKeyCache.publicKeyForCachedBytes(ByteSequence.of(encodedKey)) ?: {
|
||||
val subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(encodedKey)
|
||||
val signatureScheme = findSignatureScheme(subjectPublicKeyInfo.algorithm)
|
||||
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 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 {
|
||||
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.parseAsHex
|
||||
import net.corda.core.utilities.toHexString
|
||||
import java.nio.ByteBuffer
|
||||
import java.security.MessageDigest
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.ConcurrentMap
|
||||
@ -39,9 +38,10 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
|
||||
return true
|
||||
}
|
||||
|
||||
// This is an efficient hashCode, because there is no point in performing a hash calculation on a cryptographic hash.
|
||||
// It just takes the first 4 bytes and transforms them into an Int.
|
||||
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()
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
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) }
|
||||
|
||||
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
|
||||
|
@ -1,9 +1,16 @@
|
||||
package net.corda.core.internal
|
||||
|
||||
import net.corda.core.DeleteForDJVM
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.i2p.crypto.eddsa.EdDSAEngine
|
||||
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.X509EncodedKeySpec
|
||||
|
||||
@ -30,7 +37,7 @@ class X509EdDSAEngine : Signature {
|
||||
|
||||
override fun engineInitVerify(publicKey: PublicKey) {
|
||||
val parsedKey = try {
|
||||
publicKey as? EdDSAPublicKey ?: EdDSAPublicKey(X509EncodedKeySpec(publicKey.encoded))
|
||||
publicKey as? EdDSAPublicKey ?: EdDSAPublicKey(X509EncodedKeySpec(Crypto.encodePublicKey(publicKey)))
|
||||
} catch (e: Exception) {
|
||||
throw (InvalidKeyException(e.message))
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
|
||||
fun data(): ByteArray? {
|
||||
return when (type()) {
|
||||
Type.HASH -> (constraint as HashAttachmentConstraint).attachmentId.bytes
|
||||
Type.SIGNATURE -> (constraint as SignatureAttachmentConstraint).key.encoded
|
||||
Type.SIGNATURE -> Crypto.encodePublicKey((constraint as SignatureAttachmentConstraint).key)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ sealed class ByteSequence(private val _bytes: ByteArray, val offset: Int, val si
|
||||
if (this === other) return true
|
||||
if (other !is ByteSequence) 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)
|
||||
}
|
||||
|
||||
@ -125,13 +126,18 @@ sealed class ByteSequence(private val _bytes: ByteArray, val offset: Int, val si
|
||||
return true
|
||||
}
|
||||
|
||||
private var _hashCode: Int = 0;
|
||||
|
||||
override fun hashCode(): Int {
|
||||
val thisBytes = _bytes
|
||||
var result = 1
|
||||
for (index in offset until (offset + size)) {
|
||||
result = 31 * result + thisBytes[index]
|
||||
}
|
||||
return result
|
||||
return if (_hashCode == 0) {
|
||||
val thisBytes = _bytes
|
||||
var result = 1
|
||||
for (index in offset until (offset + size)) {
|
||||
result = 31 * result + thisBytes[index]
|
||||
}
|
||||
_hashCode = result
|
||||
result
|
||||
} else _hashCode
|
||||
}
|
||||
|
||||
override fun toString(): String = "[${copyBytes().toHexString()}]"
|
||||
|
@ -9,7 +9,7 @@ import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.internal.hash
|
||||
import java.nio.charset.Charset
|
||||
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.
|
||||
|
||||
@ -81,7 +81,7 @@ fun String.hexToBase64(): String = hexToByteArray().toBase64()
|
||||
fun parsePublicKeyBase58(base58String: String): PublicKey = Crypto.decodePublicKey(base58String.base58ToByteArray())
|
||||
|
||||
/** 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. */
|
||||
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.crypto.Crypto
|
||||
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.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.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.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.X509v3CertificateBuilder
|
||||
import org.bouncycastle.cert.bc.BcX509ExtensionUtils
|
||||
@ -28,12 +47,18 @@ import java.nio.file.Path
|
||||
import java.security.KeyPair
|
||||
import java.security.PublicKey
|
||||
import java.security.SignatureException
|
||||
import java.security.cert.*
|
||||
import java.security.cert.CertPath
|
||||
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.Instant
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.*
|
||||
import java.util.ArrayList
|
||||
import java.util.Date
|
||||
import javax.security.auth.x500.X500Principal
|
||||
import kotlin.experimental.and
|
||||
import kotlin.experimental.or
|
||||
@ -189,7 +214,7 @@ object X509Utilities {
|
||||
crlIssuer: X500Name? = null): X509v3CertificateBuilder {
|
||||
val serial = generateCertificateSerialNumber()
|
||||
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 builder = JcaX509v3CertificateBuilder(issuer, serial, validityWindow.first, validityWindow.second, subject, subjectPublicKey)
|
||||
|
@ -1,6 +1,10 @@
|
||||
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.io.Input
|
||||
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.serialization.SerializeAsTokenContext
|
||||
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.SgxSupport
|
||||
import net.corda.serialization.internal.serializationContextKey
|
||||
@ -302,7 +312,7 @@ object PrivateKeySerializer : Serializer<PrivateKey>() {
|
||||
object PublicKeySerializer : Serializer<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.
|
||||
output.writeBytesWithLength(obj.encoded)
|
||||
output.writeBytesWithLength(Crypto.encodePublicKey(obj))
|
||||
}
|
||||
|
||||
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.TrustAnchor
|
||||
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.Executors
|
||||
import java.util.stream.Stream
|
||||
@ -136,7 +138,7 @@ class PersistentIdentityService(cacheFactory: NamedCacheFactory) : SingletonSeri
|
||||
)
|
||||
},
|
||||
toPersistentEntity = { key: String, value: PublicKey ->
|
||||
PersistentHashToPublicKey(key, value.encoded)
|
||||
PersistentHashToPublicKey(key, Crypto.encodePublicKey(value))
|
||||
},
|
||||
persistentEntityClass = PersistentHashToPublicKey::class.java)
|
||||
}
|
||||
|
@ -1,6 +1,14 @@
|
||||
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.telemetry.TelemetryServiceImpl
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
@ -16,9 +24,12 @@ import org.bouncycastle.operator.ContentSigner
|
||||
import java.security.KeyPair
|
||||
import java.security.PrivateKey
|
||||
import java.security.PublicKey
|
||||
import java.util.*
|
||||
import javax.persistence.*
|
||||
import kotlin.collections.LinkedHashSet
|
||||
import java.util.UUID
|
||||
import javax.persistence.Column
|
||||
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
|
||||
@ -52,7 +63,7 @@ class BasicHSMKeyManagementService(
|
||||
var privateKey: ByteArray = EMPTY_BYTE_ARRAY
|
||||
) {
|
||||
constructor(publicKey: PublicKey, privateKey: PrivateKey)
|
||||
: this(publicKey.toStringShort(), publicKey.encoded, privateKey.encoded)
|
||||
: this(publicKey.toStringShort(), Crypto.encodePublicKey(publicKey), privateKey.encoded)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
@ -13,6 +13,6 @@ import javax.persistence.Converter
|
||||
*/
|
||||
@Converter(autoApply = true)
|
||||
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()) }
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package sandbox.net.corda.core.crypto
|
||||
|
||||
import sandbox.net.corda.core.crypto.DJVM.fromDJVM
|
||||
import sandbox.net.corda.core.crypto.DJVM.toDJVM
|
||||
import sandbox.java.lang.Object
|
||||
import sandbox.java.lang.String
|
||||
import sandbox.java.lang.doCatch
|
||||
import sandbox.java.math.BigInteger
|
||||
@ -10,7 +9,8 @@ import sandbox.java.security.PrivateKey
|
||||
import sandbox.java.security.PublicKey
|
||||
import sandbox.java.util.ArrayList
|
||||
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.SubjectPublicKeyInfo
|
||||
import java.security.GeneralSecurityException
|
||||
@ -149,6 +149,11 @@ object Crypto : Object() {
|
||||
return decodePublicKey(signatureScheme.schemeCodeName, encodedKey)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun encodePublicKey(key: java.security.PublicKey): ByteArray {
|
||||
return key.encoded
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deriveKeyPair(signatureScheme: SignatureScheme, privateKey: PrivateKey, seed: ByteArray): KeyPair {
|
||||
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.serialization.DESERIALIZATION_CACHE_PROPERTY
|
||||
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 java.lang.reflect.Type
|
||||
import java.security.PublicKey
|
||||
@ -28,7 +34,7 @@ object PublicKeySerializer
|
||||
context: SerializationContext
|
||||
) {
|
||||
// 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,
|
||||
|
Loading…
Reference in New Issue
Block a user