diff --git a/common/protob/messages-thp.proto b/common/protob/messages-thp.proto new file mode 100644 index 0000000000..743cf3a1ee --- /dev/null +++ b/common/protob/messages-thp.proto @@ -0,0 +1,39 @@ +syntax = "proto2"; +package hw.trezor.messages.thp; + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorMessageThp"; + +option (include_in_bitcoin_only) = true; + +import "messages.proto"; + +/** + * Only for internal use. + * @embed + */ + message ThpCredentialMetadata { + option (internal_only) = true; + optional string host_name = 1; // Human-readable host name +} + +/** + * Only for internal use. + * @embed + */ + message ThpPairingCredential { + option (internal_only) = true; + optional ThpCredentialMetadata cred_metadata = 1; // Credential metadata + optional bytes mac = 2; // Message authentication code generated by the Trezor +} + +/** + * Only for internal use. + * @embed + */ + message ThpAuthenticatedCredentialData { + option (internal_only) = true; + optional bytes host_static_pubkey = 1; // Host's static public key used in the handshake + optional ThpCredentialMetadata cred_metadata = 2; // Credential metadata +} diff --git a/core/src/all_modules.py b/core/src/all_modules.py index f76f8e7983..00abd550e1 100644 --- a/core/src/all_modules.py +++ b/core/src/all_modules.py @@ -384,6 +384,12 @@ import apps.misc.sign_identity apps.workflow_handlers import apps.workflow_handlers +if utils.USE_THP: + apps.thp + import apps.thp + apps.thp.credential_manager + import apps.thp.credential_manager + if not utils.BITCOIN_ONLY: trezor.enums.BinanceOrderSide import trezor.enums.BinanceOrderSide @@ -787,7 +793,6 @@ if not utils.BITCOIN_ONLY: import apps.zcash.signer apps.zcash.unified_addresses import apps.zcash.unified_addresses - # generate full alphabet a A diff --git a/core/src/apps/thp/__init__.py b/core/src/apps/thp/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core/src/apps/thp/credential_manager.py b/core/src/apps/thp/credential_manager.py new file mode 100644 index 0000000000..73c1d0abcd --- /dev/null +++ b/core/src/apps/thp/credential_manager.py @@ -0,0 +1,90 @@ +from typing import TYPE_CHECKING + +from trezor import protobuf +from trezor.crypto import hmac +from trezor.messages import ( + ThpAuthenticatedCredentialData, + ThpCredentialMetadata, + ThpPairingCredential, +) +from trezor.wire import wrap_protobuf_load + +if TYPE_CHECKING: + from apps.common.paths import Slip21Path + + +def derive_cred_auth_key() -> bytes: + """ + Derive current credential authentication mac-ing key from device secret. + """ + from storage.device import get_cred_auth_key_counter, get_device_secret + + from apps.common.seed import Slip21Node + + # Derive the key using SLIP-21 https://github.com/satoshilabs/slips/blob/master/slip-0021.md, + # the derivation path is m/"Credential authentication key"/(counter 4-byte BE) + + thp_secret = get_device_secret() + label = b"Credential authentication key" + counter = get_cred_auth_key_counter() + path: Slip21Path = [label, counter] + + symmetric_key_node: Slip21Node = Slip21Node(thp_secret) + symmetric_key_node.derive_path(path) + cred_auth_key = symmetric_key_node.key() + + return cred_auth_key + + +def invalidate_cred_auth_key() -> None: + from storage.device import increment_cred_auth_key_counter + + increment_cred_auth_key_counter() + + +def issue_credential( + host_static_pubkey: bytes, + credential_metadata: ThpCredentialMetadata, +) -> bytes: + """ + Issue a pairing credential binded to the provided host static public key + and credential metadata. + """ + cred_auth_key = derive_cred_auth_key() + proto_msg = ThpAuthenticatedCredentialData( + host_static_pubkey=host_static_pubkey, + cred_metadata=credential_metadata, + ) + authenticated_credential_data = _encode_message_into_new_buffer(proto_msg) + mac = hmac(hmac.SHA256, cred_auth_key, authenticated_credential_data).digest() + + proto_msg = ThpPairingCredential(cred_metadata=credential_metadata, mac=mac) + credential_raw = _encode_message_into_new_buffer(proto_msg) + return credential_raw + + +def validate_credential( + encoded_pairing_credential_message: bytes, + host_static_pubkey: bytes, +) -> bool: + """ + Validate a pairing credential binded to the provided host static public key. + """ + cred_auth_key = derive_cred_auth_key() + expected_type = protobuf.type_for_name("ThpPairingCredential") + credential = wrap_protobuf_load(encoded_pairing_credential_message, expected_type) + assert ThpPairingCredential.is_type_of(credential) + proto_msg = ThpAuthenticatedCredentialData( + host_static_pubkey=host_static_pubkey, + cred_metadata=credential.cred_metadata, + ) + authenticated_credential_data = _encode_message_into_new_buffer(proto_msg) + mac = hmac(hmac.SHA256, cred_auth_key, authenticated_credential_data).digest() + return mac == credential.mac + + +def _encode_message_into_new_buffer(msg: protobuf.MessageType) -> bytes: + msg_len = protobuf.encoded_length(msg) + new_buffer = bytearray(msg_len) + protobuf.encode(new_buffer, msg) + return new_buffer diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 8524f83e46..86418c4b88 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -6115,6 +6115,52 @@ if TYPE_CHECKING: def is_type_of(cls, msg: Any) -> TypeGuard["TezosManagerTransfer"]: return isinstance(msg, cls) + class ThpCredentialMetadata(protobuf.MessageType): + host_name: "str | None" + + def __init__( + self, + *, + host_name: "str | None" = None, + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["ThpCredentialMetadata"]: + return isinstance(msg, cls) + + class ThpPairingCredential(protobuf.MessageType): + cred_metadata: "ThpCredentialMetadata | None" + mac: "bytes | None" + + def __init__( + self, + *, + cred_metadata: "ThpCredentialMetadata | None" = None, + mac: "bytes | None" = None, + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["ThpPairingCredential"]: + return isinstance(msg, cls) + + class ThpAuthenticatedCredentialData(protobuf.MessageType): + host_static_pubkey: "bytes | None" + cred_metadata: "ThpCredentialMetadata | None" + + def __init__( + self, + *, + host_static_pubkey: "bytes | None" = None, + cred_metadata: "ThpCredentialMetadata | None" = None, + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: Any) -> TypeGuard["ThpAuthenticatedCredentialData"]: + return isinstance(msg, cls) + class WebAuthnListResidentCredentials(protobuf.MessageType): @classmethod diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 062bf94bfa..c2aff8a1cf 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -7750,6 +7750,54 @@ class TezosManagerTransfer(protobuf.MessageType): self.amount = amount +class ThpCredentialMetadata(protobuf.MessageType): + MESSAGE_WIRE_TYPE = None + FIELDS = { + 1: protobuf.Field("host_name", "string", repeated=False, required=False, default=None), + } + + def __init__( + self, + *, + host_name: Optional["str"] = None, + ) -> None: + self.host_name = host_name + + +class ThpPairingCredential(protobuf.MessageType): + MESSAGE_WIRE_TYPE = None + FIELDS = { + 1: protobuf.Field("cred_metadata", "ThpCredentialMetadata", repeated=False, required=False, default=None), + 2: protobuf.Field("mac", "bytes", repeated=False, required=False, default=None), + } + + def __init__( + self, + *, + cred_metadata: Optional["ThpCredentialMetadata"] = None, + mac: Optional["bytes"] = None, + ) -> None: + self.cred_metadata = cred_metadata + self.mac = mac + + +class ThpAuthenticatedCredentialData(protobuf.MessageType): + MESSAGE_WIRE_TYPE = None + FIELDS = { + 1: protobuf.Field("host_static_pubkey", "bytes", repeated=False, required=False, default=None), + 2: protobuf.Field("cred_metadata", "ThpCredentialMetadata", repeated=False, required=False, default=None), + } + + def __init__( + self, + *, + host_static_pubkey: Optional["bytes"] = None, + cred_metadata: Optional["ThpCredentialMetadata"] = None, + ) -> None: + self.host_static_pubkey = host_static_pubkey + self.cred_metadata = cred_metadata + + class WebAuthnListResidentCredentials(protobuf.MessageType): MESSAGE_WIRE_TYPE = 800 diff --git a/rust/trezor-client/src/protos/generated/messages.rs b/rust/trezor-client/src/protos/generated/messages.rs index efea50a154..7cf263a1fe 100644 --- a/rust/trezor-client/src/protos/generated/messages.rs +++ b/rust/trezor-client/src/protos/generated/messages.rs @@ -1549,6 +1549,8 @@ pub mod exts { pub const wire_type: ::protobuf::ext::ExtFieldOptional<::protobuf::descriptor::MessageOptions, u32> = ::protobuf::ext::ExtFieldOptional::new(52002, ::protobuf::descriptor::field_descriptor_proto::Type::TYPE_UINT32); + pub const internal_only: ::protobuf::ext::ExtFieldOptional<::protobuf::descriptor::MessageOptions, bool> = ::protobuf::ext::ExtFieldOptional::new(52003, ::protobuf::descriptor::field_descriptor_proto::Type::TYPE_BOOL); + pub const experimental_field: ::protobuf::ext::ExtFieldOptional<::protobuf::descriptor::FieldOptions, bool> = ::protobuf::ext::ExtFieldOptional::new(53001, ::protobuf::descriptor::field_descriptor_proto::Type::TYPE_BOOL); pub const include_in_bitcoin_only: ::protobuf::ext::ExtFieldOptional<::protobuf::descriptor::FileOptions, bool> = ::protobuf::ext::ExtFieldOptional::new(60000, ::protobuf::descriptor::field_descriptor_proto::Type::TYPE_BOOL); @@ -1848,11 +1850,12 @@ static file_descriptor_proto_data: &'static [u8] = b"\ Values:T\n\x14experimental_message\x18\xa1\x96\x03\x20\x01(\x08\x12\x1f.\ google.protobuf.MessageOptionsR\x13experimentalMessage:>\n\twire_type\ \x18\xa2\x96\x03\x20\x01(\r\x12\x1f.google.protobuf.MessageOptionsR\x08w\ - ireType:N\n\x12experimental_field\x18\x89\x9e\x03\x20\x01(\x08\x12\x1d.g\ - oogle.protobuf.FieldOptionsR\x11experimentalField:U\n\x17include_in_bitc\ - oin_only\x18\xe0\xd4\x03\x20\x01(\x08\x12\x1c.google.protobuf.FileOption\ - sR\x14includeInBitcoinOnlyB8\n#com.satoshilabs.trezor.lib.protobufB\rTre\ - zorMessage\x80\xa6\x1d\x01\ + ireType:F\n\rinternal_only\x18\xa3\x96\x03\x20\x01(\x08\x12\x1f.google.p\ + rotobuf.MessageOptionsR\x0cinternalOnly:N\n\x12experimental_field\x18\ + \x89\x9e\x03\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\x11exper\ + imentalField:U\n\x17include_in_bitcoin_only\x18\xe0\xd4\x03\x20\x01(\x08\ + \x12\x1c.google.protobuf.FileOptionsR\x14includeInBitcoinOnlyB8\n#com.sa\ + toshilabs.trezor.lib.protobufB\rTrezorMessage\x80\xa6\x1d\x01\ "; /// `FileDescriptorProto` object which was a source for this generated file diff --git a/rust/trezor-client/src/protos/generated/messages_thp.rs b/rust/trezor-client/src/protos/generated/messages_thp.rs new file mode 100644 index 0000000000..b42c245b3c --- /dev/null +++ b/rust/trezor-client/src/protos/generated/messages_thp.rs @@ -0,0 +1,583 @@ +// This file is generated by rust-protobuf 3.3.0. Do not edit +// .proto file is parsed by protoc 3.19.6 +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_results)] +#![allow(unused_mut)] + +//! Generated file from `messages-thp.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_3_0; + +// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpCredentialMetadata) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ThpCredentialMetadata { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpCredentialMetadata.host_name) + pub host_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, +} + +impl<'a> ::std::default::Default for &'a ThpCredentialMetadata { + fn default() -> &'a ThpCredentialMetadata { + ::default_instance() + } +} + +impl ThpCredentialMetadata { + pub fn new() -> ThpCredentialMetadata { + ::std::default::Default::default() + } + + // optional string host_name = 1; + + pub fn host_name(&self) -> &str { + match self.host_name.as_ref() { + Some(v) => v, + None => "", + } + } + + pub fn clear_host_name(&mut self) { + self.host_name = ::std::option::Option::None; + } + + pub fn has_host_name(&self) -> bool { + self.host_name.is_some() + } + + // Param is passed by value, moved + pub fn set_host_name(&mut self, v: ::std::string::String) { + self.host_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_host_name(&mut self) -> &mut ::std::string::String { + if self.host_name.is_none() { + self.host_name = ::std::option::Option::Some(::std::string::String::new()); + } + self.host_name.as_mut().unwrap() + } + + // Take field + pub fn take_host_name(&mut self) -> ::std::string::String { + self.host_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 oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "host_name", + |m: &ThpCredentialMetadata| { &m.host_name }, + |m: &mut ThpCredentialMetadata| { &mut m.host_name }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "ThpCredentialMetadata", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ThpCredentialMetadata { + const NAME: &'static str = "ThpCredentialMetadata"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.host_name = ::std::option::Option::Some(is.read_string()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.host_name.as_ref() { + my_size += ::protobuf::rt::string_size(1, &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 + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.host_name.as_ref() { + os.write_string(1, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ThpCredentialMetadata { + ThpCredentialMetadata::new() + } + + fn clear(&mut self) { + self.host_name = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static ThpCredentialMetadata { + static instance: ThpCredentialMetadata = ThpCredentialMetadata { + host_name: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ThpCredentialMetadata { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpCredentialMetadata").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ThpCredentialMetadata { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ThpCredentialMetadata { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpPairingCredential) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ThpPairingCredential { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpPairingCredential.cred_metadata) + pub cred_metadata: ::protobuf::MessageField, + // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpPairingCredential.mac) + pub mac: ::std::option::Option<::std::vec::Vec>, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpPairingCredential.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ThpPairingCredential { + fn default() -> &'a ThpPairingCredential { + ::default_instance() + } +} + +impl ThpPairingCredential { + pub fn new() -> ThpPairingCredential { + ::std::default::Default::default() + } + + // optional bytes mac = 2; + + pub fn mac(&self) -> &[u8] { + match self.mac.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_mac(&mut self) { + self.mac = ::std::option::Option::None; + } + + pub fn has_mac(&self) -> bool { + self.mac.is_some() + } + + // Param is passed by value, moved + pub fn set_mac(&mut self, v: ::std::vec::Vec) { + self.mac = ::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_mac(&mut self) -> &mut ::std::vec::Vec { + if self.mac.is_none() { + self.mac = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.mac.as_mut().unwrap() + } + + // Take field + pub fn take_mac(&mut self) -> ::std::vec::Vec { + self.mac.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + 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_message_field_accessor::<_, ThpCredentialMetadata>( + "cred_metadata", + |m: &ThpPairingCredential| { &m.cred_metadata }, + |m: &mut ThpPairingCredential| { &mut m.cred_metadata }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "mac", + |m: &ThpPairingCredential| { &m.mac }, + |m: &mut ThpPairingCredential| { &mut m.mac }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "ThpPairingCredential", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ThpPairingCredential { + const NAME: &'static str = "ThpPairingCredential"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.cred_metadata)?; + }, + 18 => { + self.mac = ::std::option::Option::Some(is.read_bytes()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.cred_metadata.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + if let Some(v) = self.mac.as_ref() { + my_size += ::protobuf::rt::bytes_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 + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.cred_metadata.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + if let Some(v) = self.mac.as_ref() { + os.write_bytes(2, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ThpPairingCredential { + ThpPairingCredential::new() + } + + fn clear(&mut self) { + self.cred_metadata.clear(); + self.mac = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static ThpPairingCredential { + static instance: ThpPairingCredential = ThpPairingCredential { + cred_metadata: ::protobuf::MessageField::none(), + mac: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ThpPairingCredential { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpPairingCredential").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ThpPairingCredential { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ThpPairingCredential { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +// @@protoc_insertion_point(message:hw.trezor.messages.thp.ThpAuthenticatedCredentialData) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct ThpAuthenticatedCredentialData { + // message fields + // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpAuthenticatedCredentialData.host_static_pubkey) + pub host_static_pubkey: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:hw.trezor.messages.thp.ThpAuthenticatedCredentialData.cred_metadata) + pub cred_metadata: ::protobuf::MessageField, + // special fields + // @@protoc_insertion_point(special_field:hw.trezor.messages.thp.ThpAuthenticatedCredentialData.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a ThpAuthenticatedCredentialData { + fn default() -> &'a ThpAuthenticatedCredentialData { + ::default_instance() + } +} + +impl ThpAuthenticatedCredentialData { + pub fn new() -> ThpAuthenticatedCredentialData { + ::std::default::Default::default() + } + + // optional bytes host_static_pubkey = 1; + + pub fn host_static_pubkey(&self) -> &[u8] { + match self.host_static_pubkey.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_host_static_pubkey(&mut self) { + self.host_static_pubkey = ::std::option::Option::None; + } + + pub fn has_host_static_pubkey(&self) -> bool { + self.host_static_pubkey.is_some() + } + + // Param is passed by value, moved + pub fn set_host_static_pubkey(&mut self, v: ::std::vec::Vec) { + self.host_static_pubkey = ::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_host_static_pubkey(&mut self) -> &mut ::std::vec::Vec { + if self.host_static_pubkey.is_none() { + self.host_static_pubkey = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.host_static_pubkey.as_mut().unwrap() + } + + // Take field + pub fn take_host_static_pubkey(&mut self) -> ::std::vec::Vec { + self.host_static_pubkey.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + 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_static_pubkey", + |m: &ThpAuthenticatedCredentialData| { &m.host_static_pubkey }, + |m: &mut ThpAuthenticatedCredentialData| { &mut m.host_static_pubkey }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, ThpCredentialMetadata>( + "cred_metadata", + |m: &ThpAuthenticatedCredentialData| { &m.cred_metadata }, + |m: &mut ThpAuthenticatedCredentialData| { &mut m.cred_metadata }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "ThpAuthenticatedCredentialData", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for ThpAuthenticatedCredentialData { + const NAME: &'static str = "ThpAuthenticatedCredentialData"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.host_static_pubkey = ::std::option::Option::Some(is.read_bytes()?); + }, + 18 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.cred_metadata)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.host_static_pubkey.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + if let Some(v) = self.cred_metadata.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.host_static_pubkey.as_ref() { + os.write_bytes(1, v)?; + } + if let Some(v) = self.cred_metadata.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> ThpAuthenticatedCredentialData { + ThpAuthenticatedCredentialData::new() + } + + fn clear(&mut self) { + self.host_static_pubkey = ::std::option::Option::None; + self.cred_metadata.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static ThpAuthenticatedCredentialData { + static instance: ThpAuthenticatedCredentialData = ThpAuthenticatedCredentialData { + host_static_pubkey: ::std::option::Option::None, + cred_metadata: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for ThpAuthenticatedCredentialData { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("ThpAuthenticatedCredentialData").unwrap()).clone() + } +} + +impl ::std::fmt::Display for ThpAuthenticatedCredentialData { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for ThpAuthenticatedCredentialData { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x12messages-thp.proto\x12\x16hw.trezor.messages.thp\x1a\x0emessages.p\ + roto\":\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.Thp\ + CredentialMetadataR\x0ccredMetadata\x12\x10\n\x03mac\x18\x02\x20\x01(\ + \x0cR\x03mac:\x04\x98\xb2\x19\x01\"\xa8\x01\n\x1eThpAuthenticatedCredent\ + ialData\x12,\n\x12host_static_pubkey\x18\x01\x20\x01(\x0cR\x10hostStatic\ + Pubkey\x12R\n\rcred_metadata\x18\x02\x20\x01(\x0b2-.hw.trezor.messages.t\ + hp.ThpCredentialMetadataR\x0ccredMetadata:\x04\x98\xb2\x19\x01B;\n#com.s\ + atoshilabs.trezor.lib.protobufB\x10TrezorMessageThp\x80\xa6\x1d\x01\ +"; + +/// `FileDescriptorProto` object which was a source for this generated file +fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + static file_descriptor_proto_lazy: ::protobuf::rt::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::Lazy::new(); + file_descriptor_proto_lazy.get(|| { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() + }) +} + +/// `FileDescriptor` object which allows dynamic access to files +pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { + static generated_file_descriptor_lazy: ::protobuf::rt::Lazy<::protobuf::reflect::GeneratedFileDescriptor> = ::protobuf::rt::Lazy::new(); + static file_descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::FileDescriptor> = ::protobuf::rt::Lazy::new(); + file_descriptor.get(|| { + let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { + let mut deps = ::std::vec::Vec::with_capacity(1); + deps.push(super::messages::file_descriptor().clone()); + let mut messages = ::std::vec::Vec::with_capacity(3); + messages.push(ThpCredentialMetadata::generated_message_descriptor_data()); + messages.push(ThpPairingCredential::generated_message_descriptor_data()); + messages.push(ThpAuthenticatedCredentialData::generated_message_descriptor_data()); + let mut enums = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedFileDescriptor::new_generated( + file_descriptor_proto(), + deps, + messages, + enums, + ) + }); + ::protobuf::reflect::FileDescriptor::new_generated_2(generated_file_descriptor) + }) +}