aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Maxwell <greg@xiph.org>2014-04-06 00:18:52 -0700
committerMatt Corallo <git@bluematt.me>2014-08-10 18:36:06 -0700
commit1e21c17d208e310295475c0e4a46d750a5c9ba2d (patch)
tree247bec498d6cb2221a9e262cb88cfc5b2b95000f
parent36065cc529bb9be5655fcaaad2746edb7b6f4ddb (diff)
Make CCryptoKeyStore::Unlock check all keys.
CCryptoKeyStore::Unlock has a loop to attempt decrypting each key which only executes once, likely due to a simple mistake when the code was originally written. This patch fixes the behavior by making it check all keys. It also adds a fatal assertion in the case some decrypt but some do not, since that indicates that the wallet is in some kind of really bad state. This may make unlocking noticeably slower on wallets with many keys.
-rw-r--r--src/crypter.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/crypter.cpp b/src/crypter.cpp
index 4c43e3a798..2f94e08273 100644
--- a/src/crypter.cpp
+++ b/src/crypter.cpp
@@ -152,6 +152,8 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
if (!SetCrypted())
return false;
+ bool keyPass = false;
+ bool keyFail = false;
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
for (; mi != mapCryptedKeys.end(); ++mi)
{
@@ -159,15 +161,31 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
CKeyingMaterial vchSecret;
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
- return false;
+ {
+ keyFail = true;
+ break;
+ }
if (vchSecret.size() != 32)
- return false;
+ {
+ keyFail = true;
+ break;
+ }
CKey key;
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
- if (key.GetPubKey() == vchPubKey)
+ if (key.GetPubKey() != vchPubKey)
+ {
+ keyFail = true;
break;
- return false;
+ }
+ keyPass = true;
+ }
+ if (keyPass && keyFail)
+ {
+ LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.");
+ assert(false);
}
+ if (keyFail || !keyPass)
+ return false;
vMasterKey = vMasterKeyIn;
}
NotifyStatusChanged(this);