Monero
message_store.h
Go to the documentation of this file.
1 // Copyright (c) 2018, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #pragma once
30 
31 #include <cstdlib>
32 #include <string>
33 #include <vector>
34 #include "crypto/hash.h"
35 #include <boost/serialization/vector.hpp>
36 #include <boost/program_options/variables_map.hpp>
37 #include <boost/program_options/options_description.hpp>
38 #include <boost/optional/optional.hpp>
43 #include "common/i18n.h"
44 #include "common/command_line.h"
45 #include "wipeable_string.h"
46 #include "net/abstract_http_client.h"
47 #include "serialization/crypto.h"
48 #include "serialization/string.h"
50 #include "message_transporter.h"
51 
52 #undef MONERO_DEFAULT_LOG_CATEGORY
53 #define MONERO_DEFAULT_LOG_CATEGORY "wallet.mms"
54 #define AUTO_CONFIG_TOKEN_BYTES 4
55 #define AUTO_CONFIG_TOKEN_PREFIX "mms"
56 
57 namespace mms
58 {
59  enum class message_type
60  {
61  key_set,
66  note,
69  };
70 
71  enum class message_direction
72  {
73  in,
74  out
75  };
76 
77  enum class message_state
78  {
80  sent,
81 
82  waiting,
83  processed,
84 
85  cancelled
86  };
87 
88  enum class message_processing
89  {
95  sign_tx,
96  send_tx,
97  submit_tx,
100  };
101 
102  struct message
103  {
104  uint32_t id;
107  std::string content;
108  uint64_t created;
109  uint64_t modified;
110  uint64_t sent;
111  uint32_t signer_index;
114  uint32_t wallet_height;
115  uint32_t round;
116  uint32_t signature_count;
117  std::string transport_id;
118 
120  VERSION_FIELD(0)
121  VARINT_FIELD(id)
124  FIELD(content)
129  FIELD(hash)
135  END_SERIALIZE()
136  };
137  // "wallet_height" (for lack of a short name that would describe what it is about)
138  // is the number of transfers present in the wallet at the time of message
139  // construction; used to coordinate generation of sync info (which depends
140  // on the content of the wallet at time of generation)
141 
143  {
144  std::string label;
145  std::string transport_address;
148  bool me;
149  uint32_t index;
150  std::string auto_config_token;
155 
157  VERSION_FIELD(0)
158  FIELD(label)
159  FIELD(transport_address)
160  FIELD(monero_address_known)
161  FIELD(monero_address)
162  FIELD(me)
163  VARINT_FIELD(index)
164  FIELD(auto_config_token)
165  FIELD(auto_config_public_key)
166  FIELD(auto_config_secret_key)
167  FIELD(auto_config_transport_address)
168  FIELD(auto_config_running)
169  END_SERIALIZE()
170 
172  {
173  monero_address_known = false;
174  memset(&monero_address, 0, sizeof(cryptonote::account_public_address));
175  me = false;
176  index = 0;
177  auto_config_public_key = crypto::null_pkey;
178  auto_config_secret_key = crypto::null_skey;
179  auto_config_running = false;
180  };
181  };
182 
184  {
186  std::vector<uint32_t> message_ids;
187  uint32_t receiving_signer_index = 0;
188  };
189 
191  {
193  crypto::chacha_iv iv;
196  };
197 
199  {
200  std::string label;
201  std::string transport_address;
203 
205  VERSION_FIELD(0)
206  FIELD(label)
207  FIELD(transport_address)
208  FIELD(monero_address)
209  END_SERIALIZE()
210  };
211 
212  // Overal .mms file structure, with the "message_store" object serialized to and
213  // encrypted in "encrypted_data"
214  struct file_data
215  {
216  std::string magic_string;
217  uint32_t file_version;
218  crypto::chacha_iv iv;
219  std::string encrypted_data;
220 
222  FIELD(magic_string)
223  FIELD(file_version)
224  FIELD(iv)
225  FIELD(encrypted_data)
226  END_SERIALIZE()
227  };
228 
229  // The following struct provides info about the current state of a "wallet2" object
230  // at the time of a "message_store" method call that those methods need. See on the
231  // one hand a first parameter of this type for several of those methods, and on the
232  // other hand the method "wallet2::get_multisig_wallet_state" which clients like the
233  // CLI wallet can use to get that info.
234  //
235  // Note that in the case of a wallet that is already multisig "address" is NOT the
236  // multisig address, but the "original" wallet address at creation time. Likewise
237  // "view_secret_key" is the original view secret key then.
238  //
239  // This struct definition is here and not in "wallet2.h" to avoid circular imports.
241  {
245  bool multisig;
250  std::string mms_file;
251 
253  VERSION_FIELD(0)
254  FIELD(address)
255  VARINT_FIELD(nettype)
256  FIELD(view_secret_key)
257  FIELD(multisig)
258  FIELD(multisig_is_ready)
259  FIELD(has_multisig_partial_key_images)
260  VARINT_FIELD(multisig_rounds_passed)
261  VARINT_FIELD(num_transfer_details)
262  FIELD(mms_file)
263  END_SERIALIZE()
264  };
265 
267  {
268  public:
269  message_store(std::unique_ptr<epee::net_utils::http::abstract_http_client> http_client);
270 
271  // Initialize and start to use the MMS, set the first signer, this wallet itself
272  // Filename, if not null and not empty, is used to create the ".mms" file
273  // reset it if already used, with deletion of all signers and messages
274  void init(const multisig_wallet_state &state, const std::string &own_label,
275  const std::string &own_transport_address, uint32_t num_authorized_signers, uint32_t num_required_signers);
276  void set_active(bool active) { m_active = active; };
277  void set_auto_send(bool auto_send) { m_auto_send = auto_send; };
278  void set_options(const boost::program_options::variables_map& vm);
279  void set_options(const std::string &bitmessage_address, const epee::wipeable_string &bitmessage_login);
280  bool get_active() const { return m_active; };
281  bool get_auto_send() const { return m_auto_send; };
282  uint32_t get_num_required_signers() const { return m_num_required_signers; };
283  uint32_t get_num_authorized_signers() const { return m_num_authorized_signers; };
284 
285  void set_signer(const multisig_wallet_state &state,
286  uint32_t index,
287  const boost::optional<std::string> &label,
288  const boost::optional<std::string> &transport_address,
289  const boost::optional<cryptonote::account_public_address> monero_address);
290 
291  const authorized_signer &get_signer(uint32_t index) const;
292  bool get_signer_index_by_monero_address(const cryptonote::account_public_address &monero_address, uint32_t &index) const;
293  bool get_signer_index_by_label(const std::string label, uint32_t &index) const;
294  const std::vector<authorized_signer> &get_all_signers() const { return m_signers; };
295  bool signer_config_complete() const;
296  bool signer_labels_complete() const;
297  void get_signer_config(std::string &signer_config);
298  void unpack_signer_config(const multisig_wallet_state &state, const std::string &signer_config,
299  std::vector<authorized_signer> &signers);
300  void process_signer_config(const multisig_wallet_state &state, const std::string &signer_config);
301 
302  void start_auto_config(const multisig_wallet_state &state);
303  bool check_auto_config_token(const std::string &raw_token,
304  std::string &adjusted_token) const;
305  size_t add_auto_config_data_message(const multisig_wallet_state &state,
306  const std::string &auto_config_token);
307  void process_auto_config_data_message(uint32_t id);
308  std::string get_config_checksum() const;
309  void stop_auto_config();
310 
311  // Process data just created by "me" i.e. the own local wallet, e.g. as the result of a "prepare_multisig" command
312  // Creates the resulting messages to the right signers
313  void process_wallet_created_data(const multisig_wallet_state &state, message_type type, const std::string &content);
314 
315  // Go through all the messages, look at the "ready to process" ones, and check whether any single one
316  // or any group of them can be processed, because they are processable as single messages (like a tx
317  // that is fully signed and thus ready for submit to the net) or because they form a complete group
318  // (e.g. key sets from all authorized signers to make the wallet multisig). If there are multiple
319  // candidates, e.g. in 2/3 multisig sending to one OR the other signer to sign, there will be more
320  // than 1 element in 'data' for the user to choose. If nothing is ready "false" is returned.
321  // The method mostly ignores the order in which the messages were received because messages may be delayed
322  // (e.g. sync data from a signer arrives AFTER a transaction to submit) or because message time stamps
323  // may be wrong so it's not possible to order them reliably.
324  // Messages also may be ready by themselves but the wallet not yet ready for them (e.g. sync data already
325  // arriving when the wallet is not yet multisig because key sets were delayed or were lost altogether.)
326  // If nothing is ready 'wait_reason' may contain further info about the reason why.
327  bool get_processable_messages(const multisig_wallet_state &state,
328  bool force_sync,
329  std::vector<processing_data> &data_list,
330  std::string &wait_reason);
331  void set_messages_processed(const processing_data &data);
332 
333  size_t add_message(const multisig_wallet_state &state,
335  const std::string &content);
336  const std::vector<message> &get_all_messages() const { return m_messages; };
337  bool get_message_by_id(uint32_t id, message &m) const;
338  message get_message_by_id(uint32_t id) const;
339  void set_message_processed_or_sent(uint32_t id);
340  void delete_message(uint32_t id);
341  void delete_all_messages();
342  static std::string get_sanitized_text(const std::string &text, size_t max_length);
343 
344  void send_message(const multisig_wallet_state &state, uint32_t id);
345  bool check_for_messages(const multisig_wallet_state &state, std::vector<message> &messages);
346  void stop() { m_run.store(false, std::memory_order_relaxed); m_transporter.stop(); }
347 
348  void write_to_file(const multisig_wallet_state &state, const std::string &filename);
349  void read_from_file(const multisig_wallet_state &state, const std::string &filename, bool load_deprecated_formats = false);
350 
351  template <class t_archive>
352  inline void serialize(t_archive &a, const unsigned int ver)
353  {
354  a & m_active;
355  a & m_num_authorized_signers;
356  a & m_nettype;
357  a & m_num_required_signers;
358  a & m_signers;
359  a & m_messages;
360  a & m_next_message_id;
361  a & m_auto_send;
362  }
363 
365  VERSION_FIELD(0)
366  FIELD(m_active)
367  VARINT_FIELD(m_num_authorized_signers)
368  VARINT_FIELD(m_nettype)
369  VARINT_FIELD(m_num_required_signers)
370  FIELD(m_signers)
371  FIELD(m_messages)
372  VARINT_FIELD(m_next_message_id)
373  FIELD(m_auto_send)
374  END_SERIALIZE()
375 
376  static const char* message_type_to_string(message_type type);
377  static const char* message_direction_to_string(message_direction direction);
378  static const char* message_state_to_string(message_state state);
379  std::string signer_to_string(const authorized_signer &signer, uint32_t max_width);
380 
381  static const char *tr(const char *str) { return i18n_translate(str, "tools::mms"); }
382  static void init_options(boost::program_options::options_description& desc_params);
383 
384  private:
385  bool m_active;
390  std::vector<authorized_signer> m_signers;
391  std::vector<message> m_messages;
393  std::string m_filename;
395  std::atomic<bool> m_run;
396 
397  bool get_message_index_by_id(uint32_t id, size_t &index) const;
398  size_t get_message_index_by_id(uint32_t id) const;
399  message& get_message_ref_by_id(uint32_t id);
400  bool any_message_of_type(message_type type, message_direction direction) const;
401  bool any_message_with_hash(const crypto::hash &hash) const;
402  size_t get_other_signers_id_count(const std::vector<uint32_t> &ids) const;
403  bool message_ids_complete(const std::vector<uint32_t> &ids) const;
404  void encrypt(crypto::public_key public_key, const std::string &plaintext,
405  std::string &ciphertext, crypto::public_key &encryption_public_key, crypto::chacha_iv &iv);
406  void decrypt(const std::string &ciphertext, const crypto::public_key &encryption_public_key, const crypto::chacha_iv &iv,
407  const crypto::secret_key &view_secret_key, std::string &plaintext);
408  std::string create_auto_config_token();
409  void setup_signer_for_auto_config(uint32_t index, const std::string token, bool receiving);
410  void delete_transport_message(uint32_t id);
411  std::string account_address_to_string(const cryptonote::account_public_address &account_address) const;
412  void save(const multisig_wallet_state &state);
413  };
414 }
415 
417 BOOST_CLASS_VERSION(mms::message_store, 0)
418 BOOST_CLASS_VERSION(mms::message, 0)
419 BOOST_CLASS_VERSION(mms::file_transport_message, 0)
420 BOOST_CLASS_VERSION(mms::authorized_signer, 1)
421 BOOST_CLASS_VERSION(mms::auto_config_data, 0)
422 
423 namespace boost
424 {
425  namespace serialization
426  {
427  template <class Archive>
428  inline void serialize(Archive &a, mms::file_data &x, const boost::serialization::version_type ver)
429  {
430  a & x.magic_string;
431  a & x.file_version;
432  a & x.iv;
433  a & x.encrypted_data;
434  }
435 
436  template <class Archive>
437  inline void serialize(Archive &a, mms::message &x, const boost::serialization::version_type ver)
438  {
439  a & x.id;
440  a & x.type;
441  a & x.direction;
442  a & x.content;
443  a & x.created;
444  a & x.modified;
445  a & x.sent;
446  a & x.signer_index;
447  a & x.hash;
448  a & x.state;
449  a & x.wallet_height;
450  a & x.round;
451  a & x.signature_count;
452  a & x.transport_id;
453  }
454 
455  template <class Archive>
456  inline void serialize(Archive &a, mms::authorized_signer &x, const boost::serialization::version_type ver)
457  {
458  a & x.label;
459  a & x.transport_address;
461  a & x.monero_address;
462  a & x.me;
463  a & x.index;
464  if (ver < 1)
465  {
466  return;
467  }
468  a & x.auto_config_token;
472  a & x.auto_config_running;
473  }
474 
475  template <class Archive>
476  inline void serialize(Archive &a, mms::auto_config_data &x, const boost::serialization::version_type ver)
477  {
478  a & x.label;
479  a & x.transport_address;
480  a & x.monero_address;
481  }
482 
483  template <class Archive>
484  inline void serialize(Archive &a, mms::file_transport_message &x, const boost::serialization::version_type ver)
485  {
486  a & x.sender_address;
487  a & x.iv;
489  a & x.internal_message;
490  }
491 
492  template <class Archive>
493  inline void serialize(Archive &a, crypto::chacha_iv &x, const boost::serialization::version_type ver)
494  {
495  a & x.data;
496  }
497 
498  }
499 }
static void init(std::string cache_filename)
Definition: blockchain_blackball.cpp:221
Definition: message_store.h:267
std::vector< authorized_signer > m_signers
Definition: message_store.h:390
uint32_t m_num_authorized_signers
Definition: message_store.h:386
void set_active(bool active)
Definition: message_store.h:276
bool get_auto_send() const
Definition: message_store.h:281
const std::vector< message > & get_all_messages() const
Definition: message_store.h:336
uint32_t m_next_message_id
Definition: message_store.h:392
void stop()
Definition: message_store.h:346
uint32_t m_num_required_signers
Definition: message_store.h:387
const std::vector< authorized_signer > & get_all_signers() const
Definition: message_store.h:294
std::string m_filename
Definition: message_store.h:393
uint32_t get_num_required_signers() const
Definition: message_store.h:282
bool m_auto_send
Definition: message_store.h:388
void set_auto_send(bool auto_send)
Definition: message_store.h:277
cryptonote::network_type m_nettype
Definition: message_store.h:389
uint32_t get_num_authorized_signers() const
Definition: message_store.h:283
bool m_active
Definition: message_store.h:385
bool get_active() const
Definition: message_store.h:280
std::atomic< bool > m_run
Definition: message_store.h:395
void serialize(t_archive &a, const unsigned int ver)
Definition: message_store.h:352
std::vector< message > m_messages
Definition: message_store.h:391
message_transporter m_transporter
Definition: message_store.h:394
Definition: message_transporter.h:83
#define tr(x)
Definition: common_defines.h:4
const char * i18n_translate(const char *s, const std::string &context)
Definition: i18n.cpp:321
string a
Definition: MakeCryptoOps.py:15
bool read_from_file(epee::wipeable_string &pass)
Definition: password.cpp:208
void serialize(Archive &a, crypto::chacha_iv &x, const boost::serialization::version_type ver)
Definition: message_store.h:493
void save(Archive &a, const std::unordered_map< h_key, hval > &x, const boost::serialization::version_type ver)
Definition: unordered_containers_boost_serialization.h:42
Definition: unordered_containers_boost_serialization.h:38
const
Definition: build_protob.py:9
const crypto::public_key null_pkey
Definition: crypto.cpp:74
const crypto::secret_key null_skey
Definition: crypto.cpp:75
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
Definition: crypto.h:67
POD_CLASS public_key
Definition: crypto.h:61
POD_CLASS hash
Definition: hash.h:48
network_type
Definition: cryptonote_config.h:273
void init_options(boost::program_options::options_description &hidden_options, boost::program_options::options_description &normal_options)
Definition: posix_daemonizer.inl:56
Definition: message_store.cpp:49
message_direction
Definition: message_store.h:72
message_state
Definition: message_store.h:78
message_processing
Definition: message_store.h:89
message_type
Definition: message_store.h:60
Definition: binary_utils.h:36
Definition: blockchain_ancestry.cpp:72
BOOST_CLASS_VERSION(nodetool::peerlist_types, nodetool::CURRENT_PEERLIST_STORAGE_ARCHIVE_VER)
static std::string decrypt(const std::string &ciphertext, const crypto::key_image &key_image, const crypto::chacha_key &key, uint8_t field)
Definition: ringdb.cpp:138
static std::string encrypt(const std::string &plaintext, const crypto::key_image &key_image, const crypto::chacha_key &key, uint8_t field)
Definition: ringdb.cpp:123
Simple DSL AAPI based on.
#define BEGIN_SERIALIZE_OBJECT()
begins the environment of the DSL \detailed for described the serialization of an object
Definition: serialization.h:191
#define FIELD(f)
tags the field with the variable name and then serializes it
Definition: serialization.h:244
#define VERSION_FIELD(v)
Definition: serialization.h:295
#define END_SERIALIZE()
self-explanatory
Definition: serialization.h:215
#define VARINT_FIELD(f)
tags and serializes the varint f
Definition: serialization.h:264
static const unsigned char iv[64]
Definition: sha512-hash.c:13
Definition: cryptonote_basic.h:501
Definition: message_store.h:143
cryptonote::account_public_address monero_address
Definition: message_store.h:147
crypto::secret_key auto_config_secret_key
Definition: message_store.h:152
bool me
Definition: message_store.h:148
bool auto_config_running
Definition: message_store.h:154
std::string transport_address
Definition: message_store.h:145
std::string label
Definition: message_store.h:144
uint32_t index
Definition: message_store.h:149
std::string auto_config_token
Definition: message_store.h:150
bool monero_address_known
Definition: message_store.h:146
crypto::public_key auto_config_public_key
Definition: message_store.h:151
std::string auto_config_transport_address
Definition: message_store.h:153
Definition: message_store.h:199
std::string label
Definition: message_store.h:200
std::string transport_address
Definition: message_store.h:201
cryptonote::account_public_address monero_address
Definition: message_store.h:202
Definition: message_store.h:215
std::string magic_string
Definition: message_store.h:216
crypto::chacha_iv iv
Definition: message_store.h:218
std::string encrypted_data
Definition: message_store.h:219
uint32_t file_version
Definition: message_store.h:217
Definition: message_store.h:191
crypto::chacha_iv iv
Definition: message_store.h:193
cryptonote::account_public_address sender_address
Definition: message_store.h:192
message internal_message
Definition: message_store.h:195
crypto::public_key encryption_public_key
Definition: message_store.h:194
Definition: message_store.h:103
uint64_t modified
Definition: message_store.h:109
uint32_t signer_index
Definition: message_store.h:111
uint32_t wallet_height
Definition: message_store.h:114
message_state state
Definition: message_store.h:113
crypto::hash hash
Definition: message_store.h:112
uint32_t round
Definition: message_store.h:115
message_type type
Definition: message_store.h:105
std::string content
Definition: message_store.h:107
uint64_t sent
Definition: message_store.h:110
uint32_t id
Definition: message_store.h:104
uint64_t created
Definition: message_store.h:108
std::string transport_id
Definition: message_store.h:117
message_direction direction
Definition: message_store.h:106
uint32_t signature_count
Definition: message_store.h:116
Definition: message_store.h:241
cryptonote::network_type nettype
Definition: message_store.h:243
uint32_t multisig_rounds_passed
Definition: message_store.h:248
crypto::secret_key view_secret_key
Definition: message_store.h:244
size_t num_transfer_details
Definition: message_store.h:249
bool has_multisig_partial_key_images
Definition: message_store.h:247
bool multisig_is_ready
Definition: message_store.h:246
cryptonote::account_public_address address
Definition: message_store.h:242
std::string mms_file
Definition: message_store.h:250
bool multisig
Definition: message_store.h:245
Definition: message_store.h:184
std::vector< uint32_t > message_ids
Definition: message_store.h:186
message_processing processing
Definition: message_store.h:185
Definition: blake256.h:36