From a5240a08a7d624d20344344b79441c67311f7fd9 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Sat, 19 Jul 2014 02:17:52 +0400 Subject: [PATCH] Extended signature format checkings. --- src/kernel.cpp | 2 +- src/main.cpp | 14 +++++++------- src/main.h | 4 ++-- src/rpcrawtransaction.cpp | 2 +- src/script.cpp | 2 +- src/script.h | 17 +++++++++++------ 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index bf3fade..ec0803c 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -397,7 +397,7 @@ bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hash return tx.DoS(1, error("CheckProofOfStake() : INFO: read txPrev failed")); // previous transaction not in main chain, may occur during initial download // Verify signature - if (!VerifySignature(txPrev, tx, 0, STANDARD_SCRIPT_VERIFY_FLAGS, 0)) + if (!VerifySignature(txPrev, tx, 0, MANDATORY_SCRIPT_VERIFY_FLAGS, 0)) return tx.DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str())); // Read block header diff --git a/src/main.cpp b/src/main.cpp index a63c008..14e7ce3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -726,7 +726,7 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!tx.ConnectInputs(txdb, mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false, true, STANDARD_SCRIPT_VERIFY_FLAGS)) + if (!tx.ConnectInputs(txdb, mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false, true, VALIDATION_SWITCH_TIME < tx.nTime ? STRICT_FLAGS : SOFT_FLAGS)) { return error("CTxMemPool::accept() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str()); } @@ -1544,14 +1544,14 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, map& mapTestPool, const CDiskTxPos& posThisTx, const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fScriptChecks=true, - unsigned int flags=STANDARD_SCRIPT_VERIFY_FLAGS, std::vector *pvChecks = NULL); + unsigned int flags=STRICT_FLAGS, std::vector *pvChecks = NULL); bool ClientConnectInputs(); bool CheckTransaction() const; bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index d019a82..a7e8a93 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -502,7 +502,7 @@ Value signrawtransaction(const Array& params, bool fHelp) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS, 0)) + if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STRICT_FLAGS, 0)) fComplete = false; } diff --git a/src/script.cpp b/src/script.cpp index bcd3e94..c629438 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1647,7 +1647,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransa } // Test solution - return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STANDARD_SCRIPT_VERIFY_FLAGS, 0); + return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STRICT_FLAGS, 0); } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType) diff --git a/src/script.h b/src/script.h index ed03059..60ef0e4 100644 --- a/src/script.h +++ b/src/script.h @@ -40,24 +40,29 @@ enum SCRIPT_VERIFY_NULLDUMMY = (1U << 4), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length }; +// Strict verification: +// +// * force DER encoding; +// * force low S; +// * ensure that CHECKMULTISIG dummy argument is null. +static const unsigned int STRICT_FORMAT_FLAGS = SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_NULLDUMMY; + // Mandatory script verification flags that all new blocks must comply with for // them to be valid. (but old blocks may not comply with) Currently just P2SH, // but in the future other flags may be added, such as a soft-fork to enforce // strict DER encoding. // -// Failing one of these tests may trigger a DoS ban - see CheckInputs() for +// Failing one of these tests may trigger a DoS ban - see ConnectInputs() for // details. static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH; // Standard script verification flags that standard transactions will comply // with. However scripts violating these flags may still be present in valid // blocks and we must accept those blocks. -static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | - SCRIPT_VERIFY_STRICTENC | - SCRIPT_VERIFY_NULLDUMMY; +static const unsigned int STRICT_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | STRICT_FORMAT_FLAGS; -// For convenience, standard but not mandatory verify flags. -static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; +// Soft verifications, no extended signature format checkings +static const unsigned int SOFT_FLAGS = STRICT_FLAGS & ~STRICT_FORMAT_FLAGS; enum txnouttype { -- 1.7.1