mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-05 14:08:39 +00:00
186 lines
7.2 KiB
Python
186 lines
7.2 KiB
Python
# This file is part of the Trezor project.
|
|
#
|
|
# Copyright (C) 2012-2019 SatoshiLabs and contributors
|
|
#
|
|
# This library is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Lesser General Public License version 3
|
|
# as published by the Free Software Foundation.
|
|
#
|
|
# 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 License along with this library.
|
|
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
|
|
|
import pytest
|
|
|
|
from trezorlib import btc, messages
|
|
from trezorlib.debuglink import SessionDebugWrapper as Session
|
|
from trezorlib.exceptions import TrezorFailure
|
|
from trezorlib.tools import parse_path
|
|
|
|
from ... import bip32
|
|
from ...input_flows import InputFlowShowXpubQRCode
|
|
|
|
VECTORS_BITCOIN = ( # coin_name, xpub_magic, path, xpub
|
|
(
|
|
"Bitcoin",
|
|
0x0488B21E,
|
|
parse_path("m/44h/0h/0h"),
|
|
"xpub6BiVtCpG9fQPxnPmHXG8PhtzQdWC2Su4qWu6XW9tpWFYhxydCLJGrWBJZ5H6qTAHdPQ7pQhtpjiYZVZARo14qHiay2fvrX996oEP42u8wZy",
|
|
),
|
|
(
|
|
"Bitcoin",
|
|
0x0488B21E,
|
|
parse_path("m/44h/0h/10h"),
|
|
"xpub6BiVtCpG9fQQR6cSuFeDaSvCDgNvNme499JUGX4RHDiZVWwZy9NwNieWKXHLe8XRbdrEmY87aqztBCbRJkXWV7VJB96XBT5cpkqYMHwvLWB",
|
|
),
|
|
(
|
|
"Bitcoin",
|
|
0x0488B21E,
|
|
parse_path("m/44h/0h/0h/0/0"),
|
|
"xpub6FVDRC1jiWNTuT3embehwSZ1buxRDyZGbTakVCkBr6w2LwpERmYqXyvtrLeJX9hqzLaucS3qJXGekeFsSVCELkbgepp7FVGeH5BYekEgT9x",
|
|
),
|
|
(
|
|
"Bitcoin",
|
|
0x0488B21E,
|
|
parse_path("m/44h/0h/10h/1/100"),
|
|
"xpub6GhTNegKCjTqjYS4HNkPhXHXHNZV2cPC38N7HbpUKexXXuTkjKPnijqKTB7yXidP4JtTUWTuWPTt6P55xi91NPgUp51BnqYzYdNhho4y5j8",
|
|
),
|
|
(
|
|
"Testnet",
|
|
0x043587CF,
|
|
parse_path("m/44h/1h/0h"),
|
|
"tpubDDKn3FtHc74CaRrRbi1WFdJNaaenZkDWqq9NsEhcafnDZ4VuKeuLG2aKHm5SuwuLgAhRkkfHqcCxpnVNSrs5kJYZXwa6Ud431VnevzzzK3U",
|
|
),
|
|
(
|
|
"Testnet",
|
|
0x043587CF,
|
|
parse_path("m/44h/1h/0h/0/0"),
|
|
"tpubDGwNSs8z8jZU2EcUiubR4frGvKqddvLBqCDNknnWhmoUd6EHrRWrqXmDaWBNddWzM5Yqh4e4TUYFK9hGCEnSrMKgV6cthRhArfZpwzihdw7",
|
|
),
|
|
( # PSBT master fingerprint retrieval
|
|
"Bitcoin",
|
|
0x0488B21E,
|
|
parse_path("m/0h"),
|
|
"xpub68Zyu13qjcQvJXTsnmhH2h2TyPiXAama5bTU8u9iRXyYtS9X9yWvSKij6YGt7JJ2nr5rSGi4KLUW5Z8bTKHqXhbLwqb7smG3Y8j2wy4rmf3",
|
|
),
|
|
pytest.param(
|
|
"Litecoin",
|
|
0x019DA462,
|
|
parse_path("m/44h/2h/0h"),
|
|
"Ltub2Y8PyEMWQVgiX4L4gVzU8PakBTQ2WBxFdS6tJARQeasUUfXmBut2jGShnQyD3jgyBf7mmvs5jPNgmgXad5J6M8a8FiZK78dbT21fYtTAC9a",
|
|
marks=pytest.mark.altcoin,
|
|
),
|
|
pytest.param(
|
|
"Litecoin",
|
|
0x019DA462,
|
|
parse_path("m/44h/2h/10h"),
|
|
"Ltub2Y8PyEMWQVgiy8Zio1XrKWkGL6ZmCZB9W5ShbvbzZ14irCrAb62YEoMafTAM5a2A6x6XNcyDdCNW7NVgES9jtQqyUZcBUFTimS7VVJ8tbpE",
|
|
marks=pytest.mark.altcoin,
|
|
),
|
|
pytest.param(
|
|
"Litecoin",
|
|
0x019DA462,
|
|
parse_path("m/44h/2h/0h/0/0"),
|
|
"Ltub2dTvwC4v7GNeR6UEaywQ6j72wHi4dwRo3oDDzvXAwb4CrXVQEUTbxC4hEfULiKByiUMEmYLhuMo1YMYmBBjKJ8kyk9ia5gZaVNWq5rVLom4",
|
|
marks=pytest.mark.altcoin,
|
|
),
|
|
pytest.param(
|
|
"Litecoin",
|
|
0x019DA462,
|
|
parse_path("m/44h/2h/10h/1/100"),
|
|
"Ltub2dcb6Nghj3kwaC2g3TtPgFzMSm7LXfe4mijFYsvEtxXu18vicTB4kYc9z6jGVMpdYhMScNhVY1naQYALnM2x4fvaGzAAGgcuZ89nFyyLhiK",
|
|
marks=pytest.mark.altcoin,
|
|
),
|
|
)
|
|
|
|
VECTORS_INVALID = ( # coin_name, path
|
|
("Bitcoin", parse_path("m/44h/1h/0h")), # Testnet path on Bitcoin
|
|
("Testnet", parse_path("m/44h/0h/0h")), # Bitcoin path on Testnet
|
|
("Bitcoin", parse_path("m/40h/0h/0h")), # Unknown purpose
|
|
("Bitcoin", parse_path("m/13h/0h/0h")), # SLIP-13 path
|
|
# Bitcoin path on Litecoin
|
|
pytest.param("Litecoin", parse_path("m/44h/0h/0h"), marks=pytest.mark.altcoin),
|
|
# Segwit path on Bitcoin Cash
|
|
pytest.param("Bcash", parse_path("m/84h/145h/0h"), marks=pytest.mark.altcoin),
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_BITCOIN)
|
|
def test_get_public_node(session: Session, coin_name, xpub_magic, path, xpub):
|
|
res = btc.get_public_node(session, path, coin_name=coin_name)
|
|
assert res.xpub == xpub
|
|
assert bip32.serialize(res.node, xpub_magic) == xpub
|
|
|
|
|
|
@pytest.mark.models("core")
|
|
@pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_BITCOIN)
|
|
def test_get_public_node_show(session: Session, coin_name, xpub_magic, path, xpub):
|
|
with session.client as client:
|
|
IF = InputFlowShowXpubQRCode(client)
|
|
client.set_input_flow(IF.get())
|
|
res = btc.get_public_node(session, path, coin_name=coin_name, show_display=True)
|
|
assert res.xpub == xpub
|
|
assert bip32.serialize(res.node, xpub_magic) == xpub
|
|
|
|
|
|
@pytest.mark.xfail(reason="Currently path validation on get_public_node is disabled.")
|
|
@pytest.mark.parametrize("coin_name, path", VECTORS_INVALID)
|
|
def test_invalid_path(session: Session, coin_name, path):
|
|
with pytest.raises(TrezorFailure, match="Forbidden key path"):
|
|
btc.get_public_node(session, path, coin_name=coin_name)
|
|
|
|
|
|
def test_slip25_path(session: Session):
|
|
# Ensure that CoinJoin XPUBs are inaccessible without user authorization.
|
|
with pytest.raises(TrezorFailure, match="Forbidden key path"):
|
|
btc.get_public_node(
|
|
session,
|
|
parse_path("m/10025h/0h/0h/1h"),
|
|
script_type=messages.InputScriptType.SPENDTAPROOT,
|
|
)
|
|
|
|
|
|
VECTORS_SCRIPT_TYPES = ( # script_type, xpub, xpub_ignored_magic
|
|
(
|
|
None,
|
|
"xpub6BiVtCp7ozsRo7kaoYNrCNAVJwPYTQHjoXFD3YS797S55Y42sm2raxPrXQWAJodn7aXnHJdhz433ZJDhyUztHW55WatHeoYUVqui8cYNX8y",
|
|
"xpub6BiVtCp7ozsRo7kaoYNrCNAVJwPYTQHjoXFD3YS797S55Y42sm2raxPrXQWAJodn7aXnHJdhz433ZJDhyUztHW55WatHeoYUVqui8cYNX8y",
|
|
),
|
|
(
|
|
messages.InputScriptType.SPENDADDRESS,
|
|
"xpub6BiVtCp7ozsRo7kaoYNrCNAVJwPYTQHjoXFD3YS797S55Y42sm2raxPrXQWAJodn7aXnHJdhz433ZJDhyUztHW55WatHeoYUVqui8cYNX8y",
|
|
"xpub6BiVtCp7ozsRo7kaoYNrCNAVJwPYTQHjoXFD3YS797S55Y42sm2raxPrXQWAJodn7aXnHJdhz433ZJDhyUztHW55WatHeoYUVqui8cYNX8y",
|
|
),
|
|
(
|
|
messages.InputScriptType.SPENDP2SHWITNESS,
|
|
"ypub6WYmBsV2xgQueQwhduAUQTFzUuXzQ2HEidmRpwKzX7ox8dsG8RCRD23zYcTkJiHhXDeb2nEGSiPbSaqGhBQu5jkgNvaiEiMxmZyMXEvfNco",
|
|
"xpub6BiVtCp7ozsRo7kaoYNrCNAVJwPYTQHjoXFD3YS797S55Y42sm2raxPrXQWAJodn7aXnHJdhz433ZJDhyUztHW55WatHeoYUVqui8cYNX8y",
|
|
),
|
|
(
|
|
messages.InputScriptType.SPENDWITNESS,
|
|
"zpub6qP2VY9x7MxPVi8pUFx6cYMVesgSLeGjdkHecLDsu8BqBjgVP5Myq5i8ZpRLJcwcvrmPnFppuNk9KsSqQspusySHFGH8pdBT3J2zujqcVuz",
|
|
"xpub6BiVtCp7ozsRo7kaoYNrCNAVJwPYTQHjoXFD3YS797S55Y42sm2raxPrXQWAJodn7aXnHJdhz433ZJDhyUztHW55WatHeoYUVqui8cYNX8y",
|
|
),
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("script_type, xpub, xpub_ignored_magic", VECTORS_SCRIPT_TYPES)
|
|
def test_script_type(session: Session, script_type, xpub, xpub_ignored_magic):
|
|
path = parse_path("m/44h/0h/0")
|
|
res = btc.get_public_node(
|
|
session, path, coin_name="Bitcoin", script_type=script_type
|
|
)
|
|
assert res.xpub == xpub
|
|
res = btc.get_public_node(
|
|
session,
|
|
path,
|
|
coin_name="Bitcoin",
|
|
script_type=script_type,
|
|
ignore_xpub_magic=True,
|
|
)
|
|
assert res.xpub == xpub_ignored_magic
|