From 3103eaa192da6603f12a43c38f1446cef502b2fe Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 15 May 2014 00:26:37 -0400 Subject: [PATCH] Commit broken attachment loader (S3 403s I can't figure out...) --- js/api.js | 44 ++++++++++++++++++++++++++++++++++++++++---- js/crypto.js | 18 ++++++++++++++++-- js/helpers.js | 18 ++++++++++++++++-- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/js/api.js b/js/api.js index ddeb2efeb4..aa1f0ae5b4 100644 --- a/js/api.js +++ b/js/api.js @@ -29,6 +29,7 @@ URL_CALLS['devices'] = "/v1/devices"; URL_CALLS['keys'] = "/v1/keys"; URL_CALLS['push'] = "/v1/websocket"; URL_CALLS['messages'] = "/v1/messages"; +URL_CALLS['attachment'] = "/v1/attachments"; var API = new function() { @@ -116,9 +117,9 @@ var API = new function() { user : number, password : password, jsonData : { signalingKey : btoa(getString(signaling_key)), - supportsSms : false, - fetchesMessages : true, - registrationId: registrationId}, + supportsSms : false, + fetchesMessages : true, + registrationId : registrationId}, }).then(function(response) { if (success_callback !== undefined) success_callback(response); @@ -182,5 +183,40 @@ var API = new function() { do_auth : true, jsonData : jsonData, }); - } + }; + + this.getAttachment = function(id) { + return doAjax({ + call : 'attachment', + httpType : 'GET', + urlParameters : '/' + id, + do_auth : true, + }).then(function(response) { + console.log(response); + return new Promise(function(resolve, reject) { + $.ajax(response.location, { + type : "GET", + xhrFields: { + responseType: "arraybuffer" + }, + /*headers: { + "Content-Type": "application/octet-stream" + },*/ + + success : function(response, textStatus, jqXHR) { + resolve(response); + }, + + error : function(jqXHR, textStatus, errorThrown) { + var code = jqXHR.status; + if (code > 999 || code < 100) + code = -1; + var e = new Error(code); + e.name = "HTTPError"; + reject(e); + } + }); + }); + }); + }; }(); // API diff --git a/js/crypto.js b/js/crypto.js index 54dc29ce24..cc7e4f6bc1 100644 --- a/js/crypto.js +++ b/js/crypto.js @@ -538,10 +538,24 @@ window.crypto = (function() { var iv = decodedMessage.slice(1, 1 + 16); var ciphertext = decodedMessage.slice(1 + 16, decodedMessage.byteLength - 10); - var ivAndCipherText = decodedMessage.slice(1, decodedMessage.byteLength - 10); + var ivAndCiphertext = decodedMessage.slice(1, decodedMessage.byteLength - 10); var mac = decodedMessage.slice(decodedMessage.byteLength - 10, decodedMessage.byteLength); - return verifyMACWithVersionByte(ivAndCipherText, mac_key, mac).then(function() { + return verifyMACWithVersionByte(ivAndCiphertext, mac_key, mac).then(function() { + return window.crypto.subtle.decrypt({name: "AES-CBC", iv: iv}, aes_key, ciphertext); + }); + }; + + crypto.decryptAttachment = function(encryptedBin, keys) { + var aes_key = key.slice(0, 32); + var mac_key = key.slice(32, 64); + + var iv = encryptedBin.slice(0, 32); + var ciphertext = encryptedBin.slice(32, encryptedBin.byteLength - 32); + var ivAndCiphertext = encryptedBin.slice(0, encryptedBin.byteLength - 32); + var mac = encryptedBin.slice(encryptedBin.byteLength - 32, encryptedBin.byteLength); + + return verifyMAC(ivAndCiphertext, mac_key, mac).then(function() { return window.crypto.subtle.decrypt({name: "AES-CBC", iv: iv}, aes_key, ciphertext); }); }; diff --git a/js/helpers.js b/js/helpers.js index 60fb1c9672..9141d55b92 100644 --- a/js/helpers.js +++ b/js/helpers.js @@ -463,8 +463,22 @@ function subscribeToPush(message_callback) { console.log("Successfully decoded message with id: " + message.id); socket.send(JSON.stringify({type: 1, id: message.id})); return crypto.handleIncomingPushMessageProto(proto).then(function(decrypted) { - storeMessage(decrypted); - message_callback(decrypted); + var handleAttachment = function(attachment) { + return API.getAttachment(attachment.id).then(function(encryptedBin) { + return crypto.decryptAttachment(encryptedBin, attachment.key).then(function(decryptedBin) { + attachment.decrypted = decryptedBin; + }); + }); + }; + + var promises = []; + for (var i = 0; i < decrypted.message.attachments.length; i++) { + promises[i] = handleAttachment(decrypted.message.attachments[i]); + } + return Promise.all(promises).then(function() { + storeMessage(decrypted); + message_callback(decrypted); + }); }) }).catch(function(e) { console.log("Error handling incoming message: ");