mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 15:09:59 +01:00
Merge #16946: wallet: include a checksum of encrypted private keys
d67055e00dUpgrade or rewrite encrypted key checksums (Andrew Chow)c9a9ddb414Set fDecryptionThoroughlyChecked based on whether crypted key checksums are valid (Andrew Chow)a8334f7ac3Read and write a checksum for encrypted keys (Andrew Chow) Pull request description: Adds a checksum to the encrypted key record in the wallet database so that encrypted keys can be checked for corruption on wallet loading, in the same way that unencrypted keys are. This allows for us to skip the full decryption of keys upon the first unlocking of the wallet in that session as any key corruption will have already been detected. The checksum is just the double SHA256 of the encrypted key and it is appended to the record after the encrypted key itself. This is backwards compatible as old wallets will be able to read the encrypted key and ignore that there is more data in the stream. Additionally, old wallets will be upgraded upon their first unlocking (so that key decryption is checked before we commit to a checksum of the encrypted key) and a wallet flag set indicating that. The presence of the wallet flag lets us skip the full decryption as if `fDecryptionThoroughlyChecked` were true. This does mean that the first time an old wallet is unlocked in a new version will take much longer, but subsequent unlocks will be instantaneous. Furthermore, corruption will be detected upon loading rather than on trying to send so wallet corruption will be detected sooner. Fixes #12423 ACKs for top commit: laanwj: code review ACKd67055e00djonatack: Code review ACKd67055e00dmeshcollider: Code review ACKd67055e00dTree-SHA512: d5c1c10cfcb5db9e10dcf2326423565a9f499290b81f3155ec72254ed5bd7491e2ff5c50e98590eb07842c20d7797b4efa1c3475bae64971d500aad3b4e711d4
This commit is contained in:
@@ -220,6 +220,7 @@ bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key
|
||||
bool keyPass = mapCryptedKeys.empty(); // Always pass when there are no encrypted keys
|
||||
bool keyFail = false;
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||
WalletBatch batch(m_storage.GetDatabase());
|
||||
for (; mi != mapCryptedKeys.end(); ++mi)
|
||||
{
|
||||
const CPubKey &vchPubKey = (*mi).second.first;
|
||||
@@ -233,6 +234,10 @@ bool LegacyScriptPubKeyMan::CheckDecryptionKey(const CKeyingMaterial& master_key
|
||||
keyPass = true;
|
||||
if (fDecryptionThoroughlyChecked)
|
||||
break;
|
||||
else {
|
||||
// Rewrite these encrypted keys with checksums
|
||||
batch.WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
|
||||
}
|
||||
}
|
||||
if (keyPass && keyFail)
|
||||
{
|
||||
@@ -713,8 +718,13 @@ bool LegacyScriptPubKeyMan::AddKeyPubKeyInner(const CKey& key, const CPubKey &pu
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||
bool LegacyScriptPubKeyMan::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret, bool checksum_valid)
|
||||
{
|
||||
// Set fDecryptionThoroughlyChecked to false when the checksum is invalid
|
||||
if (!checksum_valid) {
|
||||
fDecryptionThoroughlyChecked = false;
|
||||
}
|
||||
|
||||
return AddCryptedKeyInner(vchPubKey, vchCryptedSecret);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user