From 0c353eb242974556f5bf44a25c34ad4d7fa0f378 Mon Sep 17 00:00:00 2001 From: M1nd3r Date: Mon, 9 Dec 2024 16:08:30 +0100 Subject: [PATCH] wip - change session behavior [no changelog] --- common/protob/messages-thp.proto | 1 - core/src/apps/base.py | 68 +++++--- core/src/storage/cache_thp.py | 62 +++---- core/src/trezor/messages.py | 2 - core/src/trezor/wire/thp/__init__.py | 2 +- core/src/trezor/wire/thp/channel.py | 2 +- .../wire/thp/received_message_handler.py | 15 +- core/src/trezor/wire/thp/session_context.py | 18 +-- core/src/trezor/wire/thp/session_manager.py | 29 ++-- core/tests/test_storage.cache.py | 46 ++++-- core/tests/thp_common.py | 2 +- python/src/trezorlib/messages.py | 3 - python/src/trezorlib/transport/session.py | 12 +- .../src/protos/generated/messages_thp.rs | 151 +++++++----------- 14 files changed, 201 insertions(+), 212 deletions(-) diff --git a/common/protob/messages-thp.proto b/common/protob/messages-thp.proto index 8419948f01..bfb15edbbc 100644 --- a/common/protob/messages-thp.proto +++ b/common/protob/messages-thp.proto @@ -78,7 +78,6 @@ message ThpCreateNewSession{ optional string passphrase = 1; optional bool on_device = 2; // User wants to enter passphrase on the device optional bool derive_cardano = 3; // If True, Cardano keys will be derived. Ignored with BTC-only - optional uint32 session_id = 4; // Id of the session to modify } /** diff --git a/core/src/apps/base.py b/core/src/apps/base.py index eacdb79a28..cb06d5a5ad 100644 --- a/core/src/apps/base.py +++ b/core/src/apps/base.py @@ -220,13 +220,15 @@ if utils.USE_THP: """ from trezor import log, loop from trezor.enums import FailureType - from trezor.messages import Failure, ThpNewSession + from trezor.messages import Failure from trezor.wire import NotInitialized from trezor.wire.context import get_context from trezor.wire.errors import ActionCancelled, DataError - from trezor.wire.thp import SessionState from trezor.wire.thp.session_context import GenericSessionContext - from trezor.wire.thp.session_manager import create_new_session + from trezor.wire.thp.session_manager import ( + get_new_management_session_ctx, + get_new_session_context, + ) from apps.common.seed import derive_and_store_roots @@ -236,11 +238,38 @@ if utils.USE_THP: assert isinstance(ctx, GenericSessionContext) channel = ctx.channel + session_id = ctx.session_id # Do not use `ctx` beyond this point, as it is techically # allowed to change in between await statements - if message.session_id is None: - new_session = create_new_session(channel) + + is_management = ( + message.passphrase is None + and message.on_device is not True + and message.derive_cardano is not True + ) + + if not 0 <= session_id <= 255: + return Failure( + code=FailureType.DataError, + message="Invalid session_id for session creation.", + ) + + if is_management: + # TODO this block is completely useless and will be removed - or will result in session.clear + new_session = get_new_management_session_ctx( + channel_ctx=channel, session_id=session_id + ) + succ_message = "New management session created." + + if __debug__ and utils.ALLOW_DEBUG_MESSAGES: + log.debug( + __name__, "New management session with sid %d created.", session_id + ) + else: + new_session = get_new_session_context( + channel_ctx=channel, session_id=session_id + ) try: await unlock_device() await derive_and_store_roots(new_session, message) @@ -252,23 +281,20 @@ if utils.USE_THP: return Failure(code=FailureType.NotInitialized, message=e.message) # TODO handle other errors (`Exception` when "Cardano icarus secret is already set!") - new_session.set_session_state(SessionState.ALLOCATED) - channel.sessions[new_session.session_id] = new_session - loop.schedule(new_session.handle()) - new_session_id: int = new_session.session_id - else: - # HMMMMMMMMMMMMMMMMMM - pass - if __debug__ and utils.ALLOW_DEBUG_MESSAGES: - log.debug( - __name__, - "create_new_session - new session created. Passphrase: %s, Session id: %d\n%s", - message.passphrase if message.passphrase is not None else "", - new_session.session_id, - str(channel.sessions), - ) + succ_message = "New session created." - return ThpNewSession(new_session_id=new_session_id) + if __debug__ and utils.ALLOW_DEBUG_MESSAGES: + log.debug( + __name__, + "New session with sid %d and passphrase %s created.", + session_id, + message.passphrase if message.passphrase is not None else "", + ) + + channel.sessions[new_session.session_id] = new_session + loop.schedule(new_session.handle()) + + return Success(message=succ_message) else: diff --git a/core/src/storage/cache_thp.py b/core/src/storage/cache_thp.py index 7856da4801..183d8832f9 100644 --- a/core/src/storage/cache_thp.py +++ b/core/src/storage/cache_thp.py @@ -24,7 +24,8 @@ BROADCAST_CHANNEL_ID = const(0xFFFF) KEY_LENGTH = const(32) TAG_LENGTH = const(16) _UNALLOCATED_STATE = const(0) -_MANAGEMENT_STATE = const(2) +_ALLOCATED_STATE = const(1) +_SEEDLESS_STATE = const(2) MANAGEMENT_SESSION_ID = const(0) @@ -176,28 +177,35 @@ def get_all_allocated_channels() -> list[ChannelCache]: def get_allocated_session( channel_id: bytes, session_id: bytes ) -> SessionThpCache | None: + index = get_allocated_session_index(channel_id, session_id) + if index is None: + return index + return _SESSIONS[index] + + +def get_allocated_session_index(channel_id: bytes, session_id: bytes) -> int | None: """ - Finds and returns the first allocated session matching the given `channel_id` and `session_id`, - or `None` if no match is found. + Finds and returns index of the first allocated session matching the given `channel_id` + and `session_id`, or `None` if no match is found. Raises `Exception` if either channel_id or session_id has an invalid length. """ if len(channel_id) != _CHANNEL_ID_LENGTH or len(session_id) != SESSION_ID_LENGTH: raise Exception("At least one of arguments has invalid length") - for session in _SESSIONS: - if _get_session_state(session) == _UNALLOCATED_STATE: + for i in range(_MAX_SESSIONS_COUNT): + if _get_session_state(_SESSIONS[i]) == _UNALLOCATED_STATE: continue - if session.channel_id != channel_id: + if _SESSIONS[i].channel_id != channel_id: continue - if session.session_id != session_id: + if _SESSIONS[i].session_id != session_id: continue - return session + return i return None def is_management_session(session_cache: SessionThpCache) -> bool: - return _get_session_state(session_cache) == _MANAGEMENT_STATE + return _get_session_state(session_cache) == _SEEDLESS_STATE def set_channel_host_ephemeral_key(channel: ChannelCache, key: bytearray) -> None: @@ -206,26 +214,24 @@ def set_channel_host_ephemeral_key(channel: ChannelCache, key: bytearray) -> Non channel.host_ephemeral_pubkey = key -def get_new_session(channel: ChannelCache, management: bool = False) -> SessionThpCache: - new_sid = get_next_session_id(channel) - index = _get_next_session_index() +def create_or_replace_session( + channel: ChannelCache, session_id: bytes +) -> SessionThpCache: + index = get_allocated_session_index(channel.channel_id, session_id) + if index is None: + index = _get_next_session_index() _SESSIONS[index] = SessionThpCache() _SESSIONS[index].channel_id[:] = channel.channel_id - _SESSIONS[index].session_id[:] = new_sid + _SESSIONS[index].session_id[:] = session_id _SESSIONS[index].last_usage = _get_usage_counter_and_increment() channel.last_usage = ( _get_usage_counter_and_increment() ) # increment also use of the channel so it does not get replaced - if management: - _SESSIONS[index].state[:] = bytearray( - _MANAGEMENT_STATE.to_bytes(_SESSION_STATE_LENGTH, "big") - ) - else: - _SESSIONS[index].state[:] = bytearray( - _UNALLOCATED_STATE.to_bytes(_SESSION_STATE_LENGTH, "big") - ) + _SESSIONS[index].state[:] = bytearray( + _ALLOCATED_STATE.to_bytes(_SESSION_STATE_LENGTH, "big") + ) return _SESSIONS[index] @@ -239,14 +245,14 @@ def _get_next_channel_index() -> int: idx = _get_unallocated_channel_index() if idx is not None: return idx - return get_least_recently_used_item(_CHANNELS, max_count=_MAX_CHANNELS_COUNT) + return _get_least_recently_used_item(_CHANNELS, max_count=_MAX_CHANNELS_COUNT) def _get_next_session_index() -> int: idx = _get_unallocated_session_index() if idx is not None: return idx - return get_least_recently_used_item(_SESSIONS, max_count=_MAX_SESSIONS_COUNT) + return _get_least_recently_used_item(_SESSIONS, max_count=_MAX_SESSIONS_COUNT) def _get_unallocated_channel_index() -> int | None: @@ -282,19 +288,19 @@ def get_next_channel_id() -> bytes: return cid_counter.to_bytes(_CHANNEL_ID_LENGTH, "big") -def get_next_session_id(channel: ChannelCache) -> bytes: +def _deprecated_get_next_session_id(channel: ChannelCache) -> bytes: while True: if channel.session_id_counter >= 255: channel.session_id_counter = 1 else: channel.session_id_counter += 1 - if _is_session_id_unique(channel): + if _deprecated_is_session_id_unique(channel): break new_sid = channel.session_id_counter return new_sid.to_bytes(SESSION_ID_LENGTH, "big") -def _is_session_id_unique(channel: ChannelCache) -> bool: +def _deprecated_is_session_id_unique(channel: ChannelCache) -> bool: for session in _SESSIONS: if session.channel_id == channel.channel_id: if session.session_id == channel.session_id_counter: @@ -311,7 +317,7 @@ def _is_cid_unique() -> bool: return True -def get_least_recently_used_item( +def _get_least_recently_used_item( list: list[ChannelCache] | list[SessionThpCache], max_count: int ) -> int: global _usage_counter @@ -366,6 +372,6 @@ def clear_all_except_one_session_keys(excluded: Tuple[bytes, bytes]) -> None: s_last_usage = session.last_usage session.clear() session.last_usage = s_last_usage - session.state = bytearray(_MANAGEMENT_STATE.to_bytes(1, "big")) + session.state = bytearray(_SEEDLESS_STATE.to_bytes(1, "big")) session.session_id[:] = bytearray(sid) session.channel_id[:] = bytearray(cid) diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 3181781fb7..d230774c81 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -6182,7 +6182,6 @@ if TYPE_CHECKING: passphrase: "str | None" on_device: "bool | None" derive_cardano: "bool | None" - session_id: "int | None" def __init__( self, @@ -6190,7 +6189,6 @@ if TYPE_CHECKING: passphrase: "str | None" = None, on_device: "bool | None" = None, derive_cardano: "bool | None" = None, - session_id: "int | None" = None, ) -> None: pass diff --git a/core/src/trezor/wire/thp/__init__.py b/core/src/trezor/wire/thp/__init__.py index ce61cf815a..8cf3a9207d 100644 --- a/core/src/trezor/wire/thp/__init__.py +++ b/core/src/trezor/wire/thp/__init__.py @@ -72,7 +72,7 @@ class ChannelState(IntEnum): class SessionState(IntEnum): UNALLOCATED = 0 ALLOCATED = 1 - MANAGEMENT = 2 + SEEDLESS = 2 class PacketHeader: diff --git a/core/src/trezor/wire/thp/channel.py b/core/src/trezor/wire/thp/channel.py index 0398b64b9a..d2ddcbf96e 100644 --- a/core/src/trezor/wire/thp/channel.py +++ b/core/src/trezor/wire/thp/channel.py @@ -23,9 +23,9 @@ from . import ( from .checksum import CHECKSUM_LENGTH from .transmission_loop import TransmissionLoop from .writer import ( - PACKET_LENGTH, CONT_HEADER_LENGTH, INIT_HEADER_LENGTH, + PACKET_LENGTH, write_payload_to_wire_and_add_checksum, ) diff --git a/core/src/trezor/wire/thp/received_message_handler.py b/core/src/trezor/wire/thp/received_message_handler.py index 0dd402a1f9..2a7fbbdf30 100644 --- a/core/src/trezor/wire/thp/received_message_handler.py +++ b/core/src/trezor/wire/thp/received_message_handler.py @@ -10,7 +10,6 @@ from storage.cache_common import ( ) from storage.cache_thp import ( KEY_LENGTH, - MANAGEMENT_SESSION_ID, SESSION_ID_LENGTH, TAG_LENGTH, update_channel_last_used, @@ -46,6 +45,7 @@ from . import ( ) from .checksum import CHECKSUM_LENGTH from .crypto import PUBKEY_LENGTH, Handshake +from .session_context import SeedlessSessionContext from .writer import ( INIT_HEADER_LENGTH, MESSAGE_TYPE_LENGTH, @@ -353,23 +353,18 @@ async def _handle_state_ENCRYPTED_TRANSPORT(ctx: Channel, message_length: int) - ">BH", memoryview(ctx.buffer)[INIT_HEADER_LENGTH:] ) if session_id not in ctx.sessions: - if session_id == MANAGEMENT_SESSION_ID: - s = session_manager.create_new_management_session(ctx) - else: - s = session_manager.get_session_from_cache(ctx, session_id) + + s = session_manager.get_session_from_cache(ctx, session_id) if s is None: - assert session_id != MANAGEMENT_SESSION_ID - - # Create management session backed by cache (non-trivial session_id) - s = session_manager.create_new_management_session(ctx, session_id) + s = SeedlessSessionContext(ctx, session_id) ctx.sessions[session_id] = s loop.schedule(s.handle()) elif ctx.sessions[session_id].get_session_state() is SessionState.UNALLOCATED: raise ThpUnallocatedSessionError(session_id) - # TODO what should happen here? Should I create a new management session? + # TODO what should happen here? Should I create a new seedless session? s = ctx.sessions[session_id] update_session_last_used(s.channel_id, (s.session_id).to_bytes(1, "big")) diff --git a/core/src/trezor/wire/thp/session_context.py b/core/src/trezor/wire/thp/session_context.py index 6565df656b..4520738757 100644 --- a/core/src/trezor/wire/thp/session_context.py +++ b/core/src/trezor/wire/thp/session_context.py @@ -1,7 +1,7 @@ from typing import TYPE_CHECKING from storage import cache_thp -from storage.cache_thp import MANAGEMENT_SESSION_ID, SessionThpCache +from storage.cache_thp import SessionThpCache from trezor import log, loop, protobuf, utils from trezor.wire import message_handler, protocol_common from trezor.wire.context import UnexpectedMessageException @@ -128,23 +128,13 @@ class GenericSessionContext(Context): def get_session_state(self) -> SessionState: ... -class ManagementSessionContext(GenericSessionContext): +class SeedlessSessionContext(GenericSessionContext): - def __init__( - self, - channel_ctx: Channel, - session_id: int = MANAGEMENT_SESSION_ID, - session_cache: SessionThpCache | None = None, - ) -> None: - self.session_cache = session_cache + def __init__(self, channel_ctx: Channel, session_id: int) -> None: super().__init__(channel_ctx, session_id) def get_session_state(self) -> SessionState: - return SessionState.MANAGEMENT - - def release(self) -> None: - if self.session_cache is not None: - cache_thp.clear_session(self.session_cache) + return SessionState.SEEDLESS class SessionContext(GenericSessionContext): diff --git a/core/src/trezor/wire/thp/session_manager.py b/core/src/trezor/wire/thp/session_manager.py index 4b03dab5e3..e7d39c4006 100644 --- a/core/src/trezor/wire/thp/session_manager.py +++ b/core/src/trezor/wire/thp/session_manager.py @@ -4,7 +4,7 @@ from storage import cache_thp from .session_context import ( GenericSessionContext, - ManagementSessionContext, + SeedlessSessionContext, SessionContext, ) @@ -12,25 +12,26 @@ if TYPE_CHECKING: from .channel import Channel -def create_new_session(channel_ctx: Channel) -> SessionContext: - """ - Creates new `SessionContext` backed by cache. - """ - session_cache = cache_thp.get_new_session(channel_ctx.channel_cache) +def get_new_session_context( + channel_ctx: Channel, + session_id: int, +) -> SessionContext: + session_cache = cache_thp.create_or_replace_session( + channel=channel_ctx.channel_cache, + session_id=session_id.to_bytes(1, "big"), + ) return SessionContext(channel_ctx, session_cache) -def create_new_management_session( - channel_ctx: Channel, session_id: int = cache_thp.MANAGEMENT_SESSION_ID -) -> ManagementSessionContext: +def get_new_management_session_ctx( + channel_ctx: Channel, session_id: int +) -> SeedlessSessionContext: """ - Creates new `ManagementSessionContext` that is not backed by cache entry. + Creates new `ManagementSessionContext` that is not backed by a cache entry. Seed cannot be derived with this type of session. """ - if session_id != cache_thp.MANAGEMENT_SESSION_ID: - cache_thp.get_new_session(channel_ctx.channel_cache, management=True) - return ManagementSessionContext(channel_ctx, session_id) + return SeedlessSessionContext(channel_ctx, session_id) def get_session_from_cache( @@ -46,5 +47,5 @@ def get_session_from_cache( if session_cache is None: return None elif cache_thp.is_management_session(session_cache): - return ManagementSessionContext(channel_ctx, session_id) + return SeedlessSessionContext(channel_ctx, session_id) return SessionContext(channel_ctx, session_cache) diff --git a/core/tests/test_storage.cache.py b/core/tests/test_storage.cache.py index 0c92bf254a..8b426dd070 100644 --- a/core/tests/test_storage.cache.py +++ b/core/tests/test_storage.cache.py @@ -48,11 +48,15 @@ class TestStorageCache(unittest.TestCase): self.assertEqual(len(channel.sessions), 0) cid_1 = channel.channel_id - session_cache_1 = cache_thp.get_new_session(channel.channel_cache) + session_cache_1 = cache_thp._deprecated_get_new_session( + channel.channel_cache + ) session_1 = SessionContext(channel, session_cache_1) self.assertEqual(session_1.channel_id, cid_1) - session_cache_2 = cache_thp.get_new_session(channel.channel_cache) + session_cache_2 = cache_thp._deprecated_get_new_session( + channel.channel_cache + ) session_2 = SessionContext(channel, session_cache_2) self.assertEqual(session_2.channel_id, cid_1) self.assertEqual(session_1.channel_id, session_2.channel_id) @@ -62,7 +66,9 @@ class TestStorageCache(unittest.TestCase): cid_2 = channel_2.channel_id self.assertNotEqual(cid_1, cid_2) - session_cache_3 = cache_thp.get_new_session(channel_2.channel_cache) + session_cache_3 = cache_thp._deprecated_get_new_session( + channel_2.channel_cache + ) session_3 = SessionContext(channel_2, session_cache_3) self.assertEqual(session_3.channel_id, cid_2) @@ -136,13 +142,15 @@ class TestStorageCache(unittest.TestCase): cid = [] sid = [] for i in range(3): - sesions_A.append(cache_thp.get_new_session(channel_cache_A)) + sesions_A.append(cache_thp._deprecated_get_new_session(channel_cache_A)) cid.append(sesions_A[i].channel_id) sid.append(sesions_A[i].session_id) sessions_B = [] for i in range(cache_thp._MAX_SESSIONS_COUNT - 3): - sessions_B.append(cache_thp.get_new_session(channel_cache_B)) + sessions_B.append( + cache_thp._deprecated_get_new_session(channel_cache_B) + ) for i in range(3): self.assertEqual(sesions_A[i], cache_thp._SESSIONS[i]) @@ -152,7 +160,7 @@ class TestStorageCache(unittest.TestCase): self.assertEqual(sessions_B[i - 3], cache_thp._SESSIONS[i]) # Assert that new session replaces the oldest (least used) one (_SESSOIONS[0]) - new_session = cache_thp.get_new_session(channel_cache_B) + new_session = cache_thp._deprecated_get_new_session(channel_cache_B) self.assertEqual(new_session, cache_thp._SESSIONS[0]) self.assertNotEqual(new_session.channel_id, cid[0]) self.assertNotEqual(new_session.session_id, sid[0]) @@ -165,7 +173,7 @@ class TestStorageCache(unittest.TestCase): ) self.assertTrue(channel_cache_A.last_usage > channel_cache_B.last_usage) - new_new_session = cache_thp.get_new_session(channel_cache_B) + new_new_session = cache_thp._deprecated_get_new_session(channel_cache_B) # Assert that creating a new session on channel B shifts the "last usage" again # and that _SESSIONS[1] was not replaced, but that _SESSIONS[2] was replaced @@ -182,8 +190,12 @@ class TestStorageCache(unittest.TestCase): sessions = [] for i in range(3): - sessions.append(cache_thp.get_new_session(channel_A.channel_cache)) - sessions.append(cache_thp.get_new_session(channel_B.channel_cache)) + sessions.append( + cache_thp._deprecated_get_new_session(channel_A.channel_cache) + ) + sessions.append( + cache_thp._deprecated_get_new_session(channel_B.channel_cache) + ) self.assertEqual(cache_thp._SESSIONS[2 * i].channel_id, cid_A) self.assertNotEqual(cache_thp._SESSIONS[2 * i].last_usage, 0) @@ -224,11 +236,11 @@ class TestStorageCache(unittest.TestCase): def test_get_set(self): channel = thp_common.get_new_channel(self.interface) - session_1 = cache_thp.get_new_session(channel.channel_cache) + session_1 = cache_thp._deprecated_get_new_session(channel.channel_cache) session_1.set(KEY, b"hello") self.assertEqual(session_1.get(KEY), b"hello") - session_2 = cache_thp.get_new_session(channel.channel_cache) + session_2 = cache_thp._deprecated_get_new_session(channel.channel_cache) session_2.set(KEY, b"world") self.assertEqual(session_2.get(KEY), b"world") @@ -241,12 +253,12 @@ class TestStorageCache(unittest.TestCase): def test_get_set_int(self): channel = thp_common.get_new_channel(self.interface) - session_1 = cache_thp.get_new_session(channel.channel_cache) + session_1 = cache_thp._deprecated_get_new_session(channel.channel_cache) session_1.set_int(KEY, 1234) self.assertEqual(session_1.get_int(KEY), 1234) - session_2 = cache_thp.get_new_session(channel.channel_cache) + session_2 = cache_thp._deprecated_get_new_session(channel.channel_cache) session_2.set_int(KEY, 5678) self.assertEqual(session_2.get_int(KEY), 5678) @@ -259,7 +271,7 @@ class TestStorageCache(unittest.TestCase): def test_get_set_bool(self): channel = thp_common.get_new_channel(self.interface) - session_1 = cache_thp.get_new_session(channel.channel_cache) + session_1 = cache_thp._deprecated_get_new_session(channel.channel_cache) with self.assertRaises(AssertionError): session_1.set_bool(KEY, True) @@ -270,7 +282,7 @@ class TestStorageCache(unittest.TestCase): session_1.set_bool(KEY, True) self.assertEqual(session_1.get_bool(KEY), True) - session_2 = cache_thp.get_new_session(channel.channel_cache) + session_2 = cache_thp._deprecated_get_new_session(channel.channel_cache) session_2.fields = session_2.fields = (0,) + session_2.fields[1:] session_2.set_bool(KEY, False) self.assertEqual(session_2.get_bool(KEY), False) @@ -285,7 +297,7 @@ class TestStorageCache(unittest.TestCase): def test_delete(self): channel = thp_common.get_new_channel(self.interface) - session_1 = cache_thp.get_new_session(channel.channel_cache) + session_1 = cache_thp._deprecated_get_new_session(channel.channel_cache) self.assertIsNone(session_1.get(KEY)) session_1.set(KEY, b"hello") @@ -294,7 +306,7 @@ class TestStorageCache(unittest.TestCase): self.assertIsNone(session_1.get(KEY)) session_1.set(KEY, b"hello") - session_2 = cache_thp.get_new_session(channel.channel_cache) + session_2 = cache_thp._deprecated_get_new_session(channel.channel_cache) self.assertIsNone(session_2.get(KEY)) session_2.set(KEY, b"hello") diff --git a/core/tests/thp_common.py b/core/tests/thp_common.py index 298a513002..d22243d29e 100644 --- a/core/tests/thp_common.py +++ b/core/tests/thp_common.py @@ -31,7 +31,7 @@ if utils.USE_THP: def prepare_context() -> None: channel = get_new_channel() - session_cache = cache_thp.get_new_session(channel.channel_cache) + session_cache = cache_thp._deprecated_get_new_session(channel.channel_cache) session_ctx = SessionContext(channel, session_cache) context.CURRENT_CONTEXT = session_ctx diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index cdea61bd51..86fd70dfd8 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -7915,7 +7915,6 @@ class ThpCreateNewSession(protobuf.MessageType): 1: protobuf.Field("passphrase", "string", repeated=False, required=False, default=None), 2: protobuf.Field("on_device", "bool", repeated=False, required=False, default=None), 3: protobuf.Field("derive_cardano", "bool", repeated=False, required=False, default=None), - 4: protobuf.Field("session_id", "uint32", repeated=False, required=False, default=None), } def __init__( @@ -7924,12 +7923,10 @@ class ThpCreateNewSession(protobuf.MessageType): passphrase: Optional["str"] = None, on_device: Optional["bool"] = None, derive_cardano: Optional["bool"] = None, - session_id: Optional["int"] = None, ) -> None: self.passphrase = passphrase self.on_device = on_device self.derive_cardano = derive_cardano - self.session_id = session_id class ThpNewSession(protobuf.MessageType): diff --git a/python/src/trezorlib/transport/session.py b/python/src/trezorlib/transport/session.py index 4015f48a8f..7b55490198 100644 --- a/python/src/trezorlib/transport/session.py +++ b/python/src/trezorlib/transport/session.py @@ -174,17 +174,19 @@ class SessionV2(Session): @classmethod def new( - cls, client: TrezorClient, passphrase: str | None, derive_cardano: bool + cls, + client: TrezorClient, + passphrase: str | None, + derive_cardano: bool, + session_id: int = 0, ) -> SessionV2: assert isinstance(client.protocol, ProtocolV2) - session = cls(client, b"\x00") - new_session: messages.ThpNewSession = session.call( + session = cls(client, session_id.to_bytes(1, "big")) + _: messages.Success = session.call( messages.ThpCreateNewSession( passphrase=passphrase, derive_cardano=derive_cardano ) ) - assert new_session.new_session_id is not None - session_id = new_session.new_session_id session.update_id_and_sid(session_id.to_bytes(1, "big")) return session diff --git a/rust/trezor-client/src/protos/generated/messages_thp.rs b/rust/trezor-client/src/protos/generated/messages_thp.rs index a0e08ccbd3..9bd5e40d3d 100644 --- a/rust/trezor-client/src/protos/generated/messages_thp.rs +++ b/rust/trezor-client/src/protos/generated/messages_thp.rs @@ -504,8 +504,6 @@ pub struct ThpCreateNewSession { pub on_device: ::std::option::Option, // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCreateNewSession.derive_cardano) pub derive_cardano: ::std::option::Option, - // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCreateNewSession.session_id) - pub session_id: ::std::option::Option, // special fields // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpCreateNewSession.special_fields) pub special_fields: ::protobuf::SpecialFields, @@ -596,27 +594,8 @@ impl ThpCreateNewSession { self.derive_cardano = ::std::option::Option::Some(v); } - // optional uint32 session_id = 4; - - pub fn session_id(&self) -> u32 { - self.session_id.unwrap_or(0) - } - - pub fn clear_session_id(&mut self) { - self.session_id = ::std::option::Option::None; - } - - pub fn has_session_id(&self) -> bool { - self.session_id.is_some() - } - - // Param is passed by value, moved - pub fn set_session_id(&mut self, v: u32) { - self.session_id = ::std::option::Option::Some(v); - } - fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(4); + let mut fields = ::std::vec::Vec::with_capacity(3); let mut oneofs = ::std::vec::Vec::with_capacity(0); fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( "passphrase", @@ -633,11 +612,6 @@ impl ThpCreateNewSession { |m: &ThpCreateNewSession| { &m.derive_cardano }, |m: &mut ThpCreateNewSession| { &mut m.derive_cardano }, )); - fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( - "session_id", - |m: &ThpCreateNewSession| { &m.session_id }, - |m: &mut ThpCreateNewSession| { &mut m.session_id }, - )); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "ThpCreateNewSession", fields, @@ -665,9 +639,6 @@ impl ::protobuf::Message for ThpCreateNewSession { 24 => { self.derive_cardano = ::std::option::Option::Some(is.read_bool()?); }, - 32 => { - self.session_id = ::std::option::Option::Some(is.read_uint32()?); - }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -689,9 +660,6 @@ impl ::protobuf::Message for ThpCreateNewSession { if let Some(v) = self.derive_cardano { my_size += 1 + 1; } - if let Some(v) = self.session_id { - my_size += ::protobuf::rt::uint32_size(4, v); - } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); self.special_fields.cached_size().set(my_size as u32); my_size @@ -707,9 +675,6 @@ impl ::protobuf::Message for ThpCreateNewSession { if let Some(v) = self.derive_cardano { os.write_bool(3, v)?; } - if let Some(v) = self.session_id { - os.write_uint32(4, v)?; - } os.write_unknown_fields(self.special_fields.unknown_fields())?; ::std::result::Result::Ok(()) } @@ -730,7 +695,6 @@ impl ::protobuf::Message for ThpCreateNewSession { self.passphrase = ::std::option::Option::None; self.on_device = ::std::option::Option::None; self.derive_cardano = ::std::option::Option::None; - self.session_id = ::std::option::Option::None; self.special_fields.clear(); } @@ -739,7 +703,6 @@ impl ::protobuf::Message for ThpCreateNewSession { passphrase: ::std::option::Option::None, on_device: ::std::option::Option::None, derive_cardano: ::std::option::Option::None, - session_id: ::std::option::Option::None, special_fields: ::protobuf::SpecialFields::new(), }; &instance @@ -4083,62 +4046,62 @@ static file_descriptor_proto_data: &'static [u8] = b"\ .thp.ThpPairingMethodR\x0epairingMethods\"\xb2\x01\n%ThpHandshakeComplet\ ionReqNoisePayload\x126\n\x17host_pairing_credential\x18\x01\x20\x01(\ \x0cR\x15hostPairingCredential\x12Q\n\x0fpairing_methods\x18\x02\x20\x03\ - (\x0e2(.hw.trezor.messages.thp.ThpPairingMethodR\x0epairingMethods\"\x98\ - \x01\n\x13ThpCreateNewSession\x12\x1e\n\npassphrase\x18\x01\x20\x01(\tR\ - \npassphrase\x12\x1b\n\ton_device\x18\x02\x20\x01(\x08R\x08onDevice\x12%\ - \n\x0ederive_cardano\x18\x03\x20\x01(\x08R\rderiveCardano\x12\x1d\n\nses\ - sion_id\x18\x04\x20\x01(\rR\tsessionId\"5\n\rThpNewSession\x12$\n\x0enew\ - _session_id\x18\x01\x20\x01(\rR\x0cnewSessionId\"5\n\x16ThpStartPairingR\ - equest\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostName\"\x20\n\x1eT\ - hpPairingPreparationsFinished\"8\n\x16ThpCodeEntryCommitment\x12\x1e\n\n\ - commitment\x18\x01\x20\x01(\x0cR\ncommitment\"5\n\x15ThpCodeEntryChallen\ - ge\x12\x1c\n\tchallenge\x18\x01\x20\x01(\x0cR\tchallenge\"J\n\x15ThpCode\ - EntryCpaceHost\x121\n\x15cpace_host_public_key\x18\x01\x20\x01(\x0cR\x12\ - cpaceHostPublicKey\"P\n\x17ThpCodeEntryCpaceTrezor\x125\n\x17cpace_trezo\ - r_public_key\x18\x01\x20\x01(\x0cR\x14cpaceTrezorPublicKey\"#\n\x0fThpCo\ - deEntryTag\x12\x10\n\x03tag\x18\x02\x20\x01(\x0cR\x03tag\",\n\x12ThpCode\ - EntrySecret\x12\x16\n\x06secret\x18\x01\x20\x01(\x0cR\x06secret\"\x20\n\ - \x0cThpQrCodeTag\x12\x10\n\x03tag\x18\x01\x20\x01(\x0cR\x03tag\")\n\x0fT\ - hpQrCodeSecret\x12\x16\n\x06secret\x18\x01\x20\x01(\x0cR\x06secret\"+\n\ - \x17ThpNfcUnidirectionalTag\x12\x10\n\x03tag\x18\x01\x20\x01(\x0cR\x03ta\ - g\"4\n\x1aThpNfcUnidirectionalSecret\x12\x16\n\x06secret\x18\x01\x20\x01\ - (\x0cR\x06secret\"D\n\x14ThpCredentialRequest\x12,\n\x12host_static_pubk\ - ey\x18\x01\x20\x01(\x0cR\x10hostStaticPubkey\"i\n\x15ThpCredentialRespon\ - se\x120\n\x14trezor_static_pubkey\x18\x01\x20\x01(\x0cR\x12trezorStaticP\ - ubkey\x12\x1e\n\ncredential\x18\x02\x20\x01(\x0cR\ncredential\"\x0f\n\rT\ - hpEndRequest\"\x10\n\x0eThpEndResponse\":\n\x15ThpCredentialMetadata\x12\ - \x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostName:\x04\x98\xb2\x19\x01\"\ - \x82\x01\n\x14ThpPairingCredential\x12R\n\rcred_metadata\x18\x01\x20\x01\ - (\x0b2-.hw.trezor.messages.thp.ThpCredentialMetadataR\x0ccredMetadata\ - \x12\x10\n\x03mac\x18\x02\x20\x01(\x0cR\x03mac:\x04\x98\xb2\x19\x01\"\ - \xa8\x01\n\x1eThpAuthenticatedCredentialData\x12,\n\x12host_static_pubke\ - y\x18\x01\x20\x01(\x0cR\x10hostStaticPubkey\x12R\n\rcred_metadata\x18\ - \x02\x20\x01(\x0b2-.hw.trezor.messages.thp.ThpCredentialMetadataR\x0ccre\ - dMetadata:\x04\x98\xb2\x19\x01*\xf6\x06\n\x0eThpMessageType\x12-\n\"ThpM\ - essageType_ThpCreateNewSession\x10\xe8\x07\x1a\x04\x80\xa6\x1d\x01\x12'\ - \n\x1cThpMessageType_ThpNewSession\x10\xe9\x07\x1a\x04\x80\xa6\x1d\x01\ - \x120\n%ThpMessageType_ThpStartPairingRequest\x10\xf0\x07\x1a\x04\x80\ - \xa6\x1d\x01\x128\n-ThpMessageType_ThpPairingPreparationsFinished\x10\ - \xf1\x07\x1a\x04\x80\xa6\x1d\x01\x12.\n#ThpMessageType_ThpCredentialRequ\ - est\x10\xf2\x07\x1a\x04\x80\xa6\x1d\x01\x12/\n$ThpMessageType_ThpCredent\ - ialResponse\x10\xf3\x07\x1a\x04\x80\xa6\x1d\x01\x12'\n\x1cThpMessageType\ - _ThpEndRequest\x10\xf4\x07\x1a\x04\x80\xa6\x1d\x01\x12(\n\x1dThpMessageT\ - ype_ThpEndResponse\x10\xf5\x07\x1a\x04\x80\xa6\x1d\x01\x120\n%ThpMessage\ - Type_ThpCodeEntryCommitment\x10\xf8\x07\x1a\x04\x80\xa6\x1d\x01\x12/\n$T\ - hpMessageType_ThpCodeEntryChallenge\x10\xf9\x07\x1a\x04\x80\xa6\x1d\x01\ - \x12/\n$ThpMessageType_ThpCodeEntryCpaceHost\x10\xfa\x07\x1a\x04\x80\xa6\ - \x1d\x01\x121\n&ThpMessageType_ThpCodeEntryCpaceTrezor\x10\xfb\x07\x1a\ - \x04\x80\xa6\x1d\x01\x12)\n\x1eThpMessageType_ThpCodeEntryTag\x10\xfc\ - \x07\x1a\x04\x80\xa6\x1d\x01\x12,\n!ThpMessageType_ThpCodeEntrySecret\ - \x10\xfd\x07\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1bThpMessageType_ThpQrCodeT\ - ag\x10\x80\x08\x1a\x04\x80\xa6\x1d\x01\x12)\n\x1eThpMessageType_ThpQrCod\ - eSecret\x10\x81\x08\x1a\x04\x80\xa6\x1d\x01\x121\n&ThpMessageType_ThpNfc\ - UnidirectionalTag\x10\x88\x08\x1a\x04\x80\xa6\x1d\x01\x124\n)ThpMessageT\ - ype_ThpNfcUnidirectionalSecret\x10\x89\x08\x1a\x04\x80\xa6\x1d\x01\"\x05\ - \x08\0\x10\xe7\x07\"\t\x08\xcc\x08\x10\xff\xff\xff\xff\x07*S\n\x10ThpPai\ - ringMethod\x12\x0c\n\x08NoMethod\x10\x01\x12\r\n\tCodeEntry\x10\x02\x12\ - \n\n\x06QrCode\x10\x03\x12\x16\n\x12NFC_Unidirectional\x10\x04B;\n#com.s\ - atoshilabs.trezor.lib.protobufB\x10TrezorMessageThp\x80\xa6\x1d\x01\ + (\x0e2(.hw.trezor.messages.thp.ThpPairingMethodR\x0epairingMethods\"y\n\ + \x13ThpCreateNewSession\x12\x1e\n\npassphrase\x18\x01\x20\x01(\tR\npassp\ + hrase\x12\x1b\n\ton_device\x18\x02\x20\x01(\x08R\x08onDevice\x12%\n\x0ed\ + erive_cardano\x18\x03\x20\x01(\x08R\rderiveCardano\"5\n\rThpNewSession\ + \x12$\n\x0enew_session_id\x18\x01\x20\x01(\rR\x0cnewSessionId\"5\n\x16Th\ + pStartPairingRequest\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostNam\ + e\"\x20\n\x1eThpPairingPreparationsFinished\"8\n\x16ThpCodeEntryCommitme\ + nt\x12\x1e\n\ncommitment\x18\x01\x20\x01(\x0cR\ncommitment\"5\n\x15ThpCo\ + deEntryChallenge\x12\x1c\n\tchallenge\x18\x01\x20\x01(\x0cR\tchallenge\"\ + J\n\x15ThpCodeEntryCpaceHost\x121\n\x15cpace_host_public_key\x18\x01\x20\ + \x01(\x0cR\x12cpaceHostPublicKey\"P\n\x17ThpCodeEntryCpaceTrezor\x125\n\ + \x17cpace_trezor_public_key\x18\x01\x20\x01(\x0cR\x14cpaceTrezorPublicKe\ + y\"#\n\x0fThpCodeEntryTag\x12\x10\n\x03tag\x18\x02\x20\x01(\x0cR\x03tag\ + \",\n\x12ThpCodeEntrySecret\x12\x16\n\x06secret\x18\x01\x20\x01(\x0cR\ + \x06secret\"\x20\n\x0cThpQrCodeTag\x12\x10\n\x03tag\x18\x01\x20\x01(\x0c\ + R\x03tag\")\n\x0fThpQrCodeSecret\x12\x16\n\x06secret\x18\x01\x20\x01(\ + \x0cR\x06secret\"+\n\x17ThpNfcUnidirectionalTag\x12\x10\n\x03tag\x18\x01\ + \x20\x01(\x0cR\x03tag\"4\n\x1aThpNfcUnidirectionalSecret\x12\x16\n\x06se\ + cret\x18\x01\x20\x01(\x0cR\x06secret\"D\n\x14ThpCredentialRequest\x12,\n\ + \x12host_static_pubkey\x18\x01\x20\x01(\x0cR\x10hostStaticPubkey\"i\n\ + \x15ThpCredentialResponse\x120\n\x14trezor_static_pubkey\x18\x01\x20\x01\ + (\x0cR\x12trezorStaticPubkey\x12\x1e\n\ncredential\x18\x02\x20\x01(\x0cR\ + \ncredential\"\x0f\n\rThpEndRequest\"\x10\n\x0eThpEndResponse\":\n\x15Th\ + pCredentialMetadata\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostName\ + :\x04\x98\xb2\x19\x01\"\x82\x01\n\x14ThpPairingCredential\x12R\n\rcred_m\ + etadata\x18\x01\x20\x01(\x0b2-.hw.trezor.messages.thp.ThpCredentialMetad\ + ataR\x0ccredMetadata\x12\x10\n\x03mac\x18\x02\x20\x01(\x0cR\x03mac:\x04\ + \x98\xb2\x19\x01\"\xa8\x01\n\x1eThpAuthenticatedCredentialData\x12,\n\ + \x12host_static_pubkey\x18\x01\x20\x01(\x0cR\x10hostStaticPubkey\x12R\n\ + \rcred_metadata\x18\x02\x20\x01(\x0b2-.hw.trezor.messages.thp.ThpCredent\ + ialMetadataR\x0ccredMetadata:\x04\x98\xb2\x19\x01*\xf6\x06\n\x0eThpMessa\ + geType\x12-\n\"ThpMessageType_ThpCreateNewSession\x10\xe8\x07\x1a\x04\ + \x80\xa6\x1d\x01\x12'\n\x1cThpMessageType_ThpNewSession\x10\xe9\x07\x1a\ + \x04\x80\xa6\x1d\x01\x120\n%ThpMessageType_ThpStartPairingRequest\x10\ + \xf0\x07\x1a\x04\x80\xa6\x1d\x01\x128\n-ThpMessageType_ThpPairingPrepara\ + tionsFinished\x10\xf1\x07\x1a\x04\x80\xa6\x1d\x01\x12.\n#ThpMessageType_\ + ThpCredentialRequest\x10\xf2\x07\x1a\x04\x80\xa6\x1d\x01\x12/\n$ThpMessa\ + geType_ThpCredentialResponse\x10\xf3\x07\x1a\x04\x80\xa6\x1d\x01\x12'\n\ + \x1cThpMessageType_ThpEndRequest\x10\xf4\x07\x1a\x04\x80\xa6\x1d\x01\x12\ + (\n\x1dThpMessageType_ThpEndResponse\x10\xf5\x07\x1a\x04\x80\xa6\x1d\x01\ + \x120\n%ThpMessageType_ThpCodeEntryCommitment\x10\xf8\x07\x1a\x04\x80\ + \xa6\x1d\x01\x12/\n$ThpMessageType_ThpCodeEntryChallenge\x10\xf9\x07\x1a\ + \x04\x80\xa6\x1d\x01\x12/\n$ThpMessageType_ThpCodeEntryCpaceHost\x10\xfa\ + \x07\x1a\x04\x80\xa6\x1d\x01\x121\n&ThpMessageType_ThpCodeEntryCpaceTrez\ + or\x10\xfb\x07\x1a\x04\x80\xa6\x1d\x01\x12)\n\x1eThpMessageType_ThpCodeE\ + ntryTag\x10\xfc\x07\x1a\x04\x80\xa6\x1d\x01\x12,\n!ThpMessageType_ThpCod\ + eEntrySecret\x10\xfd\x07\x1a\x04\x80\xa6\x1d\x01\x12&\n\x1bThpMessageTyp\ + e_ThpQrCodeTag\x10\x80\x08\x1a\x04\x80\xa6\x1d\x01\x12)\n\x1eThpMessageT\ + ype_ThpQrCodeSecret\x10\x81\x08\x1a\x04\x80\xa6\x1d\x01\x121\n&ThpMessag\ + eType_ThpNfcUnidirectionalTag\x10\x88\x08\x1a\x04\x80\xa6\x1d\x01\x124\n\ + )ThpMessageType_ThpNfcUnidirectionalSecret\x10\x89\x08\x1a\x04\x80\xa6\ + \x1d\x01\"\x05\x08\0\x10\xe7\x07\"\t\x08\xcc\x08\x10\xff\xff\xff\xff\x07\ + *S\n\x10ThpPairingMethod\x12\x0c\n\x08NoMethod\x10\x01\x12\r\n\tCodeEntr\ + y\x10\x02\x12\n\n\x06QrCode\x10\x03\x12\x16\n\x12NFC_Unidirectional\x10\ + \x04B;\n#com.satoshilabs.trezor.lib.protobufB\x10TrezorMessageThp\x80\ + \xa6\x1d\x01\ "; /// `FileDescriptorProto` object which was a source for this generated file