wallet: better masterkey handling for timeouts.
This commit is contained in:
parent
bf6d992855
commit
6e5bb6eef7
@ -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);
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user