diff --git a/js/libtextsecure.js b/js/libtextsecure.js index 437d7e0f..62368839 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -34411,37 +34411,6 @@ Internal.protoText = function() { '}\n' + '' ; - protoText['protos/DeviceMessages.proto'] = - 'package textsecure;\n' + - 'message ProvisioningUuid {\n' + - ' optional string uuid = 1;\n' + - '}\n' + - 'message ProvisionEnvelope {\n' + - ' optional bytes publicKey = 1;\n' + - ' optional bytes body = 2; // Encrypted ProvisionMessage\n' + - '}\n' + - 'message ProvisionMessage {\n' + - ' optional bytes identityKeyPrivate = 2;\n' + - ' optional string number = 3;\n' + - ' optional string provisioningCode = 4;\n' + - '}\n' + - 'message DeviceControl {\n' + - ' enum Type {\n' + - ' UNKNOWN = 0;\n' + - ' NEW_DEVICE_REGISTERED = 1; // Requries only newDeviceId\n' + - ' SENT_MESSAGE = 2; // Requires only message\n' + - ' }\n' + - ' message MessageSent {\n' + - ' required string otherNumber = 1; // The destination account (ie phone #), not device\n' + - ' required uint64 timestamp = 2;\n' + - ' required bytes message = 3; // PushMessageContent\n' + - ' }\n' + - ' required Type type = 1;\n' + - ' optional uint32 newDeviceId = 2;\n' + - ' optional MessageSent message = 3;\n' + - '}\n' + -'' ; - return protoText; }(); /* vim: ts=4:sw=4 @@ -34469,15 +34438,10 @@ Internal.protobuf = function() { }; var protocolMessages = loadProtoBufs('WhisperTextProtocol.proto'); - var deviceMessages = loadProtoBufs('DeviceMessages.proto'); return { WhisperMessage : protocolMessages.WhisperMessage, - PreKeyWhisperMessage : protocolMessages.PreKeyWhisperMessage, - DeviceInit : deviceMessages.DeviceInit, - IdentityKey : deviceMessages.IdentityKey, - DeviceControl : deviceMessages.DeviceControl, - ProvisionMessage : deviceMessages.ProvisionMessage, + PreKeyWhisperMessage : protocolMessages.PreKeyWhisperMessage }; }(); @@ -34639,28 +34603,9 @@ Internal.SessionRecord = function() { throw e; } - var doDeleteSession = false; - if (session.indexInfo.closed != -1) { - doDeleteSession = (session.indexInfo.closed < (Date.now() - MESSAGE_LOST_THRESHOLD_MS)); + sessions[util.toString(session.indexInfo.baseKey)] = session; - if (!doDeleteSession) { - var keysLeft = false; - for (var key in session) { - if (key != "indexInfo" && key != "oldRatchetList" && key != "currentRatchet") { - keysLeft = true; - break; - } - } - doDeleteSession = !keysLeft; - console.log((doDeleteSession ? "Deleting " : "Not deleting ") + "closed session which has not yet timed out"); - } else - console.log("Deleting closed session due to timeout (created at " + session.indexInfo.closed + ")"); - } - - if (doDeleteSession) - delete sessions[util.toString(session.indexInfo.baseKey)]; - else - sessions[util.toString(session.indexInfo.baseKey)] = session; + this.removeOldSessions(); var openSessionRemaining = false; for (var key in sessions) @@ -34722,6 +34667,23 @@ Internal.SessionRecord = function() { session.oldRatchetList.splice(index, 1); } }, + removeOldSessions: function() { + // Retain only the last 20 sessions + var sessions = this._sessions; + var oldestBaseKey, oldestSession; + while (Object.keys(sessions).length > 20) { + for (var key in sessions) { + var session = sessions[key]; + if (session.indexInfo.closed > -1 && // session is closed + (!oldestSession || session.indexInfo.closed < oldestSession.indexInfo.closed)) { + oldestBaseKey = key; + oldestSession = session; + } + } + console.log("Deleting session closed at", session.indexInfo.closed); + delete this.sessions[util.toString(oldestBaseKey)]; + } + }, }; return SessionRecord; @@ -34812,7 +34774,7 @@ SessionBuilder.prototype = { record.updateSessionState(session, device.registrationId); return Promise.all([ this.storage.storeSession(address, record.serialize()), - this.storage.putIdentityKey(this.remoteAddress.getName(), record.identityKey) + this.storage.saveIdentity(this.remoteAddress.getName(), record.identityKey) ]); }.bind(this)); }.bind(this)); @@ -34869,7 +34831,7 @@ SessionBuilder.prototype = { // end of decryptWhisperMessage ... to ensure that the sender // actually holds the private keys for all reported pubkeys record.updateSessionState(new_session, message.registrationId); - return this.storage.putIdentityKey(this.remoteAddress.getName(), message.identityKey.toArrayBuffer()).then(function() { + return this.storage.saveIdentity(this.remoteAddress.getName(), message.identityKey.toArrayBuffer()).then(function() { return message.preKeyId; }); }.bind(this)); @@ -35389,7 +35351,6 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ })(); })(); - /* * vim: ts=4:sw=4:expandtab */ @@ -36810,7 +36771,7 @@ var TextSecureServer = (function() { // update our own identity key, which may have changed // if we're relinking after a reinstall on the master device - var putIdentity = textsecure.storage.protocol.putIdentityKey.bind( + var putIdentity = textsecure.storage.protocol.saveIdentity.bind( null, number, identityKeyPair.pubKey ); textsecure.storage.protocol.removeIdentityKey(number).then(putIdentity, putIdentity); diff --git a/js/models/conversations.js b/js/models/conversations.js index 34a02258..31d6c305 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -403,7 +403,7 @@ } return textsecure.storage.protocol.removeIdentityKey(number).then(function() { - return textsecure.storage.protocol.putIdentityKey(number, identityKey).then(function() { + return textsecure.storage.protocol.saveIdentity(number, identityKey).then(function() { var promise = Promise.resolve(); this.messageCollection.each(function(message) { if (message.hasKeyConflict(number)) { diff --git a/js/signal_protocol_store.js b/js/signal_protocol_store.js index 9ef385b9..82261175 100644 --- a/js/signal_protocol_store.js +++ b/js/signal_protocol_store.js @@ -275,7 +275,7 @@ }); }); }, - putIdentityKey: function(identifier, publicKey) { + saveIdentity: function(identifier, publicKey) { if (identifier === null || identifier === undefined) { throw new Error("Tried to put identity key for undefined/null key"); } diff --git a/libtextsecure/account_manager.js b/libtextsecure/account_manager.js index a216a1e8..57abc164 100644 --- a/libtextsecure/account_manager.js +++ b/libtextsecure/account_manager.js @@ -110,7 +110,7 @@ // update our own identity key, which may have changed // if we're relinking after a reinstall on the master device - var putIdentity = textsecure.storage.protocol.putIdentityKey.bind( + var putIdentity = textsecure.storage.protocol.saveIdentity.bind( null, number, identityKeyPair.pubKey ); textsecure.storage.protocol.removeIdentityKey(number).then(putIdentity, putIdentity); diff --git a/libtextsecure/libsignal-protocol.js b/libtextsecure/libsignal-protocol.js index 30ec6c9a..1d348e8f 100644 --- a/libtextsecure/libsignal-protocol.js +++ b/libtextsecure/libsignal-protocol.js @@ -34297,37 +34297,6 @@ Internal.protoText = function() { '}\n' + '' ; - protoText['protos/DeviceMessages.proto'] = - 'package textsecure;\n' + - 'message ProvisioningUuid {\n' + - ' optional string uuid = 1;\n' + - '}\n' + - 'message ProvisionEnvelope {\n' + - ' optional bytes publicKey = 1;\n' + - ' optional bytes body = 2; // Encrypted ProvisionMessage\n' + - '}\n' + - 'message ProvisionMessage {\n' + - ' optional bytes identityKeyPrivate = 2;\n' + - ' optional string number = 3;\n' + - ' optional string provisioningCode = 4;\n' + - '}\n' + - 'message DeviceControl {\n' + - ' enum Type {\n' + - ' UNKNOWN = 0;\n' + - ' NEW_DEVICE_REGISTERED = 1; // Requries only newDeviceId\n' + - ' SENT_MESSAGE = 2; // Requires only message\n' + - ' }\n' + - ' message MessageSent {\n' + - ' required string otherNumber = 1; // The destination account (ie phone #), not device\n' + - ' required uint64 timestamp = 2;\n' + - ' required bytes message = 3; // PushMessageContent\n' + - ' }\n' + - ' required Type type = 1;\n' + - ' optional uint32 newDeviceId = 2;\n' + - ' optional MessageSent message = 3;\n' + - '}\n' + -'' ; - return protoText; }(); /* vim: ts=4:sw=4 @@ -34355,15 +34324,10 @@ Internal.protobuf = function() { }; var protocolMessages = loadProtoBufs('WhisperTextProtocol.proto'); - var deviceMessages = loadProtoBufs('DeviceMessages.proto'); return { WhisperMessage : protocolMessages.WhisperMessage, - PreKeyWhisperMessage : protocolMessages.PreKeyWhisperMessage, - DeviceInit : deviceMessages.DeviceInit, - IdentityKey : deviceMessages.IdentityKey, - DeviceControl : deviceMessages.DeviceControl, - ProvisionMessage : deviceMessages.ProvisionMessage, + PreKeyWhisperMessage : protocolMessages.PreKeyWhisperMessage }; }(); @@ -34525,28 +34489,9 @@ Internal.SessionRecord = function() { throw e; } - var doDeleteSession = false; - if (session.indexInfo.closed != -1) { - doDeleteSession = (session.indexInfo.closed < (Date.now() - MESSAGE_LOST_THRESHOLD_MS)); + sessions[util.toString(session.indexInfo.baseKey)] = session; - if (!doDeleteSession) { - var keysLeft = false; - for (var key in session) { - if (key != "indexInfo" && key != "oldRatchetList" && key != "currentRatchet") { - keysLeft = true; - break; - } - } - doDeleteSession = !keysLeft; - console.log((doDeleteSession ? "Deleting " : "Not deleting ") + "closed session which has not yet timed out"); - } else - console.log("Deleting closed session due to timeout (created at " + session.indexInfo.closed + ")"); - } - - if (doDeleteSession) - delete sessions[util.toString(session.indexInfo.baseKey)]; - else - sessions[util.toString(session.indexInfo.baseKey)] = session; + this.removeOldSessions(); var openSessionRemaining = false; for (var key in sessions) @@ -34608,6 +34553,23 @@ Internal.SessionRecord = function() { session.oldRatchetList.splice(index, 1); } }, + removeOldSessions: function() { + // Retain only the last 20 sessions + var sessions = this._sessions; + var oldestBaseKey, oldestSession; + while (Object.keys(sessions).length > 20) { + for (var key in sessions) { + var session = sessions[key]; + if (session.indexInfo.closed > -1 && // session is closed + (!oldestSession || session.indexInfo.closed < oldestSession.indexInfo.closed)) { + oldestBaseKey = key; + oldestSession = session; + } + } + console.log("Deleting session closed at", session.indexInfo.closed); + delete this.sessions[util.toString(oldestBaseKey)]; + } + }, }; return SessionRecord; @@ -34698,7 +34660,7 @@ SessionBuilder.prototype = { record.updateSessionState(session, device.registrationId); return Promise.all([ this.storage.storeSession(address, record.serialize()), - this.storage.putIdentityKey(this.remoteAddress.getName(), record.identityKey) + this.storage.saveIdentity(this.remoteAddress.getName(), record.identityKey) ]); }.bind(this)); }.bind(this)); @@ -34755,7 +34717,7 @@ SessionBuilder.prototype = { // end of decryptWhisperMessage ... to ensure that the sender // actually holds the private keys for all reported pubkeys record.updateSessionState(new_session, message.registrationId); - return this.storage.putIdentityKey(this.remoteAddress.getName(), message.identityKey.toArrayBuffer()).then(function() { + return this.storage.saveIdentity(this.remoteAddress.getName(), message.identityKey.toArrayBuffer()).then(function() { return message.preKeyId; }); }.bind(this)); @@ -35274,4 +35236,4 @@ Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJ })(); -})(); +})(); \ No newline at end of file diff --git a/libtextsecure/test/in_memory_signal_protocol_store.js b/libtextsecure/test/in_memory_signal_protocol_store.js index 8cfe2561..3156230f 100644 --- a/libtextsecure/test/in_memory_signal_protocol_store.js +++ b/libtextsecure/test/in_memory_signal_protocol_store.js @@ -49,7 +49,7 @@ SignalProtocolStore.prototype = { resolve(this.get('identityKey' + identifier)); }.bind(this)); }, - putIdentityKey: function(identifier, identityKey) { + saveIdentity: function(identifier, identityKey) { if (identifier === null || identifier === undefined) throw new Error("Tried to put identity key for undefined/null key"); return new Promise(function(resolve) { diff --git a/libtextsecure/test/protocol_wrapper_test.js b/libtextsecure/test/protocol_wrapper_test.js index 7b8c5854..02d2de56 100644 --- a/libtextsecure/test/protocol_wrapper_test.js +++ b/libtextsecure/test/protocol_wrapper_test.js @@ -13,7 +13,7 @@ describe('Protocol Wrapper', function() { before(function(done) { localStorage.clear(); libsignal.KeyHelper.generateIdentityKeyPair().then(function(identityKey) { - return textsecure.storage.protocol.putIdentityKey(identifier, identityKey); + return textsecure.storage.protocol.saveIdentity(identifier, identityKey); }).then(done); }); describe('processPreKey', function() { diff --git a/libtextsecure/test/storage_test.js b/libtextsecure/test/storage_test.js index 40971916..e7bdd04e 100644 --- a/libtextsecure/test/storage_test.js +++ b/libtextsecure/test/storage_test.js @@ -31,7 +31,7 @@ describe("SignalProtocolStore", function() { }).then(done,done); }); it('stores identity keys', function(done) { - store.putIdentityKey(identifier, testKey.pubKey).then(function() { + store.saveIdentity(identifier, testKey.pubKey).then(function() { return store.loadIdentityKey(identifier).then(function(key) { assertEqualArrayBuffers(key, testKey.pubKey); }); @@ -39,7 +39,7 @@ describe("SignalProtocolStore", function() { }); it('returns whether a key is trusted', function(done) { var newIdentity = textsecure.crypto.getRandomBytes(33); - store.putIdentityKey(identifier, testKey.pubKey).then(function() { + store.saveIdentity(identifier, testKey.pubKey).then(function() { store.isTrustedIdentity(identifier, newIdentity).then(function(trusted) { if (trusted) { done(new Error('Allowed to overwrite identity key')); @@ -51,7 +51,7 @@ describe("SignalProtocolStore", function() { }); it('returns whether a key is untrusted', function(done) { var newIdentity = textsecure.crypto.getRandomBytes(33); - store.putIdentityKey(identifier, testKey.pubKey).then(function() { + store.saveIdentity(identifier, testKey.pubKey).then(function() { store.isTrustedIdentity(identifier, testKey.pubKey).then(function(trusted) { if (trusted) { done(); diff --git a/test/storage_test.js b/test/storage_test.js index f001e5f2..fb65a631 100644 --- a/test/storage_test.js +++ b/test/storage_test.js @@ -35,9 +35,9 @@ describe("SignalProtocolStore", function() { }).then(done,done); }); }); - describe('putIdentityKey', function() { + describe('saveIdentity', function() { it('stores identity keys', function(done) { - store.putIdentityKey(identifier, testKey.pubKey).then(function() { + store.saveIdentity(identifier, testKey.pubKey).then(function() { return store.loadIdentityKey(identifier).then(function(key) { assertEqualArrayBuffers(key, testKey.pubKey); }); @@ -45,8 +45,8 @@ describe("SignalProtocolStore", function() { }); it('rejects on key change', function(done) { var newIdentity = textsecure.crypto.getRandomBytes(33); - store.putIdentityKey(identifier, testKey.pubKey).then(function() { - store.putIdentityKey(identifier, newIdentity).then(function() { + store.saveIdentity(identifier, testKey.pubKey).then(function() { + store.saveIdentity(identifier, newIdentity).then(function() { done(new Error('Allowed to overwrite identity key')); }).catch(function(e) { assert(e instanceof Error); @@ -57,7 +57,7 @@ describe("SignalProtocolStore", function() { }); describe('isTrustedIdentity', function() { it('returns true if a key is trusted', function(done) { - store.putIdentityKey(identifier, testKey.pubKey).then(function() { + store.saveIdentity(identifier, testKey.pubKey).then(function() { store.isTrustedIdentity(identifier, testKey.pubKey).then(function(trusted) { if (trusted) { done(); @@ -69,7 +69,7 @@ describe("SignalProtocolStore", function() { }); it('returns false if a key is untrusted', function(done) { var newIdentity = textsecure.crypto.getRandomBytes(33); - store.putIdentityKey(identifier, testKey.pubKey).then(function() { + store.saveIdentity(identifier, testKey.pubKey).then(function() { store.isTrustedIdentity(identifier, newIdentity).then(function(trusted) { if (trusted) { done(new Error('Allowed to overwrite identity key'));