aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mnemonics/electrum-words.cpp77
-rw-r--r--src/mnemonics/electrum-words.h22
-rw-r--r--src/simplewallet/simplewallet.cpp18
-rw-r--r--src/wallet/api/wallet.cpp4
-rw-r--r--src/wallet/api/wallet.h2
-rw-r--r--src/wallet/wallet2.cpp15
-rw-r--r--src/wallet/wallet2.h2
-rw-r--r--src/wallet/wallet2_api.h2
-rw-r--r--src/wallet/wallet_rpc_server.cpp7
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)
{