コード例 #1
0
async def reset_device(ctx, msg):
    if __debug__:
        global internal_entropy

    # validate parameters and device state
    if msg.strength not in (128, 192, 256):
        raise wire.FailureError(
            FailureType.ProcessError,
            'Invalid strength (has to be 128, 192 or 256 bits)')
    if storage.is_initialized():
        raise wire.FailureError(
            FailureType.UnexpectedMessage,
            'Already initialized')

    if msg.pin_protection:
        # request new PIN
        newpin = await request_pin_confirm(ctx)
    else:
        # new PIN is empty
        newpin = ''

    # generate and display internal entropy
    internal_entropy = random.bytes(32)
    if msg.display_random:
        await show_entropy(ctx, internal_entropy)

    # request external entropy and compute mnemonic
    ack = await ctx.call(EntropyRequest(), wire_types.EntropyAck)
    mnemonic = generate_mnemonic(
        msg.strength, internal_entropy, ack.entropy)

    if msg.skip_backup:
        # let user backup the mnemonic later
        pass
    else:
        # warn user about mnemonic safety
        await show_warning(ctx)
        while True:
            # show mnemonic and require confirmation of a random word
            await show_mnemonic(ctx, mnemonic)
            if await check_mnemonic(ctx, mnemonic):
                break
            await show_wrong_entry(ctx)

    # write PIN into storage
    if not config.change_pin(pin_to_int(''), pin_to_int(newpin), None):
        raise wire.FailureError(
            FailureType.ProcessError, 'Could not change PIN')

    # write settings and mnemonic into storage
    storage.load_settings(
        label=msg.label, use_passphrase=msg.passphrase_protection)
    storage.load_mnemonic(
        mnemonic=mnemonic, needs_backup=msg.skip_backup)

    # show success message
    if not msg.skip_backup:
        await show_success(ctx)

    return Success(message='Initialized')
コード例 #2
0
ファイル: __init__.py プロジェクト: vodelerk/trezor-core
async def sign_tx(ctx, msg):
    from trezor.messages.RequestType import TXFINISHED
    from trezor.messages.wire_types import TxAck

    from apps.common import seed
    from . import signing
    from . import layout

    # TODO: rework this so we don't have to pass root to signing.sign_tx
    root = await seed.derive_node(ctx, [])

    signer = signing.sign_tx(msg, root)
    res = None
    while True:
        try:
            req = signer.send(res)
        except signing.SigningError as e:
            raise wire.FailureError(*e.args)
        except signing.AddressError as e:
            raise wire.FailureError(*e.args)
        if req.__qualname__ == 'TxRequest':
            if req.request_type == TXFINISHED:
                break
            res = await ctx.call(req, TxAck)
        elif req.__qualname__ == 'UiConfirmOutput':
            res = await layout.confirm_output(ctx, req.output, req.coin)
        elif req.__qualname__ == 'UiConfirmTotal':
            res = await layout.confirm_total(ctx, req.spending, req.fee,
                                             req.coin)
        elif req.__qualname__ == 'UiConfirmFeeOverThreshold':
            res = await layout.confirm_feeoverthreshold(ctx, req.fee, req.coin)
        else:
            raise TypeError('Invalid signing instruction')
    return req
コード例 #3
0
async def load_device(ctx, msg):

    if storage.is_initialized():
        raise wire.FailureError(UnexpectedMessage, 'Already initialized')

    if msg.node is not None:
        raise wire.FailureError(ProcessError,
                                'LoadDevice.node is not supported')

    if not msg.skip_checksum and not bip39.check(msg.mnemonic):
        raise wire.FailureError(ProcessError, 'Mnemonic is not valid')

    await require_confirm(
        ctx,
        Text('Loading seed', ui.ICON_DEFAULT, ui.BOLD, 'Loading private seed',
             'is not recommended.', ui.NORMAL, 'Continue only if you',
             'know what you are doing!'))

    storage.load_mnemonic(mnemonic=msg.mnemonic, needs_backup=True)
    storage.load_settings(use_passphrase=msg.passphrase_protection,
                          label=msg.label)
    if msg.pin:
        config.change_pin(pin_to_int(''), pin_to_int(msg.pin), None)

    return Success(message='Device loaded')
コード例 #4
0
ファイル: load_device.py プロジェクト: nining/trezor-core
async def layout_load_device(session_id, msg):
    from trezor.crypto import bip39
    from trezor.messages.Success import Success
    from trezor.messages.FailureType import UnexpectedMessage, Other
    from trezor.ui.text import Text
    from ..common.confirm import require_confirm
    from ..common import storage

    if storage.is_initialized():
        raise wire.FailureError(UnexpectedMessage, 'Already initialized')

    if msg.node is not None:
        raise wire.FailureError(Other, 'LoadDevice.node is not supported')

    if not msg.skip_checksum and not bip39.check(msg.mnemonic):
        raise wire.FailureError(Other, 'Mnemonic is not valid')

    await require_confirm(
        session_id,
        Text('Loading seed', ui.ICON_RESET, ui.BOLD, 'Loading private seed',
             'is not recommended.', ui.NORMAL, 'Continue only if you',
             'know what you are doing!'))

    storage.load_mnemonic(msg.mnemonic)
    storage.load_settings(pin=msg.pin,
                          passphrase_protection=msg.passphrase_protection,
                          language=msg.language,
                          label=msg.label)

    return Success(message='Device loaded')
コード例 #5
0
async def request_passphrase_ack(ctx, on_device):
    if not on_device:
        text = Text(
            'Passphrase entry', ui.ICON_CONFIG,
            'Please, type passphrase', 'on connected host.')
        text.render()

    req = PassphraseRequest(on_device=on_device)
    ack = await ctx.call(req, wire_types.PassphraseAck, wire_types.Cancel)
    if ack.MESSAGE_WIRE_TYPE == wire_types.Cancel:
        raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')

    if on_device:
        if ack.passphrase is not None:
            raise wire.FailureError(ProcessError, 'Passphrase provided when it should not be')
        keyboard = PassphraseKeyboard('Enter passphrase')
        passphrase = await ctx.wait(keyboard)
        if passphrase == CANCELLED:
            raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')
    else:
        if ack.passphrase is None:
            raise wire.FailureError(ProcessError, 'Passphrase not provided')
        passphrase = ack.passphrase

    req = PassphraseStateRequest(state=get_state(state=ack.state, passphrase=passphrase))
    ack = await ctx.call(req, wire_types.PassphraseStateAck, wire_types.Cancel)

    return passphrase
コード例 #6
0
async def reset_device(ctx, msg):
    # validate parameters and device state
    if msg.strength not in (128, 192, 256):
        raise wire.FailureError(
            FailureType.ProcessError,
            'Invalid strength (has to be 128, 192 or 256 bits)')
    if storage.is_initialized():
        raise wire.FailureError(FailureType.UnexpectedMessage,
                                'Already initialized')

    # request new PIN
    if msg.pin_protection:
        newpin = await request_pin_confirm(ctx)
    else:
        newpin = ''

    # generate and display internal entropy
    internal_ent = random.bytes(32)
    if __debug__:
        debug.reset_internal_entropy = internal_ent
    if msg.display_random:
        await show_entropy(ctx, internal_ent)

    # request external entropy and compute mnemonic
    ent_ack = await ctx.call(EntropyRequest(), wire_types.EntropyAck)
    mnemonic = generate_mnemonic(msg.strength, internal_ent, ent_ack.entropy)

    if not msg.skip_backup:
        # require confirmation of the mnemonic safety
        await show_warning(ctx)

        # show mnemonic and require confirmation of a random word
        while True:
            await show_mnemonic(ctx, mnemonic)
            if await check_mnemonic(ctx, mnemonic):
                break
            await show_wrong_entry(ctx)

    # write PIN into storage
    if not config.change_pin(pin_to_int(''), pin_to_int(newpin), None):
        raise wire.FailureError(FailureType.ProcessError,
                                'Could not change PIN')

    # write settings and mnemonic into storage
    storage.load_settings(label=msg.label,
                          use_passphrase=msg.passphrase_protection)
    storage.load_mnemonic(mnemonic=mnemonic, needs_backup=msg.skip_backup)

    # show success message.  if we skipped backup, it's possible that homescreen
    # is still running, uninterrupted.  restart it to pick up new label.
    if not msg.skip_backup:
        await show_success(ctx)
    else:
        workflow.restartdefault()

    return Success(message='Initialized')
