diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mnemonics/electrum-words.cpp | 77 | ||||
-rw-r--r-- | src/mnemonics/electrum-words.h | 22 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 18 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 4 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 15 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet2_api.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 7 |
9 files changed, 94 insertions, 55 deletions
diff --git a/src/mnemonics/electrum-words.cpp b/src/mnemonics/electrum-words.cpp index 6ae33a743..1b14905f6 100644 --- a/src/mnemonics/electrum-words.cpp +++ b/src/mnemonics/electrum-words.cpp @@ -236,11 +236,13 @@ namespace crypto /*! * \brief Converts seed words to bytes (secret key). * \param words String containing the words separated by spaces. - * \param dst To put the secret key restored from the words. + * \param dst To put the secret data restored from the words. + * \param len The number of bytes to expect, 0 if unknown + * \param duplicate If true and len is not zero, we accept half the data, and duplicate it * \param language_name Language of the seed as found gets written here. * \return false if not a multiple of 3 words, or if word is not in the words list */ - bool words_to_bytes(std::string words, crypto::secret_key& dst, + bool words_to_bytes(std::string words, std::string& dst, size_t len, bool duplicate, std::string &language_name) { std::vector<std::string> seed; @@ -248,15 +250,23 @@ namespace crypto boost::algorithm::trim(words); boost::split(seed, words, boost::is_any_of(" "), boost::token_compress_on); - // error on non-compliant word list - if (seed.size() != seed_length/2 && seed.size() != seed_length && - seed.size() != seed_length + 1) - { + if (len % 4) return false; - } - // If it is seed with a checksum. - bool has_checksum = seed.size() == (seed_length + 1); + bool has_checksum = true; + if (len) + { + // error on non-compliant word list + const size_t expected = len * 8 * 3 / 32; + if (seed.size() != expected/2 && seed.size() != expected && + seed.size() != expected + 1) + { + return false; + } + + // If it is seed with a checksum. + has_checksum = seed.size() == (expected + 1); + } std::vector<uint32_t> matched_indices; Language::Base *language; @@ -290,32 +300,55 @@ namespace crypto if (!(val % word_list_length == w1)) return false; - memcpy(dst.data + i * 4, &val, 4); // copy 4 bytes to position + dst.append((const char*)&val, 4); // copy 4 bytes to position } - std::string wlist_copy = words; - if (seed.size() == seed_length/2) + if (len > 0 && duplicate) { - memcpy(dst.data+16, dst.data, 16); // if electrum 12-word seed, duplicate - wlist_copy += ' '; - wlist_copy += words; + const size_t expected = len * 3 / 32; + std::string wlist_copy = words; + if (seed.size() == expected/2) + { + dst.append(dst); // if electrum 12-word seed, duplicate + wlist_copy += ' '; + wlist_copy += words; + } } return true; } /*! + * \brief Converts seed words to bytes (secret key). + * \param words String containing the words separated by spaces. + * \param dst To put the secret key restored from the words. + * \param language_name Language of the seed as found gets written here. + * \return false if not a multiple of 3 words, or if word is not in the words list + */ + bool words_to_bytes(std::string words, crypto::secret_key& dst, + std::string &language_name) + { + std::string s; + if (!words_to_bytes(words, s, sizeof(dst), true, language_name)) + return false; + if (s.size() != sizeof(dst)) + return false; + dst = *(const crypto::secret_key*)s.data(); + return true; + } + + /*! * \brief Converts bytes (secret key) to seed words. * \param src Secret key * \param words Space delimited concatenated words get written here. * \param language_name Seed language name * \return true if successful false if not. Unsuccessful if wrong key size. */ - bool bytes_to_words(const crypto::secret_key& src, std::string& words, + bool bytes_to_words(const char *src, size_t len, std::string& words, const std::string &language_name) { - if (sizeof(src.data) % 4 != 0 || sizeof(src.data) == 0) return false; + if (len % 4 != 0 || len == 0) return false; Language::Base *language; if (language_name == "English") @@ -376,13 +409,13 @@ namespace crypto uint32_t word_list_length = word_list.size(); // 8 bytes -> 3 words. 8 digits base 16 -> 3 digits base 1626 - for (unsigned int i=0; i < sizeof(src.data)/4; i++, words += ' ') + for (unsigned int i=0; i < len/4; i++, words += ' ') { uint32_t w1, w2, w3; uint32_t val; - memcpy(&val, (src.data) + (i * 4), 4); + memcpy(&val, src + (i * 4), 4); w1 = val % word_list_length; w2 = ((val / word_list_length) + w1) % word_list_length; @@ -404,6 +437,12 @@ namespace crypto return true; } + bool bytes_to_words(const crypto::secret_key& src, std::string& words, + const std::string &language_name) + { + return bytes_to_words(src.data, sizeof(src), words, language_name); + } + /*! * \brief Gets a list of seed languages that are supported. * \param languages The vector is set to the list of languages. diff --git a/src/mnemonics/electrum-words.h b/src/mnemonics/electrum-words.h index 94ce9c200..941768352 100644 --- a/src/mnemonics/electrum-words.h +++ b/src/mnemonics/electrum-words.h @@ -64,6 +64,17 @@ namespace crypto /*! * \brief Converts seed words to bytes (secret key). * \param words String containing the words separated by spaces. + * \param dst To put the secret data restored from the words. + * \param len The number of bytes to expect, 0 if unknown + * \param duplicate If true and len is not zero, we accept half the data, and duplicate it + * \param language_name Language of the seed as found gets written here. + * \return false if not a multiple of 3 words, or if word is not in the words list + */ + bool words_to_bytes(std::string words, std::string& dst, size_t len, bool duplicate, + std::string &language_name); + /*! + * \brief Converts seed words to bytes (secret key). + * \param words String containing the words separated by spaces. * \param dst To put the secret key restored from the words. * \param language_name Language of the seed as found gets written here. * \return false if not a multiple of 3 words, or if word is not in the words list @@ -72,6 +83,17 @@ namespace crypto std::string &language_name); /*! + * \brief Converts bytes to seed words. + * \param src Secret data + * \param len Secret data length in bytes (positive multiples of 4 only) + * \param words Space delimited concatenated words get written here. + * \param language_name Seed language name + * \return true if successful false if not. Unsuccessful if wrong key size. + */ + bool bytes_to_words(const char *src, size_t len, std::string& words, + const std::string &language_name); + + /*! * \brief Converts bytes (secret key) to seed words. * \param src Secret key * \param words Space delimited concatenated words get written here. diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index d971f4fed..ebcfea1a9 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3964,20 +3964,12 @@ bool simple_wallet::get_tx_proof(const std::vector<std::string> &args) try { - std::string error_str; - std::string sig_str = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, args.size() == 3 ? args[2] : "", error_str); - if (sig_str.empty()) - { - fail_msg_writer() << error_str; - } + std::string sig_str = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, args.size() == 3 ? args[2] : ""); + const std::string filename = "monero_tx_proof"; + if (epee::file_io_utils::save_string_to_file(filename, sig_str)) + success_msg_writer() << tr("signature file saved to: ") << filename; else - { - const std::string filename = "monero_tx_proof"; - if (epee::file_io_utils::save_string_to_file(filename, sig_str)) - success_msg_writer() << tr("signature file saved to:") << filename; - else - fail_msg_writer() << tr("failed to save signature file"); - } + fail_msg_writer() << tr("failed to save signature file"); } catch (const std::exception &e) { diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index db8911042..b14c2e1eb 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1467,7 +1467,7 @@ bool WalletImpl::checkTxKey(const std::string &txid_str, std::string tx_key_str, } } -std::string WalletImpl::getTxProof(const std::string &txid_str, const std::string &address_str, const std::string &message, std::string &error_str) const +std::string WalletImpl::getTxProof(const std::string &txid_str, const std::string &address_str, const std::string &message) const { crypto::hash txid; if (!epee::string_tools::hex_to_pod(txid_str, txid)) @@ -1488,7 +1488,7 @@ std::string WalletImpl::getTxProof(const std::string &txid_str, const std::strin try { m_status = Status_Ok; - return m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, message, error_str); + return m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, message); } catch (const std::exception &e) { diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index ecf540f22..50d46fc19 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -138,7 +138,7 @@ public: virtual std::string getUserNote(const std::string &txid) const; virtual std::string getTxKey(const std::string &txid) const; virtual bool checkTxKey(const std::string &txid, std::string tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations); - virtual std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message, std::string &error_str) const; + virtual std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message) const; virtual bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations); virtual std::string signMessage(const std::string &message); virtual bool verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c4124a677..90a36e032 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6306,9 +6306,8 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de } } -std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message, std::string &error_str) +std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message) { - error_str = ""; // determine if the address is found in the subaddress hash table (i.e. whether the proof is outbound or inbound) const bool is_out = m_subaddresses.count(address.m_spend_public_key) == 0; @@ -6324,11 +6323,7 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac { crypto::secret_key tx_key; std::vector<crypto::secret_key> additional_tx_keys; - if (!get_tx_key(txid, tx_key, additional_tx_keys)) - { - error_str = tr("Tx secret key wasn't found in the wallet file."); - return {}; - } + THROW_WALLET_EXCEPTION_IF(!get_tx_key(txid, tx_key, additional_tx_keys), error::wallet_internal_error, "Tx secret key wasn't found in the wallet file."); const size_t num_sigs = 1 + additional_tx_keys.size(); shared_secret.resize(num_sigs); @@ -6431,11 +6426,7 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac bool in_pool; uint64_t confirmations; check_tx_key_helper(txid, derivation, additional_derivations, address, received, in_pool, confirmations); - if (!received) - { - error_str = tr("No funds received in this tx."); - return {}; - } + THROW_WALLET_EXCEPTION_IF(!received, error::wallet_internal_error, tr("No funds received in this tx.")); // concatenate all signature strings for (size_t i = 0; i < num_sigs; ++i) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index ed224136d..8284fcd73 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -713,7 +713,7 @@ namespace tools bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const; void check_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations); void check_tx_key_helper(const crypto::hash &txid, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations); - std::string get_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message, std::string &error_str); + std::string get_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message); bool check_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message, const std::string &sig_str, uint64_t &received, bool &in_pool, uint64_t &confirmations); /*! diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index 8d6b2ffa9..f84541ae1 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -701,7 +701,7 @@ struct Wallet virtual std::string getUserNote(const std::string &txid) const = 0; virtual std::string getTxKey(const std::string &txid) const = 0; virtual bool checkTxKey(const std::string &txid, std::string tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) = 0; - virtual std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message, std::string &error_str) const = 0; + virtual std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message) const = 0; virtual bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations) = 0; /* diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 97a414648..666981918 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -1584,12 +1584,7 @@ namespace tools try { - res.signature = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, req.message, er.message); - if (res.signature.empty()) - { - er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; - return false; - } + res.signature = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, req.message); } catch (const std::exception &e) { |