Projects : bitcoin : bitcoin_dumpblock_no_losers
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 | |
23 | // Retrieve a key corresponding to a given address from the store. |
24 | // Return true if succesful. |
25 | virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0; |
26 | |
27 | // Retrieve only the public key corresponding to a given address. |
28 | // This may succeed even if GetKey fails (e.g., encrypted wallets) |
29 | virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const; |
30 | |
31 | virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret) const |
32 | { |
33 | CKey key; |
34 | if (!GetKey(address, key)) |
35 | return false; |
36 | vchSecret = key.GetSecret(); |
37 | return true; |
38 | } |
39 | |
40 | // Generate a new key, and add it to the store |
41 | virtual std::vector<unsigned char> GenerateNewKey(); |
42 | }; |
43 | |
44 | typedef std::map<CBitcoinAddress, CSecret> KeyMap; |
45 | |
46 | // Basic key store, that keeps keys in an address->secret map |
47 | class CBasicKeyStore : public CKeyStore |
48 | { |
49 | protected: |
50 | KeyMap mapKeys; |
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 | bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const |
62 | { |
63 | CRITICAL_BLOCK(cs_KeyStore) |
64 | { |
65 | KeyMap::const_iterator mi = mapKeys.find(address); |
66 | if (mi != mapKeys.end()) |
67 | { |
68 | keyOut.SetSecret((*mi).second); |
69 | return true; |
70 | } |
71 | } |
72 | return false; |
73 | } |
74 | }; |
75 | |
76 | typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap; |
77 | |
78 | // Keystore which keeps the private keys encrypted |
79 | // It derives from the basic key store, which is used if no encryption is active. |
80 | class CCryptoKeyStore : public CBasicKeyStore |
81 | { |
82 | private: |
83 | CryptedKeyMap mapCryptedKeys; |
84 | |
85 | CKeyingMaterial vMasterKey; |
86 | |
87 | // if fUseCrypto is true, mapKeys must be empty |
88 | // if fUseCrypto is false, vMasterKey must be empty |
89 | bool fUseCrypto; |
90 | |
91 | protected: |
92 | bool SetCrypted(); |
93 | |
94 | // will encrypt previously unencrypted keys |
95 | bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); |
96 | |
97 | bool Unlock(const CKeyingMaterial& vMasterKeyIn); |
98 | |
99 | public: |
100 | CCryptoKeyStore() : fUseCrypto(false) |
101 | { |
102 | } |
103 | |
104 | bool IsCrypted() const |
105 | { |
106 | return fUseCrypto; |
107 | } |
108 | |
109 | bool IsLocked() const |
110 | { |
111 | if (!IsCrypted()) |
112 | return false; |
113 | bool result; |
114 | CRITICAL_BLOCK(cs_KeyStore) |
115 | result = vMasterKey.empty(); |
116 | return result; |
117 | } |
118 | |
119 | bool Lock() |
120 | { |
121 | if (!SetCrypted()) |
122 | return false; |
123 | |
124 | CRITICAL_BLOCK(cs_KeyStore) |
125 | vMasterKey.clear(); |
126 | |
127 | return true; |
128 | } |
129 | |
130 | virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); |
131 | std::vector<unsigned char> GenerateNewKey(); |
132 | bool AddKey(const CKey& key); |
133 | bool HaveKey(const CBitcoinAddress &address) const |
134 | { |
135 | CRITICAL_BLOCK(cs_KeyStore) |
136 | { |
137 | if (!IsCrypted()) |
138 | return CBasicKeyStore::HaveKey(address); |
139 | return mapCryptedKeys.count(address) > 0; |
140 | } |
141 | return false; |
142 | } |
143 | bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const; |
144 | bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const; |
145 | }; |
146 | |
147 | #endif |