libconsensus: Add input validation of flags
Makes it an error to use flags that have not been defined on the libconsensus API. There has been some confusion as to what pass to libconsensus, and (combined with mention in the release notes) this should clear it up. Using undocumented flags is a risk because their meaning, and what combinations are allowed, changes from release to release. E.g. it is no longer possible to pass (CLEANSTACK | P2SH) without running into an assertion after the segwit changes.
This commit is contained in:
parent
c587577356
commit
5ca8ef299a
|
@ -69,10 +69,19 @@ struct ECCryptoClosure
|
|||
ECCryptoClosure instance_of_eccryptoclosure;
|
||||
}
|
||||
|
||||
/** Check that all specified flags are part of the libconsensus interface. */
|
||||
static bool verify_flags(unsigned int flags)
|
||||
{
|
||||
return (flags & ~(bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL)) == 0;
|
||||
}
|
||||
|
||||
static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, CAmount amount,
|
||||
const unsigned char *txTo , unsigned int txToLen,
|
||||
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
|
||||
{
|
||||
if (!verify_flags(flags)) {
|
||||
return bitcoinconsensus_ERR_INVALID_FLAGS;
|
||||
}
|
||||
try {
|
||||
TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen);
|
||||
CTransaction tx;
|
||||
|
|
|
@ -42,6 +42,7 @@ typedef enum bitcoinconsensus_error_t
|
|||
bitcoinconsensus_ERR_TX_SIZE_MISMATCH,
|
||||
bitcoinconsensus_ERR_TX_DESERIALIZE,
|
||||
bitcoinconsensus_ERR_AMOUNT_REQUIRED,
|
||||
bitcoinconsensus_ERR_INVALID_FLAGS,
|
||||
} bitcoinconsensus_error;
|
||||
|
||||
/** Script verification flags */
|
||||
|
@ -54,6 +55,9 @@ enum
|
|||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65)
|
||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // enable CHECKSEQUENCEVERIFY (BIP112)
|
||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS = (1U << 11), // enable WITNESS (BIP141)
|
||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG |
|
||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY |
|
||||
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS
|
||||
};
|
||||
|
||||
/// Returns 1 if the input nIn of the serialized transaction pointed to by
|
||||
|
|
|
@ -173,11 +173,14 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
|
|||
#if defined(HAVE_CONSENSUS_LIB)
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
stream << tx2;
|
||||
int libconsensus_flags = flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL;
|
||||
if (libconsensus_flags == flags) {
|
||||
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
|
||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message);
|
||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect, message);
|
||||
} else {
|
||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect, message);
|
||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message);
|
||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect, message);
|
||||
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect,message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue