Reject blocks with non-canonical signatures starting from protocol version 60016
This commit is contained in:
19
src/main.cpp
19
src/main.cpp
@@ -3884,22 +3884,27 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
|
||||
return (nFound >= nRequired);
|
||||
}
|
||||
|
||||
bool static IsCanonicalBlockSignature(const CBlock* pblock)
|
||||
bool static IsCanonicalBlockSignature(const CBlock* pblock, bool checkLowS)
|
||||
{
|
||||
if (pblock->IsProofOfWork()) {
|
||||
return pblock->vchBlockSig.empty();
|
||||
}
|
||||
|
||||
return IsLowDERSignature(pblock->vchBlockSig, NULL, false);
|
||||
return checkLowS ? IsLowDERSignature(pblock->vchBlockSig, NULL, false) : IsDERSignature(pblock->vchBlockSig, NULL, false);
|
||||
}
|
||||
|
||||
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, bool fMayBanPeerIfInvalid)
|
||||
{
|
||||
if (!IsCanonicalBlockSignature(pblock)) {
|
||||
if (pfrom && pfrom->nVersion >= CANONICAL_BLOCK_SIG_VERSION)
|
||||
return state.DoS(100, error("ProcessNewBlock(): bad block signature encoding"),
|
||||
REJECT_INVALID, "bad-block-signature-encoding");
|
||||
return false;
|
||||
if (!IsCanonicalBlockSignature(pblock, false)) {
|
||||
if (pfrom && pfrom->nVersion >= CANONICAL_BLOCK_SIG_VERSION)
|
||||
return state.DoS(100, error("ProcessNewBlock(): bad block signature encoding"),
|
||||
REJECT_INVALID, "bad-block-signature-encoding");
|
||||
}
|
||||
|
||||
if (!IsCanonicalBlockSignature(pblock, true)) {
|
||||
if (pfrom && pfrom->nVersion >= CANONICAL_BLOCK_SIG_LOW_S_VERSION)
|
||||
return state.DoS(100, error("ProcessNewBlock(): bad block signature encoding (low-s)"),
|
||||
REJECT_INVALID, "bad-block-signature-encoding");
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -176,30 +176,19 @@ bool IsLowDERSignature(const valtype &vchSig, ScriptError* serror, bool haveHash
|
||||
if (!IsValidSignatureEncoding(vchSig, haveHashType)) {
|
||||
return set_error(serror, SCRIPT_ERR_SIG_DER);
|
||||
}
|
||||
unsigned int nLenR = vchSig[3];
|
||||
unsigned int nLenS = vchSig[5+nLenR];
|
||||
const unsigned char *S = &vchSig[6+nLenR];
|
||||
// If the S value is above the order of the curve divided by two, its
|
||||
// complement modulo the order could have been used instead, which is
|
||||
// one byte shorter when encoded correctly.
|
||||
if (!CPubKey::CheckSignatureElement(S, nLenS, true))
|
||||
return set_error(serror, SCRIPT_ERR_SIG_HIGH_S);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
bool IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
|
||||
if (!IsValidSignatureEncoding(vchSig)) {
|
||||
return set_error(serror, SCRIPT_ERR_SIG_DER);
|
||||
}
|
||||
std::vector<unsigned char> vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1);
|
||||
std::vector<unsigned char> vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - (haveHashType ? 1 : 0));
|
||||
if (!CPubKey::CheckLowS(vchSigCopy)) {
|
||||
return set_error(serror, SCRIPT_ERR_SIG_HIGH_S);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
bool IsDERSignature(const valtype &vchSig, ScriptError* serror, bool haveHashType) {
|
||||
if (!IsValidSignatureEncoding(vchSig, haveHashType)) {
|
||||
return set_error(serror, SCRIPT_ERR_SIG_DER);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
|
||||
if (vchSig.size() == 0) {
|
||||
|
||||
@@ -162,6 +162,7 @@ public:
|
||||
|
||||
bool IsCompressedOrUncompressedPubKey(const std::vector<unsigned char> &vchPubKey);
|
||||
bool IsLowDERSignature(const std::vector<unsigned char> &vchSig, ScriptError* serror, bool haveHashType = true);
|
||||
bool IsDERSignature(const std::vector<unsigned char> &vchSig, ScriptError* serror, bool haveHashType = true);
|
||||
|
||||
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
|
||||
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
|
||||
|
||||
@@ -17,8 +17,9 @@ static const int INIT_PROTO_VERSION = 209;
|
||||
//! In this version, 'getheaders' was introduced.
|
||||
static const int GETHEADERS_VERSION = 31800;
|
||||
|
||||
//! demand canonical block signatures starting from this version
|
||||
static const int CANONICAL_BLOCK_SIG_VERSION = 60018;
|
||||
//! reject blocks with non-canonical signatures starting from this version
|
||||
static const int CANONICAL_BLOCK_SIG_VERSION = 60016;
|
||||
static const int CANONICAL_BLOCK_SIG_LOW_S_VERSION = 60018;
|
||||
|
||||
//! disconnect from peers older than this proto version
|
||||
static const int MIN_PEER_PROTO_VERSION = CANONICAL_BLOCK_SIG_VERSION;
|
||||
|
||||
Reference in New Issue
Block a user