mirror of
https://github.com/corda/corda.git
synced 2024-12-28 16:58:55 +00:00
Merge commit '932d632716c55fef0bda7c6519677a46b66f05c2' into andr3ej-provider-setup-ent
# Conflicts: # core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt # node/src/main/kotlin/net/corda/node/Corda.kt
This commit is contained in:
commit
f7151e96d3
@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
package net.corda.core.crypto
|
package net.corda.core.crypto
|
||||||
|
|
||||||
|
import net.corda.core.crypto.CordaObjectIdentifier.COMPOSITE_KEY
|
||||||
|
import net.corda.core.crypto.CordaObjectIdentifier.COMPOSITE_SIGNATURE
|
||||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
||||||
import java.security.AccessController
|
|
||||||
import java.security.PrivilegedAction
|
|
||||||
import java.security.Provider
|
import java.security.Provider
|
||||||
|
|
||||||
class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME security provider wrapper") {
|
class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME security provider wrapper") {
|
||||||
@ -21,20 +21,12 @@ class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME secur
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
AccessController.doPrivileged(PrivilegedAction<Unit> { setup() })
|
put("KeyFactory.${CompositeKey.KEY_ALGORITHM}", CompositeKeyFactory::class.java.name)
|
||||||
}
|
put("Signature.${CompositeSignature.SIGNATURE_ALGORITHM}", CompositeSignature::class.java.name)
|
||||||
|
put("Alg.Alias.KeyFactory.$COMPOSITE_KEY", CompositeKey.KEY_ALGORITHM)
|
||||||
private fun setup() {
|
put("Alg.Alias.KeyFactory.OID.$COMPOSITE_KEY", CompositeKey.KEY_ALGORITHM)
|
||||||
put("KeyFactory.${CompositeKey.KEY_ALGORITHM}", "net.corda.core.crypto.CompositeKeyFactory")
|
put("Alg.Alias.Signature.$COMPOSITE_SIGNATURE", CompositeSignature.SIGNATURE_ALGORITHM)
|
||||||
put("Signature.${CompositeSignature.SIGNATURE_ALGORITHM}", "net.corda.core.crypto.CompositeSignature")
|
put("Alg.Alias.Signature.OID.$COMPOSITE_SIGNATURE", CompositeSignature.SIGNATURE_ALGORITHM)
|
||||||
|
|
||||||
val compositeKeyOID = CordaObjectIdentifier.COMPOSITE_KEY.id
|
|
||||||
put("Alg.Alias.KeyFactory.$compositeKeyOID", CompositeKey.KEY_ALGORITHM)
|
|
||||||
put("Alg.Alias.KeyFactory.OID.$compositeKeyOID", CompositeKey.KEY_ALGORITHM)
|
|
||||||
|
|
||||||
val compositeSignatureOID = CordaObjectIdentifier.COMPOSITE_SIGNATURE.id
|
|
||||||
put("Alg.Alias.Signature.$compositeSignatureOID", CompositeSignature.SIGNATURE_ALGORITHM)
|
|
||||||
put("Alg.Alias.Signature.OID.$compositeSignatureOID", CompositeSignature.SIGNATURE_ALGORITHM)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,19 +10,17 @@
|
|||||||
|
|
||||||
package net.corda.core.crypto
|
package net.corda.core.crypto
|
||||||
|
|
||||||
import net.corda.core.internal.X509EdDSAEngine
|
import net.corda.core.crypto.internal.*
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
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
|
||||||
import net.i2p.crypto.eddsa.EdDSASecurityProvider
|
|
||||||
import net.i2p.crypto.eddsa.math.GroupElement
|
import net.i2p.crypto.eddsa.math.GroupElement
|
||||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec
|
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.ASN1Integer
|
import org.bouncycastle.asn1.ASN1Integer
|
||||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
|
||||||
import org.bouncycastle.asn1.DERNull
|
import org.bouncycastle.asn1.DERNull
|
||||||
import org.bouncycastle.asn1.DLSequence
|
import org.bouncycastle.asn1.DLSequence
|
||||||
import org.bouncycastle.asn1.bc.BCObjectIdentifiers
|
import org.bouncycastle.asn1.bc.BCObjectIdentifiers
|
||||||
@ -37,7 +35,6 @@ 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
|
||||||
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey
|
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey
|
||||||
import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
|
|
||||||
import org.bouncycastle.jce.ECNamedCurveTable
|
import org.bouncycastle.jce.ECNamedCurveTable
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||||
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec
|
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec
|
||||||
@ -47,7 +44,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.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
|
||||||
import org.bouncycastle.pqc.jcajce.spec.SPHINCS256KeyGenParameterSpec
|
import org.bouncycastle.pqc.jcajce.spec.SPHINCS256KeyGenParameterSpec
|
||||||
@ -84,7 +80,7 @@ object Crypto {
|
|||||||
"RSA_SHA256",
|
"RSA_SHA256",
|
||||||
AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption, null),
|
AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption, null),
|
||||||
listOf(AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, null)),
|
listOf(AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, null)),
|
||||||
BouncyCastleProvider.PROVIDER_NAME,
|
cordaBouncyCastleProvider.name,
|
||||||
"RSA",
|
"RSA",
|
||||||
"SHA256WITHRSA",
|
"SHA256WITHRSA",
|
||||||
null,
|
null,
|
||||||
@ -99,7 +95,7 @@ object Crypto {
|
|||||||
"ECDSA_SECP256K1_SHA256",
|
"ECDSA_SECP256K1_SHA256",
|
||||||
AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA256, SECObjectIdentifiers.secp256k1),
|
AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA256, SECObjectIdentifiers.secp256k1),
|
||||||
listOf(AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SECObjectIdentifiers.secp256k1)),
|
listOf(AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SECObjectIdentifiers.secp256k1)),
|
||||||
BouncyCastleProvider.PROVIDER_NAME,
|
cordaBouncyCastleProvider.name,
|
||||||
"ECDSA",
|
"ECDSA",
|
||||||
"SHA256withECDSA",
|
"SHA256withECDSA",
|
||||||
ECNamedCurveTable.getParameterSpec("secp256k1"),
|
ECNamedCurveTable.getParameterSpec("secp256k1"),
|
||||||
@ -114,7 +110,7 @@ object Crypto {
|
|||||||
"ECDSA_SECP256R1_SHA256",
|
"ECDSA_SECP256R1_SHA256",
|
||||||
AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA256, SECObjectIdentifiers.secp256r1),
|
AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA256, SECObjectIdentifiers.secp256r1),
|
||||||
listOf(AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SECObjectIdentifiers.secp256r1)),
|
listOf(AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SECObjectIdentifiers.secp256r1)),
|
||||||
BouncyCastleProvider.PROVIDER_NAME,
|
cordaBouncyCastleProvider.name,
|
||||||
"ECDSA",
|
"ECDSA",
|
||||||
"SHA256withECDSA",
|
"SHA256withECDSA",
|
||||||
ECNamedCurveTable.getParameterSpec("secp256r1"),
|
ECNamedCurveTable.getParameterSpec("secp256r1"),
|
||||||
@ -128,14 +124,13 @@ object Crypto {
|
|||||||
* Not to be confused with the EdDSA variants, Ed25519ctx and Ed25519ph.
|
* Not to be confused with the EdDSA variants, Ed25519ctx and Ed25519ph.
|
||||||
*/
|
*/
|
||||||
@JvmField
|
@JvmField
|
||||||
val EDDSA_ED25519_SHA512 = SignatureScheme(
|
val EDDSA_ED25519_SHA512: SignatureScheme = SignatureScheme(
|
||||||
4,
|
4,
|
||||||
"EDDSA_ED25519_SHA512",
|
"EDDSA_ED25519_SHA512",
|
||||||
// OID taken from https://tools.ietf.org/html/draft-ietf-curdle-pkix-00
|
AlgorithmIdentifier(`id-Curve25519ph`, null),
|
||||||
AlgorithmIdentifier(ASN1ObjectIdentifier("1.3.101.112"), null),
|
|
||||||
emptyList(), // Both keys and the signature scheme use the same OID in i2p library.
|
emptyList(), // Both keys and the signature scheme use the same OID in i2p library.
|
||||||
// We added EdDSA to bouncy castle for certificate signing.
|
// We added EdDSA to bouncy castle for certificate signing.
|
||||||
BouncyCastleProvider.PROVIDER_NAME,
|
cordaBouncyCastleProvider.name,
|
||||||
"1.3.101.112",
|
"1.3.101.112",
|
||||||
EdDSAEngine.SIGNATURE_ALGORITHM,
|
EdDSAEngine.SIGNATURE_ALGORITHM,
|
||||||
EdDSANamedCurveTable.getByName("ED25519"),
|
EdDSANamedCurveTable.getByName("ED25519"),
|
||||||
@ -158,7 +153,7 @@ object Crypto {
|
|||||||
"SPHINCS-256_SHA512",
|
"SPHINCS-256_SHA512",
|
||||||
AlgorithmIdentifier(BCObjectIdentifiers.sphincs256_with_SHA512, DLSequence(arrayOf(ASN1Integer(0), SHA512_256))),
|
AlgorithmIdentifier(BCObjectIdentifiers.sphincs256_with_SHA512, DLSequence(arrayOf(ASN1Integer(0), SHA512_256))),
|
||||||
listOf(AlgorithmIdentifier(BCObjectIdentifiers.sphincs256, DLSequence(arrayOf(ASN1Integer(0), SHA512_256)))),
|
listOf(AlgorithmIdentifier(BCObjectIdentifiers.sphincs256, DLSequence(arrayOf(ASN1Integer(0), SHA512_256)))),
|
||||||
"BCPQC",
|
bouncyCastlePQCProvider.name,
|
||||||
"SPHINCS256",
|
"SPHINCS256",
|
||||||
"SHA512WITHSPHINCS256",
|
"SHA512WITHSPHINCS256",
|
||||||
SPHINCS256KeyGenParameterSpec(SPHINCS256KeyGenParameterSpec.SHA512_256),
|
SPHINCS256KeyGenParameterSpec(SPHINCS256KeyGenParameterSpec.SHA512_256),
|
||||||
@ -175,7 +170,7 @@ object Crypto {
|
|||||||
"COMPOSITE",
|
"COMPOSITE",
|
||||||
AlgorithmIdentifier(CordaObjectIdentifier.COMPOSITE_KEY),
|
AlgorithmIdentifier(CordaObjectIdentifier.COMPOSITE_KEY),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
CordaSecurityProvider.PROVIDER_NAME,
|
cordaSecurityProvider.name,
|
||||||
CompositeKey.KEY_ALGORITHM,
|
CompositeKey.KEY_ALGORITHM,
|
||||||
CompositeSignature.SIGNATURE_ALGORITHM,
|
CompositeSignature.SIGNATURE_ALGORITHM,
|
||||||
null,
|
null,
|
||||||
@ -209,22 +204,6 @@ object Crypto {
|
|||||||
+ signatureSchemeMap.values.map { Pair(it.signatureOID, it) })
|
+ signatureSchemeMap.values.map { Pair(it.signatureOID, it) })
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
// This map is required to defend against users that forcibly call Security.addProvider / Security.removeProvider
|
|
||||||
// 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.
|
|
||||||
// The val is private to avoid any harmful state changes.
|
|
||||||
private val providerMap: Map<String, Provider> = mapOf(
|
|
||||||
BouncyCastleProvider.PROVIDER_NAME to getBouncyCastleProvider(),
|
|
||||||
CordaSecurityProvider.PROVIDER_NAME to CordaSecurityProvider(),
|
|
||||||
"BCPQC" to BouncyCastlePQCProvider()) // Unfortunately, provider's name is not final in BouncyCastlePQCProvider, so we explicitly set it.
|
|
||||||
|
|
||||||
private fun getBouncyCastleProvider() = BouncyCastleProvider().apply {
|
|
||||||
putAll(EdDSASecurityProvider())
|
|
||||||
// Override the normal EdDSA engine with one which can handle X509 keys.
|
|
||||||
put("Signature.${EdDSAEngine.SIGNATURE_ALGORITHM}", X509EdDSAEngine::class.qualifiedName)
|
|
||||||
addKeyInfoConverter(EDDSA_ED25519_SHA512.signatureOID.algorithm, KeyInfoConverter(EDDSA_ED25519_SHA512))
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun supportedSignatureSchemes(): List<SignatureScheme> = ArrayList(signatureSchemeMap.values)
|
fun supportedSignatureSchemes(): List<SignatureScheme> = ArrayList(signatureSchemeMap.values)
|
||||||
|
|
||||||
@ -233,13 +212,6 @@ object Crypto {
|
|||||||
return providerMap[name] ?: throw IllegalArgumentException("Unrecognised provider: $name")
|
return providerMap[name] ?: throw IllegalArgumentException("Unrecognised provider: $name")
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
// This registration is needed for reading back EdDSA key from java keystore.
|
|
||||||
// TODO: Find a way to make JKS work with bouncy castle provider or implement our own provide so we don't have to register bouncy castle provider.
|
|
||||||
Security.addProvider(getBouncyCastleProvider())
|
|
||||||
Security.addProvider(CordaSecurityProvider())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalise an algorithm identifier by converting [DERNull] parameters into a Kotlin null value.
|
* Normalise an algorithm identifier by converting [DERNull] parameters into a Kotlin null value.
|
||||||
*/
|
*/
|
||||||
@ -886,7 +858,7 @@ object Crypto {
|
|||||||
// Compute the HMAC-SHA512 using a privateKey as the MAC_key and a seed ByteArray.
|
// Compute the HMAC-SHA512 using a privateKey as the MAC_key and a seed ByteArray.
|
||||||
private fun deriveHMAC(privateKey: PrivateKey, seed: ByteArray): ByteArray {
|
private fun deriveHMAC(privateKey: PrivateKey, seed: ByteArray): ByteArray {
|
||||||
// Compute hmac(privateKey, seed).
|
// Compute hmac(privateKey, seed).
|
||||||
val mac = Mac.getInstance("HmacSHA512", providerMap[BouncyCastleProvider.PROVIDER_NAME])
|
val mac = Mac.getInstance("HmacSHA512", cordaBouncyCastleProvider)
|
||||||
val keyData = when (privateKey) {
|
val keyData = when (privateKey) {
|
||||||
is BCECPrivateKey -> privateKey.d.toByteArray()
|
is BCECPrivateKey -> privateKey.d.toByteArray()
|
||||||
is EdDSAPrivateKey -> privateKey.geta()
|
is EdDSAPrivateKey -> privateKey.geta()
|
||||||
@ -897,16 +869,6 @@ object Crypto {
|
|||||||
return mac.doFinal(seed)
|
return mac.doFinal(seed)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class KeyInfoConverter(val signatureScheme: SignatureScheme) : AsymmetricKeyInfoConverter {
|
|
||||||
override fun generatePublic(keyInfo: SubjectPublicKeyInfo?): PublicKey? {
|
|
||||||
return keyInfo?.let { decodePublicKey(signatureScheme, it.encoded) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generatePrivate(keyInfo: PrivateKeyInfo?): PrivateKey? {
|
|
||||||
return keyInfo?.let { decodePrivateKey(signatureScheme, it.encoded) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a point's coordinates are on the expected curve to avoid certain types of ECC attacks.
|
* Check if a point's coordinates are on the expected curve to avoid certain types of ECC attacks.
|
||||||
* Point-at-infinity is not permitted as well.
|
* Point-at-infinity is not permitted as well.
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
package net.corda.core.crypto
|
package net.corda.core.crypto
|
||||||
|
|
||||||
import net.corda.core.contracts.PrivacySalt
|
import net.corda.core.contracts.PrivacySalt
|
||||||
|
import net.corda.core.crypto.internal.platformSecureRandomFactory
|
||||||
import net.corda.core.serialization.SerializationDefaults
|
import net.corda.core.serialization.SerializationDefaults
|
||||||
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.core.utilities.toBase58
|
import net.corda.core.utilities.toBase58
|
||||||
import net.corda.core.utilities.toSHA256Bytes
|
import net.corda.core.utilities.toSHA256Bytes
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import net.corda.core.utilities.SgxSupport
|
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.security.*
|
import java.security.*
|
||||||
|
|
||||||
@ -203,14 +203,6 @@ private class DummySecureRandomSpi : SecureRandomSpi() {
|
|||||||
}
|
}
|
||||||
object DummySecureRandom : SecureRandom(DummySecureRandomSpi(), null)
|
object DummySecureRandom : SecureRandom(DummySecureRandomSpi(), null)
|
||||||
|
|
||||||
private val _newSecureRandom: () -> SecureRandom by lazy {
|
|
||||||
when {
|
|
||||||
SgxSupport.isInsideEnclave -> { { DummySecureRandom } }
|
|
||||||
System.getProperty("os.name") == "Linux" -> { { SecureRandom.getInstance("NativePRNGNonBlocking") } }
|
|
||||||
else -> { { SecureRandom.getInstanceStrong() } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an instance of [SecureRandom] to avoid blocking, due to waiting for additional entropy, when possible.
|
* Get an instance of [SecureRandom] to avoid blocking, due to waiting for additional entropy, when possible.
|
||||||
* In this version, the NativePRNGNonBlocking is exclusively used on Linux OS to utilize dev/urandom because in high traffic
|
* In this version, the NativePRNGNonBlocking is exclusively used on Linux OS to utilize dev/urandom because in high traffic
|
||||||
@ -230,7 +222,7 @@ private val _newSecureRandom: () -> SecureRandom by lazy {
|
|||||||
* which should never happen and suggests an unusual JVM or non-standard Java library.
|
* which should never happen and suggests an unusual JVM or non-standard Java library.
|
||||||
*/
|
*/
|
||||||
@Throws(NoSuchAlgorithmException::class)
|
@Throws(NoSuchAlgorithmException::class)
|
||||||
fun newSecureRandom(): SecureRandom = _newSecureRandom()
|
fun newSecureRandom(): SecureRandom = platformSecureRandomFactory()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a random positive non-zero long generated using a secure RNG. This function sacrifies a bit of entropy in order
|
* Returns a random positive non-zero long generated using a secure RNG. This function sacrifies a bit of entropy in order
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package net.corda.core.crypto.internal
|
||||||
|
|
||||||
|
import net.corda.core.crypto.CordaSecurityProvider
|
||||||
|
import net.corda.core.crypto.Crypto.EDDSA_ED25519_SHA512
|
||||||
|
import net.corda.core.crypto.Crypto.decodePrivateKey
|
||||||
|
import net.corda.core.crypto.Crypto.decodePublicKey
|
||||||
|
import net.corda.core.crypto.DummySecureRandom
|
||||||
|
import net.corda.core.internal.X509EdDSAEngine
|
||||||
|
import net.corda.core.utilities.SgxSupport
|
||||||
|
import net.i2p.crypto.eddsa.EdDSAEngine
|
||||||
|
import net.i2p.crypto.eddsa.EdDSASecurityProvider
|
||||||
|
import org.apache.commons.lang.SystemUtils
|
||||||
|
import org.bouncycastle.asn1.ASN1ObjectIdentifier
|
||||||
|
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo
|
||||||
|
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
||||||
|
import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||||
|
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider
|
||||||
|
import java.security.SecureRandom
|
||||||
|
import java.security.Security
|
||||||
|
|
||||||
|
internal val cordaSecurityProvider = CordaSecurityProvider().also {
|
||||||
|
Security.insertProviderAt(it, 1) // The position is 1-based.
|
||||||
|
}
|
||||||
|
// OID taken from https://tools.ietf.org/html/draft-ietf-curdle-pkix-00
|
||||||
|
internal val `id-Curve25519ph` = ASN1ObjectIdentifier("1.3.101.112")
|
||||||
|
internal val cordaBouncyCastleProvider = BouncyCastleProvider().apply {
|
||||||
|
putAll(EdDSASecurityProvider())
|
||||||
|
// Override the normal EdDSA engine with one which can handle X509 keys.
|
||||||
|
put("Signature.${EdDSAEngine.SIGNATURE_ALGORITHM}", X509EdDSAEngine::class.java.name)
|
||||||
|
addKeyInfoConverter(`id-Curve25519ph`, object : AsymmetricKeyInfoConverter {
|
||||||
|
override fun generatePublic(keyInfo: SubjectPublicKeyInfo) = decodePublicKey(EDDSA_ED25519_SHA512, keyInfo.encoded)
|
||||||
|
override fun generatePrivate(keyInfo: PrivateKeyInfo) = decodePrivateKey(EDDSA_ED25519_SHA512, keyInfo.encoded)
|
||||||
|
})
|
||||||
|
}.also {
|
||||||
|
// This registration is needed for reading back EdDSA key from java keystore.
|
||||||
|
// TODO: Find a way to make JKS work with bouncy castle provider or implement our own provide so we don't have to register bouncy castle provider.
|
||||||
|
Security.addProvider(it)
|
||||||
|
}
|
||||||
|
internal val bouncyCastlePQCProvider = BouncyCastlePQCProvider().apply {
|
||||||
|
require(name == "BCPQC") // The constant it comes from is not final.
|
||||||
|
}
|
||||||
|
// This map is required to defend against users that forcibly call Security.addProvider / Security.removeProvider
|
||||||
|
// 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.
|
||||||
|
// The val is private to avoid any harmful state changes.
|
||||||
|
internal val providerMap = listOf(cordaBouncyCastleProvider, cordaSecurityProvider, bouncyCastlePQCProvider).map { it.name to it }.toMap()
|
||||||
|
internal val platformSecureRandomFactory: () -> SecureRandom = when {
|
||||||
|
SgxSupport.isInsideEnclave -> {
|
||||||
|
{ DummySecureRandom }
|
||||||
|
}
|
||||||
|
SystemUtils.IS_OS_LINUX -> {
|
||||||
|
{ SecureRandom.getInstance("NativePRNGNonBlocking") }
|
||||||
|
}
|
||||||
|
else -> SecureRandom::getInstanceStrong
|
||||||
|
}
|
@ -13,10 +13,13 @@
|
|||||||
|
|
||||||
package net.corda.node
|
package net.corda.node
|
||||||
|
|
||||||
|
import net.corda.core.crypto.CordaSecurityProvider
|
||||||
|
import net.corda.core.crypto.Crypto
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
import net.corda.node.internal.EnterpriseNode
|
import net.corda.node.internal.EnterpriseNode
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
Crypto.findProvider(CordaSecurityProvider.PROVIDER_NAME) // Install our SecureRandom before e.g. UUID asks for one.
|
||||||
// Pass the arguments to the Node factory. In the Enterprise edition, this line is modified to point to a subclass.
|
// Pass the arguments to the Node factory. In the Enterprise edition, this line is modified to point to a subclass.
|
||||||
// It will exit the process in case of startup failure and is not intended to be used by embedders. If you want
|
// It will exit the process in case of startup failure and is not intended to be used by embedders. If you want
|
||||||
// to embed Node in your own container, instantiate it directly and set up the configuration objects yourself.
|
// to embed Node in your own container, instantiate it directly and set up the configuration objects yourself.
|
||||||
|
Loading…
Reference in New Issue
Block a user