Update License in File Headers
[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 COPYING 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     virtual ~CKeyStore() {}
19
20     // Add a key to the store.
21     virtual bool AddKey(const CKey& key) =0;
22
23     // Check whether a key corresponding to a given address is present in the store.
24     virtual bool HaveKey(const CBitcoinAddress &address) const =0;
25     virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
26     virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
27     virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
28
29     // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
30     virtual bool AddCScript(const CScript& redeemScript) =0;
31     virtual bool HaveCScript(const uint160 &hash) const =0;
32     virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const =0;
33
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  */
100 class CCryptoKeyStore : public CBasicKeyStore
101 {
102 private:
103     CryptedKeyMap mapCryptedKeys;
104
105     CKeyingMaterial vMasterKey;
106
107     // if fUseCrypto is true, mapKeys must be empty
108     // if fUseCrypto is false, vMasterKey must be empty
109     bool fUseCrypto;
110
111 protected:
112     bool SetCrypted();
113
114     // will encrypt previously unencrypted keys
115     bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
116
117     bool Unlock(const CKeyingMaterial& vMasterKeyIn);
118
119 public:
120     CCryptoKeyStore() : fUseCrypto(false)
121     {
122     }
123
124     bool IsCrypted() const
125     {
126         return fUseCrypto;
127     }
128
129     bool IsLocked() const
130     {
131         if (!IsCrypted())
132             return false;
133         bool result;
134         CRITICAL_BLOCK(cs_KeyStore)
135             result = vMasterKey.empty();
136         return result;
137     }
138
139     bool Lock()
140     {
141         if (!SetCrypted())
142             return false;
143
144         CRITICAL_BLOCK(cs_KeyStore)
145             vMasterKey.clear();
146
147         return true;
148     }
149
150     virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
151     bool AddKey(const CKey& key);
152     bool HaveKey(const CBitcoinAddress &address) const
153     {
154         CRITICAL_BLOCK(cs_KeyStore)
155         {
156             if (!IsCrypted())
157                 return CBasicKeyStore::HaveKey(address);
158             return mapCryptedKeys.count(address) > 0;
159         }
160         return false;
161     }
162     bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
163     bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
164     void GetKeys(std::set<CBitcoinAddress> &setAddress) const
165     {
166         if (!IsCrypted())
167         {
168             CBasicKeyStore::GetKeys(setAddress);
169             return;
170         }
171         setAddress.clear();
172         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
173         while (mi != mapCryptedKeys.end())
174         {
175             setAddress.insert((*mi).first);
176             mi++;
177         }
178     }
179 };
180
181 #endif