Browse Source

Fix #1826

cl-refactor
Gav Wood 10 years ago
parent
commit
6aa6265989
  1. 76
      exp/main.cpp
  2. 2
      libdevcore/Common.cpp
  3. 6
      libdevcrypto/Common.cpp
  4. 2
      libdevcrypto/Common.h
  5. 2
      libethcore/CommonJS.cpp
  6. 8
      libethcore/CommonJS.h
  7. 4
      libweb3jsonrpc/WebThreeStubServerBase.cpp

76
exp/main.cpp

@ -72,15 +72,35 @@ public:
KeyManager() { readKeys(); }
~KeyManager() {}
Secret secret(h128 const& _uuid, std::string const& _pass)
Secret secret(h128 const& _uuid, function<std::string()> const& _pass)
{
auto rit = m_ready.find(_uuid);
if (rit != m_ready.end())
return rit->second;
auto it = m_keys.find(_uuid);
if (it == m_keys.end())
return Secret();
return Secret(decrypt(it->second, _pass));
Secret ret(decrypt(it->second, _pass()));
if (ret)
m_ready[_uuid] = ret;
return ret;
}
h128 create(std::string const& _pass)
{
auto s = Secret::random();
h128 r(sha3(s));
m_ready[r] = s;
m_keys[r] = encrypt(s.asBytes(), _pass);
return r;
}
private:
void writeKeys(std::string const& _keysPath = getDataDir("web3") + "/keys")
{
(void)_keysPath;
}
void readKeys(std::string const& _keysPath = getDataDir("web3") + "/keys")
{
fs::path p(_keysPath);
@ -90,25 +110,44 @@ private:
{
cdebug << "Reading" << it->path();
js::read_string(contentsString(it->path().string()), v);
js::mObject o = v.get_obj();
int version = o.count("Version") ? stoi(o["Version"].get_str()) : o.count("version") ? o["version"].get_int() : 0;
if (version == 2)
m_keys[fromUUID(o["id"].get_str())] = o["crypto"];
if (v.type() == js::obj_type)
{
js::mObject o = v.get_obj();
int version = o.count("Version") ? stoi(o["Version"].get_str()) : o.count("version") ? o["version"].get_int() : 0;
if (version == 2)
m_keys[fromUUID(o["id"].get_str())] = o["crypto"];
else
cwarn << "Cannot read key version" << version;
}
else
cwarn << "Cannot read key version" << version;
cwarn << "Invalid JSON in key file" << it->path().string();
}
}
static js::mValue encrypt(bytes const& _v, std::string const& _pass)
{
(void)_v;
(void)_pass;
return js::mValue();
}
static bytes decrypt(js::mValue const& _v, std::string const& _pass)
{
js::mObject o = _v.get_obj();
bytes pKey;
// derive key
bytes derivedKey;
if (o["kdf"].get_str() == "pbkdf2")
{
auto params = o["kdfparams"].get_obj();
if (params["prf"].get_str() != "hmac-sha256")
{
cwarn << "Unknown PRF for PBKDF2" << params["prf"].get_str() << "not supported.";
return bytes();
}
unsigned iterations = params["c"].get_int();
bytes salt = fromHex(params["salt"].get_str());
pKey = pbkdf2(_pass, salt, iterations).asBytes();
derivedKey = pbkdf2(_pass, salt, iterations, params["dklen"].get_int());
}
else
{
@ -116,16 +155,23 @@ private:
return bytes();
}
// TODO check MAC
bytes cipherText = fromHex(o["ciphertext"].get_str());
// check MAC
h256 mac(o["mac"].get_str());
(void)mac;
h256 macExp = sha3(bytesConstRef(&derivedKey).cropped(derivedKey.size() - 16).toBytes() + cipherText);
if (mac != macExp)
{
cwarn << "Invalid key - MAC mismatch; expected" << toString(macExp) << ", got" << toString(mac);
return bytes();
}
bytes cipherText = fromHex(o["ciphertext"].get_str());
// decrypt
bytes ret;
if (o["cipher"].get_str() == "aes-128-cbc")
{
auto params = o["cipherparams"].get_obj();
h128 key(sha3(h128(pKey, h128::AlignRight)), h128::AlignRight);
h128 key(sha3(h128(derivedKey, h128::AlignRight)), h128::AlignRight);
h128 iv(params["iv"].get_str());
decryptSymNoAuth(key, iv, &cipherText, ret);
}
@ -138,13 +184,15 @@ private:
return ret;
}
mutable std::map<h128, Secret> m_ready;
std::map<h128, js::mValue> m_keys;
};
int main()
{
cdebug << toHex(pbkdf2("password", asBytes("salt"), 1, 20));
KeyManager keyman;
cdebug << "Secret key for 0498f19a-59db-4d54-ac95-33901b4f1870 is " << keyman.secret(fromUUID("0498f19a-59db-4d54-ac95-33901b4f1870"), "foo");
cdebug << "Secret key for 0498f19a-59db-4d54-ac95-33901b4f1870 is " << keyman.secret(fromUUID("0498f19a-59db-4d54-ac95-33901b4f1870"), [](){ return "foo"; });
}
#elif 0

