-
+ CDBEA27A3083796762500A9719D220DC1D21DF8CE1306CEA02267E17A2BCFF3760A44DB87765EC5E8F77F638835028653C20F34C4685E4F0974843FA360CDE1Fbitcoin/src/keystore.cpp(0 . 0)(1 . 212)
 9940 //  /****************************\
 9941 // *      EXPERIMENTAL BRANCH.    *
 9942 // *    FOR LABORATORY USE ONLY.  *
 9943 // ********************************
 9944 //           ************
 9945 //          **************
 9946 //         ****************
 9947 //        ****   ****   ****
 9948 //        ***     ***    ***
 9949 //        ***     ***    ***
 9950 //         ***    * *    **
 9951 //         ******** ********
 9952 //         *******   ******
 9953 //             ***   **
 9954 //           *  ******* **
 9955 //           ** * * * * *
 9956 //     **     *         *     ***
 9957 //    ****    * *     * *    ****
 9958 //    ****    *** * * **     ***
 9959 //     ****    *********   ******
 9960 //    *******    *****    *******
 9961 //    *********        ****** **
 9962 //     **   ******   ******
 9963 //            **  *******       **
 9964 //    **       *******         ***
 9965 //   ****   ********  ************
 9966 //   ************    ************
 9967 //    ********             *******
 9968 //   ******                   ****
 9969 //    ***                      ***
 9970 // ********************************
 9971 // Copyright (c) 2009-2010 Satoshi Nakamoto
 9972 // Copyright (c) 2011 The Bitcoin developers
 9973 // Distributed under the MIT/X11 software license, see the accompanying
 9974 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
 9975 
 9976 #include "headers.h"
 9977 #include "db.h"
 9978 #include "crypter.h"
 9979 
 9980 std::vector<unsigned char> CKeyStore::GenerateNewKey()
 9981 {
 9982     RandAddSeedPerfmon();
 9983     CKey key;
 9984     key.MakeNewKey();
 9985     if (!AddKey(key))
 9986         throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed");
 9987     return key.GetPubKey();
 9988 }
 9989 
 9990 bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
 9991 {
 9992     CKey key;
 9993     if (!GetKey(address, key))
 9994         return false;
 9995     vchPubKeyOut = key.GetPubKey();
 9996     return true;
 9997 }
 9998 
 9999 bool CBasicKeyStore::AddKey(const CKey& key)
10000 {
10001     CRITICAL_BLOCK(cs_KeyStore)
10002         mapKeys[key.GetAddress()] = key.GetSecret();
10003     return true;
10004 }
10005 
10006 bool CCryptoKeyStore::SetCrypted()
10007 {
10008     CRITICAL_BLOCK(cs_KeyStore)
10009     {
10010         if (fUseCrypto)
10011             return true;
10012         if (!mapKeys.empty())
10013             return false;
10014         fUseCrypto = true;
10015     }
10016     return true;
10017 }
10018 
10019 std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey()
10020 {
10021     RandAddSeedPerfmon();
10022     CKey key;
10023     key.MakeNewKey();
10024     if (!AddKey(key))
10025         throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed");
10026     return key.GetPubKey();
10027 }
10028 
10029 bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
10030 {
10031     CRITICAL_BLOCK(cs_KeyStore)
10032     {
10033         if (!SetCrypted())
10034             return false;
10035 
10036         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
10037         for (; mi != mapCryptedKeys.end(); ++mi)
10038         {
10039             const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
10040             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
10041             CSecret vchSecret;
10042             if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
10043                 return false;
10044             CKey key;
10045             key.SetSecret(vchSecret);
10046             if (key.GetPubKey() == vchPubKey)
10047                 break;
10048             return false;
10049         }
10050         vMasterKey = vMasterKeyIn;
10051     }
10052     return true;
10053 }
10054 
10055 bool CCryptoKeyStore::AddKey(const CKey& key)
10056 {
10057     CRITICAL_BLOCK(cs_KeyStore)
10058     {
10059         if (!IsCrypted())
10060             return CBasicKeyStore::AddKey(key);
10061 
10062         if (IsLocked())
10063             return false;
10064 
10065         std::vector<unsigned char> vchCryptedSecret;
10066         std::vector<unsigned char> vchPubKey = key.GetPubKey();
10067         if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
10068             return false;
10069 
10070         if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
10071             return false;
10072     }
10073     return true;
10074 }
10075 
10076 
10077 bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
10078 {
10079     CRITICAL_BLOCK(cs_KeyStore)
10080     {
10081         if (!SetCrypted())
10082             return false;
10083 
10084         mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
10085     }
10086     return true;
10087 }
10088 
10089 bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
10090 {
10091     CRITICAL_BLOCK(cs_KeyStore)
10092     {
10093         if (!IsCrypted())
10094             return CBasicKeyStore::GetKey(address, keyOut);
10095 
10096         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
10097         if (mi != mapCryptedKeys.end())
10098         {
10099             const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
10100             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
10101             CSecret vchSecret;
10102             if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
10103                 return false;
10104             keyOut.SetSecret(vchSecret);
10105             return true;
10106         }
10107     }
10108     return false;
10109 }
10110 
10111 bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
10112 {
10113     CRITICAL_BLOCK(cs_KeyStore)
10114     {
10115         if (!IsCrypted())
10116             return CKeyStore::GetPubKey(address, vchPubKeyOut);
10117 
10118         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
10119         if (mi != mapCryptedKeys.end())
10120         {
10121             vchPubKeyOut = (*mi).second.first;
10122             return true;
10123         }
10124     }
10125     return false;
10126 }
10127 
10128 bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
10129 {
10130     CRITICAL_BLOCK(cs_KeyStore)
10131     {
10132         if (!mapCryptedKeys.empty() || IsCrypted())
10133             return false;
10134 
10135         fUseCrypto = true;
10136         CKey key;
10137         BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
10138         {
10139             if (!key.SetSecret(mKey.second))
10140                 return false;
10141             const std::vector<unsigned char> vchPubKey = key.GetPubKey();
10142             std::vector<unsigned char> vchCryptedSecret;
10143             if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
10144                 return false;
10145             if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
10146                 return false;
10147         }
10148         mapKeys.clear();
10149     }
10150     return true;
10151 }