Update CMakeLists.txt - play with openssl
[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 "sync.h"
10
11 #include <boost/signals2/signal.hpp>
12
13 #include <variant>
14
15 class CScript;
16
17 class CNoDestination {
18 public:
19     friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; }
20     friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
21 };
22
23 /** A txout script template with a specific destination. It is either:
24   * CNoDestination: no destination set
25   * CKeyID: TX_PUBKEYHASH destination
26   * CScriptID: TX_SCRIPTHASH destination
27   *
28   * A CTxDestination is the internal data type encoded in a CBitcoinAddress.
29   */
30 using CTxDestination = std::variant<CNoDestination, CKeyID, CScriptID>;
31
32 /** A virtual base class for key stores */
33 class CKeyStore
34 {
35 protected:
36     mutable CCriticalSection cs_KeyStore;
37
38 public:
39     virtual ~CKeyStore() {}
40
41     // Add a key to the store.
42     virtual bool AddKey(const CKey& key) =0;
43
44     // Add a malleable key to store.
45     virtual bool AddMalleableKey(const CMalleableKeyView &keyView, const CSecret &vchSecretH) =0;
46     virtual bool GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const =0;
47
48     // Check whether a key corresponding to a given address is present in the store.
49     virtual bool HaveKey(const CKeyID &address) const =0;
50     virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
51     virtual void GetKeys(std::set<CKeyID> &setAddress) const =0;
52     virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
53
54     // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
55     virtual bool AddCScript(const CScript& redeemScript) =0;
56     virtual bool HaveCScript(const CScriptID &hash) const =0;
57     virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;
58
59     // Support for Watch-only addresses
60     virtual bool AddWatchOnly(const CScript &dest) =0;
61     virtual bool RemoveWatchOnly(const CScript &dest) =0;
62     virtual bool HaveWatchOnly(const CScript &dest) const =0;
63     virtual bool HaveWatchOnly() const =0;
64
65     virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const
66     {
67         CKey key;
68         if (!GetKey(address, key))
69             return false;
70         vchSecret = key.GetSecret(fCompressed);
71         return true;
72     }
73
74     virtual bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const =0;
75     virtual bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R, CMalleableKeyView &view) const =0;
76     virtual bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const =0;
77     virtual void ListMalleableViews(std::list<CMalleableKeyView> &malleableViewList) const =0;
78 };
79
80 typedef std::map<CKeyID, std::pair<CSecret, bool> > KeyMap;
81 typedef std::map<CScriptID, CScript > ScriptMap;
82 typedef std::set<CScript> WatchOnlySet;
83 typedef std::map<CMalleableKeyView, CSecret> MalleableKeyMap;
84
85 /** Basic key store, that keeps keys in an address->secret map */
86 class CBasicKeyStore : public CKeyStore
87 {
88 protected:
89     KeyMap mapKeys;
90     MalleableKeyMap mapMalleableKeys;
91
92     ScriptMap mapScripts;
93     WatchOnlySet setWatchOnly;
94
95 public:
96     bool AddKey(const CKey& key);
97     bool AddMalleableKey(const CMalleableKeyView& keyView, const CSecret &vchSecretH);
98     bool GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const
99     {
100         {
101             LOCK(cs_KeyStore);
102             MalleableKeyMap::const_iterator mi = mapMalleableKeys.find(keyView);
103             if (mi != mapMalleableKeys.end())
104             {
105                 mKey = mi->first.GetMalleableKey(mi->second);
106                 return true;
107             }
108         }
109         return false;
110     }
111
112     bool HaveKey(const CKeyID &address) const
113     {
114         bool result;
115         {
116             LOCK(cs_KeyStore);
117             result = (mapKeys.count(address) > 0);
118         }
119         return result;
120     }
121     void GetKeys(std::set<CKeyID> &setAddress) const
122     {
123         setAddress.clear();
124         {
125             LOCK(cs_KeyStore);
126             KeyMap::const_iterator mi;
127             for (mi = mapKeys.begin(); mi != mapKeys.end(); ++mi) setAddress.insert((*mi).first);
128         }
129     }
130     bool GetKey(const CKeyID &address, CKey &keyOut) const
131     {
132         {
133             LOCK(cs_KeyStore);
134             KeyMap::const_iterator mi = mapKeys.find(address);
135             if (mi != mapKeys.end())
136             {
137                 keyOut.SetSecret((*mi).second.first, (*mi).second.second);
138                 return true;
139             }
140         }
141         return false;
142     }
143     virtual bool AddCScript(const CScript& redeemScript);
144     virtual bool HaveCScript(const CScriptID &hash) const;
145     virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
146
147     virtual bool AddWatchOnly(const CScript &dest);
148     virtual bool RemoveWatchOnly(const CScript &dest);
149     virtual bool HaveWatchOnly(const CScript &dest) const;
150     virtual bool HaveWatchOnly() const;
151
152     bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const
153     {
154         {
155             LOCK(cs_KeyStore);
156             for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
157             {
158                 if (mi->first.CheckKeyVariant(R, pubKeyVariant))
159                     return true;
160             }
161         }
162         return false;
163     }
164
165     bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R, CMalleableKeyView &view) const
166     {
167         {
168             LOCK(cs_KeyStore);
169             for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
170             {
171                 if (mi->first.CheckKeyVariant(R, pubKeyVariant))
172                 {
173                     view = mi->first;
174                     return true;
175                 }
176             }
177         }
178         return false;
179     }
180
181     bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const
182     {
183         {
184             LOCK(cs_KeyStore);
185             for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
186             {
187                 if (mi->first.CheckKeyVariant(R, pubKeyVariant))
188                 {
189                     CMalleableKey mKey = mi->first.GetMalleableKey(mi->second);
190                     return mKey.CheckKeyVariant(R, pubKeyVariant, privKey);
191                 }
192             }
193         }
194         return false;
195     }
196
197     void ListMalleableViews(std::list<CMalleableKeyView> &malleableViewList) const
198     {
199         malleableViewList.clear();
200         {
201             LOCK(cs_KeyStore);
202             for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
203                 malleableViewList.push_back(CMalleableKeyView(mi->first));
204         }
205     }
206
207     bool GetMalleableView(const CMalleablePubKey &mpk, CMalleableKeyView &view)
208     {
209         const CKeyID &mpkID = mpk.GetID();
210         {
211             LOCK(cs_KeyStore);
212             for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
213                 if (mi->first.GetID() == mpkID)
214                 {
215                     view = CMalleableKeyView(mi->first);
216                     return true;
217                 }
218         }
219
220         return false;
221     }
222 };
223
224 typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
225 typedef std::map<CMalleableKeyView, std::vector<unsigned char> > CryptedMalleableKeyMap;
226
227 /** Keystore which keeps the private keys encrypted.
228  * It derives from the basic key store, which is used if no encryption is active.
229  */
230 class CCryptoKeyStore : public CBasicKeyStore
231 {
232 private:
233     CryptedKeyMap mapCryptedKeys;
234     CryptedMalleableKeyMap mapCryptedMalleableKeys;
235
236     CKeyingMaterial vMasterKey;
237
238     // if fUseCrypto is true, mapKeys must be empty
239     // if fUseCrypto is false, vMasterKey must be empty
240     bool fUseCrypto;
241
242 protected:
243     bool SetCrypted();
244
245     // will encrypt previously unencrypted keys
246     bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
247     bool DecryptKeys(const CKeyingMaterial& vMasterKeyIn);
248
249     bool Unlock(const CKeyingMaterial& vMasterKeyIn);
250
251 public:
252     CCryptoKeyStore() : fUseCrypto(false) { }
253
254     bool IsCrypted() const
255     {
256         return fUseCrypto;
257     }
258
259     bool IsLocked() const
260     {
261         if (!IsCrypted())
262             return false;
263         bool result;
264         {
265             LOCK(cs_KeyStore);
266             result = vMasterKey.empty();
267         }
268         return result;
269     }
270
271     bool Lock();
272
273     virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
274     virtual bool AddCryptedMalleableKey(const CMalleableKeyView& keyView, const std::vector<unsigned char>  &vchCryptedSecretH);
275
276     bool AddKey(const CKey& key);
277     bool AddMalleableKey(const CMalleableKeyView& keyView, const CSecret &vchSecretH);
278     bool HaveKey(const CKeyID &address) const
279     {
280         {
281             LOCK(cs_KeyStore);
282             if (!IsCrypted())
283                 return CBasicKeyStore::HaveKey(address);
284             return mapCryptedKeys.count(address) > 0;
285         }
286     }
287     bool GetKey(const CKeyID &address, CKey& keyOut) const;
288     bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
289     void GetKeys(std::set<CKeyID> &setAddress) const
290     {
291         if (!IsCrypted())
292         {
293             CBasicKeyStore::GetKeys(setAddress);
294             return;
295         }
296         setAddress.clear();
297         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
298         while (mi != mapCryptedKeys.end())
299         {
300             setAddress.insert((*mi).first);
301             mi++;
302         }
303     }
304
305     bool GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const;
306
307     bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const
308     {
309         {
310             LOCK(cs_KeyStore);
311             if (!IsCrypted())
312                 return CBasicKeyStore::CheckOwnership(pubKeyVariant, R);
313             for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
314             {
315                 if (mi->first.CheckKeyVariant(R, pubKeyVariant))
316                     return true;
317             }
318         }
319         return false;
320     }
321
322     bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R, CMalleableKeyView &view) const
323     {
324         {
325             LOCK(cs_KeyStore);
326             if (!IsCrypted())
327                 return CBasicKeyStore::CheckOwnership(pubKeyVariant, R, view);
328             for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
329             {
330                 if (mi->first.CheckKeyVariant(R, pubKeyVariant))
331                 {
332                     view = mi->first;
333                     return true;
334                 }
335             }
336         }
337         return false;
338     }
339
340     bool CheckOwnership(const CMalleablePubKey &mpk)
341     {
342         CMalleableKeyView view;
343         return GetMalleableView(mpk, view);
344     }
345
346     bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const;
347
348     void ListMalleableViews(std::list<CMalleableKeyView> &malleableViewList) const
349     {
350         malleableViewList.clear();
351         {
352             LOCK(cs_KeyStore);
353             if (!IsCrypted())
354                 return CBasicKeyStore::ListMalleableViews(malleableViewList);
355             for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
356                 malleableViewList.push_back(CMalleableKeyView(mi->first));
357         }
358     }
359
360     bool GetMalleableView(const CMalleablePubKey &mpk, CMalleableKeyView &view)
361     {
362         const CKeyID &mpkID = mpk.GetID();
363         {
364             LOCK(cs_KeyStore);
365             if (!IsCrypted())
366                 return CBasicKeyStore::GetMalleableView(mpk, view);
367             for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
368                 if (mi->first.GetID() == mpkID)
369                 {
370                     view = CMalleableKeyView(mi->first);
371                     return true;
372                 }
373         }
374
375         return false;
376     }
377
378     /* Wallet status (encrypted, locked) changed.
379      * Note: Called without locks held.
380      */
381     boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
382 };
383
384 #endif