aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet2.cpp
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2014-12-01 20:14:58 +0200
committerRiccardo Spagni <ric@spagni.net>2014-12-01 20:15:06 +0200
commit4cd15cdde58c00bfcde5af1c9f57779e62a76f2f (patch)
tree89b46555ee93ac9eb2af22afae639a51d904d090 /src/wallet/wallet2.cpp
parentMerge pull request #191 (diff)
parentPrints seed after wallet upgrade. Removed iostream include. (diff)
downloadmonero-4cd15cdde58c00bfcde5af1c9f57779e62a76f2f.tar.xz
Merge pull request #1
f1eaf88 Prints seed after wallet upgrade. Removed iostream include. (Oran Juice) 70971be Doxygen comments (Oran Juice) 031ca23 Rewrites to old wallet file correctly (Oran Juice) 1f833dc Doxygen comments in (Oran Juice) 0bd88ff Writes seed language while generating wallet. Wallet open fix. (Oran Juice) 09a659e Stores seed language in wallet file. added rapidjson. Yet to test backward compatibility (Oran Juice)
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r--src/wallet/wallet2.cpp89
1 files changed, 84 insertions, 5 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 8a868f3d8..6c271f037 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -48,6 +48,9 @@ using namespace epee;
#include "cryptonote_protocol/blobdatatype.h"
#include "mnemonics/electrum-words.h"
#include "common/dns_utils.h"
+#include "rapidjson/document.h"
+#include "rapidjson/writer.h"
+#include "rapidjson/stringbuffer.h"
extern "C"
{
@@ -99,11 +102,19 @@ bool wallet2::get_seed(std::string& electrum_words)
}
/*!
* \brief Sets the seed language
+ * \param language Seed language to set to
*/
void wallet2::set_seed_language(const std::string &language)
{
seed_language = language;
}
+/*!
+ * \brief Tells if the wallet file is deprecated.
+ */
+bool wallet2::is_deprecated() const
+{
+ return is_old_file_format;
+}
//----------------------------------------------------------------------------------------------------
void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_t height)
{
@@ -432,7 +443,13 @@ bool wallet2::clear()
m_local_bc_height = 1;
return true;
}
-//----------------------------------------------------------------------------------------------------
+
+/*!
+ * \brief Stores wallet information to wallet file.
+ * \param keys_file_name Name of wallet file
+ * \param password Password of wallet file
+ * \return Whether it was successful.
+ */
bool wallet2::store_keys(const std::string& keys_file_name, const std::string& password)
{
std::string account_data;
@@ -440,6 +457,22 @@ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& p
CHECK_AND_ASSERT_MES(r, false, "failed to serialize wallet keys");
wallet2::keys_file_data keys_file_data = boost::value_initialized<wallet2::keys_file_data>();
+ // Create a JSON object with "key_data" and "seed_language" as keys.
+ rapidjson::Document json;
+ json.SetObject();
+ rapidjson::Value value(rapidjson::kStringType);
+ value.SetString(account_data.c_str(), account_data.length());
+ json.AddMember("key_data", value, json.GetAllocator());
+ value.SetString(seed_language.c_str(), seed_language.length());
+ json.AddMember("seed_language", value, json.GetAllocator());
+
+ // Serialize the JSON object
+ rapidjson::StringBuffer buffer;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+ json.Accept(writer);
+ account_data = buffer.GetString();
+
+ // Encrypt the entire JSON object.
crypto::chacha8_key key;
crypto::generate_chacha8_key(password, key);
std::string cipher;
@@ -465,30 +498,60 @@ namespace
return r && expected_pub == pub;
}
}
-//----------------------------------------------------------------------------------------------------
+
+/*!
+ * \brief Load wallet information from wallet file.
+ * \param keys_file_name Name of wallet file
+ * \param password Password of wallet file
+ */
void wallet2::load_keys(const std::string& keys_file_name, const std::string& password)
{
wallet2::keys_file_data keys_file_data;
std::string buf;
bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf);
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name);
+
+ // Decrypt the contents
r = ::serialization::parse_binary(buf, keys_file_data);
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "internal error: failed to deserialize \"" + keys_file_name + '\"');
-
crypto::chacha8_key key;
crypto::generate_chacha8_key(password, key);
std::string account_data;
account_data.resize(keys_file_data.account_data.size());
crypto::chacha8(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
+ // The contents should be JSON if the wallet follows the new format.
+ rapidjson::Document json;
+ if (json.Parse(account_data.c_str(), keys_file_data.account_data.size()).HasParseError())
+ {
+ is_old_file_format = true;
+ }
+ else
+ {
+ account_data = std::string(json["key_data"].GetString(), json["key_data"].GetString() +
+ json["key_data"].GetStringLength());
+ set_seed_language(std::string(json["seed_language"].GetString(), json["seed_language"].GetString() +
+ json["seed_language"].GetStringLength()));
+ }
+
const cryptonote::account_keys& keys = m_account.get_keys();
r = epee::serialization::load_t_from_binary(m_account, account_data);
r = r && verify_keys(keys.m_view_secret_key, keys.m_account_address.m_view_public_key);
r = r && verify_keys(keys.m_spend_secret_key, keys.m_account_address.m_spend_public_key);
THROW_WALLET_EXCEPTION_IF(!r, error::invalid_password);
}
-//----------------------------------------------------------------------------------------------------
-crypto::secret_key wallet2::generate(const std::string& wallet_, const std::string& password, const crypto::secret_key& recovery_param, bool recover, bool two_random)
+
+/*!
+ * \brief Generates a wallet or restores one.
+ * \param wallet_ Name of wallet file
+ * \param password Password of wallet file
+ * \param recovery_param If it is a restore, the recovery key
+ * \param recover Whether it is a restore
+ * \param two_random Whether it is a non-deterministic wallet
+ * \return The secret key of the generated wallet
+ */
+crypto::secret_key wallet2::generate(const std::string& wallet_, const std::string& password,
+ const crypto::secret_key& recovery_param, bool recover, bool two_random)
{
clear();
prepare_file_names(wallet_);
@@ -514,6 +577,22 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const std::stri
store();
return retval;
}
+
+/*!
+ * \brief Rewrites to the wallet file for wallet upgrade (doesn't generate key, assumes it's already there)
+ * \param wallet_name Name of wallet file (should exist)
+ * \param password Password for wallet file
+ */
+void wallet2::rewrite(const std::string& wallet_name, const std::string& password)
+{
+ prepare_file_names(wallet_name);
+ boost::system::error_code ignored_ec;
+ THROW_WALLET_EXCEPTION_IF(!boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_not_found, m_wallet_file);
+ THROW_WALLET_EXCEPTION_IF(!boost::filesystem::exists(m_keys_file, ignored_ec), error::file_not_found, m_keys_file);
+ bool r = store_keys(m_keys_file, password);
+ THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file);
+ store();
+}
//----------------------------------------------------------------------------------------------------
void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists)
{