mirror of
https://github.com/moparisthebest/mail
synced 2024-12-21 23:08:50 -05:00
user keypair is now derived on email dao init and pub key pushed to the cloud
This commit is contained in:
parent
e943dfd304
commit
65e0a7d520
@ -6,6 +6,7 @@ app.crypto.Crypto = function(window, util) {
|
||||
'use strict';
|
||||
|
||||
var symmetricUserKey = null, // the user's secret key used to encrypt item-keys
|
||||
keyId = null, // the key ID linking the user's key set
|
||||
aes = new app.crypto.AesCCM(sjcl); // use authenticated AES-CCM mode by default
|
||||
|
||||
/**
|
||||
@ -31,16 +32,18 @@ app.crypto.Crypto = function(window, util) {
|
||||
symmetricUserKey = util.random(keySize);
|
||||
var iv = util.random(ivSize);
|
||||
var key = aes.encrypt(symmetricUserKey, pbkdf2, iv);
|
||||
keyStore.persist(storageId, {
|
||||
storedKey = {
|
||||
_id: util.UUID(),
|
||||
userId: emailAddress,
|
||||
encryptedKey: key,
|
||||
keyIV: iv
|
||||
});
|
||||
};
|
||||
keyStore.persist(storageId, storedKey);
|
||||
} else {
|
||||
// decrypt key
|
||||
symmetricUserKey = aes.decrypt(storedKey.encryptedKey, pbkdf2, storedKey.keyIV);
|
||||
}
|
||||
keyId = storedKey._id;
|
||||
|
||||
callback();
|
||||
});
|
||||
@ -78,10 +81,10 @@ app.crypto.Crypto = function(window, util) {
|
||||
/**
|
||||
* Derive an asymmetric keypait from the user's secret
|
||||
*/
|
||||
this.deriveKeyPair = function(naclCrypto, id) {
|
||||
this.deriveKeyPair = function(naclCrypto) {
|
||||
var keys = naclCrypto.generateKeypair(symmetricUserKey);
|
||||
if (id) {
|
||||
keys.id = id;
|
||||
if (keyId) {
|
||||
keys.id = keyId;
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
@ -2,9 +2,11 @@
|
||||
* A high-level Data-Access Api for handling Email synchronization
|
||||
* between the cloud service and the device's local storage
|
||||
*/
|
||||
app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
||||
app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, naclCrypto) {
|
||||
'use strict';
|
||||
|
||||
var keypair; // the user's keypair
|
||||
|
||||
/**
|
||||
* Inits all dependencies
|
||||
*/
|
||||
@ -14,7 +16,8 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
||||
// sync user's cloud key with local storage
|
||||
cloudstorage.getUserSecretKey(account.get('emailAddress'), function(err) {
|
||||
if (err) {
|
||||
console.log('Could not sync user key from server: ' + JSON.stringify(err));
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
// init crypto
|
||||
initCrypto();
|
||||
@ -28,7 +31,21 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
|
||||
|
||||
function initCrypto() {
|
||||
crypto.init(account.get('emailAddress'), password, account.get('symKeySize'), account.get('symIvSize'), function() {
|
||||
callback();
|
||||
initNaclCrypto();
|
||||
});
|
||||
}
|
||||
|
||||
function initNaclCrypto() {
|
||||
// derive keypair from user's secret key
|
||||
keypair = crypto.deriveKeyPair(naclCrypto);
|
||||
//publish public key to cloud service
|
||||
var pubkey = new app.model.PublicKey({
|
||||
_id: keypair.id,
|
||||
userId: account.get('emailAddress'),
|
||||
publicKey: keypair.boxPk
|
||||
});
|
||||
cloudstorage.putPublicKey(pubkey.toJSON(), function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -4,23 +4,18 @@ var cloudstoragedao_test = {
|
||||
user: 'test@atlasdev.onmicrosoft.com',
|
||||
password: 'Xoza76645',
|
||||
keySize: 128,
|
||||
ivSize: 104,
|
||||
privateKey: "Bv51afjeuH8CatKo75HOHQRT1B3amvF+DEwijka79nA=",
|
||||
publicKey: new app.model.PublicKey({
|
||||
_id: "da4bfa93-ba87-490e-877c-e4020a6f6729",
|
||||
userId: 'test@atlasdev.onmicrosoft.com',
|
||||
publicKey: "yHUhh3Pcbjmh2k367pSXfE8hDwPsAxQs0QETm9mfmz0="
|
||||
})
|
||||
ivSize: 104
|
||||
};
|
||||
|
||||
asyncTest("Init", 1, function() {
|
||||
// init dependencies
|
||||
var util = new app.crypto.Util(window, uuid);
|
||||
var jsonDao = new app.dao.LawnchairDAO(window);
|
||||
cloudstoragedao_test.crypto = new app.crypto.Crypto(window, util);
|
||||
cloudstoragedao_test.storage = new app.dao.DeviceStorage(util, cloudstoragedao_test.crypto, jsonDao, null);
|
||||
var crypto = new app.crypto.Crypto(window, util);
|
||||
var naclCrypto = new app.crypto.NaclCrypto(nacl, util);
|
||||
cloudstoragedao_test.storage = new app.dao.DeviceStorage(util, crypto, jsonDao, null);
|
||||
cloudstoragedao_test.cloudstorage = new app.dao.CloudStorage(window, $);
|
||||
cloudstoragedao_test.emailDao = new app.dao.EmailDAO(_, cloudstoragedao_test.crypto, cloudstoragedao_test.storage, cloudstoragedao_test.cloudstorage);
|
||||
cloudstoragedao_test.emailDao = new app.dao.EmailDAO(_, crypto, cloudstoragedao_test.storage, cloudstoragedao_test.cloudstorage, naclCrypto);
|
||||
|
||||
// clear db before tests
|
||||
jsonDao.clear(function(err) {
|
||||
@ -31,6 +26,15 @@ asyncTest("Init", 1, function() {
|
||||
});
|
||||
|
||||
asyncTest("Persist public key to cloud", 1, function() {
|
||||
|
||||
// testdata
|
||||
cloudstoragedao_test.privateKey = "Bv51afjeuH8CatKo75HOHQRT1B3amvF+DEwijka79nA=";
|
||||
cloudstoragedao_test.publicKey = new app.model.PublicKey({
|
||||
_id: "da4bfa93-ba87-490e-877c-e4020a6f6729",
|
||||
userId: 'integration@atlasdev.onmicrosoft.com',
|
||||
publicKey: "yHUhh3Pcbjmh2k367pSXfE8hDwPsAxQs0QETm9mfmz0="
|
||||
});
|
||||
|
||||
cloudstoragedao_test.cloudstorage.putPublicKey(cloudstoragedao_test.publicKey.toJSON(), function(err) {
|
||||
ok(!err, 'Persist key to cloud');
|
||||
|
||||
@ -39,7 +43,7 @@ asyncTest("Persist public key to cloud", 1, function() {
|
||||
});
|
||||
|
||||
asyncTest("Get Public key from cloud", 2, function() {
|
||||
cloudstoragedao_test.cloudstorage.getPublicKey(cloudstoragedao_test.user, function(err, data) {
|
||||
cloudstoragedao_test.cloudstorage.getPublicKey(cloudstoragedao_test.publicKey.get('userId'), function(err, data) {
|
||||
ok(!err && data && data.publicKey, 'Get public key from cloud');
|
||||
deepEqual(data, cloudstoragedao_test.publicKey.toJSON(), 'Public key is equal');
|
||||
|
||||
@ -69,7 +73,10 @@ asyncTest("Persist user secret key to cloud", 1, function() {
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("Sync emails from cloud", 3, function() {
|
||||
|
||||
module("Email DAO");
|
||||
|
||||
asyncTest("Init", 1, function() {
|
||||
|
||||
var account = new app.model.Account({
|
||||
emailAddress: cloudstoragedao_test.user,
|
||||
@ -77,17 +84,22 @@ asyncTest("Sync emails from cloud", 3, function() {
|
||||
symIvSize: cloudstoragedao_test.ivSize
|
||||
});
|
||||
|
||||
cloudstoragedao_test.emailDao.init(account, cloudstoragedao_test.password, function() {
|
||||
ok(true, 'Init complete');
|
||||
cloudstoragedao_test.emailDao.init(account, cloudstoragedao_test.password, function(err) {
|
||||
ok(!err, 'Init complete');
|
||||
|
||||
cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(err) {
|
||||
ok(!err, 'Synced items');
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
cloudstoragedao_test.emailDao.listItems('inbox', 0, null, function(collection) {
|
||||
ok(collection.length > 0, 'Read synced items');
|
||||
asyncTest("Sync emails from cloud", 3, function() {
|
||||
|
||||
start();
|
||||
});
|
||||
cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(err) {
|
||||
ok(!err, 'Synced items');
|
||||
|
||||
cloudstoragedao_test.emailDao.listItems('inbox', 0, null, function(collection) {
|
||||
ok(collection.length > 0, 'Read synced items');
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
});
|
@ -40,6 +40,8 @@
|
||||
<script src="../lib/sjcl/codecString.js"></script>
|
||||
<script src="../lib/sjcl/aes.js"></script>
|
||||
<script src="../lib/sjcl/ccm.js"></script>
|
||||
|
||||
<script src="../lib/nacl.js"></script>
|
||||
|
||||
<script src="../lib/uuid.js"></script>
|
||||
<script src="../lib/openpgp.min.js"></script>
|
||||
@ -60,7 +62,8 @@
|
||||
<script src="../js/crypto/aes-cbc.js"></script>
|
||||
<script src="../js/crypto/aes-ccm.js"></script>
|
||||
<script src="../js/crypto/aes-gcm.js"></script>
|
||||
<script src="../js/crypto/crypto.js"></script>
|
||||
<script src="../js/crypto/nacl-crypto.js"></script>
|
||||
<script src="../js/crypto/crypto.js"></script>
|
||||
|
||||
<script src="../js/dao/localstorage-dao.js"></script>
|
||||
<script src="../js/dao/lawnchair-dao.js"></script>
|
||||
|
@ -12,14 +12,18 @@ asyncTest("Init", 2, function() {
|
||||
var util = new app.crypto.Util(window, uuid);
|
||||
var jsonDao = new app.dao.LawnchairDAO(window);
|
||||
emaildao_test.crypto = new app.crypto.Crypto(window, util);
|
||||
var naclCrypto = new app.crypto.NaclCrypto(nacl, util);
|
||||
emaildao_test.storage = new app.dao.DeviceStorage(util, emaildao_test.crypto, jsonDao, null);
|
||||
// cloud storage stub
|
||||
var cloudstorageStub = {
|
||||
getUserSecretKey: function(emailAdress, callback) {
|
||||
callback();
|
||||
},
|
||||
putPublicKey: function(pk, callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
emaildao_test.emailDao = new app.dao.EmailDAO(_, emaildao_test.crypto, emaildao_test.storage, cloudstorageStub);
|
||||
emaildao_test.emailDao = new app.dao.EmailDAO(_, emaildao_test.crypto, emaildao_test.storage, cloudstorageStub, naclCrypto);
|
||||
|
||||
// generate test data
|
||||
emaildao_test.list = new TestData().getEmailCollection(100);
|
||||
|
@ -58,6 +58,7 @@
|
||||
<script src="../js/model/email-model.js"></script>
|
||||
<script src="../js/model/folder-model.js"></script>
|
||||
<script src="../js/model/account-model.js"></script>
|
||||
<script src="../js/model/publickey-model.js"></script>
|
||||
|
||||
<script src="../js/crypto/util.js"></script>
|
||||
<script src="../js/crypto/pbkdf2.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user