Ejemplo n.º 1
0
async def request_mnemonic(
        ctx: wire.Context, word_count: int,
        backup_type: Optional[EnumTypeBackupType]) -> Optional[str]:
    await ctx.call(ButtonRequest(code=ButtonRequestType.MnemonicInput),
                   ButtonAck)

    words = []
    for i in range(word_count):
        if backup_types.is_slip39_word_count(word_count):
            keyboard = Slip39Keyboard("Type word %s of %s:" %
                                      (i + 1, word_count))
        else:
            keyboard = Bip39Keyboard("Type word %s of %s:" %
                                     (i + 1, word_count))
        if __debug__:
            word = await ctx.wait(keyboard, input_signal())
        else:
            word = await ctx.wait(keyboard)

        if not await check_word_validity(ctx, i, word, backup_type, words):
            return None

        words.append(word)

    return " ".join(words)
Ejemplo n.º 2
0
async def show_invalid_mnemonic(ctx: wire.Context, word_count: int) -> None:
    if backup_types.is_slip39_word_count(word_count):
        await show_warning(
            ctx, ("You have entered", "an invalid recovery", "share."))
    else:
        await show_warning(
            ctx, ("You have entered", "an invalid recovery", "seed."))
Ejemplo n.º 3
0
async def request_mnemonic(
        ctx: wire.GenericContext, word_count: int,
        backup_type: Optional[EnumTypeBackupType]) -> Optional[str]:
    await button_request(ctx, code=ButtonRequestType.MnemonicInput)

    words = []  # type: List[str]
    for i in range(word_count):
        if backup_types.is_slip39_word_count(word_count):
            keyboard = Slip39Keyboard(
                "Type word %s of %s:" %
                (i + 1,
                 word_count))  # type: Union[Slip39Keyboard, Bip39Keyboard]
        else:
            keyboard = Bip39Keyboard("Type word %s of %s:" %
                                     (i + 1, word_count))

        word = await ctx.wait(keyboard)
        words.append(word)

        try:
            word_validity.check(backup_type, words)
        except word_validity.AlreadyAdded:
            await show_share_already_added(ctx)
            return None
        except word_validity.IdentifierMismatch:
            await show_identifier_mismatch(ctx)
            return None
        except word_validity.ThresholdReached:
            await show_group_threshold_reached(ctx)
            return None

    return " ".join(words)
Ejemplo n.º 4
0
async def load_device(ctx, msg):
    word_count = _validate(msg)
    is_slip39 = backup_types.is_slip39_word_count(word_count)

    if not is_slip39 and not msg.skip_checksum and not bip39.check(
            msg.mnemonics[0]):
        raise wire.ProcessError("Mnemonic is not valid")

    await _warn(ctx)

    if not is_slip39:  # BIP-39
        secret = msg.mnemonics[0].encode()
        backup_type = BackupType.Bip39
    else:
        identifier, iteration_exponent, secret, group_count = slip39.combine_mnemonics(
            msg.mnemonics)
        if group_count == 1:
            backup_type = BackupType.Slip39_Basic
        elif group_count > 1:
            backup_type = BackupType.Slip39_Advanced
        else:
            raise RuntimeError("Invalid group count")
        storage.device.set_slip39_identifier(identifier)
        storage.device.set_slip39_iteration_exponent(iteration_exponent)

    storage.device.store_mnemonic_secret(secret,
                                         backup_type,
                                         needs_backup=True,
                                         no_backup=False)
    storage.device.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, None)

    return Success(message="Device loaded")
Ejemplo n.º 5
0
async def _request_share_first_screen(ctx: wire.GenericContext,
                                      word_count: int) -> None:
    if backup_types.is_slip39_word_count(word_count):
        remaining = storage_recovery.fetch_slip39_remaining_shares()
        if remaining:
            await _request_share_next_screen(ctx)
        else:
            content = layout.RecoveryHomescreen("Enter any share",
                                                "(%d words)" % word_count)
            await layout.homescreen_dialog(ctx, content, "Enter share")
    else:  # BIP-39
        content = layout.RecoveryHomescreen("Enter recovery seed",
                                            "(%d words)" % word_count)
        await layout.homescreen_dialog(ctx, content, "Enter seed")
Ejemplo n.º 6
0
async def _process_words(
    ctx: wire.GenericContext, words: str
) -> Tuple[Optional[bytes], EnumTypeBackupType]:
    word_count = len(words.split(" "))
    is_slip39 = backup_types.is_slip39_word_count(word_count)

    share = None
    if not is_slip39:  # BIP-39
        secret = recover.process_bip39(words)  # type: Optional[bytes]
    else:
        secret, share = recover.process_slip39(words)

    backup_type = backup_types.infer_backup_type(is_slip39, share)
    if secret is None:  # SLIP-39
        assert share is not None
        if share.group_count and share.group_count > 1:
            await layout.show_group_share_success(ctx, share.index, share.group_index)
        await _request_share_next_screen(ctx)

    return secret, backup_type
Ejemplo n.º 7
0
async def load_device(ctx, msg):
    word_count = _validate(msg)
    is_slip39 = backup_types.is_slip39_word_count(word_count)

    if not is_slip39 and not msg.skip_checksum and not bip39.check(
            msg.mnemonics[0]):
        raise wire.ProcessError("Mnemonic is not valid")

    await _warn(ctx)

    if not is_slip39:  # BIP-39
        secret = msg.mnemonics[0].encode()
        backup_type = BackupType.Bip39
    else:
        identifier, iteration_exponent, secret = slip39.recover_ems(
            msg.mnemonics)

        # this must succeed if the recover_ems call succeeded
        share = slip39.decode_mnemonic(msg.mnemonics[0])
        if share.group_count == 1:
            backup_type = BackupType.Slip39_Basic
        elif share.group_count > 1:
            backup_type = BackupType.Slip39_Advanced
        else:
            raise wire.ProcessError("Invalid group count")

        storage.device.set_slip39_identifier(identifier)
        storage.device.set_slip39_iteration_exponent(iteration_exponent)

    storage.device.store_mnemonic_secret(
        secret,
        backup_type,
        needs_backup=msg.needs_backup is True,
        no_backup=msg.no_backup is True,
    )
    storage.device.set_passphrase_enabled(msg.passphrase_protection)
    storage.device.set_label(msg.label or "")
    if msg.pin:
        config.change_pin(pin_to_int(""), pin_to_int(msg.pin), None, None)

    return Success(message="Device loaded")