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