0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-04 13:55:23 -05:00

wallet: Remove unused encryption keys from watchonly wallets

Due to a bug in earlier versions, some wallets without private keys may
have an encryption key. This encryption key is unused and can lead to
confusing behavior elsewhere. When such wallets are detected, those
encryption keys will now be deleted from the wallet. For safety, we only
do this to wallets which have private keys disabled, have encryption keys,
and definitely do not have encrypted keys.
This commit is contained in:
Andrew Chow 2023-10-24 17:45:01 -04:00 committed by Ava Chow
parent 813a16a463
commit 2b9279b50a
2 changed files with 21 additions and 0 deletions

View file

@ -154,6 +154,11 @@ bool WalletBatch::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
return WriteIC(std::make_pair(DBKeys::MASTER_KEY, nID), kMasterKey, true);
}
bool WalletBatch::EraseMasterKey(unsigned int id)
{
return EraseIC(std::make_pair(DBKeys::MASTER_KEY, id));
}
bool WalletBatch::WriteCScript(const uint160& hash, const CScript& redeemScript)
{
return WriteIC(std::make_pair(DBKeys::CSCRIPT, hash), redeemScript, false);
@ -1241,6 +1246,21 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
result = DBErrors::CORRUPT;
}
// Since it was accidentally possible to "encrypt" a wallet with private keys disabled, we should check if this is
// such a wallet and remove the encryption key records to avoid any future issues.
// Although wallets without private keys should not have *ckey records, we should double check that.
// Removing the mkey records is only safe if there are no *ckey records.
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && pwallet->HasEncryptionKeys() && !pwallet->HaveCryptedKeys()) {
pwallet->WalletLogPrintf("Detected extraneous encryption keys in this wallet without private keys. Removing extraneous encryption keys.\n");
for (const auto& [id, _] : pwallet->mapMasterKeys) {
if (!EraseMasterKey(id)) {
pwallet->WalletLogPrintf("Error: Unable to remove extraneous encryption key '%u'. Wallet corrupt.\n", id);
return DBErrors::CORRUPT;
}
}
pwallet->mapMasterKeys.clear();
}
return result;
}

View file

@ -238,6 +238,7 @@ public:
bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta);
bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta);
bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey);
bool EraseMasterKey(unsigned int id);
bool WriteCScript(const uint160& hash, const CScript& redeemScript);