Ethereum  PoC-8
The C++ Implementation of Ethereum
KeyManager.h
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16  */
22 #pragma once
23 
24 #include <functional>
25 #include <mutex>
26 #include <libdevcore/FileSystem.h>
27 #include <libdevcore/CommonData.h>
29 
30 #include <boost/filesystem.hpp>
31 
32 namespace dev
33 {
34 namespace eth
35 {
36 class PasswordUnknown: public Exception {};
37 
38 struct KeyInfo
39 {
40  KeyInfo() = default;
41  KeyInfo(h256 const& _passHash, std::string const& _accountName, std::string const& _passwordHint = std::string()): passHash(_passHash), accountName(_accountName), passwordHint(_passwordHint) {}
42 
46  std::string accountName;
48  std::string passwordHint;
49 };
50 
51 static h256 const UnknownPassword;
53 static auto const DontKnowThrow = [](){ throw PasswordUnknown(); return std::string(); };
54 
55 enum class SemanticPassword
56 {
57  Existing,
58  Master
59 };
60 
61 // TODO: This one is specifically for Ethereum, but we can make it generic in due course.
62 // TODO: hidden-partition style key-store.
75 {
76 public:
78 
79  KeyManager(boost::filesystem::path const& _keysFile = defaultPath(), boost::filesystem::path const& _secretsPath = SecretStore::defaultPath());
80  ~KeyManager();
81 
82  void setKeysFile(boost::filesystem::path const& _keysFile) { m_keysFile = _keysFile; }
83  boost::filesystem::path const& keysFile() const { return m_keysFile; }
84 
85  bool exists() const;
86  void create(std::string const& _pass);
87  bool load(std::string const& _pass);
88  void save(std::string const& _pass) const { write(_pass, m_keysFile); }
89 
90  void notePassword(std::string const& _pass) { m_cachedPasswords[hashPassword(_pass)] = _pass; }
91  void noteHint(std::string const& _pass, std::string const& _hint) { if (!_hint.empty()) m_passwordHint[hashPassword(_pass)] = _hint; }
92  bool haveHint(std::string const& _pass) const { auto h = hashPassword(_pass); return m_cachedPasswords.count(h) && !m_cachedPasswords.at(h).empty(); }
93 
95  Addresses accounts() const;
97  AddressHash accountsHash() const { return AddressHash() + accounts(); }
98  bool hasAccount(Address const& _address) const;
100  std::string const& accountName(Address const& _address) const;
102  std::string const& passwordHint(Address const& _address) const;
103 
105  h128 uuid(Address const& _a) const;
107  Address address(h128 const& _uuid) const;
108 
109  h128 import(Secret const& _s, std::string const& _accountName, std::string const& _pass, std::string const& _passwordHint);
110  h128 import(Secret const& _s, std::string const& _accountName) { return import(_s, _accountName, defaultPassword(), std::string()); }
111 
112  SecretStore& store() { return m_store; }
113  void importExisting(h128 const& _uuid, std::string const& _accountName, std::string const& _pass, std::string const& _passwordHint);
114  void importExisting(h128 const& _uuid, std::string const& _accountName, Address const& _addr, h256 const& _passHash = h256(), std::string const& _passwordHint = std::string());
115 
118  Secret secret(Address const& _address, std::function<std::string()> const& _pass = DontKnowThrow, bool _usePasswordCache = true) const;
121  Secret secret(h128 const& _uuid, std::function<std::string()> const& _pass = DontKnowThrow, bool _usePasswordCache = true) const;
122 
123  bool recode(Address const& _address, std::string const& _newPass, std::string const& _hint, std::function<std::string()> const& _pass = DontKnowThrow, KDF _kdf = KDF::Scrypt);
124 
125  void kill(h128 const& _id) { kill(address(_id)); }
126  void kill(Address const& _a);
127 
128  static boost::filesystem::path defaultPath() { return getDataDir("ethereum") / boost::filesystem::path("keys.info"); }
129 
131  static KeyPair presaleSecret(std::string const& _json, std::function<std::string(bool)> const& _password);
132 
134  static KeyPair newKeyPair(NewKeyType _type);
135 private:
136  std::string getPassword(h128 const& _uuid, std::function<std::string()> const& _pass = DontKnowThrow) const;
137  std::string getPassword(h256 const& _passHash, std::function<std::string()> const& _pass = DontKnowThrow) const;
138  std::string defaultPassword(std::function<std::string()> const& _pass = DontKnowThrow) const { return getPassword(m_master, _pass); }
139  h256 hashPassword(std::string const& _pass) const;
140 
142  void cachePassword(std::string const& _password) const;
143 
144  // Only use if previously loaded ok.
145  // @returns false if wasn't previously loaded ok.
146  bool write() const { return write(m_keysFile); }
147  bool write(boost::filesystem::path const& _keysFile) const;
148  void write(std::string const& _pass, boost::filesystem::path const& _keysFile) const; // TODO: all passwords should be a secure string.
149  void write(SecureFixedHash<16> const& _key, boost::filesystem::path const& _keysFile) const;
150 
151  // Ethereum keys.
152 
154  std::unordered_map<h128, Address> m_uuidLookup;
156  std::unordered_map<Address, h128> m_addrLookup;
158  std::unordered_map<Address, KeyInfo> m_keyInfo;
160  std::unordered_map<h256, std::string> m_passwordHint;
161 
162  // Passwords that we're storing. Mapping password hash -> password.
163  mutable std::unordered_map<h256, std::string> m_cachedPasswords;
164 
165  // DEPRECATED.
166  // Used to be the default password for keys in the keystore, stored in the keys file.
167  // Now the default password is based off the key of the keys file directly, so this is redundant
168  // except for the fact that people have existing keys stored with it. Leave for now until/unless
169  // we have an upgrade strategy.
170  std::string m_defaultPasswordDeprecated;
171 
172  mutable boost::filesystem::path m_keysFile;
173  mutable SecureFixedHash<16> m_keysFileKey;
174  mutable h256 m_master;
175  SecretStore m_store;
176 };
177 
178 }
179 }
dev::eth::KeyManager::hasAccount
bool hasAccount(Address const &_address) const
Definition: KeyManager.cpp:281
dev::eth::KeyManager
High-level manager of password-encrypted keys for Ethereum. Usage:
Definition: KeyManager.h:75
dev::eth::KeyManager::NewKeyType::FirstFour
@ FirstFour
dev::eth::KeyManager::notePassword
void notePassword(std::string const &_pass)
Definition: KeyManager.h:90
dev::eth::KeyManager::NewKeyType::DirectICAP
@ DirectICAP
dev::eth::KeyInfo::passHash
h256 passHash
Hash of the password or h256() / UnknownPassword if unknown.
Definition: KeyManager.h:44
dev::eth::KeyInfo
Definition: KeyManager.h:39
SecretStore.h
dev::eth::KeyInfo::passwordHint
std::string passwordHint
Hint of the password. Alternative place for storage than the hash-based lookup.
Definition: KeyManager.h:48
dev::SecureFixedHash< 32 >
dev::KDF
KDF
Definition: SecretStore.h:35
dev::eth::KeyManager::haveHint
bool haveHint(std::string const &_pass) const
Definition: KeyManager.h:92
dev::eth::KeyManager::accountsHash
AddressHash accountsHash() const
Definition: KeyManager.h:97
dev::eth::KeyManager::NewKeyType::FirstTwo
@ FirstTwo
dev::eth::KeyManager::setKeysFile
void setKeysFile(boost::filesystem::path const &_keysFile)
Definition: KeyManager.h:82
dev::eth::KeyManager::defaultPath
static boost::filesystem::path defaultPath()
Definition: KeyManager.h:128
dev::h256
FixedHash< 32 > h256
Definition: FixedHash.h:356
dev::eth::KeyInfo::KeyInfo
KeyInfo()=default
dev::eth::KeyInfo::accountName
std::string accountName
Name of the key, or JSON key info if begins with '{'.
Definition: KeyManager.h:46
dev::eth::KeyManager::NewKeyType
NewKeyType
Definition: KeyManager.h:77
dev::Addresses
h160s Addresses
A vector of Ethereum addresses.
Definition: Address.h:33
dev::FixedHash< 32 >
dev::eth::KeyManager::recode
bool recode(Address const &_address, std::string const &_newPass, std::string const &_hint, std::function< std::string()> const &_pass=DontKnowThrow, KDF _kdf=KDF::Scrypt)
Definition: KeyManager.cpp:62
dev::eth::SemanticPassword::Master
@ Master
dev::eth::KeyManager::NewKeyType::NoVanity
@ NoVanity
dev::eth::KeyManager::secret
Secret secret(h128 const &_uuid, std::function< std::string()> const &_pass=DontKnowThrow, bool _usePasswordCache=true) const
dev::eth::KeyManager::secret
Secret secret(Address const &_address, std::function< std::string()> const &_pass=DontKnowThrow, bool _usePasswordCache=true) const
dev::eth::KeyManager::importExisting
void importExisting(h128 const &_uuid, std::string const &_accountName, Address const &_addr, h256 const &_passHash=h256(), std::string const &_passwordHint=std::string())
dev::Exception
Base class for all exceptions.
Definition: Exceptions.h:39
dev::eth::KeyManager::store
SecretStore & store()
Definition: KeyManager.h:112
dev::eth::KeyInfo::KeyInfo
KeyInfo(h256 const &_passHash, std::string const &_accountName, std::string const &_passwordHint=std::string())
Definition: KeyManager.h:41
dev::AddressHash
std::unordered_set< h160 > AddressHash
A hash set of Ethereum addresses.
Definition: Address.h:36
dev::eth::KeyManager::create
void create(std::string const &_pass)
Definition: KeyManager.cpp:56
dev::eth::KeyManager::presaleSecret
static KeyPair presaleSecret(std::string const &_json, std::function< std::string(bool)> const &_password)
Extracts the secret key from the presale wallet.
Definition: KeyManager.cpp:240
dev::eth::KeyManager::passwordHint
std::string const & passwordHint(Address const &_address) const
Definition: KeyManager.cpp:305
dev::eth::KeyManager::exists
bool exists() const
Definition: KeyManager.cpp:51
dev::eth::KeyManager::NewKeyType::FirstTwoNextTwo
@ FirstTwoNextTwo
dev::eth::KeyManager::load
bool load(std::string const &_pass)
Definition: KeyManager.cpp:74
dev::eth::KeyManager::~KeyManager
~KeyManager()
Definition: KeyManager.cpp:48
dev::SecretStore::defaultPath
static boost::filesystem::path defaultPath()
Definition: SecretStore.h:124
dev::eth::KeyManager::uuid
h128 uuid(Address const &_a) const
Definition: KeyManager.cpp:177
dev::KDF::Scrypt
@ Scrypt
dev::getDataDir
boost::filesystem::path getDataDir(std::string _prefix="ethereum")
dev::eth::KeyManager::keysFile
boost::filesystem::path const & keysFile() const
Definition: KeyManager.h:83
CommonData.h
FileSystem.h
dev::eth::KeyManager::accounts
Addresses accounts() const
Definition: KeyManager.cpp:270
dev::eth::KeyManager::newKeyPair
static KeyPair newKeyPair(NewKeyType _type)
Definition: KeyManager.cpp:373
dev::eth::KeyManager::save
void save(std::string const &_pass) const
Definition: KeyManager.h:88
dev::eth::SemanticPassword::Existing
@ Existing
dev::eth::KeyManager::noteHint
void noteHint(std::string const &_pass, std::string const &_hint)
Definition: KeyManager.h:91
dev::eth::PasswordUnknown
Definition: KeyManager.h:36
dev::eth::SemanticPassword
SemanticPassword
Definition: KeyManager.h:56
dev::eth::KeyManager::kill
void kill(h128 const &_id)
Definition: KeyManager.h:125
dev::eth::KeyManager::address
Address address(h128 const &_uuid) const
Definition: KeyManager.cpp:185
dev::eth::KeyManager::KeyManager
KeyManager(boost::filesystem::path const &_keysFile=defaultPath(), boost::filesystem::path const &_secretsPath=SecretStore::defaultPath())
Definition: KeyManager.cpp:37
dev
Definition: Address.cpp:21
dev::KeyPair
Definition: Common.h:149
dev::eth::KeyManager::accountName
std::string const & accountName(Address const &_address) const
Definition: KeyManager.cpp:293
dev::eth::KeyManager::NewKeyType::FirstThree
@ FirstThree
dev::SecretStore
Definition: SecretStore.h:49
dev::eth::KeyManager::importExisting
void importExisting(h128 const &_uuid, std::string const &_accountName, std::string const &_pass, std::string const &_passwordHint)