From 7ec5bd789e647e9a9c25e6558c1b453a2531da80 Mon Sep 17 00:00:00 2001 From: Konstantinos Chalkias Date: Mon, 4 Sep 2017 10:44:22 +0100 Subject: [PATCH] Composite Signature OID fix and crypto comments clean up (#1393) --- .../net/corda/core/crypto/CompositeKey.kt | 6 ++-- .../corda/core/crypto/CompositeKeyFactory.kt | 2 +- .../core/crypto/CordaSecurityProvider.kt | 8 +++-- .../kotlin/net/corda/core/crypto/Crypto.kt | 2 +- .../net/corda/core/crypto/CryptoUtils.kt | 33 +++++++------------ .../net/corda/core/crypto/DigitalSignature.kt | 4 +-- .../net/corda/core/crypto/MerkleTree.kt | 4 +-- .../net/corda/core/crypto/SecureHash.kt | 2 +- .../net/corda/core/crypto/SignableData.kt | 1 - .../net/corda/core/crypto/SignatureScheme.kt | 3 +- .../core/transactions/MerkleTransaction.kt | 2 +- 11 files changed, 29 insertions(+), 38 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/crypto/CompositeKey.kt b/core/src/main/kotlin/net/corda/core/crypto/CompositeKey.kt index 80e5ac9d64..ae86b3f198 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CompositeKey.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CompositeKey.kt @@ -12,7 +12,7 @@ import java.util.* /** * A tree data structure that enables the representation of composite public keys. - * Notice that with that implementation CompositeKey extends PublicKey. Leaves are represented by single public keys. + * Notice that with that implementation CompositeKey extends [PublicKey]. Leaves are represented by single public keys. * * For complex scenarios, such as *"Both Alice and Bob need to sign to consume a state S"*, we can represent * the requirement by creating a tree with a root [CompositeKey], and Alice and Bob as children. @@ -159,7 +159,7 @@ class CompositeKey private constructor(val threshold: Int, children: List get() = children.flatMap { it.node.keys }.toSet() // Uses PublicKey.keys extension. diff --git a/core/src/main/kotlin/net/corda/core/crypto/CompositeKeyFactory.kt b/core/src/main/kotlin/net/corda/core/crypto/CompositeKeyFactory.kt index 62d81c4147..df7fc7c433 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CompositeKeyFactory.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CompositeKeyFactory.kt @@ -26,7 +26,7 @@ class CompositeKeyFactory : KeyFactorySpi() { @Throws(InvalidKeySpecException::class) override fun engineGetKeySpec(key: Key, keySpec: Class): T { - // Only support [X509EncodedKeySpec]. + // Only support X509EncodedKeySpec. throw InvalidKeySpecException("Not implemented yet $key $keySpec") } diff --git a/core/src/main/kotlin/net/corda/core/crypto/CordaSecurityProvider.kt b/core/src/main/kotlin/net/corda/core/crypto/CordaSecurityProvider.kt index 2b490cfce1..eaae5e2ffb 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CordaSecurityProvider.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CordaSecurityProvider.kt @@ -21,14 +21,16 @@ class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME secur val compositeKeyOID = CordaObjectIdentifier.COMPOSITE_KEY.id put("Alg.Alias.KeyFactory.$compositeKeyOID", CompositeKey.KEY_ALGORITHM) put("Alg.Alias.KeyFactory.OID.$compositeKeyOID", CompositeKey.KEY_ALGORITHM) - put("Alg.Alias.Signature.$compositeKeyOID", CompositeSignature.SIGNATURE_ALGORITHM) - put("Alg.Alias.Signature.OID.$compositeKeyOID", CompositeSignature.SIGNATURE_ALGORITHM) + + val compositeSignatureOID = CordaObjectIdentifier.COMPOSITE_SIGNATURE.id + put("Alg.Alias.Signature.$compositeSignatureOID", CompositeSignature.SIGNATURE_ALGORITHM) + put("Alg.Alias.Signature.OID.$compositeSignatureOID", CompositeSignature.SIGNATURE_ALGORITHM) } } object CordaObjectIdentifier { // UUID-based OID - // TODO: Register for an OID space and issue our own shorter OID + // TODO: Register for an OID space and issue our own shorter OID. @JvmField val COMPOSITE_KEY = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791002") @JvmField val COMPOSITE_SIGNATURE = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791003") } diff --git a/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt b/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt index 5195840780..c5f6b16256 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt @@ -197,7 +197,7 @@ object Crypto { private val providerMap: Map = 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. + "BCPQC" to BouncyCastlePQCProvider()) // Unfortunately, provider's name is not final in BouncyCastlePQCProvider, so we explicitly set it. private fun getBouncyCastleProvider() = BouncyCastleProvider().apply { putAll(EdDSASecurityProvider()) diff --git a/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt b/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt index 023b2d20c1..922359ca58 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt @@ -17,13 +17,9 @@ import java.security.* * @throws SignatureException if signing is not possible due to malformed data or private key. */ @Throws(IllegalArgumentException::class, InvalidKeyException::class, SignatureException::class) -fun PrivateKey.sign(bytesToSign: ByteArray): DigitalSignature { - return DigitalSignature(Crypto.doSign(this, bytesToSign)) -} +fun PrivateKey.sign(bytesToSign: ByteArray): DigitalSignature = DigitalSignature(Crypto.doSign(this, bytesToSign)) -fun PrivateKey.sign(bytesToSign: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey { - return DigitalSignature.WithKey(publicKey, this.sign(bytesToSign).bytes) -} +fun PrivateKey.sign(bytesToSign: ByteArray, publicKey: PublicKey) = DigitalSignature.WithKey(publicKey, this.sign(bytesToSign).bytes) /** * Helper function to sign with a key pair. @@ -81,32 +77,27 @@ fun PublicKey.isValid(content: ByteArray, signature: DigitalSignature) : Boolean /** Render a public key to its hash (in Base58) of its serialised form using the DL prefix. */ fun PublicKey.toStringShort(): String = "DL" + this.toSHA256Bytes().toBase58() -val PublicKey.keys: Set get() { - return if (this is CompositeKey) this.leafKeys - else setOf(this) -} +val PublicKey.keys: Set get() = (this as? CompositeKey)?.leafKeys ?: setOf(this) fun PublicKey.isFulfilledBy(otherKey: PublicKey): Boolean = isFulfilledBy(setOf(otherKey)) -fun PublicKey.isFulfilledBy(otherKeys: Iterable): Boolean { - return if (this is CompositeKey) this.isFulfilledBy(otherKeys) - else this in otherKeys -} +fun PublicKey.isFulfilledBy(otherKeys: Iterable): Boolean = (this as? CompositeKey)?.isFulfilledBy(otherKeys) ?: (this in otherKeys) -/** Checks whether any of the given [keys] matches a leaf on the CompositeKey tree or a single PublicKey */ +/** Checks whether any of the given [keys] matches a leaf on the [CompositeKey] tree or a single [PublicKey]. */ fun PublicKey.containsAny(otherKeys: Iterable): Boolean { return if (this is CompositeKey) keys.intersect(otherKeys).isNotEmpty() else this in otherKeys } -/** Returns the set of all [PublicKey]s of the signatures */ +/** Returns the set of all [PublicKey]s of the signatures. */ fun Iterable.byKeys() = map { it.by }.toSet() -// Allow Kotlin destructuring: val (private, public) = keyPair +// Allow Kotlin destructuring: +// val (private, public) = keyPair operator fun KeyPair.component1(): PrivateKey = this.private operator fun KeyPair.component2(): PublicKey = this.public -/** A simple wrapper that will make it easier to swap out the EC algorithm we use in future */ +/** A simple wrapper that will make it easier to swap out the EC algorithm we use in future. */ fun generateKeyPair(): KeyPair = Crypto.generateKeyPair() /** @@ -147,13 +138,11 @@ fun KeyPair.verify(signatureData: ByteArray, clearData: ByteArray): Boolean = Cr * @param numOfBytes how many random bytes to output. * @return a random [ByteArray]. * @throws NoSuchAlgorithmException thrown if "NativePRNGNonBlocking" is not supported on the JVM - * or if no strong SecureRandom implementations are available or if Security.getProperty("securerandom.strongAlgorithms") is null or empty, + * or if no strong [SecureRandom] implementations are available or if Security.getProperty("securerandom.strongAlgorithms") is null or empty, * which should never happen and suggests an unusual JVM or non-standard Java library. */ @Throws(NoSuchAlgorithmException::class) -fun secureRandomBytes(numOfBytes: Int): ByteArray { - return newSecureRandom().generateSeed(numOfBytes) -} +fun secureRandomBytes(numOfBytes: Int): ByteArray = newSecureRandom().generateSeed(numOfBytes) /** * Get an instance of [SecureRandom] to avoid blocking, due to waiting for additional entropy, when possible. diff --git a/core/src/main/kotlin/net/corda/core/crypto/DigitalSignature.kt b/core/src/main/kotlin/net/corda/core/crypto/DigitalSignature.kt index 0e0f36c606..9e28be8a3a 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/DigitalSignature.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/DigitalSignature.kt @@ -6,8 +6,8 @@ import java.security.InvalidKeyException import java.security.PublicKey import java.security.SignatureException -// TODO: Is there a use-case for bare [DigitalSignature], or is everything a [DigitalSignature.WithKey]? If there's no -// actual use-case, we should merge the with key version into the parent class. In that case [CompositeSignatureWithKeys] +// TODO: Is there a use-case for bare DigitalSignature, or is everything a DigitalSignature.WithKey? If there's no +// actual use-case, we should merge the with key version into the parent class. In that case CompositeSignatureWithKeys // should be renamed to match. /** A wrapper around a digital signature. */ @CordaSerializable diff --git a/core/src/main/kotlin/net/corda/core/crypto/MerkleTree.kt b/core/src/main/kotlin/net/corda/core/crypto/MerkleTree.kt index 831e20758e..1555ed70fc 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/MerkleTree.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/MerkleTree.kt @@ -3,7 +3,7 @@ package net.corda.core.crypto import java.util.* /** - * Creation and verification of a Merkle Tree for a Wire Transaction. + * Creation and verification of a Merkle tree for a [WireTransaction]. * * See: https://en.wikipedia.org/wiki/Merkle_tree * @@ -49,7 +49,7 @@ sealed class MerkleTree { */ private tailrec fun buildMerkleTree(lastNodesList: List): MerkleTree { if (lastNodesList.size == 1) { - return lastNodesList[0] //Root reached. + return lastNodesList[0] // Root reached. } else { val newLevelHashes: MutableList = ArrayList() val n = lastNodesList.size diff --git a/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt b/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt index af2114ab6d..837f27faea 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt @@ -12,7 +12,7 @@ import java.security.MessageDigest */ @CordaSerializable sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) { - /** SHA-256 is part of the SHA-2 hash function family. Generated hash is fixed size, 256-bits (32-bytes) */ + /** SHA-256 is part of the SHA-2 hash function family. Generated hash is fixed size, 256-bits (32-bytes). */ class SHA256(bytes: ByteArray) : SecureHash(bytes) { init { require(bytes.size == 32) diff --git a/core/src/main/kotlin/net/corda/core/crypto/SignableData.kt b/core/src/main/kotlin/net/corda/core/crypto/SignableData.kt index a893381f7b..5027247980 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/SignableData.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/SignableData.kt @@ -11,4 +11,3 @@ import net.corda.core.serialization.CordaSerializable */ @CordaSerializable data class SignableData(val txId: SecureHash, val signatureMetadata: SignatureMetadata) - diff --git a/core/src/main/kotlin/net/corda/core/crypto/SignatureScheme.kt b/core/src/main/kotlin/net/corda/core/crypto/SignatureScheme.kt index 9ec9d26863..0176397c2f 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/SignatureScheme.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/SignatureScheme.kt @@ -29,4 +29,5 @@ data class SignatureScheme( val signatureName: String, val algSpec: AlgorithmParameterSpec?, val keySize: Int?, - val desc: String) + val desc: String +) diff --git a/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt index 7793b709e6..3675b20dc8 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt @@ -230,7 +230,7 @@ class FilteredTransaction private constructor( } /** - * Runs verification of Partial Merkle Branch against [id]. + * Runs verification of partial Merkle branch against [id]. */ @Throws(MerkleTreeException::class) fun verify(): Boolean {