wallet: wipe seed from memory where appropriate
This commit is contained in:
+31
-13
@@ -789,7 +789,7 @@ bool wallet2::is_deterministic() const
|
||||
return keys_deterministic;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::get_seed(std::string& electrum_words, const epee::wipeable_string &passphrase) const
|
||||
bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeable_string &passphrase) const
|
||||
{
|
||||
bool keys_deterministic = is_deterministic();
|
||||
if (!keys_deterministic)
|
||||
@@ -815,7 +815,7 @@ bool wallet2::get_seed(std::string& electrum_words, const epee::wipeable_string
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::get_multisig_seed(std::string& seed, const epee::wipeable_string &passphrase, bool raw) const
|
||||
bool wallet2::get_multisig_seed(epee::wipeable_string& seed, const epee::wipeable_string &passphrase, bool raw) const
|
||||
{
|
||||
bool ready;
|
||||
uint32_t threshold, total;
|
||||
@@ -838,7 +838,7 @@ bool wallet2::get_multisig_seed(std::string& seed, const epee::wipeable_string &
|
||||
crypto::secret_key skey;
|
||||
crypto::public_key pkey;
|
||||
const account_keys &keys = get_account().get_keys();
|
||||
std::string data;
|
||||
epee::wipeable_string data;
|
||||
data.append((const char*)&threshold, sizeof(uint32_t));
|
||||
data.append((const char*)&total, sizeof(uint32_t));
|
||||
skey = keys.m_spend_secret_key;
|
||||
@@ -864,7 +864,7 @@ bool wallet2::get_multisig_seed(std::string& seed, const epee::wipeable_string &
|
||||
|
||||
if (raw)
|
||||
{
|
||||
seed = epee::string_tools::buff_to_hex_nodelimer(data);
|
||||
seed = epee::to_hex::wipeable_string({(const unsigned char*)data.data(), data.size()});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3161,7 +3161,7 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip
|
||||
* \param create_address_file Whether to create an address file
|
||||
*/
|
||||
void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password,
|
||||
const std::string& multisig_data, bool create_address_file)
|
||||
const epee::wipeable_string& multisig_data, bool create_address_file)
|
||||
{
|
||||
clear();
|
||||
prepare_file_names(wallet_);
|
||||
@@ -10671,14 +10671,14 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs)
|
||||
return n_outputs;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string wallet2::encrypt(const std::string &plaintext, const crypto::secret_key &skey, bool authenticated) const
|
||||
std::string wallet2::encrypt(const char *plaintext, size_t len, const crypto::secret_key &skey, bool authenticated) const
|
||||
{
|
||||
crypto::chacha_key key;
|
||||
crypto::generate_chacha_key(&skey, sizeof(skey), key, m_kdf_rounds);
|
||||
std::string ciphertext;
|
||||
crypto::chacha_iv iv = crypto::rand<crypto::chacha_iv>();
|
||||
ciphertext.resize(plaintext.size() + sizeof(iv) + (authenticated ? sizeof(crypto::signature) : 0));
|
||||
crypto::chacha20(plaintext.data(), plaintext.size(), key, iv, &ciphertext[sizeof(iv)]);
|
||||
ciphertext.resize(len + sizeof(iv) + (authenticated ? sizeof(crypto::signature) : 0));
|
||||
crypto::chacha20(plaintext, len, key, iv, &ciphertext[sizeof(iv)]);
|
||||
memcpy(&ciphertext[0], &iv, sizeof(iv));
|
||||
if (authenticated)
|
||||
{
|
||||
@@ -10692,12 +10692,28 @@ std::string wallet2::encrypt(const std::string &plaintext, const crypto::secret_
|
||||
return ciphertext;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string wallet2::encrypt(const epee::span<char> &plaintext, const crypto::secret_key &skey, bool authenticated) const
|
||||
{
|
||||
return encrypt(plaintext.data(), plaintext.size(), skey, authenticated);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string wallet2::encrypt(const std::string &plaintext, const crypto::secret_key &skey, bool authenticated) const
|
||||
{
|
||||
return encrypt(plaintext.data(), plaintext.size(), skey, authenticated);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string wallet2::encrypt(const epee::wipeable_string &plaintext, const crypto::secret_key &skey, bool authenticated) const
|
||||
{
|
||||
return encrypt(plaintext.data(), plaintext.size(), skey, authenticated);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string wallet2::encrypt_with_view_secret_key(const std::string &plaintext, bool authenticated) const
|
||||
{
|
||||
return encrypt(plaintext, get_account().get_keys().m_view_secret_key, authenticated);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string wallet2::decrypt(const std::string &ciphertext, const crypto::secret_key &skey, bool authenticated) const
|
||||
template<typename T>
|
||||
T wallet2::decrypt(const std::string &ciphertext, const crypto::secret_key &skey, bool authenticated) const
|
||||
{
|
||||
const size_t prefix_size = sizeof(chacha_iv) + (authenticated ? sizeof(crypto::signature) : 0);
|
||||
THROW_WALLET_EXCEPTION_IF(ciphertext.size() < prefix_size,
|
||||
@@ -10706,8 +10722,6 @@ std::string wallet2::decrypt(const std::string &ciphertext, const crypto::secret
|
||||
crypto::chacha_key key;
|
||||
crypto::generate_chacha_key(&skey, sizeof(skey), key, m_kdf_rounds);
|
||||
const crypto::chacha_iv &iv = *(const crypto::chacha_iv*)&ciphertext[0];
|
||||
std::string plaintext;
|
||||
plaintext.resize(ciphertext.size() - prefix_size);
|
||||
if (authenticated)
|
||||
{
|
||||
crypto::hash hash;
|
||||
@@ -10718,10 +10732,14 @@ std::string wallet2::decrypt(const std::string &ciphertext, const crypto::secret
|
||||
THROW_WALLET_EXCEPTION_IF(!crypto::check_signature(hash, pkey, signature),
|
||||
error::wallet_internal_error, "Failed to authenticate ciphertext");
|
||||
}
|
||||
crypto::chacha20(ciphertext.data() + sizeof(iv), ciphertext.size() - prefix_size, key, iv, &plaintext[0]);
|
||||
return plaintext;
|
||||
std::unique_ptr<char[]> buffer{new char[ciphertext.size() - prefix_size]};
|
||||
auto wiper = epee::misc_utils::create_scope_leave_handler([&]() { memwipe(buffer.get(), ciphertext.size() - prefix_size); });
|
||||
crypto::chacha20(ciphertext.data() + sizeof(iv), ciphertext.size() - prefix_size, key, iv, buffer.get());
|
||||
return T(buffer.get(), ciphertext.size() - prefix_size);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template epee::wipeable_string wallet2::decrypt(const std::string &ciphertext, const crypto::secret_key &skey, bool authenticated) const;
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string wallet2::decrypt_with_view_secret_key(const std::string &ciphertext, bool authenticated) const
|
||||
{
|
||||
return decrypt(ciphertext, get_account().get_keys().m_view_secret_key, authenticated);
|
||||
|
||||
Reference in New Issue
Block a user