mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-27 16:48:09 +00:00
New unit tests for signing (bitcoin cash)
This commit is contained in:
parent
efe36b3a2f
commit
9917d9ebfc
@ -36,6 +36,7 @@ TXHASH_c63e24 = binascii.unhexlify(b'c63e24ed820c5851b60c54613fbc4bcb37df6cd49b4
|
||||
TXHASH_c6be22 = binascii.unhexlify(b'c6be22d34946593bcad1d2b013e12f74159e69574ffea21581dad115572e031c')
|
||||
TXHASH_d5f65e = binascii.unhexlify(b'd5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882')
|
||||
TXHASH_d6da21 = binascii.unhexlify(b'd6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236')
|
||||
TXHASH_d2dcda = binascii.unhexlify('d2dcdaf547ea7f57a713c607f15e883ddc4a98167ee2c43ed953c53cb5153e24')
|
||||
|
||||
|
||||
class TestMsgSigntx(common.TrezorTest):
|
||||
@ -619,6 +620,78 @@ class TestMsgSigntx(common.TrezorTest):
|
||||
# Now run the attack, must trigger the exception
|
||||
self.assertRaises(CallException, self.client.sign_tx, 'Bitcoin', [inp1, inp2], [out1, out2], debug_processor=attack_processor)
|
||||
|
||||
def test_attack_change_input_address(self):
|
||||
# This unit test attempts to modify input address after the Trezor checked
|
||||
# that it matches the change output
|
||||
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiTestnet)
|
||||
|
||||
inp1 = proto_types.TxInputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/0/0"),
|
||||
# moUJnmge8SRXuediK7bW6t4YfrPqbE6hD7
|
||||
prev_hash=TXHASH_d2dcda,
|
||||
prev_index=1,
|
||||
script_type=proto_types.SPENDADDRESS,
|
||||
)
|
||||
|
||||
out1 = proto_types.TxOutputType(
|
||||
address='mwue7mokpBRAsJtHqEMcRPanYBmsSmYKvY',
|
||||
amount=100000,
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
out2 = proto_types.TxOutputType(
|
||||
address_n=self.client.expand_path("44'/1'/12345'/1/0"),
|
||||
amount=123400000-5000-100000,
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
global run_attack
|
||||
run_attack = True
|
||||
|
||||
def attack_processor(req, msg):
|
||||
import sys
|
||||
global run_attack
|
||||
|
||||
if req.details.tx_hash != b'':
|
||||
return msg
|
||||
|
||||
if req.request_type != proto_types.TXINPUT:
|
||||
return msg
|
||||
|
||||
if req.details.request_index != 0:
|
||||
return msg
|
||||
|
||||
if not run_attack:
|
||||
return msg
|
||||
|
||||
msg.inputs[0].address_n[2] = 12345 + 0x80000000
|
||||
run_attack = False
|
||||
return msg
|
||||
|
||||
# Test if the transaction can be signed normally
|
||||
(_, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2])
|
||||
|
||||
self.assertEqual(binascii.hexlify(serialized_tx), b'0100000001243e15b53cc553d93ec4e27e16984adc3d885ef107c613a7577fea47f5dadcd2010000006a47304402207d517dcb6b823bba4d252da096795a7f914d0c477aee26e554ba61653c45608a02202cba1e805c586c830472f399510be5d42c2fcfd67b8a6b0690cbe8a3e6e475e801210364430c9122948e525e2f1c6d88f00f47679274f0810fd8c63754954f310995c1ffffffff02a0860100000000001976a914b3cc67f3349974d0f1b50e9bb5dfdf226f888fa088ac18555907000000001976a91485a3f5b0d23cdd61f5f8e1eb8c9ca0890dd15a9788ac00000000')
|
||||
|
||||
# Now run the attack, must trigger the exception
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=TXHASH_d2dcda)),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d2dcda)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=TXHASH_d2dcda)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=TXHASH_d2dcda)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.Failure(code=proto_types.Failure_ProcessError),
|
||||
])
|
||||
self.assertRaises(CallException, self.client.sign_tx, 'Testnet', [inp1], [out1, out2], debug_processor=attack_processor)
|
||||
|
||||
def test_spend_coinbase(self):
|
||||
# 25 TEST generated to m/1 (mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV)
|
||||
# tx: d6da21677d7cca5f42fbc7631d062c9ae918a0254f7c6c22de8e8cb7fd5b8236
|
||||
|
210
tests/device_tests/test_msg_signtx_bcc.py
Normal file
210
tests/device_tests/test_msg_signtx_bcc.py
Normal file
@ -0,0 +1,210 @@
|
||||
# This file is part of the TREZOR project.
|
||||
#
|
||||
# Copyright (C) 2017 Jochen Hoenicke <hoenicke@gmail.com>
|
||||
#
|
||||
# This library is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import unittest
|
||||
import common
|
||||
import binascii
|
||||
|
||||
import trezorlib.messages_pb2 as proto
|
||||
import trezorlib.types_pb2 as proto_types
|
||||
from trezorlib.tx_api import TxApiTestnet
|
||||
from trezorlib.ckd_public import deserialize
|
||||
from trezorlib.client import CallException
|
||||
|
||||
|
||||
class TestMsgSigntxSegwit(common.TrezorTest):
|
||||
|
||||
def test_send_bcc_change(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiTestnet)
|
||||
inp1 = proto_types.TxInputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/0/0"),
|
||||
# moUJnmge8SRXuediK7bW6t4YfrPqbE6hD7
|
||||
amount=123400000,
|
||||
prev_hash=binascii.unhexlify('d2dcdaf547ea7f57a713c607f15e883ddc4a98167ee2c43ed953c53cb5153e24'),
|
||||
prev_index=1,
|
||||
script_type=proto_types.SPENDADDRESS,
|
||||
)
|
||||
inp2 = proto_types.TxInputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/0/1"),
|
||||
# mhSeXqbaojGkaezxgwobgMxGHzv79x7rhK
|
||||
amount=43210000,
|
||||
prev_hash=binascii.unhexlify('fe26bc077de27b72ffc5ce77a7e296c7c855b7deb3dec72a3f82c0c07c722bb0'),
|
||||
prev_index=1,
|
||||
script_type=proto_types.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto_types.TxOutputType(
|
||||
address='mwue7mokpBRAsJtHqEMcRPanYBmsSmYKvY',
|
||||
amount=100000000,
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto_types.TxOutputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/1/0"),
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
amount=23400000 + 43210000 - 5000
|
||||
)
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto_types.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = self.client.sign_tx('Testnet Cash', [inp1,inp2], [out1, out2])
|
||||
|
||||
print(binascii.hexlify(serialized_tx))
|
||||
self.assertEqual(binascii.hexlify(serialized_tx), b'0100000002243e15b53cc553d93ec4e27e16984adc3d885ef107c613a7577fea47f5dadcd2010000006b483045022100ebcce894cac5d1750f4b1abc7d8c0a5d25944c12a02942b0cc1c89c397acc09602207335077bd698cefc1694d5817abdb3b7aecfcd110ca07729d893577ada71d35441210364430c9122948e525e2f1c6d88f00f47679274f0810fd8c63754954f310995c1ffffffffb02b727cc0c0823f2ac7deb3deb755c8c796e2a777cec5ff727be27d07bc26fe010000006b4830450221008a140434b3f105686c6c4a704c9f2d09b2faf633b81b9ec2304b81f2fd617a9c0220497279b656c4034fd30c41c6f1d0e2ad2aa1b867575aa8f4c13218cb8c114140412103749e3f0a7b01f73427ed67c1cedbb4ecd2315ad6b7c2513355393b95d1ba6137ffffffff0200e1f505000000001976a914b3cc67f3349974d0f1b50e9bb5dfdf226f888fa088acc84ff803000000001976a914f80fb232a1e54b1fa732bc120cae72eabd7fcf6888ac00000000')
|
||||
|
||||
|
||||
def test_attack_amount(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiTestnet)
|
||||
inp1 = proto_types.TxInputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/0/0"),
|
||||
# moUJnmge8SRXuediK7bW6t4YfrPqbE6hD7
|
||||
amount=123399999,
|
||||
prev_hash=binascii.unhexlify('d2dcdaf547ea7f57a713c607f15e883ddc4a98167ee2c43ed953c53cb5153e24'),
|
||||
prev_index=1,
|
||||
script_type=proto_types.SPENDADDRESS,
|
||||
)
|
||||
inp2 = proto_types.TxInputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/0/1"),
|
||||
# mhSeXqbaojGkaezxgwobgMxGHzv79x7rhK
|
||||
amount=43210000,
|
||||
prev_hash=binascii.unhexlify('fe26bc077de27b72ffc5ce77a7e296c7c855b7deb3dec72a3f82c0c07c722bb0'),
|
||||
prev_index=1,
|
||||
script_type=proto_types.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto_types.TxOutputType(
|
||||
address='mwue7mokpBRAsJtHqEMcRPanYBmsSmYKvY',
|
||||
amount=100000000,
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto_types.TxOutputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/1/0"),
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
amount=23399999 + 43210000 - 5000
|
||||
)
|
||||
|
||||
global run_attack
|
||||
run_attack = True
|
||||
|
||||
def attack_processor(req, msg):
|
||||
import sys
|
||||
global run_attack
|
||||
|
||||
if req.details.tx_hash != b'':
|
||||
return msg
|
||||
|
||||
if req.request_type != proto_types.TXINPUT:
|
||||
return msg
|
||||
|
||||
if req.details.request_index != 0:
|
||||
return msg
|
||||
|
||||
if not run_attack:
|
||||
return msg
|
||||
|
||||
msg.inputs[0].amount = 123400000
|
||||
run_attack = False
|
||||
return msg
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.Failure(code=proto_types.Failure_ProcessError),
|
||||
])
|
||||
self.assertRaises(CallException, self.client.sign_tx, 'Testnet Cash', [inp1, inp2], [out1, out2], debug_processor=attack_processor)
|
||||
|
||||
def test_attack_change_input(self):
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiTestnet)
|
||||
inp1 = proto_types.TxInputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/0/0"),
|
||||
# moUJnmge8SRXuediK7bW6t4YfrPqbE6hD7
|
||||
amount=123400000,
|
||||
prev_hash=binascii.unhexlify('d2dcdaf547ea7f57a713c607f15e883ddc4a98167ee2c43ed953c53cb5153e24'),
|
||||
prev_index=1,
|
||||
script_type=proto_types.SPENDADDRESS,
|
||||
)
|
||||
inp2 = proto_types.TxInputType(
|
||||
address_n=self.client.expand_path("44'/1'/4'/0/1"),
|
||||
# mhSeXqbaojGkaezxgwobgMxGHzv79x7rhK
|
||||
amount=43210000,
|
||||
prev_hash=binascii.unhexlify('fe26bc077de27b72ffc5ce77a7e296c7c855b7deb3dec72a3f82c0c07c722bb0'),
|
||||
prev_index=1,
|
||||
script_type=proto_types.SPENDADDRESS,
|
||||
)
|
||||
out1 = proto_types.TxOutputType(
|
||||
address='mwue7mokpBRAsJtHqEMcRPanYBmsSmYKvY',
|
||||
amount=100000000,
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto_types.TxOutputType(
|
||||
address_n=self.client.expand_path("44'/1'/1'/1/0"),
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
amount=23400000 + 43210000 - 5000
|
||||
)
|
||||
|
||||
global attack_ctr
|
||||
attack_ctr = 0
|
||||
|
||||
def attack_processor(req, msg):
|
||||
import sys
|
||||
global attack_ctr
|
||||
|
||||
if req.details.tx_hash != b'':
|
||||
return msg
|
||||
|
||||
if req.request_type != proto_types.TXINPUT:
|
||||
return msg
|
||||
|
||||
attack_ctr += 1
|
||||
if attack_ctr > 2:
|
||||
return msg
|
||||
|
||||
msg.inputs[0].address_n[2] = 1 + 0x80000000
|
||||
return msg
|
||||
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.Failure(code=proto_types.Failure_ProcessError),
|
||||
])
|
||||
self.assertRaises(CallException, self.client.sign_tx, 'Testnet Cash', [inp1, inp2], [out1, out2], debug_processor=attack_processor)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -23,6 +23,7 @@ import trezorlib.messages_pb2 as proto
|
||||
import trezorlib.types_pb2 as proto_types
|
||||
from trezorlib.tx_api import TxApiTestnet
|
||||
from trezorlib.ckd_public import deserialize
|
||||
from trezorlib.client import CallException
|
||||
|
||||
|
||||
class TestMsgSigntxSegwit(common.TrezorTest):
|
||||
@ -157,6 +158,85 @@ class TestMsgSigntxSegwit(common.TrezorTest):
|
||||
|
||||
self.assertEqual(binascii.hexlify(serialized_tx), b'01000000000101be0210025c5be68a473f6a38bf53b53bc88d5c46567616026dc056e72b92319c01000000232200201e8dda334f11171190b3da72e526d441491464769679a319a2f011da5ad312a1ffffffff01887d1800000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac040047304402205b44c20cf2681690edaaf7cd2e30d4704124dd8b7eb1fb7f459d3906c3c374a602205ca359b6544ce2c101c979899c782f7d141c3b0454ea69202b1fb4c09d3b715701473044022052fafa64022554ae436dbf781e550bf0d326fef31eea1438350b3ff1940a180102202851bd19203b7fe8582a9ef52e82aa9f61cd52d4bcedfe6dcc0cf782468e6a8e01695221038e81669c085a5846e68e03875113ddb339ecbb7cb11376d4163bca5dc2e2a0c1210348c5c3be9f0e6cf1954ded1c0475beccc4d26aaa9d0cce2dd902538ff1018a112103931140ebe0fbbb7df0be04ed032a54e9589e30339ba7bbb8b0b71b15df1294da53ae00000000')
|
||||
|
||||
def test_attack_change_input_address(self):
|
||||
# This unit test attempts to modify input address after the Trezor checked
|
||||
# that it matches the change output
|
||||
|
||||
self.setup_mnemonic_allallall()
|
||||
self.client.set_tx_api(TxApiTestnet)
|
||||
inp1 = proto_types.TxInputType(
|
||||
address_n=self.client.expand_path("49'/1'/0'/1/0"),
|
||||
# 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
|
||||
amount=123456789,
|
||||
prev_hash=binascii.unhexlify('20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'),
|
||||
prev_index=0,
|
||||
script_type=proto_types.SPENDP2SHWITNESS,
|
||||
)
|
||||
out1 = proto_types.TxOutputType(
|
||||
address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
|
||||
amount=12300000,
|
||||
script_type=proto_types.PAYTOADDRESS,
|
||||
)
|
||||
out2 = proto_types.TxOutputType(
|
||||
address_n=self.client.expand_path("49'/1'/12345'/1/0"),
|
||||
script_type=proto_types.PAYTOP2SHWITNESS,
|
||||
amount=123456789 - 11000 - 12300000,
|
||||
)
|
||||
|
||||
global run_attack
|
||||
run_attack = True
|
||||
|
||||
def attack_processor(req, msg):
|
||||
import sys
|
||||
global run_attack
|
||||
|
||||
if req.details.tx_hash != b'':
|
||||
return msg
|
||||
|
||||
if req.request_type != proto_types.TXINPUT:
|
||||
return msg
|
||||
|
||||
if req.details.request_index != 0:
|
||||
return msg
|
||||
|
||||
if not run_attack:
|
||||
return msg
|
||||
|
||||
msg.inputs[0].address_n[2] = 12345 + 0x80000000
|
||||
run_attack = False
|
||||
return msg
|
||||
|
||||
# Test if the transaction can be signed normally
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXFINISHED),
|
||||
])
|
||||
(signatures, serialized_tx) = self.client.sign_tx('Testnet', [inp1], [out1, out2])
|
||||
|
||||
self.assertEqual(binascii.hexlify(serialized_tx), b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a914dae9e09a7fc3bbe5a716fffec1bbb340b82a4fb9870248304502210099b5c4f8fd4402c9c0136fee5f711137d64fc9f14587e01bfa7798f5428f845d0220253e21c98f5b1b64efae69bc2ea9799c5620a43450baa6762a0c3cf4fdc886e5012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000')
|
||||
|
||||
# Now run the attack, must trigger the exception
|
||||
with self.client:
|
||||
self.client.set_expected_responses([
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
|
||||
proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=1)),
|
||||
proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
|
||||
proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
|
||||
proto.Failure(code=proto_types.Failure_ProcessError),
|
||||
])
|
||||
self.assertRaises(CallException, self.client.sign_tx, 'Testnet', [inp1], [out1, out2], debug_processor=attack_processor)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -830,6 +830,12 @@ class ProtocolMixin(object):
|
||||
elif res.request_type == types.TXINPUT:
|
||||
msg = types.TransactionType()
|
||||
msg.inputs.extend([current_tx.inputs[res.details.request_index], ])
|
||||
if debug_processor is not None:
|
||||
# If debug_processor function is provided,
|
||||
# pass thru it the request and prepared response.
|
||||
# This is useful for unit tests, see test_msg_signtx
|
||||
msg = debug_processor(res, msg)
|
||||
|
||||
res = self.call(proto.TxAck(tx=msg))
|
||||
continue
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user