Electroneum
hw::trezor Namespace Reference

Namespaces

 exc
 
 protocol
 

Classes

class  BridgeTransport
 
class  DebugLink
 
class  GenericMessage
 
class  MessageMapper
 
class  Protocol
 
class  ProtocolV1
 
class  Transport
 
struct  trezor_usb_desc_t
 
class  UdpTransport
 

Typedefs

using json = rapidjson::Document
 
using json_val = rapidjson::Value
 
typedef std::vector< std::shared_ptr< Transport > > t_transport_vect
 

Functions

void register_all (std::map< std::string, std::unique_ptr< device >> &registry)
 
void register_all ()
 
template<class t_message = google::protobuf::Message>
std::shared_ptr< t_message > message_ptr_retype (std::shared_ptr< google::protobuf::Message > &in)
 
template<class t_message = google::protobuf::Message>
std::shared_ptr< t_message > message_ptr_retype_static (std::shared_ptr< google::protobuf::Message > &in)
 
bool t_serialize (const std::string &in, std::string &out)
 
bool t_serialize (const json_val &in, std::string &out)
 
std::string t_serialize (const json_val &in)
 
bool t_deserialize (const std::string &in, std::string &out)
 
bool t_deserialize (const std::string &in, json &out)
 
uint64_t pack_version (uint32_t major, uint32_t minor, uint32_t patch)
 
void enumerate (t_transport_vect &res)
 
void sort_transports_by_env (t_transport_vect &res)
 
std::shared_ptr< Transporttransport (const std::string &path)
 
void throw_failure_exception (const messages::common::Failure *failure)
 
std::ostream & operator<< (std::ostream &o, hw::trezor::Transport const &t)
 
std::ostream & operator<< (std::ostream &o, std::shared_ptr< hw::trezor::Transport > const &t)
 
template<class t_req , class t_res , class t_transport >
bool invoke_bridge_http (const boost::string_ref uri, const t_req &out_struct, t_res &result_struct, t_transport &transport, const boost::string_ref method="POST", std::chrono::milliseconds timeout=std::chrono::seconds(180))
 
template<class t_transport = Transport>
std::shared_ptr< t_transport > transport_typed (const std::string &path)
 
template<class t_message = google::protobuf::Message>
std::shared_ptr< t_message > exchange_message (Transport &transport, const google::protobuf::Message &req, boost::optional< messages::MessageType > resp_type=boost::none)
 

Variables

const char * TYPE_PREFIX = "MessageType_"
 
const char * PACKAGES []
 
const std::string DEFAULT_BRIDGE = "127.0.0.1:21325"
 

Typedef Documentation

◆ json

Definition at line 59 of file transport.hpp.

◆ json_val

Definition at line 60 of file transport.hpp.

◆ t_transport_vect

typedef std::vector<std::shared_ptr<Transport> > hw::trezor::t_transport_vect

Definition at line 135 of file transport.hpp.

Function Documentation

◆ enumerate()

void hw::trezor::enumerate ( t_transport_vect res)

Enumerates all transports

Definition at line 1144 of file transport.cpp.

1144  {
1145  BridgeTransport bt;
1146  try{
1147  bt.enumerate(res);
1148  } catch (const std::exception & e){
1149  MERROR("BridgeTransport enumeration failed:" << e.what());
1150  }
1151 
1152 #ifdef WITH_DEVICE_TREZOR_WEBUSB
1153  hw::trezor::WebUsbTransport btw;
1154  try{
1155  btw.enumerate(res);
1156  } catch (const std::exception & e){
1157  MERROR("WebUsbTransport enumeration failed:" << e.what());
1158  }
1159 #endif
1160 
1161 #ifdef WITH_DEVICE_TREZOR_UDP
1163  try{
1164  btu.enumerate(res);
1165  } catch (const std::exception & e){
1166  MERROR("UdpTransport enumeration failed:" << e.what());
1167  }
1168 #endif
1169  }
const char * res
Definition: hmac_keccak.cpp:41
#define MERROR(x)
Definition: misc_log_ex.h:73
void enumerate(t_transport_vect &res) override
Definition: transport.cpp:566
Here is the call graph for this function:

◆ exchange_message()

template<class t_message = google::protobuf::Message>
std::shared_ptr<t_message> hw::trezor::exchange_message ( Transport transport,
const google::protobuf::Message &  req,
boost::optional< messages::MessageType >  resp_type = boost::none 
)

Simple wrapper for write-read message exchange with expected message response type.

