1
0
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:
Tankred Hase 2013-04-19 16:38:32 +02:00
parent e943dfd304
commit 65e0a7d520
6 changed files with 70 additions and 30 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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