NOTICK Add more detail on signature build failures (#6510)

Add details of the signature provider and key algorithm if `InvalidKeyException` is thrown when constructing a `ContentSigner`, in order to be able to usefully diagnose incorrect signature providers or similar errors.
This commit is contained in:
Ross Nicoll 2020-07-23 15:17:59 +01:00 committed by GitHub
parent 14279a30cc
commit 05c2428f2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 7 deletions

View File

@ -6,6 +6,7 @@ import net.corda.core.crypto.internal.Instances
import org.bouncycastle.asn1.x509.AlgorithmIdentifier
import org.bouncycastle.operator.ContentSigner
import java.io.OutputStream
import java.security.InvalidKeyException
import java.security.PrivateKey
import java.security.Provider
import java.security.SecureRandom
@ -24,14 +25,18 @@ object ContentSignerBuilder {
else
Signature.getInstance(signatureScheme.signatureName, provider)
val sig = signatureInstance.apply {
// TODO special handling for Sphincs due to a known BouncyCastle's Sphincs bug we reported.
// It is fixed in BC 161b12, so consider updating the below if-statement after updating BouncyCastle.
if (random != null && signatureScheme != SPHINCS256_SHA256) {
initSign(privateKey, random)
} else {
initSign(privateKey)
val sig = try {
signatureInstance.apply {
// TODO special handling for Sphincs due to a known BouncyCastle's Sphincs bug we reported.
// It is fixed in BC 161b12, so consider updating the below if-statement after updating BouncyCastle.
if (random != null && signatureScheme != SPHINCS256_SHA256) {
initSign(privateKey, random)
} else {
initSign(privateKey)
}
}
} catch(ex: InvalidKeyException) {
throw InvalidKeyException("Incorrect key type ${privateKey.algorithm} for signature scheme ${signatureInstance.algorithm}", ex)
}
return object : ContentSigner {
private val stream = SignatureOutputStream(sig, optimised)

View File

@ -0,0 +1,33 @@
package net.corda.nodeapi.internal.crypto
import net.corda.core.crypto.Crypto
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test
import java.math.BigInteger
import java.security.InvalidKeyException
class ContentSignerBuilderTest {
companion object {
private const val entropy = "20200723"
}
@Test(timeout = 300_000)
fun `should build content signer for valid eddsa key`() {
val signatureScheme = Crypto.EDDSA_ED25519_SHA512
val provider = Crypto.findProvider(signatureScheme.providerName)
val issuerKeyPair = Crypto.deriveKeyPairFromEntropy(signatureScheme, BigInteger(entropy))
ContentSignerBuilder.build(signatureScheme, issuerKeyPair.private, provider)
}
@Test(timeout = 300_000)
fun `should fail to build content signer for incorrect key type`() {
val signatureScheme = Crypto.EDDSA_ED25519_SHA512
val provider = Crypto.findProvider(signatureScheme.providerName)
val issuerKeyPair = Crypto.deriveKeyPairFromEntropy(Crypto.ECDSA_SECP256R1_SHA256, BigInteger(entropy))
assertThatExceptionOfType(InvalidKeyException::class.java)
.isThrownBy {
ContentSignerBuilder.build(signatureScheme, issuerKeyPair.private, provider)
}
.withMessage("Incorrect key type EC for signature scheme NONEwithEdDSA")
}
}