mirror of https://github.com/moparisthebest/mail
refactor to generate and store random salt for PBKDF2
This commit is contained in:
parent
cb0e974fea
commit
1eb14d1e11
|
@ -5,6 +5,7 @@ define(function(require) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var $ = require('jquery'),
|
var $ = require('jquery'),
|
||||||
|
util = require('cryptoLib/util'),
|
||||||
ImapClient = require('imap-client'),
|
ImapClient = require('imap-client'),
|
||||||
SmtpClient = require('smtp-client'),
|
SmtpClient = require('smtp-client'),
|
||||||
EmailDAO = require('js/dao/email-dao'),
|
EmailDAO = require('js/dao/email-dao'),
|
||||||
|
@ -18,7 +19,7 @@ define(function(require) {
|
||||||
var self = {};
|
var self = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the application by loading the view templates
|
* Start the application
|
||||||
*/
|
*/
|
||||||
self.start = function(callback) {
|
self.start = function(callback) {
|
||||||
// are we running in native app or in browser?
|
// are we running in native app or in browser?
|
||||||
|
@ -32,7 +33,9 @@ define(function(require) {
|
||||||
|
|
||||||
function onDeviceReady() {
|
function onDeviceReady() {
|
||||||
console.log('Starting app.');
|
console.log('Starting app.');
|
||||||
callback();
|
// init app config storage
|
||||||
|
self._appConfigStore = new DeviceStorageDAO();
|
||||||
|
self._appConfigStore.init('app-config', callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,10 +65,17 @@ define(function(require) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// login using the received email address
|
self.getSalt(function(err, salt) {
|
||||||
self.login(emailAddress, password, token, function(err) {
|
if (err || !salt) {
|
||||||
// send email address to sandbox
|
callback({
|
||||||
callback(err, emailAddress);
|
errMsg: 'Error gettin salt on login!',
|
||||||
|
err: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// login using the received email address
|
||||||
|
self.login(emailAddress, password, salt, token, callback);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -76,25 +86,21 @@ define(function(require) {
|
||||||
* Lookup the user's email address. Check local cache if available, otherwise query google's token info api to learn the user's email address
|
* Lookup the user's email address. Check local cache if available, otherwise query google's token info api to learn the user's email address
|
||||||
*/
|
*/
|
||||||
self.queryEmailAddress = function(token, callback) {
|
self.queryEmailAddress = function(token, callback) {
|
||||||
var deviceStorage, key = 'emailaddress';
|
var itemKey = 'emailaddress';
|
||||||
|
|
||||||
// check device storage
|
self._appConfigStore.listItems(itemKey, 0, null, function(err, cachedItems) {
|
||||||
deviceStorage = new DeviceStorageDAO();
|
if (err) {
|
||||||
deviceStorage.init('app-config', function() {
|
callback(err);
|
||||||
deviceStorage.listItems(key, 0, null, function(err, cachedItems) {
|
return;
|
||||||
if (err) {
|
}
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do roundtrip to google api if no email address is cached yet
|
// do roundtrip to google api if no email address is cached yet
|
||||||
if (!cachedItems || cachedItems.length < 1) {
|
if (!cachedItems || cachedItems.length < 1) {
|
||||||
queryGoogleApi();
|
queryGoogleApi();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(null, cachedItems[0]);
|
callback(null, cachedItems[0]);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function queryGoogleApi() {
|
function queryGoogleApi() {
|
||||||
|
@ -112,7 +118,7 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache the email address on the device
|
// cache the email address on the device
|
||||||
deviceStorage.storeList([info.email], key, function(err) {
|
self._appConfigStore.storeList([info.email], itemKey, function(err) {
|
||||||
callback(err, info.email);
|
callback(err, info.email);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -126,12 +132,45 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a random salt from the app storage or generate a new one
|
||||||
|
*/
|
||||||
|
self.getSalt = function(callback) {
|
||||||
|
var itemKey = 'salt',
|
||||||
|
salt;
|
||||||
|
|
||||||
|
self._appConfigStore.listItems(itemKey, 0, null, function(err, cachedItems) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate random salt if non exists
|
||||||
|
if (!cachedItems || cachedItems.length < 1) {
|
||||||
|
salt = util.random(config.symKeySize);
|
||||||
|
|
||||||
|
// store the salt locally
|
||||||
|
self._appConfigStore.storeList([salt], itemKey, function(err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, salt);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, cachedItems[0]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instanciate the mail email data access object and its dependencies. Login to imap on init.
|
* Instanciate the mail email data access object and its dependencies. Login to imap on init.
|
||||||
*/
|
*/
|
||||||
self.login = function(userId, password, token, callback) {
|
self.login = function(userId, password, salt, token, callback) {
|
||||||
var auth, imapOptions, smtpOptions,
|
var auth, imapOptions, smtpOptions,
|
||||||
keychain, imapClient, smtpClient, crypto, deviceStorage;
|
keychain, imapClient, smtpClient, crypto, userStorage;
|
||||||
|
|
||||||
// create mail credentials objects for imap/smtp
|
// create mail credentials objects for imap/smtp
|
||||||
auth = {
|
auth = {
|
||||||
|
@ -159,15 +198,16 @@ define(function(require) {
|
||||||
imapClient = new ImapClient(imapOptions);
|
imapClient = new ImapClient(imapOptions);
|
||||||
smtpClient = new SmtpClient(smtpOptions);
|
smtpClient = new SmtpClient(smtpOptions);
|
||||||
crypto = new Crypto();
|
crypto = new Crypto();
|
||||||
deviceStorage = new DeviceStorageDAO();
|
userStorage = new DeviceStorageDAO();
|
||||||
self._emailDao = new EmailDAO(keychain, imapClient, smtpClient, crypto, deviceStorage);
|
self._emailDao = new EmailDAO(keychain, imapClient, smtpClient, crypto, userStorage);
|
||||||
|
|
||||||
// init email dao
|
// init email dao
|
||||||
var account = {
|
var account = {
|
||||||
emailAddress: userId,
|
emailAddress: userId,
|
||||||
symKeySize: config.symKeySize,
|
symKeySize: config.symKeySize,
|
||||||
symIvSize: config.symIvSize,
|
symIvSize: config.symIvSize,
|
||||||
asymKeySize: config.asymKeySize
|
asymKeySize: config.asymKeySize,
|
||||||
|
salt: salt
|
||||||
};
|
};
|
||||||
self._emailDao.init(account, password, callback);
|
self._emailDao.init(account, password, callback);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,23 +4,37 @@ define(function(require) {
|
||||||
var appController = require('js/app-controller');
|
var appController = require('js/app-controller');
|
||||||
|
|
||||||
var LoginCtrl = function($scope, $location) {
|
var LoginCtrl = function($scope, $location) {
|
||||||
var nextPath = '/desktop';
|
|
||||||
|
|
||||||
if (window.chrome && chrome.identity) {
|
// start the main app controller
|
||||||
// start the main app controller
|
appController.start(function(err) {
|
||||||
appController.fetchOAuthToken('passphrase', function(err) {
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.chrome && chrome.identity) {
|
||||||
|
login('passphrase', onLogin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onLogin();
|
||||||
|
});
|
||||||
|
|
||||||
|
function login(password, callback) {
|
||||||
|
appController.fetchOAuthToken(password, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$location.path(nextPath);
|
callback();
|
||||||
$scope.$apply();
|
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$location.path(nextPath);
|
function onLogin() {
|
||||||
|
$location.path('/desktop');
|
||||||
|
$scope.$apply();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return LoginCtrl;
|
return LoginCtrl;
|
||||||
|
|
|
@ -15,15 +15,29 @@ define(function(require) {
|
||||||
var WriteCtrl = function($scope) {
|
var WriteCtrl = function($scope) {
|
||||||
$scope.signature = str.signature;
|
$scope.signature = str.signature;
|
||||||
|
|
||||||
if (window.chrome && chrome.identity) {
|
// start the main app controller
|
||||||
// start the main app controller
|
appController.start(function(err) {
|
||||||
appController.fetchOAuthToken('passphrase', function(err) {
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.chrome && chrome.identity) {
|
||||||
|
login('passphrase', function() {
|
||||||
|
emailDao = appController._emailDao;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function login(password, callback) {
|
||||||
|
appController.fetchOAuthToken(password, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emailDao = appController._emailDao;
|
callback();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ define(function(require) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// valdiate input
|
// valdiate input
|
||||||
if (!args.emailAddress || !args.keySize || !args.rsaKeySize) {
|
if (!args.emailAddress || !args.keySize || !args.rsaKeySize || typeof args.password !== 'string' || !args.salt) {
|
||||||
callback({
|
callback({
|
||||||
errMsg: 'Crypto init failed. Not all args set!'
|
errMsg: 'Crypto init failed. Not all args set!'
|
||||||
});
|
});
|
||||||
|
@ -41,7 +41,7 @@ define(function(require) {
|
||||||
self.rsaKeySize = args.rsaKeySize;
|
self.rsaKeySize = args.rsaKeySize;
|
||||||
|
|
||||||
// derive PBKDF2 from password in web worker thread
|
// derive PBKDF2 from password in web worker thread
|
||||||
self.deriveKey(args.password, self.keySize, function(err, derivedKey) {
|
self.deriveKey(args.password, args.salt, self.keySize, function(err, derivedKey) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -124,16 +124,17 @@ define(function(require) {
|
||||||
/**
|
/**
|
||||||
* Do PBKDF2 key derivation in a WebWorker thread
|
* Do PBKDF2 key derivation in a WebWorker thread
|
||||||
*/
|
*/
|
||||||
Crypto.prototype.deriveKey = function(password, keySize, callback) {
|
Crypto.prototype.deriveKey = function(password, salt, keySize, callback) {
|
||||||
startWorker({
|
startWorker({
|
||||||
script: PBKDF2_WORKER,
|
script: PBKDF2_WORKER,
|
||||||
args: {
|
args: {
|
||||||
password: password,
|
password: password,
|
||||||
|
salt: salt,
|
||||||
keySize: keySize
|
keySize: keySize
|
||||||
},
|
},
|
||||||
callback: callback,
|
callback: callback,
|
||||||
noWorker: function() {
|
noWorker: function() {
|
||||||
return pbkdf2.getKey(password, keySize);
|
return pbkdf2.getKey(password, salt, keySize);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// import web worker dependencies
|
// import web worker dependencies
|
||||||
importScripts('../../lib/require.js');
|
importScripts('../../lib/require.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In the web worker thread context, 'this' and 'self' can be used as a global
|
* In the web worker thread context, 'this' and 'self' can be used as a global
|
||||||
* variable namespace similar to the 'window' object in the main thread
|
* variable namespace similar to the 'window' object in the main thread
|
||||||
*/
|
*/
|
||||||
self.onmessage = function(e) {
|
self.onmessage = function(e) {
|
||||||
// fetch dependencies via require.js
|
// fetch dependencies via require.js
|
||||||
require(['../../require-config'], function() {
|
require(['../../require-config'], function() {
|
||||||
require.config({
|
require.config({
|
||||||
baseUrl: '../../lib'
|
baseUrl: '../../lib'
|
||||||
});
|
});
|
||||||
|
|
||||||
require(['js/crypto/pbkdf2'], function(pbkdf2) {
|
require(['js/crypto/pbkdf2'], function(pbkdf2) {
|
||||||
|
|
||||||
var i = e.data,
|
var i = e.data,
|
||||||
key = null;
|
key = null;
|
||||||
|
|
||||||
if (i.password && i.keySize) {
|
if (i.password && i.salt && i.keySize) {
|
||||||
// start deriving key
|
// start deriving key
|
||||||
key = pbkdf2.getKey(i.password, i.keySize);
|
key = pbkdf2.getKey(i.password, i.salt, i.keySize);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw 'Not all arguments for web worker crypto are defined!';
|
throw 'Not all arguments for web worker crypto are defined!';
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass output back to main thread
|
// pass output back to main thread
|
||||||
self.postMessage(key);
|
self.postMessage(key);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
}());
|
}());
|
|
@ -2,23 +2,23 @@
|
||||||
* A Wrapper for Forge's PBKDF2 function
|
* A Wrapper for Forge's PBKDF2 function
|
||||||
*/
|
*/
|
||||||
define(['node-forge'], function(forge) {
|
define(['node-forge'], function(forge) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var self = {};
|
var self = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PBKDF2-HMAC-SHA1 key derivation with a constant salt and 1000 iterations
|
* PBKDF2-HMAC-SHA1 key derivation with a constant salt and 1000 iterations
|
||||||
* @param password [String] The password in UTF8
|
* @param password [String] The password in UTF8
|
||||||
* @param keySize [Number] The key size in bits
|
* @param salt [String] The base64 encoded salt
|
||||||
* @return [String] The base64 encoded key
|
* @param keySize [Number] The key size in bits
|
||||||
*/
|
* @return [String] The base64 encoded key
|
||||||
self.getKey = function(password, keySize) {
|
*/
|
||||||
var salt = forge.util.decode64("vbhmLjC+Ub6MSbhS6/CkOwxB25wvwRkSLP2DzDtYb+4=");
|
self.getKey = function(password, salt, keySize) {
|
||||||
var key = forge.pkcs5.pbkdf2(password, salt, 1000, keySize / 8);
|
var key = forge.pkcs5.pbkdf2(password, forge.util.decode64(salt), 1000, keySize / 8);
|
||||||
var keyBase64 = forge.util.encode64(key);
|
var keyBase64 = forge.util.encode64(key);
|
||||||
|
|
||||||
return keyBase64;
|
return keyBase64;
|
||||||
};
|
};
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
|
@ -58,6 +58,7 @@ define(function(require) {
|
||||||
self._crypto.init({
|
self._crypto.init({
|
||||||
emailAddress: emailAddress,
|
emailAddress: emailAddress,
|
||||||
password: password,
|
password: password,
|
||||||
|
salt: self._account.salt,
|
||||||
keySize: self._account.symKeySize,
|
keySize: self._account.symKeySize,
|
||||||
rsaKeySize: self._account.asymKeySize,
|
rsaKeySize: self._account.asymKeySize,
|
||||||
storedKeypair: storedKeypair
|
storedKeypair: storedKeypair
|
||||||
|
|
|
@ -21,15 +21,20 @@ define(function(require) {
|
||||||
afterEach(function() {});
|
afterEach(function() {});
|
||||||
|
|
||||||
describe('login', function() {
|
describe('login', function() {
|
||||||
it('should work', function(done) {
|
this.timeout(20000);
|
||||||
appController.fetchOAuthToken(test.passphrase, function(err, userId) {
|
|
||||||
expect(err).to.not.exist;
|
|
||||||
expect(userId).to.exist;
|
|
||||||
emailDao = appController._emailDao;
|
|
||||||
|
|
||||||
emailDao.imapLogin(function(err) {
|
it('should work', function(done) {
|
||||||
|
appController.start(function(err) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
|
||||||
|
appController.fetchOAuthToken(test.passphrase, function(err) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
done();
|
emailDao = appController._emailDao;
|
||||||
|
|
||||||
|
emailDao.imapLogin(function(err) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,7 +15,7 @@ define(function(require) {
|
||||||
describe('App Controller unit tests', function() {
|
describe('App Controller unit tests', function() {
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
sinon.stub(controller, 'login', function(userId, password, token, callback) {
|
sinon.stub(controller, 'login', function(userId, password, salt, token, callback) {
|
||||||
controller._emailDao = sinon.createStubInstance(EmailDAO);
|
controller._emailDao = sinon.createStubInstance(EmailDAO);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
|
@ -50,29 +50,31 @@ define(function(require) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('login', function() {
|
describe('fetchOAuthToken', function() {
|
||||||
it('should work the first time', function(done) {
|
beforeEach(function() {
|
||||||
// clear db
|
controller._appConfigStore = sinon.createStubInstance(DeviceStorageDAO);
|
||||||
var deviceStorage = new DeviceStorageDAO();
|
});
|
||||||
deviceStorage.init('app-config', function() {
|
|
||||||
deviceStorage.clear(function() {
|
|
||||||
|
|
||||||
// do test with fresh db
|
it('should work the first time', function(done) {
|
||||||
controller.fetchOAuthToken(appControllerTest.passphrase, function(err, userId) {
|
controller._appConfigStore.listItems.yields(null, []);
|
||||||
expect(err).to.not.exist;
|
controller._appConfigStore.storeList.yields();
|
||||||
expect(userId).to.equal(appControllerTest.user);
|
|
||||||
expect(window.chrome.identity.getAuthToken.calledOnce).to.be.true;
|
controller.fetchOAuthToken(appControllerTest.passphrase, function(err) {
|
||||||
expect($.ajax.calledOnce).to.be.true;
|
expect(err).to.not.exist;
|
||||||
done();
|
expect(controller._appConfigStore.listItems.calledTwice).to.be.true;
|
||||||
});
|
expect(controller._appConfigStore.storeList.calledTwice).to.be.true;
|
||||||
});
|
expect(window.chrome.identity.getAuthToken.calledOnce).to.be.true;
|
||||||
|
expect($.ajax.calledOnce).to.be.true;
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work when the email address is cached', function(done) {
|
it('should work when the email address is cached', function(done) {
|
||||||
controller.fetchOAuthToken(appControllerTest.passphrase, function(err, userId) {
|
controller._appConfigStore.listItems.yields(null, ['asdf']);
|
||||||
|
|
||||||
|
controller.fetchOAuthToken(appControllerTest.passphrase, function(err) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(userId).to.equal(appControllerTest.user);
|
expect(controller._appConfigStore.listItems.calledTwice).to.be.true;
|
||||||
expect(window.chrome.identity.getAuthToken.calledOnce).to.be.true;
|
expect(window.chrome.identity.getAuthToken.calledOnce).to.be.true;
|
||||||
expect($.ajax.called).to.be.false;
|
expect($.ajax.called).to.be.false;
|
||||||
done();
|
done();
|
||||||
|
|
|
@ -8,7 +8,8 @@ define(['js/crypto/crypto', 'cryptoLib/util', 'test/test-data'], function(Crypto
|
||||||
password: 'Password',
|
password: 'Password',
|
||||||
keySize: 128,
|
keySize: 128,
|
||||||
ivSize: 128,
|
ivSize: 128,
|
||||||
rsaKeySize: 1024
|
rsaKeySize: 1024,
|
||||||
|
salt: util.random(128)
|
||||||
};
|
};
|
||||||
|
|
||||||
var crypto;
|
var crypto;
|
||||||
|
@ -22,6 +23,7 @@ define(['js/crypto/crypto', 'cryptoLib/util', 'test/test-data'], function(Crypto
|
||||||
crypto.init({
|
crypto.init({
|
||||||
emailAddress: cryptoTest.user,
|
emailAddress: cryptoTest.user,
|
||||||
password: cryptoTest.password,
|
password: cryptoTest.password,
|
||||||
|
salt: cryptoTest.salt,
|
||||||
keySize: cryptoTest.keySize,
|
keySize: cryptoTest.keySize,
|
||||||
rsaKeySize: cryptoTest.rsaKeySize
|
rsaKeySize: cryptoTest.rsaKeySize
|
||||||
}, function(err, generatedKeypair) {
|
}, function(err, generatedKeypair) {
|
||||||
|
@ -40,6 +42,7 @@ define(['js/crypto/crypto', 'cryptoLib/util', 'test/test-data'], function(Crypto
|
||||||
crypto.init({
|
crypto.init({
|
||||||
emailAddress: cryptoTest.user,
|
emailAddress: cryptoTest.user,
|
||||||
password: cryptoTest.password,
|
password: cryptoTest.password,
|
||||||
|
salt: cryptoTest.salt,
|
||||||
keySize: cryptoTest.keySize,
|
keySize: cryptoTest.keySize,
|
||||||
rsaKeySize: cryptoTest.rsaKeySize,
|
rsaKeySize: cryptoTest.rsaKeySize,
|
||||||
storedKeypair: cryptoTest.generatedKeypair
|
storedKeypair: cryptoTest.generatedKeypair
|
||||||
|
@ -51,7 +54,7 @@ define(['js/crypto/crypto', 'cryptoLib/util', 'test/test-data'], function(Crypto
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("PBKDF2 (Async/Worker)", 2, function() {
|
asyncTest("PBKDF2 (Async/Worker)", 2, function() {
|
||||||
crypto.deriveKey(cryptoTest.password, cryptoTest.keySize, function(err, key) {
|
crypto.deriveKey(cryptoTest.password, cryptoTest.salt, cryptoTest.keySize, function(err, key) {
|
||||||
ok(!err);
|
ok(!err);
|
||||||
equal(util.base642Str(key).length * 8, cryptoTest.keySize, 'Keysize ' + cryptoTest.keySize);
|
equal(util.base642Str(key).length * 8, cryptoTest.keySize, 'Keysize ' + cryptoTest.keySize);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/devicestorag
|
||||||
crypto.init({
|
crypto.init({
|
||||||
emailAddress: devicestorageTest.user,
|
emailAddress: devicestorageTest.user,
|
||||||
password: devicestorageTest.password,
|
password: devicestorageTest.password,
|
||||||
|
salt: util.random(devicestorageTest.keySize),
|
||||||
keySize: devicestorageTest.keySize,
|
keySize: devicestorageTest.keySize,
|
||||||
rsaKeySize: devicestorageTest.rsaKeySize
|
rsaKeySize: devicestorageTest.rsaKeySize
|
||||||
}, function(err, generatedKeypair) {
|
}, function(err, generatedKeypair) {
|
||||||
|
|
Loading…
Reference in New Issue