Move GenerateNewKey back to CWallet
[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 license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "headers.h"
7 #include "crypter.h"
8 #include "db.h"
9 #include "script.h"
10
11 bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &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     CRITICAL_BLOCK(cs_KeyStore)
25         mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
26     return true;
27 }
28
29 bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
30 {
31     CRITICAL_BLOCK(cs_KeyStore)
32         mapScripts[Hash160(redeemScript)] = redeemScript;
33     return true;
34 }
35
36 bool CBasicKeyStore::HaveCScript(const uint160& hash) const
37 {
38     bool result;
39     CRITICAL_BLOCK(cs_KeyStore)
40         result = (mapScripts.count(hash) > 0);
41     return result;
42 }
43
44
45 bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) const
46 {
47     CRITICAL_BLOCK(cs_KeyStore)
48     {
49         ScriptMap::const_iterator mi = mapScripts.find(hash);
50         if (mi != mapScripts.end())
51         {
52             redeemScriptOut = (*mi).second;
53             return true;
54         }
55     }
56     return false;
57 }
58
59 bool CCryptoKeyStore::SetCrypted()
60 {
61     CRITICAL_BLOCK(cs_KeyStore)
62     {
63         if (fUseCrypto)
64             return true;
65         if (!mapKeys.empty())
66             return false;
67         fUseCrypto = true;
68     }
69     return true;
70 }
71
72 bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
73 {
74     CRITICAL_BLOCK(cs_KeyStore)
75     {
76         if (!SetCrypted())
77             return false;
78
79         CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
80         for (; mi != mapCryptedKeys.end(); ++mi)
81         {
82             const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
83             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
84             CSecret vchSecret;
85             if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
86                 return false;
87             CKey key;
88             key.SetPubKey(vchPubKey);
89             key.SetSecret(vchSecret);
90             if (key.GetPubKey() == vchPubKey)
91                 break;
92             return false;
93         }
94         vMasterKey = vMasterKeyIn;
95     }
96     return true;
97 }
98
99 bool CCryptoKeyStore::AddKey(const CKey& key)
100 {
101     CRITICAL_BLOCK(cs_KeyStore)
102     {
103         if (!IsCrypted())
104             return CBasicKeyStore::AddKey(key);
105
106         if (IsLocked())
107             return false;
108
109         std::vector<unsigned char> vchCryptedSecret;
110         std::vector<unsigned char> vchPubKey = key.GetPubKey();
111         bool fCompressed;
112         if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
113             return false;
114
115         if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
116             return false;
117     }
118     return true;
119 }
120
121
122 bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
123 {
124     CRITICAL_BLOCK(cs_KeyStore)
125     {
126         if (!SetCrypted())
127             return false;
128
129         mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
130     }
131     return true;
132 }
133
134 bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
135 {
136     CRITICAL_BLOCK(cs_KeyStore)
137     {
138         if (!IsCrypted())
139             return CBasicKeyStore::GetKey(address, keyOut);
140
141         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
142         if (mi != mapCryptedKeys.end())
143         {
144             const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
145             const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
146             CSecret vchSecret;
147             if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
148                 return false;
149             keyOut.SetPubKey(vchPubKey);
150             keyOut.SetSecret(vchSecret);
151             return true;
152         }
153     }
154     return false;
155 }
156
157 bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
158 {
159     CRITICAL_BLOCK(cs_KeyStore)
160     {
161         if (!IsCrypted())
162             return CKeyStore::GetPubKey(address, vchPubKeyOut);
163
164         CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
165         if (mi != mapCryptedKeys.end())
166         {
167             vchPubKeyOut = (*mi).second.first;
168             return true;
169         }
170     }
171     return false;
172 }
173
174 bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
175 {
176     CRITICAL_BLOCK(cs_KeyStore)
177     {
178         if (!mapCryptedKeys.empty() || IsCrypted())
179             return false;
180
181         fUseCrypto = true;
182         BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
183         {
184             CKey key;
185             if (!key.SetSecret(mKey.second.first, mKey.second.second))
186                 return false;
187             const std::vector<unsigned char> vchPubKey = key.GetPubKey();
188             std::vector<unsigned char> vchCryptedSecret;
189             bool fCompressed;
190             if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
191                 return false;
192             if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
193                 return false;
194         }
195         mapKeys.clear();
196     }
197     return true;
198 }