1
0
mirror of https://github.com/moparisthebest/mail synced 2024-11-26 10:52:17 -05:00

sending end-2-end encrypted emails internally work

This commit is contained in:
Tankred Hase 2013-07-01 22:42:39 +02:00
parent a4f03bdca1
commit 699871276c
6 changed files with 160 additions and 13 deletions

View File

@ -84,6 +84,14 @@ define(['jquery', 'js/app-config'], function($, app) {
self.put(item, uri, callback); self.put(item, uri, callback);
}; };
/**
* Deliver an email to the user's outbox
*/
self.deliverEmail = function(email, from, to, callback) {
var uri = app.config.cloudUrl + '/email/user/' + from + '/folder/outbox/' + email.id + '?to=' + to;
self.put(email, uri, callback);
};
/** /**
* Delete an encrypted item from the cloud * Delete an encrypted item from the cloud
* @param type [String] The type of item e.g. 'email' * @param type [String] The type of item e.g. 'email'

View File

@ -143,7 +143,7 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da
var filter = ''; var filter = '';
if (localItems && localItems.length > 0) { if (localItems && localItems.length > 0) {
// sync delta of last item sent date // sync delta of last item sent date
filter = '?date=' + localItems[localItems.length - 1].sentDate; //filter = '?date=' + localItems[localItems.length - 1].sentDate;
startSync(filter); startSync(filter);
} else { } else {
// do a full sync of all items on the cloud // do a full sync of all items on the cloud
@ -225,9 +225,9 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da
// validate email addresses // validate email addresses
var invalidRecipient; var invalidRecipient;
_.each(email.to, function(address) { _.each(email.to, function(i) {
if (!validateEmail(address)) { if (!validateEmail(i.address)) {
invalidRecipient = address; invalidRecipient = i.address;
} }
}); });
if (invalidRecipient) { if (invalidRecipient) {
@ -236,7 +236,7 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da
}); });
return; return;
} }
if (!validateEmail(email.from)) { if (!validateEmail(email.from[0].address)) {
callback({ callback({
errMsg: 'Invalid sender: ' + email.from errMsg: 'Invalid sender: ' + email.from
}); });
@ -245,11 +245,59 @@ define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/lawnchair-da
// generate a new UUID for the new email // generate a new UUID for the new email
email.id = util.UUID(); email.id = util.UUID();
// set sent date
email.sentDate = util.formatDate(new Date());
// only support single recipient for e-2-e encryption
var recipient = email.to[0].address;
// check if receiver has a public key
keychain.getReveiverPublicKey(recipient, function(err, receiverPubkey) {
if (err) {
callback(err);
return;
}
if (receiverPubkey) {
// public key found... encrypt and send
encrypt(email, receiverPubkey);
} else {
// no public key found... send plaintext mail via SMTP
send(email);
}
});
function encrypt(email, receiverPubkey) {
// encrypt the email
crypto.encryptListForUser([email], [receiverPubkey], function(err, encryptedList) {
if (err) {
callback(err);
return;
}
var ct = encryptedList[0];
var envelope = {
id: email.id,
crypto: 'rsa-1024-sha-256-aes-128-cbc',
sentDate: email.sentDate,
ciphertext: ct.ciphertext,
encryptedKey: ct.encryptedKey,
iv: ct.iv,
signature: ct.signature,
senderPk: ct.senderPk
};
send(envelope);
});
}
function send(email) {
// send email to cloud service // send email to cloud service
cloudstorage.putEncryptedItem(email, 'email', userId, 'outbox', function(err) { cloudstorage.deliverEmail(email, userId, recipient, function(err) {
callback(err); callback(err);
}); });
}
}; };
}; };

View File

@ -46,6 +46,51 @@ define(['underscore', 'js/dao/lawnchair-dao'], function(_, jsonDao) {
}); });
}; };
/**
* Look up a reveiver's public key by user id
* @param userId [String] the receiver's email address
*/
self.getReveiverPublicKey = function(userId, callback) {
// search local keyring for public key
jsonDao.list('publickey', 0, null, function(allPubkeys) {
var pubkey = _.findWhere(allPubkeys, {
userId: userId
});
if (!pubkey || !pubkey._id) {
// no public key by that user id in storage
// find from cloud by email address
cloudstorage.getPublicKeyByUserId(userId, function(err, cloudPubkey) {
if (err || !cloudPubkey) {
callback();
return;
}
if (cloudPubkey && cloudPubkey._id) {
// there is a public key for that user already in the cloud...
// save to local storage
saveLocalPublicKey(cloudPubkey, function(err) {
if (err) {
callback(err);
return;
}
callback(null, cloudPubkey);
});
} else {
// no public key for that user
callback();
return;
}
});
} else {
// that user's public key is already in local storage
callback(null, pubkey);
}
});
};
/** /**
* Gets the local user's key either from local storage * Gets the local user's key either from local storage
* or fetches it from the cloud. The private key is encrypted. * or fetches it from the cloud. The private key is encrypted.

View File

@ -105,11 +105,21 @@ define(['jquery', 'underscore', 'backbone', 'js/app-config'], function($, _, Bac
var signature = '\n\nSent with whiteout mail - get your free mailbox for end-2-end encrypted messaging!\nhttps://mail.whiteout.io'; var signature = '\n\nSent with whiteout mail - get your free mailbox for end-2-end encrypted messaging!\nhttps://mail.whiteout.io';
var email = { var email = {
from: self.account, to: [],
to: to,
subject: page.find('#subjectInput').val(), subject: page.find('#subjectInput').val(),
body: page.find('#bodyTextarea').val() + signature body: page.find('#bodyTextarea').val() + signature
}; };
email.from = [{
name: '',
address: self.account
}
];
to.forEach(function(address) {
email.to.push({
name: '',
address: address
});
});
// post message to main window // post message to main window
app.util.postMessage('sendEmail', { app.util.postMessage('sendEmail', {

View File

@ -161,13 +161,40 @@ define(['js/dao/email-dao', 'js/dao/keychain-dao', 'js/dao/lawnchair-dao',
}); });
}); });
asyncTest("Send Plaintext Email item", 1, function() { asyncTest("Send e-2-e Encrypted Email item", 1, function() {
var email = { var email = {
from: cloudstoragedaoTest.user, // sender address
to: [cloudstoragedaoTest.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
}; };
email.from = [{
address: cloudstoragedaoTest.user
}
];
email.to = [{
address: cloudstoragedaoTest.user
}
];
cloudstoragedaoTest.emailDao.sendEmail(email, function(err) {
ok(!err, 'Email sent');
start();
});
});
asyncTest("Send Plaintext Email item", 1, function() {
var email = {
subject: 'Client Email DAO Test', // Subject line
body: 'Hello world' // plaintext body
};
email.from = [{
address: cloudstoragedaoTest.user
}
];
email.to = [{
address: 'safewithme.testuser@gmail.com'
}
];
cloudstoragedaoTest.emailDao.sendEmail(email, function(err) { cloudstoragedaoTest.emailDao.sendEmail(email, function(err) {
ok(!err, 'Email sent'); ok(!err, 'Email sent');

View File

@ -81,4 +81,13 @@ define(['js/dao/keychain-dao', 'js/dao/lawnchair-dao'], function(KeychainDAO, js
}); });
}); });
asyncTest("Get User Keypair", 2, function() {
keychaindaoTest.keychainDao.getReveiverPublicKey(keychaindaoTest.user, function(err, pubkey) {
ok(!err);
ok(pubkey && pubkey.publicKey);
start();
});
});
}); });