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