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