diff --git a/core/src/apps/common/request_pin.py b/core/src/apps/common/request_pin.py index 42f1e2904..52bb82a92 100644 --- a/core/src/apps/common/request_pin.py +++ b/core/src/apps/common/request_pin.py @@ -10,20 +10,12 @@ from trezor.ui.text import Text from apps.common.sdcard import SdCardUnavailable, request_sd_salt if False: - from typing import Any, Optional, Tuple + from typing import Any, NoReturn, Optional, Tuple if __debug__: from apps.debug import input_signal -class PinCancelled(Exception): - pass - - -class PinInvalid(Exception): - pass - - async def request_pin( prompt: str = "Enter your PIN", attempts_remaining: int = None, @@ -44,19 +36,16 @@ async def request_pin( else: pin = await dialog if pin is CANCELLED: - raise PinCancelled + raise wire.PinCancelled assert isinstance(pin, str) return pin async def request_pin_ack(ctx: wire.Context, *args: Any, **kwargs: Any) -> str: - try: - await ctx.call(ButtonRequest(code=ButtonRequestType.Other), ButtonAck) - pin = await ctx.wait(request_pin(*args, **kwargs)) - assert isinstance(pin, str) - return pin - except PinCancelled: - raise wire.ActionCancelled("Cancelled") + await ctx.call(ButtonRequest(code=ButtonRequestType.Other), ButtonAck) + pin = await ctx.wait(request_pin(*args, **kwargs)) + assert isinstance(pin, str) + return pin async def request_pin_confirm(ctx: wire.Context, *args: Any, **kwargs: Any) -> str: @@ -103,7 +92,7 @@ async def verify_user_pin( try: salt = await request_sd_salt() except SdCardUnavailable: - raise PinCancelled + raise wire.PinCancelled("SD salt is unavailable") if config.unlock(pin_to_int(pin), salt): return elif not config.has_pin(): @@ -116,20 +105,22 @@ async def verify_user_pin( if config.unlock(pin_to_int(pin), salt): return - raise PinInvalid + raise wire.PinInvalid -async def show_pin_invalid(ctx: wire.Context) -> None: +async def error_pin_invalid(ctx: wire.Context) -> NoReturn: from apps.common.confirm import confirm text = Text("Wrong PIN", ui.ICON_WRONG, ui.RED) text.normal("The PIN you entered is", "invalid.") await confirm(ctx, text, confirm=None, cancel="Close") + raise wire.PinInvalid -async def show_pin_matches_wipe_code(ctx: wire.Context) -> None: +async def error_pin_matches_wipe_code(ctx: wire.Context) -> NoReturn: from apps.common.confirm import confirm text = Text("Invalid PIN", ui.ICON_WRONG, ui.RED) text.normal("The new PIN must be", "different from your", "wipe code.") await confirm(ctx, text, confirm=None, cancel="Close") + raise wire.PinInvalid diff --git a/core/src/apps/management/change_pin.py b/core/src/apps/management/change_pin.py index ce99e2b29..1858d9457 100644 --- a/core/src/apps/management/change_pin.py +++ b/core/src/apps/management/change_pin.py @@ -7,10 +7,10 @@ from trezor.ui.text import Text from apps.common.confirm import require_confirm from apps.common.layout import show_success from apps.common.request_pin import ( + error_pin_invalid, + error_pin_matches_wipe_code, request_pin_and_sd_salt, request_pin_confirm, - show_pin_invalid, - show_pin_matches_wipe_code, ) if False: @@ -30,8 +30,7 @@ async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success: # if changing pin, pre-check the entered pin before getting new pin if curpin and not msg.remove: if not config.check_pin(pin_to_int(curpin), salt): - await show_pin_invalid(ctx) - raise wire.PinInvalid("PIN invalid") + await error_pin_invalid(ctx) # get new pin if not msg.remove: @@ -42,10 +41,9 @@ async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success: # write into storage if not config.change_pin(pin_to_int(curpin), pin_to_int(newpin), salt, salt): if newpin: - await show_pin_matches_wipe_code(ctx) + await error_pin_matches_wipe_code(ctx) else: - await show_pin_invalid(ctx) - raise wire.PinInvalid("PIN invalid") + await error_pin_invalid(ctx) if newpin: if curpin: diff --git a/core/src/apps/management/change_wipe_code.py b/core/src/apps/management/change_wipe_code.py index 9fc269270..a24478c7f 100644 --- a/core/src/apps/management/change_wipe_code.py +++ b/core/src/apps/management/change_wipe_code.py @@ -8,9 +8,9 @@ from trezor.ui.text import Text from apps.common.confirm import require_confirm from apps.common.layout import show_success from apps.common.request_pin import ( + error_pin_invalid, request_pin_ack, request_pin_and_sd_salt, - show_pin_invalid, ) if False: @@ -31,8 +31,7 @@ async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success: if not msg.remove: # Pre-check the entered PIN. if config.has_pin() and not config.check_pin(pin_to_int(pin), salt): - await show_pin_invalid(ctx) - raise wire.PinInvalid("PIN invalid") + await error_pin_invalid(ctx) # Get new wipe code. wipe_code = await _request_wipe_code_confirm(ctx, pin) @@ -41,8 +40,7 @@ async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success: # Write into storage. if not config.change_wipe_code(pin_to_int(pin), salt, pin_to_int(wipe_code)): - await show_pin_invalid(ctx) - raise wire.PinInvalid("PIN invalid") + await error_pin_invalid(ctx) if wipe_code: if has_wipe_code: diff --git a/core/src/apps/management/recovery_device/__init__.py b/core/src/apps/management/recovery_device/__init__.py index 515140b8c..f2b009921 100644 --- a/core/src/apps/management/recovery_device/__init__.py +++ b/core/src/apps/management/recovery_device/__init__.py @@ -9,9 +9,9 @@ from trezor.ui.text import Text from apps.common.confirm import require_confirm from apps.common.request_pin import ( + error_pin_invalid, request_pin_and_sd_salt, request_pin_confirm, - show_pin_invalid, ) from apps.management.recovery_device.homescreen import ( recovery_homescreen, @@ -46,8 +46,7 @@ async def recovery_device(ctx: wire.Context, msg: RecoveryDevice) -> Success: if msg.dry_run: curpin, salt = await request_pin_and_sd_salt(ctx, "Enter PIN") if not config.check_pin(pin_to_int(curpin), salt): - await show_pin_invalid(ctx) - raise wire.PinInvalid("PIN invalid") + await error_pin_invalid(ctx) if not msg.dry_run: # set up pin if requested diff --git a/core/src/apps/management/sd_protect.py b/core/src/apps/management/sd_protect.py index 071d3a472..55538cf4e 100644 --- a/core/src/apps/management/sd_protect.py +++ b/core/src/apps/management/sd_protect.py @@ -10,9 +10,9 @@ from trezor.ui.text import Text from apps.common.confirm import require_confirm from apps.common.layout import show_success from apps.common.request_pin import ( + error_pin_invalid, request_pin_ack, request_pin_and_sd_salt, - show_pin_invalid, ) from apps.common.sdcard import ensure_sdcard, sd_problem_dialog @@ -83,8 +83,7 @@ async def sd_protect_enable(ctx: wire.Context, msg: SdProtect) -> Success: # SD-protection. If it fails for any reason, we suppress the # exception, because primarily we need to raise wire.PinInvalid. pass - await show_pin_invalid(ctx) - raise wire.PinInvalid("PIN invalid") + await error_pin_invalid(ctx) storage.device.set_sd_salt_auth_key(salt_auth_key) @@ -107,8 +106,7 @@ async def sd_protect_disable(ctx: wire.Context, msg: SdProtect) -> Success: # Check PIN and remove salt. if not config.change_pin(pin_to_int(pin), pin_to_int(pin), salt, None): - await show_pin_invalid(ctx) - raise wire.PinInvalid("PIN invalid") + await error_pin_invalid(ctx) storage.device.set_sd_salt_auth_key(None) @@ -143,8 +141,7 @@ async def sd_protect_refresh(ctx: wire.Context, msg: SdProtect) -> Success: await _set_salt(ctx, new_salt, new_salt_tag, stage=True) if not config.change_pin(pin_to_int(pin), pin_to_int(pin), old_salt, new_salt): - await show_pin_invalid(ctx) - raise wire.PinInvalid("PIN invalid") + await error_pin_invalid(ctx) storage.device.set_sd_salt_auth_key(new_auth_key) diff --git a/core/src/apps/webauthn/fido2.py b/core/src/apps/webauthn/fido2.py index 78231de41..50bdcce48 100644 --- a/core/src/apps/webauthn/fido2.py +++ b/core/src/apps/webauthn/fido2.py @@ -576,7 +576,8 @@ class KeepaliveCallback: async def verify_user(keepalive_callback: KeepaliveCallback) -> bool: - from apps.common.request_pin import verify_user_pin, PinCancelled, PinInvalid + from trezor.wire import PinCancelled, PinInvalid + from apps.common.request_pin import verify_user_pin import trezor.pin try: diff --git a/core/src/boot.py b/core/src/boot.py index a8b5168fd..54a9d6f64 100644 --- a/core/src/boot.py +++ b/core/src/boot.py @@ -1,10 +1,10 @@ import storage import storage.device import storage.sd_salt -from trezor import config, log, loop, res, ui, utils +from trezor import config, log, loop, res, ui, utils, wire from trezor.pin import show_pin_timeout -from apps.common.request_pin import PinCancelled, verify_user_pin +from apps.common.request_pin import verify_user_pin async def bootscreen() -> None: @@ -16,12 +16,11 @@ async def bootscreen() -> None: await verify_user_pin() storage.init_unlocked() return - except PinCancelled as e: + except wire.PinCancelled: # verify_user_pin will convert a SdCardUnavailable (in case of sd salt) # to PinCancelled exception. - # log the exception and retry loop - if __debug__: - log.exception(__name__, e) + # Ignore exception, retry loop. + pass except BaseException as e: # other exceptions here are unexpected and should halt the device if __debug__: