1
0
mirror of https://github.com/moparisthebest/mail synced 2024-12-22 07:18:49 -05:00

migrated cloudstorage to use aws service

This commit is contained in:
Tankred Hase 2013-04-18 20:34:02 +02:00
parent 32a52ad6e7
commit ba376d166e
7 changed files with 114 additions and 67 deletions

View File

@ -1,9 +1,6 @@
/** 'use strict';
* A simple server for serving static files using node.js
*/
var express = require('express'), var express = require('express'),
fs = require('fs'),
port, app, dev; port, app, dev;
port = process.env.PORT || 8585; port = process.env.PORT || 8585;

View File

@ -18,7 +18,7 @@ var app; // container for the application namespace
* Global app configurations * Global app configurations
*/ */
app.config = { app.config = {
cloudUrl: 'https://whiteout-io.appspot.com', cloudUrl: 'http://storage.whiteout.io',
symKeySize: 128, symKeySize: 128,
symIvSize: 104, symIvSize: 104,
asymKeySize: 2048, asymKeySize: 2048,

View File

@ -23,34 +23,29 @@ app.crypto.Crypto = function(window, util) {
// fetch user's encrypted secret key from keychain/storage // fetch user's encrypted secret key from keychain/storage
var keyStore = new app.dao.LocalStorageDAO(window); var keyStore = new app.dao.LocalStorageDAO(window);
var storageId = emailAddress + '_encryptedSymmetricKey'; var storageId = emailAddress + '_encryptedSymmetricKey';
var encryptedKey = keyStore.read(storageId); var storedKey = keyStore.read(storageId);
// check if key exists // check if key exists
if (!encryptedKey) { if (!storedKey) {
// generate key, encrypt and persist if none exists // generate key, encrypt and persist if none exists
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, { keyStore.persist(storageId, {
key: key, _id: util.UUID(),
iv: iv userId: emailAddress,
encryptedKey: key,
keyIV: iv
}); });
} else { } else {
// decrypt key // decrypt key
symmetricUserKey = aes.decrypt(encryptedKey.key, pbkdf2, encryptedKey.iv); symmetricUserKey = aes.decrypt(storedKey.encryptedKey, pbkdf2, storedKey.keyIV);
} }
callback(); callback();
}); });
}; };
/**
* Generates the user's asymmetric keypair from the user's secret key
*/
this.generateKeypair = function(naclCrypto) {
return naclCrypto.generateKeypair(symmetricUserKey);
};
/** /**
* Do PBKDF2 key derivation in a WebWorker thread * Do PBKDF2 key derivation in a WebWorker thread
*/ */

View File