コード例 #7
0
async def layout_reset_device(session_id, msg):
    from trezor.ui.text import Text
    from trezor.crypto import hashlib, random, bip39
    from trezor.messages.EntropyRequest import EntropyRequest
    from trezor.messages.Success import Success
    from trezor.messages import FailureType
    from trezor.messages import ButtonRequestType
    from trezor.messages.wire_types import EntropyAck

    from apps.common.request_pin import request_pin_twice
    from apps.common.confirm import require_confirm
    from apps.common import storage

    if __debug__:
        global internal_entropy

    if msg.strength not in (128, 192, 256):
        raise wire.FailureError(
            FailureType.Other,
            'Invalid strength (has to be 128, 192 or 256 bits)')

    if storage.is_initialized():
        raise wire.FailureError(FailureType.UnexpectedMessage,
                                'Already initialized')

    internal_entropy = random.bytes(32)

    if msg.display_random:
        entropy_lines = chunks(ubinascii.hexlify(internal_entropy), 16)
        entropy_content = Text('Internal entropy', ui.ICON_RESET,
                               *entropy_lines)
        await require_confirm(session_id, entropy_content,
                              ButtonRequestType.ResetDevice)

    if msg.pin_protection:
        pin = await request_pin_twice(session_id)
    else:
        pin = None

    external_entropy_ack = await wire.call(session_id, EntropyRequest(),
                                           EntropyAck)
    ctx = hashlib.sha256()
    ctx.update(internal_entropy)
    ctx.update(external_entropy_ack.entropy)
    entropy = ctx.digest()
    mnemonic = bip39.from_data(entropy[:msg.strength // 8])

    await show_mnemonic_by_word(session_id, mnemonic)

    storage.load_mnemonic(mnemonic)
    storage.load_settings(pin=pin,
                          passphrase_protection=msg.passphrase_protection,
                          language=msg.language,
                          label=msg.label)

    return Success(message='Initialized')
コード例 #8
0
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:
        raise wire.FailureError(FailureType.ProcessError,
                                'No setting provided')

    if msg.homescreen is not None:
        if len(msg.homescreen) > storage.HOMESCREEN_MAXSIZE:
            raise wire.FailureError(FailureType.DataError,
                                    'Homescreen is too complex')
        await require_confirm(ctx,
                              Text('Change homescreen', ui.ICON_CONFIG,
                                   'Do you really want to',
                                   'change homescreen?'),
                              code=ButtonRequestType.ProtectCall)

    # TODO: split label (bold) and '?' (normal) once we support mixed styles on one line
    if msg.label is not None:
        await require_confirm(ctx,
                              Text('Change label', ui.ICON_CONFIG,
                                   'Do you really want to', 'change label to',
                                   ui.BOLD, '%s?' % msg.label),
                              code=ButtonRequestType.ProtectCall)

    if msg.use_passphrase is not None:
        await require_confirm(ctx,
                              Text(
                                  'Enable passphrase' if msg.use_passphrase
                                  else 'Disable passphrase', ui.ICON_CONFIG,
                                  'Do you really want to',
                                  'enable passphrase' if msg.use_passphrase
                                  else 'disable passphrase', 'encryption?'),
                              code=ButtonRequestType.ProtectCall)

    if msg.passphrase_source is not None:
        if msg.passphrase_source == PassphraseSourceType.DEVICE:
            desc = 'ON DEVICE'
        elif msg.passphrase_source == PassphraseSourceType.HOST:
            desc = 'ON HOST'
        else:
            desc = 'ASK'
        await require_confirm(ctx,
                              Text('Passphrase source', ui.ICON_CONFIG,
                                   'Do you really want to',
                                   'change the passphrase', 'source to',
                                   ui.BOLD, 'ALWAYS %s?' % desc),
                              code=ButtonRequestType.ProtectCall)

    storage.load_settings(label=msg.label,
                          use_passphrase=msg.use_passphrase,
                          homescreen=msg.homescreen,
                          passphrase_source=msg.passphrase_source)

    return Success(message='Settings applied')
コード例 #9
0
async def request_passphrase(ctx):
    from trezor.ui.text import Text
    from trezor.ui.entry_select import EntrySelector

    ui.display.clear()
    text = Text('Enter passphrase', ui.ICON_RESET, 'Where to enter your',
                'passphrase?')
    entry = EntrySelector(text)
    entry_type = await entry

    on_device = (entry_type == 0)

    from trezor.messages.FailureType import ActionCancelled, ProcessError
    from trezor.messages.PassphraseRequest import PassphraseRequest
    from trezor.messages.wire_types import PassphraseAck, Cancel

    ui.display.clear()

    pass_req = PassphraseRequest()

    if on_device:
        pass_req.on_device = True
    else:
        from trezor.ui.text import Text
        text = Text('Passphrase entry', ui.ICON_RESET,
                    'Please, type passphrase', 'on connected host.')
        text.render()

    ack = await ctx.call(pass_req, PassphraseAck, Cancel)
    if ack.MESSAGE_WIRE_TYPE == Cancel:
        raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')

    if on_device:
        if ack.passphrase is not None:
            raise wire.FailureError(
                ProcessError, 'Passphrase provided when it should not be')
        from trezor.ui.passphrase import PassphraseKeyboard, CANCELLED
        passphrase = await PassphraseKeyboard('Enter passphrase')
        if passphrase == CANCELLED:
            raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')
    else:
        if ack.passphrase is None:
            raise wire.FailureError(ProcessError, 'Passphrase not provided')
        passphrase = ack.passphrase

    # TODO: process ack.state and check against the current device state, throw error if different

    return passphrase
コード例 #10
0
async def request_pin_ack(ctx, *args, **kwargs):
    # TODO: send PinMatrixRequest here, with specific code?
    await ctx.call(ButtonRequest(code=Other), wire_types.ButtonAck)
    try:
        return await request_pin(*args, **kwargs)
    except PinCancelled:
        raise wire.FailureError(FailureType.ActionCancelled, 'Cancelled')
コード例 #11
0
ファイル: get_address.py プロジェクト: jakezeal/trezor-core
async def layout_get_address(ctx, msg):
    from trezor.messages.Address import Address
    from trezor.messages.FailureType import ProcessError
    from ..common import coins
    from ..common import seed
    from ..wallet.sign_tx import addresses

    if msg.multisig:
        raise wire.FailureError(ProcessError,
                                'GetAddress.multisig is unsupported')

    address_n = msg.address_n or ()
    coin_name = msg.coin_name or 'Bitcoin'
    coin = coins.by_name(coin_name)

    node = await seed.derive_node(ctx, address_n)
    address = addresses.get_address(msg.script_type, coin, node)

    if msg.show_display:
        while True:
            if await _show_address(ctx, address):
                break
            if await _show_qr(ctx, address):
                break

    return Address(address=address)
コード例 #12
0
async def apply_settings(ctx, msg):
    if msg.homescreen is None and msg.label is None and msg.use_passphrase is None:
        raise wire.FailureError(FailureType.ProcessError,
                                'No setting provided')

    if msg.homescreen is not None:
        await require_confirm(ctx,
                              Text('Change homescreen', ui.ICON_CONFIG,
                                   'Do you really want to',
                                   'change homescreen?'),
                              code=ButtonRequestType.ProtectCall)

    # TODO: split label (bold) and '?' (normal) once we support mixed styles on one line
    if msg.label is not None:
        await require_confirm(ctx,
                              Text('Change label', ui.ICON_CONFIG,
                                   'Do you really want to', 'change label to',
                                   ui.BOLD, '%s?' % msg.label),
                              code=ButtonRequestType.ProtectCall)

    if msg.use_passphrase is not None:
        await require_confirm(ctx,
                              Text(
                                  'Enable passphrase' if msg.use_passphrase
                                  else 'Disable passphrase', ui.ICON_CONFIG,
                                  'Do you really want to',
                                  'enable passphrase' if msg.use_passphrase
                                  else 'disable passphrase', 'encryption?'),
                              code=ButtonRequestType.ProtectCall)

    storage.load_settings(label=msg.label,
                          use_passphrase=msg.use_passphrase,
                          homescreen=msg.homescreen)

    return Success(message='Settings applied')
コード例 #13
0
async def sign_tx(session_id, msg):
    from trezor.messages.RequestType import TXFINISHED
    from trezor.messages.wire_types import TxAck

    from apps.common import seed
    from . import signing
    from . import layout

    root = await seed.get_root(session_id)

    signer = signing.sign_tx(msg, root)
    res = None
    while True:
        try:
            req = signer.send(res)
        except signing.SigningError as e:
            raise wire.FailureError(*e.args)
        if req.__qualname__ == 'TxRequest':
            if req.request_type == TXFINISHED:
                break
            res = await wire.call(session_id, req, TxAck)
        elif req.__qualname__ == 'UiConfirmOutput':
            res = await layout.confirm_output(session_id, req.output, req.coin)
        elif req.__qualname__ == 'UiConfirmTotal':
            res = await layout.confirm_total(session_id, req.spending, req.fee,
                                             req.coin)
        elif req.__qualname__ == 'UiConfirmFeeOverThreshold':
            res = await layout.confirm_feeoverthreshold(
                session_id, req.fee, req.coin)
        else:
            raise TypeError('Invalid signing instruction')
    return req
コード例 #14
0
async def request_pin_on_display(ctx: wire.Context, code: int=None) -> str:
    from trezor.messages.ButtonRequest import ButtonRequest
    from trezor.messages.ButtonRequestType import ProtectCall
    from trezor.messages.FailureType import PinCancelled
    from trezor.messages.wire_types import ButtonAck
    from trezor.ui.confirm import ConfirmDialog, CONFIRMED
    from trezor.ui.pin import PinMatrix

    if __debug__:
        global matrix

    _, label = _get_code_and_label(code)

    await ctx.call(ButtonRequest(code=ProtectCall),
                   ButtonAck)

    ui.display.clear()
    matrix = PinMatrix(label)
    dialog = ConfirmDialog(matrix)
    pin = matrix.pin
    matrix = None

    if await dialog != CONFIRMED:
        raise wire.FailureError(PinCancelled, 'PIN cancelled')
    return pin
コード例 #15
0
async def request_passphrase(ctx):
    on_device = await request_passphrase_entry(ctx) == DEVICE
    state, passphrase = await request_passphrase_ack(ctx, on_device)
    if state is not None:
        if state != get_state(salt=state[:32], passphrase=passphrase):
            raise wire.FailureError(ProcessError, 'Passphrase mismatch')
    return passphrase
コード例 #16
0
ファイル: confirm.py プロジェクト: DINKIN/trezor-core
async def require_confirm(*args, **kwargs):
    from trezor.messages.FailureType import ActionCancelled

    confirmed = await confirm(*args, **kwargs)

    if not confirmed:
        raise wire.FailureError(ActionCancelled, 'Cancelled')
コード例 #17
0
async def request_passphrase_on_display(ctx):
    from trezor.messages.FailureType import ActionCancelled
    from trezor.ui.passphrase import PassphraseKeyboard, CANCELLED

    ui.display.clear()
    passphrase = await PassphraseKeyboard('Enter passphrase')
    if passphrase == CANCELLED:
        raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')
    return passphrase
コード例 #18
0
async def protect_by_pin_or_fail(ctx: wire.Context, at_least_once: bool=False):
    from trezor.messages.FailureType import PinInvalid
    from . import storage

    locked = storage.is_locked() or at_least_once
    if locked:
        pin = await request_pin(ctx)
        if not storage.unlock(pin, _render_pin_failure):
            raise wire.FailureError(PinInvalid, 'PIN invalid')
コード例 #19
0
async def recovery_device(ctx, msg):
    '''
    Recover BIP39 seed into empty device.

    1. Ask for the number of words in recovered seed.
    2. Let user type in the mnemonic words one by one.
    3. Optionally check the seed validity.
    4. Optionally ask for the PIN, with confirmation.
    5. Save into storage.
    '''
    if not msg.dry_run and storage.is_initialized():
        raise wire.FailureError(UnexpectedMessage, 'Already initialized')

    # ask for the number of words
    wordcount = await request_wordcount(ctx)

    # ask for mnemonic words one by one
    mnemonic = await request_mnemonic(ctx, wordcount)

    # check mnemonic validity
    if msg.enforce_wordlist or msg.dry_run:
        if not bip39.check(mnemonic):
            raise wire.FailureError(ProcessError, 'Mnemonic is not valid')

    # ask for pin repeatedly
    if msg.pin_protection:
        newpin = await request_pin_confirm(ctx, cancellable=False)

    # save into storage
    if not msg.dry_run:
        if msg.pin_protection:
            config.change_pin(pin_to_int(''), pin_to_int(newpin), None)
        storage.load_settings(label=msg.label,
                              use_passphrase=msg.passphrase_protection)
        storage.load_mnemonic(mnemonic=mnemonic, needs_backup=False)
        return Success(message='Device recovered')
    else:
        if storage.get_mnemonic() == mnemonic:
            return Success(
                message='The seed is valid and matches the one in the device')
        else:
            raise wire.FailureError(
                ProcessError,
                'The seed is valid but does not match the one in the device')
コード例 #20
0
async def layout_apply_settings(session_id, msg):
    from trezor.messages.Success import Success
    from trezor.messages.FailureType import Other
    from trezor.ui.text import Text
    from ..common.confirm import require_confirm
    from ..common.request_pin import protect_by_pin
    from ..common import storage

    await protect_by_pin(session_id)

    if msg.homescreen is not None:
        raise wire.FailureError(Other,
                                'ApplySettings.homescreen is not supported')

    if msg.label is None and msg.language is None and msg.use_passphrase is None:
        raise wire.FailureError(Other, 'No setting provided')

    if msg.label is not None:
        await require_confirm(
            session_id,
            Text('Change label', ui.ICON_RESET, 'Do you really want to',
                 'change label to', ui.BOLD, '%s' % msg.label, ui.NORMAL, '?'))

    if msg.language is not None:
        await require_confirm(
            session_id,
            Text('Change language', ui.ICON_RESET, 'Do you really want to',
                 'change language to', ui.BOLD, '%s' % msg.language, ui.NORMAL,
                 '?'))

    if msg.use_passphrase is not None:
        await require_confirm(
            session_id,
            Text(
                'Enable passphrase'
                if msg.use_passphrase else 'Disable passphrase', ui.ICON_RESET,
                'Do you really want to', 'enable passphrase' if
                msg.use_passphrase else 'disable passphrase', 'encryption?'))

    storage.load_settings(label=msg.label,
                          language=msg.language,
                          passphrase_protection=msg.use_passphrase)

    return Success(message='Settings applied')
コード例 #21
0
ファイル: seed.py プロジェクト: davidftv/trezor-core
async def compute_seed(ctx: wire.Context) -> bytes:
    from trezor.messages.FailureType import ProcessError
    from .request_passphrase import protect_by_passphrase
    from . import storage

    if not storage.is_initialized():
        raise wire.FailureError(ProcessError, 'Device is not initialized')

    passphrase = await protect_by_passphrase(ctx)
    return bip39.seed(storage.get_mnemonic(), passphrase)
コード例 #22
0
async def verify_message(ctx, msg):
    message = msg.message
    address = msg.address
    signature = msg.signature
    coin_name = msg.coin_name or 'Bitcoin'
    coin = coins.by_name(coin_name)

    digest = message_digest(coin, message)

    script_type = None
    recid = signature[0]
    if recid >= 27 and recid <= 34:
        script_type = SPENDADDRESS  # p2pkh
    elif recid >= 35 and recid <= 38:
        script_type = SPENDP2SHWITNESS  # segwit-in-p2sh
        signature = bytes([signature[0] - 4]) + signature[1:]
    elif recid >= 39 and recid <= 42:
        script_type = SPENDWITNESS  # native segwit
        signature = bytes([signature[0] - 8]) + signature[1:]
    else:
        raise wire.FailureError(ProcessError, 'Invalid signature')

    pubkey = secp256k1.verify_recover(signature, digest)

    if not pubkey:
        raise wire.FailureError(ProcessError, 'Invalid signature')

    if script_type == SPENDADDRESS:
        addr = address_pkh(pubkey, coin.address_type)
    elif script_type == SPENDP2SHWITNESS:
        addr = address_p2wpkh_in_p2sh(pubkey, coin.address_type_p2sh)
    elif script_type == SPENDWITNESS:
        addr = address_p2wpkh(pubkey, coin.bech32_prefix)
    else:
        raise wire.FailureError(ProcessError, 'Invalid signature')

    if addr != address:
        raise wire.FailureError(ProcessError, 'Invalid signature')

    await require_confirm_verify_message(ctx, address, message)

    return Success(message='Message verified')
コード例 #23
0
async def backup_device(ctx, msg):
    if not storage.is_initialized():
        raise wire.FailureError(ProcessError, 'Device is not initialized')
    if not storage.needs_backup():
        raise wire.FailureError(ProcessError, 'Seed already backed up')

    mnemonic = storage.get_mnemonic()

    storage.set_backed_up()

    # warn user about mnemonic safety
    await show_warning(ctx)
    while True:
        # show mnemonic and require confirmation of a random word
        await show_mnemonic(ctx, mnemonic)
        if await check_mnemonic(ctx, mnemonic):
            break
        await show_wrong_entry(ctx)

    return Success(message='Seed successfully backed up')
コード例 #24
0
async def request_pin_twice(ctx: wire.Context) -> str:
    from trezor.messages.FailureType import ActionCancelled
    from trezor.messages import PinMatrixRequestType

    pin_first = await request_pin(ctx, PinMatrixRequestType.NewFirst)
    pin_again = await request_pin(ctx, PinMatrixRequestType.NewSecond)
    if pin_first != pin_again:
        # changed message due to consistency with T1 msgs
        raise wire.FailureError(ActionCancelled, 'PIN change failed')

    return pin_first
コード例 #25
0
async def request_passphrase_entry(ctx):
    text = Text('Enter passphrase', ui.ICON_CONFIG, 'Where to enter your',
                'passphrase?')
    text.render()

    ack = await ctx.call(ButtonRequest(code=ButtonRequestType.PassphraseType),
                         wire_types.ButtonAck, wire_types.Cancel)
    if ack.MESSAGE_WIRE_TYPE == wire_types.Cancel:
        raise wire.FailureError(ActionCancelled, 'Passphrase cancelled')

    selector = EntrySelector(text)
    return await ctx.wait(selector)
コード例 #26
0
async def compute_seed(session_id: int) -> bytes:
    from trezor.messages.FailureType import Other
    from .request_passphrase import protect_by_passphrase
    from .request_pin import protect_by_pin
    from . import storage

    if not storage.is_initialized():
        raise wire.FailureError(Other, 'Device is not initialized')

    await protect_by_pin(session_id)

    passphrase = await protect_by_passphrase(session_id)
    return bip39.seed(storage.get_mnemonic(), passphrase)
コード例 #27
0
ファイル: __init__.py プロジェクト: almaddy95/trezor-core-1
async def sign_tx(ctx, msg):
    from apps.wallet.sign_tx import layout, progress, signing

    # TODO: rework this so we don't have to pass root to signing.sign_tx
    root = await seed.derive_node(ctx, [])

    signer = signing.sign_tx(msg, root)
    res = None
    while True:
        try:
            req = signer.send(res)
        except signing.SigningError as e:
            raise wire.FailureError(*e.args)
        except signing.MultisigError as e:
            raise wire.FailureError(*e.args)
        except signing.AddressError as e:
            raise wire.FailureError(*e.args)
        except signing.ScriptsError as e:
            raise wire.FailureError(*e.args)
        except signing.Bip143Error as e:
            raise wire.FailureError(*e.args)
        if req.__qualname__ == 'TxRequest':
            if req.request_type == TXFINISHED:
                break
            res = await ctx.call(req, TxAck)
        elif req.__qualname__ == 'UiConfirmOutput':
            res = await layout.confirm_output(ctx, req.output, req.coin)
            progress.report_init()
        elif req.__qualname__ == 'UiConfirmTotal':
            res = await layout.confirm_total(ctx, req.spending, req.fee,
                                             req.coin)
            progress.report_init()
        elif req.__qualname__ == 'UiConfirmFeeOverThreshold':
            res = await layout.confirm_feeoverthreshold(ctx, req.fee, req.coin)
            progress.report_init()
        else:
            raise TypeError('Invalid signing instruction')
    return req
コード例 #28
0
async def recovery_device(ctx, msg):
    '''
    Recover BIP39 seed into empty device.

    1. Ask for the number of words in recovered seed.
    2. Let user type in the mnemonic words one by one.
    3. Optionally check the seed validity.
    4. Optionally ask for the PIN, with confirmation.
    5. Save into storage.
    '''
    from trezor import config
    from trezor.crypto import bip39
    from trezor.messages.FailureType import UnexpectedMessage, ProcessError
    from trezor.messages.Success import Success
    from trezor.ui.text import Text
    from apps.common import storage
    from apps.common.request_pin import request_pin
    from apps.common.request_words import request_words

    if storage.is_initialized():
        raise wire.FailureError(UnexpectedMessage, 'Already initialized')

    wordcount = await request_words(
        ctx, Text('Device recovery', ui.ICON_RECOVERY, 'Number of words?'))
    mnemonic = await request_mnemonic(wordcount, 'Type %s. word')

    if msg.enforce_wordlist and not bip39.check(mnemonic):
        raise wire.FailureError(ProcessError, 'Mnemonic is not valid')

    if msg.pin_protection:
        curpin = ''
        newpin = await request_pin(ctx)
        config.change_pin(curpin, newpin)

    storage.load_settings(label=msg.label,
                          use_passphrase=msg.passphrase_protection)
    storage.load_mnemonic(mnemonic)
    return Success()
コード例 #29
0
async def verify_message(ctx, msg):
    message = msg.message
    address = msg.address
    signature = msg.signature
    coin_name = msg.coin_name or 'Bitcoin'
    coin = coins.by_name(coin_name)

    await confirm_verify_message(ctx, message)

    digest = message_digest(coin, message)
    pubkey = secp256k1.verify_recover(signature, digest)

    if not pubkey:
        raise wire.FailureError(ProcessError, 'Invalid signature')

    raw_address = base58.decode_check(address)
    _, pkh = address_type.split(coin, raw_address)
    pkh2 = ripemd160(sha256(pubkey).digest()).digest()

    if pkh != pkh2:
        raise wire.FailureError(ProcessError, 'Invalid signature')

    return Success(message='Message verified')
コード例 #30
0
async def set_u2f_counter(ctx, msg):
    if msg.u2f_counter is None:
        raise wire.FailureError(FailureType.ProcessError,
                                'No value provided provided')

    await require_confirm(ctx,
                          Text('Set U2F counter', ui.ICON_CONFIG,
                               'Do you really want to', 'set the U2F counter',
                               ui.BOLD, 'to %d?' % msg.u2f_counter),
                          code=ButtonRequestType.ProtectCall)

    storage.set_u2f_counter(msg.u2f_counter)

    return Success(message='U2F counter set')