Add attachment digests

// FREEBIE
This commit is contained in:
lilia 2017-03-07 16:54:15 -08:00
parent f1a1a819ba
commit 43de0cc2ec
5 changed files with 65 additions and 10 deletions

View file

@ -36695,6 +36695,23 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ
var calculateMAC = libsignal.crypto.calculateMAC; var calculateMAC = libsignal.crypto.calculateMAC;
var verifyMAC = libsignal.crypto.verifyMAC; var verifyMAC = libsignal.crypto.verifyMAC;
function verifyDigest(data, theirDigest) {
return crypto.subtle.digest({name: 'SHA-256'}, data).then(function(ourDigest) {
var a = new Uint8Array(ourDigest);
var b = new Uint8Array(theirDigest);
var result = 0;
for (var i=0; i < theirDigest.byteLength; ++i) {
result = result | (a[i] ^ b[i]);
}
if (result !== 0) {
throw new Error('Bad digest');
}
});
}
function calculateDigest(data) {
return crypto.subtle.digest({name: 'SHA-256'}, data);
}
window.textsecure = window.textsecure || {}; window.textsecure = window.textsecure || {};
window.textsecure.crypto = { window.textsecure.crypto = {
// Decrypts message into a raw string // Decrypts message into a raw string
@ -36724,7 +36741,7 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ
}); });
}, },
decryptAttachment: function(encryptedBin, keys) { decryptAttachment: function(encryptedBin, keys, theirDigest) {
if (keys.byteLength != 64) { if (keys.byteLength != 64) {
throw new Error("Got invalid length attachment keys"); throw new Error("Got invalid length attachment keys");
} }
@ -36741,6 +36758,10 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ
var mac = encryptedBin.slice(encryptedBin.byteLength - 32, encryptedBin.byteLength); var mac = encryptedBin.slice(encryptedBin.byteLength - 32, encryptedBin.byteLength);
return verifyMAC(ivAndCiphertext, mac_key, mac, 32).then(function() { return verifyMAC(ivAndCiphertext, mac_key, mac, 32).then(function() {
if (theirDigest !== undefined) {
return verifyDigest(encryptedBin, theirDigest);
}
}).then(function() {
return decrypt(aes_key, ciphertext, iv); return decrypt(aes_key, ciphertext, iv);
}); });
}, },
@ -36764,7 +36785,9 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ
var encryptedBin = new Uint8Array(16 + ciphertext.byteLength + 32); var encryptedBin = new Uint8Array(16 + ciphertext.byteLength + 32);
encryptedBin.set(ivAndCiphertext); encryptedBin.set(ivAndCiphertext);
encryptedBin.set(new Uint8Array(mac), 16 + ciphertext.byteLength); encryptedBin.set(new Uint8Array(mac), 16 + ciphertext.byteLength);
return encryptedBin.buffer; return calculateDigest(encryptedBin.buffer).then(function(digest) {
return { ciphertext: encryptedBin.buffer, digest: digest };
});
}); });
}); });
}, },
@ -38539,10 +38562,12 @@ MessageReceiver.prototype.extend({
return textsecure.storage.get('blocked', []).indexOf(number) >= 0; return textsecure.storage.get('blocked', []).indexOf(number) >= 0;
}, },
handleAttachment: function(attachment) { handleAttachment: function(attachment) {
var digest = attachment.digest ? attachment.digest.toArrayBuffer() : undefined;
function decryptAttachment(encrypted) { function decryptAttachment(encrypted) {
return textsecure.crypto.decryptAttachment( return textsecure.crypto.decryptAttachment(
encrypted, encrypted,
attachment.key.toArrayBuffer() attachment.key.toArrayBuffer(),
digest
); );
} }
@ -39041,10 +39066,11 @@ MessageSender.prototype = {
proto.key = libsignal.crypto.getRandomBytes(64); proto.key = libsignal.crypto.getRandomBytes(64);
var iv = libsignal.crypto.getRandomBytes(16); var iv = libsignal.crypto.getRandomBytes(16);
return textsecure.crypto.encryptAttachment(attachment.data, proto.key, iv).then(function(encryptedBin) { return textsecure.crypto.encryptAttachment(attachment.data, proto.key, iv).then(function(result) {
return this.server.putAttachment(encryptedBin).then(function(id) { return this.server.putAttachment(result.ciphertext).then(function(id) {
proto.id = id; proto.id = id;
proto.contentType = attachment.contentType; proto.contentType = attachment.contentType;
proto.digest = result.digest;
return proto; return proto;
}); });
}.bind(this)); }.bind(this));

View file

@ -10,6 +10,23 @@
var calculateMAC = libsignal.crypto.calculateMAC; var calculateMAC = libsignal.crypto.calculateMAC;
var verifyMAC = libsignal.crypto.verifyMAC; var verifyMAC = libsignal.crypto.verifyMAC;
function verifyDigest(data, theirDigest) {
return crypto.subtle.digest({name: 'SHA-256'}, data).then(function(ourDigest) {
var a = new Uint8Array(ourDigest);
var b = new Uint8Array(theirDigest);
var result = 0;
for (var i=0; i < theirDigest.byteLength; ++i) {
result = result | (a[i] ^ b[i]);
}
if (result !== 0) {
throw new Error('Bad digest');
}
});
}
function calculateDigest(data) {
return crypto.subtle.digest({name: 'SHA-256'}, data);
}
window.textsecure = window.textsecure || {}; window.textsecure = window.textsecure || {};
window.textsecure.crypto = { window.textsecure.crypto = {
// Decrypts message into a raw string // Decrypts message into a raw string
@ -39,7 +56,7 @@
}); });
}, },
decryptAttachment: function(encryptedBin, keys) { decryptAttachment: function(encryptedBin, keys, theirDigest) {
if (keys.byteLength != 64) { if (keys.byteLength != 64) {
throw new Error("Got invalid length attachment keys"); throw new Error("Got invalid length attachment keys");
} }
@ -56,6 +73,10 @@
var mac = encryptedBin.slice(encryptedBin.byteLength - 32, encryptedBin.byteLength); var mac = encryptedBin.slice(encryptedBin.byteLength - 32, encryptedBin.byteLength);
return verifyMAC(ivAndCiphertext, mac_key, mac, 32).then(function() { return verifyMAC(ivAndCiphertext, mac_key, mac, 32).then(function() {
if (theirDigest !== undefined) {
return verifyDigest(encryptedBin, theirDigest);
}
}).then(function() {
return decrypt(aes_key, ciphertext, iv); return decrypt(aes_key, ciphertext, iv);
}); });
}, },
@ -79,7 +100,9 @@
var encryptedBin = new Uint8Array(16 + ciphertext.byteLength + 32); var encryptedBin = new Uint8Array(16 + ciphertext.byteLength + 32);
encryptedBin.set(ivAndCiphertext); encryptedBin.set(ivAndCiphertext);
encryptedBin.set(new Uint8Array(mac), 16 + ciphertext.byteLength); encryptedBin.set(new Uint8Array(mac), 16 + ciphertext.byteLength);
return encryptedBin.buffer; return calculateDigest(encryptedBin.buffer).then(function(digest) {
return { ciphertext: encryptedBin.buffer, digest: digest };
});
}); });
}); });
}, },

