1
0
Fork 0
forked from lthn/blockchain

wallet2: made new format unloadable by old wallets + correct error on file read errors

This commit is contained in:
sowle 2020-05-19 20:12:43 +03:00
parent d9150e592a
commit 4b3e8da6fa
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
4 changed files with 52 additions and 17 deletions

View file

@ -143,7 +143,8 @@
#define POS_MINIMUM_COINSTAKE_AGE 10 // blocks count
#define WALLET_FILE_SIGNATURE 0x1111012101101011LL //Bender's nightmare
#define WALLET_FILE_SIGNATURE_OLD 0x1111012101101011LL // Bender's nightmare
#define WALLET_FILE_SIGNATURE_V2 0x111101120101011LL // another Bender's nightmare
#define WALLET_FILE_MAX_BODY_SIZE 0x88888888L //2GB
#define WALLET_FILE_MAX_KEYS_SIZE 10000 //
#define WALLET_BRAIN_DATE_OFFSET 1543622400

View file

@ -2037,20 +2037,27 @@ bool wallet2::prepare_file_names(const std::wstring& file_path)
return true;
}
//----------------------------------------------------------------------------------------------------
void wallet2::load_keys(const std::string& buff, const std::string& password)
void wallet2::load_keys(const std::string& buff, const std::string& password, uint64_t file_signature)
{
wallet2::keys_file_data keys_file_data;
// std::string buf;
// bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf);
// CHECK_AND_THROW_WALLET_EX(!r, error::file_read_error, keys_file_name);
bool r = ::serialization::parse_binary(buff, keys_file_data);
bool r = false;
wallet2::keys_file_data kf_data = AUTO_VAL_INIT(kf_data);
if (file_signature == WALLET_FILE_SIGNATURE_OLD)
{
wallet2::keys_file_data_old kf_data_old;
r = ::serialization::parse_binary(buff, kf_data_old);
kf_data = wallet2::keys_file_data::from_old(kf_data_old);
}
else if (file_signature == WALLET_FILE_SIGNATURE_V2)
{
r = ::serialization::parse_binary(buff, kf_data);
}
THROW_IF_TRUE_WALLET_EX(!r, error::wallet_internal_error, "internal error: failed to deserialize");
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]);
account_data.resize(kf_data.account_data.size());
crypto::chacha8(kf_data.account_data.data(), kf_data.account_data.size(), key, kf_data.iv, &account_data[0]);
const currency::account_keys& keys = m_account.get_keys();
r = epee::serialization::load_t_from_binary(m_account, account_data);
@ -2131,22 +2138,22 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password)
THROW_IF_TRUE_WALLET_EX(e || !exists, error::file_not_found, epee::string_encoding::convert_to_ansii(m_wallet_file));
boost::filesystem::ifstream data_file;
data_file.open(m_wallet_file, std::ios_base::binary | std::ios_base::in);
THROW_IF_TRUE_WALLET_EX(data_file.fail(), error::file_not_found, epee::string_encoding::convert_to_ansii(m_wallet_file));
THROW_IF_TRUE_WALLET_EX(data_file.fail(), error::file_read_error, epee::string_encoding::convert_to_ansii(m_wallet_file));
wallet_file_binary_header wbh = AUTO_VAL_INIT(wbh);
data_file.read((char*)&wbh, sizeof(wbh));
THROW_IF_TRUE_WALLET_EX(data_file.fail(), error::file_not_found, epee::string_encoding::convert_to_ansii(m_wallet_file));
THROW_IF_TRUE_WALLET_EX(data_file.fail(), error::file_read_error, epee::string_encoding::convert_to_ansii(m_wallet_file));
THROW_IF_TRUE_WALLET_EX(wbh.m_signature != WALLET_FILE_SIGNATURE, error::file_not_found, epee::string_encoding::convert_to_ansii(m_wallet_file));
THROW_IF_TRUE_WALLET_EX(wbh.m_signature != WALLET_FILE_SIGNATURE_OLD && wbh.m_signature != WALLET_FILE_SIGNATURE_V2, error::file_read_error, epee::string_encoding::convert_to_ansii(m_wallet_file));
THROW_IF_TRUE_WALLET_EX(wbh.m_cb_body > WALLET_FILE_MAX_BODY_SIZE ||
wbh.m_cb_keys > WALLET_FILE_MAX_KEYS_SIZE, error::file_not_found, epee::string_encoding::convert_to_ansii(m_wallet_file));
wbh.m_cb_keys > WALLET_FILE_MAX_KEYS_SIZE, error::file_read_error, epee::string_encoding::convert_to_ansii(m_wallet_file));
keys_buff.resize(wbh.m_cb_keys);
data_file.read((char*)keys_buff.data(), wbh.m_cb_keys);
load_keys(keys_buff, password);
load_keys(keys_buff, password, wbh.m_signature);
bool need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, data_file);
@ -2188,7 +2195,7 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor
//store data
wallet_file_binary_header wbh = AUTO_VAL_INIT(wbh);
wbh.m_signature = WALLET_FILE_SIGNATURE;
wbh.m_signature = WALLET_FILE_SIGNATURE_V2;
wbh.m_cb_keys = keys_buff.size();
//@#@ change it to proper
wbh.m_cb_body = 1000;

View file

@ -445,7 +445,7 @@ namespace tools
typedef std::map<uint64_t, std::set<size_t> > free_amounts_cache_type;
struct keys_file_data
struct keys_file_data_old
{
crypto::chacha8_iv iv;
std::string account_data;
@ -455,6 +455,29 @@ namespace tools
FIELD(account_data)
END_SERIALIZE()
};
struct keys_file_data
{
uint8_t version;
crypto::chacha8_iv iv;
std::string account_data;
static keys_file_data from_old(const keys_file_data_old& v)
{
keys_file_data result = AUTO_VAL_INIT(result);
result.iv = v.iv;
result.account_data = v.account_data;
return result;
}
DEFINE_SERIALIZATION_VERSION(1)
BEGIN_SERIALIZE_OBJECT()
VERSION_ENTRY(version)
FIELD(iv)
FIELD(account_data)
END_SERIALIZE()
};
void assign_account(const currency::account_base& acc);
void generate(const std::wstring& path, const std::string& password, bool auditable_wallet);
void restore(const std::wstring& path, const std::string& pass, const std::string& seed_phrase);
@ -789,7 +812,7 @@ private:
void add_transfers_to_expiration_list(const std::vector<uint64_t>& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id);
void remove_transfer_from_expiration_list(uint64_t transfer_index);
void load_keys(const std::string& keys_file_name, const std::string& password);
void load_keys(const std::string& keys_file_name, const std::string& password, uint64_t file_signature);
void process_new_transaction(const currency::transaction& tx, uint64_t height, const currency::block& b);
void detach_blockchain(uint64_t including_height);
bool extract_offers_from_transfer_entry(size_t i, std::unordered_map<crypto::hash, bc_services::offer_details_ex>& offers_local);

View file

@ -769,6 +769,10 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st
{
return API_RETURN_CODE_FILE_NOT_FOUND;
}
catch (const tools::error::file_read_error&)
{
return API_RETURN_CODE_INVALID_FILE;
}
catch (const tools::error::wallet_load_notice_wallet_restored& /**/)
{
return_code = API_RETURN_CODE_FILE_RESTORED;