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 #ifndef BITCOIN_KEYSTORE_H
0006 #define BITCOIN_KEYSTORE_H
0007 
0008 #include "crypter.h"
0009 
0010 // A virtual base class for key stores
0011 class CKeyStore
0012 {
0013 protected:
0014     mutable CCriticalSection cs_KeyStore;
0015 
0016 public:
0017     // Add a key to the store.
0018     virtual bool AddKey(const CKey& key) =0;
0019 
0020     // Check whether a key corresponding to a given address is present in the store.
0021     virtual bool HaveKey(const CBitcoinAddress &address) const =0;
0022 
0023     // Retrieve a key corresponding to a given address from the store.
0024     // Return true if succesful.
0025     virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
0026 
0027     // Retrieve only the public key corresponding to a given address.
0028     // This may succeed even if GetKey fails (e.g., encrypted wallets)
0029     virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
0030 
0031     // Generate a new key, and add it to the store
0032     virtual std::vector<unsigned char> GenerateNewKey();
0033 };
0034 
0035 typedef std::map<CBitcoinAddress, CSecret> KeyMap;
0036 
0037 // Basic key store, that keeps keys in an address->secret map
0038 class CBasicKeyStore : public CKeyStore
0039 {
0040 protected:
0041     KeyMap mapKeys;
0042 
0043 public:
0044     bool AddKey(const CKey& key);
0045     bool HaveKey(const CBitcoinAddress &address) const
0046     {
0047         bool result;
0048         CRITICAL_BLOCK(cs_KeyStore)
0049             result = (mapKeys.count(address) > 0);
0050         return result;
0051     }
0052     bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
0053     {
0054         CRITICAL_BLOCK(cs_KeyStore)
0055         {
0056             KeyMap::const_iterator mi = mapKeys.find(address);
0057             if (mi != mapKeys.end())
0058             {
0059                 keyOut.SetSecret((*mi).second);
0060                 return true;
0061             }
0062         }
0063         return false;
0064     }
0065 };
0066 
0067 typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
0068 
0069 // Keystore which keeps the private keys encrypted
0070 // It derives from the basic key store, which is used if no encryption is active.
0071 class CCryptoKeyStore : public CBasicKeyStore
0072 {
0073 private:
0074     CryptedKeyMap mapCryptedKeys;
0075 
0076     CKeyingMaterial vMasterKey;
0077 
0078     // if fUseCrypto is true, mapKeys must be empty
0079     // if fUseCrypto is false, vMasterKey must be empty
0080     bool fUseCrypto;
0081 
0082 protected:
0083     bool SetCrypted();
0084 
0085     // will encrypt previously unencrypted keys
0086     bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
0087 
0088     bool Unlock(const CKeyingMaterial& vMasterKeyIn);
0089 
0090 public:
0091     CCryptoKeyStore() : fUseCrypto(false)
0092     {
0093     }
0094 
0095     bool IsCrypted() const
0096     {
0097         return fUseCrypto;
0098     }
0099 
0100     bool IsLocked() const
0101     {
0102         if (!IsCrypted())
0103             return false;
0104         bool result;
0105         CRITICAL_BLOCK(cs_KeyStore)
0106             result = vMasterKey.empty();
0107         return result;
0108     }
0109 
0110     bool Lock()
0111     {
0112         if (!SetCrypted())
0113             return false;
0114 
0115         CRITICAL_BLOCK(cs_KeyStore)
0116             vMasterKey.clear();
0117 
0118         return true;
0119     }
0120 
0121     virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
0122     std::vector<unsigned char> GenerateNewKey();
0123     bool AddKey(const CKey& key);
0124     bool HaveKey(const CBitcoinAddress &address) const
0125     {
0126         CRITICAL_BLOCK(cs_KeyStore)
0127         {
0128             if (!IsCrypted())
0129                 return CBasicKeyStore::HaveKey(address);
0130             return mapCryptedKeys.count(address) > 0;
0131         }
0132         return false;
0133     }
0134     bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
0135     bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
0136 };
0137 
0138 #endif