mirror of
https://github.com/moparisthebest/mail
synced 2025-02-07 02:20:14 -05:00
refactored crypto for user to use RSA encrypt/sign
This commit is contained in:
parent
413a99a04f
commit
fcf64569b2
@ -66,15 +66,19 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function decryptKeypair(storedKeypair, pbkdf2) {
|
function decryptKeypair(storedKeypair, pbkdf2) {
|
||||||
|
var keypairJson, keypair;
|
||||||
|
// try to decrypt with pbkdf2
|
||||||
try {
|
try {
|
||||||
var keypairJson = aes.decrypt(storedKeypair.encryptedKeys, pbkdf2, storedKeypair.keyIV);
|
keypairJson = aes.decrypt(storedKeypair.encryptedKeys, pbkdf2, storedKeypair.keyIV);
|
||||||
var keypair = JSON.parse(keypairJson);
|
keypair = JSON.parse(keypairJson);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
callback({
|
callback({
|
||||||
errMsg: 'Wrong password!'
|
errMsg: 'Wrong password!'
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// set rsa keys
|
||||||
|
rsa.init(keypair.pubkeyPem, keypair.privkeyPem, keypair._id);
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
@ -205,22 +209,7 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
// En/Decrypt something speficially using the user's secret key
|
// En/Decrypt something speficially using the user's secret key
|
||||||
//
|
//
|
||||||
|
|
||||||
this.aesEncryptForUser = function(plaintext, iv, callback) {
|
this.encryptListForUser = function(list, recipientPubkey, callback) {
|
||||||
var ciphertext = aes.encrypt(plaintext, symmetricUserKey, iv);
|
|
||||||
callback(ciphertext);
|
|
||||||
};
|
|
||||||
this.aesDecryptForUser = function(ciphertext, iv, callback) {
|
|
||||||
var decrypted = aes.decrypt(ciphertext, symmetricUserKey, iv);
|
|
||||||
callback(decrypted);
|
|
||||||
};
|
|
||||||
this.aesEncryptForUserSync = function(plaintext, iv) {
|
|
||||||
return aes.encrypt(plaintext, symmetricUserKey, iv);
|
|
||||||
};
|
|
||||||
this.aesDecryptForUserSync = function(ciphertext, iv) {
|
|
||||||
return aes.decrypt(ciphertext, symmetricUserKey, iv);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.aesEncryptListForUser = function(list, callback) {
|
|
||||||
var envelope, envelopes = [],
|
var envelope, envelopes = [],
|
||||||
self = this;
|
self = this;
|
||||||
|
|
||||||
@ -242,26 +231,33 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
encryptedList.forEach(function(i) {
|
encryptedList.forEach(function(i) {
|
||||||
// process new values
|
// process new values
|
||||||
i.itemIV = i.iv;
|
i.itemIV = i.iv;
|
||||||
i.keyIV = util.random(self.ivSize);
|
i.encryptedKey = rsa.encrypt(i.key);
|
||||||
i.encryptedKey = self.aesEncryptForUserSync(i.key, i.keyIV);
|
i.keyIV = rsa.sign([i.itemIV, i.encryptedKey, i.ciphertext]);
|
||||||
// delete old ones
|
// delete old ones
|
||||||
delete i.iv;
|
delete i.iv;
|
||||||
delete i.key;
|
delete i.key;
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(encryptedList);
|
callback(null, encryptedList);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.aesDecryptListForUser = function(encryptedList, callback) {
|
this.decryptListForUser = function(encryptedList, recipientPubkey, callback) {
|
||||||
var list = [],
|
var list = [],
|
||||||
self = this;
|
self = this;
|
||||||
|
|
||||||
// decrypt keys for user
|
// decrypt keys for user
|
||||||
encryptedList.forEach(function(i) {
|
encryptedList.forEach(function(i) {
|
||||||
// decrypt item key
|
// verify signature
|
||||||
i.key = self.aesDecryptForUserSync(i.encryptedKey, i.keyIV);
|
if (!rsa.verify([i.itemIV, i.encryptedKey, i.ciphertext], i.keyIV)) {
|
||||||
|
callback({
|
||||||
|
errMsg: 'Verifying RSA signature failed!'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// precoess new values
|
||||||
i.iv = i.itemIV;
|
i.iv = i.itemIV;
|
||||||
|
i.key = rsa.decrypt(i.encryptedKey);
|
||||||
// delete old values
|
// delete old values
|
||||||
delete i.keyIV;
|
delete i.keyIV;
|
||||||
delete i.itemIV;
|
delete i.itemIV;
|
||||||
@ -275,7 +271,7 @@ app.crypto.Crypto = function(window, util) {
|
|||||||
list.push(i.plaintext);
|
list.push(i.plaintext);
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(list);
|
callback(null, list);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,11 +14,13 @@ app.crypto.RSA = function(forge, util) {
|
|||||||
* and signing
|
* and signing
|
||||||
*/
|
*/
|
||||||
this.init = function(pubkeyPem, privkeyPem, keyId) {
|
this.init = function(pubkeyPem, privkeyPem, keyId) {
|
||||||
keypair.publicKey = forge.pki.publicKeyFromPem(pubkeyPem);
|
keypair = {
|
||||||
|
_id: keyId,
|
||||||
|
publicKey: forge.pki.publicKeyFromPem(pubkeyPem)
|
||||||
|
};
|
||||||
if (privkeyPem) {
|
if (privkeyPem) {
|
||||||
keypair.privateKey = forge.pki.privateKeyFromPem(privkeyPem);
|
keypair.privateKey = forge.pki.privateKeyFromPem(privkeyPem);
|
||||||
}
|
}
|
||||||
keypair._id = keyId;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,15 +44,13 @@ var Util = function(window, uuid, crypt) {
|
|||||||
* @list list [Array] The list of items to encrypt
|
* @list list [Array] The list of items to encrypt
|
||||||
*/
|
*/
|
||||||
this.encryptList = function(aes, list) {
|
this.encryptList = function(aes, list) {
|
||||||
var json, ct, outList = [];
|
var outList = [];
|
||||||
|
|
||||||
list.forEach(function(i) {
|
list.forEach(function(i) {
|
||||||
// stringify to JSON before encryption
|
// stringify to JSON before encryption
|
||||||
json = JSON.stringify(i.plaintext);
|
|
||||||
ct = aes.encrypt(json, i.key, i.iv);
|
|
||||||
outList.push({
|
outList.push({
|
||||||
id: i.id,
|
id: i.id,
|
||||||
ciphertext: ct,
|
ciphertext: aes.encrypt(JSON.stringify(i.plaintext), i.key, i.iv),
|
||||||
key: i.key,
|
key: i.key,
|
||||||
iv: i.iv
|
iv: i.iv
|
||||||
});
|
});
|
||||||
@ -67,15 +65,13 @@ var Util = function(window, uuid, crypt) {
|
|||||||
* @list list [Array] The list of items to decrypt
|
* @list list [Array] The list of items to decrypt
|
||||||
*/
|
*/
|
||||||
this.decryptList = function(aes, list) {
|
this.decryptList = function(aes, list) {
|
||||||
var json, pt, outList = [];
|
var outList = [];
|
||||||
|
|
||||||
list.forEach(function(i) {
|
list.forEach(function(i) {
|
||||||
// decrypt JSON and parse to object literal
|
// decrypt JSON and parse to object literal
|
||||||
json = aes.decrypt(i.ciphertext, i.key, i.iv);
|
|
||||||
pt = JSON.parse(json);
|
|
||||||
outList.push({
|
outList.push({
|
||||||
id: i.id,
|
id: i.id,
|
||||||
plaintext: pt,
|
plaintext: JSON.parse(aes.decrypt(i.ciphertext, i.key, i.iv)),
|
||||||
key: i.key,
|
key: i.key,
|
||||||
iv: i.iv
|
iv: i.iv
|
||||||
});
|
});
|
||||||
|
@ -32,33 +32,7 @@ asyncTest("PBKDF2 (Async/Worker)", 1, function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("En/Decrypt for User", 4, function() {
|
asyncTest("AES en/decrypt (Async/Worker)", 2, function() {
|
||||||
var secret = "Secret stuff";
|
|
||||||
|
|
||||||
var itemKey = crypto_test.util.random(crypto_test.keySize);
|
|
||||||
var itemIV = crypto_test.util.random(crypto_test.ivSize);
|
|
||||||
var keyIV = crypto_test.util.random(crypto_test.ivSize);
|
|
||||||
|
|
||||||
crypto_test.crypto.aesEncrypt(secret, itemKey, itemIV, function(ciphertext) {
|
|
||||||
ok(ciphertext, 'Encrypt item');
|
|
||||||
|
|
||||||
crypto_test.crypto.aesEncryptForUser(itemKey, keyIV, function(encryptedKey) {
|
|
||||||
ok(encryptedKey, 'Encrypt item key');
|
|
||||||
|
|
||||||
crypto_test.crypto.aesDecryptForUser(encryptedKey, keyIV, function(decryptedKey) {
|
|
||||||
equal(decryptedKey, itemKey, 'Decrypt item key');
|
|
||||||
|
|
||||||
crypto_test.crypto.aesDecrypt(ciphertext, decryptedKey, itemIV, function(decrypted) {
|
|
||||||
equal(decrypted, secret, 'Decrypt item');
|
|
||||||
|
|
||||||
start();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
asyncTest("AES (Async/Worker)", 2, function() {
|
|
||||||
var secret = 'Big secret';
|
var secret = 'Big secret';
|
||||||
|
|
||||||
var key = crypto_test.util.random(crypto_test.keySize);
|
var key = crypto_test.util.random(crypto_test.keySize);
|
||||||
@ -75,7 +49,7 @@ asyncTest("AES (Async/Worker)", 2, function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("AES batch (Async/Worker)", 5, function() {
|
asyncTest("AES en/decrypt batch (Async/Worker)", 5, function() {
|
||||||
// generate test data
|
// generate test data
|
||||||
var collection, list, td = new TestData();
|
var collection, list, td = new TestData();
|
||||||
|
|
||||||
@ -96,23 +70,28 @@ asyncTest("AES batch (Async/Worker)", 5, function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest("AES batch for User (Async/Worker)", 5, function() {
|
asyncTest("AES/RSA encrypt batch for User (Async/Worker)", 2, function() {
|
||||||
// generate test data
|
// generate test data
|
||||||
var collection, list, td = new TestData();
|
var collection, td = new TestData();
|
||||||
|
|
||||||
collection = td.getEmailCollection(100);
|
collection = td.getEmailCollection(10);
|
||||||
list = collection.toJSON();
|
crypto_test.list = collection.toJSON();
|
||||||
|
|
||||||
crypto_test.crypto.aesEncryptListForUser(list, function(encryptedList) {
|
crypto_test.crypto.encryptListForUser(crypto_test.list, null, function(err, encryptedList) {
|
||||||
ok(encryptedList, 'Encrypt list for user');
|
ok(!err && encryptedList, 'Encrypt list for user');
|
||||||
equal(encryptedList.length, list.length, 'Length of list');
|
equal(encryptedList.length, crypto_test.list.length, 'Length of list');
|
||||||
|
crypto_test.encryptedList = encryptedList;
|
||||||
|
|
||||||
crypto_test.crypto.aesDecryptListForUser(encryptedList, function(decryptedList) {
|
start();
|
||||||
ok(decryptedList, 'Decrypt list');
|
});
|
||||||
equal(decryptedList.length, list.length, 'Length of list');
|
});
|
||||||
deepEqual(decryptedList, list, 'Decrypted list is correct');
|
|
||||||
|
asyncTest("AES/RSA decrypt batch for User (Async/Worker)", 3, function() {
|
||||||
start();
|
crypto_test.crypto.decryptListForUser(crypto_test.encryptedList, null, function(err, decryptedList) {
|
||||||
});
|
ok(!err && decryptedList, 'Decrypt list');
|
||||||
|
equal(decryptedList.length, crypto_test.list.length, 'Length of list');
|
||||||
|
deepEqual(decryptedList, crypto_test.list, 'Decrypted list is correct');
|
||||||
|
|
||||||
|
start();
|
||||||
});
|
});
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user