Back to home page

Bitcoin sources

 
 

    


0001 // Copyright (c) 2009-2010 Satoshi Nakamoto
0002 // Copyright (c) 2011 The Bitcoin developers
0003 // Distributed under the MIT/X11 software license, see the accompanying
0004 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
0005 
0006 #include "headers.h"
0007 #include "db.h"
0008 #include "crypter.h"
0009 
0010 std::vector<unsigned char> CKeyStore::GenerateNewKey()
0011 {
0012     RandAddSeedPerfmon();
0013     CKey key;
0014     key.MakeNewKey();
0015     if (!AddKey(key))
0016         throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed");
0017     return key.GetPubKey();
0018 }
0019 
0020 bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
0021 {
0022     CKey key;
0023     if (!GetKey(address, key))
0024         return false;
0025     vchPubKeyOut = key.GetPubKey();
0026     return true;
0027 }
0028 
0029 bool CBasicKeyStore::AddKey(const CKey& key)
0030 {
0031     CRITICAL_BLOCK(cs_KeyStore)
0032         mapKeys[key.GetAddress()] = key.GetSecret();
0033     return true;
0034 }
0035 
0036 bool CCryptoKeyStore::SetCrypted()
0037 {
0038     CRITICAL_BLOCK(cs_KeyStore)
0039     {
0040         if (fUseCrypto)
0041             return true;
0042         if (!mapKeys.empty())
0043             return false;
0044         fUseCrypto = true;
0045     }
0046     return true;
0047 }
0048 
0049 std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey()
0050 {
0051     RandAddSeedPerfmon();
0052     CKey key;
0053     key.MakeNewKey();
0054     if (!AddKey(key))
0055         throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed");
0056     return key.GetPubKey();
0057 }
0058 
0059 bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
0060 {
0061     CRITICAL_BLOCK(cs_KeyStore)
0062     {
0063         if (!SetCrypted())
0064             return false;
0065 
0066         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
0067         for (; mi != mapCryptedKeys.end(); ++mi)
0068         {
0069             const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
0070             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
0071             CSecret vchSecret;
0072             if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
0073                 return false;
0074             CKey key;
0075             key.SetSecret(vchSecret);
0076             if (key.GetPubKey() == vchPubKey)
0077                 break;
0078             return false;
0079         }
0080         vMasterKey = vMasterKeyIn;
0081     }
0082     return true;
0083 }
0084 
0085 bool CCryptoKeyStore::AddKey(const CKey& key)
0086 {
0087     CRITICAL_BLOCK(cs_KeyStore)
0088     {
0089         if (!IsCrypted())
0090             return CBasicKeyStore::AddKey(key);
0091 
0092         if (IsLocked())
0093             return false;
0094 
0095         std::vector<unsigned char> vchCryptedSecret;
0096         std::vector<unsigned char> vchPubKey = key.GetPubKey();
0097         if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
0098             return false;
0099 
0100         if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
0101             return false;
0102     }
0103     return true;
0104 }
0105 
0106 
0107 bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
0108 {
0109     CRITICAL_BLOCK(cs_KeyStore)
0110     {
0111         if (!SetCrypted())
0112             return false;
0113 
0114         mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
0115     }
0116     return true;
0117 }
0118 
0119 bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
0120 {
0121     CRITICAL_BLOCK(cs_KeyStore)
0122     {
0123         if (!IsCrypted())
0124             return CBasicKeyStore::GetKey(address, keyOut);
0125 
0126         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
0127         if (mi != mapCryptedKeys.end())
0128         {
0129             const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
0130             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
0131             CSecret vchSecret;
0132             if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
0133                 return false;
0134             keyOut.SetSecret(vchSecret);
0135             return true;
0136         }
0137     }
0138     return false;
0139 }
0140 
0141 bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
0142 {
0143     CRITICAL_BLOCK(cs_KeyStore)
0144     {
0145         if (!IsCrypted())
0146             return CKeyStore::GetPubKey(address, vchPubKeyOut);
0147 
0148         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
0149         if (mi != mapCryptedKeys.end())
0150         {
0151             vchPubKeyOut = (*mi).second.first;
0152             return true;
0153         }
0154     }
0155     return false;
0156 }
0157 
0158 bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
0159 {
0160     CRITICAL_BLOCK(cs_KeyStore)
0161     {
0162         if (!mapCryptedKeys.empty() || IsCrypted())
0163             return false;
0164 
0165         fUseCrypto = true;
0166         CKey key;
0167         BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
0168         {
0169             if (!key.SetSecret(mKey.second))
0170                 return false;
0171             const std::vector<unsigned char> vchPubKey = key.GetPubKey();
0172             std::vector<unsigned char> vchCryptedSecret;
0173             if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
0174                 return false;
0175             if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
0176                 return false;
0177         }
0178         mapKeys.clear();
0179     }
0180     return true;
0181 }