diff --git a/src/js/crypto/crypto.js b/src/js/crypto/crypto.js
index 60b0fec..ffc0114 100644
--- a/src/js/crypto/crypto.js
+++ b/src/js/crypto/crypto.js
@@ -7,9 +7,6 @@ app.crypto.Crypto = function(window, util) {
var aes = new cryptoLib.AesCBC(forge); // use AES-CBC mode by default
var rsa = new cryptoLib.RSA(forge, util); // use RSA for asym. crypto
- var keyStore = new app.dao.LocalStorageDAO(window);
-
- var storageId; // storage id for the encrypted keypair in local storage
/**
* Initializes the crypto modules by fetching the user's
@@ -26,35 +23,28 @@ app.crypto.Crypto = function(window, util) {
return;
}
- this.emailAddress = args.emailAddress;
- this.keySize = args.keySize;
- this.ivSize = args.keySize;
- this.rsaKeySize = args.rsaKeySize;
-
- storageId = self.emailAddress + '_encryptedKeypair';
+ self.emailAddress = args.emailAddress;
+ self.keySize = args.keySize;
+ self.ivSize = args.keySize;
+ self.rsaKeySize = args.rsaKeySize;
// derive PBKDF2 from password in web worker thread
- this.deriveKey(args.password, self.keySize, function(pbkdf2) {
-
- // TODO: rm keystore logix and check args.storedKeypair
-
- // fetch user's encrypted secret key from keychain/storage
- var storedKeypair = keyStore.read(storageId);
+ self.deriveKey(args.password, self.keySize, function(pbkdf2) {
// check if key exists
- if (!storedKeypair) {
+ if (!args.storedKeypair) {
// generate keys, encrypt and persist if none exists
generateKeypair(pbkdf2);
} else {
// decrypt key
- decryptKeypair(storedKeypair, pbkdf2);
+ decryptKeypair(args.storedKeypair, pbkdf2);
}
});
function generateKeypair(pbkdf2) {
// generate RSA keypair in web worker
- rsa.generateKeypair(self.rsaKeySize, function(err, keypair) {
+ rsa.generateKeypair(self.rsaKeySize, function(err, generatedKeypair) {
if (err) {
callback(err);
return;
@@ -62,28 +52,43 @@ app.crypto.Crypto = function(window, util) {
// encrypt keypair
var iv = util.random(self.ivSize);
- var encryptedKeys = aes.encrypt(JSON.stringify(keypair), pbkdf2, iv);
+ var encryptedPrivateKey = aes.encrypt(generatedKeypair.privkeyPem, pbkdf2, iv);
- // store encrypted keypair
- var newStoredKeypair = {
- _id: keypair._id,
- userId: self.emailAddress,
- encryptedKey: encryptedKeys,
- iv: iv
+ // new encrypted keypair object
+ var newKeypair = {
+ publicKey: {
+ _id: generatedKeypair._id,
+ userId: self.emailAddress,
+ publicKey: generatedKeypair.pubkeyPem
+ },
+ privateKey: {
+ _id: generatedKeypair._id,
+ userId: self.emailAddress,
+ encryptedKey: encryptedPrivateKey,
+ iv: iv
+ }
};
- keyStore.persist(storageId, newStoredKeypair);
- // TODO: return generated keypair for storage in keychain dao
- callback();
+ // return generated keypair for storage in keychain dao
+ callback(null, newKeypair);
});
}
function decryptKeypair(storedKeypair, pbkdf2) {
- var keypairJson, keypair;
+ var decryptedPrivateKey;
+
+ // validate input
+ if (!storedKeypair || !storedKeypair.privateKey || !storedKeypair.privateKey.encryptedKey || !storedKeypair.privateKey.iv) {
+ callback({
+ errMsg: 'Incomplete arguments for private key decryption!'
+ });
+ return;
+ }
+
// try to decrypt with pbkdf2
try {
- keypairJson = aes.decrypt(storedKeypair.encryptedKey, pbkdf2, storedKeypair.iv);
- keypair = JSON.parse(keypairJson);
+ var prK = storedKeypair.privateKey;
+ decryptedPrivateKey = aes.decrypt(prK.encryptedKey, pbkdf2, prK.iv);
} catch (ex) {
callback({
errMsg: 'Wrong password!'
@@ -91,56 +96,12 @@ app.crypto.Crypto = function(window, util) {
return;
}
// set rsa keys
- rsa.init(keypair.pubkeyPem, keypair.privkeyPem, keypair._id);
+ rsa.init(storedKeypair.publicKey.publicKey, decryptedPrivateKey, storedKeypair.publicKey._id);
callback();
}
};
- // TODO: not required since key is synced before crypto init in keychain dao getUserKeyPair
-
- /**
- * Return a Public Key object containing the Public Key PEM
- */
- this.getPublicKey = function() {
- var keypair = rsa.exportKeys();
-
- return {
- _id: keypair._id,
- userId: this.emailAddress,
- publicKey: keypair.pubkeyPem
- };
- };
-
- // TODO: not required since key is synced before crypto init in keychain dao getUserKeyPair
-
- /**
- * Return a Private Key object containing the encrypted private key
- */
- this.getEncryptedPrivateKey = function(emailAddress) {
- if (!emailAddress && !storageId) {
- throw new Error('Emailaddress needs to be set or crypto needs to be initiated!');
- }
-
- var strgId = (storageId) ? storageId : emailAddress + '_encryptedKeypair';
- var storedKeypair = keyStore.read(strgId);
-
- return storedKeypair;
- };
-
- // TODO: not required since key is synced before crypto init in keychain dao getUserKeyPair
-
- this.putEncryptedPrivateKey = function(privkey) {
- var strgId = (storageId) ? storageId : privkey.userId + '_encryptedKeypair';
-
- // validate private key object
- if (!strgId || !privkey || !privkey._id || !privkey.userId || !privkey.encryptedKey || !privkey.iv) {
- throw new Error('Invalid encrypted private key object... will not store!');
- }
-
- return keyStore.persist(strgId, privkey);
- };
-
/**
* Do PBKDF2 key derivation in a WebWorker thread
*/
diff --git a/test/unit/crypto-test.js b/test/unit/crypto-test.js
index fa70a3a..489e423 100644
--- a/test/unit/crypto-test.js
+++ b/test/unit/crypto-test.js
@@ -8,41 +8,42 @@ var crypto_test = {
rsaKeySize: 1024
};
-asyncTest("Init", 2, function() {
+asyncTest("Init without keypair", 4, function() {
// init dependencies
crypto_test.util = new cryptoLib.Util(window, uuid);
crypto_test.crypto = new app.crypto.Crypto(window, crypto_test.util);
ok(crypto_test.crypto, 'Crypto');
+ // test without passing keys
crypto_test.crypto.init({
emailAddress: crypto_test.user,
password: crypto_test.password,
keySize: crypto_test.keySize,
rsaKeySize: crypto_test.rsaKeySize
- }, function(err) {
- ok(!err, 'Init crypto');
+ }, function(err, generatedKeypair) {
+ ok(!err && generatedKeypair, 'Init crypto without keypair input');
+ var pk = generatedKeypair.publicKey;
+ ok(pk._id && pk.userId, 'Key ID: ' + pk._id);
+ ok(pk.publicKey.indexOf('-----BEGIN PUBLIC KEY-----') === 0, pk.publicKey);
+ crypto_test.generatedKeypair = generatedKeypair;
start();
});
});
-test("Get Public Key PEM", 2, function() {
- var pk = crypto_test.crypto.getPublicKey();
- ok(pk._id && pk.userId, 'Key ID: ' + pk._id);
- ok(pk.publicKey.indexOf('-----BEGIN PUBLIC KEY-----') === 0, pk.publicKey);
-});
+asyncTest("Init with keypair", 1, function() {
+ // test with passing keypair
+ crypto_test.crypto.init({
+ emailAddress: crypto_test.user,
+ password: crypto_test.password,
+ keySize: crypto_test.keySize,
+ rsaKeySize: crypto_test.rsaKeySize,
+ storedKeypair: crypto_test.generatedKeypair
+ }, function(err, generatedKeypair) {
+ ok(!err, 'Init crypto with keypair input');
-test("Get Encrypted Private Key", 2, function() {
- var prk = crypto_test.crypto.getEncryptedPrivateKey();
- ok(prk._id && prk.userId, 'Key ID: ' + prk._id);
- ok(prk.encryptedKey, prk.encryptedKey);
-
- crypto_test.prk = prk;
-});
-
-test("Put Encrypted Private Key", 1, function() {
- crypto_test.crypto.putEncryptedPrivateKey(crypto_test.prk);
- ok(true);
+ start();
+ });
});
asyncTest("PBKDF2 (Async/Worker)", 1, function() {
@@ -98,7 +99,7 @@ asyncTest("AES/RSA encrypt batch for User (Async/Worker)", 2, function() {
collection = td.getEmailCollection(10);
crypto_test.list = collection.toJSON();
- var receiverPubkeys = [crypto_test.crypto.getPublicKey()];
+ var receiverPubkeys = [crypto_test.generatedKeypair.publicKey];
crypto_test.crypto.encryptListForUser(crypto_test.list, receiverPubkeys, function(err, encryptedList) {
ok(!err && encryptedList, 'Encrypt list for user');
@@ -111,7 +112,7 @@ asyncTest("AES/RSA encrypt batch for User (Async/Worker)", 2, function() {
asyncTest("AES/RSA decrypt batch for User (Async/Worker)", 3, function() {
- var senderPubkeys = [crypto_test.crypto.getPublicKey()];
+ var senderPubkeys = [crypto_test.generatedKeypair.publicKey];
crypto_test.crypto.decryptListForUser(crypto_test.encryptedList, senderPubkeys, function(err, decryptedList) {
ok(!err && decryptedList, 'Decrypt list');
diff --git a/test/unit/devicestorage-test.js b/test/unit/devicestorage-test.js
index 1ea796c..a740bf3 100644
--- a/test/unit/devicestorage-test.js
+++ b/test/unit/devicestorage-test.js
@@ -25,8 +25,9 @@ asyncTest("Init", 3, function() {
password: devicestorage_test.password,
keySize: devicestorage_test.keySize,
rsaKeySize: devicestorage_test.rsaKeySize
- }, function(err) {
- ok(!err, 'Init crypto');
+ }, function(err, generatedKeypair) {
+ ok(!err && generatedKeypair, 'Init crypto');
+ devicestorage_test.generatedKeypair = generatedKeypair;
// clear db before tests
devicestorage_test.jsonDao.clear(function(err) {
@@ -39,7 +40,7 @@ asyncTest("Init", 3, function() {
});
asyncTest("Encrypt list for user", 2, function() {
- var receiverPubkeys = [devicestorage_test.crypto.getPublicKey()];
+ var receiverPubkeys = [devicestorage_test.generatedKeypair.publicKey];
devicestorage_test.crypto.encryptListForUser(devicestorage_test.list, receiverPubkeys, function(err, encryptedList) {
ok(!err);
@@ -60,7 +61,7 @@ asyncTest("Store encrypted list", 1, function() {
asyncTest("List items", 3, function() {
- var senderPubkeys = [devicestorage_test.crypto.getPublicKey()];
+ var senderPubkeys = [devicestorage_test.generatedKeypair.publicKey];
var offset = 2,
num = 6;
diff --git a/test/unit/index.html b/test/unit/index.html
index ebabd62..beca018 100644
--- a/test/unit/index.html
+++ b/test/unit/index.html
@@ -57,11 +57,11 @@
-
-
+
+