Remove in-band error signalling from SignatureHash, fixing the SIGHASH_SINGLE bug.
This commit is contained in:
@@ -1095,17 +1095,16 @@ public:
|
||||
|
||||
uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
|
||||
{
|
||||
static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) {
|
||||
// nIn out of range
|
||||
return one;
|
||||
throw logic_error("input index is out of range");
|
||||
}
|
||||
|
||||
// Check for invalid use of SIGHASH_SINGLE
|
||||
if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
|
||||
if (nIn >= txTo.vout.size()) {
|
||||
// nOut out of range
|
||||
return one;
|
||||
throw logic_error("no matching output for SIGHASH_SINGLE");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1136,7 +1135,12 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn
|
||||
int nHashType = vchSig.back();
|
||||
vchSig.pop_back();
|
||||
|
||||
uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
|
||||
uint256 sighash;
|
||||
try {
|
||||
sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
|
||||
} catch (logic_error ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!VerifySignature(vchSig, pubkey, sighash))
|
||||
return false;
|
||||
|
||||
@@ -25,7 +25,13 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
|
||||
if (!keystore->GetKey(address, key))
|
||||
return false;
|
||||
|
||||
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
|
||||
uint256 hash;
|
||||
try {
|
||||
hash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
|
||||
} catch (logic_error ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!key.Sign(hash, vchSig))
|
||||
return false;
|
||||
vchSig.push_back((unsigned char)nHashType);
|
||||
|
||||
Reference in New Issue
Block a user