Add policy: null signature for failed CHECK(MULTI)SIG

e41bd449ab
This commit is contained in:
lateminer
2018-01-13 13:26:20 +03:00
parent bba401c693
commit 1506d6b0ae
5 changed files with 21 additions and 1 deletions

View File

@@ -930,6 +930,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
}
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode);
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size())
return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
popstack(stack);
popstack(stack);
stack.push_back(fSuccess ? vchTrue : vchFalse);
@@ -959,6 +962,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
if (nOpCount > MAX_OPS_PER_SCRIPT)
return set_error(serror, SCRIPT_ERR_OP_COUNT);
int ikey = ++i;
// ikey2 is the position of last non-signature item in the stack. Top stack item = 1.
// With SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if operation fails.
int ikey2 = nKeysCount + 2;
i += nKeysCount;
if ((int)stack.size() < i)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
@@ -1013,8 +1019,14 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
}
// Clean up stack of actual arguments
while (i-- > 1)
while (i-- > 1) {
// If the operation failed, we require that all signatures must be empty vector
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && !ikey2 && stacktop(-1).size())
return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
if (ikey2 > 0)
ikey2--;
popstack(stack);
}
// A bug causes CHECKMULTISIG to consume one extra argument
// whose contents were not checked in any way.

View File

@@ -90,6 +90,10 @@ enum
//
// See BIP112 for details
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10),
// Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed
//
SCRIPT_VERIFY_NULLFAIL = (1U << 14),
};
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);

View File

@@ -63,6 +63,8 @@ const char* ScriptErrorString(const ScriptError serror)
return "Non-canonical signature: S value is unnecessarily high";
case SCRIPT_ERR_SIG_NULLDUMMY:
return "Dummy CHECKMULTISIG argument must be zero";
case SCRIPT_ERR_SIG_NULLFAIL:
return "Signature must be zero for failed CHECK(MULTI)SIG operation";
case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS:
return "NOPx reserved for soft-fork upgrades";
case SCRIPT_ERR_PUBKEYTYPE:

View File

@@ -48,6 +48,7 @@ typedef enum ScriptError_t
SCRIPT_ERR_SIG_NULLDUMMY,
SCRIPT_ERR_PUBKEYTYPE,
SCRIPT_ERR_CLEANSTACK,
SCRIPT_ERR_SIG_NULLFAIL,
/* softfork safeness */
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS,