Browse Source

more attempts to mimic what Vitalik did with wallet encryption.

cl-refactor
Gav Wood 10 years ago
parent
commit
234cc551b6
  1. 36
      alethzero/MainWin.cpp
  2. 1
      alethzero/MainWin.h
  3. 59
      libqethereum/QEthereum.cpp
  4. 53
      libqethereum/QEthereum.h
  5. 2
      libwhisper/Message.h
  6. 9
      third/MainWin.cpp
  7. 8
      third/MainWin.h

36
alethzero/MainWin.cpp

@ -28,6 +28,11 @@
#include <QtGui/QClipboard>
#include <QtCore/QtCore>
#include <boost/algorithm/string.hpp>
#include <cryptopp/aes.h>
#include <cryptopp/pwdbased.h>
#include <cryptopp/modes.h>
#include <cryptopp/sha.h>
#include <cryptopp/filters.h>
#include <test/JsonSpiritHeaders.h>
#include <libserpent/funcs.h>
#include <libserpent/util.h>
@ -135,11 +140,13 @@ Main::Main(QWidget *parent) :
{
// NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
m_ethereum = new QEthereum(this, ethereum(), owned());
m_whisper = new QWhisper(this, whisper());
QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
auto qeth = m_ethereum;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, this));
auto qshh = m_whisper;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, qshh, this));
});
connect(ui->webView, &QWebView::loadFinished, [=]()
@ -584,9 +591,34 @@ void Main::on_importKeyFile_triggered()
if (obj["encseed"].type() == js::str_type)
{
QString pw = QInputDialog::getText(this, "Enter Password", "Enter the wallet's passphrase", QLineEdit::Password);
string encseedstr = obj["encseed"].get_str();
bytes encseed = fromHex(encseedstr);
Secret sec = sha3(encseed);
bytes pwbytes = asBytes(pw.toStdString());
byte targetBuffer[64];
byte saltBuffer[64];
CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256>().DeriveKey(targetBuffer, 64, 0, pwbytes.data(), pwbytes.size(), saltBuffer, 0, 2000);
try
{
CryptoPP::AES::Decryption aesDecryption(targetBuffer, 64);
byte iv[CryptoPP::AES::BLOCKSIZE];
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv);
std::string decrypted;
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decrypted));
stfDecryptor.Put(encseed.data(), encseed.size());
stfDecryptor.MessageEnd();
encseed = asBytes(decrypted);
}
catch (exception const& e)
{
cerr << e.what() << endl;
return;
}
auto sec = sha3(encseed);
k = KeyPair(sec);
if (obj["ethaddr"].type() == js::str_type)
{

1
alethzero/MainWin.h

@ -246,4 +246,5 @@ private:
bool m_logChanged = true;
QEthereum* m_ethereum = nullptr;
QWhisper* m_whisper = nullptr;
};

59
libqethereum/QEthereum.cpp

@ -476,6 +476,65 @@ void QEthereum::poll()
emit watchChanged(w);
}
// TODO: repot and hook all these up.
QWhisper::QWhisper(QObject* _p, std::shared_ptr<dev::shh::Interface> const& _c): QObject(_p), m_face(_c)
{
}
QWhisper::~QWhisper()
{
}
// probably want a better way of doing this. somehow guarantee that the face() will always be available as long as this object is.
struct NoInterface: public Exception {};
std::shared_ptr<dev::shh::Interface> QWhisper::face() const
{
auto ret = m_face.lock();
if (!ret)
throw NoInterface();
return ret;
}
void QWhisper::faceDieing()
{
}
void QWhisper::send(QString /*dev::Address*/ _dest, QString /*ev::KeyPair*/ _from, QString /*dev::h256 const&*/ _topic, QString /*dev::bytes const&*/ _payload)
{
(void)_dest;
(void)_from;
(void)_topic;
(void)_payload;
}
unsigned QWhisper::newWatch(QString _json)
{
(void)_json;
return 0;
}
QString QWhisper::watchMessages(unsigned _w)
{
(void)_w;
return "";
}
void QWhisper::killWatch(unsigned _w)
{
(void)_w;
}
void QWhisper::clearWatches()
{
}
void QWhisper::poll()
{
}
// extra bits needed to link on VS
#ifdef _MSC_VER

53
libqethereum/QEthereum.h

@ -6,9 +6,14 @@
#include <libdevcore/CommonIO.h>
#include <libethcore/CommonEth.h>
namespace dev { namespace eth {
namespace dev {
namespace eth {
class Interface;
}}
}
namespace shh {
class Interface;
}
}
class QJSEngine;
class QWebFrame;
@ -203,11 +208,51 @@ private:
QList<dev::KeyPair> m_accounts;
};
#define QETH_INSTALL_JS_NAMESPACE(frame, eth, env) [frame, eth, env]() \
class QWhisper: public QObject
{
Q_OBJECT
public:
QWhisper(QObject* _p, std::shared_ptr<dev::shh::Interface> const& _c);
virtual ~QWhisper();
std::shared_ptr<dev::shh::Interface> face() const;
void setFace(std::shared_ptr<dev::shh::Interface> const& _c) { m_face = _c; }
/// Call when the face() is going to be deleted to make this object useless but safe.
void faceDieing();
Q_INVOKABLE QWhisper* self() { return this; }
/// Basic message send.
Q_INVOKABLE void send(QString /*dev::Address*/ _dest, QString /*ev::KeyPair*/ _from, QString /*dev::h256 const&*/ _topic, QString /*dev::bytes const&*/ _payload);
// Watches interface
Q_INVOKABLE unsigned newWatch(QString _json);
Q_INVOKABLE QString watchMessages(unsigned _w);
Q_INVOKABLE void killWatch(unsigned _w);
void clearWatches();
public slots:
/// Check to see if anything has changed, fire off signals if so.
/// @note Must be called in the QObject's thread.
void poll();
signals:
void watchChanged(unsigned _w);
private:
std::weak_ptr<dev::shh::Interface> m_face;
std::vector<unsigned> m_watches;
};
#define QETH_INSTALL_JS_NAMESPACE(frame, eth, shh, env) [frame, eth, shh, env]() \
{ \
frame->disconnect(); \
frame->addToJavaScriptWindowObject("env", env, QWebFrame::QtOwnership); \
frame->addToJavaScriptWindowObject("eth", eth, QWebFrame::ScriptOwnership); \
frame->addToJavaScriptWindowObject("shh", eth, QWebFrame::ScriptOwnership); \
frame->evaluateJavaScript("eth.makeWatch = function(a) { var ww = eth.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { eth.killWatch(w); }; ret.changed = function(f) { eth.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(eth.watchMessages(this.w)) }; return ret; }"); \
frame->evaluateJavaScript("eth.watch = function(a) { return eth.makeWatch(JSON.stringify(a)) }"); \
frame->evaluateJavaScript("eth.watchChain = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.watch('chain') INSTEAD.'); return eth.makeWatch('chain') }"); \
@ -226,6 +271,8 @@ private:
frame->evaluateJavaScript("String.prototype.sha3 = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.sha3old(this) }"); \
frame->evaluateJavaScript("console.log = env.note"); \
frame->evaluateJavaScript("window.onerror = function (errorMsg, url, lineNumber, column, errorObj) { env.warn('Error: ' + errorMsg + ', Script: ' + url + ', Line: ' + lineNumber + ', Column: ' + column + ', StackTrace: ' + String(errorObj)) }"); \
frame->evaluateJavaScript("shh.makeWatch = function(a) { var ww = shh.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { shh.killWatch(w); }; ret.changed = function(f) { shh.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(shh.watchMessages(this.w)) }; return ret; }"); \
frame->evaluateJavaScript("shh.watch = function(a) { return shh.makeWatch(JSON.stringify(a)) }"); \
}
template <unsigned N> inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>> toInt(QString const& _s)

2
libwhisper/Message.h

@ -40,7 +40,7 @@ struct Message
{
unsigned expiry = 0;
unsigned ttl = 0;
bytes topic;
bytes topic; // TODO: change to h256
bytes payload;
Message() {}

9
third/MainWin.cpp

@ -106,11 +106,13 @@ Main::Main(QWidget *parent) :
{
// NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
m_ethereum = new QEthereum(this, ethereum(), owned());
m_whisper = new QWhisper(this, whisper());
QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
auto qeth = m_ethereum;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, this));
auto qshh = m_whisper;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, qshh, this));
});
connect(ui->webView, &QWebView::loadFinished, [=]()
@ -153,6 +155,11 @@ eth::Client* Main::ethereum() const
return m_web3->ethereum();
}
std::shared_ptr<dev::shh::WhisperHost> Main::whisper() const
{
return m_web3->whisper();
}
void Main::onKeysChanged()
{
installBalancesWatch();

8
third/MainWin.h

@ -41,7 +41,11 @@ namespace eth {
class Client;
class State;
class MessageFilter;
}}
}
namespace shh {
class WhisperHost;
}
}
class QQuickView;
@ -55,6 +59,7 @@ public:
dev::WebThreeDirect* web3() const { return m_web3.get(); }
dev::eth::Client* ethereum() const;
std::shared_ptr<dev::shh::WhisperHost> whisper() const;
QList<dev::KeyPair> const& owned() const { return m_myKeys; }
@ -128,4 +133,5 @@ private:
QNetworkAccessManager m_webCtrl;
QEthereum* m_ethereum = nullptr;
QWhisper* m_whisper = nullptr;
};

Loading…
Cancel
Save