Add wallet privkey encryption.
[novacoin.git] / src / keystore.h
index 2f37ec5..8d445be 100644 (file)
@@ -4,7 +4,112 @@
 #ifndef BITCOIN_KEYSTORE_H
 #define BITCOIN_KEYSTORE_H
 
-bool AddKey(const CKey& key);
-std::vector<unsigned char> GenerateNewKey();
+#include "crypter.h"
+
+class CKeyStore
+{
+public:
+    mutable CCriticalSection cs_KeyStore;
+
+    virtual bool AddKey(const CKey& key) =0;
+    virtual bool HaveKey(const std::vector<unsigned char> &vchPubKey) const =0;
+    virtual bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const =0;
+    virtual std::vector<unsigned char> GenerateNewKey();
+};
+
+typedef std::map<std::vector<unsigned char>, CPrivKey> KeyMap;
+
+class CBasicKeyStore : public CKeyStore
+{
+protected:
+    KeyMap mapKeys;
+
+public:
+    bool AddKey(const CKey& key);
+    bool HaveKey(const std::vector<unsigned char> &vchPubKey) const
+    {
+        return (mapKeys.count(vchPubKey) > 0);
+    }
+    bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const
+    {
+        std::map<std::vector<unsigned char>, CPrivKey>::const_iterator mi = mapKeys.find(vchPubKey);
+        if (mi != mapKeys.end())
+        {
+            keyOut = (*mi).second;
+            return true;
+        }
+        return false;
+    }
+};
+
+class CCryptoKeyStore : public CBasicKeyStore
+{
+private:
+    std::map<std::vector<unsigned char>, std::vector<unsigned char> > mapCryptedKeys;
+
+    CKeyingMaterial vMasterKey;
+
+    // if fUseCrypto is true, mapKeys must be empty
+    // if fUseCrypto is false, vMasterKey must be empty
+    bool fUseCrypto;
+
+protected:
+    bool SetCrypted()
+    {
+        if (fUseCrypto)
+            return true;
+        if (!mapKeys.empty())
+            return false;
+        fUseCrypto = true;
+        return true;
+    }
+
+    // will encrypt previously unencrypted keys
+    bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
+
+    bool Unlock(const CKeyingMaterial& vMasterKeyIn);
+
+public:
+    mutable CCriticalSection cs_vMasterKey; //No guarantees master key wont get locked before you can use it, so lock this first
+
+    CCryptoKeyStore() : fUseCrypto(false)
+    {
+    }
+
+    bool IsCrypted() const
+    {
+        return fUseCrypto;
+    }
+
+    bool IsLocked() const
+    {
+        if (!IsCrypted())
+            return false;
+        return vMasterKey.empty();
+    }
+
+    bool Lock()
+    {
+        CRITICAL_BLOCK(cs_vMasterKey)
+        {
+            if (!SetCrypted())
+                return false;
+
+            vMasterKey.clear();
+        }
+        return true;
+    }
+
+    virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
+    std::vector<unsigned char> GenerateNewKey();
+    bool AddKey(const CKey& key);
+    bool HaveKey(const std::vector<unsigned char> &vchPubKey) const
+    {
+        if (!IsCrypted())
+            return CBasicKeyStore::HaveKey(vchPubKey);
+        return mapCryptedKeys.count(vchPubKey) > 0;
+    }
+    bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const;
+};
 
 #endif