Update all copyrights to 2012
[novacoin.git] / src / keystore.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_KEYSTORE_H
6 #define BITCOIN_KEYSTORE_H
7
8 #include "crypter.h"
9 #include "script.h"
10
11 // A virtual base class for key stores
12 class CKeyStore
13 {
14 protected:
15     mutable CCriticalSection cs_KeyStore;
16
17 public:
18     // Add a key to the store.
19     virtual bool AddKey(const CKey& key) =0;
20
21     // Check whether a key corresponding to a given address is present in the store.
22     virtual bool HaveKey(const CBitcoinAddress &address) const =0;
23     virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
24     virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
25     virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
26
27     // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
28     virtual bool AddCScript(const CScript& redeemScript) =0;
29     virtual bool HaveCScript(const uint160 &hash) const =0;
30     virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const =0;
31
32     // Generate a new key, and add it to the store
33     virtual std::vector<unsigned char> GenerateNewKey();
34     virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret, bool &fCompressed) const
35     {
36         CKey key;
37         if (!GetKey(address, key))
38             return false;
39         vchSecret = key.GetSecret(fCompressed);
40         return true;
41     }
42 };
43
44 typedef std::map<CBitcoinAddress, std::pair<CSecret, bool> > KeyMap;
45 typedef std::map<uint160, CScript > ScriptMap;
46
47 // Basic key store, that keeps keys in an address->secret map
48 class CBasicKeyStore : public CKeyStore
49 {
50 protected:
51     KeyMap mapKeys;
52     ScriptMap mapScripts;
53
54 public:
55     bool AddKey(const CKey& key);
56     bool HaveKey(const CBitcoinAddress &address) const
57     {
58         bool result;
59         CRITICAL_BLOCK(cs_KeyStore)
60             result = (mapKeys.count(address) > 0);
61         return result;
62     }
63     void GetKeys(std::set<CBitcoinAddress> &setAddress) const
64     {
65         setAddress.clear();
66         CRITICAL_BLOCK(cs_KeyStore)
67         {
68             KeyMap::const_iterator mi = mapKeys.begin();
69             while (mi != mapKeys.end())
70             {
71                 setAddress.insert((*mi).first);
72                 mi++;
73             }
74         }
75     }
76     bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
77     {
78         CRITICAL_BLOCK(cs_KeyStore)
79         {
80             KeyMap::const_iterator mi = mapKeys.find(address);
81             if (mi != mapKeys.end())
82             {
83                 keyOut.Reset();
84                 keyOut.SetSecret((*mi).second.first, (*mi).second.second);
85                 return true;
86             }
87         }
88         return false;
89     }
90     virtual bool AddCScript(const CScript& redeemScript);
91     virtual bool HaveCScript(const uint160 &hash) const;
92     virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const;
93 };
94
95 typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
96
97 // Keystore which keeps the private keys encrypted
98 // It derives from the basic key store, which is used if no encryption is active.
99 class CCryptoKeyStore : public CBasicKeyStore
100 {
101 private:
102     CryptedKeyMap mapCryptedKeys;
103
104     CKeyingMaterial vMasterKey;
105
106     // if fUseCrypto is true, mapKeys must be empty
107     // if fUseCrypto is false, vMasterKey must be empty
108     bool fUseCrypto;
109
110 protected:
111     bool SetCrypted();
112
113     // will encrypt previously unencrypted keys
114     bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
115
116     bool Unlock(const CKeyingMaterial& vMasterKeyIn);
117
118 public:
119     CCryptoKeyStore() : fUseCrypto(false)
120     {
121     }
122
123     bool IsCrypted() const
124     {
125         return fUseCrypto;
126     }
127
128     bool IsLocked() const
129     {
130         if (!IsCrypted())
131             return false;
132         bool result;
133         CRITICAL_BLOCK(cs_KeyStore)
134             result = vMasterKey.empty();
135         return result;
136     }
137
138     bool Lock()
139     {
140         if (!SetCrypted())
141             return false;
142
143         CRITICAL_BLOCK(cs_KeyStore)
144             vMasterKey.clear();
145
146         return true;
147     }
148
149     virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
150     bool AddKey(const CKey& key);
151     bool HaveKey(const CBitcoinAddress &address) const
152     {
153         CRITICAL_BLOCK(cs_KeyStore)
154         {
155             if (!IsCrypted())
156                 return CBasicKeyStore::HaveKey(address);
157             return mapCryptedKeys.count(address) > 0;
158         }
159         return false;
160     }
161     bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
162     bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
163     void GetKeys(std::set<CBitcoinAddress> &setAddress) const
164     {
165         if (!IsCrypted())
166         {
167             CBasicKeyStore::GetKeys(setAddress);
168             return;
169         }
170         setAddress.clear();
171         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
172         while (mi != mapCryptedKeys.end())
173         {
174             setAddress.insert((*mi).first);
175             mi++;
176         }
177     }
178 };
179
180 #endif