View file

@ -338,10 +338,12 @@ MessageReceiver.prototype.extend({
return textsecure.storage.get('blocked', []).indexOf(number) >= 0; return textsecure.storage.get('blocked', []).indexOf(number) >= 0;
}, },
handleAttachment: function(attachment) { handleAttachment: function(attachment) {
var digest = attachment.digest ? attachment.digest.toArrayBuffer() : undefined;
function decryptAttachment(encrypted) { function decryptAttachment(encrypted) {
return textsecure.crypto.decryptAttachment( return textsecure.crypto.decryptAttachment(
encrypted, encrypted,
attachment.key.toArrayBuffer() attachment.key.toArrayBuffer(),
digest
); );
} }

View file

@ -119,10 +119,11 @@ MessageSender.prototype = {
proto.key = libsignal.crypto.getRandomBytes(64); proto.key = libsignal.crypto.getRandomBytes(64);
var iv = libsignal.crypto.getRandomBytes(16); var iv = libsignal.crypto.getRandomBytes(16);
return textsecure.crypto.encryptAttachment(attachment.data, proto.key, iv).then(function(encryptedBin) { return textsecure.crypto.encryptAttachment(attachment.data, proto.key, iv).then(function(result) {
return this.server.putAttachment(encryptedBin).then(function(id) { return this.server.putAttachment(result.ciphertext).then(function(id) {
proto.id = id; proto.id = id;
proto.contentType = attachment.contentType; proto.contentType = attachment.contentType;
proto.digest = result.digest;
return proto; return proto;
}); });
}.bind(this)); }.bind(this));

View file

@ -120,6 +120,9 @@ message AttachmentPointer {
optional fixed64 id = 1; optional fixed64 id = 1;
optional string contentType = 2; optional string contentType = 2;
optional bytes key = 3; optional bytes key = 3;
optional uint32 size = 4;
optional bytes thumbnail = 5;
optional bytes digest = 6;
} }
message GroupContext { message GroupContext {