diff --git a/src/pow.cpp b/src/pow.cpp index 87be47a01a..6841a7b30a 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -80,7 +80,8 @@ bool CheckProof(const CBlockHeader& block, const Consensus::Params& params) | SCRIPT_VERIFY_MINIMALDATA // Pushes are minimally-sized | SCRIPT_VERIFY_SIGPUSHONLY // Witness is push-only | SCRIPT_VERIFY_LOW_S // Stop easiest signature fiddling - | SCRIPT_VERIFY_WITNESS; // Required for cleanstack eval in VerifyScript + | SCRIPT_VERIFY_WITNESS // Required for cleanstack eval in VerifyScript + | SCRIPT_NO_SIGHASH_BYTE; // non-Check(Multi)Sig signatures will not have sighash byte return GenericVerifyScript(block.proof.solution, block.proof.challenge, proof_flags, block); } diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 31f76063ab..524040aea6 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -223,12 +223,19 @@ bool CheckSignatureEncoding(const vector &vchSig, unsigned int fl if (vchSig.size() == 0) { return true; } - if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) { + bool no_hash_byte = (flags & SCRIPT_NO_SIGHASH_BYTE) == SCRIPT_NO_SIGHASH_BYTE; + std::vector vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size()); + // Push a dummy sighash byte to pass checks + if (no_hash_byte) { + vchSigCopy.push_back(SIGHASH_ALL); + } + + if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSigCopy)) { return set_error(serror, SCRIPT_ERR_SIG_DER); - } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { + } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSigCopy, serror)) { // serror is set return false; - } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) { + } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSigCopy)) { return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); } return true; @@ -1313,8 +1320,8 @@ bool EvalScript(vector >& stack, const CScript& script, un valtype& vchData = stacktop(-2); valtype& vchPubKey = stacktop(-1); - // Sigs from stack have no hash type, so we disable strictenc check - if (!CheckSignatureEncoding(vchSig, (flags & ~SCRIPT_VERIFY_STRICTENC), serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { + // Sigs from stack have no hash byte ever + if (!CheckSignatureEncoding(vchSig, (flags | SCRIPT_NO_SIGHASH_BYTE), serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { //serror is set return false; } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 58ee3a3705..0eafb26387 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -107,6 +107,10 @@ enum // Public keys in segregated witness scripts must be compressed // SCRIPT_VERIFY_WITNESS_PUBKEYTYPE = (1U << 15), + + // Signature checking assumes no sighash byte after the DER signature + // + SCRIPT_NO_SIGHASH_BYTE = (1U << 16), };