From 23611c31ae7460c949cff161db9de75b4e1b909a Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 9 Mar 2017 18:01:57 -0600 Subject: [PATCH] clear auth hash depending on version --- .../app/frontend/models/local/itemParams.js | 9 +++-- .../app/services/helpers/crypto.js | 7 +++- .../app/services/helpers/encryptionHelper.js | 15 +++++--- .../javascripts/app/services/syncManager.js | 34 +++++++++++++------ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/app/frontend/models/local/itemParams.js b/app/assets/javascripts/app/frontend/models/local/itemParams.js index b1f571fc9..07582fc42 100644 --- a/app/assets/javascripts/app/frontend/models/local/itemParams.js +++ b/app/assets/javascripts/app/frontend/models/local/itemParams.js @@ -33,10 +33,15 @@ class ItemParams { var params = {uuid: this.item.uuid, content_type: this.item.content_type, deleted: this.item.deleted, created_at: this.item.created_at}; if(this.keys) { - EncryptionHelper.encryptItem(itemCopy, this.keys, "002"); + let encryptionVersion = "001"; + EncryptionHelper.encryptItem(itemCopy, this.keys, encryptionVersion); params.content = itemCopy.content; params.enc_item_key = itemCopy.enc_item_key; - params.auth_hash = itemCopy.auth_hash; + if(encryptionVersion === "001") { + params.auth_hash = itemCopy.auth_hash; + } else { + params.auth_hash = null; + } } else { params.content = this.forExportFile ? itemCopy.createContentJSONFromProperties() : "000" + Neeto.crypto.base64(JSON.stringify(itemCopy.createContentJSONFromProperties())); diff --git a/app/assets/javascripts/app/services/helpers/crypto.js b/app/assets/javascripts/app/services/helpers/crypto.js index 682a1c282..3607d9054 100644 --- a/app/assets/javascripts/app/services/helpers/crypto.js +++ b/app/assets/javascripts/app/services/helpers/crypto.js @@ -30,7 +30,12 @@ class SNCrypto { } } - decryptText({ciphertextToAuth, contentCiphertext, encryptionKey, iv, authHash, authKey} = {}) { + decryptText({ciphertextToAuth, contentCiphertext, encryptionKey, iv, authHash, authKey} = {}, requiresAuth) { + if(requiresAuth && !authHash) { + console.error("Auth hash is required."); + return; + } + if(authHash) { var localAuthHash = Neeto.crypto.hmac256(ciphertextToAuth, authKey); if(authHash !== localAuthHash) { diff --git a/app/assets/javascripts/app/services/helpers/encryptionHelper.js b/app/assets/javascripts/app/services/helpers/encryptionHelper.js index 58838c240..24de8ec7a 100644 --- a/app/assets/javascripts/app/services/helpers/encryptionHelper.js +++ b/app/assets/javascripts/app/services/helpers/encryptionHelper.js @@ -47,7 +47,8 @@ class EncryptionHelper { ciphertextToAuth: string, iv: null, authHash: null, - encryptionKey: baseKey + encryptionKey: baseKey, + authKey: authKey } } else { let components = string.split(":"); @@ -66,12 +67,14 @@ class EncryptionHelper { static decryptItem(item, keys) { // decrypt encrypted key var encryptedItemKey = item.enc_item_key; - if(!encryptedItemKey.startsWith("002")) { + var requiresAuth = true; + if(encryptedItemKey.startsWith("002") === false) { // legacy encryption type, has no prefix encryptedItemKey = "001" + encryptedItemKey; + requiresAuth = false; } var keyParams = this.encryptionComponentsFromString(encryptedItemKey, keys.mk, keys.encryptionKey, keys.authKey); - var item_key = Neeto.crypto.decryptText(keyParams); + var item_key = Neeto.crypto.decryptText(keyParams, requiresAuth); if(!item_key) { return; @@ -81,8 +84,10 @@ class EncryptionHelper { var ek = Neeto.crypto.firstHalfOfKey(item_key); var ak = Neeto.crypto.secondHalfOfKey(item_key); var itemParams = this.encryptionComponentsFromString(item.content, ek, ek, ak); - var content = Neeto.crypto.decryptText(itemParams); - + if(!itemParams.authHash) { + itemParams.authHash = item.auth_hash; + } + var content = Neeto.crypto.decryptText(itemParams, true); item.content = content; } diff --git a/app/assets/javascripts/app/services/syncManager.js b/app/assets/javascripts/app/services/syncManager.js index c08668210..25d4e00f1 100644 --- a/app/assets/javascripts/app/services/syncManager.js +++ b/app/assets/javascripts/app/services/syncManager.js @@ -172,7 +172,7 @@ class SyncManager { params.sync_token = this.syncToken; params.cursor_token = this.cursorToken; - this.httpManager.postAbsolute(this.syncURL, params, function(response){ + var onSyncSuccess = function(response) { this.modelManager.clearDirtyItems(subItems); this.syncStatus.error = null; @@ -209,19 +209,33 @@ class SyncManager { } else { this.callQueuedCallbacksAndCurrent(callback, response); } + }.bind(this); - }.bind(this), function(response){ - console.log("Sync error: ", response); - var error = response ? response.error : {message: "Could not connect to server."}; + try { + this.httpManager.postAbsolute(this.syncURL, params, function(response){ - this.syncStatus.syncOpInProgress = false; - this.syncStatus.error = error; - this.writeItemsToLocalStorage(allDirtyItems, false, null); + try { + onSyncSuccess(response); + } catch(e) { + console.log("Caught sync success exception:", e); + } - this.$rootScope.$broadcast("sync:error", error); + }.bind(this), function(response){ + console.log("Sync error: ", response); + var error = response ? response.error : {message: "Could not connect to server."}; - this.callQueuedCallbacksAndCurrent(callback, {error: "Sync error"}); - }.bind(this)); + this.syncStatus.syncOpInProgress = false; + this.syncStatus.error = error; + this.writeItemsToLocalStorage(allDirtyItems, false, null); + + this.$rootScope.$broadcast("sync:error", error); + + this.callQueuedCallbacksAndCurrent(callback, {error: "Sync error"}); + }.bind(this)); + } + catch(e) { + console.log("Sync exception caught:", e); + } } handleUnsavedItemsResponse(unsaved) {