Add wallet privkey encryption.
[novacoin.git] / src / keystore.h
1 // Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4 #ifndef BITCOIN_KEYSTORE_H
5 #define BITCOIN_KEYSTORE_H
6
7 #include "crypter.h"
8
9 class CKeyStore
10 {
11 public:
12     mutable CCriticalSection cs_KeyStore;
13
14     virtual bool AddKey(const CKey& key) =0;
15     virtual bool HaveKey(const std::vector<unsigned char> &vchPubKey) const =0;
16     virtual bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const =0;
17     virtual std::vector<unsigned char> GenerateNewKey();
18 };
19
20 typedef std::map<std::vector<unsigned char>, CPrivKey> KeyMap;
21
22 class CBasicKeyStore : public CKeyStore
23 {
24 protected:
25     KeyMap mapKeys;
26
27 public:
28     bool AddKey(const CKey& key);
29     bool HaveKey(const std::vector<unsigned char> &vchPubKey) const
30     {
31         return (mapKeys.count(vchPubKey) > 0);
32     }
33     bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const
34     {
35         std::map<std::vector<unsigned char>, CPrivKey>::const_iterator mi = mapKeys.find(vchPubKey);
36         if (mi != mapKeys.end())
37         {
38             keyOut = (*mi).second;
39             return true;
40         }
41         return false;
42     }
43 };
44
45 class CCryptoKeyStore : public CBasicKeyStore
46 {
47 private:
48     std::map<std::vector<unsigned char>, std::vector<unsigned char> > mapCryptedKeys;
49
50     CKeyingMaterial vMasterKey;
51
52     // if fUseCrypto is true, mapKeys must be empty
53     // if fUseCrypto is false, vMasterKey must be empty
54     bool fUseCrypto;
55
56 protected:
57     bool SetCrypted()
58     {
59         if (fUseCrypto)
60             return true;
61         if (!mapKeys.empty())
62             return false;
63         fUseCrypto = true;
64         return true;
65     }
66
67     // will encrypt previously unencrypted keys
68     bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
69
70     bool Unlock(const CKeyingMaterial& vMasterKeyIn);
71
72 public:
73     mutable CCriticalSection cs_vMasterKey; //No guarantees master key wont get locked before you can use it, so lock this first
74
75     CCryptoKeyStore() : fUseCrypto(false)
76     {
77     }
78
79     bool IsCrypted() const
80     {
81         return fUseCrypto;
82     }
83
84     bool IsLocked() const
85     {
86         if (!IsCrypted())
87             return false;
88         return vMasterKey.empty();
89     }
90
91     bool Lock()
92     {
93         CRITICAL_BLOCK(cs_vMasterKey)
94         {
95             if (!SetCrypted())
96                 return false;
97
98             vMasterKey.clear();
99         }
100         return true;
101     }
102
103     virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
104     std::vector<unsigned char> GenerateNewKey();
105     bool AddKey(const CKey& key);
106     bool HaveKey(const std::vector<unsigned char> &vchPubKey) const
107     {
108         if (!IsCrypted())
109             return CBasicKeyStore::HaveKey(vchPubKey);
110         return mapCryptedKeys.count(vchPubKey) > 0;
111     }
112     bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const;
113 };
114
115 #endif