diff --git a/tests/device_tests/test_msg_getaddress.py b/tests/device_tests/test_msg_getaddress.py index 10cdaadbe..203d83a6c 100644 --- a/tests/device_tests/test_msg_getaddress.py +++ b/tests/device_tests/test_msg_getaddress.py @@ -144,30 +144,42 @@ class TestMsgGetaddress: ) @pytest.mark.multisig - def test_multisig_missing(self, client): - xpubs = [] - for n in range(1, 4): - # shift account numbers by 10 to create valid multisig, - # but not containing the keys used below - n = n + 10 - node = btc.get_public_node(client, parse_path("44'/0'/%d'" % n)) - xpubs.append(node.xpub) - for nr in range(1, 4): - with pytest.raises(TrezorFailure): - btc.get_address( - client, - "Bitcoin", - parse_path("44'/0'/%d'/0/0" % nr), - show_display=(nr == 1), - multisig=getmultisig(0, 0, xpubs=xpubs), - ) + @pytest.mark.parametrize("show_display", (True, False)) + def test_multisig_missing(self, client, show_display): + # Multisig with global suffix specification. + # Use account numbers 1, 2 and 3 to create a valid multisig, + # but not containing the keys from account 0 used below. + nodes = [ + btc.get_public_node(client, parse_path("44'/0'/%d'" % i)).node + for i in range(1, 4) + ] + multisig1 = messages.MultisigRedeemScriptType( + nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2 + ) + + # Multisig with per-node suffix specification. + node = btc.get_public_node( + client, parse_path("44h/0h/0h/0"), coin_name="Bitcoin" + ).node + + multisig2 = messages.MultisigRedeemScriptType( + pubkeys=[ + messages.HDNodePathType(node=node, address_n=[1]), + messages.HDNodePathType(node=node, address_n=[2]), + messages.HDNodePathType(node=node, address_n=[3]), + ], + signatures=[b"", b"", b""], + m=2, + ) + + for multisig in (multisig1, multisig2): with pytest.raises(TrezorFailure): btc.get_address( client, "Bitcoin", - parse_path("44'/0'/%d'/1/0" % nr), - show_display=(nr == 1), - multisig=getmultisig(1, 0, xpubs=xpubs), + parse_path("44'/0'/0'/0/0"), + show_display=show_display, + multisig=multisig, ) @pytest.mark.altcoin diff --git a/tests/device_tests/test_msg_getaddress_segwit.py b/tests/device_tests/test_msg_getaddress_segwit.py index d06277915..743523435 100644 --- a/tests/device_tests/test_msg_getaddress_segwit.py +++ b/tests/device_tests/test_msg_getaddress_segwit.py @@ -17,6 +17,7 @@ import pytest from trezorlib import btc, messages as proto +from trezorlib.exceptions import TrezorFailure from trezorlib.tools import parse_path @@ -121,3 +122,42 @@ class TestMsgGetaddressSegwit: ) == "2MwuUwUzPG17wiKQpfXmzfxJEoe7RXZDRad" ) + + @pytest.mark.multisig + @pytest.mark.parametrize("show_display", (True, False)) + def test_multisig_missing(self, client, show_display): + # Multisig with global suffix specification. + # Use account numbers 1, 2 and 3 to create a valid multisig, + # but not containing the keys from account 0 used below. + nodes = [ + btc.get_public_node(client, parse_path("49'/0'/%d'" % i)).node + for i in range(1, 4) + ] + multisig1 = proto.MultisigRedeemScriptType( + nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2 + ) + + # Multisig with per-node suffix specification. + node = btc.get_public_node( + client, parse_path("49h/0h/0h/0"), coin_name="Bitcoin" + ).node + multisig2 = proto.MultisigRedeemScriptType( + pubkeys=[ + proto.HDNodePathType(node=node, address_n=[1]), + proto.HDNodePathType(node=node, address_n=[2]), + proto.HDNodePathType(node=node, address_n=[3]), + ], + signatures=[b"", b"", b""], + m=2, + ) + + for multisig in (multisig1, multisig2): + with pytest.raises(TrezorFailure): + btc.get_address( + client, + "Bitcoin", + parse_path("49'/0'/0'/0/0"), + show_display=show_display, + multisig=multisig, + script_type=proto.InputScriptType.SPENDP2SHWITNESS, + ) diff --git a/tests/device_tests/test_msg_getaddress_segwit_native.py b/tests/device_tests/test_msg_getaddress_segwit_native.py index 7abf951ce..34ac0bfae 100644 --- a/tests/device_tests/test_msg_getaddress_segwit_native.py +++ b/tests/device_tests/test_msg_getaddress_segwit_native.py @@ -17,6 +17,7 @@ import pytest from trezorlib import btc, messages as proto +from trezorlib.exceptions import TrezorFailure from trezorlib.tools import parse_path @@ -129,3 +130,42 @@ class TestMsgGetaddressSegwitNative: ) == "tb1qgvn67p4twmpqhs8c39tukmu9geamtf7x0z3flwf9rrw4ff3h6d2qt0czq3" ) + + @pytest.mark.multisig + @pytest.mark.parametrize("show_display", (True, False)) + def test_multisig_missing(self, client, show_display): + # Multisig with global suffix specification. + # Use account numbers 1, 2 and 3 to create a valid multisig, + # but not containing the keys from account 0 used below. + nodes = [ + btc.get_public_node(client, parse_path("84'/0'/%d'" % i)).node + for i in range(1, 4) + ] + multisig1 = proto.MultisigRedeemScriptType( + nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2 + ) + + # Multisig with per-node suffix specification. + node = btc.get_public_node( + client, parse_path("84h/0h/0h/0"), coin_name="Bitcoin" + ).node + multisig2 = proto.MultisigRedeemScriptType( + pubkeys=[ + proto.HDNodePathType(node=node, address_n=[1]), + proto.HDNodePathType(node=node, address_n=[2]), + proto.HDNodePathType(node=node, address_n=[3]), + ], + signatures=[b"", b"", b""], + m=2, + ) + + for multisig in (multisig1, multisig2): + with pytest.raises(TrezorFailure): + btc.get_address( + client, + "Bitcoin", + parse_path("84'/0'/0'/0/0"), + show_display=show_display, + multisig=multisig, + script_type=proto.InputScriptType.SPENDWITNESS, + ) diff --git a/tests/device_tests/test_msg_getownershipproof.py b/tests/device_tests/test_msg_getownershipproof.py index b4abd736b..0eb90f44a 100644 --- a/tests/device_tests/test_msg_getownershipproof.py +++ b/tests/device_tests/test_msg_getownershipproof.py @@ -36,6 +36,43 @@ def test_ownership_id(client): ) +def test_attack_ownership_id(client): + # Multisig with global suffix specification. + # Use account numbers 1, 2 and 3 to create a valid multisig, + # but not containing the keys from account 0 used below. + nodes = [ + btc.get_public_node(client, parse_path("84'/0'/%d'" % i)).node + for i in range(1, 4) + ] + multisig1 = messages.MultisigRedeemScriptType( + nodes=nodes, address_n=[0, 0], signatures=[b"", b"", b""], m=2 + ) + + # Multisig with per-node suffix specification. + node = btc.get_public_node( + client, parse_path("84h/0h/0h/0"), coin_name="Bitcoin" + ).node + multisig2 = messages.MultisigRedeemScriptType( + pubkeys=[ + messages.HDNodePathType(node=node, address_n=[1]), + messages.HDNodePathType(node=node, address_n=[2]), + messages.HDNodePathType(node=node, address_n=[3]), + ], + signatures=[b"", b"", b""], + m=2, + ) + + for multisig in (multisig1, multisig2): + with pytest.raises(TrezorFailure): + btc.get_ownership_id( + client, + "Bitcoin", + parse_path("84'/0'/0'/0/0"), + multisig=multisig, + script_type=messages.InputScriptType.SPENDWITNESS, + ) + + def test_p2wpkh_ownership_proof(client): ownership_proof, _ = btc.get_ownership_proof( client, diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 06f5f20e8..f98b93f47 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -201,15 +201,20 @@ "test_msg_getaddress.py-test_grs": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress.py-test_ltc": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress.py-test_multisig": "cf79d7965130fccaac260cf5dbda12750a83819668a8f89eca303b63dadbe17e", -"test_msg_getaddress.py-test_multisig_missing": "04ea55eff09fb8fe4f68efe8b6b2c2be442c98ac1c9802ef0681125009e7b5d4", +"test_msg_getaddress.py-test_multisig_missing[False]": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", +"test_msg_getaddress.py-test_multisig_missing[True]": "2be0e32b151a6ed5fbdfa919bccea0f786b848719761d91a1ae6c49f2959bd25", "test_msg_getaddress.py-test_public_ckd": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress.py-test_tbtc": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress.py::test_crw": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress.py::test_invalid_path": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress.py::test_unknown_path_tt": "0f6e15d265d012a341811965b72e75fbe0e76a17091f0bb2e89caa4a75c550a0", +"test_msg_getaddress_segwit.py-test_multisig_missing[False]": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", +"test_msg_getaddress_segwit.py-test_multisig_missing[True]": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress_segwit.py-test_show_multisig_3": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress_segwit.py-test_show_segwit": "329134e85a7cc76eaf776c92b7fc3932946d411249661bf9a2d9ce314fcf27f8", "test_msg_getaddress_segwit.py-test_show_segwit_altcoin": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", +"test_msg_getaddress_segwit_native.py-test_multisig_missing[False]": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", +"test_msg_getaddress_segwit_native.py-test_multisig_missing[True]": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress_segwit_native.py-test_show_multisig_3": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getaddress_segwit_native.py-test_show_segwit": "e6b8007c78b6d375635ff5a1b3047bfe57727b9a449a3c19d2ebf64648ac3946", "test_msg_getaddress_segwit_native.py-test_show_segwit_altcoin": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", @@ -245,6 +250,7 @@ "test_msg_getentropy.py::test_entropy[65]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356", "test_msg_getentropy.py::test_entropy[8]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356", "test_msg_getentropy.py::test_entropy[9]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356", +"test_msg_getownershipproof.py::test_attack_ownership_id": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586", "test_msg_getownershipproof.py::test_confirm_ownership_proof": "7724ef59fee121da564b935b5880479c9518d97dc286e2949f13a8a8bdf6fa4a", "test_msg_getownershipproof.py::test_confirm_ownership_proof_with_data": "1043f54be594bd3180c59c8474ef7ef46be35f99ad5f6890949c38680c097e52", "test_msg_getownershipproof.py::test_fake_ownership_id": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",