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.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);

View File

@ -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();

View File

@ -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;