From: CryptoManiac Date: Mon, 2 May 2016 17:58:08 +0000 (+0300) Subject: Fix control flow issue. X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=45f11251a5d0f237161e864c4ad873a7cb62ace6 Fix control flow issue. Since the loop increment ++mi was unreachable, the loop body never executed more than once. --- diff --git a/src/keystore.cpp b/src/keystore.cpp index 25efa34..86a4cc3 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -146,30 +146,74 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) if (!SetCrypted()) return false; - CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); - for (; mi != mapCryptedKeys.end(); ++mi) + bool keyPass = false; + bool keyFail = false; + + // Check regular key pairs { - const auto &vchPubKey = (*mi).second.first; - const auto &vchCryptedSecret = (*mi).second.second; - CSecret vchSecret; - if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) - return false; - if (vchSecret.size() != 32) - return false; - CKey key; - key.SetSecret(vchSecret); - key.SetCompressedPubKey(vchPubKey.IsCompressed()); - if (key.GetPubKey() == vchPubKey) - break; - return false; + auto mi = mapCryptedKeys.begin(); + for (; mi != mapCryptedKeys.end(); ++mi) + { + const auto &vchPubKey = (*mi).second.first; + const auto &vchCryptedSecret = (*mi).second.second; + CSecret vchSecret; + if (!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) + { + keyFail = true; + break; + } + if (vchSecret.size() != 32) + { + keyFail = true; + break; + } + keyPass = true; + if (fDecryptionThoroughlyChecked) + break; + } + } + + // Check malleable key pairs + { + if (keyPass && !keyFail) + { + auto mi = mapCryptedMalleableKeys.begin(); + for(; mi != mapCryptedMalleableKeys.end(); ++mi) + { + const auto &H = mi->first.GetMalleablePubKey().GetH(); + CSecret vchSecretH; + if (!DecryptSecret(vMasterKeyIn, mi->second, H.GetHash(), vchSecretH)) + { + keyFail = true; + break; + } + if (vchSecretH.size() != 32) + { + keyFail = true; + break; + } + keyPass = true; + if (fDecryptionThoroughlyChecked) + break; + } + } } + if (keyPass && keyFail) + { + printf("The wallet is probably corrupted: Some keys decrypt but not all.\n"); + assert(false); + } + if (keyFail || !keyPass) + return false; vMasterKey = vMasterKeyIn; + fDecryptionThoroughlyChecked = true; } NotifyStatusChanged(this); return true; } + bool CCryptoKeyStore::AddKey(const CKey& key) { { diff --git a/src/keystore.h b/src/keystore.h index 36149ba..65398a1 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -237,6 +237,9 @@ private: // if fUseCrypto is false, vMasterKey must be empty bool fUseCrypto; + // keeps track of whether Unlock has run a thorough check before + bool fDecryptionThoroughlyChecked; + protected: bool SetCrypted(); @@ -247,7 +250,7 @@ protected: bool Unlock(const CKeyingMaterial& vMasterKeyIn); public: - CCryptoKeyStore() : fUseCrypto(false) { } + CCryptoKeyStore() : fUseCrypto(false), fDecryptionThoroughlyChecked(false) { } bool IsCrypted() const {