Electroneum
Loading...
Searching...
No Matches
hw::trezor Namespace Reference

Namespaces

namespace  exc
namespace  protocol

Classes

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

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

using hw::trezor::json = rapidjson::Document

Definition at line 59 of file transport.hpp.

◆ json_val

using hw::trezor::json_val = rapidjson::Value

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
1162 hw::trezor::UdpTransport btu;
1163 try{
1164 btu.enumerate(res);
1165 } catch (const std::exception & e){
1166 MERROR("UdpTransport enumeration failed:" << e.what());
1167 }
1168#endif
1169 }
void enumerate(t_transport_vect &res) override
void enumerate(t_transport_vect &res) override
const char * res
#define MERROR(x)
Definition misc_log_ex.h:73
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.
377 BOOST_STATIC_ASSERT(boost::is_base_of<google::protobuf::Message, t_message>::value);
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 }
static messages::MessageType get_message_wire_number()
void throw_failure_exception(const messages::common::Failure *failure)
std::shared_ptr< t_message > message_ptr_retype(std::shared_ptr< google::protobuf::Message > &in)
std::shared_ptr< Transport > transport(const std::string &path)
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 }
bool t_serialize(const std::string &in, std::string &out)
Definition transport.cpp:55
bool t_deserialize(const std::string &in, std::string &out)
Definition transport.cpp:74
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 {
74 BOOST_STATIC_ASSERT(boost::is_base_of<google::protobuf::Message, t_message>::value);
75 if (!in){
76 return nullptr;
77 }
78
79 return std::dynamic_pointer_cast<t_message>(in);
80 }
Here is the caller graph for this function:

◆ 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 {
84 BOOST_STATIC_ASSERT(boost::is_base_of<google::protobuf::Message, t_message>::value);
85 if (!in){
86 return nullptr;
87 }
88
89 return std::static_pointer_cast<t_message>(in);
90 }

◆ 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)
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 ( )

Definition at line 735 of file device_trezor.cpp.

735 {
736 }

◆ register_all() [2/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 }

◆ 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 }
void apply_permutation(std::vector< size_t > permutation, const F &swap)
Here is the call graph for this function:

◆ t_deserialize() [1/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_deserialize() [2/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_serialize() [1/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 }
Here is the call 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 {
61 rapidjson::StringBuffer sb;
62 rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
63 in.Accept(writer);
64 out = sb.GetString();
65 return true;
66 }

◆ t_serialize() [3/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:

◆ 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){
1233 } else if (ecode == messages::common::Failure_FailureType_Failure_PinExpected){
1235 } else if (ecode == messages::common::Failure_FailureType_Failure_PinInvalid){
1237 } else if (ecode == messages::common::Failure_FailureType_Failure_NotEnoughFunds){
1239 } else if (ecode == messages::common::Failure_FailureType_Failure_NotInitialized){
1241 } else if (ecode == messages::common::Failure_FailureType_Failure_FirmwareError){
1243 } else {
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 }
static const char * PATH_PREFIX
static const char * PATH_PREFIX
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 }
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.

48 {
49 "hw.trezor.messages.",
50 "hw.trezor.messages.common.",
51 "hw.trezor.messages.management.",
52#ifdef WITH_TREZOR_DEBUGGING
53 "hw.trezor.messages.debug.",
54#endif
55 "hw.trezor.messages.electroneum."
56 };

◆ TYPE_PREFIX

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

Definition at line 47 of file messages_map.cpp.