You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/src/apps/common/request_passphrase.py

78 lines
2.6 KiB

from trezor import ui, wire
from trezor.messages import ButtonRequestType, MessageType, PassphraseSourceType
from trezor.messages.ButtonRequest import ButtonRequest
from trezor.messages.PassphraseRequest import PassphraseRequest
from trezor.messages.PassphraseStateRequest import PassphraseStateRequest
from trezor.ui.entry_select import DEVICE, EntrySelector
from trezor.ui.passphrase import CANCELLED, PassphraseKeyboard
from trezor.ui.text import Text
from apps.common import storage
from apps.common.cache import get_state
@ui.layout
async def request_passphrase_entry(ctx):
text = Text("Enter passphrase", ui.ICON_CONFIG)
text.normal("Where to enter your", "passphrase?")
text.render()
ack = await ctx.call(
ButtonRequest(code=ButtonRequestType.PassphraseType),
MessageType.ButtonAck,
MessageType.Cancel,
)
if ack.MESSAGE_WIRE_TYPE == MessageType.Cancel:
raise wire.ActionCancelled("Passphrase cancelled")
selector = EntrySelector(text)
return await ctx.wait(selector)
@ui.layout
async def request_passphrase_ack(ctx, on_device):
if not on_device:
text = Text("Passphrase entry", ui.ICON_CONFIG)
text.normal("Please, type passphrase", "on connected host.")
text.render()
req = PassphraseRequest(on_device=on_device)
ack = await ctx.call(req, MessageType.PassphraseAck, MessageType.Cancel)
if ack.MESSAGE_WIRE_TYPE == MessageType.Cancel:
raise wire.ActionCancelled("Passphrase cancelled")
if on_device:
if ack.passphrase is not None:
raise wire.ProcessError("Passphrase provided when it should not be")
keyboard = PassphraseKeyboard("Enter passphrase")
passphrase = await ctx.wait(keyboard)
if passphrase == CANCELLED:
raise wire.ActionCancelled("Passphrase cancelled")
else:
if ack.passphrase is None:
raise wire.ProcessError("Passphrase not provided")
passphrase = ack.passphrase
req = PassphraseStateRequest(
state=get_state(prev_state=ack.state, passphrase=passphrase)
)
ack = await ctx.call(req, MessageType.PassphraseStateAck, MessageType.Cancel)
return passphrase
async def request_passphrase(ctx):
if storage.get_passphrase_source() == PassphraseSourceType.ASK:
on_device = await request_passphrase_entry(ctx) == DEVICE
else:
on_device = storage.get_passphrase_source() == PassphraseSourceType.DEVICE
passphrase = await request_passphrase_ack(ctx, on_device)
return passphrase
async def protect_by_passphrase(ctx):
if storage.has_passphrase():
return await request_passphrase(ctx)
else:
return ""