I just found this code in Corda's crypto API for handling key verification:
fun doVerify(signatureScheme: SignatureScheme, publicKey: PublicKey, signatureData: ByteArray, clearData: ByteArray): Boolean {
require(Crypto.isSupportedSignatureScheme(signatureScheme)) {
"Unsupported key/algorithm for schemeCodeName: ${signatureScheme.schemeCodeName}"
}
if (signatureData.isEmpty()) throw IllegalArgumentException("Signature data is empty!")
if (clearData.isEmpty()) throw IllegalArgumentException("Clear data is empty, nothing to verify!")
val verificationResult = Crypto.isValid(signatureScheme, publicKey, signatureData, clearData)
if (verificationResult) {
return true
} else {
throw SignatureException("Signature Verification failed!")
}
}
I can understand throwing exceptions when arguments are invalid, but I'm curious as to why this either returns true, or throws another exception when verificationResult
is false
, rather than just return verificationResult
. This seems like a highly unusual design choice!
Could someone, ideally from the R3 engineering team explain?
No engineering team here, but I guess it is because Crypto.doVerify
is the function called from TransactionSignature.verify
, which is the one used in the flows to verify the signatures. Raising an exception in such an essential function, allows the flow to wrap it to a FlowException
so that it can be managed by the Flow Hospital.