mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Add SimpleSignatureChecker, SCRIPT_NO_SIGHASH_BYTE validation flag
This commit is contained in:
parent
6c91446982
commit
7bc578a398
6 changed files with 78 additions and 6 deletions
|
|
@ -159,6 +159,7 @@ BITCOIN_CORE_H = \
|
|||
rpc/util.h \
|
||||
scheduler.h \
|
||||
script/descriptor.h \
|
||||
script/generic.hpp \
|
||||
script/ismine.h \
|
||||
script/sigcache.h \
|
||||
script/sign.h \
|
||||
|
|
|
|||
59
src/script/generic.hpp
Normal file
59
src/script/generic.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef H_BITCOIN_SCRIPT_GENERIC
|
||||
#define H_BITCOIN_SCRIPT_GENERIC
|
||||
|
||||
#include <hash.h>
|
||||
#include <script/interpreter.h>
|
||||
#include <script/sign.h>
|
||||
#include <keystore.h>
|
||||
|
||||
class SimpleSignatureChecker : public BaseSignatureChecker
|
||||
{
|
||||
public:
|
||||
uint256 hash;
|
||||
|
||||
SimpleSignatureChecker(const uint256& hashIn) : hash(hashIn) {};
|
||||
bool CheckSig(const std::vector<unsigned char>& vchSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
|
||||
{
|
||||
CPubKey pubkey(vchPubKey);
|
||||
if (!pubkey.IsValid())
|
||||
return false;
|
||||
if (vchSig.empty())
|
||||
return false;
|
||||
return pubkey.Verify(hash, vchSig);
|
||||
}
|
||||
};
|
||||
|
||||
class SimpleSignatureCreator : public BaseSignatureCreator
|
||||
{
|
||||
SimpleSignatureChecker checker;
|
||||
|
||||
public:
|
||||
SimpleSignatureCreator(const uint256& hashIn) : checker(hashIn) {};
|
||||
const BaseSignatureChecker& Checker() const { return checker; }
|
||||
bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
|
||||
{
|
||||
CKey key;
|
||||
if (!provider.GetKey(keyid, key))
|
||||
return false;
|
||||
return key.Sign(checker.hash, vchSig);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool GenericVerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const T& data)
|
||||
{
|
||||
return VerifyScript(scriptSig, scriptPubKey, NULL, flags, SimpleSignatureChecker(SerializeHash(data)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GenericSignScript(const CKeyStore& keystore, const T& data, const CScript& fromPubKey, SignatureData& scriptSig)
|
||||
{
|
||||
return ProduceSignature(keystore, SimpleSignatureCreator(SerializeHash(data)), fromPubKey, scriptSig, SCRIPT_NO_SIGHASH_BYTE);
|
||||
}
|
||||
|
||||
#endif // H_BITCOIN_SCRIPT_GENERIC
|
||||
|
|
@ -203,12 +203,20 @@ bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned i
|
|||
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<unsigned char> 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;
|
||||
|
|
|
|||
|
|
@ -115,6 +115,10 @@ enum
|
|||
// Making OP_CODESEPARATOR and FindAndDelete fail any non-segwit scripts
|
||||
//
|
||||
SCRIPT_VERIFY_CONST_SCRIPTCODE = (1U << 16),
|
||||
|
||||
// Signature checking assumes no sighash byte after the DER signature
|
||||
//
|
||||
SCRIPT_NO_SIGHASH_BYTE = (1U << 17),
|
||||
};
|
||||
|
||||
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ static CScript PushAll(const std::vector<valtype>& values)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
|
||||
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata, unsigned int additional_flags)
|
||||
{
|
||||
if (sigdata.complete) return true;
|
||||
|
||||
|
|
@ -234,7 +234,7 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
|
|||
sigdata.scriptSig = PushAll(result);
|
||||
|
||||
// Test solution
|
||||
sigdata.complete = solved && VerifyScript(sigdata.scriptSig, fromPubKey, &sigdata.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker());
|
||||
sigdata.complete = solved && VerifyScript(sigdata.scriptSig, fromPubKey, &sigdata.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS|additional_flags, creator.Checker());
|
||||
return sigdata.complete;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -680,7 +680,7 @@ struct PartiallySignedTransaction
|
|||
};
|
||||
|
||||
/** Produce a script signature using a generic signature creator. */
|
||||
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
|
||||
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata, unsigned int additional_flags=0);
|
||||
|
||||
/** Produce a script signature for a transaction. */
|
||||
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue