diff --git a/core/.changelog.d/2818.added b/core/.changelog.d/2818.added new file mode 100644 index 000000000..82d387340 --- /dev/null +++ b/core/.changelog.d/2818.added @@ -0,0 +1 @@ +Add address confirmation screen to EIP712 signing flow diff --git a/core/src/apps/ethereum/layout.py b/core/src/apps/ethereum/layout.py index 72513517f..615d2dd90 100644 --- a/core/src/apps/ethereum/layout.py +++ b/core/src/apps/ethereum/layout.py @@ -114,6 +114,19 @@ def require_confirm_unknown_token( ) +def require_confirm_address(ctx: Context, address_bytes: bytes) -> Awaitable[None]: + from ubinascii import hexlify + from trezor.ui.layouts import confirm_address + + address_hex = "0x" + hexlify(address_bytes).decode() + return confirm_address( + ctx, + "Signing address", + address_hex, + br_code=ButtonRequestType.SignTx, + ) + + def require_confirm_data(ctx: Context, data: bytes, data_total: int) -> Awaitable[None]: return confirm_blob( ctx, diff --git a/core/src/apps/ethereum/sign_typed_data.py b/core/src/apps/ethereum/sign_typed_data.py index f452a64f0..c1605ad61 100644 --- a/core/src/apps/ethereum/sign_typed_data.py +++ b/core/src/apps/ethereum/sign_typed_data.py @@ -27,21 +27,27 @@ async def sign_typed_data( from trezor.crypto.curve import secp256k1 from apps.common import paths from .helpers import address_from_bytes + from .layout import require_confirm_address from trezor.messages import EthereumTypedDataSignature await paths.validate_path(ctx, keychain, msg.address_n) + node = keychain.derive(msg.address_n) + address_bytes: bytes = node.ethereum_pubkeyhash() + + # Display address so user can validate it + await require_confirm_address(ctx, address_bytes) + data_hash = await _generate_typed_data_hash( ctx, msg.primary_type, msg.metamask_v4_compat ) - node = keychain.derive(msg.address_n) signature = secp256k1.sign( node.private_key(), data_hash, False, secp256k1.CANONICAL_SIG_ETHEREUM ) return EthereumTypedDataSignature( - address=address_from_bytes(node.ethereum_pubkeyhash()), + address=address_from_bytes(address_bytes), signature=signature[1:] + signature[0:1], ) diff --git a/tests/device_tests/ethereum/test_sign_typed_data.py b/tests/device_tests/ethereum/test_sign_typed_data.py index a58e828c2..99821cc86 100644 --- a/tests/device_tests/ethereum/test_sign_typed_data.py +++ b/tests/device_tests/ethereum/test_sign_typed_data.py @@ -96,6 +96,9 @@ DATA = { def input_flow_show_more(client: Client): """Clicks show_more button wherever possible""" + yield # confirm address + client.debug.press_yes() + yield # confirm domain client.debug.wait_layout() client.debug.click(SHOW_MORE) @@ -136,6 +139,9 @@ def input_flow_show_more(client: Client): def input_flow_cancel(client: Client): """Clicks cancelling button""" + yield # confirm address + client.debug.press_yes() + yield # confirm domain client.debug.press_no() diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 7ed9c0601..caf8badf5 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -1375,17 +1375,17 @@ "TT_ethereum-test_getpublickey.py::test_ethereum_getpublickey[parameters0-result0]": "a4ecdfc2bed7623cc1dda09dcefb077c09a8d8e9aec596f94bc14351fe94b50b", "TT_ethereum-test_getpublickey.py::test_ethereum_getpublickey[parameters1-result1]": "a4ecdfc2bed7623cc1dda09dcefb077c09a8d8e9aec596f94bc14351fe94b50b", "TT_ethereum-test_getpublickey.py::test_ethereum_getpublickey[parameters2-result2]": "a4ecdfc2bed7623cc1dda09dcefb077c09a8d8e9aec596f94bc14351fe94b50b", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[array_of_structs]": "b36752afa7b5c14a924af1dcf7f3a3aa71e31ac979170bd6b34e110a6679c69b", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[bare_minimum]": "004a62518d42015a98fd250e7b55e28b695de689f48133406ba23262f6c8bb5c", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[basic_data]": "e9da8ee8b66029ef3a496125d89f8d0a206d53ee0eb9d2cec03923c5e46b543c", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[complex_data]": "6fc66270da0100317b563415e411c42b2dd8e16478a09ba4d907b9a6e45316e8", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[full_domain_empty_message]": "9afcf48978782dd150589d95116d96d0087145be3d4145eaf1012963fd76fa87", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[injective_testcase]": "ba7832596bc855b4ac82ebd4a5e6b139cd67939ce36030b26eb853117613465c", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[struct_list_non_v4]": "e9da8ee8b66029ef3a496125d89f8d0a206d53ee0eb9d2cec03923c5e46b543c", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[struct_list_v4]": "e9da8ee8b66029ef3a496125d89f8d0a206d53ee0eb9d2cec03923c5e46b543c", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[structs_arrays_v4]": "e9da8ee8b66029ef3a496125d89f8d0a206d53ee0eb9d2cec03923c5e46b543c", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data_cancel": "235da2ec1fd5b98e511e39841e0d6a9bcca68bcabff5b1f98875b74b6f183195", -"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data_show_more_button": "8ec2b388649f24cda4fe4222ac94d2a5f819ccb84bfa3508d3fcd157df61229f", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[array_of_structs]": "ed5f9713f768c531956e6643a15c132ce5ec50f8b0db2cd3b66bb93ed779e78b", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[bare_minimum]": "d6a7b9b93f9aec22aeda2ae7b9c197af75d841ac0204fbe5106ceb0c3fa4aaa7", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[basic_data]": "9d8fff61e26bd5d1dedf09361d53ba7420dd59c341509173c0cc78e1a216df5f", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[complex_data]": "5b650c855631cb16a3ba6ff67a3c18ec49945e38460794a99ba2cb3bb70ddc8e", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[full_domain_empty_message]": "f43c95e6f1df42e4717909ea4c209b35a7df2c9c5f3bfae36ae51d613470d0a7", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[injective_testcase]": "eee81511fcf5c02ad56f295b6ad7828ede1f9b0ba348dc7a4aacad1379b06a70", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[struct_list_non_v4]": "9d8fff61e26bd5d1dedf09361d53ba7420dd59c341509173c0cc78e1a216df5f", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[struct_list_v4]": "9d8fff61e26bd5d1dedf09361d53ba7420dd59c341509173c0cc78e1a216df5f", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data[structs_arrays_v4]": "9d8fff61e26bd5d1dedf09361d53ba7420dd59c341509173c0cc78e1a216df5f", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data_cancel": "f96d4a98db012ef1ea0a156b2bf56e165852d7c8b1e418e84a1070463337da0b", +"TT_ethereum-test_sign_typed_data.py::test_ethereum_sign_typed_data_show_more_button": "6e83493a3cf94fc4f97e70d004dbc7c808f10e7fef6defeda0c875af05db7577", "TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters0-result0]": "eb132cf1874910be4ebe4f19209b5d09da5cefefbd5151d796e2dd63f139232a", "TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters1-result1]": "f123d3b95e3e76fe15dbd88d67bbf4bba249b4017ce9f81ebad2f4d501a2a618", "TT_ethereum-test_sign_verify_message.py::test_signmessage[parameters2-result2]": "fbbbaffe08edf05f2cbbb513b736c594e71ad3c160bfef096a91bcc4995f6abb",