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