forked from lthn/blockchain
wallet2: made new format unloadable by old wallets + correct error on file read errors
This commit is contained in:
parent
d9150e592a
commit
4b3e8da6fa
4 changed files with 52 additions and 17 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue