From 6e5bb6eef7aec326f70b5b6910f1f71513e44e62 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 25 Oct 2016 11:27:47 -0700 Subject: [PATCH] wallet: better masterkey handling for timeouts. --- lib/wallet/masterkey.js | 37 +++++++++++++++++++++++++++++-------- lib/wallet/wallet.js | 4 ++-- test/wallet-test.js | 14 ++++++++++++++ 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/lib/wallet/masterkey.js b/lib/wallet/masterkey.js index e9a13d74..e308f63b 100644 --- a/lib/wallet/masterkey.js +++ b/lib/wallet/masterkey.js @@ -40,7 +40,7 @@ function MasterKey(options) { this.aesKey = null; this.timer = null; this.until = 0; - this._destroy = this.destroy.bind(this); + this._onTimeout = this.lock.bind(this); this.locker = new Locker(this); if (options) @@ -170,8 +170,13 @@ MasterKey.prototype.unlock = co(function* _unlock(passphrase, timeout) { MasterKey.prototype._unlock = co(function* _unlock(passphrase, timeout) { var data, key; - if (this.key) + if (this.key) { + if (this.encrypted) { + assert(this.timer != null); + this.start(timeout); + } return this.key; + } if (!passphrase) throw new Error('No passphrase.'); @@ -206,7 +211,7 @@ MasterKey.prototype.start = function start(timeout) { return; this.until = utils.now() + timeout; - this.timer = setTimeout(this._destroy, timeout * 1000); + this.timer = setTimeout(this._onTimeout, timeout * 1000); }; /** @@ -277,9 +282,25 @@ MasterKey.prototype.decipher = function decipher(data, iv) { * Destroy the key by zeroing the * privateKey and chainCode. Stop * the timer if there is one. + * @returns {Promise} */ -MasterKey.prototype.lock = function lock() { +MasterKey.prototype.lock = co(function* _lock() { + var unlock = yield this.locker.lock(); + try { + return yield this._lock(); + } finally { + unlock(); + } +}); + +/** + * Destroy the key by zeroing the + * privateKey and chainCode. Stop + * the timer if there is one. + */ + +MasterKey.prototype._lock = function lock() { if (!this.encrypted) { assert(this.timer == null); assert(this.key); @@ -303,10 +324,10 @@ MasterKey.prototype.lock = function lock() { * Destroy the key permanently. */ -MasterKey.prototype.destroy = function destroy() { - this.lock(); +MasterKey.prototype.destroy = co(function* destroy() { + yield this.lock(); this.locker.destroy(); -}; +}); /** * Decrypt the key permanently. @@ -341,7 +362,7 @@ MasterKey.prototype._decrypt = co(function* decrypt(passphrase) { if (!passphrase) return; - this.lock(); + this._lock(); key = yield this.derive(passphrase); data = crypto.decipher(this.ciphertext, key, this.iv); diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 6c618722..ee5452e6 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -236,7 +236,7 @@ Wallet.prototype.destroy = co(function* destroy() { var unlock2 = yield this.fundLock.lock(); try { this.db.unregister(this); - this.master.destroy(); + yield this.master.destroy(); this.readLock.destroy(); this.writeLock.destroy(); this.fundLock.destroy(); @@ -587,7 +587,7 @@ Wallet.prototype.lock = co(function* lock() { var unlock1 = yield this.writeLock.lock(); var unlock2 = yield this.fundLock.lock(); try { - this.master.lock(); + yield this.master.lock(); } finally { unlock2(); unlock1(); diff --git a/test/wallet-test.js b/test/wallet-test.js index 6633ac97..db86e57c 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -923,6 +923,20 @@ describe('Wallet', function() { yield w.fund(t2, { rate: 10000, round: true, account: 'foo' }); })); + it('should create two accounts multiple encryption', cob(function* () { + var w = yield walletdb.create({ id: 'foobar', passphrase: 'foo' }); + w.destroy(); + var w = yield walletdb.get('foobar'); + var account = yield w.createAccount({ name: 'foo1' }); + assert(account); + yield w.lock(); + account = yield w.createAccount({ name: 'foo2' }, 'foo'); + assert(account); + yield w.lock(); + account = yield w.createAccount({ name: 'foo3' }, 'foo'); + assert(account); + })); + it('should fill tx with inputs when encrypted', cob(function* () { var w = yield walletdb.create({ passphrase: 'foo' }); var t1, t2, err;