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