txscript: Correct OP_CHECKMULTSIG handling.

This commit corrects a case in the OP_CHECKMULTISIG handling where it was
possible to improperly validate a transaction that had a combination of
valid and malformed signatures.

It also adds a new test to ensure this case is properly handled and nukes
a superfluous comment.

Fixes #293.
This commit is contained in:
Dave Collins 2015-02-10 05:02:09 -06:00
parent f82f7b6663
commit a8a26aabb6
2 changed files with 9 additions and 5 deletions

View file

@ -381,7 +381,12 @@
["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "nPubKeys > 20"],
["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "nSigs > nPubKeys"],
[
"0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f",
"2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG",
"P2SH,STRICTENC",
"2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs"
],
["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Tests for Script.IsPushOnly()"],
["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"],

View file

@ -1838,15 +1838,11 @@ type sig struct {
// stack; sigs <numsigs> pubkeys <numpubkeys>
func opcodeCheckMultiSig(op *parsedOpcode, s *Script) error {
numPubkeys, err := s.dstack.PopInt()
if err != nil {
return err
}
// XXX arbitrary limits
// nore more than 20 pubkeys, or 201 operations
// PopInt promises that the int returned is 32 bit.
npk := int(numPubkeys.Int64())
if npk < 0 || npk > MaxPubKeysPerMultiSig {
@ -1921,6 +1917,9 @@ func opcodeCheckMultiSig(op *parsedOpcode, s *Script) error {
if len(signatures) == 0 {
s.dstack.PushBool(nsig == 0)
return nil
} else if len(signatures) < nsig {
s.dstack.PushBool(false)
return nil
}
// Trim OP_CODESEPARATORs