Remove in-band error signalling from SignatureHash, fixing the SIGHASH_SINGLE bug.

This commit is contained in:
Taylor Hornby
2016-07-11 17:00:04 -06:00
parent 85cc6f5b44
commit 67f0243533
6 changed files with 19 additions and 20 deletions

View File

@@ -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;

View File

@@ -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);