wallet: better masterkey handling for timeouts.

This commit is contained in:
Christopher Jeffrey 2016-10-25 11:27:47 -07:00
parent bf6d992855
commit 6e5bb6eef7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 45 additions and 10 deletions

View File

@ -40,7 +40,7 @@ function MasterKey(options) {
this.aesKey = null; this.aesKey = null;
this.timer = null; this.timer = null;
this.until = 0; this.until = 0;
this._destroy = this.destroy.bind(this); this._onTimeout = this.lock.bind(this);
this.locker = new Locker(this); this.locker = new Locker(this);
if (options) if (options)
@ -170,8 +170,13 @@ MasterKey.prototype.unlock = co(function* _unlock(passphrase, timeout) {
MasterKey.prototype._unlock = co(function* _unlock(passphrase, timeout) { MasterKey.prototype._unlock = co(function* _unlock(passphrase, timeout) {
var data, key; var data, key;
if (this.key) if (this.key) {
if (this.encrypted) {
assert(this.timer != null);
this.start(timeout);
}
return this.key; return this.key;
}
if (!passphrase) if (!passphrase)
throw new Error('No passphrase.'); throw new Error('No passphrase.');
@ -206,7 +211,7 @@ MasterKey.prototype.start = function start(timeout) {
return; return;
this.until = utils.now() + timeout; 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 * Destroy the key by zeroing the
* privateKey and chainCode. Stop * privateKey and chainCode. Stop
* the timer if there is one. * 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) { if (!this.encrypted) {
assert(this.timer == null); assert(this.timer == null);
assert(this.key); assert(this.key);
@ -303,10 +324,10 @@ MasterKey.prototype.lock = function lock() {
* Destroy the key permanently. * Destroy the key permanently.
*/ */
MasterKey.prototype.destroy = function destroy() { MasterKey.prototype.destroy = co(function* destroy() {
this.lock(); yield this.lock();
this.locker.destroy(); this.locker.destroy();
}; });
/** /**
* Decrypt the key permanently. * Decrypt the key permanently.
@ -341,7 +362,7 @@ MasterKey.prototype._decrypt = co(function* decrypt(passphrase) {
if (!passphrase) if (!passphrase)
return; return;
this.lock(); this._lock();
key = yield this.derive(passphrase); key = yield this.derive(passphrase);
data = crypto.decipher(this.ciphertext, key, this.iv); data = crypto.decipher(this.ciphertext, key, this.iv);

View File

@ -236,7 +236,7 @@ Wallet.prototype.destroy = co(function* destroy() {
var unlock2 = yield this.fundLock.lock(); var unlock2 = yield this.fundLock.lock();
try { try {
this.db.unregister(this); this.db.unregister(this);
this.master.destroy(); yield this.master.destroy();
this.readLock.destroy(); this.readLock.destroy();
this.writeLock.destroy(); this.writeLock.destroy();
this.fundLock.destroy(); this.fundLock.destroy();
@ -587,7 +587,7 @@ Wallet.prototype.lock = co(function* lock() {
var unlock1 = yield this.writeLock.lock(); var unlock1 = yield this.writeLock.lock();
var unlock2 = yield this.fundLock.lock(); var unlock2 = yield this.fundLock.lock();
try { try {
this.master.lock(); yield this.master.lock();
} finally { } finally {
unlock2(); unlock2();
unlock1(); unlock1();

View File

@ -923,6 +923,20 @@ describe('Wallet', function() {
yield w.fund(t2, { rate: 10000, round: true, account: 'foo' }); 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* () { it('should fill tx with inputs when encrypted', cob(function* () {
var w = yield walletdb.create({ passphrase: 'foo' }); var w = yield walletdb.create({ passphrase: 'foo' });
var t1, t2, err; var t1, t2, err;