1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 15:38:11 +00:00

core: add exception to GetPublicKey for PSBT master fingerprint (fixes #999)

This commit is contained in:
matejcik 2020-05-21 13:26:53 +02:00
parent 6fafe4c9ee
commit 2f665c8f84
3 changed files with 43 additions and 27 deletions

View File

@ -18,6 +18,7 @@ async def get_keychain_for_curve(ctx: wire.Context, curve_name: str) -> seed.Key
async def get_public_key(ctx, msg): async def get_public_key(ctx, msg):
coin_name = msg.coin_name or "Bitcoin"
script_type = msg.script_type or InputScriptType.SPENDADDRESS script_type = msg.script_type or InputScriptType.SPENDADDRESS
if msg.ecdsa_curve_name is not None: if msg.ecdsa_curve_name is not None:
@ -34,6 +35,15 @@ async def get_public_key(ctx, msg):
# only allow SLIP-13/17 namespaces # only allow SLIP-13/17 namespaces
keychain = await get_keychain_for_curve(ctx, msg.ecdsa_curve_name) keychain = await get_keychain_for_curve(ctx, msg.ecdsa_curve_name)
elif (
coin_name == "Bitcoin"
and script_type is InputScriptType.SPENDADDRESS
and msg.address_n == [HARDENED]
):
# allow extracting PSBT master fingerprinty by calling GetPublicKey(m/0')
coin = coins.by_name("Bitcoin")
keychain = await seed.get_keychain(ctx, [("secp256k1", [HARDENED])])
else: else:
# select curve and namespaces based on the requested coin properties # select curve and namespaces based on the requested coin properties
keychain, coin = await get_keychain_for_coin(ctx, msg.coin_name) keychain, coin = await get_keychain_for_coin(ctx, msg.coin_name)

View File

@ -17,10 +17,13 @@
import pytest import pytest
from trezorlib import btc, messages from trezorlib import btc, messages
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path from trezorlib.tools import parse_path
from .. import bip32 from .. import bip32
pytestmark = pytest.mark.skip_ui
VECTORS_BITCOIN = ( # coin_name, xpub_magic, path, xpub VECTORS_BITCOIN = ( # coin_name, xpub_magic, path, xpub
( (
"Bitcoin", "Bitcoin",
@ -58,35 +61,53 @@ VECTORS_BITCOIN = ( # coin_name, xpub_magic, path, xpub
parse_path("m/44h/1h/0h/0/0"), parse_path("m/44h/1h/0h/0/0"),
"tpubDGwNSs8z8jZU2EcUiubR4frGvKqddvLBqCDNknnWhmoUd6EHrRWrqXmDaWBNddWzM5Yqh4e4TUYFK9hGCEnSrMKgV6cthRhArfZpwzihdw7", "tpubDGwNSs8z8jZU2EcUiubR4frGvKqddvLBqCDNknnWhmoUd6EHrRWrqXmDaWBNddWzM5Yqh4e4TUYFK9hGCEnSrMKgV6cthRhArfZpwzihdw7",
), ),
) ( # PSBT master fingerprint retrieval
"Bitcoin",
VECTORS_ALTCOINS = ( 0x0488B21E,
( parse_path("m/0h"),
"xpub68Zyu13qjcQvJXTsnmhH2h2TyPiXAama5bTU8u9iRXyYtS9X9yWvSKij6YGt7JJ2nr5rSGi4KLUW5Z8bTKHqXhbLwqb7smG3Y8j2wy4rmf3",
),
pytest.param(
"Litecoin", "Litecoin",
0x019DA462, 0x019DA462,
parse_path("m/44h/2h/0h"), parse_path("m/44h/2h/0h"),
"Ltub2Y8PyEMWQVgiX4L4gVzU8PakBTQ2WBxFdS6tJARQeasUUfXmBut2jGShnQyD3jgyBf7mmvs5jPNgmgXad5J6M8a8FiZK78dbT21fYtTAC9a", "Ltub2Y8PyEMWQVgiX4L4gVzU8PakBTQ2WBxFdS6tJARQeasUUfXmBut2jGShnQyD3jgyBf7mmvs5jPNgmgXad5J6M8a8FiZK78dbT21fYtTAC9a",
marks=pytest.mark.altcoin,
), ),
( pytest.param(
"Litecoin", "Litecoin",
0x019DA462, 0x019DA462,
parse_path("m/44h/2h/10h"), parse_path("m/44h/2h/10h"),
"Ltub2Y8PyEMWQVgiy8Zio1XrKWkGL6ZmCZB9W5ShbvbzZ14irCrAb62YEoMafTAM5a2A6x6XNcyDdCNW7NVgES9jtQqyUZcBUFTimS7VVJ8tbpE", "Ltub2Y8PyEMWQVgiy8Zio1XrKWkGL6ZmCZB9W5ShbvbzZ14irCrAb62YEoMafTAM5a2A6x6XNcyDdCNW7NVgES9jtQqyUZcBUFTimS7VVJ8tbpE",
marks=pytest.mark.altcoin,
), ),
( pytest.param(
"Litecoin", "Litecoin",
0x019DA462, 0x019DA462,
parse_path("m/44h/2h/0h/0/0"), parse_path("m/44h/2h/0h/0/0"),
"Ltub2dTvwC4v7GNeR6UEaywQ6j72wHi4dwRo3oDDzvXAwb4CrXVQEUTbxC4hEfULiKByiUMEmYLhuMo1YMYmBBjKJ8kyk9ia5gZaVNWq5rVLom4", "Ltub2dTvwC4v7GNeR6UEaywQ6j72wHi4dwRo3oDDzvXAwb4CrXVQEUTbxC4hEfULiKByiUMEmYLhuMo1YMYmBBjKJ8kyk9ia5gZaVNWq5rVLom4",
marks=pytest.mark.altcoin,
), ),
( pytest.param(
"Litecoin", "Litecoin",
0x019DA462, 0x019DA462,
parse_path("m/44h/2h/10h/1/100"), parse_path("m/44h/2h/10h/1/100"),
"Ltub2dcb6Nghj3kwaC2g3TtPgFzMSm7LXfe4mijFYsvEtxXu18vicTB4kYc9z6jGVMpdYhMScNhVY1naQYALnM2x4fvaGzAAGgcuZ89nFyyLhiK", "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) @pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_BITCOIN)
def test_get_public_node(client, coin_name, xpub_magic, path, xpub): def test_get_public_node(client, coin_name, xpub_magic, path, xpub):
@ -95,12 +116,11 @@ def test_get_public_node(client, coin_name, xpub_magic, path, xpub):
assert bip32.serialize(res.node, xpub_magic) == xpub assert bip32.serialize(res.node, xpub_magic) == xpub
@pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_ALTCOINS) @pytest.mark.skip_t1
@pytest.mark.altcoin @pytest.mark.parametrize("coin_name, path", VECTORS_INVALID)
def test_get_public_node_altcoin(client, coin_name, xpub_magic, path, xpub): def test_invalid_path(client, coin_name, path):
res = btc.get_public_node(client, path, coin_name=coin_name) with pytest.raises(TrezorFailure, match="Forbidden key path"):
assert res.xpub == xpub btc.get_public_node(client, path, coin_name=coin_name)
assert bip32.serialize(res.node, xpub_magic) == xpub
VECTORS_SCRIPT_TYPES = ( # script_type, xpub VECTORS_SCRIPT_TYPES = ( # script_type, xpub

View File

@ -123,20 +123,6 @@
"test_msg_getentropy.py::test_entropy[65]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356", "test_msg_getentropy.py::test_entropy[65]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356",
"test_msg_getentropy.py::test_entropy[8]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356", "test_msg_getentropy.py::test_entropy[8]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356",
"test_msg_getentropy.py::test_entropy[9]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356", "test_msg_getentropy.py::test_entropy[9]": "a722fa2048fa3102889ec05558d25f837a364ef2a118e85975683e10a56f1356",
"test_msg_getpublickey.py::test_get_public_node[Bitcoin-76067358-path0-xpub6BiVtCpG9fQPxnPmHXG8PhtzQd": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node[Bitcoin-76067358-path1-xpub6BiVtCpG9fQQR6cSuFeDaSvCDg": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node[Bitcoin-76067358-path2-xpub6FVDRC1jiWNTuT3embehwSZ1bu": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node[Bitcoin-76067358-path3-xpub6GhTNegKCjTqjYS4HNkPhXHXHN": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node[Testnet-70617039-path4-tpubDDKn3FtHc74CaRrRbi1WFdJNaa": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node[Testnet-70617039-path5-tpubDGwNSs8z8jZU2EcUiubR4frGvK": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node_altcoin[Litecoin-27108450-path0-Ltub2Y8PyEMWQVgiX4L4g": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node_altcoin[Litecoin-27108450-path1-Ltub2Y8PyEMWQVgiy8Zio": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node_altcoin[Litecoin-27108450-path2-Ltub2dTvwC4v7GNeR6UEa": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_get_public_node_altcoin[Litecoin-27108450-path3-Ltub2dcb6Nghj3kwaC2g3": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_script_type[0-xpub6BiVtCp7ozsRo7kaoYNrCNAVJwPYTQHjoXFD3YS797S55Y42sm2": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_script_type[3-zpub6qP2VY9x7MxPVi8pUFx6cYMVesgSLeGjdkHecLDsu8BqBjgVP5M": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_script_type[4-ypub6WYmBsV2xgQueQwhduAUQTFzUuXzQ2HEidmRpwKzX7ox8dsG8RC": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_getpublickey.py::test_script_type[None-xpub6BiVtCp7ozsRo7kaoYNrCNAVJwPYTQHjoXFD3YS797S55Y42": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_lisk_getaddress.py-test_lisk_getaddress": "0063ceb48d21aecd1ddabdb083c8afd2042cdf577e4751fa3f57b2b80f619084", "test_msg_lisk_getaddress.py-test_lisk_getaddress": "0063ceb48d21aecd1ddabdb083c8afd2042cdf577e4751fa3f57b2b80f619084",
"test_msg_lisk_getpublickey.py-test_lisk_get_public_key": "e4cb8c7430c240e27a2211391ab5eba848be4f50136cf9f693142c2677a939d7", "test_msg_lisk_getpublickey.py-test_lisk_get_public_key": "e4cb8c7430c240e27a2211391ab5eba848be4f50136cf9f693142c2677a939d7",
"test_msg_lisk_signmessage.py-test_sign": "c47a6ec147137c75903cff19da6607eaef5a1fc03ace1f840d2952744342b568", "test_msg_lisk_signmessage.py-test_sign": "c47a6ec147137c75903cff19da6607eaef5a1fc03ace1f840d2952744342b568",