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