From a8a26aabb6b393c8f543dfce450aa6030d1f84f5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 10 Feb 2015 05:02:09 -0600 Subject: [PATCH] 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. --- txscript/data/script_invalid.json | 7 ++++++- txscript/opcode.go | 7 +++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/txscript/data/script_invalid.json b/txscript/data/script_invalid.json index 4f1d5543..0cf4e4ea 100644 --- a/txscript/data/script_invalid.json +++ b/txscript/data/script_invalid.json @@ -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"], diff --git a/txscript/opcode.go b/txscript/opcode.go index 63aab2d9..07619778 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -1838,15 +1838,11 @@ type sig struct { // stack; sigs pubkeys 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