diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1029,7 +1029,7 @@ // pubkey/signature evaluation distinguishable by // CHECKMULTISIG NOT if the STRICTENC flag is set. // See the script_(in)valid tests for details. - if (!CheckTransactionSignatureEncoding( + if (!CheckTransactionECDSASignatureEncoding( vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { diff --git a/src/script/sigencoding.h b/src/script/sigencoding.h --- a/src/script/sigencoding.h +++ b/src/script/sigencoding.h @@ -37,12 +37,21 @@ /** * Check that the signature provided to authentify a transaction is properly - * encoded. Signatures passed to OP_CHECKSIG, OP_CHECKMULTISIG and their verify - * variants must be checked using this function. + * encoded. Signatures passed to OP_CHECKSIG and its verify variant must be + * checked using this function. */ bool CheckTransactionSignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror); +/** + * Check that the signature provided to authentify a transaction is properly + * encoded ECDSA signature. Signatures passed to OP_CHECKMULTISIG and its verify + * variant must be checked using this function. + */ +bool CheckTransactionECDSASignatureEncoding(const valtype &vchSig, + uint32_t flags, + ScriptError *serror); + /** * Check that a public key is encoded properly. */ diff --git a/src/script/sigencoding.cpp b/src/script/sigencoding.cpp --- a/src/script/sigencoding.cpp +++ b/src/script/sigencoding.cpp @@ -214,6 +214,12 @@ return true; } +bool CheckTransactionECDSASignatureEncoding(const valtype &vchSig, + uint32_t flags, + ScriptError *serror) { + return CheckTransactionSignatureEncoding(vchSig, flags, serror); +} + static bool IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { switch (vchPubKey.size()) { case 33: diff --git a/src/test/sigencoding_tests.cpp b/src/test/sigencoding_tests.cpp --- a/src/test/sigencoding_tests.cpp +++ b/src/test/sigencoding_tests.cpp @@ -39,6 +39,8 @@ SigHashType sigHash = baseSigHash.withForkId(hasForkId); valtype validSig = SignatureWithHashType(vchSig, sigHash); BOOST_CHECK(CheckTransactionSignatureEncoding(validSig, flags, &err)); + BOOST_CHECK( + CheckTransactionECDSASignatureEncoding(validSig, flags, &err)); // If we have strict encoding, we prevent the use of undefined flags. std::array undefSigHashes{ @@ -50,6 +52,9 @@ BOOST_CHECK_EQUAL( CheckTransactionSignatureEncoding(undefSighash, flags, &err), !hasStrictEnc); + BOOST_CHECK_EQUAL(CheckTransactionECDSASignatureEncoding( + undefSighash, flags, &err), + !hasStrictEnc); if (hasStrictEnc) { BOOST_CHECK_EQUAL(err, SCRIPT_ERR_SIG_HASHTYPE); } @@ -62,6 +67,9 @@ BOOST_CHECK_EQUAL( CheckTransactionSignatureEncoding(invalidSig, flags, &err), !hasStrictEnc); + BOOST_CHECK_EQUAL( + CheckTransactionECDSASignatureEncoding(invalidSig, flags, &err), + !hasStrictEnc); if (hasStrictEnc) { BOOST_CHECK_EQUAL(err, hasForkId ? SCRIPT_ERR_MUST_USE_FORKID : SCRIPT_ERR_ILLEGAL_FORKID); @@ -164,6 +172,7 @@ // Empty sig is always valid. BOOST_CHECK(CheckDataSignatureEncoding({}, flags, &err)); BOOST_CHECK(CheckTransactionSignatureEncoding({}, flags, &err)); + BOOST_CHECK(CheckTransactionECDSASignatureEncoding({}, flags, &err)); // Signature are valid as long as the forkid flag is correct. CheckSignatureEncodingWithSigHashType(minimalSig, flags);