Exceptions
UnexpectedMessageExceptionif the response message type is different than expected. Exception contains message type and the message itself.

Definition at line 373 of file transport.hpp.

375  {
376  // Require strictly protocol buffers response in the template.
378 
379  // Write the request
380  transport.write(req);
381 
382  // Read the response
383  std::shared_ptr<google::protobuf::Message> msg_resp;
384  hw::trezor::messages::MessageType msg_resp_type;
385  transport.read(msg_resp, &msg_resp_type);
386 
387  // Determine type of expected message response
388  messages::MessageType required_type = resp_type ? resp_type.get() : MessageMapper::get_message_wire_number<t_message>();
389 
390  if (msg_resp_type == required_type) {
391  return message_ptr_retype<t_message>(msg_resp);
392  } else if (msg_resp_type == messages::MessageType_Failure){
393  throw_failure_exception(dynamic_cast<messages::common::Failure*>(msg_resp.get()));
394  } else {
395  throw exc::UnexpectedMessageException(msg_resp_type, msg_resp);
396  }
397  }
void throw_failure_exception(const messages::common::Failure *failure)
Definition: transport.cpp:1217
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
std::shared_ptr< Transport > transport(const std::string &path)
Definition: transport.cpp:1204
Here is the call graph for this function:

◆ invoke_bridge_http()

template<class t_req , class t_res , class t_transport >
bool hw::trezor::invoke_bridge_http ( const boost::string_ref  uri,
const t_req &  out_struct,
t_res &  result_struct,
t_transport &  transport,
const boost::string_ref  method = "POST",
std::chrono::milliseconds  timeout = std::chrono::seconds(180) 
)

Definition at line 77 of file transport.hpp.

78  {
79  std::string req_param;
80  t_serialize(out_struct, req_param);
81 
82  http::fields_list additional_params;
83  additional_params.push_back(std::make_pair("Origin","https://electroneum.trezor.io"));
84  additional_params.push_back(std::make_pair("Content-Type","application/json; charset=utf-8"));
85 
86  const http::http_response_info* pri = nullptr;
87  if(!transport.invoke(uri, method, req_param, timeout, &pri, std::move(additional_params)))
88  {
89  MERROR("Failed to invoke http request to " << uri);
90  return false;
91  }
92 
93  if(!pri)
94  {
95  MERROR("Failed to invoke http request to " << uri << ", internal error (null response ptr)");
96  return false;
97  }
98 
99  if(pri->m_response_code != 200)
100  {
101  MERROR("Failed to invoke http request to " << uri << ", wrong response code: " << pri->m_response_code
102  << " Response Body: " << pri->m_body);
103  return false;
104  }
105 
106  return t_deserialize(pri->m_body, result_struct);
107  }
#define MERROR(x)
Definition: misc_log_ex.h:73
std::list< std::pair< std::string, std::string > > fields_list
Definition: http_base.h:66
bool t_serialize(const std::string &in, std::string &out)
Definition: transport.cpp:55
::std::string string
Definition: gtest-port.h:1097
bool t_deserialize(const std::string &in, std::string &out)
Definition: transport.cpp:74
const T & move(const T &t)
Definition: gtest-port.h:1317
std::shared_ptr< Transport > transport(const std::string &path)
Definition: transport.cpp:1204
Here is the call graph for this function:
Here is the caller graph for this function:

◆ message_ptr_retype()

template<class t_message = google::protobuf::Message>
std::shared_ptr<t_message> hw::trezor::message_ptr_retype ( std::shared_ptr< google::protobuf::Message > &  in)

Definition at line 73 of file messages_map.hpp.

73  {
75  if (!in){
76  return nullptr;
77  }
78 
79  return std::dynamic_pointer_cast<t_message>(in);
80  }
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225

◆ message_ptr_retype_static()

template<class t_message = google::protobuf::Message>
std::shared_ptr<t_message> hw::trezor::message_ptr_retype_static ( std::shared_ptr< google::protobuf::Message > &  in)

Definition at line 83 of file messages_map.hpp.

83  {
85  if (!in){
86  return nullptr;
87  }
88 
89  return std::static_pointer_cast<t_message>(in);
90  }
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225

◆ operator<<() [1/2]

std::ostream & hw::trezor::operator<< ( std::ostream &  o,
hw::trezor::Transport const &  t 
)

Definition at line 1251 of file transport.cpp.

1251  {
1252  return t.dump(o);
1253  }
Here is the call graph for this function:

◆ operator<<() [2/2]

