18a39422a99dba9b6f8ae154af0a5eb1afc1b147
[novacoin.git] / src / keystore.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "keystore.h"
7 #include "script.h"
8
9 extern bool fWalletUnlockMintOnly;
10
11 bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
12 {
13     CKey key;
14     if (!GetKey(address, key))
15         return false;
16     vchPubKeyOut = key.GetPubKey();
17     return true;
18 }
19
20 bool CBasicKeyStore::AddKey(const CKey& key)
21 {
22     bool fCompressed = false;
23     CSecret secret = key.GetSecret(fCompressed);
24     {
25         LOCK(cs_KeyStore);
26         mapKeys[key.GetPubKey().GetID()] = make_pair(secret, fCompressed);
27     }
28     return true;
29 }
30
31 bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
32 {
33     {
34         LOCK(cs_KeyStore);
35         mapScripts[redeemScript.GetID()] = redeemScript;
36     }
37     return true;
38 }
39
40 bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const
41 {
42     bool result;
43     {
44         LOCK(cs_KeyStore);
45         result = (mapScripts.count(hash) > 0);
46     }
47     return result;
48 }
49
50
51 bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const
52 {
53     {
54         LOCK(cs_KeyStore);
55         ScriptMap::const_iterator mi = mapScripts.find(hash);
56         if (mi != mapScripts.end())
57         {
58             redeemScriptOut = (*mi).second;
59             return true;
60         }
61     }
62     return false;
63 }
64
65 bool CCryptoKeyStore::SetCrypted()
66 {
67     {
68         LOCK(cs_KeyStore);
69         if (fUseCrypto)
70             return true;
71         if (!mapKeys.empty())
72             return false;
73         fUseCrypto = true;
74     }
75     return true;
76 }
77
78 bool CCryptoKeyStore::Lock()
79 {
80     if (!SetCrypted())
81         return false;
82
83     {
84         LOCK(cs_KeyStore);
85         vMasterKey.clear();
86         fWalletUnlockMintOnly = false;
87     }
88
89     NotifyStatusChanged(this);
90     return true;
91 }
92
93 bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
94 {
95     {
96         LOCK(cs_KeyStore);
97         if (!SetCrypted())
98             return false;
99
100         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
101         for (; mi != mapCryptedKeys.end(); ++mi)
102         {
103             const CPubKey &vchPubKey = (*mi).second.first;
104             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
105             CSecret vchSecret;
106             if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
107                 return false;
108             if (vchSecret.size() != 32)
109                 return false;
110             CKey key;
111             key.SetPubKey(vchPubKey);
112             key.SetSecret(vchSecret);
113             if (key.GetPubKey() == vchPubKey)
114                 break;
115             return false;
116         }
117         vMasterKey = vMasterKeyIn;
118     }
119     NotifyStatusChanged(this);
120     return true;
121 }
122
123 bool CCryptoKeyStore::AddKey(const CKey& key)
124 {
125     {
126         LOCK(cs_KeyStore);
127         if (!IsCrypted())
128             return CBasicKeyStore::AddKey(key);
129
130         if (IsLocked())
131             return false;
132
133         std::vector<unsigned char> vchCryptedSecret;
134         CPubKey vchPubKey = key.GetPubKey();
135         bool fCompressed;
136         if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
137             return false;
138
139         if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
140             return false;
141     }
142     return true;
143 }
144
145
146 bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
147 {
148     {
149         LOCK(cs_KeyStore);
150         if (!SetCrypted())
151             return false;
152
153         mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
154     }
155     return true;
156 }
157
158 bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
159 {
160     {
161         LOCK(cs_KeyStore);
162         if (!IsCrypted())
163             return CBasicKeyStore::GetKey(address, keyOut);
164
165         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
166         if (mi != mapCryptedKeys.end())
167         {
168             const CPubKey &vchPubKey = (*mi).second.first;
169             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
170             CSecret vchSecret;
171             if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
172                 return false;
173             if (vchSecret.size() != 32)
174                 return false;
175             keyOut.SetPubKey(vchPubKey);
176             keyOut.SetSecret(vchSecret);
177             return true;
178         }
179     }
180     return false;
181 }
182
183 bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
184 {
185     {
186         LOCK(cs_KeyStore);
187         if (!IsCrypted())
188             return CKeyStore::GetPubKey(address, vchPubKeyOut);
189
190         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
191         if (mi != mapCryptedKeys.end())
192         {
193             vchPubKeyOut = (*mi).second.first;
194             return true;
195         }
196     }
197     return false;
198 }
199
200 bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
201 {
202     {
203         LOCK(cs_KeyStore);
204         if (!mapCryptedKeys.empty() || IsCrypted())
205             return false;
206
207         fUseCrypto = true;
208         BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
209         {
210             CKey key;
211             if (!key.SetSecret(mKey.second.first, mKey.second.second))
212                 return false;
213             const CPubKey vchPubKey = key.GetPubKey();
214             std::vector<unsigned char> vchCryptedSecret;
215             bool fCompressed;
216             if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
217                 return false;
218             if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
219                 return false;
220         }
221         mapKeys.clear();
222     }
223     return true;
224 }