From 3517018f30ea29527d60934d9cd9151d521bac9b Mon Sep 17 00:00:00 2001 From: andrew Date: Fri, 28 Dec 2018 17:10:16 +0100 Subject: [PATCH] Display the number of PIN entry attempts remaining. --- src/apps/common/request_pin.py | 10 ++++++++-- src/apps/common/storage.py | 8 ++++---- src/apps/management/change_pin.py | 2 +- src/boot.py | 2 +- src/trezor/ui/pin.py | 9 +++++++-- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/apps/common/request_pin.py b/src/apps/common/request_pin.py index 1c9d0e04f6..24f2d90da6 100644 --- a/src/apps/common/request_pin.py +++ b/src/apps/common/request_pin.py @@ -11,7 +11,7 @@ class PinCancelled(Exception): @ui.layout -async def request_pin(label=None, cancellable: bool = True) -> str: +async def request_pin(label=None, attempts_remaining=None, cancellable: bool = True) -> str: def onchange(): c = dialog.cancel if matrix.pin: @@ -36,7 +36,13 @@ async def request_pin(label=None, cancellable: bool = True) -> str: if label is None: label = "Enter your PIN" - matrix = PinMatrix(label) + sublabel = None + if attempts_remaining: + if attempts_remaining == 1: + sublabel = "This is your last attempt" + else: + sublabel = "{} attempts remaining".format(attempts_remaining) + matrix = PinMatrix(label, sublabel) matrix.onchange = onchange dialog = ConfirmDialog(matrix) dialog.cancel.area = ui.grid(12) diff --git a/src/apps/common/storage.py b/src/apps/common/storage.py index b16d8be57a..7954c015ae 100644 --- a/src/apps/common/storage.py +++ b/src/apps/common/storage.py @@ -34,11 +34,11 @@ def _new_device_id() -> str: def get_device_id() -> str: - dev_id = config.get(_APP, _DEVICE_ID, True).decode() # public + dev_id = config.get(_APP, _DEVICE_ID, True) # public if not dev_id: - dev_id = _new_device_id() - config.set(_APP, _DEVICE_ID, dev_id.encode(), True) # public - return dev_id + dev_id = _new_device_id().encode() + config.set(_APP, _DEVICE_ID, dev_id, True) # public + return dev_id.decode() def is_initialized() -> bool: diff --git a/src/apps/management/change_pin.py b/src/apps/management/change_pin.py index 2c554b8fb8..71f01ed0c9 100644 --- a/src/apps/management/change_pin.py +++ b/src/apps/management/change_pin.py @@ -16,7 +16,7 @@ async def change_pin(ctx, msg): # get current pin, return failure if invalid if config.has_pin(): - curpin = await request_pin_ack(ctx) + curpin = await request_pin_ack(ctx, "Enter old PIN", config.get_pin_rem()) if not config.check_pin(pin_to_int(curpin)): raise wire.PinInvalid("PIN invalid") else: diff --git a/src/boot.py b/src/boot.py index 622562152c..cec662cdb6 100644 --- a/src/boot.py +++ b/src/boot.py @@ -13,7 +13,7 @@ async def bootscreen(): await lockscreen() label = None while True: - pin = await request_pin(label) + pin = await request_pin(label, config.get_pin_rem()) if config.unlock(pin_to_int(pin)): return else: diff --git a/src/trezor/ui/pin.py b/src/trezor/ui/pin.py index 00bf610291..5ae89f663b 100644 --- a/src/trezor/ui/pin.py +++ b/src/trezor/ui/pin.py @@ -19,8 +19,9 @@ def generate_digits(): class PinMatrix(ui.Widget): - def __init__(self, label, pin="", maxlength=9): + def __init__(self, label, sublabel, pin="", maxlength=9): self.label = label + self.sublabel = sublabel self.pin = pin self.maxlength = maxlength self.digits = generate_digits() @@ -48,7 +49,7 @@ class PinMatrix(ui.Widget): return # clear canvas under input line - display.bar(0, 0, ui.WIDTH, 45, ui.BG) + display.bar(0, 0, ui.WIDTH, 52, ui.BG) if self.pin: # input line with pin @@ -60,6 +61,10 @@ class PinMatrix(ui.Widget): x = (box_w - l * padding) // 2 for i in range(0, l): ui.display.bar_radius(x + i * padding, y, size, size, ui.GREY, ui.BG, 4) + elif self.sublabel: + # input line with header label and sublabel + display.text_center(ui.WIDTH // 2, 20, self.label, ui.BOLD, ui.GREY, ui.BG) + display.text_center(ui.WIDTH // 2, 46, self.sublabel, ui.NORMAL, ui.GREY, ui.BG) else: # input line with header label display.text_center(ui.WIDTH // 2, 36, self.label, ui.BOLD, ui.GREY, ui.BG)