std::ostream & hw::trezor::operator<< ( std::ostream &  o,
std::shared_ptr< hw::trezor::Transport > const &  t 
)

Definition at line 1255 of file transport.cpp.

1255  {
1256  if (!t){
1257  return o << "None";
1258  }
1259 
1260  return t->dump(o);
1261  }

◆ pack_version()

uint64_t hw::trezor::pack_version ( uint32_t  major,
uint32_t  minor,
uint32_t  patch 
)

Definition at line 90 of file transport.cpp.

91  {
92  // packing (major, minor, patch) to 64 B: 16 B | 24 B | 24 B
93  const unsigned bits_1 = 16;
94  const unsigned bits_2 = 24;
95  const uint32_t mask_1 = (1 << bits_1) - 1;
96  const uint32_t mask_2 = (1 << bits_2) - 1;
97  CHECK_AND_ASSERT_THROW_MES(major <= mask_1 && minor <= mask_2 && patch <= mask_2, "Version numbers overflow packing scheme");
98  return patch | (((uint64_t)minor) << bits_2) | (((uint64_t)major) << (bits_1 + bits_2));
99  }
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
unsigned int uint32_t
Definition: stdint.h:126
unsigned __int64 uint64_t
Definition: stdint.h:136
Here is the caller graph for this function:

◆ register_all() [1/2]

void hw::trezor::register_all ( std::map< std::string, std::unique_ptr< device >> &  registry)

Definition at line 732 of file device_trezor.cpp.

732  {
733  }

◆ register_all() [2/2]

void hw::trezor::register_all ( )

Definition at line 735 of file device_trezor.cpp.

735  {
736  }

◆ sort_transports_by_env()

void hw::trezor::sort_transports_by_env ( t_transport_vect res)

Sorts found transports by TREZOR_PATH environment variable.

Definition at line 1171 of file transport.cpp.

1171  {
1172  const char *env_trezor_path = getenv("TREZOR_PATH");
1173  if (!env_trezor_path){
1174  return;
1175  }
1176 
1177  // Sort transports by the longest matching prefix with TREZOR_PATH
1178  std::string trezor_path(env_trezor_path);
1179  std::vector<size_t> match_idx(res.size());
1180  std::vector<size_t> path_permutation(res.size());
1181 
1182  for(size_t i = 0; i < res.size(); ++i){
1183  auto cpath = res[i]->get_path();
1184  std::string * s1 = &trezor_path;
1185  std::string * s2 = &cpath;
1186 
1187  // first has to be shorter in std::mismatch(). Returns first non-matching iterators.
1188  if (s1->size() >= s2->size()){
1189  std::swap(s1, s2);
1190  }
1191 
1192  const auto mism = std::mismatch(s1->begin(), s1->end(), s2->begin());
1193  match_idx[i] = mism.first - s1->begin();
1194  path_permutation[i] = i;
1195  }
1196 
1197  std::sort(path_permutation.begin(), path_permutation.end(), [&](const size_t i0, const size_t i1) {
1198  return match_idx[i0] > match_idx[i1];
1199  });
1200 
1201  tools::apply_permutation(path_permutation, res);
1202  }
const char * res
Definition: hmac_keccak.cpp:41
void apply_permutation(std::vector< size_t > permutation, const F &swap)
::std::string string
Definition: gtest-port.h:1097
Here is the call graph for this function:

◆ t_deserialize() [1/2]

bool hw::trezor::t_deserialize ( const std::string &  in,
std::string &  out 
)

Definition at line 74 of file transport.cpp.

74  {
75  out = in;
76  return true;
77  }
Here is the caller graph for this function:

◆ t_deserialize() [2/2]

bool hw::trezor::t_deserialize ( const std::string &  in,
json out 
)

Definition at line 79 of file transport.cpp.

79  {
80  if (out.Parse(in.c_str()).HasParseError()) {
81  throw exc::CommunicationException("JSON parse error");
82  }
83  return true;
84  }

◆ t_serialize() [1/3]

bool hw::trezor::t_serialize ( const std::string &  in,
std::string &  out 
)

Definition at line 55 of file transport.cpp.

55  {
56  out = in;
57  return true;
58  }
Here is the caller graph for this function:

◆ t_serialize() [2/3]

bool hw::trezor::t_serialize ( const json_val in,
std::string &  out 
)

Definition at line 60 of file transport.cpp.

