From e223db56d9cca4cc7533d0e017cb772662e447c5 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Fri, 4 Aug 2017 12:25:30 -0700 Subject: [PATCH] Set messageKeysLimit to unlimited if communicating with our devices (#1348) Set messageKeysLimit to unlimited if communicating with our devices FREEBIE --- js/libtextsecure.js | 51 +++++++++++++++++++++++++---- libtextsecure/libsignal-protocol.js | 15 ++++++--- libtextsecure/message_receiver.js | 24 ++++++++++++-- libtextsecure/outgoing_message.js | 12 ++++++- 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/js/libtextsecure.js b/js/libtextsecure.js index f7b9489983..2506b1d0bc 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -36169,7 +36169,14 @@ libsignal.SessionBuilder = function (storage, remoteAddress) { this.processV3 = builder.processV3.bind(builder); }; -function SessionCipher(storage, remoteAddress) { +function SessionCipher(storage, remoteAddress, options) { + options = options || {}; + + if (typeof options.messageKeysLimit === 'undefined') { + options.messageKeysLimit = 1000; + } + + this.messageKeysLimit = options.messageKeysLimit; this.remoteAddress = remoteAddress; this.storage = storage; } @@ -36442,7 +36449,7 @@ SessionCipher.prototype = { }); }, fillMessageKeys: function(chain, counter) { - if (Object.keys(chain.messageKeys).length >= 1000) { + if (this.messageKeysLimit && Object.keys(chain.messageKeys).length >= this.messageKeysLimit) { console.log("Too many message keys for chain"); return Promise.resolve(); // Stalker, much? } @@ -36565,8 +36572,8 @@ SessionCipher.prototype = { } }; -libsignal.SessionCipher = function(storage, remoteAddress) { - var cipher = new SessionCipher(storage, remoteAddress); +libsignal.SessionCipher = function(storage, remoteAddress, options) { + var cipher = new SessionCipher(storage, remoteAddress, options); // returns a Promise that resolves to a ciphertext object this.encrypt = cipher.encrypt.bind(cipher); @@ -38567,7 +38574,17 @@ MessageReceiver.prototype.extend({ decrypt: function(envelope, ciphertext) { var promise; var address = new libsignal.SignalProtocolAddress(envelope.source, envelope.sourceDevice); - var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address); + + var ourNumber = textsecure.storage.user.getNumber(); + var number = address.toString().split('.')[0]; + var options = {}; + + // No limit on message keys if we're communicating with our other devices + if (ourNumber === number) { + options.messageKeysLimit = false; + } + + var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address, options); switch(envelope.type) { case textsecure.protobuf.Envelope.Type.CIPHERTEXT: console.log('message from', this.getEnvelopeId(envelope)); @@ -38877,7 +38894,17 @@ MessageReceiver.prototype.extend({ }, tryMessageAgain: function(from, ciphertext) { var address = libsignal.SignalProtocolAddress.fromString(from); - var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address); + + var ourNumber = textsecure.storage.user.getNumber(); + var number = address.toString().split('.')[0]; + var options = {}; + + // No limit on message keys if we're communicating with our other devices + if (ourNumber === number) { + options.messageKeysLimit = false; + } + + var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address, options); console.log('retrying prekey whisper message'); return this.decryptPreKeyWhisperMessage(ciphertext, sessionCipher, address).then(function(plaintext) { var finalMessage = textsecure.protobuf.DataMessage.decode(plaintext); @@ -39153,7 +39180,17 @@ OutgoingMessage.prototype = { return Promise.all(deviceIds.map(function(deviceId) { var address = new libsignal.SignalProtocolAddress(number, deviceId); - var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address); + + var ourNumber = textsecure.storage.user.getNumber(); + var number = address.toString().split('.')[0]; + var options = {}; + + // No limit on message keys if we're communicating with our other devices + if (ourNumber === number) { + options.messageKeysLimit = false; + } + + var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address, options); ciphers[address.getDeviceId()] = sessionCipher; return sessionCipher.encrypt(plaintext).then(function(ciphertext) { return { diff --git a/libtextsecure/libsignal-protocol.js b/libtextsecure/libsignal-protocol.js index 233f2c0085..d726af42e7 100644 --- a/libtextsecure/libsignal-protocol.js +++ b/libtextsecure/libsignal-protocol.js @@ -36032,7 +36032,14 @@ libsignal.SessionBuilder = function (storage, remoteAddress) { this.processV3 = builder.processV3.bind(builder); }; -function SessionCipher(storage, remoteAddress) { +function SessionCipher(storage, remoteAddress, options) { + options = options || {}; + + if (typeof options.messageKeysLimit === 'undefined') { + options.messageKeysLimit = 1000; + } + + this.messageKeysLimit = options.messageKeysLimit; this.remoteAddress = remoteAddress; this.storage = storage; } @@ -36305,7 +36312,7 @@ SessionCipher.prototype = { }); }, fillMessageKeys: function(chain, counter) { - if (Object.keys(chain.messageKeys).length >= 1000) { + if (this.messageKeysLimit && Object.keys(chain.messageKeys).length >= this.messageKeysLimit) { console.log("Too many message keys for chain"); return Promise.resolve(); // Stalker, much? } @@ -36428,8 +36435,8 @@ SessionCipher.prototype = { } }; -libsignal.SessionCipher = function(storage, remoteAddress) { - var cipher = new SessionCipher(storage, remoteAddress); +libsignal.SessionCipher = function(storage, remoteAddress, options) { + var cipher = new SessionCipher(storage, remoteAddress, options); // returns a Promise that resolves to a ciphertext object this.encrypt = cipher.encrypt.bind(cipher); diff --git a/libtextsecure/message_receiver.js b/libtextsecure/message_receiver.js index 4470834159..c7b13e224e 100644 --- a/libtextsecure/message_receiver.js +++ b/libtextsecure/message_receiver.js @@ -325,7 +325,17 @@ MessageReceiver.prototype.extend({ decrypt: function(envelope, ciphertext) { var promise; var address = new libsignal.SignalProtocolAddress(envelope.source, envelope.sourceDevice); - var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address); + + var ourNumber = textsecure.storage.user.getNumber(); + var number = address.toString().split('.')[0]; + var options = {}; + + // No limit on message keys if we're communicating with our other devices + if (ourNumber === number) { + options.messageKeysLimit = false; + } + + var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address, options); switch(envelope.type) { case textsecure.protobuf.Envelope.Type.CIPHERTEXT: console.log('message from', this.getEnvelopeId(envelope)); @@ -635,7 +645,17 @@ MessageReceiver.prototype.extend({ }, tryMessageAgain: function(from, ciphertext) { var address = libsignal.SignalProtocolAddress.fromString(from); - var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address); + + var ourNumber = textsecure.storage.user.getNumber(); + var number = address.toString().split('.')[0]; + var options = {}; + + // No limit on message keys if we're communicating with our other devices + if (ourNumber === number) { + options.messageKeysLimit = false; + } + + var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address, options); console.log('retrying prekey whisper message'); return this.decryptPreKeyWhisperMessage(ciphertext, sessionCipher, address).then(function(plaintext) { var finalMessage = textsecure.protobuf.DataMessage.decode(plaintext); diff --git a/libtextsecure/outgoing_message.js b/libtextsecure/outgoing_message.js index a4b09b1707..f086759384 100644 --- a/libtextsecure/outgoing_message.js +++ b/libtextsecure/outgoing_message.js @@ -137,7 +137,17 @@ OutgoingMessage.prototype = { return Promise.all(deviceIds.map(function(deviceId) { var address = new libsignal.SignalProtocolAddress(number, deviceId); - var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address); + + var ourNumber = textsecure.storage.user.getNumber(); + var number = address.toString().split('.')[0]; + var options = {}; + + // No limit on message keys if we're communicating with our other devices + if (ourNumber === number) { + options.messageKeysLimit = false; + } + + var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address, options); ciphers[address.getDeviceId()] = sessionCipher; return sessionCipher.encrypt(plaintext).then(function(ciphertext) { return {