mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-16 11:28:14 +00:00
src/trezor/wire: add exceptions for all defined FailureTypes
Makes the error API much more ergonomic.
This commit is contained in:
parent
7df4b251ea
commit
db696b23fd
@ -1,5 +1,5 @@
|
|||||||
from trezor import ui, wire
|
from trezor import ui, wire
|
||||||
from trezor.messages import ButtonRequestType, FailureType, wire_types
|
from trezor.messages import ButtonRequestType, wire_types
|
||||||
from trezor.messages.ButtonRequest import ButtonRequest
|
from trezor.messages.ButtonRequest import ButtonRequest
|
||||||
from trezor.ui.confirm import CONFIRMED, ConfirmDialog, HoldToConfirmDialog
|
from trezor.ui.confirm import CONFIRMED, ConfirmDialog, HoldToConfirmDialog
|
||||||
|
|
||||||
@ -29,10 +29,10 @@ async def hold_to_confirm(ctx, content, code=None, *args, **kwargs):
|
|||||||
async def require_confirm(*args, **kwargs):
|
async def require_confirm(*args, **kwargs):
|
||||||
confirmed = await confirm(*args, **kwargs)
|
confirmed = await confirm(*args, **kwargs)
|
||||||
if not confirmed:
|
if not confirmed:
|
||||||
raise wire.FailureError(FailureType.ActionCancelled, 'Cancelled')
|
raise wire.ActionCancelled('Cancelled')
|
||||||
|
|
||||||
|
|
||||||
async def require_hold_to_confirm(*args, **kwargs):
|
async def require_hold_to_confirm(*args, **kwargs):
|
||||||
confirmed = await hold_to_confirm(*args, **kwargs)
|
confirmed = await hold_to_confirm(*args, **kwargs)
|
||||||
if not confirmed:
|
if not confirmed:
|
||||||
raise wire.FailureError(FailureType.ActionCancelled, 'Cancelled')
|
raise wire.ActionCancelled('Cancelled')
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from trezor import ui, wire
|
from trezor import ui, wire
|
||||||
from trezor.messages import ButtonRequestType, wire_types
|
from trezor.messages import ButtonRequestType, wire_types
|
||||||
from trezor.messages.ButtonRequest import ButtonRequest
|
from trezor.messages.ButtonRequest import ButtonRequest
|
||||||
from trezor.messages.FailureType import ActionCancelled, ProcessError
|
|
||||||
from trezor.messages import PassphraseSourceType
|
from trezor.messages import PassphraseSourceType
|
||||||
from trezor.messages.PassphraseRequest import PassphraseRequest
|
from trezor.messages.PassphraseRequest import PassphraseRequest
|
||||||
from trezor.messages.PassphraseStateRequest import PassphraseStateRequest
|
from trezor.messages.PassphraseStateRequest import PassphraseStateRequest
|
||||||
@ -24,7 +23,7 @@ async def request_passphrase_entry(ctx):
|
|||||||
wire_types.ButtonAck,
|
wire_types.ButtonAck,
|
||||||
wire_types.Cancel)
|
wire_types.Cancel)
|
||||||
if ack.MESSAGE_WIRE_TYPE == wire_types.Cancel:
|
if ack.MESSAGE_WIRE_TYPE == wire_types.Cancel:
|
||||||
raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')
|
raise wire.ActionCancelled('Passphrase cancelled')
|
||||||
|
|
||||||
selector = EntrySelector(text)
|
selector = EntrySelector(text)
|
||||||
return await ctx.wait(selector)
|
return await ctx.wait(selector)
|
||||||
@ -41,18 +40,18 @@ async def request_passphrase_ack(ctx, on_device):
|
|||||||
req = PassphraseRequest(on_device=on_device)
|
req = PassphraseRequest(on_device=on_device)
|
||||||
ack = await ctx.call(req, wire_types.PassphraseAck, wire_types.Cancel)
|
ack = await ctx.call(req, wire_types.PassphraseAck, wire_types.Cancel)
|
||||||
if ack.MESSAGE_WIRE_TYPE == wire_types.Cancel:
|
if ack.MESSAGE_WIRE_TYPE == wire_types.Cancel:
|
||||||
raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')
|
raise wire.ActionCancelled('Passphrase cancelled')
|
||||||
|
|
||||||
if on_device:
|
if on_device:
|
||||||
if ack.passphrase is not None:
|
if ack.passphrase is not None:
|
||||||
raise wire.FailureError(ProcessError, 'Passphrase provided when it should not be')
|
raise wire.ProcessError('Passphrase provided when it should not be')
|
||||||
keyboard = PassphraseKeyboard('Enter passphrase')
|
keyboard = PassphraseKeyboard('Enter passphrase')
|
||||||
passphrase = await ctx.wait(keyboard)
|
passphrase = await ctx.wait(keyboard)
|
||||||
if passphrase == CANCELLED:
|
if passphrase == CANCELLED:
|
||||||
raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')
|
raise wire.ActionCancelled('Passphrase cancelled')
|
||||||
else:
|
else:
|
||||||
if ack.passphrase is None:
|
if ack.passphrase is None:
|
||||||
raise wire.FailureError(ProcessError, 'Passphrase not provided')
|
raise wire.ProcessError('Passphrase not provided')
|
||||||
passphrase = ack.passphrase
|
passphrase = ack.passphrase
|
||||||
|
|
||||||
req = PassphraseStateRequest(state=get_state(state=ack.state, passphrase=passphrase))
|
req = PassphraseStateRequest(state=get_state(state=ack.state, passphrase=passphrase))
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from trezor import wire
|
from trezor import wire
|
||||||
from trezor.crypto import bip32, bip39
|
from trezor.crypto import bip32, bip39
|
||||||
from trezor.messages.FailureType import ProcessError
|
|
||||||
from apps.common import cache, storage
|
from apps.common import cache, storage
|
||||||
from apps.common.request_passphrase import protect_by_passphrase
|
from apps.common.request_passphrase import protect_by_passphrase
|
||||||
|
|
||||||
@ -24,7 +23,7 @@ async def _get_seed(ctx: wire.Context) -> bytes:
|
|||||||
|
|
||||||
async def _compute_seed(ctx: wire.Context) -> (bytes, str):
|
async def _compute_seed(ctx: wire.Context) -> (bytes, str):
|
||||||
if not storage.is_initialized():
|
if not storage.is_initialized():
|
||||||
raise wire.FailureError(ProcessError, 'Device is not initialized')
|
raise wire.ProcessError('Device is not initialized')
|
||||||
|
|
||||||
passphrase = await protect_by_passphrase(ctx)
|
passphrase = await protect_by_passphrase(ctx)
|
||||||
return bip39.seed(storage.get_mnemonic(), passphrase), passphrase
|
return bip39.seed(storage.get_mnemonic(), passphrase), passphrase
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from trezor import ui, wire
|
from trezor import ui, wire
|
||||||
from trezor.messages import ButtonRequestType, FailureType, PassphraseSourceType
|
from trezor.messages import ButtonRequestType, PassphraseSourceType
|
||||||
from trezor.messages.Success import Success
|
from trezor.messages.Success import Success
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
from apps.common import storage
|
from apps.common import storage
|
||||||
@ -8,11 +8,11 @@ from apps.common.confirm import require_confirm
|
|||||||
|
|
||||||
async def apply_settings(ctx, msg):
|
async def apply_settings(ctx, msg):
|
||||||
if msg.homescreen is None and msg.label is None and msg.use_passphrase is None and msg.passphrase_source is None:
|
if msg.homescreen is None and msg.label is None and msg.use_passphrase is None and msg.passphrase_source is None:
|
||||||
raise wire.FailureError(FailureType.ProcessError, 'No setting provided')
|
raise wire.ProcessError('No setting provided')
|
||||||
|
|
||||||
if msg.homescreen is not None:
|
if msg.homescreen is not None:
|
||||||
if len(msg.homescreen) > storage.HOMESCREEN_MAXSIZE:
|
if len(msg.homescreen) > storage.HOMESCREEN_MAXSIZE:
|
||||||
raise wire.FailureError(FailureType.DataError, 'Homescreen is too complex')
|
raise wire.DataError('Homescreen is too complex')
|
||||||
await require_confirm(ctx, Text(
|
await require_confirm(ctx, Text(
|
||||||
'Change homescreen', ui.ICON_CONFIG,
|
'Change homescreen', ui.ICON_CONFIG,
|
||||||
'Do you really want to', 'change homescreen?'),
|
'Do you really want to', 'change homescreen?'),
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
from trezor import wire
|
from trezor import wire
|
||||||
from trezor.messages.FailureType import ProcessError
|
|
||||||
from trezor.messages.Success import Success
|
from trezor.messages.Success import Success
|
||||||
from apps.common import storage
|
from apps.common import storage
|
||||||
from apps.management.reset_device import (check_mnemonic, show_mnemonic,
|
from apps.management.reset_device import (
|
||||||
show_warning, show_wrong_entry)
|
check_mnemonic,
|
||||||
|
show_mnemonic,
|
||||||
|
show_warning,
|
||||||
|
show_wrong_entry,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def backup_device(ctx, msg):
|
async def backup_device(ctx, msg):
|
||||||
if not storage.is_initialized():
|
if not storage.is_initialized():
|
||||||
raise wire.FailureError(ProcessError, 'Device is not initialized')
|
raise wire.ProcessError('Device is not initialized')
|
||||||
if not storage.needs_backup():
|
if not storage.needs_backup():
|
||||||
raise wire.FailureError(ProcessError, 'Seed already backed up')
|
raise wire.ProcessError('Seed already backed up')
|
||||||
|
|
||||||
mnemonic = storage.get_mnemonic()
|
mnemonic = storage.get_mnemonic()
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
from trezor import config, loop, ui, wire
|
from trezor import config, loop, ui, wire
|
||||||
from trezor.messages import FailureType, wire_types
|
from trezor.messages import wire_types
|
||||||
from trezor.messages.ButtonRequest import ButtonRequest
|
from trezor.messages.ButtonRequest import ButtonRequest
|
||||||
from trezor.messages.ButtonRequestType import Other
|
from trezor.messages.ButtonRequestType import Other
|
||||||
from trezor.messages.Failure import Failure
|
|
||||||
from trezor.messages.Success import Success
|
from trezor.messages.Success import Success
|
||||||
from trezor.pin import pin_to_int, show_pin_timeout
|
from trezor.pin import pin_to_int, show_pin_timeout
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
@ -19,7 +18,7 @@ async def change_pin(ctx, msg):
|
|||||||
if config.has_pin():
|
if config.has_pin():
|
||||||
curpin = await request_pin_ack(ctx)
|
curpin = await request_pin_ack(ctx)
|
||||||
if not config.check_pin(pin_to_int(curpin), show_pin_timeout):
|
if not config.check_pin(pin_to_int(curpin), show_pin_timeout):
|
||||||
return Failure(code=FailureType.PinInvalid, message='PIN invalid')
|
raise wire.PinInvalid('PIN invalid')
|
||||||
else:
|
else:
|
||||||
curpin = ''
|
curpin = ''
|
||||||
|
|
||||||
@ -30,13 +29,13 @@ async def change_pin(ctx, msg):
|
|||||||
newpin = ''
|
newpin = ''
|
||||||
|
|
||||||
# write into storage
|
# write into storage
|
||||||
if config.change_pin(pin_to_int(curpin), pin_to_int(newpin), show_pin_timeout):
|
if not config.change_pin(pin_to_int(curpin), pin_to_int(newpin), show_pin_timeout):
|
||||||
if newpin:
|
raise wire.PinInvalid('PIN invalid')
|
||||||
return Success(message='PIN changed')
|
|
||||||
else:
|
if newpin:
|
||||||
return Success(message='PIN removed')
|
return Success(message='PIN changed')
|
||||||
else:
|
else:
|
||||||
return Failure(code=FailureType.PinInvalid, message='PIN invalid')
|
return Success(message='PIN removed')
|
||||||
|
|
||||||
|
|
||||||
def require_confirm_change_pin(ctx, msg):
|
def require_confirm_change_pin(ctx, msg):
|
||||||
@ -75,7 +74,7 @@ async def request_pin_ack(ctx, *args, **kwargs):
|
|||||||
await ctx.call(ButtonRequest(code=Other), wire_types.ButtonAck)
|
await ctx.call(ButtonRequest(code=Other), wire_types.ButtonAck)
|
||||||
return await ctx.wait(request_pin(*args, **kwargs))
|
return await ctx.wait(request_pin(*args, **kwargs))
|
||||||
except PinCancelled:
|
except PinCancelled:
|
||||||
raise wire.FailureError(FailureType.ActionCancelled, 'Cancelled')
|
raise wire.ActionCancelled('Cancelled')
|
||||||
|
|
||||||
|
|
||||||
@ui.layout
|
@ui.layout
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from trezor import config, ui, wire
|
from trezor import config, ui, wire
|
||||||
from trezor.crypto import bip39
|
from trezor.crypto import bip39
|
||||||
from trezor.messages.FailureType import ProcessError, UnexpectedMessage
|
|
||||||
from trezor.messages.Success import Success
|
from trezor.messages.Success import Success
|
||||||
from trezor.pin import pin_to_int
|
from trezor.pin import pin_to_int
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
@ -11,13 +10,13 @@ from apps.common.confirm import require_confirm
|
|||||||
async def load_device(ctx, msg):
|
async def load_device(ctx, msg):
|
||||||
|
|
||||||
if storage.is_initialized():
|
if storage.is_initialized():
|
||||||
raise wire.FailureError(UnexpectedMessage, 'Already initialized')
|
raise wire.UnexpectedMessage('Already initialized')
|
||||||
|
|
||||||
if msg.node is not None:
|
if msg.node is not None:
|
||||||
raise wire.FailureError(ProcessError, 'LoadDevice.node is not supported')
|
raise wire.ProcessError('LoadDevice.node is not supported')
|
||||||
|
|
||||||
if not msg.skip_checksum and not bip39.check(msg.mnemonic):
|
if not msg.skip_checksum and not bip39.check(msg.mnemonic):
|
||||||
raise wire.FailureError(ProcessError, 'Mnemonic is not valid')
|
raise wire.ProcessError('Mnemonic is not valid')
|
||||||
|
|
||||||
await require_confirm(ctx, Text(
|
await require_confirm(ctx, Text(
|
||||||
'Loading seed', ui.ICON_DEFAULT,
|
'Loading seed', ui.ICON_DEFAULT,
|
||||||
|
@ -25,7 +25,7 @@ async def recovery_device(ctx, msg):
|
|||||||
5. Save into storage.
|
5. Save into storage.
|
||||||
'''
|
'''
|
||||||
if not msg.dry_run and storage.is_initialized():
|
if not msg.dry_run and storage.is_initialized():
|
||||||
raise wire.FailureError(UnexpectedMessage, 'Already initialized')
|
raise wire.UnexpectedMessage('Already initialized')
|
||||||
|
|
||||||
# ask for the number of words
|
# ask for the number of words
|
||||||
wordcount = await request_wordcount(ctx)
|
wordcount = await request_wordcount(ctx)
|
||||||
@ -36,7 +36,7 @@ async def recovery_device(ctx, msg):
|
|||||||
# check mnemonic validity
|
# check mnemonic validity
|
||||||
if msg.enforce_wordlist or msg.dry_run:
|
if msg.enforce_wordlist or msg.dry_run:
|
||||||
if not bip39.check(mnemonic):
|
if not bip39.check(mnemonic):
|
||||||
raise wire.FailureError(ProcessError, 'Mnemonic is not valid')
|
raise wire.ProcessError('Mnemonic is not valid')
|
||||||
|
|
||||||
# ask for pin repeatedly
|
# ask for pin repeatedly
|
||||||
if msg.pin_protection:
|
if msg.pin_protection:
|
||||||
@ -55,7 +55,7 @@ async def recovery_device(ctx, msg):
|
|||||||
if storage.get_mnemonic() == mnemonic:
|
if storage.get_mnemonic() == mnemonic:
|
||||||
return Success(message='The seed is valid and matches the one in the device')
|
return Success(message='The seed is valid and matches the one in the device')
|
||||||
else:
|
else:
|
||||||
raise wire.FailureError(ProcessError, 'The seed is valid but does not match the one in the device')
|
raise wire.ProcessError('The seed is valid but does not match the one in the device')
|
||||||
|
|
||||||
|
|
||||||
@ui.layout
|
@ui.layout
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from micropython import const
|
from micropython import const
|
||||||
from trezor import config, ui, wire
|
from trezor import config, ui, wire
|
||||||
from trezor.crypto import bip39, hashlib, random
|
from trezor.crypto import bip39, hashlib, random
|
||||||
from trezor.messages import ButtonRequestType, FailureType, wire_types
|
from trezor.messages import ButtonRequestType, wire_types
|
||||||
from trezor.messages.ButtonRequest import ButtonRequest
|
from trezor.messages.ButtonRequest import ButtonRequest
|
||||||
from trezor.messages.EntropyRequest import EntropyRequest
|
from trezor.messages.EntropyRequest import EntropyRequest
|
||||||
from trezor.messages.Success import Success
|
from trezor.messages.Success import Success
|
||||||
@ -24,13 +24,9 @@ if __debug__:
|
|||||||
async def reset_device(ctx, msg):
|
async def reset_device(ctx, msg):
|
||||||
# validate parameters and device state
|
# validate parameters and device state
|
||||||
if msg.strength not in (128, 192, 256):
|
if msg.strength not in (128, 192, 256):
|
||||||
raise wire.FailureError(
|
raise wire.ProcessError('Invalid strength (has to be 128, 192 or 256 bits)')
|
||||||
FailureType.ProcessError,
|
|
||||||
'Invalid strength (has to be 128, 192 or 256 bits)')
|
|
||||||
if storage.is_initialized():
|
if storage.is_initialized():
|
||||||
raise wire.FailureError(
|
raise wire.UnexpectedMessage('Already initialized')
|
||||||
FailureType.UnexpectedMessage,
|
|
||||||
'Already initialized')
|
|
||||||
|
|
||||||
# request new PIN
|
# request new PIN
|
||||||
if msg.pin_protection:
|
if msg.pin_protection:
|
||||||
@ -62,8 +58,7 @@ async def reset_device(ctx, msg):
|
|||||||
|
|
||||||
# write PIN into storage
|
# write PIN into storage
|
||||||
if not config.change_pin(pin_to_int(''), pin_to_int(newpin), None):
|
if not config.change_pin(pin_to_int(''), pin_to_int(newpin), None):
|
||||||
raise wire.FailureError(
|
raise wire.ProcessError('Could not change PIN')
|
||||||
FailureType.ProcessError, 'Could not change PIN')
|
|
||||||
|
|
||||||
# write settings and mnemonic into storage
|
# write settings and mnemonic into storage
|
||||||
storage.load_settings(
|
storage.load_settings(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from trezor import ui, wire
|
from trezor import ui, wire
|
||||||
from trezor.messages import ButtonRequestType, FailureType
|
from trezor.messages import ButtonRequestType
|
||||||
from trezor.messages.Success import Success
|
from trezor.messages.Success import Success
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
from apps.common import storage
|
from apps.common import storage
|
||||||
@ -8,7 +8,7 @@ from apps.common.confirm import require_confirm
|
|||||||
|
|
||||||
async def set_u2f_counter(ctx, msg):
|
async def set_u2f_counter(ctx, msg):
|
||||||
if msg.u2f_counter is None:
|
if msg.u2f_counter is None:
|
||||||
raise wire.FailureError(FailureType.ProcessError, 'No value provided provided')
|
raise wire.ProcessError('No value provided')
|
||||||
|
|
||||||
await require_confirm(ctx, Text(
|
await require_confirm(ctx, Text(
|
||||||
'Set U2F counter', ui.ICON_CONFIG,
|
'Set U2F counter', ui.ICON_CONFIG,
|
||||||
|
@ -3,7 +3,6 @@ from trezor.crypto import hmac
|
|||||||
from trezor.crypto.aes import AES_CBC_Decrypt, AES_CBC_Encrypt
|
from trezor.crypto.aes import AES_CBC_Decrypt, AES_CBC_Encrypt
|
||||||
from trezor.crypto.hashlib import sha512
|
from trezor.crypto.hashlib import sha512
|
||||||
from trezor.messages.CipheredKeyValue import CipheredKeyValue
|
from trezor.messages.CipheredKeyValue import CipheredKeyValue
|
||||||
from trezor.messages.FailureType import DataError
|
|
||||||
from trezor.ui.text import Text, TEXT_MARGIN_LEFT
|
from trezor.ui.text import Text, TEXT_MARGIN_LEFT
|
||||||
from trezor.utils import split_words
|
from trezor.utils import split_words
|
||||||
from apps.common import seed
|
from apps.common import seed
|
||||||
@ -12,8 +11,7 @@ from apps.common.confirm import require_confirm
|
|||||||
|
|
||||||
async def cipher_key_value(ctx, msg):
|
async def cipher_key_value(ctx, msg):
|
||||||
if len(msg.value) % 16 > 0:
|
if len(msg.value) % 16 > 0:
|
||||||
raise wire.FailureError(
|
raise wire.DataError('Value length must be a multiple of 16')
|
||||||
DataError, 'Value length must be a multiple of 16')
|
|
||||||
|
|
||||||
encrypt = msg.encrypt
|
encrypt = msg.encrypt
|
||||||
decrypt = not msg.encrypt
|
decrypt = not msg.encrypt
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
from trezor import ui
|
from trezor import ui, wire
|
||||||
from trezor.wire import FailureError
|
|
||||||
from trezor.crypto.curve import secp256k1
|
from trezor.crypto.curve import secp256k1
|
||||||
from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS
|
from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS
|
||||||
from trezor.messages.FailureType import ProcessError
|
from trezor.messages.FailureType import ProcessError
|
||||||
@ -34,7 +33,7 @@ async def sign_message(ctx, msg):
|
|||||||
elif script_type == SPENDWITNESS:
|
elif script_type == SPENDWITNESS:
|
||||||
signature = bytes([signature[0] + 8]) + signature[1:]
|
signature = bytes([signature[0] + 8]) + signature[1:]
|
||||||
else:
|
else:
|
||||||
raise FailureError(ProcessError, 'Unsupported script type')
|
raise wire.ProcessError('Unsupported script type')
|
||||||
|
|
||||||
return MessageSignature(address=address, signature=signature)
|
return MessageSignature(address=address, signature=signature)
|
||||||
|
|
||||||
|
@ -17,15 +17,15 @@ async def sign_tx(ctx, msg):
|
|||||||
try:
|
try:
|
||||||
req = signer.send(res)
|
req = signer.send(res)
|
||||||
except signing.SigningError as e:
|
except signing.SigningError as e:
|
||||||
raise wire.FailureError(*e.args)
|
raise wire.Error(*e.args)
|
||||||
except signing.MultisigError as e:
|
except signing.MultisigError as e:
|
||||||
raise wire.FailureError(*e.args)
|
raise wire.Error(*e.args)
|
||||||
except signing.AddressError as e:
|
except signing.AddressError as e:
|
||||||
raise wire.FailureError(*e.args)
|
raise wire.Error(*e.args)
|
||||||
except signing.ScriptsError as e:
|
except signing.ScriptsError as e:
|
||||||
raise wire.FailureError(*e.args)
|
raise wire.Error(*e.args)
|
||||||
except signing.Bip143Error as e:
|
except signing.Bip143Error as e:
|
||||||
raise wire.FailureError(*e.args)
|
raise wire.Error(*e.args)
|
||||||
if req.__qualname__ == 'TxRequest':
|
if req.__qualname__ == 'TxRequest':
|
||||||
if req.request_type == TXFINISHED:
|
if req.request_type == TXFINISHED:
|
||||||
break
|
break
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from trezor import ui, wire
|
from trezor import ui, wire
|
||||||
from trezor.crypto.curve import secp256k1
|
from trezor.crypto.curve import secp256k1
|
||||||
from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS
|
from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS
|
||||||
from trezor.messages.FailureType import ProcessError
|
|
||||||
from trezor.messages.Success import Success
|
from trezor.messages.Success import Success
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
from apps.common import coins
|
from apps.common import coins
|
||||||
@ -31,12 +30,12 @@ async def verify_message(ctx, msg):
|
|||||||
script_type = SPENDWITNESS # native segwit
|
script_type = SPENDWITNESS # native segwit
|
||||||
signature = bytes([signature[0] - 8]) + signature[1:]
|
signature = bytes([signature[0] - 8]) + signature[1:]
|
||||||
else:
|
else:
|
||||||
raise wire.FailureError(ProcessError, 'Invalid signature')
|
raise wire.ProcessError('Invalid signature')
|
||||||
|
|
||||||
pubkey = secp256k1.verify_recover(signature, digest)
|
pubkey = secp256k1.verify_recover(signature, digest)
|
||||||
|
|
||||||
if not pubkey:
|
if not pubkey:
|
||||||
raise wire.FailureError(ProcessError, 'Invalid signature')
|
raise wire.ProcessError('Invalid signature')
|
||||||
|
|
||||||
if script_type == SPENDADDRESS:
|
if script_type == SPENDADDRESS:
|
||||||
addr = address_pkh(pubkey, coin.address_type)
|
addr = address_pkh(pubkey, coin.address_type)
|
||||||
@ -45,10 +44,10 @@ async def verify_message(ctx, msg):
|
|||||||
elif script_type == SPENDWITNESS:
|
elif script_type == SPENDWITNESS:
|
||||||
addr = address_p2wpkh(pubkey, coin.bech32_prefix)
|
addr = address_p2wpkh(pubkey, coin.bech32_prefix)
|
||||||
else:
|
else:
|
||||||
raise wire.FailureError(ProcessError, 'Invalid signature')
|
raise wire.ProcessError('Invalid signature')
|
||||||
|
|
||||||
if addr != address:
|
if addr != address:
|
||||||
raise wire.FailureError(ProcessError, 'Invalid signature')
|
raise wire.ProcessError('Invalid signature')
|
||||||
|
|
||||||
await require_confirm_verify_message(ctx, address, message)
|
await require_confirm_verify_message(ctx, address, message)
|
||||||
|
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
import protobuf
|
import protobuf
|
||||||
|
from trezor import log, loop, messages, utils, workflow
|
||||||
from trezor import log
|
from trezor.wire import codec_v1
|
||||||
from trezor import loop
|
from trezor.wire.errors import *
|
||||||
from trezor import messages
|
|
||||||
from trezor import utils
|
|
||||||
from trezor import workflow
|
|
||||||
|
|
||||||
from . import codec_v1
|
|
||||||
|
|
||||||
workflow_handlers = {}
|
workflow_handlers = {}
|
||||||
|
|
||||||
@ -101,13 +96,6 @@ class UnexpectedMessageError(Exception):
|
|||||||
self.reader = reader
|
self.reader = reader
|
||||||
|
|
||||||
|
|
||||||
class FailureError(Exception):
|
|
||||||
def __init__(self, code, message):
|
|
||||||
super().__init__()
|
|
||||||
self.code = code
|
|
||||||
self.message = message
|
|
||||||
|
|
||||||
|
|
||||||
async def session_handler(iface, sid):
|
async def session_handler(iface, sid):
|
||||||
reader = None
|
reader = None
|
||||||
ctx = Context(iface, sid)
|
ctx = Context(iface, sid)
|
||||||
@ -135,8 +123,8 @@ async def session_handler(iface, sid):
|
|||||||
# retry with opened reader from the exception
|
# retry with opened reader from the exception
|
||||||
reader = exc.reader
|
reader = exc.reader
|
||||||
continue
|
continue
|
||||||
except FailureError as exc:
|
except Error as exc:
|
||||||
# we log FailureError as warning, not as exception
|
# we log wire.Error as warning, not as exception
|
||||||
log.warning(__name__, 'failure: %s', exc.message)
|
log.warning(__name__, 'failure: %s', exc.message)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
# sessions are never closed by raised exceptions
|
# sessions are never closed by raised exceptions
|
||||||
@ -148,7 +136,6 @@ async def session_handler(iface, sid):
|
|||||||
|
|
||||||
async def protobuf_workflow(ctx, reader, handler, *args):
|
async def protobuf_workflow(ctx, reader, handler, *args):
|
||||||
from trezor.messages.Failure import Failure
|
from trezor.messages.Failure import Failure
|
||||||
from trezor.messages.FailureType import FirmwareError
|
|
||||||
|
|
||||||
req = await protobuf.load_message(reader, messages.get_type(reader.type))
|
req = await protobuf.load_message(reader, messages.get_type(reader.type))
|
||||||
try:
|
try:
|
||||||
@ -156,13 +143,13 @@ async def protobuf_workflow(ctx, reader, handler, *args):
|
|||||||
except UnexpectedMessageError:
|
except UnexpectedMessageError:
|
||||||
# session handler takes care of this one
|
# session handler takes care of this one
|
||||||
raise
|
raise
|
||||||
except FailureError as exc:
|
except Error as exc:
|
||||||
# respond with specific code and message
|
# respond with specific code and message
|
||||||
await ctx.write(Failure(code=exc.code, message=exc.message))
|
await ctx.write(Failure(code=exc.code, message=exc.message))
|
||||||
raise
|
raise
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
# respond with a generic code and message
|
# respond with a generic code and message
|
||||||
await ctx.write(Failure(code=FirmwareError, message='Firmware error'))
|
await ctx.write(Failure(code=FailureType.FirmwareError, message='Firmware error'))
|
||||||
raise
|
raise
|
||||||
if res:
|
if res:
|
||||||
# respond with a specific response
|
# respond with a specific response
|
||||||
@ -171,7 +158,6 @@ async def protobuf_workflow(ctx, reader, handler, *args):
|
|||||||
|
|
||||||
async def unexpected_msg(ctx, reader):
|
async def unexpected_msg(ctx, reader):
|
||||||
from trezor.messages.Failure import Failure
|
from trezor.messages.Failure import Failure
|
||||||
from trezor.messages.FailureType import UnexpectedMessage
|
|
||||||
|
|
||||||
# receive the message and throw it away
|
# receive the message and throw it away
|
||||||
while reader.size > 0:
|
while reader.size > 0:
|
||||||
@ -179,5 +165,4 @@ async def unexpected_msg(ctx, reader):
|
|||||||
await reader.areadinto(buf)
|
await reader.areadinto(buf)
|
||||||
|
|
||||||
# respond with an unknown message error
|
# respond with an unknown message error
|
||||||
await ctx.write(
|
await ctx.write(Failure(code=FailureType.UnexpectedMessage, message='Unexpected message'))
|
||||||
Failure(code=UnexpectedMessage, message='Unexpected message'))
|
|
||||||
|
73
src/trezor/wire/errors.py
Normal file
73
src/trezor/wire/errors.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
from trezor.messages import FailureType
|
||||||
|
|
||||||
|
|
||||||
|
class Error(Exception):
|
||||||
|
def __init__(self, code, message):
|
||||||
|
super().__init__()
|
||||||
|
self.code = code
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
|
||||||
|
class UnexpectedMessage(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.UnexpectedMessage, message)
|
||||||
|
|
||||||
|
|
||||||
|
class ButtonExpected(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.ButtonExpected, message)
|
||||||
|
|
||||||
|
|
||||||
|
class DataError(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.DataError, message)
|
||||||
|
|
||||||
|
|
||||||
|
class ActionCancelled(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.ActionCancelled, message)
|
||||||
|
|
||||||
|
|
||||||
|
class PinExpected(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.PinExpected, message)
|
||||||
|
|
||||||
|
|
||||||
|
class PinCancelled(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.PinCancelled, message)
|
||||||
|
|
||||||
|
|
||||||
|
class PinInvalid(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.PinInvalid, message)
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidSignature(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.InvalidSignature, message)
|
||||||
|
|
||||||
|
|
||||||
|
class ProcessError(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.ProcessError, message)
|
||||||
|
|
||||||
|
|
||||||
|
class NotEnoughFunds(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.NotEnoughFunds, message)
|
||||||
|
|
||||||
|
|
||||||
|
class NotInitialized(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.NotInitialized, message)
|
||||||
|
|
||||||
|
|
||||||
|
class PinMismatch(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.PinMismatch, message)
|
||||||
|
|
||||||
|
|
||||||
|
class FirmwareError(Error):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(FailureType.FirmwareError, message)
|
Loading…
Reference in New Issue
Block a user