From ba376d166e0c491633fe5ca7cf944ad0bbfef1c5 Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Thu, 18 Apr 2013 20:34:02 +0200 Subject: [PATCH] migrated cloudstorage to use aws service --- server.js | 5 +- src/js/app-config.js | 2 +- src/js/crypto/crypto.js | 19 +++--- src/js/dao/cloudstorage-dao.js | 104 +++++++++++++++++--------------- src/js/model/publickey-model.js | 24 ++++++++ src/js/model/secretkey-model.js | 25 ++++++++ test/integration/index.html | 2 +- 7 files changed, 114 insertions(+), 67 deletions(-) create mode 100644 src/js/model/publickey-model.js create mode 100644 src/js/model/secretkey-model.js diff --git a/server.js b/server.js index 77aac44..7364374 100644 --- a/server.js +++ b/server.js @@ -1,9 +1,6 @@ -/** - * A simple server for serving static files using node.js - */ +'use strict'; var express = require('express'), - fs = require('fs'), port, app, dev; port = process.env.PORT || 8585; diff --git a/src/js/app-config.js b/src/js/app-config.js index 20f9340..245b8ea 100644 --- a/src/js/app-config.js +++ b/src/js/app-config.js @@ -18,7 +18,7 @@ var app; // container for the application namespace * Global app configurations */ app.config = { - cloudUrl: 'https://whiteout-io.appspot.com', + cloudUrl: 'http://storage.whiteout.io', symKeySize: 128, symIvSize: 104, asymKeySize: 2048, diff --git a/src/js/crypto/crypto.js b/src/js/crypto/crypto.js index 78e95cf..c33fc61 100644 --- a/src/js/crypto/crypto.js +++ b/src/js/crypto/crypto.js @@ -23,34 +23,29 @@ app.crypto.Crypto = function(window, util) { // fetch user's encrypted secret key from keychain/storage var keyStore = new app.dao.LocalStorageDAO(window); var storageId = emailAddress + '_encryptedSymmetricKey'; - var encryptedKey = keyStore.read(storageId); + var storedKey = keyStore.read(storageId); // check if key exists - if (!encryptedKey) { + if (!storedKey) { // generate key, encrypt and persist if none exists symmetricUserKey = util.random(keySize); var iv = util.random(ivSize); var key = aes.encrypt(symmetricUserKey, pbkdf2, iv); keyStore.persist(storageId, { - key: key, - iv: iv + _id: util.UUID(), + userId: emailAddress, + encryptedKey: key, + keyIV: iv }); } else { // decrypt key - symmetricUserKey = aes.decrypt(encryptedKey.key, pbkdf2, encryptedKey.iv); + symmetricUserKey = aes.decrypt(storedKey.encryptedKey, pbkdf2, storedKey.keyIV); } 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 */ diff --git a/src/js/dao/cloudstorage-dao.js b/src/js/dao/cloudstorage-dao.js index 3394e45..3bb1d22 100644 --- a/src/js/dao/cloudstorage-dao.js +++ b/src/js/dao/cloudstorage-dao.js @@ -37,21 +37,22 @@ app.dao.CloudStorage = function(window, $) { */ this.persistUserSecretKey = function(emailAddress, callback) { // fetch user's encrypted secret key from keychain/storage - var keyStore = new app.dao.LocalStorageDAO(window); - var storageId = emailAddress + '_encryptedSymmetricKey'; - var encryptedKey = keyStore.read(storageId); + var keyStore = new app.dao.LocalStorageDAO(window), + storageId = emailAddress + '_encryptedSymmetricKey', + storedKey = keyStore.read(storageId); - var payload = { - userId: emailAddress, - encryptedKey: encryptedKey.key, - keyIV: encryptedKey.iv - }; + if (!storedKey) { + callback({ + error: 'err', + status: 'No key found in storage!' + }); + return; + } - var uri = app.config.cloudUrl + '/keys/user/' + emailAddress; $.ajax({ - url: uri, + url: app.config.cloudUrl + '/secretkey/user/' + emailAddress + '/key/' + storedKey._id, type: 'PUT', - data: JSON.stringify(payload), + data: JSON.stringify(storedKey), contentType: 'application/json', success: function() { callback(); @@ -70,50 +71,25 @@ app.dao.CloudStorage = function(window, $) { */ this.getUserSecretKey = function(emailAddress, callback, replaceCallback) { // fetch user's encrypted secret key from keychain/storage - var self = this; - var keyStore = new app.dao.LocalStorageDAO(window); - var storageId = emailAddress + '_encryptedSymmetricKey'; - var storedKey = keyStore.read(storageId); + var self = this, + keyStore = new app.dao.LocalStorageDAO(window), + storageId = emailAddress + '_encryptedSymmetricKey', + storedKey = keyStore.read(storageId); - var uri = app.config.cloudUrl + '/keys/user/' + emailAddress; $.ajax({ - url: uri, + url: app.config.cloudUrl + '/secretkey/user/' + emailAddress, type: 'GET', dataType: 'json', - success: function(fetchedKey) { - if ((!storedKey || !storedKey.key) && fetchedKey && fetchedKey.encryptedKey && fetchedKey.keyIV) { - // no local key... persist fetched key - keyStore.persist(storageId, { - key: fetchedKey.encryptedKey, - iv: fetchedKey.keyIV + success: function(keys) { + if (!keys || keys.length === 0) { + callback({ + error: 'err', + status: 'Key not synced!' }); - replaceCallback(); - - } 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(); + return; } + + handleKey(keys[0], callback); }, error: function(xhr, textStatus, err) { 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(); + } + } }; }; \ No newline at end of file diff --git a/src/js/model/publickey-model.js b/src/js/model/publickey-model.js new file mode 100644 index 0000000..9aeb46c --- /dev/null +++ b/src/js/model/publickey-model.js @@ -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) {} + + }); + +}()); \ No newline at end of file diff --git a/src/js/model/secretkey-model.js b/src/js/model/secretkey-model.js new file mode 100644 index 0000000..78991ed --- /dev/null +++ b/src/js/model/secretkey-model.js @@ -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) {} + + }); + +}()); \ No newline at end of file diff --git a/test/integration/index.html b/test/integration/index.html index 2b1be85..9d90095 100644 --- a/test/integration/index.html +++ b/test/integration/index.html @@ -47,7 +47,7 @@