fixes #importWallet
This commit is contained in:
parent
25ba346489
commit
8183a1d3c7
3 changed files with 71 additions and 22 deletions
|
|
@ -5,6 +5,7 @@ var _ = require('lodash');
|
||||||
var bitcore = require('bitcore');
|
var bitcore = require('bitcore');
|
||||||
var log = require('../log');
|
var log = require('../log');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
var cryptoUtil = require('../util/crypto');
|
||||||
|
|
||||||
var version = require('../../version').version;
|
var version = require('../../version').version;
|
||||||
var TxProposals = require('./TxProposals');
|
var TxProposals = require('./TxProposals');
|
||||||
|
|
@ -252,6 +253,8 @@ Identity.prototype.exportWithWalletInfo = function() {
|
||||||
*/
|
*/
|
||||||
Identity.prototype.store = function(opts, cb) {
|
Identity.prototype.store = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
opts = opts || {};
|
||||||
|
|
||||||
self.storage.setItem(this.getId(), this.toObj(), function(err) {
|
self.storage.setItem(this.getId(), this.toObj(), function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
|
@ -279,24 +282,34 @@ Identity.prototype.close = function(cb) {
|
||||||
* @desc Imports a wallet from an encrypted base64 object
|
* @desc Imports a wallet from an encrypted base64 object
|
||||||
* @param {string} base64 - the base64 encoded object
|
* @param {string} base64 - the base64 encoded object
|
||||||
* @param {string} passphrase - passphrase to decrypt it
|
* @param {string} passphrase - passphrase to decrypt it
|
||||||
* @param {string[]} skipFields - fields to ignore when importing
|
* @param {string[]} opts.skipFields - fields to ignore when importing
|
||||||
|
* @param {string[]} opts.salt -
|
||||||
|
* @param {string[]} opts.iterations -
|
||||||
|
* @param {string[]} opts.importFunction - for stubbing
|
||||||
* @return {Wallet}
|
* @return {Wallet}
|
||||||
*/
|
*/
|
||||||
Identity.prototype.importWallet = function(base64, password, skipFields, cb) {
|
Identity.prototype.importWallet = function(base64, password, opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
preconditions.checkArgument(password);
|
preconditions.checkArgument(password);
|
||||||
preconditions.checkArgument(cb);
|
preconditions.checkArgument(cb);
|
||||||
|
var importFunction = opts.importWallet || Wallet.fromUntrustedObj;
|
||||||
var obj = this.storage.decrypt(base64, password);
|
var crypto = opts.cryptoUtil || cryptoUtil;
|
||||||
|
|
||||||
var readOpts = {
|
var readOpts = {
|
||||||
networkOpts: this.networkOpts,
|
networkOpts: this.networkOpts,
|
||||||
blockchainOpts: this.blockchainOpts,
|
blockchainOpts: this.blockchainOpts,
|
||||||
skipFields: skipFields
|
skipFields: opts.skipFields,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!obj) return cb(null);
|
// TODO set iter and salt using config.js
|
||||||
var w = Identity._walletFromObj(obj, readOpts);
|
var key = crypto.kdf(password);
|
||||||
|
var obj = crypto.decrypt(key, base64);
|
||||||
|
if (!obj) return cb(new Error('Could not decrypt'));
|
||||||
|
|
||||||
|
|
||||||
|
var w = importFunction(obj, readOpts);
|
||||||
|
if (!w) return cb(new Error('Could not decrypt'));
|
||||||
|
|
||||||
this._checkVersion(w.version);
|
this._checkVersion(w.version);
|
||||||
this.addWallet(w, function(err) {
|
this.addWallet(w, function(err) {
|
||||||
if (err) return cb(err, null);
|
if (err) return cb(err, null);
|
||||||
|
|
@ -338,7 +351,7 @@ Identity.importFromFullJson = function(str, password, opts, cb) {
|
||||||
|
|
||||||
json.wallets = json.wallets || {};
|
json.wallets = json.wallets || {};
|
||||||
async.map(json.wallets, function(walletData, callback) {
|
async.map(json.wallets, function(walletData, callback) {
|
||||||
iden.importWallet(wstr, password, opts.skipFields, function(err, w) {
|
iden.importWallet(wstr, password, opts, function(err, w) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
log.debug('Wallet ' + w.getId() + ' imported');
|
log.debug('Wallet ' + w.getId() + ' imported');
|
||||||
callback();
|
callback();
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,25 @@ var sjcl = require('../../lib/sjcl');
|
||||||
var log = require('../log.js');
|
var log = require('../log.js');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
var SALT = 'copay random string NWRlNmExMTE4NzIzYzYyYWMwODU1MTdkN';
|
var defaultSalt = 'mjuBtGybi/4=';
|
||||||
var SEPARATOR = '&';
|
var defaultIterations = 100;
|
||||||
var defaultOptions = {
|
|
||||||
adata: '',
|
// var SEPARATOR = '&';
|
||||||
cipher: 'aes',
|
// var defaultOptions = {
|
||||||
ks: 128,
|
// adata: '',
|
||||||
iter: 2000,
|
// cipher: 'aes',
|
||||||
mode: 'ccm',
|
// ks: 128,
|
||||||
ts: 64
|
// iter: 2000,
|
||||||
};
|
// mode: 'ccm',
|
||||||
|
// ts: 64
|
||||||
|
// };
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
kdf: function(value1, value2) {
|
kdf: function(value1, value2, salt, iterations) {
|
||||||
return sjcl.codec.base64.fromBits(sjcl.misc.pbkdf2(value1 + value2, SALT));
|
iterations = iterations || defaultIterations;
|
||||||
|
salt = salt || defaultSalt;
|
||||||
|
return sjcl.codec.base64.fromBits(sjcl.misc.pbkdf2(value1 + (value2 || ''), salt, iterations));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -35,10 +39,10 @@ module.exports = {
|
||||||
/**
|
/**
|
||||||
* Decrypts symmetrically using a passphrase
|
* Decrypts symmetrically using a passphrase
|
||||||
*/
|
*/
|
||||||
decrypt: function(key, cypher) {
|
decrypt: function(key, cyphertext) {
|
||||||
var output = {};
|
var output = {};
|
||||||
try {
|
try {
|
||||||
return sjcl.decrypt(key, cypher);
|
return sjcl.decrypt(key, cyphertext);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error('Decryption failed due to error: ' + e.message);
|
log.error('Decryption failed due to error: ' + e.message);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,38 @@ describe('Identity model', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#importWallet', function() {
|
||||||
|
it('should import a wallet, call the right encryption functions',function(done) {
|
||||||
|
var args = createIdentity();
|
||||||
|
args.storage.getItem.onFirstCall().callsArgWith(1, null, '{"wallet": "fakeData"}');
|
||||||
|
var backup = Wallet.fromUntrustedObj;
|
||||||
|
args.params.noWallets = true;
|
||||||
|
sinon.stub().returns(args.wallet);
|
||||||
|
|
||||||
|
var fakeCrypto = {
|
||||||
|
kdf: sinon.stub().returns('passphrase'),
|
||||||
|
decrypt: sinon.stub().returns({walletId:123}),
|
||||||
|
};
|
||||||
|
|
||||||
|
var opts = {
|
||||||
|
importWallet: sinon.stub().returns(getNewWallet()),
|
||||||
|
cryptoUtil: fakeCrypto,
|
||||||
|
};
|
||||||
|
|
||||||
|
Identity.create(args.params, function(err, iden) {
|
||||||
|
iden.importWallet(123,'password', opts, function(err){
|
||||||
|
should.not.exist(err);
|
||||||
|
fakeCrypto.kdf.getCall(0).args[0].should.equal('password');
|
||||||
|
fakeCrypto.decrypt.getCall(0).args[0].should.equal('passphrase');
|
||||||
|
fakeCrypto.decrypt.getCall(0).args[1].should.equal(123);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe('#export', function() {
|
describe('#export', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue