1
0
mirror of https://github.com/moparisthebest/mail synced 2024-12-22 15:28:49 -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'; 'use strict';
var symmetricUserKey = null, // the user's secret key used to encrypt item-keys 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 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); symmetricUserKey = util.random(keySize);
var iv = util.random(ivSize); var iv = util.random(ivSize);
var key = aes.encrypt(symmetricUserKey, pbkdf2, iv); var key = aes.encrypt(symmetricUserKey, pbkdf2, iv);
keyStore.persist(storageId, { storedKey = {
_id: util.UUID(), _id: util.UUID(),
userId: emailAddress, userId: emailAddress,
encryptedKey: key, encryptedKey: key,
keyIV: iv keyIV: iv
}); };
keyStore.persist(storageId, storedKey);
} else { } else {
// decrypt key // decrypt key
symmetricUserKey = aes.decrypt(storedKey.encryptedKey, pbkdf2, storedKey.keyIV); symmetricUserKey = aes.decrypt(storedKey.encryptedKey, pbkdf2, storedKey.keyIV);
} }
keyId = storedKey._id;
callback(); callback();
}); });
@ -78,10 +81,10 @@ app.crypto.Crypto = function(window, util) {
/** /**
* Derive an asymmetric keypait from the user's secret * Derive an asymmetric keypait from the user's secret
*/ */
this.deriveKeyPair = function(naclCrypto, id) { this.deriveKeyPair = function(naclCrypto) {
var keys = naclCrypto.generateKeypair(symmetricUserKey); var keys = naclCrypto.generateKeypair(symmetricUserKey);
if (id) { if (keyId) {
keys.id = id; keys.id = keyId;
} }
return keys; return keys;
}; };

View File

@ -2,9 +2,11 @@
* A high-level Data-Access Api for handling Email synchronization * A high-level Data-Access Api for handling Email synchronization
* between the cloud service and the device's local storage * 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'; 'use strict';
var keypair; // the user's keypair
/** /**
* Inits all dependencies * Inits all dependencies
*/ */
@ -14,7 +16,8 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
// sync user's cloud key with local storage // sync user's cloud key with local storage
cloudstorage.getUserSecretKey(account.get('emailAddress'), function(err) { cloudstorage.getUserSecretKey(account.get('emailAddress'), function(err) {
if (err) { if (err) {
console.log('Could not sync user key from server: ' + JSON.stringify(err)); callback(err);
return;
} }
// init crypto // init crypto
initCrypto(); initCrypto();
@ -28,7 +31,21 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage) {
function initCrypto() { function initCrypto() {
crypto.init(account.get('emailAddress'), password, account.get('symKeySize'), account.get('symIvSize'), function() { 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', user: 'test@atlasdev.onmicrosoft.com',
password: 'Xoza76645', password: 'Xoza76645',
keySize: 128, keySize: 128,
ivSize: 104, ivSize: 104
privateKey: "Bv51afjeuH8CatKo75HOHQRT1B3amvF+DEwijka79nA=",
publicKey: new app.model.PublicKey({
_id: "da4bfa93-ba87-490e-877c-e4020a6f6729",
userId: 'test@atlasdev.onmicrosoft.com',
publicKey: "yHUhh3Pcbjmh2k367pSXfE8hDwPsAxQs0QETm9mfmz0="
})
}; };
asyncTest("Init", 1, function() { asyncTest("Init", 1, function() {
// init dependencies // init dependencies
var util = new app.crypto.Util(window, uuid); var util = new app.crypto.Util(window, uuid);
var jsonDao = new app.dao.LawnchairDAO(window); var jsonDao = new app.dao.LawnchairDAO(window);
cloudstoragedao_test.crypto = new app.crypto.Crypto(window, util); var crypto = new app.crypto.Crypto(window, util);
cloudstoragedao_test.storage = new app.dao.DeviceStorage(util, cloudstoragedao_test.crypto, jsonDao, null); 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.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 // clear db before tests
jsonDao.clear(function(err) { jsonDao.clear(function(err) {
@ -31,6 +26,15 @@ asyncTest("Init", 1, function() {
}); });
asyncTest("Persist public key to cloud", 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) { cloudstoragedao_test.cloudstorage.putPublicKey(cloudstoragedao_test.publicKey.toJSON(), function(err) {
ok(!err, 'Persist key to cloud'); 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() { 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'); ok(!err && data && data.publicKey, 'Get public key from cloud');
deepEqual(data, cloudstoragedao_test.publicKey.toJSON(), 'Public key is equal'); 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({ var account = new app.model.Account({
emailAddress: cloudstoragedao_test.user, emailAddress: cloudstoragedao_test.user,
@ -77,17 +84,22 @@ asyncTest("Sync emails from cloud", 3, function() {
symIvSize: cloudstoragedao_test.ivSize symIvSize: cloudstoragedao_test.ivSize
}); });
cloudstoragedao_test.emailDao.init(account, cloudstoragedao_test.password, function() { cloudstoragedao_test.emailDao.init(account, cloudstoragedao_test.password, function(err) {
ok(true, 'Init complete'); ok(!err, 'Init complete');
cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(err) { start();
ok(!err, 'Synced items'); });
});
cloudstoragedao_test.emailDao.listItems('inbox', 0, null, function(collection) { asyncTest("Sync emails from cloud", 3, function() {
ok(collection.length > 0, 'Read synced items');
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

@ -41,6 +41,8 @@
<script src="../lib/sjcl/aes.js"></script> <script src="../lib/sjcl/aes.js"></script>
<script src="../lib/sjcl/ccm.js"></script> <script src="../lib/sjcl/ccm.js"></script>
<script src="../lib/nacl.js"></script>
<script src="../lib/uuid.js"></script> <script src="../lib/uuid.js"></script>
<script src="../lib/openpgp.min.js"></script> <script src="../lib/openpgp.min.js"></script>
@ -60,6 +62,7 @@
<script src="../js/crypto/aes-cbc.js"></script> <script src="../js/crypto/aes-cbc.js"></script>
<script src="../js/crypto/aes-ccm.js"></script> <script src="../js/crypto/aes-ccm.js"></script>
<script src="../js/crypto/aes-gcm.js"></script> <script src="../js/crypto/aes-gcm.js"></script>
<script src="../js/crypto/nacl-crypto.js"></script>
<script src="../js/crypto/crypto.js"></script> <script src="../js/crypto/crypto.js"></script>
<script src="../js/dao/localstorage-dao.js"></script> <script src="../js/dao/localstorage-dao.js"></script>

View File

@ -12,14 +12,18 @@ asyncTest("Init", 2, function() {
var util = new app.crypto.Util(window, uuid); var util = new app.crypto.Util(window, uuid);
var jsonDao = new app.dao.LawnchairDAO(window); var jsonDao = new app.dao.LawnchairDAO(window);
emaildao_test.crypto = new app.crypto.Crypto(window, util); 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); emaildao_test.storage = new app.dao.DeviceStorage(util, emaildao_test.crypto, jsonDao, null);
// cloud storage stub // cloud storage stub
var cloudstorageStub = { var cloudstorageStub = {
getUserSecretKey: function(emailAdress, callback) { getUserSecretKey: function(emailAdress, callback) {
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 // generate test data
emaildao_test.list = new TestData().getEmailCollection(100); 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/email-model.js"></script>
<script src="../js/model/folder-model.js"></script> <script src="../js/model/folder-model.js"></script>
<script src="../js/model/account-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/util.js"></script>
<script src="../js/crypto/pbkdf2.js"></script> <script src="../js/crypto/pbkdf2.js"></script>