@ -2378,7 +2378,7 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
std : : string cipher ;
cipher . resize ( account_data . size ( ) ) ;
keys_file_data . iv = crypto : : rand < crypto : : chacha_iv > ( ) ;
crypto : : chacha 8 ( account_data . data ( ) , account_data . size ( ) , key , keys_file_data . iv , & cipher [ 0 ] ) ;
crypto : : chacha 20 ( account_data . data ( ) , account_data . size ( ) , key , keys_file_data . iv , & cipher [ 0 ] ) ;
keys_file_data . account_data = cipher ;
std : : string buf ;
@ -2406,6 +2406,7 @@ namespace
*/
bool wallet2 : : load_keys ( const std : : string & keys_file_name , const epee : : wipeable_string & password )
{
rapidjson : : Document json ;
wallet2 : : keys_file_data keys_file_data ;
std : : string buf ;
bool r = epee : : file_io_utils : : load_file_to_string ( keys_file_name , buf ) ;
@ -2418,10 +2419,11 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
crypto : : generate_chacha_key ( password . data ( ) , password . size ( ) , 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 ] ) ;
crypto : : chacha20 ( keys_file_data . account_data . data ( ) , keys_file_data . account_data . size ( ) , key , keys_file_data . iv , & account_data [ 0 ] ) ;
if ( json . Parse ( account_data . c_str ( ) ) . HasParseError ( ) | | ! json . IsObject ( ) )
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 ( ) ) . HasParseError ( ) )
{
is_old_file_format = true ;
@ -2591,6 +2593,7 @@ bool wallet2::verify_password(const epee::wipeable_string& password) const
*/
bool wallet2 : : verify_password ( const std : : string & keys_file_name , const epee : : wipeable_string & password , bool no_spend_key )
{
rapidjson : : Document json ;
wallet2 : : keys_file_data keys_file_data ;
std : : string buf ;
bool r = epee : : file_io_utils : : load_file_to_string ( keys_file_name , buf ) ;
@ -2603,10 +2606,11 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip
crypto : : generate_chacha_key ( password . data ( ) , password . size ( ) , 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 ] ) ;
crypto : : chacha20 ( keys_file_data . account_data . data ( ) , keys_file_data . account_data . size ( ) , key , keys_file_data . iv , & account_data [ 0 ] ) ;
if ( json . Parse ( account_data . c_str ( ) ) . HasParseError ( ) | | ! json . IsObject ( ) )
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 ( ) ) . HasParseError ( ) )
{
// old format before JSON wallet key file format
@ -3345,30 +3349,42 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
generate_chacha_key_from_secret_keys ( key ) ;
std : : string cache_data ;
cache_data . resize ( cache_file_data . cache_data . size ( ) ) ;
crypto : : chacha 8 ( cache_file_data . cache_data . data ( ) , cache_file_data . cache_data . size ( ) , key , cache_file_data . iv , & cache_data [ 0 ] ) ;
crypto : : chacha 20 ( cache_file_data . cache_data . data ( ) , cache_file_data . cache_data . size ( ) , key , cache_file_data . iv , & cache_data [ 0 ] ) ;
std : : stringstream iss ;
iss < < cache_data ;
try {
std : : stringstream iss ;
iss < < cache_data ;
boost : : archive : : portable_binary_iarchive ar ( iss ) ;
ar > > * this ;
}
catch ( . . . )
{
LOG_PRINT_L0 ( " Failed to open portable binary, trying unportable " ) ;
boost : : filesystem : : copy_file ( m_wallet_file , m_wallet_file + " .unportable " , boost : : filesystem : : copy_option : : overwrite_if_exists ) ;
iss . str ( " " ) ;
iss < < cache_data ;
boost : : archive : : binary_iarchive ar ( iss ) ;
ar > > * this ;
crypto : : chacha8 ( cache_file_data . cache_data . data ( ) , cache_file_data . cache_data . size ( ) , key , cache_file_data . iv , & cache_data [ 0 ] ) ;
try
{
std : : stringstream iss ;
iss < < cache_data ;
boost : : archive : : portable_binary_iarchive ar ( iss ) ;
ar > > * this ;
}
catch ( . . . )
{
LOG_PRINT_L0 ( " Failed to open portable binary, trying unportable " ) ;
boost : : filesystem : : copy_file ( m_wallet_file , m_wallet_file + " .unportable " , boost : : filesystem : : copy_option : : overwrite_if_exists ) ;
std : : stringstream iss ;
iss . str ( " " ) ;
iss < < cache_data ;
boost : : archive : : binary_iarchive ar ( iss ) ;
ar > > * this ;
}
}
}
catch ( . . . )
{
LOG_PRINT_L1 ( " Failed to load encrypted cache, trying unencrypted " ) ;
std : : stringstream iss ;
iss < < buf ;
try {
std : : stringstream iss ;
iss < < buf ;
boost : : archive : : portable_binary_iarchive ar ( iss ) ;
ar > > * this ;
}
@ -3376,6 +3392,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
{
LOG_PRINT_L0 ( " Failed to open portable binary, trying unportable " ) ;
boost : : filesystem : : copy_file ( m_wallet_file , m_wallet_file + " .unportable " , boost : : filesystem : : copy_option : : overwrite_if_exists ) ;
std : : stringstream iss ;
iss . str ( " " ) ;
iss < < buf ;
boost : : archive : : binary_iarchive ar ( iss ) ;
@ -3505,7 +3522,7 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas
std : : string cipher ;
cipher . resize ( cache_file_data . cache_data . size ( ) ) ;
cache_file_data . iv = crypto : : rand < crypto : : chacha_iv > ( ) ;
crypto : : chacha 8 ( cache_file_data . cache_data . data ( ) , cache_file_data . cache_data . size ( ) , key , cache_file_data . iv , & cipher [ 0 ] ) ;
crypto : : chacha 20 ( cache_file_data . cache_data . data ( ) , cache_file_data . cache_data . size ( ) , key , cache_file_data . iv , & cipher [ 0 ] ) ;
cache_file_data . cache_data = cipher ;
const std : : string new_file = same_file ? m_wallet_file + " .new " : path ;
@ -8725,7 +8742,7 @@ std::string wallet2::encrypt(const std::string &plaintext, const crypto::secret_
std : : string ciphertext ;
crypto : : chacha_iv iv = crypto : : rand < crypto : : chacha_iv > ( ) ;
ciphertext . resize ( plaintext . size ( ) + sizeof ( iv ) + ( authenticated ? sizeof ( crypto : : signature ) : 0 ) ) ;
crypto : : chacha 8 ( plaintext . data ( ) , plaintext . size ( ) , key , iv , & ciphertext [ sizeof ( iv ) ] ) ;
crypto : : chacha 20 ( plaintext . data ( ) , plaintext . size ( ) , key , iv , & ciphertext [ sizeof ( iv ) ] ) ;
memcpy ( & ciphertext [ 0 ] , & iv , sizeof ( iv ) ) ;
if ( authenticated )
{
@ -8765,7 +8782,7 @@ 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 : : chacha 8 ( ciphertext . data ( ) + sizeof ( iv ) , ciphertext . size ( ) - prefix_size , key , iv , & plaintext [ 0 ] ) ;
crypto : : chacha 20 ( ciphertext . data ( ) + sizeof ( iv ) , ciphertext . size ( ) - prefix_size , key , iv , & plaintext [ 0 ] ) ;
return plaintext ;
}
//----------------------------------------------------------------------------------------------------