25 #include <boost/filesystem.hpp>
34 namespace js = json_spirit;
35 namespace fs = boost::filesystem;
37 KeyManager::KeyManager(fs::path
const& _keysFile, fs::path
const& _secretsPath):
38 m_keysFile(_keysFile), m_store(_secretsPath)
40 for (
auto const&
uuid: m_store.
keys())
43 m_addrLookup[addr] =
uuid;
44 m_uuidLookup[
uuid] = addr;
59 write(_pass, m_keysFile);
69 m_keyInfo[_address].passHash = hashPassword(_newPass);
85 unsigned version = unsigned(s[0]);
88 bool saveRequired =
false;
89 for (
auto const& i: s[1])
97 m_addrLookup[addr] =
uuid;
98 m_uuidLookup[
uuid] = addr;
99 m_keyInfo[addr] =
KeyInfo(
h256(i[2]),
string(i[3]), i.itemCount() > 4 ?
string(i[4]) :
"");
107 m_keyInfo[addr] =
KeyInfo(
h256(i[2]),
string(i[3]), i.itemCount() > 4 ?
string(i[4]) :
"");
113 for (
auto const& i: s[2])
114 m_passwordHint[
h256(i[0])] = string(i[1]);
115 m_defaultPasswordDeprecated = string(s[3]);
118 cachePassword(m_defaultPasswordDeprecated);
122 m_master = hashPassword(_pass);
123 cachePassword(_pass);
134 return secret(m_addrLookup.at(_address), _pass, _usePasswordCache);
139 if (_usePasswordCache)
140 return Secret(m_store.
secret(_uuid, [&](){ return getPassword(_uuid, _pass); }, _usePasswordCache));
142 return Secret(m_store.
secret(_uuid, _pass, _usePasswordCache));
148 auto ait = m_uuidLookup.find(_uuid);
149 if (ait != m_uuidLookup.end())
151 auto kit = m_keyInfo.find(ait->second);
152 if (kit != m_keyInfo.end())
153 ph = kit->second.passHash;
160 auto it = m_cachedPasswords.find(_passHash);
161 if (it != m_cachedPasswords.end())
163 for (
unsigned i = 0; i < 10; ++i)
168 if (_passHash == UnknownPassword || hashPassword(p) == _passHash)
179 auto it = m_addrLookup.find(_a);
180 if (it == m_addrLookup.end())
187 auto it = m_uuidLookup.find(_uuid);
188 if (it == m_uuidLookup.end())
196 auto passHash = hashPassword(_pass);
197 cachePassword(_pass);
198 m_passwordHint[passHash] = _passwordHint;
200 m_keyInfo[addr] =
KeyInfo{passHash, _accountName,
""};
201 m_addrLookup[addr] =
uuid;
202 m_uuidLookup[
uuid] = addr;
213 auto passHash = hashPassword(_pass);
214 if (!m_cachedPasswords.count(passHash))
215 cachePassword(_pass);
221 if (!m_passwordHint.count(_passHash))
222 m_passwordHint[_passHash] = _passwordHint;
223 m_uuidLookup[_uuid] = _address;
224 m_addrLookup[_address] = _uuid;
225 m_keyInfo[_address].passHash = _passHash;
226 m_keyInfo[_address].accountName = _accountName;
232 auto id = m_addrLookup[_a];
233 m_uuidLookup.erase(
id);
234 m_addrLookup.erase(_a);
243 json_spirit::read_string(_json, val);
244 auto obj = val.get_obj();
245 string p = _password(
true);
246 if (obj[
"encseed"].type() == js::str_type)
248 auto encseed =
fromHex(obj[
"encseed"].get_str());
252 if (obj[
"ethaddr"].type() == js::str_type)
254 Address a(obj[
"ethaddr"].get_str());
258 if ((p = _password(
false)).empty())
272 set<Address> addresses;
273 for (
auto const& i: m_keyInfo)
274 addresses.insert(i.first);
275 for (
auto const& key: m_store.
keys())
276 addresses.insert(m_store.
address(key));
285 if (m_keyInfo.count(_address))
287 for (
auto const& key: m_store.
keys())
288 if (m_store.
address(key) == _address)
297 return m_keyInfo.at(_address).accountName;
309 auto& info = m_keyInfo.at(_address);
310 if (info.passwordHint.size())
311 return info.passwordHint;
312 return m_passwordHint.at(info.passHash);
320 h256 KeyManager::hashPassword(
string const& _pass)
const
323 return h256(
pbkdf2(_pass,
asBytes(m_defaultPasswordDeprecated), 262144, 32).makeInsecure());
326 void KeyManager::cachePassword(
string const& _password)
const
328 m_cachedPasswords[hashPassword(_password)] = _password;
331 bool KeyManager::write(fs::path
const& _keysFile)
const
335 write(m_keysFileKey, _keysFile);
339 void KeyManager::write(
string const& _pass, fs::path
const& _keysFile)
const
345 cachePassword(_pass);
346 m_master = hashPassword(_pass);
347 write(key, _keysFile);
355 s.appendList(m_keyInfo.size());
356 for (
auto const& info: m_keyInfo)
359 auto const& ki = info.second;
360 s.appendList(5) << info.first <<
id << ki.passHash << ki.accountName << ki.passwordHint;
363 s.appendList(m_passwordHint.size());
364 for (
auto const& i: m_passwordHint)
365 s.appendList(2) << i.first << i.second;
366 s.append(m_defaultPasswordDeprecated);
369 m_keysFileKey = _key;
370 cachePassword(defaultPassword());
376 bool keepGoing =
true;
383 if (done % 1000 == 0)
384 cnote <<
"Tried" << done <<
"keys";
401 vector<std::thread*> ts;
402 for (
unsigned t = 0; t < std::thread::hardware_concurrency() - 1; ++t)
403 ts.push_back(
new std::thread(f));
406 for (std::thread* t: ts)