mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 22:38:08 +00:00
apps.common: add client-side pin input method
This commit is contained in:
parent
d00a6723c0
commit
722cc2d63b
@ -2,9 +2,12 @@ from trezor import ui
|
|||||||
from trezor import wire
|
from trezor import wire
|
||||||
from trezor.utils import unimport
|
from trezor.utils import unimport
|
||||||
|
|
||||||
|
# TODO: publish only when debuglink is on
|
||||||
|
matrix = None
|
||||||
|
|
||||||
|
|
||||||
@unimport
|
@unimport
|
||||||
async def request_pin(session_id, *args, **kwargs):
|
async def request_pin_on_display(session_id: int, code: int=None) -> str:
|
||||||
from trezor.messages.ButtonRequest import ButtonRequest
|
from trezor.messages.ButtonRequest import ButtonRequest
|
||||||
from trezor.messages.ButtonRequestType import ProtectCall
|
from trezor.messages.ButtonRequestType import ProtectCall
|
||||||
from trezor.messages.FailureType import PinCancelled
|
from trezor.messages.FailureType import PinCancelled
|
||||||
@ -12,26 +15,79 @@ async def request_pin(session_id, *args, **kwargs):
|
|||||||
from trezor.ui.confirm import ConfirmDialog, CONFIRMED
|
from trezor.ui.confirm import ConfirmDialog, CONFIRMED
|
||||||
from trezor.ui.pin import PinMatrix
|
from trezor.ui.pin import PinMatrix
|
||||||
|
|
||||||
|
global matrix
|
||||||
|
|
||||||
|
_, label = _get_code_and_label(code)
|
||||||
|
|
||||||
await wire.reply_message(session_id,
|
await wire.reply_message(session_id,
|
||||||
ButtonRequest(code=ProtectCall),
|
ButtonRequest(code=ProtectCall),
|
||||||
ButtonAck)
|
ButtonAck)
|
||||||
|
|
||||||
ui.display.clear()
|
ui.display.clear()
|
||||||
matrix = PinMatrix(*args, **kwargs)
|
matrix = PinMatrix(label)
|
||||||
dialog = ConfirmDialog(matrix)
|
dialog = ConfirmDialog(matrix)
|
||||||
|
pin = matrix.pin
|
||||||
|
matrix = None
|
||||||
|
|
||||||
if await dialog != CONFIRMED:
|
if await dialog != CONFIRMED:
|
||||||
raise wire.FailureError(PinCancelled, 'PIN cancelled')
|
raise wire.FailureError(PinCancelled, 'PIN cancelled')
|
||||||
|
return pin
|
||||||
return matrix.pin
|
|
||||||
|
|
||||||
|
|
||||||
@unimport
|
@unimport
|
||||||
async def request_pin_twice(session_id):
|
async def request_pin_on_client(session_id: int, code: int=None) -> str:
|
||||||
from trezor.messages.FailureType import PinInvalid
|
from trezor.messages.FailureType import PinCancelled
|
||||||
|
from trezor.messages.PinMatrixRequest import PinMatrixRequest
|
||||||
|
from trezor.messages.wire_types import PinMatrixAck, Cancel
|
||||||
|
from trezor.ui.pin import PinMatrix
|
||||||
|
|
||||||
pin_first = await request_pin(session_id)
|
global matrix
|
||||||
pin_again = await request_pin(session_id, 'Enter PIN again')
|
|
||||||
|
code, label = _get_code_and_label(code)
|
||||||
|
|
||||||
|
ui.display.clear()
|
||||||
|
matrix = PinMatrix(label)
|
||||||
|
matrix.render()
|
||||||
|
|
||||||
|
ack = await wire.reply_message(session_id,
|
||||||
|
PinMatrixRequest(code=code),
|
||||||
|
PinMatrixAck, Cancel)
|
||||||
|
digits = matrix.digits
|
||||||
|
matrix = None
|
||||||
|
|
||||||
|
if ack.WIRE_TYPE == Cancel:
|
||||||
|
raise wire.FailureError(PinCancelled, 'PIN cancelled')
|
||||||
|
return _decode_pin(ack.pin, digits)
|
||||||
|
|
||||||
|
|
||||||
|
request_pin = request_pin_on_client
|
||||||
|
|
||||||
|
|
||||||
|
@unimport
|
||||||
|
async def request_pin_twice(session_id: int) -> str:
|
||||||
|
from trezor.messages.FailureType import PinInvalid
|
||||||
|
from trezor.messages import PinMatrixRequestType
|
||||||
|
|
||||||
|
pin_first = await request_pin(session_id, PinMatrixRequestType.NewFirst)
|
||||||
|
pin_again = await request_pin(session_id, PinMatrixRequestType.NewSecond)
|
||||||
if pin_first != pin_again:
|
if pin_first != pin_again:
|
||||||
raise wire.FailureError(PinInvalid, 'PIN invalid')
|
raise wire.FailureError(PinInvalid, 'PIN invalid')
|
||||||
|
|
||||||
return pin_first
|
return pin_first
|
||||||
|
|
||||||
|
|
||||||
|
def _get_code_and_label(code: int) -> str:
|
||||||
|
from trezor.messages import PinMatrixRequestType
|
||||||
|
if code is None:
|
||||||
|
code = PinMatrixRequestType.Current
|
||||||
|
if code == PinMatrixRequestType.NewFirst:
|
||||||
|
label = 'Enter new PIN'
|
||||||
|
elif code == PinMatrixRequestType.NewSecond:
|
||||||
|
label = 'Enter new PIN again'
|
||||||
|
else: # PinMatrixRequestType.Current
|
||||||
|
label = 'Enter PIN'
|
||||||
|
return code, label
|
||||||
|
|
||||||
|
|
||||||
|
def _decode_pin(pin: str, secret: list) -> str:
|
||||||
|
return ''.join([str(secret[int(d) - 1]) for d in pin])
|
||||||
|
@ -10,7 +10,9 @@ def digit_area(i):
|
|||||||
height = const(48)
|
height = const(48)
|
||||||
x = (i % 3) * width
|
x = (i % 3) * width
|
||||||
y = (i // 3) * height
|
y = (i // 3) * height
|
||||||
return (x, y + 48, width - 1, height - 1) # 48px is offset of input line / -1px is due to corner bug of overlaying elements
|
# 48px is offset of input line / -1px is due to corner bug of overlaying
|
||||||
|
# elements
|
||||||
|
return (x, y + 48, width - 1, height - 1)
|
||||||
|
|
||||||
|
|
||||||
def generate_digits():
|
def generate_digits():
|
||||||
@ -21,15 +23,21 @@ def generate_digits():
|
|||||||
|
|
||||||
class PinMatrix():
|
class PinMatrix():
|
||||||
|
|
||||||
def __init__(self, label='Enter PIN', pin=''):
|
def __init__(self, label, pin=''):
|
||||||
self.label = label
|
self.label = label
|
||||||
self.pin = pin
|
self.pin = pin
|
||||||
|
self.digits = generate_digits()
|
||||||
|
|
||||||
|
# we lay out the buttons top-left to bottom-right, but the order of the
|
||||||
|
# digits is defined as bottom-left to top-right (on numpad)
|
||||||
|
reordered_digits = self.digits[6:] + self.digits[3:6] + self.digits[:3]
|
||||||
|
self.pin_buttons = [Button(digit_area(i), str(d))
|
||||||
|
for i, d in enumerate(reordered_digits)]
|
||||||
|
|
||||||
self.clear_button = Button((240 - 35, 5, 30, 30),
|
self.clear_button = Button((240 - 35, 5, 30, 30),
|
||||||
res.load('trezor/res/pin_close.toig'),
|
res.load('trezor/res/pin_close.toig'),
|
||||||
normal_style=CLEAR_BUTTON,
|
normal_style=CLEAR_BUTTON,
|
||||||
active_style=CLEAR_BUTTON_ACTIVE)
|
active_style=CLEAR_BUTTON_ACTIVE)
|
||||||
self.pin_buttons = [Button(digit_area(i), str(d))
|
|
||||||
for i, d in enumerate(generate_digits())]
|
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user