From 2fdb04872125733b775ac48f9f93e95054a481be Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Mon, 4 Dec 2017 15:28:38 -0800 Subject: [PATCH] NullMessage sent before verification sync should not be silent (#1857) --- js/libtextsecure.js | 56 +++++++++++++++++-------------- libtextsecure/message_receiver.js | 3 +- libtextsecure/sendmessage.js | 53 ++++++++++++++++------------- 3 files changed, 60 insertions(+), 52 deletions(-) diff --git a/js/libtextsecure.js b/js/libtextsecure.js index 930589e48..9879d5ec5 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -39085,8 +39085,7 @@ MessageReceiver.prototype.extend({ console.log('Got SyncMessage Request'); return this.removeFromCache(envelope); } else if (syncMessage.read && syncMessage.read.length) { - console.log('read messages', - 'from', envelope.source + '.' + envelope.sourceDevice); + console.log('read messages from', this.getEnvelopeId(envelope)); return this.handleRead(envelope, syncMessage.read); } else if (syncMessage.verified) { return this.handleVerified(envelope, syncMessage.verified); @@ -40095,39 +40094,44 @@ MessageSender.prototype = { syncVerification: function(destination, state, identityKey) { var myNumber = textsecure.storage.user.getNumber(); var myDevice = textsecure.storage.user.getDeviceId(); - if (myDevice != 1) { - // First send a null message to mask the sync message. - var nullMessage = new textsecure.protobuf.NullMessage(); + var now = Date.now(); + + if (myDevice === 1) { + return Promise.resolve(); + } - // Generate a random int from 1 and 512 + // First send a null message to mask the sync message. + var nullMessage = new textsecure.protobuf.NullMessage(); + + // Generate a random int from 1 and 512 var buffer = libsignal.crypto.getRandomBytes(1); - var paddingLength = (new Uint8Array(buffer)[0] & 0x1ff) + 1; + var paddingLength = (new Uint8Array(buffer)[0] & 0x1ff) + 1; - // Generate a random padding buffer of the chosen size - nullMessage.padding = libsignal.crypto.getRandomBytes(paddingLength); + // Generate a random padding buffer of the chosen size + nullMessage.padding = libsignal.crypto.getRandomBytes(paddingLength); - var contentMessage = new textsecure.protobuf.Content(); - contentMessage.nullMessage = nullMessage; + var contentMessage = new textsecure.protobuf.Content(); + contentMessage.nullMessage = nullMessage; - var silent = true; - return this.sendIndividualProto(destination, contentMessage, Date.now(), silent).then(function() { - var verified = new textsecure.protobuf.Verified(); - verified.state = state; - verified.destination = destination; - verified.identityKey = identityKey; - verified.nullMessage = nullMessage.padding; + // We want the NullMessage to look like a normal outgoing message; not silent + const promise = this.sendIndividualProto(destination, contentMessage, now); - var syncMessage = this.createSyncMessage(); - syncMessage.verified = verified; + return promise.then(function() { + var verified = new textsecure.protobuf.Verified(); + verified.state = state; + verified.destination = destination; + verified.identityKey = identityKey; + verified.nullMessage = nullMessage.padding; - var contentMessage = new textsecure.protobuf.Content(); - contentMessage.syncMessage = syncMessage; + var syncMessage = this.createSyncMessage(); + syncMessage.verified = verified; - return this.sendIndividualProto(myNumber, contentMessage, Date.now(), silent); - }.bind(this)); - } + var contentMessage = new textsecure.protobuf.Content(); + contentMessage.syncMessage = syncMessage; - return Promise.resolve(); + var silent = true; + return this.sendIndividualProto(myNumber, contentMessage, now, silent); + }.bind(this)); }, sendGroupProto: function(numbers, proto, timestamp) { diff --git a/libtextsecure/message_receiver.js b/libtextsecure/message_receiver.js index 62e881087..11434168a 100644 --- a/libtextsecure/message_receiver.js +++ b/libtextsecure/message_receiver.js @@ -618,8 +618,7 @@ MessageReceiver.prototype.extend({ console.log('Got SyncMessage Request'); return this.removeFromCache(envelope); } else if (syncMessage.read && syncMessage.read.length) { - console.log('read messages', - 'from', envelope.source + '.' + envelope.sourceDevice); + console.log('read messages from', this.getEnvelopeId(envelope)); return this.handleRead(envelope, syncMessage.read); } else if (syncMessage.verified) { return this.handleVerified(envelope, syncMessage.verified); diff --git a/libtextsecure/sendmessage.js b/libtextsecure/sendmessage.js index 7cc8d9268..216441f53 100644 --- a/libtextsecure/sendmessage.js +++ b/libtextsecure/sendmessage.js @@ -420,39 +420,44 @@ MessageSender.prototype = { syncVerification: function(destination, state, identityKey) { var myNumber = textsecure.storage.user.getNumber(); var myDevice = textsecure.storage.user.getDeviceId(); - if (myDevice != 1) { - // First send a null message to mask the sync message. - var nullMessage = new textsecure.protobuf.NullMessage(); + var now = Date.now(); + + if (myDevice === 1) { + return Promise.resolve(); + } + + // First send a null message to mask the sync message. + var nullMessage = new textsecure.protobuf.NullMessage(); - // Generate a random int from 1 and 512 + // Generate a random int from 1 and 512 var buffer = libsignal.crypto.getRandomBytes(1); - var paddingLength = (new Uint8Array(buffer)[0] & 0x1ff) + 1; + var paddingLength = (new Uint8Array(buffer)[0] & 0x1ff) + 1; - // Generate a random padding buffer of the chosen size - nullMessage.padding = libsignal.crypto.getRandomBytes(paddingLength); + // Generate a random padding buffer of the chosen size + nullMessage.padding = libsignal.crypto.getRandomBytes(paddingLength); - var contentMessage = new textsecure.protobuf.Content(); - contentMessage.nullMessage = nullMessage; + var contentMessage = new textsecure.protobuf.Content(); + contentMessage.nullMessage = nullMessage; - var silent = true; - return this.sendIndividualProto(destination, contentMessage, Date.now(), silent).then(function() { - var verified = new textsecure.protobuf.Verified(); - verified.state = state; - verified.destination = destination; - verified.identityKey = identityKey; - verified.nullMessage = nullMessage.padding; + // We want the NullMessage to look like a normal outgoing message; not silent + const promise = this.sendIndividualProto(destination, contentMessage, now); - var syncMessage = this.createSyncMessage(); - syncMessage.verified = verified; + return promise.then(function() { + var verified = new textsecure.protobuf.Verified(); + verified.state = state; + verified.destination = destination; + verified.identityKey = identityKey; + verified.nullMessage = nullMessage.padding; - var contentMessage = new textsecure.protobuf.Content(); - contentMessage.syncMessage = syncMessage; + var syncMessage = this.createSyncMessage(); + syncMessage.verified = verified; - return this.sendIndividualProto(myNumber, contentMessage, Date.now(), silent); - }.bind(this)); - } + var contentMessage = new textsecure.protobuf.Content(); + contentMessage.syncMessage = syncMessage; - return Promise.resolve(); + var silent = true; + return this.sendIndividualProto(myNumber, contentMessage, now, silent); + }.bind(this)); }, sendGroupProto: function(numbers, proto, timestamp) {