@ -37,21 +37,22 @@ app.dao.CloudStorage = function(window, $) {
*/ */
this.persistUserSecretKey = function(emailAddress, callback) { this.persistUserSecretKey = function(emailAddress, callback) {
// fetch user's encrypted secret key from keychain/storage // fetch user's encrypted secret key from keychain/storage
var keyStore = new app.dao.LocalStorageDAO(window); var keyStore = new app.dao.LocalStorageDAO(window),
var storageId = emailAddress + '_encryptedSymmetricKey'; storageId = emailAddress + '_encryptedSymmetricKey',
var encryptedKey = keyStore.read(storageId); storedKey = keyStore.read(storageId);
var payload = { if (!storedKey) {
userId: emailAddress, callback({
encryptedKey: encryptedKey.key, error: 'err',
keyIV: encryptedKey.iv status: 'No key found in storage!'
}; });
return;
}
var uri = app.config.cloudUrl + '/keys/user/' + emailAddress;
$.ajax({ $.ajax({
url: uri, url: app.config.cloudUrl + '/secretkey/user/' + emailAddress + '/key/' + storedKey._id,
type: 'PUT', type: 'PUT',
data: JSON.stringify(payload), data: JSON.stringify(storedKey),
contentType: 'application/json', contentType: 'application/json',
success: function() { success: function() {
callback(); callback();
@ -70,50 +71,25 @@ app.dao.CloudStorage = function(window, $) {
*/ */
this.getUserSecretKey = function(emailAddress, callback, replaceCallback) { this.getUserSecretKey = function(emailAddress, callback, replaceCallback) {
// fetch user's encrypted secret key from keychain/storage // fetch user's encrypted secret key from keychain/storage
var self = this; var self = this,
var keyStore = new app.dao.LocalStorageDAO(window); keyStore = new app.dao.LocalStorageDAO(window),
var storageId = emailAddress + '_encryptedSymmetricKey'; storageId = emailAddress + '_encryptedSymmetricKey',
var storedKey = keyStore.read(storageId); storedKey = keyStore.read(storageId);
var uri = app.config.cloudUrl + '/keys/user/' + emailAddress;
$.ajax({ $.ajax({
url: uri, url: app.config.cloudUrl + '/secretkey/user/' + emailAddress,
type: 'GET', type: 'GET',
dataType: 'json', dataType: 'json',
success: function(fetchedKey) { success: function(keys) {
if ((!storedKey || !storedKey.key) && fetchedKey && fetchedKey.encryptedKey && fetchedKey.keyIV) { if (!keys || keys.length === 0) {
// no local key... persist fetched key callback({
keyStore.persist(storageId, { error: 'err',
key: fetchedKey.encryptedKey, status: 'Key not synced!'
iv: fetchedKey.keyIV
}); });
replaceCallback(); return;
} else if (storedKey && fetchedKey && (storedKey.key !== fetchedKey.encryptedKey || storedKey.iv !== fetchedKey.keyIV)) {
// local and fetched keys are not equal
if (confirm('Swap local key?')) {
// replace local key with fetched key
keyStore.persist(storageId, {
key: fetchedKey.encryptedKey,
iv: fetchedKey.keyIV
});
replaceCallback();
} else {
if (confirm('Swap cloud key?')) {
// upload local key to cloud
self.persistUserSecretKey(emailAddress, callback);
} else {
callback({
error: 'err',
status: 'Key not synced!'
});
}
}
} else {
// local and cloud keys are equal or cloud key is null
callback();
} }
handleKey(keys[0], callback);
}, },
error: function(xhr, textStatus, err) { error: function(xhr, textStatus, err) {
callback({ callback({
@ -122,6 +98,36 @@ app.dao.CloudStorage = function(window, $) {
}); });
} }
}); });
function handleKey(fetchedKey, callback) {
if ((!storedKey || !storedKey.encryptedKey) && fetchedKey && fetchedKey.encryptedKey && fetchedKey.keyIV) {
// no local key... persist fetched key
keyStore.persist(storageId, fetchedKey);
replaceCallback();
} else if (storedKey && fetchedKey && (storedKey.encryptedKey !== fetchedKey.encryptedKey || storedKey.keyIV !== fetchedKey.keyIV)) {
// local and fetched keys are not equal
if (confirm('Swap local key?')) {
// replace local key with fetched key
keyStore.persist(storageId, fetchedKey);
replaceCallback();
} else {
if (confirm('Swap cloud key?')) {
// upload local key to cloud
self.persistUserSecretKey(emailAddress, callback);
} else {
callback({
error: 'err',
status: 'Key not synced!'
});
}
}
} else {
// local and cloud keys are equal or cloud key is null
callback();
}
}
}; };
}; };

View File

@ -0,0 +1,24 @@
(function() {
'use strict';
app.model.PublicKey = Backbone.Model.extend({
defaults: {
_id: null,
userId: null,
publicKey: null
},
initialize: function() {}
});
app.model.PublicKeyCollection = Backbone.Collection.extend({
model: app.model.PublicKey,
findByName: function(key) {}
});
}());

View File

@ -0,0 +1,25 @@
(function() {
'use strict';
app.model.SecretKey = Backbone.Model.extend({
defaults: {
_id: null,
userId: null,
encryptedKey: null,
keyIV: null
},
initialize: function() {}
});
app.model.SecretKeyCollection = Backbone.Collection.extend({
model: app.model.SecretKey,
findByName: function(key) {}
});
}());

View File

@ -47,7 +47,7 @@
<script src="../js/app-config.js"></script> <script src="../js/app-config.js"></script>
<script> <script>
app.config.workerPath = '../js'; app.config.workerPath = '../js';
app.config.cloudUrl = 'http://localhost:8888'; //app.config.cloudUrl = 'http://localhost:8888';
</script> </script>
<script src="../js/model/email-model.js"></script> <script src="../js/model/email-model.js"></script>