diff --git a/src/script/sigencoding.cpp b/src/script/sigencoding.cpp --- a/src/script/sigencoding.cpp +++ b/src/script/sigencoding.cpp @@ -24,7 +24,7 @@ * * This function is consensus-critical since BIP66. */ -static bool IsValidSignatureEncoding(const slicedvaltype &sig) { +static bool IsValidECDSASignatureEncoding(const slicedvaltype &sig) { // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] // * total-length: 1-byte length descriptor of everything that follows, // excluding the sighash byte. @@ -153,11 +153,12 @@ return true; } -static bool CheckRawSignatureEncoding(const slicedvaltype &sig, uint32_t flags, - ScriptError *serror) { +static bool CheckRawECDSASignatureEncoding(const slicedvaltype &sig, + uint32_t flags, + ScriptError *serror) { if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) && - !IsValidSignatureEncoding(sig)) { + !IsValidECDSASignatureEncoding(sig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } @@ -168,6 +169,11 @@ return true; } +static bool CheckRawSignatureEncoding(const slicedvaltype &sig, uint32_t flags, + ScriptError *serror) { + return CheckRawECDSASignatureEncoding(sig, flags, serror); +} + bool CheckDataSignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror) { // Empty signature. Not strictly DER encoded, but allowed to provide a @@ -180,21 +186,8 @@ vchSig | boost::adaptors::sliced(0, vchSig.size()), flags, serror); } -bool CheckTransactionSignatureEncoding(const valtype &vchSig, uint32_t flags, - ScriptError *serror) { - // Empty signature. Not strictly DER encoded, but allowed to provide a - // compact way to provide an invalid signature for use with CHECK(MULTI)SIG - if (vchSig.size() == 0) { - return true; - } - - if (!CheckRawSignatureEncoding( - vchSig | boost::adaptors::sliced(0, vchSig.size() - 1), flags, - serror)) { - // serror is set - return false; - } - +static bool CheckSighashEncoding(const valtype &vchSig, uint32_t flags, + ScriptError *serror) { if (flags & SCRIPT_VERIFY_STRICTENC) { if (!GetHashType(vchSig).isDefined()) { return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); @@ -217,7 +210,38 @@ bool CheckTransactionECDSASignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror) { - return CheckTransactionSignatureEncoding(vchSig, flags, serror); + // Empty signature. Not strictly DER encoded, but allowed to provide a + // compact way to provide an invalid signature for use with CHECK(MULTI)SIG + if (vchSig.size() == 0) { + return true; + } + + if (!CheckRawECDSASignatureEncoding( + vchSig | boost::adaptors::sliced(0, vchSig.size() - 1), flags, + serror)) { + // serror is set + return false; + } + + return CheckSighashEncoding(vchSig, flags, serror); +} + +bool CheckTransactionSignatureEncoding(const valtype &vchSig, uint32_t flags, + ScriptError *serror) { + // Empty signature. Not strictly DER encoded, but allowed to provide a + // compact way to provide an invalid signature for use with CHECK(MULTI)SIG + if (vchSig.size() == 0) { + return true; + } + + if (!CheckRawSignatureEncoding( + vchSig | boost::adaptors::sliced(0, vchSig.size() - 1), flags, + serror)) { + // serror is set + return false; + } + + return CheckSighashEncoding(vchSig, flags, serror); } static bool IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {