// ECOin - Copyright (c) - 2014/2021 - GPLv3 - epsylon@riseup.net (https://03c8.net) #ifndef ECOIN_KEYSTORE_H #define ECOIN_KEYSTORE_H #include "crypter.h" #include "sync.h" #include class CScript; class CKeyStore { protected: mutable CCriticalSection cs_KeyStore; public: virtual ~CKeyStore() {} virtual bool AddKey(const CKey& key) =0; virtual bool HaveKey(const CKeyID &address) const =0; virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0; virtual void GetKeys(std::set &setAddress) const =0; virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; 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; virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const { CKey key; if (!GetKey(address, key)) return false; vchSecret = key.GetSecret(fCompressed); return true; } }; typedef std::map > KeyMap; typedef std::map ScriptMap; class CBasicKeyStore : public CKeyStore { protected: KeyMap mapKeys; ScriptMap mapScripts; public: bool AddKey(const CKey& key); bool HaveKey(const CKeyID &address) const { bool result; { LOCK(cs_KeyStore); result = (mapKeys.count(address) > 0); } return result; } void GetKeys(std::set &setAddress) const { setAddress.clear(); { LOCK(cs_KeyStore); KeyMap::const_iterator mi = mapKeys.begin(); while (mi != mapKeys.end()) { setAddress.insert((*mi).first); mi++; } } } bool GetKey(const CKeyID &address, CKey &keyOut) const { { LOCK(cs_KeyStore); KeyMap::const_iterator mi = mapKeys.find(address); if (mi != mapKeys.end()) { keyOut.Reset(); keyOut.SetSecret((*mi).second.first, (*mi).second.second); return true; } } return false; } virtual bool AddCScript(const CScript& redeemScript); virtual bool HaveCScript(const CScriptID &hash) const; virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const; }; typedef std::map > > CryptedKeyMap; class CCryptoKeyStore : public CBasicKeyStore { private: CryptedKeyMap mapCryptedKeys; CKeyingMaterial vMasterKey; bool fUseCrypto; protected: bool SetCrypted(); bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); bool Unlock(const CKeyingMaterial& vMasterKeyIn); public: CCryptoKeyStore() : fUseCrypto(false) { } bool IsCrypted() const { return fUseCrypto; } bool IsLocked() const { if (!IsCrypted()) return false; bool result; { LOCK(cs_KeyStore); result = vMasterKey.empty(); } return result; } bool Lock(); virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); bool AddKey(const CKey& key); bool HaveKey(const CKeyID &address) const { { LOCK(cs_KeyStore); if (!IsCrypted()) return CBasicKeyStore::HaveKey(address); return mapCryptedKeys.count(address) > 0; } return false; } bool GetKey(const CKeyID &address, CKey& keyOut) const; bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; void GetKeys(std::set &setAddress) const { if (!IsCrypted()) { CBasicKeyStore::GetKeys(setAddress); return; } setAddress.clear(); CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); while (mi != mapCryptedKeys.end()) { setAddress.insert((*mi).first); mi++; } } boost::signals2::signal NotifyStatusChanged; }; #endif