Page MenuHomePhabricator

No OneTemporary

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

Mime Type
text/x-diff
Expires
Mon, Nov 25, 08:04 (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4584219
Default Alt Text
(24 KB)

Event Timeline