2
libdevcore/Common.cpp

@ -28,7 +28,7 @@ using namespace dev;
namespace dev
{
char const* Version = "0.9.15";
char const* Version = "0.9.15o";
void HasInvariants::checkInvariants() const
{

6
libdevcrypto/Common.cpp

@ -175,11 +175,11 @@ bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash)
return s_secp256k1.verify(_p, _s, _hash.ref(), true);
}
h256 dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations)
bytes dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen)
{
h256 ret;
bytes ret(_dkLen);
PKCS5_PBKDF2_HMAC<SHA256> pbkdf;
pbkdf.DeriveKey(ret.data(), ret.size, 0, (byte*)_pass.data(), _pass.size(), _salt.data(), _salt.size(), _iterations);
pbkdf.DeriveKey(ret.data(), ret.size(), 0, (byte*)_pass.data(), _pass.size(), _salt.data(), _salt.size(), _iterations);
return ret;
}

2
libdevcrypto/Common.h

@ -121,7 +121,7 @@ Signature sign(Secret const& _k, h256 const& _hash);
bool verify(Public const& _k, Signature const& _s, h256 const& _hash);
/// Derive key via PBKDF2.
h256 pbkdf2(std::string const& _pass, bytes const& _salt, unsigned _iterations);
bytes pbkdf2(std::string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen = 32);
/// Simple class that represents a "key pair".
/// All of the data of the class can be regenerated from the secret key (m_secret) alone.

2
libethcore/CommonJS.cpp

@ -26,6 +26,8 @@
namespace dev
{
const u256 UndefinedU256 = ~(u256)0;
Address toAddress(std::string const& _sn)
{
if (_sn.size() == 40)

8
libethcore/CommonJS.h

@ -48,14 +48,18 @@ inline Address jsToAddress(std::string const& _s) { return jsToFixed<sizeof(dev:
/// Convert u256 into user-readable string. Returns int/hex value of 64 bits int, hex of 160 bits FixedHash. As a fallback try to handle input as h256.
std::string prettyU256(u256 _n, bool _abridged = true);
extern const u256 UndefinedU256;
}
// ethcore
namespace dev
{
namespace eth
{
struct TransactionSkeleton
{
bool creation = false;
@ -63,8 +67,8 @@ struct TransactionSkeleton
Address to;
u256 value;
bytes data;
u256 gas;
u256 gasPrice;
u256 gas = UndefinedU256;
u256 gasPrice = UndefinedU256;
};
/// Convert to a block number, a bit like jsToInt, except that it correctly recognises "pending" and "latest".

4
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -502,9 +502,9 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json)
t.from = m_accounts->getDefaultTransactAccount();
if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (!t.gasPrice)
if (t.gasPrice == UndefinedU256)
t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow.
if (!t.gas)
if (t.gas == UndefinedU256)
t.gas = min<u256>(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice);
if (m_accounts->isRealAccount(t.from))

Loading…
Cancel
Save