8aaf3e64407c0661ad8a0b56d177b46da38ef664
[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 // A virtual base class for key stores
11 class CKeyStore
12 {
13 protected:
14     mutable CCriticalSection cs_KeyStore;
15
16 public:
17     virtual ~CKeyStore() {}
18
19     // Add a key to the store.
20     virtual bool AddKey(const CKey& key) =0;
21
22     // Check whether a key corresponding to a given address is present in the store.
23     virtual bool HaveKey(const CBitcoinAddress &address) const =0;
24
25     // Retrieve a key corresponding to a given address from the store.
26     // Return true if succesful.
27     virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
28
29     // Retrieve only the public key corresponding to a given address.
30     // This may succeed even if GetKey fails (e.g., encrypted wallets)
31     virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
32
33     // Generate a new key, and add it to the store
34     virtual std::vector<unsigned char> GenerateNewKey();
35 };
36
37 typedef std::map<CBitcoinAddress, CSecret> KeyMap;
38
39 // Basic key store, that keeps keys in an address->secret map
40 class CBasicKeyStore : public CKeyStore
41 {
42 protected:
43     KeyMap mapKeys;
44
45 public:
46     bool AddKey(const CKey& key);
47     bool HaveKey(const CBitcoinAddress &address) const
48     {
49         bool result;
50         CRITICAL_BLOCK(cs_KeyStore)
51             result = (mapKeys.count(address) > 0);
52         return result;
53     }
54     bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
55     {
56         CRITICAL_BLOCK(cs_KeyStore)
57         {
58             KeyMap::const_iterator mi = mapKeys.find(address);
59             if (mi != mapKeys.end())
60             {
61                 keyOut.SetSecret((*mi).second);
62                 return true;
63             }
64         }
65         return false;
66     }
67 };
68
69 typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
70
71 // Keystore which keeps the private keys encrypted
72 // It derives from the basic key store, which is used if no encryption is active.
73 class CCryptoKeyStore : public CBasicKeyStore
74 {
75 private:
76     CryptedKeyMap mapCryptedKeys;
77
78     CKeyingMaterial vMasterKey;
79
80     // if fUseCrypto is true, mapKeys must be empty
81     // if fUseCrypto is false, vMasterKey must be empty
82     bool fUseCrypto;
83
84 protected:
85     bool SetCrypted();
86
87     // will encrypt previously unencrypted keys
88     bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
89
90     bool Unlock(const CKeyingMaterial& vMasterKeyIn);
91
92 public:
93     CCryptoKeyStore() : fUseCrypto(false)
94     {
95     }
96
97     bool IsCrypted() const
98     {
99         return fUseCrypto;
100     }
101
102     bool IsLocked() const
103     {
104         if (!IsCrypted())
105             return false;
106         bool result;
107         CRITICAL_BLOCK(cs_KeyStore)
108             result = vMasterKey.empty();
109         return result;
110     }
111
112     bool Lock()
113     {
114         if (!SetCrypted())
115             return false;
116
117         CRITICAL_BLOCK(cs_KeyStore)
118             vMasterKey.clear();
119
120         return true;
121     }
122
123     virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
124     std::vector<unsigned char> GenerateNewKey();
125     bool AddKey(const CKey& key);
126     bool HaveKey(const CBitcoinAddress &address) const
127     {
128         CRITICAL_BLOCK(cs_KeyStore)
129         {
130             if (!IsCrypted())
131                 return CBasicKeyStore::HaveKey(address);
132             return mapCryptedKeys.count(address) > 0;
133         }
134         return false;
135     }
136     bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
137     bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
138 };
139
140 #endif