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

126 lines
3.9 KiB

from trezor import log, protobuf
from trezor.enums import ThpPairingMethod
from trezor.messages import (
ThpCodeEntryChallenge,
ThpCodeEntryCommitment,
ThpCodeEntryCpaceHost,
ThpCodeEntryCpaceTrezor,
ThpCodeEntrySecret,
ThpCodeEntryTag,
ThpCredentialRequest,
ThpCredentialResponse,
ThpEndRequest,
ThpEndResponse,
ThpNfcUnideirectionalSecret,
ThpNfcUnidirectionalTag,
ThpQrCodeSecret,
ThpQrCodeTag,
ThpStartPairingRequest,
)
from trezor.wire.errors import UnexpectedMessage
from trezor.wire.thp import ChannelState
from trezor.wire.thp.channel import Channel
from trezor.wire.thp.thp_session import ThpError
# TODO implement the following handlers
async def handle_pairing_request(
channel: Channel, message: protobuf.MessageType
) -> ThpCodeEntryCommitment | None:
assert ThpStartPairingRequest.is_type_of(message)
if __debug__:
log.debug(__name__, "handle_pairing_request")
_check_state(channel, ChannelState.TP1)
if _is_method_included(channel, ThpPairingMethod.PairingMethod_CodeEntry):
channel.set_channel_state(ChannelState.TP2)
return ThpCodeEntryCommitment()
channel.set_channel_state(ChannelState.TP3)
return None
async def handle_code_entry_challenge(
channel: Channel, message: protobuf.MessageType
) -> None:
assert ThpCodeEntryChallenge.is_type_of(message)
_check_state(channel, ChannelState.TP2)
channel.set_channel_state(ChannelState.TP3)
async def handle_code_entry_cpace(
channel: Channel, message: protobuf.MessageType
) -> ThpCodeEntryCpaceTrezor:
assert ThpCodeEntryCpaceHost.is_type_of(message)
_check_state(channel, ChannelState.TP3)
_check_method_is_allowed(channel, ThpPairingMethod.PairingMethod_CodeEntry)
channel.set_channel_state(ChannelState.TP4)
return ThpCodeEntryCpaceTrezor()
async def handle_code_entry_tag(
channel: Channel, message: protobuf.MessageType
) -> ThpCodeEntrySecret:
assert ThpCodeEntryTag.is_type_of(message)
_check_state(channel, ChannelState.TP4)
channel.set_channel_state(ChannelState.TC1)
return ThpCodeEntrySecret()
async def handle_qr_code_tag(
channel: Channel, message: protobuf.MessageType
) -> ThpQrCodeSecret:
assert ThpQrCodeTag.is_type_of(message)
_check_state(channel, ChannelState.TP3)
_check_method_is_allowed(channel, ThpPairingMethod.PairingMethod_QrCode)
channel.set_channel_state(ChannelState.TC1)
return ThpQrCodeSecret()
async def handle_nfc_unidirectional_tag(
channel: Channel, message: protobuf.MessageType
) -> ThpNfcUnideirectionalSecret:
assert ThpNfcUnidirectionalTag.is_type_of(message)
_check_state(channel, ChannelState.TP3)
_check_method_is_allowed(channel, ThpPairingMethod.PairingMethod_NFC_Unidirectional)
channel.set_channel_state(ChannelState.TC1)
return ThpNfcUnideirectionalSecret()
async def handle_credential_request(
channel: Channel, message: protobuf.MessageType
) -> ThpCredentialResponse:
assert ThpCredentialRequest.is_type_of(message)
_check_state(channel, ChannelState.TC1)
return ThpCredentialResponse()
async def handle_end_request(
channel: Channel, message: protobuf.MessageType
) -> ThpEndResponse:
assert ThpEndRequest.is_type_of(message)
_check_state(channel, ChannelState.TC1)
channel.set_channel_state(ChannelState.ENCRYPTED_TRANSPORT)
return ThpEndResponse()
def _check_state(channel: Channel, expected_state: ChannelState) -> None:
if expected_state is not channel.get_channel_state():
raise UnexpectedMessage("Unexpected message")
def _check_method_is_allowed(channel: Channel, method: ThpPairingMethod) -> None:
if not _is_method_included(channel, method):
raise ThpError("Unexpected pairing method")
def _is_method_included(channel: Channel, method: ThpPairingMethod) -> bool:
return method in channel.selected_pairing_methods