Exemple #1
0
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
Exemple #2
0
async def cardano_sign_message(ctx, msg):
    mnemonic = storage.get_mnemonic()
    root_node = bip32.from_mnemonic_cardano(mnemonic)

    try:
        signature = _sign_message(root_node, msg.message, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")
    mnemonic = None
    root_node = None

    if not await show_swipable_with_confirmation(
        ctx, msg.message, "Signing message", ui.ICON_RECEIVE, ui.GREEN
    ):
        raise wire.ActionCancelled("Signing cancelled")

    if not await show_swipable_with_confirmation(
        ctx,
        _break_address_n_to_lines(msg.address_n),
        "With address",
        ui.ICON_RECEIVE,
        ui.GREEN,
    ):
        raise wire.ActionCancelled("Signing cancelled")

    return signature
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.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, wire_types.PassphraseStateAck, wire_types.Cancel)

    return passphrase
Exemple #4
0
async def cardano_get_address(ctx, msg):
    mnemonic = storage.get_mnemonic()
    root_node = bip32.from_mnemonic_cardano(mnemonic)

    try:
        address, _ = derive_address_and_node(root_node, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving address failed")
    mnemonic = None
    root_node = None

    if msg.show_display:
        if not await show_swipable_with_confirmation(ctx,
                                                     address,
                                                     "Export address",
                                                     icon=ui.ICON_SEND,
                                                     icon_color=ui.GREEN):
            raise wire.ActionCancelled("Exporting cancelled")
        else:
            lines = _break_address_n_to_lines(msg.address_n)
            if not await show_swipable_with_confirmation(ctx,
                                                         lines,
                                                         "For BIP32 path",
                                                         icon=ui.ICON_SEND,
                                                         icon_color=ui.GREEN):
                raise wire.ActionCancelled("Exporting cancelled")

    return CardanoAddress(address=address)
Exemple #5
0
async def sign_tx(ctx, msg):
    keychain = await seed.get_keychain(ctx)

    progress.init(msg.transactions_count, "Loading data")

    try:
        attested = len(msg.inputs) * [False]
        input_coins_sum = 0
        # request transactions
        tx_req = CardanoTxRequest()

        for index in range(msg.transactions_count):
            progress.advance()
            tx_ack = await request_transaction(ctx, tx_req, index)
            tx_hash = hashlib.blake2b(data=bytes(tx_ack.transaction),
                                      outlen=32).digest()
            tx_decoded = cbor.decode(tx_ack.transaction)
            for i, input in enumerate(msg.inputs):
                if not attested[i] and input.prev_hash == tx_hash:
                    attested[i] = True
                    outputs = tx_decoded[1]
                    amount = outputs[input.prev_index][1]
                    input_coins_sum += amount

        if not all(attested):
            raise wire.ProcessError("No tx data sent for input " +
                                    str(attested.index(False)))

        transaction = Transaction(msg.inputs, msg.outputs, keychain,
                                  msg.protocol_magic, input_coins_sum)

        # clear progress bar
        display_homescreen()

        for i in msg.inputs:
            await validate_path(ctx, validate_full_path, keychain, i.address_n,
                                CURVE)

        # sign the transaction bundle and prepare the result
        tx_body, tx_hash = transaction.serialise_tx()
        tx = CardanoSignedTx(tx_body=tx_body, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    # display the transaction in UI
    if not await show_tx(
            ctx,
            transaction.output_addresses,
            transaction.outgoing_coins,
            transaction.fee,
            transaction.network_name,
            transaction.inputs,
            transaction.outputs,
    ):
        raise wire.ActionCancelled("Signing cancelled")

    return tx
Exemple #6
0
async def get_address(ctx, msg):
    await paths.validate_path(ctx, validate_full_path, path=msg.address_n)

    mnemonic = storage.get_mnemonic()
    passphrase = await seed._get_cached_passphrase(ctx)
    root_node = bip32.from_mnemonic_cardano(mnemonic, passphrase)

    try:
        address, _ = derive_address_and_node(root_node, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving address failed")
    mnemonic = None
    root_node = None

    if msg.show_display:
        if not await confirm_with_pagination(ctx,
                                             address,
                                             "Export address",
                                             icon=ui.ICON_SEND,
                                             icon_color=ui.GREEN):
            raise wire.ActionCancelled("Exporting cancelled")

    return CardanoAddress(address=address)
Exemple #7
0
async def request_passphrase_ack(ctx: wire.Context, on_device: bool) -> str:
    if not on_device:
        text = Text("Passphrase entry", ui.ICON_CONFIG)
        text.normal("Please, type passphrase", "on connected host.")
        await Popup(text)

    req = PassphraseRequest(on_device=on_device)
    ack = await ctx.call(req, PassphraseAck)

    if on_device:
        if ack.passphrase is not None:
            raise wire.ProcessError(
                "Passphrase provided when it should not be")

        keyboard = PassphraseKeyboard("Enter passphrase", _MAX_PASSPHRASE_LEN)
        if __debug__:
            passphrase = await ctx.wait(keyboard, input_signal())
        else:
            passphrase = await ctx.wait(keyboard)
        if passphrase is CANCELLED:
            raise wire.ActionCancelled("Passphrase cancelled")
    else:
        if ack.passphrase is None:
            raise wire.ProcessError("Passphrase not provided")
        passphrase = ack.passphrase

    state = cache.get_state(prev_state=ack.state, passphrase=passphrase)
    req = PassphraseStateRequest(state=state)
    ack = await ctx.call(req, PassphraseStateAck)

    return passphrase
Exemple #8
0
async def add_resident_credential(
    ctx: wire.Context, msg: WebAuthnAddResidentCredential
) -> Success:
    if not msg.credential_id:
        raise wire.ProcessError("Missing credential ID parameter.")

    try:
        cred = Fido2Credential.from_cred_id(bytes(msg.credential_id), None)
    except Exception:
        text = Text("Import credential", ui.ICON_WRONG, ui.RED)
        text.normal(
            "The credential you are",
            "trying to import does",
            "not belong to this",
            "authenticator.",
        )
        await require_confirm(ctx, text, confirm=None, cancel="Close")
        raise wire.ActionCancelled("Cancelled") from None

    content = ConfirmContent(ConfirmAddCredential(cred))
    await require_confirm(ctx, content)

    if store_resident_credential(cred):
        return Success(message="Credential added")
    else:
        raise wire.ProcessError("Internal credential storage is full.")
Exemple #9
0
async def request_pin_ack(ctx, *args, **kwargs):
    try:
        await ctx.call(ButtonRequest(code=ButtonRequestType.Other),
                       MessageType.ButtonAck)
        return await ctx.wait(request_pin(*args, **kwargs))
    except PinCancelled:
        raise wire.ActionCancelled("Cancelled")
Exemple #10
0
async def _require_confirm_output(
    ctx, dst: MoneroTransactionDestinationEntry, network_type: int, payment_id: bytes
):
    """
    Single transaction destination confirmation
    """
    from apps.monero.xmr.addresses import encode_addr
    from apps.monero.xmr.networks import net_version

    version = net_version(network_type, dst.is_subaddress, payment_id is not None)
    addr = encode_addr(
        version, dst.addr.spend_public_key, dst.addr.view_public_key, payment_id
    )

    text_addr = common.split_address(addr.decode())
    text_amount = common.format_amount(dst.amount)

    if not await common.naive_pagination(
        ctx,
        [ui.BOLD, text_amount, ui.MONO] + list(text_addr),
        "Confirm send",
        ui.ICON_SEND,
        ui.GREEN,
        4,
    ):
        raise wire.ActionCancelled("Cancelled")
Exemple #11
0
async def _show_page(page: int, page_count: int, content):
    content = Scrollpage(content[page], page, page_count)
    if page + 1 == page_count:
        if await ConfirmDialog(content) != CONFIRMED:
            raise wire.ActionCancelled("Action cancelled")
    else:
        content.render()
        await animate_swipe()
Exemple #12
0
async def request_pin_ack(ctx: wire.Context, *args: Any, **kwargs: Any) -> str:
    try:
        await ctx.call(ButtonRequest(code=ButtonRequestType.Other), ButtonAck)
        pin = await ctx.wait(request_pin(*args, **kwargs))
        assert isinstance(pin, str)
        return pin
    except PinCancelled:
        raise wire.ActionCancelled("Cancelled")
Exemple #13
0
async def _require_confirm_payment_id(ctx, payment_id):
    if not await common.naive_pagination(
            ctx,
        [ui.MONO] + list(chunks(hexlify((payment_id)), 16)),
            "Payment ID",
            ui.ICON_SEND,
            ui.GREEN,
    ):
        raise wire.ActionCancelled("Cancelled")
Exemple #14
0
async def recovery_process(ctx: wire.GenericContext) -> Success:
    try:
        return await _continue_recovery_process(ctx)
    except recover.RecoveryAborted:
        dry_run = storage_recovery.is_dry_run()
        if dry_run:
            storage_recovery.end_progress()
        else:
            storage.wipe()
        raise wire.ActionCancelled("Cancelled")
Exemple #15
0
async def cardano_verify_message(ctx, msg):
    try:
        res = _verify_message(msg.public_key, msg.signature, msg.message)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Verifying failed")

    if not res:
        return Failure(message="Invalid signature")

    if not await show_swipable_with_confirmation(
            ctx, msg.message, "Verifying message", ui.ICON_RECEIVE, ui.GREEN):
        raise wire.ActionCancelled("Verifying cancelled")

    if not await show_swipable_with_confirmation(ctx, hexlify(
            msg.public_key), "With public key", ui.ICON_RECEIVE, ui.GREEN):
        raise wire.ActionCancelled("Verifying cancelled")

    return Success(message="Message verified")
Exemple #16
0
async def _request_on_device(ctx: wire.Context) -> str:
    await button_request(ctx, code=ButtonRequestType.PassphraseEntry)

    keyboard = PassphraseKeyboard("Enter passphrase", _MAX_PASSPHRASE_LEN)
    passphrase = await ctx.wait(keyboard)
    if passphrase is CANCELLED:
        raise wire.ActionCancelled("Passphrase entry cancelled")

    assert isinstance(passphrase, str)

    return passphrase
Exemple #17
0
async def _require_confirm_properties(ctx, definition: NEMMosaicDefinition):
    # TODO: we should send a button request here
    pages = _get_mosaic_properties(definition)
    pages[-1] = Confirm(pages[-1])
    paginated = Paginated(pages)

    if __debug__:
        result = await ctx.wait(paginated, confirm_signal)
    else:
        result = await ctx.wait(paginated)
    if result is not CONFIRMED:
        raise wire.ActionCancelled("Action cancelled")
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.ActionCancelled('Passphrase cancelled')

    selector = EntrySelector(text)
    return await ctx.wait(selector)
Exemple #19
0
async def request_passphrase_on_device(ctx: wire.GenericContext, max_len: int) -> str:
    await button_request(
        ctx, "passphrase_device", code=ButtonRequestType.PassphraseEntry
    )

    keyboard = passphrase.PassphraseKeyboard("Enter passphrase", max_len)
    result = await ctx.wait(keyboard)
    if result is passphrase.CANCELLED:
        raise wire.ActionCancelled("Passphrase entry cancelled")

    assert isinstance(result, str)
    return result
Exemple #20
0
async def require_confirm_output(ctx, address:str, amount:int):
    text_addr = common.split_address(address)
    text_amount = common.format_amount(amount)

    if not await common.naive_pagination(
        ctx,
        [ui.BOLD, text_amount, ui.MONO] + list(text_addr),
        "Confirm send",
        ui.ICON_SEND,
        ui.GREEN,
        4,
    ):
        raise wire.ActionCancelled("Cancelled")
async def verify_message(ctx, msg):
    await paths.validate_path(ctx, validate_full_path, path=msg.address_n)

    try:
        res = _verify_message(msg.public_key, msg.signature, msg.message)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Verifying failed")

    if not res:
        return Failure(message="Invalid signature")

    if not await confirm_with_pagination(ctx, msg.message, "Verifying message",
                                         ui.ICON_RECEIVE, ui.GREEN):
        raise wire.ActionCancelled("Verifying cancelled")

    if not await confirm_with_pagination(ctx, hexlify(
            msg.public_key), "With public key", ui.ICON_RECEIVE, ui.GREEN):
        raise wire.ActionCancelled("Verifying cancelled")

    return Success(message="Message verified")
Exemple #22
0
async def show_proposal_page(page: int, page_count: int, pages: list, title: str):
    text = Text(title, ui.ICON_SEND, icon_color=ui.PURPLE)
    text.bold("Proposal {}: ".format(page + 1))
    text.mono(*split_proposal(pages[page]))
    content = Scrollpage(text, page, page_count)

    if page + 1 >= page_count:
        confirm = await ConfirmDialog(content)
        if confirm == CANCELLED:
            raise wire.ActionCancelled("Cancelled")
    else:
        content.render()
        await animate_swipe()
async def _request_on_device(ctx: wire.Context) -> str:
    await ctx.call(ButtonRequest(code=ButtonRequestType.PassphraseEntry), ButtonAck)

    keyboard = PassphraseKeyboard("Enter passphrase", _MAX_PASSPHRASE_LEN)
    if __debug__:
        passphrase = await ctx.wait(keyboard, input_signal())
    else:
        passphrase = await ctx.wait(keyboard)
    if passphrase is CANCELLED:
        raise wire.ActionCancelled("Passphrase entry cancelled")

    assert isinstance(passphrase, str)

    return passphrase
Exemple #24
0
async def show_lines_page(page: int, page_count: int, pages: list,
                          header: str):
    if header == "Arbitrary data":
        text = Text(header, ui.ICON_WIPE, icon_color=ui.RED)
    else:
        text = Text(header, ui.ICON_CONFIRM, icon_color=ui.GREEN)
    text.mono(*pages[page])

    content = Scrollpage(text, page, page_count)
    if page + 1 == page_count:
        if await ConfirmDialog(content) != CONFIRMED:
            raise wire.ActionCancelled("Action cancelled")
    else:
        content.render()
        await animate_swipe()
Exemple #25
0
async def show_voter_page(page: int, page_count: int, pages: list):
    lines = [
        "{:2d}. {}".format(wi + 1, helpers.eos_name_to_string(producer))
        for wi, producer in pages[page]
    ]
    text = Text("Vote for producers", ui.ICON_CONFIRM, icon_color=ui.GREEN)
    text.mono(*lines)
    content = Scrollpage(text, page, page_count)

    if page + 1 == page_count:
        if await ConfirmDialog(content) != CONFIRMED:
            raise wire.ActionCancelled("Action cancelled")
    else:
        content.render()
        await animate_swipe()
Exemple #26
0
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)
Exemple #27
0
async def sign_tx(ctx, msg):
    mnemonic = storage.get_mnemonic()
    passphrase = await seed._get_cached_passphrase(ctx)
    root_node = bip32.from_mnemonic_cardano(mnemonic, passphrase)

    progress.init(msg.transactions_count, "Loading data")

    try:
        # request transactions
        transactions = []
        tx_req = CardanoTxRequest()
        for index in range(msg.transactions_count):
            progress.advance()
            tx_ack = await request_transaction(ctx, tx_req, index)
            transactions.append(tx_ack.transaction)

        # clear progress bar
        display_homescreen()

        for i in msg.inputs:
            await validate_path(ctx, validate_full_path, path=i.address_n)

        # sign the transaction bundle and prepare the result
        transaction = Transaction(msg.inputs, msg.outputs, transactions,
                                  root_node, msg.network)
        tx_body, tx_hash = transaction.serialise_tx()
        tx = CardanoSignedTx(tx_body=tx_body, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    # display the transaction in UI
    if not await show_tx(
            ctx,
            transaction.output_addresses,
            transaction.outgoing_coins,
            transaction.change_derivation_paths,
            transaction.change_coins,
            transaction.fee,
            len(tx_body),
            transaction.network_name,
    ):
        raise wire.ActionCancelled("Signing cancelled")

    return tx
Exemple #28
0
async def sign_tx(ctx, msg):
    keychain = await seed.get_keychain(ctx)

    progress.init(msg.transactions_count, "Loading data")

    try:
        # request transactions
        transactions = []
        tx_req = CardanoTxRequest()
        for index in range(msg.transactions_count):
            progress.advance()
            tx_ack = await request_transaction(ctx, tx_req, index)
            transactions.append(tx_ack.transaction)

        # clear progress bar
        display_homescreen()

        for i in msg.inputs:
            await validate_path(ctx, validate_full_path, keychain, i.address_n,
                                CURVE)

        # sign the transaction bundle and prepare the result
        transaction = Transaction(msg.inputs, msg.outputs, transactions,
                                  keychain, msg.protocol_magic)
        tx_body, tx_hash = transaction.serialise_tx()
        tx = CardanoSignedTx(tx_body=tx_body, tx_hash=tx_hash)

    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Signing failed")

    # display the transaction in UI
    if not await show_tx(
            ctx,
            transaction.output_addresses,
            transaction.outgoing_coins,
            transaction.fee,
            transaction.network_name,
            transaction.inputs,
            transaction.outputs,
    ):
        raise wire.ActionCancelled("Signing cancelled")

    return tx
Exemple #29
0
async def cardano_get_public_key(ctx, msg):
    mnemonic = storage.get_mnemonic()
    root_node = bip32.from_mnemonic_cardano(mnemonic)

    try:
        key = _get_public_key(root_node, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving public key failed")
    mnemonic = None
    root_node = None

    lines = ["For BIP32 path: ", ""]
    lines.extend(_break_address_n_to_lines(msg.address_n))
    if not await show_swipable_with_confirmation(ctx, lines,
                                                 "Export xpub key"):
        raise wire.ActionCancelled("Exporting cancelled")

    return key
Exemple #30
0
async def get_address(ctx, msg):
    keychain = await seed.get_keychain(ctx)

    await paths.validate_path(ctx, validate_full_path, path=msg.address_n)

    try:
        address, _ = derive_address_and_node(keychain, msg.address_n)
    except ValueError as e:
        if __debug__:
            log.exception(__name__, e)
        raise wire.ProcessError("Deriving address failed")

    if msg.show_display:
        if not await confirm_with_pagination(ctx,
                                             address,
                                             "Export address",
                                             icon=ui.ICON_SEND,
                                             icon_color=ui.GREEN):
            raise wire.ActionCancelled("Exporting cancelled")

    return CardanoAddress(address=address)