60  {
62  rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
63  in.Accept(writer);
64  out = sb.GetString();
65  return true;
66  }
GenericStringBuffer< UTF8< char >, CrtAllocator > StringBuffer
Definition: fwd.h:59

◆ t_serialize() [3/3]

std::string hw::trezor::t_serialize ( const json_val in)

Definition at line 68 of file transport.cpp.

68  {
69  std::string ret;
70  t_serialize(in, ret);
71  return ret;
72  }
::std::string string
Definition: gtest-port.h:1097
std::string t_serialize(const json_val &in)
Definition: transport.cpp:68

◆ throw_failure_exception()

void hw::trezor::throw_failure_exception ( const messages::common::Failure *  failure)

Throws corresponding failure exception.

Definition at line 1217 of file transport.cpp.

1217  {
1218  if (failure == nullptr){
1219  throw std::invalid_argument("Failure message cannot be null");
1220  }
1221 
1222  boost::optional<std::string> message = failure->has_message() ? boost::make_optional(failure->message()) : boost::none;
1223  boost::optional<uint32_t> code = failure->has_code() ? boost::make_optional(static_cast<uint32_t>(failure->code())) : boost::none;
1224  if (!code){
1225  throw exc::proto::FailureException(code, message);
1226  }
1227 
1228  auto ecode = failure->code();
1229  if (ecode == messages::common::Failure_FailureType_Failure_UnexpectedMessage){
1230  throw exc::proto::UnexpectedMessageException(code, message);
1231  } else if (ecode == messages::common::Failure_FailureType_Failure_ActionCancelled){
1232  throw exc::proto::CancelledException(code, message);
1233  } else if (ecode == messages::common::Failure_FailureType_Failure_PinExpected){
1234  throw exc::proto::PinExpectedException(code, message);
1235  } else if (ecode == messages::common::Failure_FailureType_Failure_PinInvalid){
1236  throw exc::proto::InvalidPinException(code, message);
1237  } else if (ecode == messages::common::Failure_FailureType_Failure_NotEnoughFunds){
1238  throw exc::proto::NotEnoughFundsException(code, message);
1239  } else if (ecode == messages::common::Failure_FailureType_Failure_NotInitialized){
1240  throw exc::proto::NotInitializedException(code, message);
1241  } else if (ecode == messages::common::Failure_FailureType_Failure_FirmwareError){
1242  throw exc::proto::FirmwareErrorException(code, message);
1243  } else {
1244  throw exc::proto::FailureException(code, message);
1245  }
1246  }
std::string message("Message requiring signing")
Here is the call graph for this function:
Here is the caller graph for this function:

◆ transport()

std::shared_ptr< Transport > hw::trezor::transport ( const std::string &  path)

Transforms path to the transport

Definition at line 1204 of file transport.cpp.

1204  {
1205  if (boost::starts_with(path, BridgeTransport::PATH_PREFIX)){
1206  return std::make_shared<BridgeTransport>(path.substr(strlen(BridgeTransport::PATH_PREFIX)));
1207 
1208  } else if (boost::starts_with(path, UdpTransport::PATH_PREFIX)){
1209  return std::make_shared<UdpTransport>(path.substr(strlen(UdpTransport::PATH_PREFIX)));
1210 
1211  } else {
1212  throw std::invalid_argument("Unknown Trezor device path: " + path);
1213 
1214  }
1215  }
Here is the caller graph for this function:

◆ transport_typed()

template<class t_transport = Transport>
std::shared_ptr<t_transport> hw::trezor::transport_typed ( const std::string &  path)

Transforms path to the particular transport

Definition at line 319 of file transport.hpp.

319  {
320  auto t = transport(path);
321  if (!t){
322  return nullptr;
323  }
324 
325  return std::dynamic_pointer_cast<t_transport>(t);
326  }
std::shared_ptr< Transport > transport(const std::string &path)
Definition: transport.cpp:1204
Here is the call graph for this function:

Variable Documentation

◆ DEFAULT_BRIDGE

const std::string hw::trezor::DEFAULT_BRIDGE = "127.0.0.1:21325"

Definition at line 63 of file transport.hpp.

◆ PACKAGES

const char* hw::trezor::PACKAGES[]
Initial value:
= {
"hw.trezor.messages.",
"hw.trezor.messages.common.",
"hw.trezor.messages.management.",
"hw.trezor.messages.electroneum."
}

Definition at line 48 of file messages_map.cpp.

◆ TYPE_PREFIX

const char* hw::trezor::TYPE_PREFIX = "MessageType_"

Definition at line 47 of file messages_map.cpp.