Skip to content

Commit 829c920

Browse files
committed
Move CCryptoKeyStore to crypter.cpp
This breaks the dependency on crypter for disable-wallet builds.
1 parent ae6ea5a commit 829c920

File tree

5 files changed

+240
-237
lines changed

5 files changed

+240
-237
lines changed

src/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ version.o: obj/build.h
3939
libbitcoin_server_a_SOURCES = \
4040
addrman.cpp \
4141
alert.cpp \
42-
crypter.cpp \
4342
rpcserver.cpp \
4443
bloom.cpp \
4544
chainparams.cpp \
@@ -61,6 +60,7 @@ libbitcoin_server_a_SOURCES = \
6160

6261
libbitcoin_wallet_a_SOURCES = \
6362
db.cpp \
63+
crypter.cpp \
6464
miner.cpp \
6565
rpcdump.cpp \
6666
rpcmining.cpp \

src/crypter.cpp

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
#include "crypter.h"
66

7+
#include "script.h"
8+
79
#include <string>
810
#include <vector>
9-
11+
#include <boost/foreach.hpp>
1012
#include <openssl/aes.h>
1113
#include <openssl/evp.h>
1214

@@ -117,3 +119,156 @@ bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned
117119
return false;
118120
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
119121
}
122+
123+
bool CCryptoKeyStore::SetCrypted()
124+
{
125+
LOCK(cs_KeyStore);
126+
if (fUseCrypto)
127+
return true;
128+
if (!mapKeys.empty())
129+
return false;
130+
fUseCrypto = true;
131+
return true;
132+
}
133+
134+
bool CCryptoKeyStore::Lock()
135+
{
136+
if (!SetCrypted())
137+
return false;
138+
139+
{
140+
LOCK(cs_KeyStore);
141+
vMasterKey.clear();
142+
}
143+
144+
NotifyStatusChanged(this);
145+
return true;
146+
}
147+
148+
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
149+
{
150+
{
151+
LOCK(cs_KeyStore);
152+
if (!SetCrypted())
153+
return false;
154+
155+
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
156+
for (; mi != mapCryptedKeys.end(); ++mi)
157+
{
158+
const CPubKey &vchPubKey = (*mi).second.first;
159+
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
160+
CKeyingMaterial vchSecret;
161+
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
162+
return false;
163+
if (vchSecret.size() != 32)
164+
return false;
165+
CKey key;
166+
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
167+
if (key.GetPubKey() == vchPubKey)
168+
break;
169+
return false;
170+
}
171+
vMasterKey = vMasterKeyIn;
172+
}
173+
NotifyStatusChanged(this);
174+
return true;
175+
}
176+
177+
bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
178+
{
179+
{
180+
LOCK(cs_KeyStore);
181+
if (!IsCrypted())
182+
return CBasicKeyStore::AddKeyPubKey(key, pubkey);
183+
184+
if (IsLocked())
185+
return false;
186+
187+
std::vector<unsigned char> vchCryptedSecret;
188+
CKeyingMaterial vchSecret(key.begin(), key.end());
189+
if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret))
190+
return false;
191+
192+
if (!AddCryptedKey(pubkey, vchCryptedSecret))
193+
return false;
194+
}
195+
return true;
196+
}
197+
198+
199+
bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
200+
{
201+
{
202+
LOCK(cs_KeyStore);
203+
if (!SetCrypted())
204+
return false;
205+
206+
mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
207+
}
208+
return true;
209+
}
210+
211+
bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
212+
{
213+
{
214+
LOCK(cs_KeyStore);
215+
if (!IsCrypted())
216+
return CBasicKeyStore::GetKey(address, keyOut);
217+
218+
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
219+
if (mi != mapCryptedKeys.end())
220+
{
221+
const CPubKey &vchPubKey = (*mi).second.first;
222+
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
223+
CKeyingMaterial vchSecret;
224+
if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
225+
return false;
226+
if (vchSecret.size() != 32)
227+
return false;
228+
keyOut.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
229+
return true;
230+
}
231+
}
232+
return false;
233+
}
234+
235+
bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
236+
{
237+
{
238+
LOCK(cs_KeyStore);
239+
if (!IsCrypted())
240+
return CKeyStore::GetPubKey(address, vchPubKeyOut);
241+
242+
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
243+
if (mi != mapCryptedKeys.end())
244+
{
245+
vchPubKeyOut = (*mi).second.first;
246+
return true;
247+
}
248+
}
249+
return false;
250+
}
251+
252+
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
253+
{
254+
{
255+
LOCK(cs_KeyStore);
256+
if (!mapCryptedKeys.empty() || IsCrypted())
257+
return false;
258+
259+
fUseCrypto = true;
260+
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
261+
{
262+
const CKey &key = mKey.second;
263+
CPubKey vchPubKey = key.GetPubKey();
264+
CKeyingMaterial vchSecret(key.begin(), key.end());
265+
std::vector<unsigned char> vchCryptedSecret;
266+
if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret))
267+
return false;
268+
if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
269+
return false;
270+
}
271+
mapKeys.clear();
272+
}
273+
return true;
274+
}

src/crypter.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "allocators.h"
99
#include "serialize.h"
10+
#include "keystore.h"
1011

1112
class uint256;
1213

@@ -106,4 +107,86 @@ class CCrypter
106107
bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
107108
bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
108109

110+
/** Keystore which keeps the private keys encrypted.
111+
* It derives from the basic key store, which is used if no encryption is active.
112+
*/
113+
class CCryptoKeyStore : public CBasicKeyStore
114+
{
115+
private:
116+
CryptedKeyMap mapCryptedKeys;
117+
118+
CKeyingMaterial vMasterKey;
119+
120+
// if fUseCrypto is true, mapKeys must be empty
121+
// if fUseCrypto is false, vMasterKey must be empty
122+
bool fUseCrypto;
123+
124+
protected:
125+
bool SetCrypted();
126+
127+
// will encrypt previously unencrypted keys
128+
bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
129+
130+
bool Unlock(const CKeyingMaterial& vMasterKeyIn);
131+
132+
public:
133+
CCryptoKeyStore() : fUseCrypto(false)
134+
{
135+
}
136+
137+
bool IsCrypted() const
138+
{
139+
return fUseCrypto;
140+
}
141+
142+
bool IsLocked() const
143+
{
144+
if (!IsCrypted())
145+
return false;
146+
bool result;
147+
{
148+
LOCK(cs_KeyStore);
149+
result = vMasterKey.empty();
150+
}
151+
return result;
152+
}
153+
154+
bool Lock();
155+
156+
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
157+
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
158+
bool HaveKey(const CKeyID &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 CKeyID &address, CKey& keyOut) const;
169+
bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
170+
void GetKeys(std::set<CKeyID> &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+
/* Wallet status (encrypted, locked) changed.
187+
* Note: Called without locks held.
188+
*/
189+
boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
190+
};
191+
109192
#endif

0 commit comments

Comments
 (0)