From b6c3093945c60e640a3231fba5adaf2ca2d6e730 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Fri, 4 Aug 2017 10:50:31 -0700 Subject: [PATCH] SessionCipher: allow caller to provide fillMessageKeys limit If options.messageKeysLimit is provided by falsey, then we don't apply any limit at all. This can be used to set no limit for communications from your own devices. Why would you want that? People leave their laptops closed for weeks at a time and get this error, since their other devices are sending messages to it constantly: "Too many message keys for chain" And it seems to be really hard to fix once you're in this state. Sync messages no longer show up from the device that got into this state. FREEBIE --- dist/libsignal-protocol.js | 15 +++++++++++---- src/SessionCipher.js | 15 +++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/dist/libsignal-protocol.js b/dist/libsignal-protocol.js index 233f2c0..d726af4 100644 --- a/dist/libsignal-protocol.js +++ b/dist/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/src/SessionCipher.js b/src/SessionCipher.js index df7bf7e..df116b2 100644 --- a/src/SessionCipher.js +++ b/src/SessionCipher.js @@ -1,4 +1,11 @@ -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; } @@ -271,7 +278,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? } @@ -394,8 +401,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);