fix warnings: delete called on 'XX' that has virtual functions but non-virtual destru...
[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     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         {
60             LOCK(cs_KeyStore);
61             result = (mapKeys.count(address) > 0);
62         }
63         return result;
64     }
65     void GetKeys(std::set<CBitcoinAddress> &setAddress) const
66     {
67         setAddress.clear();
68         {
69             LOCK(cs_KeyStore);
70             KeyMap::const_iterator mi = mapKeys.begin();
71             while (mi != mapKeys.end())
72             {
73                 setAddress.insert((*mi).first);
74                 mi++;
75             }
76         }
77     }
78     bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
79     {
80         {
81             LOCK(cs_KeyStore);
82             KeyMap::const_iterator mi = mapKeys.find(address);
83             if (mi != mapKeys.end())
84             {
85                 keyOut.Reset();
86                 keyOut.SetSecret((*mi).second.first, (*mi).second.second);
87                 return true;
88             }
89         }
90         return false;
91     }
92     virtual bool AddCScript(const CScript& redeemScript);
93     virtual bool HaveCScript(const uint160 &hash) const;
94     virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const;
95 };
96
97 typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
98
99 /** Keystore which keeps the private keys encrypted.
100  * It derives from the basic key store, which is used if no encryption is active.
101  */
102 class CCryptoKeyStore : public CBasicKeyStore
103 {
104 private:
105     CryptedKeyMap mapCryptedKeys;
106
107     CKeyingMaterial vMasterKey;
108
109     // if fUseCrypto is true, mapKeys must be empty
110     // if fUseCrypto is false, vMasterKey must be empty
111     bool fUseCrypto;
112
113 protected:
114     bool SetCrypted();
115
116     // will encrypt previously unencrypted keys
117     bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
118
119     bool Unlock(const CKeyingMaterial& vMasterKeyIn);
120
121 public:
122     CCryptoKeyStore() : fUseCrypto(false)
123     {
124     }
125
126     bool IsCrypted() const
127     {
128         return fUseCrypto;
129     }
130
131     bool IsLocked() const
132     {
133         if (!IsCrypted())
134             return false;
135         bool result;
136         {
137             LOCK(cs_KeyStore);
138             result = vMasterKey.empty();
139         }
140         return result;
141     }
142
143     bool Lock()
144     {
145         if (!SetCrypted())
146             return false;
147
148         {
149             LOCK(cs_KeyStore);
150             vMasterKey.clear();
151         }
152
153         return true;
154     }
155
156     virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
157     bool AddKey(const CKey& key);
158     bool HaveKey(const CBitcoinAddress &address) const
159     {
160         {
161             LOCK(cs_KeyStore);
162             if (!IsCrypted())
163                 return CBasicKeyStore::HaveKey(address);
164             return mapCryptedKeys.count(address) > 0;
165         }
166         return false;
167     }
168     bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
169     bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
170     void GetKeys(std::set<CBitcoinAddress> &setAddress) const
171     {
172         if (!IsCrypted())
173         {
174             CBasicKeyStore::GetKeys(setAddress);
175             return;
176         }
177         setAddress.clear();
178         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
179         while (mi != mapCryptedKeys.end())
180         {
181             setAddress.insert((*mi).first);
182             mi++;
183         }
184     }
185 };
186
187 #endif