1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-10 15:30:55 +00:00

fix(legacy): show XPUB using a QR code

Similar layout to `fsm_layoutAddress` is used.

Fixes #3043.
This commit is contained in:
Roman Zeyde 2025-01-08 12:11:44 +01:00 committed by Roman Zeyde
parent 023e0c8722
commit 367ba7cd5c
6 changed files with 83 additions and 31 deletions

View File

@ -0,0 +1 @@
Allow showing XPUB using a QR code.

View File

@ -114,13 +114,16 @@ void fsm_msgGetPublicKey(const GetPublicKey *msg) {
}
if (msg->has_show_display && msg->show_display) {
for (int page = 0; page < 2; page++) {
layoutXPUB(resp->xpub, page);
if (!protectButton(ButtonRequestType_ButtonRequest_PublicKey, true)) {
memzero(resp, sizeof(PublicKey));
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
layoutHome();
return;
int page = 0;
bool qrcode = false;
while (page < 2) {
layoutXPUB(resp->xpub, page, qrcode);
if (protectButton(ButtonRequestType_ButtonRequest_PublicKey, false)) {
page += 1; // advance to the next page
qrcode = false; // switch to XPUB text
} else {
qrcode = !qrcode; // switch to and from QR
}
}
}

View File

@ -985,17 +985,21 @@ static void _layout_xpub(const char *xpub, const char *desc, int page) {
}
}
void layoutXPUB(const char *xpub, int page) {
void layoutXPUB(const char *xpub, int page, bool qrcode) {
if (layoutLast != layoutAddress && layoutLast != layoutXPUB) {
layoutSwipe();
} else {
oledClear();
}
layoutLast = layoutXPUB;
char desc[] = "XPUB _/2";
desc[5] = '1' + page;
_layout_xpub(xpub, desc, page);
layoutButtonNo(_("Cancel"), &bmp_btn_cancel);
if (qrcode) {
renderQR(xpub);
} else {
char desc[] = "XPUB _/2";
desc[5] = '1' + page;
_layout_xpub(xpub, desc, page);
layoutButtonNo(_("QR Code"), NULL);
}
layoutButtonYes(_("Confirm"), &bmp_btn_confirm);
oledRefresh();
}

View File

@ -92,7 +92,7 @@ void layoutAddress(const char *address, const char *desc, bool qrcode,
bool ignorecase, const uint32_t *address_n,
size_t address_n_count, bool address_is_account);
void layoutPublicKey(const uint8_t *pubkey);
void layoutXPUB(const char *xpub, int page);
void layoutXPUB(const char *xpub, int page, bool qrcode);
void layoutXPUBMultisig(const char *xpub, int index, int page, bool ours);
void layoutSignIdentity(const IdentityType *identity, const char *challenge);
void layoutDecryptIdentity(const IdentityType *identity);

View File

@ -134,6 +134,39 @@ def test_invalid_path(client: Client, coin_name, path):
btc.get_public_node(client, path, coin_name=coin_name)
@pytest.mark.models("legacy")
@pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_BITCOIN)
def test_get_public_node_show_legacy(client: Client, coin_name, xpub_magic, path, xpub):
def input_flow():
yield
client.debug.press_no() # show QR code
yield
client.debug.press_no() # back to text
yield
client.debug.press_no() # show QR code
yield
client.debug.press_yes() # next xpub page
yield
client.debug.press_no() # show QR code again
yield
client.debug.press_no() # back to text
yield
client.debug.press_yes() # finish the flow
yield
with client:
# test XPUB display flow (without showing QR code)
res = btc.get_public_node(client, path, coin_name=coin_name, show_display=True)
assert res.xpub == xpub
assert bip32.serialize(res.node, xpub_magic) == xpub
# test XPUB QR code display using the input flow above
client.set_input_flow(input_flow)
res = btc.get_public_node(client, path, coin_name=coin_name, show_display=True)
assert res.xpub == xpub
assert bip32.serialize(res.node, xpub_magic) == xpub
def test_slip25_path(client: Client):
# Ensure that CoinJoin XPUBs are inaccessible without user authorization.
with pytest.raises(TrezorFailure, match="Forbidden key path"):

View File

@ -31,24 +31,24 @@
"T1B1_en_bitcoin-test_decred.py::test_decred_multisig_change": "8f95b7d2e65a76068196ab46c8189ba5a137795b43e88699d85ad7e2c164d645",
"T1B1_en_bitcoin-test_decred.py::test_send_decred": "50fa7dc09dbf22fc4c1e62ee2870e9047e29dd050edbdcf34341a5483d52cdac",
"T1B1_en_bitcoin-test_decred.py::test_send_decred_change": "b27eb08c244e00f9a2c5fecad0a8efc65fa2eba15f72ad0eb3b42a3ac16d465d",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-10025-InputScriptType.SPE-6c24ae6f": "d1ac62d128ed78eef5947994e9c9d70194a203eadb5a50f9ca9af66b42ba333d",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-44-InputScriptType.SPENDA-fc66840d": "9b30c98b35338d933fe992e4a47fb259a54f0f6f204610f63c6e6cbff427dbb9",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-49-InputScriptType.SPENDP-3f679311": "09d1f2688240677ac55f2677b62973ee7fe4ca788e9e139b9f6de5a1a66d6205",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-84-InputScriptType.SPENDW-dedbd46d": "565050e8908a69cd9866a8696cdc103c19d1299486c682211f608e63b6597648",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-86-InputScriptType.SPENDT-9b717395": "f71944d71edb2531faef0a177c2eda4f88bcb0ef77883db18f655d706759b5b0",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-1-44-InputScriptType.SPENDA-908dd45b": "c7987e946ff4f7f80f2aef9acd226f50ab2439837a188c0601861d0f15ca14c3",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-1-49-InputScriptType.SPENDP-07c408b2": "fd3a4f48f9ea6b02a88db9ec8ab21ad72a4aee1e983e4e626b420834b375e190",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-1-84-InputScriptType.SPENDW-ae5dad46": "0c3090e26ede1019969dee87ce0ea88d46e54ec587c54cf975e1947fe90b5a0e",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-1-86-InputScriptType.SPENDT-f5c0cb2f": "c7a98dbc8fdf8b8a62d3ececef56e7ff2613a9491e6734b5683c1e2a5a074bed",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-10025-InputScriptType.SPE-ad017c81": "ec6aa625a688e2d54857aafca83b513d6509b13898b0fb79166e5d85c74a414b",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-44-InputScriptType.SPENDA-87568704": "a03f1c3753c5a53e05ea9737c7f2583c2935a1a68684d37c0230a1a4d9453bea",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-49-InputScriptType.SPENDP-08c818f5": "84ee5c5a45dbff7bb3d2d79b48e2323c84ff589540f6806b32b286f6bc5ce4e8",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-84-InputScriptType.SPENDW-3a2da005": "f56e158c4fe862875dc4d655e0a5f203312a6509bf7c16bf462a237feaf78b7b",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-86-InputScriptType.SPENDT-0d2d3911": "5f990152867980f9b129e85f9fa1963006895c49a33045e2a9363cb9fa493f26",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-1-44-InputScriptType.SPENDA-06441aab": "bf7d2992e2732384f0e574732e36342b09ef6a8b50641a29c5d05a13c026fd7b",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-1-49-InputScriptType.SPENDP-2341fa5a": "a381684066de8a00048ab82491599140c8e36a8eed9b9c31284e76275b7d396c",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-1-84-InputScriptType.SPENDW-59aa0a79": "cd384fcf3379759dd5fc3f2737ddfb9185a55e506d9d0869f8a85ba31ed1d973",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-1-86-InputScriptType.SPENDT-af95048b": "f24b6c201efc2efbb174a48766df03f5964ea95908abca791714e22bcf9b635d",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-10025-InputScriptType.SPE-6c24ae6f": "104401402fa93edc328c73d3c6ac3f185d55bc2515c4c6f74f518ecb2c247048",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-44-InputScriptType.SPENDA-fc66840d": "8ce74bf750fa077f3349cce10fabfe945bd3c44a957de62949ccb33b9f9dd0b8",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-49-InputScriptType.SPENDP-3f679311": "35e777790592f18aa33e3ca9d7bc8de386f3e079966e914c836c88c30ff85fd6",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-84-InputScriptType.SPENDW-dedbd46d": "7c9abf10389dba7937e29b9d494639589e0bff2698e54cef177e3b6da0c92e18",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-0-86-InputScriptType.SPENDT-9b717395": "eda93660418b28f718f1370691abc58427f382d0cbb6fc1d51e2bda02ad4dba4",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-1-44-InputScriptType.SPENDA-908dd45b": "1fc0840d4f3da3dcd2d0267a5f8c1578fabc92af6f675ba7d90ae1d72191bb8d",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-1-49-InputScriptType.SPENDP-07c408b2": "54991fdd4d36a72f0948611b20f6e07b7cab07854a4ad538981ac54ebedc6961",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-1-84-InputScriptType.SPENDW-ae5dad46": "e532ad6eee6ed465436d2265de6216c9194ba04f03706df70b69524a78ec8d17",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Bitcoin-1-86-InputScriptType.SPENDT-f5c0cb2f": "5548f9742257256c208b3901d9c76c25f8287a44b4083d267f0d7f75603f9120",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-10025-InputScriptType.SPE-ad017c81": "60d72b0cf0980fe5d5779e561b4d32c18ec088206d9a9c3ec1e0b1d3954df53f",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-44-InputScriptType.SPENDA-87568704": "45323e5eaab0c214c44b4b6667dfeb6870a7c22da1e23e4bfcdf3945c11ae45a",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-49-InputScriptType.SPENDP-08c818f5": "9f147172e3cd4911bacf3c18754fb46f7c6dc7c46d080b9e9328fb48d276df30",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-84-InputScriptType.SPENDW-3a2da005": "c10d0063e773ecee0ed5f844ac5b3000ccf762e8dc5ccaed188f0a84f9f788d3",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-0-86-InputScriptType.SPENDT-0d2d3911": "7febe50f7f780da4275d4e3bcca421a91a93e327fcb9d108ca5404b1e4500deb",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-1-44-InputScriptType.SPENDA-06441aab": "7b204973f3ca702ad0f69799b795f601d1441a56be38bdf9166aada439227674",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-1-49-InputScriptType.SPENDP-2341fa5a": "cfe83fe0b30062606ccd54403c4dc9c256ebfb5ca60474c128f9d04380dac9f4",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-1-84-InputScriptType.SPENDW-59aa0a79": "6e6dab3036adda56b78ceafe68239522c27f4ee3fec74f0113371c5cfa85ca93",
"T1B1_en_bitcoin-test_descriptors.py::test_descriptors_trezorlib[Testnet-1-86-InputScriptType.SPENDT-af95048b": "32fce016e30f21c81a33514e2895972ac58dceb5e61b55fa4990552910144408",
"T1B1_en_bitcoin-test_firo.py::test_spend_lelantus": "cbb87e77f54c351584dd713a8eaabb99b65a515e57c30bfb9e7a38660ca6895b",
"T1B1_en_bitcoin-test_fujicoin.py::test_send_p2tr": "bfa5dc1a494ea17fd43d52a315a7f1abe9ad80d7fdaa8b3ec5f92c4118638d1e",
"T1B1_en_bitcoin-test_getaddress.py::test_bch": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
@ -133,6 +133,17 @@
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node[Litecoin-27108450-path9-Ltub2dTvwC4v7GNe-8d6d95fb": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node[Testnet-70617039-path4-tpubDDKn3FtHc74Ca-f3b70aff": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node[Testnet-70617039-path5-tpubDGwNSs8z8jZU2-8b5efa13": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Bitcoin-76067358-path0-xpub6-bf232aa0": "9432d50e05621eaf35b55bed19fd73227733b286324f9080310dc0c98a2df03e",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Bitcoin-76067358-path1-xpub6-42fe2535": "7b2f01d7e2744b837be4606aec7ef5361b230299fb2d3a515bfa69ac2c9591d9",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Bitcoin-76067358-path2-xpub6-7d53be7d": "97e473eaf4a28afb6531460e9c282f1a3edf572b8044986158bf5d230fc480c9",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Bitcoin-76067358-path3-xpub6-40ff3d1a": "cba39be984a08e13e2554269bb6f7a2a3cf73928f734a22401239dcef0964118",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Bitcoin-76067358-path6-xpub6-2233337c": "55a3b51f784add99ad325a0da0a5b0be4c9efa4ac7248bc4a43881bdb7133900",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Litecoin-27108450-path10-Ltu-5c9baf11": "f90c7e41611ad5b441d2f92cc13a8e3ebb561fa3311ce546aa1f2801330059f0",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Litecoin-27108450-path7-Ltub-40e7a24f": "883985d5141042aad58f34b4e3e4b9d7ae50e00052502843700320f223c90648",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Litecoin-27108450-path8-Ltub-c105cc05": "ab637d75e41769d72fbb829c7434ba1a4673da0e3503520d7ddadda3ba5cb1df",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Litecoin-27108450-path9-Ltub-deb2b005": "8c473abbeab271b11a1dd81e47fd61a5b3727663023882184116a1632f996ceb",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Testnet-70617039-path4-tpubD-3ff0907e": "ff4370b8a9dab8e3fe8443574a6a63d9806ecb051f43f614605c216db7ea1136",
"T1B1_en_bitcoin-test_getpublickey.py::test_get_public_node_show_legacy[Testnet-70617039-path5-tpubD-92239b2c": "1e2d268042077f65eb4df4ba99d6908cc4cc00e97d4b5fd5ae216db0376c3c1a",
"T1B1_en_bitcoin-test_getpublickey.py::test_invalid_path[Bcash-path5]": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"T1B1_en_bitcoin-test_getpublickey.py::test_invalid_path[Bitcoin-path0]": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"T1B1_en_bitcoin-test_getpublickey.py::test_invalid_path[Bitcoin-path2]": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",