|
|
@ -121,6 +121,23 @@ static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<u |
|
|
|
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)); |
|
|
|
} |
|
|
|
|
|
|
|
static bool DecryptHDSeed( |
|
|
|
const CKeyingMaterial& vMasterKey, |
|
|
|
const std::vector<unsigned char>& vchCryptedSecret, |
|
|
|
const uint256& seedFp, |
|
|
|
HDSeed& seed) |
|
|
|
{ |
|
|
|
CKeyingMaterial vchSecret; |
|
|
|
|
|
|
|
// Use seed's fingerprint as IV
|
|
|
|
// TODO: Handle IV properly when we make encryption a supported feature
|
|
|
|
if(!DecryptSecret(vMasterKey, vchCryptedSecret, seedFp, vchSecret)) |
|
|
|
return false; |
|
|
|
|
|
|
|
seed = HDSeed(vchSecret); |
|
|
|
return seed.Fingerprint() == seedFp; |
|
|
|
} |
|
|
|
|
|
|
|
static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key) |
|
|
|
{ |
|
|
|
CKeyingMaterial vchSecret; |
|
|
@ -202,6 +219,15 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) |
|
|
|
|
|
|
|
bool keyPass = false; |
|
|
|
bool keyFail = false; |
|
|
|
{ |
|
|
|
HDSeed seed; |
|
|
|
if (!DecryptHDSeed(vMasterKeyIn, cryptedHDSeed.second, cryptedHDSeed.first, seed)) |
|
|
|
{ |
|
|
|
keyFail = true; |
|
|
|
} else { |
|
|
|
keyPass = true; |
|
|
|
} |
|
|
|
} |
|
|
|
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); |
|
|
|
for (; mi != mapCryptedKeys.end(); ++mi) |
|
|
|
{ |
|
|
@ -261,6 +287,67 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool CCryptoKeyStore::SetHDSeed(const HDSeed& seed) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_SpendingKeyStore); |
|
|
|
if (!IsCrypted()) { |
|
|
|
return CBasicKeyStore::SetHDSeed(seed); |
|
|
|
} |
|
|
|
|
|
|
|
if (IsLocked()) |
|
|
|
return false; |
|
|
|
|
|
|
|
std::vector<unsigned char> vchCryptedSecret; |
|
|
|
// Use seed's fingerprint as IV
|
|
|
|
// TODO: Handle this properly when we make encryption a supported feature
|
|
|
|
auto seedFp = seed.Fingerprint(); |
|
|
|
if (!EncryptSecret(vMasterKey, seed.RawSeed(), seedFp, vchCryptedSecret)) |
|
|
|
return false; |
|
|
|
|
|
|
|
// This will call into CWallet to store the crypted seed to disk
|
|
|
|
if (!SetCryptedHDSeed(seedFp, vchCryptedSecret)) |
|
|
|
return false; |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool CCryptoKeyStore::SetCryptedHDSeed( |
|
|
|
const uint256& seedFp, |
|
|
|
const std::vector<unsigned char>& vchCryptedSecret) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_SpendingKeyStore); |
|
|
|
if (!IsCrypted()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
cryptedHDSeed = std::make_pair(seedFp, vchCryptedSecret); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool CCryptoKeyStore::HaveHDSeed() const |
|
|
|
{ |
|
|
|
LOCK(cs_SpendingKeyStore); |
|
|
|
if (!IsCrypted()) |
|
|
|
return CBasicKeyStore::HaveHDSeed(); |
|
|
|
|
|
|
|
return !cryptedHDSeed.second.empty(); |
|
|
|
} |
|
|
|
|
|
|
|
bool CCryptoKeyStore::GetHDSeed(HDSeed& seedOut) const |
|
|
|
{ |
|
|
|
LOCK(cs_SpendingKeyStore); |
|
|
|
if (!IsCrypted()) |
|
|
|
return CBasicKeyStore::GetHDSeed(seedOut); |
|
|
|
|
|
|
|
if (cryptedHDSeed.second.empty()) |
|
|
|
return false; |
|
|
|
|
|
|
|
return DecryptHDSeed(vMasterKey, cryptedHDSeed.second, cryptedHDSeed.first, seedOut); |
|
|
|
} |
|
|
|
|
|
|
|
bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -463,6 +550,20 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) |
|
|
|
return false; |
|
|
|
|
|
|
|
fUseCrypto = true; |
|
|
|
{ |
|
|
|
std::vector<unsigned char> vchCryptedSecret; |
|
|
|
// Use seed's fingerprint as IV
|
|
|
|
// TODO: Handle this properly when we make encryption a supported feature
|
|
|
|
auto seedFp = hdSeed.Fingerprint(); |
|
|
|
if (!EncryptSecret(vMasterKeyIn, hdSeed.RawSeed(), seedFp, vchCryptedSecret)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
// This will call into CWallet to store the crypted seed to disk
|
|
|
|
if (!SetCryptedHDSeed(seedFp, vchCryptedSecret)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
hdSeed = HDSeed(); |
|
|
|
BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys) |
|
|
|
{ |
|
|
|
const CKey &key = mKey.second; |
|
|
|