X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fkeystore.cpp;h=b4783ec5b9258e774ea3041e86c08729155452c8;hb=1c4fc9052a444c114d9c1501d2c6d1305de650d0;hp=f659495a1a8093b0a4c7d245d6d00717749012f0;hpb=4e87d341f75f13bbd7d108c31c03886fbc4df56f;p=novacoin.git diff --git a/src/keystore.cpp b/src/keystore.cpp index f659495..b4783ec 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,58 +1,137 @@ -// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "headers.h" -#include "db.h" -#include "crypter.h" +#include "keystore.h" +#include "script.h" +#include "base58.h" -std::vector CKeyStore::GenerateNewKey() +extern bool fWalletUnlockMintOnly; + +bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const { - RandAddSeedPerfmon(); CKey key; - key.MakeNewKey(); - if (!AddKey(key)) - throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed"); - return key.GetPubKey(); + if (!GetKey(address, key)) + return false; + vchPubKeyOut = key.GetPubKey(); + return true; } bool CBasicKeyStore::AddKey(const CKey& key) { - CRITICAL_BLOCK(cs_mapPubKeys) - CRITICAL_BLOCK(cs_KeyStore) + bool fCompressed = false; + CSecret secret = key.GetSecret(fCompressed); { - mapKeys[key.GetPubKey()] = key.GetPrivKey(); - mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey(); + LOCK(cs_KeyStore); + mapKeys[key.GetPubKey().GetID()] = make_pair(secret, fCompressed); } return true; } -std::vector CCryptoKeyStore::GenerateNewKey() +bool CBasicKeyStore::AddCScript(const CScript& redeemScript) { - RandAddSeedPerfmon(); - CKey key; - key.MakeNewKey(); - if (!AddKey(key)) - throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed"); - return key.GetPubKey(); + { + LOCK(cs_KeyStore); + mapScripts[redeemScript.GetID()] = redeemScript; + } + return true; +} + +bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const +{ + bool result; + { + LOCK(cs_KeyStore); + result = (mapScripts.count(hash) > 0); + } + return result; +} + + +bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const +{ + { + LOCK(cs_KeyStore); + ScriptMap::const_iterator mi = mapScripts.find(hash); + if (mi != mapScripts.end()) + { + redeemScriptOut = (*mi).second; + return true; + } + } + return false; +} + +bool CBasicKeyStore::AddWatchOnly(const CScript &dest) +{ + LOCK(cs_KeyStore); + + CTxDestination address; + if (ExtractDestination(dest, address)) { + CKeyID keyID; + CBitcoinAddress(address).GetKeyID(keyID); + if (HaveKey(keyID)) + return false; + } + + setWatchOnly.insert(dest); + return true; +} + +bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const +{ + LOCK(cs_KeyStore); + return setWatchOnly.count(dest) > 0; +} + +bool CCryptoKeyStore::SetCrypted() +{ + { + LOCK(cs_KeyStore); + if (fUseCrypto) + return true; + if (!mapKeys.empty()) + return false; + fUseCrypto = true; + } + return true; +} + +bool CCryptoKeyStore::Lock() +{ + if (!SetCrypted()) + return false; + + { + LOCK(cs_KeyStore); + vMasterKey.clear(); + fWalletUnlockMintOnly = false; + } + + NotifyStatusChanged(this); + return true; } bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) { - CRITICAL_BLOCK(cs_vMasterKey) { + LOCK(cs_KeyStore); if (!SetCrypted()) return false; - std::map, std::vector >::const_iterator mi = mapCryptedKeys.begin(); + CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); for (; mi != mapCryptedKeys.end(); ++mi) { - const std::vector &vchPubKey = (*mi).first; - const std::vector &vchCryptedSecret = (*mi).second; + const CPubKey &vchPubKey = (*mi).second.first; + const std::vector &vchCryptedSecret = (*mi).second.second; CSecret vchSecret; - if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret)) + if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) + return false; + if (vchSecret.size() != 32) return false; CKey key; + key.SetPubKey(vchPubKey); key.SetSecret(vchSecret); if (key.GetPubKey() == vchPubKey) break; @@ -60,14 +139,21 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) } vMasterKey = vMasterKeyIn; } + NotifyStatusChanged(this); return true; } bool CCryptoKeyStore::AddKey(const CKey& key) { - CRITICAL_BLOCK(cs_KeyStore) - CRITICAL_BLOCK(cs_vMasterKey) { + LOCK(cs_KeyStore); + + CScript script; + script.SetDestination(key.GetPubKey().GetID()); + + if (HaveWatchOnly(script)) + return false; + if (!IsCrypted()) return CBasicKeyStore::AddKey(key); @@ -75,8 +161,9 @@ bool CCryptoKeyStore::AddKey(const CKey& key) return false; std::vector vchCryptedSecret; - std::vector vchPubKey = key.GetPubKey(); - if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret)) + CPubKey vchPubKey = key.GetPubKey(); + bool fCompressed; + if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret)) return false; if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) @@ -86,37 +173,54 @@ bool CCryptoKeyStore::AddKey(const CKey& key) } -bool CCryptoKeyStore::AddCryptedKey(const std::vector &vchPubKey, const std::vector &vchCryptedSecret) +bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) { - CRITICAL_BLOCK(cs_mapPubKeys) - CRITICAL_BLOCK(cs_KeyStore) { + LOCK(cs_KeyStore); if (!SetCrypted()) return false; - mapCryptedKeys[vchPubKey] = vchCryptedSecret; - mapPubKeys[Hash160(vchPubKey)] = vchPubKey; + mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret); } return true; } -bool CCryptoKeyStore::GetPrivKey(const std::vector &vchPubKey, CPrivKey& keyOut) const +bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const { - CRITICAL_BLOCK(cs_vMasterKey) { + LOCK(cs_KeyStore); if (!IsCrypted()) - return CBasicKeyStore::GetPrivKey(vchPubKey, keyOut); + return CBasicKeyStore::GetKey(address, keyOut); - std::map, std::vector >::const_iterator mi = mapCryptedKeys.find(vchPubKey); + CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); if (mi != mapCryptedKeys.end()) { - const std::vector &vchCryptedSecret = (*mi).second; + const CPubKey &vchPubKey = (*mi).second.first; + const std::vector &vchCryptedSecret = (*mi).second.second; CSecret vchSecret; - if (!DecryptSecret(vMasterKey, (*mi).second, Hash((*mi).first.begin(), (*mi).first.end()), vchSecret)) + if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret)) return false; - CKey key; - key.SetSecret(vchSecret); - keyOut = key.GetPrivKey(); + if (vchSecret.size() != 32) + return false; + keyOut.SetPubKey(vchPubKey); + keyOut.SetSecret(vchSecret); + return true; + } + } + return false; +} + +bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const +{ + { + LOCK(cs_KeyStore); + if (!IsCrypted()) + return CKeyStore::GetPubKey(address, vchPubKeyOut); + + CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); + if (mi != mapCryptedKeys.end()) + { + vchPubKeyOut = (*mi).second.first; return true; } } @@ -125,22 +229,23 @@ bool CCryptoKeyStore::GetPrivKey(const std::vector &vchPubKey, CP bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) { - CRITICAL_BLOCK(cs_KeyStore) - CRITICAL_BLOCK(cs_vMasterKey) { + LOCK(cs_KeyStore); if (!mapCryptedKeys.empty() || IsCrypted()) return false; fUseCrypto = true; - CKey key; BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys) { - if (!key.SetPrivKey(mKey.second)) + CKey key; + if (!key.SetSecret(mKey.second.first, mKey.second.second)) return false; + const CPubKey vchPubKey = key.GetPubKey(); std::vector vchCryptedSecret; - if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(mKey.first.begin(), mKey.first.end()), vchCryptedSecret)) + bool fCompressed; + if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret)) return false; - if (!AddCryptedKey(mKey.first, vchCryptedSecret)) + if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) return false; } mapKeys.clear();