feat(core): extend THP credentials with app_name
What changed, and why it matters
This commit adds a new optional 'app_name' field to Trezor's Trusted Host Pairing (THP) credentials. It lets the device display both the application name and the host/browser name during pairing and connection prompts, making it clearer to users which app is requesting access. There is no direct evidence in the commit that this fixes an active security vulnerability; it reads as a user-experience and metadata improvement.
Treat as a routine feature commit rather than a security patch. If reviewing for security, verify that the relaxed host_name/app_name validation does not allow ambiguous or misleading display strings that could confuse users during pairing approval, and confirm that app_name is sanitized before being shown on the device screen.
Security signals we found
New optional string field added to pairing credential metadata
UI confirmation prompts now include both app_name and host_name
Validation relaxed: credential phase now accepts either host_name or app_name instead of requiring host_name
Pairing-request approval message moved from dialog method to caller
No changelog entry ([no changelog])
Evidence from the diff
The change extends protobuf messages ThpPairingRequest and ThpCredentialMetadata with an optional app_name string, regenerates Python/Rust bindings, and updates the core firmware to store, propagate, and display app_name alongside host_name. UI helper _app_on_host formats strings such as ‘App on Browser’. The validation in handle_credential_phase was loosened from requiring host_name to requiring either host_name or app_name. A ThpPairingRequestApproved message is now sent immediately after the pairing dialog rather than from inside the dialog method. No cryptographic, authorization, or parsing hardening is visible.
Changed components
common/protob/messages-thp.protocore/src/apps/base.pycore/src/apps/thp/pairing.pycore/src/trezor/messages.pycore/src/trezor/wire/thp/pairing_context.pycore/src/trezor/wire/thp/ui.pypython/src/trezorlib/messages.pyrust/trezor-client/src/protos/generated/messages_thp.rsInspect captured patch +216 / −94
diff --git a/common/protob/messages-thp.proto b/common/protob/messages-thp.proto
index c97799b5..f1d7c9bf 100644
--- a/common/protob/messages-thp.proto
+++ b/common/protob/messages-thp.proto
@@ -98,7 +98,8 @@ message ThpCreateNewSession {
* @next ThpPairingRequestApproved
*/
message ThpPairingRequest {
- optional string host_name = 1; // Human-readable host name
+ optional string host_name = 1; // Human-readable host name (browser name for web apps)
+ optional string app_name = 2; // Human-readable application name
}
/**
@@ -245,8 +246,9 @@ message ThpEndResponse {}
*/
message ThpCredentialMetadata {
option (internal_only) = true;
- optional string host_name = 1; // Human-readable host name
+ optional string host_name = 1; // Human-readable host name (browser name for web apps)
optional bool autoconnect = 2; // Whether host is allowed to autoconnect without user confirmation
+ optional string app_name = 3; // Human-readable application name
}
/**
diff --git a/core/src/apps/base.py b/core/src/apps/base.py
index 76935578..bbe145cc 100644
--- a/core/src/apps/base.py
+++ b/core/src/apps/base.py
@@ -328,13 +328,15 @@ if utils.USE_THP:
assert credential.cred_metadata is not None
cred_metadata = ThpCredentialMetadata(
- host_name=credential.cred_metadata.host_name, autoconnect=autoconnect
+ host_name=credential.cred_metadata.host_name,
+ app_name=credential.cred_metadata.app_name,
+ autoconnect=autoconnect,
)
if autoconnect:
from trezor.wire.thp import ui
await ui.show_autoconnect_credential_confirmation_screen(
- cred_metadata.host_name
+ cred_metadata.host_name, cred_metadata.app_name
)
new_cred = issue_credential(
host_static_public_key=message.host_static_public_key,
diff --git a/core/src/apps/thp/pairing.py b/core/src/apps/thp/pairing.py
index 2b1cdb51..a9c94559 100644
--- a/core/src/apps/thp/pairing.py
+++ b/core/src/apps/thp/pairing.py
@@ -21,6 +21,7 @@ from trezor.messages import (
ThpNfcTagTrezor,
ThpPairingPreparationsFinished,
ThpPairingRequest,
+ ThpPairingRequestApproved,
ThpQrCodeSecret,
ThpQrCodeTag,
ThpSelectMethod,
@@ -105,14 +106,17 @@ async def handle_pairing_request(
if not ThpPairingRequest.is_type_of(message):
raise UnexpectedMessage("Unexpected message")
+ # TODO: make app_name required eventually
if not message.host_name:
raise DataError("Missing host_name.")
ctx.host_name = message.host_name
+ ctx.app_name = message.app_name
if __debug__ and not ctx.channel_ctx.should_show_pairing_dialog:
await _skip_pairing_dialog(ctx)
else:
await ctx.show_pairing_dialog()
+ await ctx.write(ThpPairingRequestApproved())
assert ThpSelectMethod.MESSAGE_WIRE_TYPE is not None
select_method_msg = await ctx.read(
[
@@ -186,8 +190,9 @@ async def handle_credential_phase(
autoconnect = ctx.channel_ctx.is_channel_to_replace()
if credential.cred_metadata is not None:
ctx.host_name = credential.cred_metadata.host_name
- if ctx.host_name is None:
- raise DataError("Missing hostname in credential")
+ ctx.app_name = credential.cred_metadata.app_name
+ if ctx.host_name is None and ctx.app_name is None:
+ raise DataError("Missing host/app name in credential")
if show_connection_dialog and not autoconnect:
await ctx.show_connection_dialog()
@@ -425,6 +430,7 @@ async def _handle_credential_request(
trezor_static_public_key = crypto.get_trezor_static_public_key()
credential_metadata = ThpCredentialMetadata(
host_name=ctx.host_name,
+ app_name=ctx.app_name,
autoconnect=autoconnect,
)
credential = issue_credential(message.host_static_public_key, credential_metadata)
diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py
index f7706e41..61bd3959 100644
--- a/core/src/trezor/messages.py
+++ b/core/src/trezor/messages.py
@@ -6272,11 +6272,13 @@ if TYPE_CHECKING:
class ThpPairingRequest(protobuf.MessageType):
host_name: "str | None"
+ app_name: "str | None"
def __init__(
self,
*,
host_name: "str | None" = None,
+ app_name: "str | None" = None,
) -> None:
pass
@@ -6487,12 +6489,14 @@ if TYPE_CHECKING:
class ThpCredentialMetadata(protobuf.MessageType):
host_name: "str | None"
autoconnect: "bool | None"
+ app_name: "str | None"
def __init__(
self,
*,
host_name: "str | None" = None,
autoconnect: "bool | None" = None,
+ app_name: "str | None" = None,
) -> None:
pass
diff --git a/core/src/trezor/wire/thp/pairing_context.py b/core/src/trezor/wire/thp/pairing_context.py
index b9a6ffc6..1f0c4a93 100644
--- a/core/src/trezor/wire/thp/pairing_context.py
+++ b/core/src/trezor/wire/thp/pairing_context.py
@@ -44,6 +44,7 @@ class PairingContext(Context):
self.cpace: Cpace
self.host_name: str | None
+ self.app_name: str | None
async def handle(self) -> None:
next_message: Message | None = None
@@ -136,33 +137,23 @@ class PairingContext(Context):
raise DataError("Selected pairing method is not supported")
self.selected_method = selected_method
- async def show_pairing_dialog(self, device_name: str | None = None) -> None:
- from trezor.messages import ThpPairingRequestApproved
+ async def show_pairing_dialog(self) -> None:
from trezor.ui.layouts import confirm_action
- if not device_name:
- action_string = f"Allow {self.host_name} to pair with this Trezor?"
- else:
- action_string = (
- f"Allow {self.host_name} on {device_name} to pair with this Trezor?"
- )
-
+ subject = ui._app_on_host(self.app_name, self.host_name)
+ action_string = f"Allow {subject} to pair with this Trezor?"
await confirm_action(
br_name="thp_pairing_request",
title="Before you continue",
action=action_string,
)
- await self.write(ThpPairingRequestApproved())
-
- async def show_connection_dialog(self, device_name: str | None = None) -> None:
- await ui.show_connection_dialog(self.host_name, device_name)
+ async def show_connection_dialog(self) -> None:
+ await ui.show_connection_dialog(self.host_name, self.app_name)
- async def show_autoconnect_credential_confirmation_screen(
- self, device_name: str | None = None
- ) -> None:
+ async def show_autoconnect_credential_confirmation_screen(self) -> None:
await ui.show_autoconnect_credential_confirmation_screen(
- self.host_name, device_name
+ self.host_name, self.app_name
)
async def show_pairing_method_screen(
diff --git a/core/src/trezor/wire/thp/ui.py b/core/src/trezor/wire/thp/ui.py
index 029eab2b..31a93c32 100644
--- a/core/src/trezor/wire/thp/ui.py
+++ b/core/src/trezor/wire/thp/ui.py
@@ -4,16 +4,23 @@ if TYPE_CHECKING:
from trezorui_api import UiResult
+def _app_on_host(app_name: str | None, host_name: str | None) -> str:
+ if app_name and host_name:
+ return f"{app_name} on {host_name}"
+ elif not app_name and not host_name:
+ return "(unknown)"
+ else:
+ return (app_name or "") + (host_name or "")
+
+
async def show_autoconnect_credential_confirmation_screen(
host_name: str | None,
- device_name: str | None = None,
+ app_name: str | None,
) -> None:
from trezor.ui.layouts import confirm_action
- if not device_name:
- action_string = f"Allow {host_name} to connect automatically to this Trezor?"
- else:
- action_string = f"Allow {host_name} on {device_name} to connect automatically to this Trezor?"
+ subject = _app_on_host(app_name, host_name)
+ action_string = f"Allow {subject} to connect automatically to this Trezor?"
await confirm_action(
br_name="thp_autoconnect_credential_request",
@@ -22,17 +29,11 @@ async def show_autoconnect_credential_confirmation_screen(
)
-async def show_connection_dialog(
- host_name: str | None, device_name: str | None = None
-) -> None:
+async def show_connection_dialog(host_name: str | None, app_name: str | None) -> None:
from trezor.ui.layouts import confirm_action
- if not device_name:
- action_string = f"Allow {host_name} to connect with this Trezor?"
- else:
- action_string = (
- f"Allow {host_name} on {device_name} to connect with this Trezor?"
- )
+ subject = _app_on_host(app_name, host_name)
+ action_string = f"Allow {subject} to connect with this Trezor?"
await confirm_action(
br_name="thp_connection_request",
diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py
index 7b63c43c..a261ecff 100644
--- a/python/src/trezorlib/messages.py
+++ b/python/src/trezorlib/messages.py
@@ -8017,14 +8017,17 @@ class ThpPairingRequest(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 1008
FIELDS = {
1: protobuf.Field("host_name", "string", repeated=False, required=False, default=None),
+ 2: protobuf.Field("app_name", "string", repeated=False, required=False, default=None),
}
def __init__(
self,
*,
host_name: Optional["str"] = None,
+ app_name: Optional["str"] = None,
) -> None:
self.host_name = host_name
+ self.app_name = app_name
class ThpPairingRequestApproved(protobuf.MessageType):
@@ -8228,6 +8231,7 @@ class ThpCredentialMetadata(protobuf.MessageType):
FIELDS = {
1: protobuf.Field("host_name", "string", repeated=False, required=False, default=None),
2: protobuf.Field("autoconnect", "bool", repeated=False, required=False, default=None),
+ 3: protobuf.Field("app_name", "string", repeated=False, required=False, default=None),
}
def __init__(
@@ -8235,9 +8239,11 @@ class ThpCredentialMetadata(protobuf.MessageType):
*,
host_name: Optional["str"] = None,
autoconnect: Optional["bool"] = None,
+ app_name: Optional["str"] = None,
) -> None:
self.host_name = host_name
self.autoconnect = autoconnect
+ self.app_name = app_name
class ThpPairingCredential(protobuf.MessageType):
diff --git a/rust/trezor-client/src/protos/generated/messages_thp.rs b/rust/trezor-client/src/protos/generated/messages_thp.rs
index 33424a23..7d0b5b92 100644
--- a/rust/trezor-client/src/protos/generated/messages_thp.rs
+++ b/rust/trezor-client/src/protos/generated/messages_thp.rs
@@ -719,6 +719,8 @@ pub struct ThpPairingRequest {
// message fields
// @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpPairingRequest.host_name)
pub host_name: ::std::option::Option<::std::string::String>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpPairingRequest.app_name)
+ pub app_name: ::std::option::Option<::std::string::String>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpPairingRequest.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@@ -771,14 +773,55 @@ impl ThpPairingRequest {
self.host_name.take().unwrap_or_else(|| ::std::string::String::new())
}
+ // optional string app_name = 2;
+
+ pub fn app_name(&self) -> &str {
+ match self.app_name.as_ref() {
+ Some(v) => v,
+ None => "",
+ }
+ }
+
+ pub fn clear_app_name(&mut self) {
+ self.app_name = ::std::option::Option::None;
+ }
+
+ pub fn has_app_name(&self) -> bool {
+ self.app_name.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_app_name(&mut self, v: ::std::string::String) {
+ self.app_name = ::std::option::Option::Some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_app_name(&mut self) -> &mut ::std::string::String {
+ if self.app_name.is_none() {
+ self.app_name = ::std::option::Option::Some(::std::string::String::new());
+ }
+ self.app_name.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_app_name(&mut self) -> ::std::string::String {
+ self.app_name.take().unwrap_or_else(|| ::std::string::String::new())
+ }
+
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
- let mut fields = ::std::vec::Vec::with_capacity(1);
+ let mut fields = ::std::vec::Vec::with_capacity(2);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"host_name",
|m: &ThpPairingRequest| { &m.host_name },
|m: &mut ThpPairingRequest| { &mut m.host_name },
));
+ fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+ "app_name",
+ |m: &ThpPairingRequest| { &m.app_name },
+ |m: &mut ThpPairingRequest| { &mut m.app_name },
+ ));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpPairingRequest>(
"ThpPairingRequest",
fields,
@@ -800,6 +843,9 @@ impl ::protobuf::Message for ThpPairingRequest {
10 => {
self.host_name = ::std::option::Option::Some(is.read_string()?);
},
+ 18 => {
+ self.app_name = ::std::option::Option::Some(is.read_string()?);
+ },
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@@ -815,6 +861,9 @@ impl ::protobuf::Message for ThpPairingRequest {
if let Some(v) = self.host_name.as_ref() {
my_size += ::protobuf::rt::string_size(1, &v);
}
+ if let Some(v) = self.app_name.as_ref() {
+ my_size += ::protobuf::rt::string_size(2, &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
@@ -824,6 +873,9 @@ impl ::protobuf::Message for ThpPairingRequest {
if let Some(v) = self.host_name.as_ref() {
os.write_string(1, v)?;
}
+ if let Some(v) = self.app_name.as_ref() {
+ os.write_string(2, v)?;
+ }
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@@ -842,12 +894,14 @@ impl ::protobuf::Message for ThpPairingRequest {
fn clear(&mut self) {
self.host_name = ::std::option::Option::None;
+ self.app_name = ::std::option::Option::None;
self.special_fields.clear();
}
fn default_instance() -> &'static ThpPairingRequest {
static instance: ThpPairingRequest = ThpPairingRequest {
host_name: ::std::option::Option::None,
+ app_name: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@@ -3414,6 +3468,8 @@ pub struct ThpCredentialMetadata {
pub host_name: ::std::option::Option<::std::string::String>,
// @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCredentialMetadata.autoconnect)
pub autoconnect: ::std::option::Option<bool>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCredentialMetadata.app_name)
+ pub app_name: ::std::option::Option<::std::string::String>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpCredentialMetadata.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@@ -3485,8 +3541,44 @@ impl ThpCredentialMetadata {
self.autoconnect = ::std::option::Option::Some(v);
}
+ // optional string app_name = 3;
+
+ pub fn app_name(&self) -> &str {
+ match self.app_name.as_ref() {
+ Some(v) => v,
+ None => "",
+ }
+ }
+
+ pub fn clear_app_name(&mut self) {
+ self.app_name = ::std::option::Option::None;
+ }
+
+ pub fn has_app_name(&self) -> bool {
+ self.app_name.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_app_name(&mut self, v: ::std::string::String) {
+ self.app_name = ::std::option::Option::Some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_app_name(&mut self) -> &mut ::std::string::String {
+ if self.app_name.is_none() {
+ self.app_name = ::std::option::Option::Some(::std::string::String::new());
+ }
+ self.app_name.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_app_name(&mut self) -> ::std::string::String {
+ self.app_name.take().unwrap_or_else(|| ::std::string::String::new())
+ }
+
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
- let mut fields = ::std::vec::Vec::with_capacity(2);
+ 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::<_, _>(
"host_name",
@@ -3498,6 +3590,11 @@ impl ThpCredentialMetadata {
|m: &ThpCredentialMetadata| { &m.autoconnect },
|m: &mut ThpCredentialMetadata| { &mut m.autoconnect },
));
+ fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+ "app_name",
+ |m: &ThpCredentialMetadata| { &m.app_name },
+ |m: &mut ThpCredentialMetadata| { &mut m.app_name },
+ ));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<ThpCredentialMetadata>(
"ThpCredentialMetadata",
fields,
@@ -3522,6 +3619,9 @@ impl ::protobuf::Message for ThpCredentialMetadata {
16 => {
self.autoconnect = ::std::option::Option::Some(is.read_bool()?);
},
+ 26 => {
+ self.app_name = ::std::option::Option::Some(is.read_string()?);
+ },
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@@ -3540,6 +3640,9 @@ impl ::protobuf::Message for ThpCredentialMetadata {
if let Some(v) = self.autoconnect {
my_size += 1 + 1;
}
+ if let Some(v) = self.app_name.as_ref() {
+ my_size += ::protobuf::rt::string_size(3, &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
@@ -3552,6 +3655,9 @@ impl ::protobuf::Message for ThpCredentialMetadata {
if let Some(v) = self.autoconnect {
os.write_bool(2, v)?;
}
+ if let Some(v) = self.app_name.as_ref() {
+ os.write_string(3, v)?;
+ }
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@@ -3571,6 +3677,7 @@ impl ::protobuf::Message for ThpCredentialMetadata {
fn clear(&mut self) {
self.host_name = ::std::option::Option::None;
self.autoconnect = ::std::option::Option::None;
+ self.app_name = ::std::option::Option::None;
self.special_fields.clear();
}
@@ -3578,6 +3685,7 @@ impl ::protobuf::Message for ThpCredentialMetadata {
static instance: ThpCredentialMetadata = ThpCredentialMetadata {
host_name: ::std::option::Option::None,
autoconnect: ::std::option::Option::None,
+ app_name: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@@ -4241,61 +4349,63 @@ static file_descriptor_proto_data: &'static [u8] = b"\
ial\x18\x01\x20\x01(\x0cR\x15hostPairingCredential\"\x87\x01\n\x13ThpCre\
ateNewSession\x12\x1e\n\npassphrase\x18\x01\x20\x01(\tR\npassphrase\x12\
\"\n\ton_device\x18\x02\x20\x01(\x08:\x05falseR\x08onDevice\x12,\n\x0ede\
- rive_cardano\x18\x03\x20\x01(\x08:\x05falseR\rderiveCardano\"0\n\x11ThpP\
- airingRequest\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostName\"\x1b\
- \n\x19ThpPairingRequestApproved\"s\n\x0fThpSelectMethod\x12`\n\x17select\
- ed_pairing_method\x18\x01\x20\x02(\x0e2(.hw.trezor.messages.thp.ThpPairi\
- ngMethodR\x15selectedPairingMethod\"\x20\n\x1eThpPairingPreparationsFini\
- shed\"8\n\x16ThpCodeEntryCommitment\x12\x1e\n\ncommitment\x18\x01\x20\
- \x02(\x0cR\ncommitment\"5\n\x15ThpCodeEntryChallenge\x12\x1c\n\tchalleng\
- e\x18\x01\x20\x02(\x0cR\tchallenge\"P\n\x17ThpCodeEntryCpaceTrezor\x125\
- \n\x17cpace_trezor_public_key\x18\x01\x20\x02(\x0cR\x14cpaceTrezorPublic\
- Key\"_\n\x18ThpCodeEntryCpaceHostTag\x121\n\x15cpace_host_public_key\x18\
- \x01\x20\x02(\x0cR\x12cpaceHostPublicKey\x12\x10\n\x03tag\x18\x02\x20\
- \x02(\x0cR\x03tag\",\n\x12ThpCodeEntrySecret\x12\x16\n\x06secret\x18\x01\
- \x20\x02(\x0cR\x06secret\"\x20\n\x0cThpQrCodeTag\x12\x10\n\x03tag\x18\
- \x01\x20\x02(\x0cR\x03tag\")\n\x0fThpQrCodeSecret\x12\x16\n\x06secret\
- \x18\x01\x20\x02(\x0cR\x06secret\"!\n\rThpNfcTagHost\x12\x10\n\x03tag\
- \x18\x01\x20\x02(\x0cR\x03tag\"#\n\x0fThpNfcTagTrezor\x12\x10\n\x03tag\
- \x18\x01\x20\x02(\x0cR\x03tag\"\x94\x01\n\x14ThpCredentialRequest\x123\n\
- \x16host_static_public_key\x18\x01\x20\x02(\x0cR\x13hostStaticPublicKey\
- \x12'\n\x0bautoconnect\x18\x02\x20\x01(\x08:\x05falseR\x0bautoconnect\
- \x12\x1e\n\ncredential\x18\x03\x20\x01(\x0cR\ncredential\"p\n\x15ThpCred\
- entialResponse\x127\n\x18trezor_static_public_key\x18\x01\x20\x02(\x0cR\
- \x15trezorStaticPublicKey\x12\x1e\n\ncredential\x18\x02\x20\x02(\x0cR\nc\
- redential\"\x0f\n\rThpEndRequest\"\x10\n\x0eThpEndResponse\"\\\n\x15ThpC\
- redentialMetadata\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostName\
- \x12\x20\n\x0bautoconnect\x18\x02\x20\x01(\x08R\x0bautoconnect:\x04\x98\
- \xb2\x19\x01\"\x82\x01\n\x14ThpPairingCredential\x12R\n\rcred_metadata\
- \x18\x01\x20\x02(\x0b2-.hw.trezor.messages.thp.ThpCredentialMetadataR\
- \x0ccredMetadata\x12\x10\n\x03mac\x18\x02\x20\x02(\x0cR\x03mac:\x04\x98\
- \xb2\x19\x01\"\xaf\x01\n\x1eThpAuthenticatedCredentialData\x123\n\x16hos\
- t_static_public_key\x18\x01\x20\x02(\x0cR\x13hostStaticPublicKey\x12R\n\
- \rcred_metadata\x18\x02\x20\x02(\x0b2-.hw.trezor.messages.thp.ThpCredent\
- ialMetadataR\x0ccredMetadata:\x04\x98\xb2\x19\x01*\xfb\x06\n\x0eThpMessa\
- geType\x12\x19\n\x15ThpMessageType_Cancel\x10\x14\x12\x20\n\x1cThpMessag\
- eType_ButtonRequest\x10\x1a\x12\x1c\n\x18ThpMessageType_ButtonAck\x10\
- \x1b\x12%\n\x20ThpMessageType_ThpPairingRequest\x10\xf0\x07\x12-\n(ThpMe\
- ssageType_ThpPairingRequestApproved\x10\xf1\x07\x12#\n\x1eThpMessageType\
- _ThpSelectMethod\x10\xf2\x07\x122\n-ThpMessageType_ThpPairingPreparation\
- sFinished\x10\xf3\x07\x12(\n#ThpMessageType_ThpCredentialRequest\x10\xf8\
- \x07\x12)\n$ThpMessageType_ThpCredentialResponse\x10\xf9\x07\x12!\n\x1cT\
- hpMessageType_ThpEndRequest\x10\xfa\x07\x12\"\n\x1dThpMessageType_ThpEnd\
- Response\x10\xfb\x07\x12*\n%ThpMessageType_ThpCodeEntryCommitment\x10\
- \x80\x08\x12)\n$ThpMessageType_ThpCodeEntryChallenge\x10\x81\x08\x12+\n&\
- ThpMessageType_ThpCodeEntryCpaceTrezor\x10\x82\x08\x12,\n'ThpMessageType\
- _ThpCodeEntryCpaceHostTag\x10\x83\x08\x12&\n!ThpMessageType_ThpCodeEntry\
- Secret\x10\x84\x08\x12\x20\n\x1bThpMessageType_ThpQrCodeTag\x10\x88\x08\
- \x12#\n\x1eThpMessageType_ThpQrCodeSecret\x10\x89\x08\x12!\n\x1cThpMessa\
- geType_ThpNfcTagHost\x10\x90\x08\x12#\n\x1eThpMessageType_ThpNfcTagTrezo\
- r\x10\x91\x08\x1a\x04\xd0\xf3\x18\x01\"\x04\x08\0\x10\x13\"\x04\x08\x15\
- \x10\x19\"\x05\x08\x1c\x10\xe7\x07\"\x06\x08\xe8\x07\x10\xe8\x07\"\x06\
- \x08\xe9\x07\x10\xef\x07\"\x06\x08\xf4\x07\x10\xf7\x07\"\x06\x08\xfc\x07\
- \x10\xff\x07\"\x06\x08\x85\x08\x10\x87\x08\"\x06\x08\x8a\x08\x10\x8f\x08\
- \"\x06\x08\x92\x08\x10\xcb\x08\"\t\x08\xcc\x08\x10\xff\xff\xff\xff\x07*G\
- \n\x10ThpPairingMethod\x12\x0f\n\x0bSkipPairing\x10\x01\x12\r\n\tCodeEnt\
- ry\x10\x02\x12\n\n\x06QrCode\x10\x03\x12\x07\n\x03NFC\x10\x04B;\n#com.sa\
- toshilabs.trezor.lib.protobufB\x10TrezorMessageThp\x80\xa6\x1d\x01\
+ rive_cardano\x18\x03\x20\x01(\x08:\x05falseR\rderiveCardano\"K\n\x11ThpP\
+ airingRequest\x12\x1b\n\thost_name\x18\x01\x20\x01(\tR\x08hostName\x12\
+ \x19\n\x08app_name\x18\x02\x20\x01(\tR\x07appName\"\x1b\n\x19ThpPairingR\
+ equestApproved\"s\n\x0fThpSelectMethod\x12`\n\x17selected_pairing_method\
+ \x18\x01\x20\x02(\x0e2(.hw.trezor.messages.thp.ThpPairingMethodR\x15sele\
+ ctedPairingMethod\"\x20\n\x1eThpPairingPreparationsFinished\"8\n\x16ThpC\
+ odeEntryCommitment\x12\x1e\n\ncommitment\x18\x01\x20\x02(\x0cR\ncommitme\
+ nt\"5\n\x15ThpCodeEntryChallenge\x12\x1c\n\tchallenge\x18\x01\x20\x02(\
+ \x0cR\tchallenge\"P\n\x17ThpCodeEntryCpaceTrezor\x125\n\x17cpace_trezor_\
+ public_key\x18\x01\x20\x02(\x0cR\x14cpaceTrezorPublicKey\"_\n\x18ThpCode\
+ EntryCpaceHostTag\x121\n\x15cpace_host_public_key\x18\x01\x20\x02(\x0cR\
+ \x12cpaceHostPublicKey\x12\x10\n\x03tag\x18\x02\x20\x02(\x0cR\x03tag\",\
+ \n\x12ThpCodeEntrySecret\x12\x16\n\x06secret\x18\x01\x20\x02(\x0cR\x06se\
+ cret\"\x20\n\x0cThpQrCodeTag\x12\x10\n\x03tag\x18\x01\x20\x02(\x0cR\x03t\
+ ag\")\n\x0fThpQrCodeSecret\x12\x16\n\x06secret\x18\x01\x20\x02(\x0cR\x06\
+ secret\"!\n\rThpNfcTagHost\x12\x10\n\x03tag\x18\x01\x20\x02(\x0cR\x03tag\
+ \"#\n\x0fThpNfcTagTrezor\x12\x10\n\x03tag\x18\x01\x20\x02(\x0cR\x03tag\"\
+ \x94\x01\n\x14ThpCredentialRequest\x123\n\x16host_static_public_key\x18\
+ \x01\x20\x02(\x0cR\x13hostStaticPublicKey\x12'\n\x0bautoconnect\x18\x02\
+ \x20\x01(\x08:\x05falseR\x0bautoconnect\x12\x1e\n\ncredential\x18\x03\
+ \x20\x01(\x0cR\ncredential\"p\n\x15ThpCredentialResponse\x127\n\x18trezo\
+ r_static_public_key\x18\x01\x20\x02(\x0cR\x15trezorStaticPublicKey\x12\
+ \x1e\n\ncredential\x18\x02\x20\x02(\x0cR\ncredential\"\x0f\n\rThpEndRequ\
+ est\"\x10\n\x0eThpEndResponse\"w\n\x15ThpCredentialMetadata\x12\x1b\n\th\
+ ost_name\x18\x01\x20\x01(\tR\x08hostName\x12\x20\n\x0bautoconnect\x18\
+ \x02\x20\x01(\x08R\x0bautoconnect\x12\x19\n\x08app_name\x18\x03\x20\x01(\
+ \tR\x07appName:\x04\x98\xb2\x19\x01\"\x82\x01\n\x14ThpPairingCredential\
+ \x12R\n\rcred_metadata\x18\x01\x20\x02(\x0b2-.hw.trezor.messages.thp.Thp\
+ CredentialMetadataR\x0ccredMetadata\x12\x10\n\x03mac\x18\x02\x20\x02(\
+ \x0cR\x03mac:\x04\x98\xb2\x19\x01\"\xaf\x01\n\x1eThpAuthenticatedCredent\
+ ialData\x123\n\x16host_static_public_key\x18\x01\x20\x02(\x0cR\x13hostSt\
+ aticPublicKey\x12R\n\rcred_metadata\x18\x02\x20\x02(\x0b2-.hw.trezor.mes\
+ sages.thp.ThpCredentialMetadataR\x0ccredMetadata:\x04\x98\xb2\x19\x01*\
+ \xfb\x06\n\x0eThpMessageType\x12\x19\n\x15ThpMessageType_Cancel\x10\x14\
+ \x12\x20\n\x1cThpMessageType_ButtonRequest\x10\x1a\x12\x1c\n\x18ThpMessa\
+ geType_ButtonAck\x10\x1b\x12%\n\x20ThpMessageType_ThpPairingRequest\x10\
+ \xf0\x07\x12-\n(ThpMessageType_ThpPairingRequestApproved\x10\xf1\x07\x12\
+ #\n\x1eThpMessageType_ThpSelectMethod\x10\xf2\x07\x122\n-ThpMessageType_\
+ ThpPairingPreparationsFinished\x10\xf3\x07\x12(\n#ThpMessageType_ThpCred\
+ entialRequest\x10\xf8\x07\x12)\n$ThpMessageType_ThpCredentialResponse\
+ \x10\xf9\x07\x12!\n\x1cThpMessageType_ThpEndRequest\x10\xfa\x07\x12\"\n\
+ \x1dThpMessageType_ThpEndResponse\x10\xfb\x07\x12*\n%ThpMessageType_ThpC\
+ odeEntryCommitment\x10\x80\x08\x12)\n$ThpMessageType_ThpCodeEntryChallen\
+ ge\x10\x81\x08\x12+\n&ThpMessageType_ThpCodeEntryCpaceTrezor\x10\x82\x08\
+ \x12,\n'ThpMessageType_ThpCodeEntryCpaceHostTag\x10\x83\x08\x12&\n!ThpMe\
+ ssageType_ThpCodeEntrySecret\x10\x84\x08\x12\x20\n\x1bThpMessageType_Thp\
+ QrCodeTag\x10\x88\x08\x12#\n\x1eThpMessageType_ThpQrCodeSecret\x10\x89\
+ \x08\x12!\n\x1cThpMessageType_ThpNfcTagHost\x10\x90\x08\x12#\n\x1eThpMes\
+ sageType_ThpNfcTagTrezor\x10\x91\x08\x1a\x04\xd0\xf3\x18\x01\"\x04\x08\0\
+ \x10\x13\"\x04\x08\x15\x10\x19\"\x05\x08\x1c\x10\xe7\x07\"\x06\x08\xe8\
+ \x07\x10\xe8\x07\"\x06\x08\xe9\x07\x10\xef\x07\"\x06\x08\xf4\x07\x10\xf7\
+ \x07\"\x06\x08\xfc\x07\x10\xff\x07\"\x06\x08\x85\x08\x10\x87\x08\"\x06\
+ \x08\x8a\x08\x10\x8f\x08\"\x06\x08\x92\x08\x10\xcb\x08\"\t\x08\xcc\x08\
+ \x10\xff\xff\xff\xff\x07*G\n\x10ThpPairingMethod\x12\x0f\n\x0bSkipPairin\
+ g\x10\x01\x12\r\n\tCodeEntry\x10\x02\x12\n\n\x06QrCode\x10\x03\x12\x07\n\
+ \x03NFC\x10\x04B;\n#com.satoshilabs.trezor.lib.protobufB\x10TrezorMessag\
+ eThp\x80\xa6\x1d\x01\
";
/// `FileDescriptorProto` object which was a source for this generated file
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.