Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F10907591
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
24 KB
Subscribers
None
View Options
diff --git a/src/keystore.cpp b/src/keystore.cpp
index a38c2f88e7..37bf7a1c8f 100644
--- a/src/keystore.cpp
+++ b/src/keystore.cpp
@@ -1,104 +1,130 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "keystore.h"
#include "key.h"
#include "pubkey.h"
#include "util.h"
bool CKeyStore::AddKey(const CKey &key) {
return AddKeyPubKey(key, key.GetPubKey());
}
bool CBasicKeyStore::GetPubKey(const CKeyID &address,
CPubKey &vchPubKeyOut) const {
CKey key;
if (!GetKey(address, key)) {
LOCK(cs_KeyStore);
WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
if (it != mapWatchKeys.end()) {
vchPubKeyOut = it->second;
return true;
}
return false;
}
vchPubKeyOut = key.GetPubKey();
return true;
}
bool CBasicKeyStore::AddKeyPubKey(const CKey &key, const CPubKey &pubkey) {
LOCK(cs_KeyStore);
mapKeys[pubkey.GetID()] = key;
return true;
}
+bool CBasicKeyStore::HaveKey(const CKeyID &address) const {
+ LOCK(cs_KeyStore);
+ return mapKeys.count(address) > 0;
+}
+
+std::set<CKeyID> CBasicKeyStore::GetKeys() const {
+ LOCK(cs_KeyStore);
+ std::set<CKeyID> set_address;
+ for (const auto &mi : mapKeys) {
+ set_address.insert(mi.first);
+ }
+ return set_address;
+}
+
+bool CBasicKeyStore::GetKey(const CKeyID &address, CKey &keyOut) const {
+ {
+ LOCK(cs_KeyStore);
+ KeyMap::const_iterator mi = mapKeys.find(address);
+ if (mi != mapKeys.end()) {
+ keyOut = mi->second;
+ return true;
+ }
+ }
+ return false;
+}
+
bool CBasicKeyStore::AddCScript(const CScript &redeemScript) {
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
return error("CBasicKeyStore::AddCScript(): redeemScripts > %i bytes "
"are invalid",
MAX_SCRIPT_ELEMENT_SIZE);
LOCK(cs_KeyStore);
mapScripts[CScriptID(redeemScript)] = redeemScript;
return true;
}
bool CBasicKeyStore::HaveCScript(const CScriptID &hash) const {
LOCK(cs_KeyStore);
return mapScripts.count(hash) > 0;
}
bool CBasicKeyStore::GetCScript(const CScriptID &hash,
CScript &redeemScriptOut) const {
LOCK(cs_KeyStore);
ScriptMap::const_iterator mi = mapScripts.find(hash);
if (mi != mapScripts.end()) {
redeemScriptOut = (*mi).second;
return true;
}
return false;
}
static bool ExtractPubKey(const CScript &dest, CPubKey &pubKeyOut) {
// TODO: Use Solver to extract this?
CScript::const_iterator pc = dest.begin();
opcodetype opcode;
std::vector<uint8_t> vch;
if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65)
return false;
pubKeyOut = CPubKey(vch);
if (!pubKeyOut.IsFullyValid()) return false;
if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG ||
dest.GetOp(pc, opcode, vch))
return false;
return true;
}
bool CBasicKeyStore::AddWatchOnly(const CScript &dest) {
LOCK(cs_KeyStore);
setWatchOnly.insert(dest);
CPubKey pubKey;
if (ExtractPubKey(dest, pubKey)) mapWatchKeys[pubKey.GetID()] = pubKey;
return true;
}
bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest) {
LOCK(cs_KeyStore);
setWatchOnly.erase(dest);
CPubKey pubKey;
if (ExtractPubKey(dest, pubKey)) mapWatchKeys.erase(pubKey.GetID());
return true;
}
bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const {
LOCK(cs_KeyStore);
return setWatchOnly.count(dest) > 0;
}
bool CBasicKeyStore::HaveWatchOnly() const {
LOCK(cs_KeyStore);
return (!setWatchOnly.empty());
}
diff --git a/src/keystore.h b/src/keystore.h
index 8e793260e0..ce4aa1d9bb 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -1,109 +1,85 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_KEYSTORE_H
#define BITCOIN_KEYSTORE_H
#include "key.h"
#include "pubkey.h"
#include "script/script.h"
#include "script/standard.h"
#include "sync.h"
#include <boost/signals2/signal.hpp>
/** A virtual base class for key stores */
class CKeyStore {
protected:
mutable CCriticalSection cs_KeyStore;
public:
virtual ~CKeyStore() {}
//! Add a key to the store.
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) = 0;
virtual bool AddKey(const CKey &key);
//! Check whether a key corresponding to a given address is present in the
//! store.
virtual bool HaveKey(const CKeyID &address) const = 0;
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const = 0;
virtual std::set<CKeyID> GetKeys() const = 0;
virtual bool GetPubKey(const CKeyID &address,
CPubKey &vchPubKeyOut) const = 0;
//! Support for BIP 0013 : see
//! https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki
virtual bool AddCScript(const CScript &redeemScript) = 0;
virtual bool HaveCScript(const CScriptID &hash) const = 0;
virtual bool GetCScript(const CScriptID &hash,
CScript &redeemScriptOut) const = 0;
//! Support for Watch-only addresses
virtual bool AddWatchOnly(const CScript &dest) = 0;
virtual bool RemoveWatchOnly(const CScript &dest) = 0;
virtual bool HaveWatchOnly(const CScript &dest) const = 0;
virtual bool HaveWatchOnly() const = 0;
};
typedef std::map<CKeyID, CKey> KeyMap;
typedef std::map<CKeyID, CPubKey> WatchKeyMap;
typedef std::map<CScriptID, CScript> ScriptMap;
typedef std::set<CScript> WatchOnlySet;
/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore {
protected:
KeyMap mapKeys;
WatchKeyMap mapWatchKeys;
ScriptMap mapScripts;
WatchOnlySet setWatchOnly;
public:
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override;
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override;
- bool HaveKey(const CKeyID &address) const override {
- bool result;
- {
- LOCK(cs_KeyStore);
- result = (mapKeys.count(address) > 0);
- }
- return result;
- }
- std::set<CKeyID> GetKeys() const override {
- LOCK(cs_KeyStore);
- std::set<CKeyID> set_address;
- for (const auto &mi : mapKeys) {
- set_address.insert(mi.first);
- }
- return set_address;
- }
- bool GetKey(const CKeyID &address, CKey &keyOut) const override {
- {
- LOCK(cs_KeyStore);
- KeyMap::const_iterator mi = mapKeys.find(address);
- if (mi != mapKeys.end()) {
- keyOut = mi->second;
- return true;
- }
- }
- return false;
- }
+ bool HaveKey(const CKeyID &address) const override;
+ std::set<CKeyID> GetKeys() const override;
+ bool GetKey(const CKeyID &address, CKey &keyOut) const override;
virtual bool AddCScript(const CScript &redeemScript) override;
virtual bool HaveCScript(const CScriptID &hash) const override;
virtual bool GetCScript(const CScriptID &hash,
CScript &redeemScriptOut) const override;
virtual bool AddWatchOnly(const CScript &dest) override;
virtual bool RemoveWatchOnly(const CScript &dest) override;
virtual bool HaveWatchOnly(const CScript &dest) const override;
virtual bool HaveWatchOnly() const override;
};
typedef std::vector<uint8_t, secure_allocator<uint8_t>> CKeyingMaterial;
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<uint8_t>>>
CryptedKeyMap;
#endif // BITCOIN_KEYSTORE_H
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
index a691031ee7..3fb09127f2 100644
--- a/src/wallet/crypter.cpp
+++ b/src/wallet/crypter.cpp
@@ -1,280 +1,312 @@
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypter.h"
#include "crypto/aes.h"
#include "crypto/sha512.h"
#include "script/script.h"
#include "script/standard.h"
#include "util.h"
#include <string>
#include <vector>
int CCrypter::BytesToKeySHA512AES(const std::vector<uint8_t> &chSalt,
const SecureString &strKeyData, int count,
uint8_t *key, uint8_t *iv) const {
// This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc
// cipher and sha512 message digest. Because sha512's output size (64b) is
// greater than the aes256 block size (16b) + aes256 key size (32b), there's
// no need to process more than once (D_0).
if (!count || !key || !iv) return 0;
uint8_t buf[CSHA512::OUTPUT_SIZE];
CSHA512 di;
di.Write((const uint8_t *)strKeyData.c_str(), strKeyData.size());
if (chSalt.size()) di.Write(&chSalt[0], chSalt.size());
di.Finalize(buf);
for (int i = 0; i != count - 1; i++)
di.Reset().Write(buf, sizeof(buf)).Finalize(buf);
memcpy(key, buf, WALLET_CRYPTO_KEY_SIZE);
memcpy(iv, buf + WALLET_CRYPTO_KEY_SIZE, WALLET_CRYPTO_IV_SIZE);
memory_cleanse(buf, sizeof(buf));
return WALLET_CRYPTO_KEY_SIZE;
}
bool CCrypter::SetKeyFromPassphrase(const SecureString &strKeyData,
const std::vector<uint8_t> &chSalt,
const unsigned int nRounds,
const unsigned int nDerivationMethod) {
if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) return false;
int i = 0;
if (nDerivationMethod == 0)
i = BytesToKeySHA512AES(chSalt, strKeyData, nRounds, vchKey.data(),
vchIV.data());
if (i != (int)WALLET_CRYPTO_KEY_SIZE) {
memory_cleanse(vchKey.data(), vchKey.size());
memory_cleanse(vchIV.data(), vchIV.size());
return false;
}
fKeySet = true;
return true;
}
bool CCrypter::SetKey(const CKeyingMaterial &chNewKey,
const std::vector<uint8_t> &chNewIV) {
if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE ||
chNewIV.size() != WALLET_CRYPTO_IV_SIZE)
return false;
memcpy(vchKey.data(), chNewKey.data(), chNewKey.size());
memcpy(vchIV.data(), chNewIV.data(), chNewIV.size());
fKeySet = true;
return true;
}
bool CCrypter::Encrypt(const CKeyingMaterial &vchPlaintext,
std::vector<uint8_t> &vchCiphertext) const {
if (!fKeySet) return false;
// max ciphertext len for a n bytes of plaintext is
// n + AES_BLOCKSIZE bytes
vchCiphertext.resize(vchPlaintext.size() + AES_BLOCKSIZE);
AES256CBCEncrypt enc(vchKey.data(), vchIV.data(), true);
size_t nLen =
enc.Encrypt(&vchPlaintext[0], vchPlaintext.size(), &vchCiphertext[0]);
if (nLen < vchPlaintext.size()) return false;
vchCiphertext.resize(nLen);
return true;
}
bool CCrypter::Decrypt(const std::vector<uint8_t> &vchCiphertext,
CKeyingMaterial &vchPlaintext) const {
if (!fKeySet) return false;
// plaintext will always be equal to or lesser than length of ciphertext
int nLen = vchCiphertext.size();
vchPlaintext.resize(nLen);
AES256CBCDecrypt dec(vchKey.data(), vchIV.data(), true);
nLen =
dec.Decrypt(&vchCiphertext[0], vchCiphertext.size(), &vchPlaintext[0]);
if (nLen == 0) return false;
vchPlaintext.resize(nLen);
return true;
}
static bool EncryptSecret(const CKeyingMaterial &vMasterKey,
const CKeyingMaterial &vchPlaintext,
const uint256 &nIV,
std::vector<uint8_t> &vchCiphertext) {
CCrypter cKeyCrypter;
std::vector<uint8_t> chIV(WALLET_CRYPTO_IV_SIZE);
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_IV_SIZE);
if (!cKeyCrypter.SetKey(vMasterKey, chIV)) return false;
return cKeyCrypter.Encrypt(*((const CKeyingMaterial *)&vchPlaintext),
vchCiphertext);
}
static bool DecryptSecret(const CKeyingMaterial &vMasterKey,
const std::vector<uint8_t> &vchCiphertext,
const uint256 &nIV, CKeyingMaterial &vchPlaintext) {
CCrypter cKeyCrypter;
std::vector<uint8_t> chIV(WALLET_CRYPTO_IV_SIZE);
memcpy(&chIV[0], &nIV, WALLET_CRYPTO_IV_SIZE);
if (!cKeyCrypter.SetKey(vMasterKey, chIV)) return false;
return cKeyCrypter.Decrypt(vchCiphertext,
*((CKeyingMaterial *)&vchPlaintext));
}
static bool DecryptKey(const CKeyingMaterial &vMasterKey,
const std::vector<uint8_t> &vchCryptedSecret,
const CPubKey &vchPubKey, CKey &key) {
CKeyingMaterial vchSecret;
if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(),
vchSecret))
return false;
if (vchSecret.size() != 32) return false;
key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
return key.VerifyPubKey(vchPubKey);
}
bool CCryptoKeyStore::SetCrypted() {
LOCK(cs_KeyStore);
if (fUseCrypto) return true;
if (!mapKeys.empty()) return false;
fUseCrypto = true;
return true;
}
+bool CCryptoKeyStore::IsLocked() const {
+ if (!IsCrypted()) {
+ return false;
+ }
+ bool result;
+ {
+ LOCK(cs_KeyStore);
+ result = vMasterKey.empty();
+ }
+ return result;
+}
+
bool CCryptoKeyStore::Lock() {
if (!SetCrypted()) return false;
{
LOCK(cs_KeyStore);
vMasterKey.clear();
}
NotifyStatusChanged(this);
return true;
}
bool CCryptoKeyStore::Unlock(const CKeyingMaterial &vMasterKeyIn) {
{
LOCK(cs_KeyStore);
if (!SetCrypted()) return false;
bool keyPass = false;
bool keyFail = false;
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
for (; mi != mapCryptedKeys.end(); ++mi) {
const CPubKey &vchPubKey = (*mi).second.first;
const std::vector<uint8_t> &vchCryptedSecret = (*mi).second.second;
CKey key;
if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key)) {
keyFail = true;
break;
}
keyPass = true;
if (fDecryptionThoroughlyChecked) break;
}
if (keyPass && keyFail) {
LogPrintf("The wallet is probably corrupted: Some keys decrypt but "
"not all.\n");
assert(false);
}
if (keyFail || !keyPass) return false;
vMasterKey = vMasterKeyIn;
fDecryptionThoroughlyChecked = true;
}
NotifyStatusChanged(this);
return true;
}
bool CCryptoKeyStore::AddKeyPubKey(const CKey &key, const CPubKey &pubkey) {
{
LOCK(cs_KeyStore);
if (!IsCrypted()) return CBasicKeyStore::AddKeyPubKey(key, pubkey);
if (IsLocked()) return false;
std::vector<uint8_t> vchCryptedSecret;
CKeyingMaterial vchSecret(key.begin(), key.end());
if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(),
vchCryptedSecret))
return false;
if (!AddCryptedKey(pubkey, vchCryptedSecret)) return false;
}
return true;
}
bool CCryptoKeyStore::AddCryptedKey(
const CPubKey &vchPubKey, const std::vector<uint8_t> &vchCryptedSecret) {
{
LOCK(cs_KeyStore);
if (!SetCrypted()) return false;
mapCryptedKeys[vchPubKey.GetID()] =
make_pair(vchPubKey, vchCryptedSecret);
}
return true;
}
+bool CCryptoKeyStore::HaveKey(const CKeyID &address) const {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted()) {
+ return CBasicKeyStore::HaveKey(address);
+ }
+ return mapCryptedKeys.count(address) > 0;
+}
+
bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey &keyOut) const {
{
LOCK(cs_KeyStore);
if (!IsCrypted()) return CBasicKeyStore::GetKey(address, keyOut);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end()) {
const CPubKey &vchPubKey = (*mi).second.first;
const std::vector<uint8_t> &vchCryptedSecret = (*mi).second.second;
return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut);
}
}
return false;
}
bool CCryptoKeyStore::GetPubKey(const CKeyID &address,
CPubKey &vchPubKeyOut) const {
{
LOCK(cs_KeyStore);
if (!IsCrypted())
return CBasicKeyStore::GetPubKey(address, vchPubKeyOut);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end()) {
vchPubKeyOut = (*mi).second.first;
return true;
}
// Check for watch-only pubkeys
return CBasicKeyStore::GetPubKey(address, vchPubKeyOut);
}
return false;
}
+std::set<CKeyID> CCryptoKeyStore::GetKeys() const {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted()) {
+ return CBasicKeyStore::GetKeys();
+ }
+ std::set<CKeyID> set_address;
+ for (const auto &mi : mapCryptedKeys) {
+ set_address.insert(mi.first);
+ }
+ return set_address;
+}
+
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial &vMasterKeyIn) {
{
LOCK(cs_KeyStore);
if (!mapCryptedKeys.empty() || IsCrypted()) return false;
fUseCrypto = true;
for (KeyMap::value_type &mKey : mapKeys) {
const CKey &key = mKey.second;
CPubKey vchPubKey = key.GetPubKey();
CKeyingMaterial vchSecret(key.begin(), key.end());
std::vector<uint8_t> vchCryptedSecret;
if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(),
vchCryptedSecret))
return false;
if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) return false;
}
mapKeys.clear();
}
return true;
}
diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h
index 066ba42b42..76efa6e9a1 100644
--- a/src/wallet/crypter.h
+++ b/src/wallet/crypter.h
@@ -1,189 +1,162 @@
// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_WALLET_CRYPTER_H
#define BITCOIN_WALLET_CRYPTER_H
#include "keystore.h"
#include "serialize.h"
#include "support/allocators/secure.h"
#include <atomic>
class uint256;
const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
const unsigned int WALLET_CRYPTO_IV_SIZE = 16;
/**
* Private key encryption is done based on a CMasterKey, which holds a salt and
* random encryption key.
*
* CMasterKeys are encrypted using AES-256-CBC using a key derived using
* derivation method nDerivationMethod (0 == EVP_sha512()) and derivation
* iterations nDeriveIterations. vchOtherDerivationParameters is provided for
* alternative algorithms which may require more parameters (such as scrypt).
*
* Wallet Private Keys are then encrypted using AES-256-CBC with the
* double-sha256 of the public key as the IV, and the master key's key as the
* encryption key (see keystore.[ch]).
*/
/** Master key for wallet encryption */
class CMasterKey {
public:
std::vector<uint8_t> vchCryptedKey;
std::vector<uint8_t> vchSalt;
//! 0 = EVP_sha512()
//! 1 = scrypt()
unsigned int nDerivationMethod;
unsigned int nDeriveIterations;
//! Use this for more parameters to key derivation, such as the various
//! parameters to scrypt
std::vector<uint8_t> vchOtherDerivationParameters;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
READWRITE(vchCryptedKey);
READWRITE(vchSalt);
READWRITE(nDerivationMethod);
READWRITE(nDeriveIterations);
READWRITE(vchOtherDerivationParameters);
}
CMasterKey() {
// 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
// ie slightly lower than the lowest hardware we need bother supporting
nDeriveIterations = 25000;
nDerivationMethod = 0;
vchOtherDerivationParameters = std::vector<uint8_t>(0);
}
};
typedef std::vector<uint8_t, secure_allocator<uint8_t>> CKeyingMaterial;
namespace wallet_crypto {
class TestCrypter;
}
/** Encryption/decryption context with key information */
class CCrypter {
// for test access to chKey/chIV
friend class wallet_crypto::TestCrypter;
private:
std::vector<uint8_t, secure_allocator<uint8_t>> vchKey;
std::vector<uint8_t, secure_allocator<uint8_t>> vchIV;
bool fKeySet;
int BytesToKeySHA512AES(const std::vector<uint8_t> &chSalt,
const SecureString &strKeyData, int count,
uint8_t *key, uint8_t *iv) const;
public:
bool SetKeyFromPassphrase(const SecureString &strKeyData,
const std::vector<uint8_t> &chSalt,
const unsigned int nRounds,
const unsigned int nDerivationMethod);
bool Encrypt(const CKeyingMaterial &vchPlaintext,
std::vector<uint8_t> &vchCiphertext) const;
bool Decrypt(const std::vector<uint8_t> &vchCiphertext,
CKeyingMaterial &vchPlaintext) const;
bool SetKey(const CKeyingMaterial &chNewKey,
const std::vector<uint8_t> &chNewIV);
void CleanKey() {
memory_cleanse(vchKey.data(), vchKey.size());
memory_cleanse(vchIV.data(), vchIV.size());
fKeySet = false;
}
CCrypter() {
fKeySet = false;
vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
vchIV.resize(WALLET_CRYPTO_IV_SIZE);
}
~CCrypter() { CleanKey(); }
};
/**
* Keystore which keeps the private keys encrypted.
* It derives from the basic key store, which is used if no encryption is
* active.
*/
class CCryptoKeyStore : public CBasicKeyStore {
private:
CKeyingMaterial vMasterKey;
//! if fUseCrypto is true, mapKeys must be empty
//! if fUseCrypto is false, vMasterKey must be empty
std::atomic<bool> fUseCrypto;
//! keeps track of whether Unlock has run a thorough check before
bool fDecryptionThoroughlyChecked;
protected:
bool SetCrypted();
//! will encrypt previously unencrypted keys
bool EncryptKeys(CKeyingMaterial &vMasterKeyIn);
bool Unlock(const CKeyingMaterial &vMasterKeyIn);
CryptedKeyMap mapCryptedKeys;
public:
CCryptoKeyStore()
: fUseCrypto(false), fDecryptionThoroughlyChecked(false) {}
bool IsCrypted() const { return fUseCrypto; }
-
- bool IsLocked() const {
- if (!IsCrypted()) return false;
- bool result;
- {
- LOCK(cs_KeyStore);
- result = vMasterKey.empty();
- }
- return result;
- }
-
+ bool IsLocked() const;
bool Lock();
virtual bool AddCryptedKey(const CPubKey &vchPubKey,
const std::vector<uint8_t> &vchCryptedSecret);
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override;
- bool HaveKey(const CKeyID &address) const override {
- LOCK(cs_KeyStore);
- if (!IsCrypted()) {
- return CBasicKeyStore::HaveKey(address);
- }
-
- return mapCryptedKeys.count(address) > 0;
- }
+ bool HaveKey(const CKeyID &address) const override;
bool GetKey(const CKeyID &address, CKey &keyOut) const override;
bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const override;
- std::set<CKeyID> GetKeys() const override {
- LOCK(cs_KeyStore);
- if (!IsCrypted()) {
- return CBasicKeyStore::GetKeys();
- }
- std::set<CKeyID> set_address;
- for (const auto &mi : mapCryptedKeys) {
- set_address.insert(mi.first);
- }
- return set_address;
- }
+ std::set<CKeyID> GetKeys() const override;
/**
* Wallet status (encrypted, locked) changed.
* Note: Called without locks held.
*/
boost::signals2::signal<void(CCryptoKeyStore *wallet)> NotifyStatusChanged;
};
#endif // BITCOIN_WALLET_CRYPTER_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Nov 25, 08:04 (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4584219
Default Alt Text
(24 KB)
Attached To
rSTAGING Bitcoin ABC staging
Event Timeline
Log In to Comment