implemented storage and lookup of user keypair

This commit is contained in:
Tankred Hase 2013-05-27 19:25:45 +02:00
parent a3ff4c48c1
commit 6a33f17f42
4 changed files with 146 additions and 42 deletions

View File

@ -11,6 +11,8 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, util) {
this.init = function(account, password, callback) { this.init = function(account, password, callback) {
this.account = account; this.account = account;
// TODO: call getUserKeyPair to read/sync keypair with devicestorage/cloud
// sync user's cloud key with local storage // sync user's cloud key with local storage
var storedKey = crypto.getEncryptedPrivateKey(account.get('emailAddress')); var storedKey = crypto.getEncryptedPrivateKey(account.get('emailAddress'));
cloudstorage.syncPrivateKey(account.get('emailAddress'), storedKey, function(err) { cloudstorage.syncPrivateKey(account.get('emailAddress'), storedKey, function(err) {
@ -30,6 +32,9 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, util) {
}); });
function initCrypto() { function initCrypto() {
// TODO: passed fetched keypair from keychain dao
crypto.init({ crypto.init({
emailAddress: account.get('emailAddress'), emailAddress: account.get('emailAddress'),
password: password, password: password,
@ -45,6 +50,8 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, util) {
}); });
} }
// TODO: refactor to be part of sync in getUserKeypair
function publishPublicKey() { function publishPublicKey() {
// get public key from crypto // get public key from crypto
var pubkey = crypto.getPublicKey(); var pubkey = crypto.getPublicKey();
@ -84,7 +91,7 @@ app.dao.EmailDAO = function(_, crypto, devicestorage, cloudstorage, util) {
if (!folder) { if (!folder) {
// get items from storage // get items from storage
devicestorage.listItems('email_' + folderName, offset, num, function(err, decryptedList) { devicestorage.listItems('email_' + folderName, offset, num, null, function(err, decryptedList) {
if (err) { if (err) {
callback(err); callback(err);
return; return;

View File

@ -22,25 +22,28 @@ app.dao.KeychainDAO = function(jsonDao, cloudstorage) {
* return [Object] The user's key pair {publicKey, privateKey} * return [Object] The user's key pair {publicKey, privateKey}
*/ */
this.getUserKeyPair = function(userId, callback) { this.getUserKeyPair = function(userId, callback) {
// try to read public key from local storage // loojup public key id
jsonDao.read(userId + '_publickey', function(pubkey) { jsonDao.read('publickey_' + userId, function(pubkeyId) {
if (!pubkey) { // try to read public key from local storage
// no public key in storage jsonDao.read('publickey_' + pubkeyId._id, function(pubkey) {
// TODO: fetch from cloud if (!pubkey) {
// TODO: persist in local storage // no public key in storage
callback({ // TODO: fetch from cloud
errMsg: 'Not implemented yet!' // TODO: persist in local storage
}); callback({
} else { errMsg: 'Not implemented yet!'
// public key found });
// get corresponding private key } else {
fetchEncryptedPrivateKey(pubkey); // public key found
} // get corresponding private key
fetchEncryptedPrivateKey(pubkey);
}
});
}); });
function fetchEncryptedPrivateKey(publicKey) { function fetchEncryptedPrivateKey(publicKey) {
// try to read private key from local storage // try to read private key from local storage
jsonDao.read(userId + '_privatekey_' + publicKey._id, function(privkey) { jsonDao.read('privatekey_' + publicKey._id, function(privkey) {
if (!privkey) { if (!privkey) {
// no private key in storage // no private key in storage
// TODO: fetch from cloud // TODO: fetch from cloud
@ -65,7 +68,67 @@ app.dao.KeychainDAO = function(jsonDao, cloudstorage) {
* @param [Object] The user's key pair {publicKey, privateKey} * @param [Object] The user's key pair {publicKey, privateKey}
*/ */
this.putUserKeyPair = function(keypair, callback) { this.putUserKeyPair = function(keypair, callback) {
// validate input
if (!keypair || !keypair.publicKey || !keypair.privateKey || !keypair.publicKey.userId || keypair.publicKey.userId !== keypair.privateKey.userId) {
callback({
errMsg: 'Incorrect input!'
});
return;
}
// persist public key (email, _id)
var pkLookupKey = 'publickey_' + keypair.publicKey.userId;
jsonDao.persist(pkLookupKey, {
_id: keypair.publicKey._id
}, function(res1) {
// validate result
if (res1.key !== pkLookupKey) {
callback({
errMsg: 'Persisting went wrong!'
});
return;
}
// persist public key
var pkKey = 'publickey_' + keypair.publicKey._id;
jsonDao.persist(pkKey, keypair.publicKey, function(res2) {
// validate result
if (res2.key !== pkKey) {
callback({
errMsg: 'Persisting went wrong!'
});
return;
}
// persist public key (email, _id)
var prkLookupKey = 'privatekey_' + keypair.privateKey.userId;
jsonDao.persist(prkLookupKey, {
_id: keypair.privateKey._id
}, function(res3) {
// validate result
if (res3.key !== prkLookupKey) {
callback({
errMsg: 'Persisting went wrong!'
});
return;
}
// persist private key
var prkKey = 'privatekey_' + keypair.privateKey._id;
jsonDao.persist(prkKey, keypair.privateKey, function(res4) {
// validate result
if (res4.key !== prkKey) {
callback({
errMsg: 'Persisting went wrong!'
});
return;
}
callback(null);
});
});
});
});
}; };
}; };

View File

@ -10,7 +10,7 @@ var cloudstoragedao_test = {
asyncTest("Init", 1, function() { asyncTest("Init", 1, function() {
// init dependencies // init dependencies
cloudstoragedao_test.util = new app.crypto.Util(window, uuid); cloudstoragedao_test.util = new cryptoLib.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, cloudstoragedao_test.util); cloudstoragedao_test.crypto = new app.crypto.Crypto(window, cloudstoragedao_test.util);
cloudstoragedao_test.storage = new app.dao.DeviceStorage(cloudstoragedao_test.util, cloudstoragedao_test.crypto, jsonDao, null); cloudstoragedao_test.storage = new app.dao.DeviceStorage(cloudstoragedao_test.util, cloudstoragedao_test.crypto, jsonDao, null);
@ -119,22 +119,22 @@ asyncTest("Init", 1, function() {
}); });
}); });
// asyncTest("Send Plaintext Email item", 1, function() { asyncTest("Send Plaintext Email item", 1, function() {
// var email = new app.model.Email({ var email = new app.model.Email({
// id: cloudstoragedao_test.util.UUID(), id: cloudstoragedao_test.util.UUID(),
// from: cloudstoragedao_test.user, // sender address from: cloudstoragedao_test.user, // sender address
// to: [cloudstoragedao_test.user], // list of receivers to: [cloudstoragedao_test.user], // list of receivers
// subject: 'Client Email DAO Test', // Subject line subject: 'Client Email DAO Test', // Subject line
// body: 'Hello world' // plaintext body body: 'Hello world' // plaintext body
// }); });
// cloudstoragedao_test.emailDao.sendEmail(email, function(err) { cloudstoragedao_test.emailDao.sendEmail(email, function(err) {
// ok(!err, 'Email sent'); ok(!err, 'Email sent');
// start(); start();
// }); });
// }); });
// asyncTest("Check virtual inbox, re-encrypt and push to cloud", 1, function() { // asyncTest("Check virtual inbox, re-encrypt and push to cloud", 1, function() {
// cloudstoragedao_test.emailDao.checkVInbox(function(err) { // cloudstoragedao_test.emailDao.checkVInbox(function(err) {
@ -144,14 +144,20 @@ asyncTest("Init", 1, function() {
// }); // });
// }); // });
// asyncTest("Sync emails from cloud", 2, function() { asyncTest("Sync emails from cloud", 1, function() {
// cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(err) { cloudstoragedao_test.emailDao.syncFromCloud('inbox', function(err) {
// ok(!err, 'Synced items'); ok(!err, 'Synced items');
// cloudstoragedao_test.emailDao.listItems('inbox', 0, null, function(collection) { start();
// ok(collection.length > 0, 'Read synced items'); });
});
// start(); asyncTest("List emails from cloud", 3, function() {
// });
// }); cloudstoragedao_test.emailDao.listItems('inbox', 0, null, function(err, collection) {
// }); ok(!err);
ok(collection.length > 0, 'Read synced items');
start();
});
});

View File

@ -5,10 +5,10 @@ var keychaindao_test = {
password: 'Password', password: 'Password',
keySize: 128, keySize: 128,
ivSize: 128, ivSize: 128,
rsaKeySize: 1024 rsaKeySize: 512
}; };
asyncTest("Init", 1, function() { asyncTest("Init", 2, function() {
// init dependencies // init dependencies
var util = new cryptoLib.Util(window, uuid); var util = new cryptoLib.Util(window, uuid);
var jsonDao = new app.dao.LawnchairDAO(window); var jsonDao = new app.dao.LawnchairDAO(window);
@ -26,7 +26,35 @@ asyncTest("Init", 1, function() {
keychaindao_test.keychainDao = new app.dao.KeychainDAO(jsonDao, cloudstorageStub); keychaindao_test.keychainDao = new app.dao.KeychainDAO(jsonDao, cloudstorageStub);
ok(keychaindao_test.keychainDao); ok(keychaindao_test.keychainDao);
start(); // clear db before test
jsonDao.clear(function() {
ok(true, 'cleared db');
start();
});
});
asyncTest("Put User Keypair", 1, function() {
keychaindao_test.keypair = {
publicKey: {
_id: '1',
userId: keychaindao_test.user,
publicKey: 'asdf'
},
privateKey: {
_id: '1',
userId: keychaindao_test.user,
encryptedKey: 'qwer',
iv: 'yxvc'
}
};
keychaindao_test.keychainDao.putUserKeyPair(keychaindao_test.keypair, function(err) {
ok(!err);
start();
});
}); });
asyncTest("Get User Keypair", 2, function() { asyncTest("Get User Keypair", 2, function() {