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