diff --git a/core/src/apps/base.py b/core/src/apps/base.py index 18d96e717..cb6c14035 100644 --- a/core/src/apps/base.py +++ b/core/src/apps/base.py @@ -6,6 +6,7 @@ from storage import cache from trezor import config, sdcard, utils, wire, workflow from trezor.messages import Capability, MessageType from trezor.messages.Features import Features +from trezor.messages.PreauthorizedRequest import PreauthorizedRequest from trezor.messages.Success import Success from apps.common import mnemonic @@ -13,12 +14,22 @@ from apps.common.request_pin import verify_user_pin if False: import protobuf - from typing import Optional, NoReturn + from typing import Iterable, NoReturn, Optional, Protocol from trezor.messages.Initialize import Initialize from trezor.messages.GetFeatures import GetFeatures from trezor.messages.Cancel import Cancel from trezor.messages.LockDevice import LockDevice from trezor.messages.Ping import Ping + from trezor.messages.DoPreauthorized import DoPreauthorized + +if False: + + class Authorization(Protocol): + def expected_wire_types(self) -> Iterable[int]: + ... + + def __del__(self) -> None: + ... def get_features() -> Features: @@ -114,11 +125,41 @@ async def handle_Ping(ctx: wire.Context, msg: Ping) -> Success: return Success(message=msg.message) +async def handle_DoPreauthorized( + ctx: wire.Context, msg: DoPreauthorized +) -> protobuf.MessageType: + authorization = storage.cache.get( + storage.cache.APP_BASE_AUTHORIZATION + ) # type: Authorization + if not authorization: + raise wire.ProcessError("No preauthorized operation") + + req = await ctx.call_any( + PreauthorizedRequest(), *authorization.expected_wire_types() + ) + + handler = wire.find_registered_workflow_handler(ctx.iface, req.MESSAGE_WIRE_TYPE) + if handler is None: + return wire.unexpected_message() + + return await handler(ctx, req, authorization) # type: ignore + + +def set_authorization(authorization: Authorization) -> None: + previous = storage.cache.get( + storage.cache.APP_BASE_AUTHORIZATION + ) # type: Authorization + if previous: + previous.__del__() + storage.cache.set(storage.cache.APP_BASE_AUTHORIZATION, authorization) + + ALLOW_WHILE_LOCKED = ( MessageType.Initialize, MessageType.GetFeatures, MessageType.Cancel, MessageType.LockDevice, + MessageType.DoPreauthorized, MessageType.WipeDevice, ) @@ -193,5 +234,6 @@ def boot() -> None: wire.register(MessageType.Cancel, handle_Cancel) wire.register(MessageType.LockDevice, handle_LockDevice) wire.register(MessageType.Ping, handle_Ping) + wire.register(MessageType.DoPreauthorized, handle_DoPreauthorized) workflow.idle_timer.set(storage.device.get_autolock_delay_ms(), lock_device) diff --git a/core/src/apps/bitcoin/sign_tx/progress.py b/core/src/apps/bitcoin/sign_tx/progress.py index 1cd8003a9..440eda463 100644 --- a/core/src/apps/bitcoin/sign_tx/progress.py +++ b/core/src/apps/bitcoin/sign_tx/progress.py @@ -1,4 +1,4 @@ -from trezor import ui, utils +from trezor import ui, utils, workflow _progress = 0 _steps = 0 @@ -19,6 +19,7 @@ def advance(i: int = 1) -> None: def report_init() -> None: + workflow.close_others() ui.display.clear() ui.header("Signing transaction") diff --git a/core/src/storage/cache.py b/core/src/storage/cache.py index 13765224f..ff495b025 100644 --- a/core/src/storage/cache.py +++ b/core/src/storage/cache.py @@ -10,6 +10,7 @@ _SESSIONLESS_FLAG = 128 APP_COMMON_SEED = 0 APP_CARDANO_ROOT = 1 APP_MONERO_LIVE_REFRESH = 2 +APP_BASE_AUTHORIZATION = 3 # Keys that are valid across sessions APP_COMMON_SEED_WITHOUT_PASSPHRASE = 1 | _SESSIONLESS_FLAG diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 185d8c494..a4c6e09a8 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -332,7 +332,7 @@ "test_msg_signtx_komodo.py-test_one_one_rewards_claim": "e53f221fda81469027e39e21877a81a8fafbffbece0a45aeda12aae8873b0464", "test_msg_signtx_peercoin.py::test_timestamp_included": "825b9bdf5238c5c6415a254a6bae4b2bd9df8fc5cb31f66f0c20145cb4e60bbb", "test_msg_signtx_segwit.py-test_attack_change_input_address": "5ae71202c062ef7942626a80a4ceeb8d8c4ea5065a97f0de6a97505e9cb82c2c", -"test_msg_signtx_segwit.py-test_attack_mixed_inputs": "1ae5200c6ce74cefae77ab1cfd6e032d0660aa4d106b8c54e092856f656f1e39", +"test_msg_signtx_segwit.py-test_attack_mixed_inputs": "406596db037a13d5e26b3829a74b6efcde1d13159532a36fcd6b1b4bdcef3781", "test_msg_signtx_segwit.py-test_send_multisig_1": "958a0741070e057dcb889b2000e5487d391bc513e4a5d86193a355261c5f361b", "test_msg_signtx_segwit.py-test_send_p2sh": "ca593e31e919b9e920289b13e4c70b9607f34b93d06ace69835e3d08ecf046c8", "test_msg_signtx_segwit.py-test_send_p2sh_change": "562c7ee5a2e264c9f93387dd165403dab32bb305a4c3a6143a902c4a4c9e5950",