From 0290c9a2bf2d4495e757231f4e0e355463a204fa Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Wed, 9 Sep 2020 15:01:05 +1000 Subject: [PATCH 1/7] fix segfault on app start with tray icon --- app/tray_icon.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/tray_icon.js b/app/tray_icon.js index f803ac6b0..88a32ac93 100644 --- a/app/tray_icon.js +++ b/app/tray_icon.js @@ -65,12 +65,12 @@ function createTrayIcon(getMainWindow, messages) { trayContextMenu = Menu.buildFromTemplate([ { id: 'toggleWindowVisibility', - label: messages[mainWindow.isVisible() ? 'hide' : 'show'].message, + label: messages[mainWindow.isVisible() ? 'appMenuHide' : 'show'].message, click: tray.toggleWindowVisibility, }, { id: 'quit', - label: messages.quit.message, + label: messages.appMenuQuit.message, click: app.quit.bind(app), }, ]); From a5474ac5e2e3c5ad8de6f0d338a7935715a76099 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Thu, 10 Sep 2020 09:06:05 +1000 Subject: [PATCH 2/7] fix read-receipt being sent onFocus on invalid conversation --- app/tray_icon.js | 3 ++- js/views/conversation_view.js | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/tray_icon.js b/app/tray_icon.js index 88a32ac93..7dfdf1fd2 100644 --- a/app/tray_icon.js +++ b/app/tray_icon.js @@ -65,7 +65,8 @@ function createTrayIcon(getMainWindow, messages) { trayContextMenu = Menu.buildFromTemplate([ { id: 'toggleWindowVisibility', - label: messages[mainWindow.isVisible() ? 'appMenuHide' : 'show'].message, + label: + messages[mainWindow.isVisible() ? 'appMenuHide' : 'show'].message, click: tray.toggleWindowVisibility, }, { diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 097556d16..3f3cb13c4 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -391,7 +391,10 @@ this.window.addEventListener('resize', this.onResize); this.onFocus = () => { - if (this.$el.css('display') !== 'none') { + if ( + this.$el.css('display') !== 'none' && + this.$el.css('display') !== '' + ) { this.markRead(); } }; From ec64ad80b4807f8f4e9a1937d9571a9c9ead1d0d Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 11 Sep 2020 16:21:48 +1000 Subject: [PATCH 3/7] rename LOKI_FRIEND_REQUEST to FALLBACK_MESSAGE --- js/modules/metadata/CiphertextMessage.js | 2 +- js/modules/metadata/SecretSessionCipher.js | 10 +++++----- protos/UnidentifiedDelivery.proto | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/modules/metadata/CiphertextMessage.js b/js/modules/metadata/CiphertextMessage.js index 1e2ddb6ea..20274e204 100644 --- a/js/modules/metadata/CiphertextMessage.js +++ b/js/modules/metadata/CiphertextMessage.js @@ -11,5 +11,5 @@ module.exports = { ENCRYPTED_MESSAGE_OVERHEAD: 53, - LOKI_FRIEND_REQUEST: 101, + FALLBACK_MESSAGE: 101, }; diff --git a/js/modules/metadata/SecretSessionCipher.js b/js/modules/metadata/SecretSessionCipher.js index 5f8d38495..3e0166c42 100644 --- a/js/modules/metadata/SecretSessionCipher.js +++ b/js/modules/metadata/SecretSessionCipher.js @@ -199,8 +199,8 @@ function _createUnidentifiedSenderMessageContentFromBuffer(serialized) { case TypeEnum.PREKEY_MESSAGE: type = CiphertextMessage.PREKEY_TYPE; break; - case TypeEnum.LOKI_FRIEND_REQUEST: - type = CiphertextMessage.LOKI_FRIEND_REQUEST; + case TypeEnum.FALLBACK_MESSAGE: + type = CiphertextMessage.FALLBACK_MESSAGE; break; default: throw new Error(`Unknown type: ${message.type}`); @@ -226,8 +226,8 @@ function _getProtoMessageType(type) { return TypeEnum.MESSAGE; case CiphertextMessage.PREKEY_TYPE: return TypeEnum.PREKEY_MESSAGE; - case CiphertextMessage.LOKI_FRIEND_REQUEST: - return TypeEnum.LOKI_FRIEND_REQUEST; + case CiphertextMessage.FALLBACK_MESSAGE: + return TypeEnum.FALLBACK_MESSAGE; default: throw new Error(`_getProtoMessageType: type '${type}' does not exist`); } @@ -481,7 +481,7 @@ SecretSessionCipher.prototype = { signalProtocolStore, sender ).decryptPreKeyWhisperMessage(message.content); - case CiphertextMessage.LOKI_FRIEND_REQUEST: + case CiphertextMessage.FALLBACK_MESSAGE: return new libloki.crypto.FallBackSessionCipher(sender).decrypt( message.content ); diff --git a/protos/UnidentifiedDelivery.proto b/protos/UnidentifiedDelivery.proto index 9b49b8c9b..ee7422d65 100644 --- a/protos/UnidentifiedDelivery.proto +++ b/protos/UnidentifiedDelivery.proto @@ -25,7 +25,7 @@ message UnidentifiedSenderMessage { enum Type { PREKEY_MESSAGE = 1; MESSAGE = 2; - LOKI_FRIEND_REQUEST = 3; + FALLBACK_MESSAGE = 3; } optional Type type = 1; From 7054268b14aff69dec7c6b8d570fba69cb57cdf6 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 11 Sep 2020 16:32:26 +1000 Subject: [PATCH 4/7] use source from decoded content and not envelope on ssk --- ts/receiver/contentMessage.ts | 19 +++++++++++++++---- ts/session/sending/MessageSender.ts | 13 +++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts index 87439cb82..4425a528c 100644 --- a/ts/receiver/contentMessage.ts +++ b/ts/receiver/contentMessage.ts @@ -18,6 +18,7 @@ import ByteBuffer from 'bytebuffer'; import { BlockedNumberController } from '../util/blockedNumberController'; import { decryptWithSenderKey } from '../session/medium_group/ratchet'; import { StringUtils } from '../session/utils'; +import { UserUtil } from '../util'; export async function handleContentMessage(envelope: EnvelopePlus) { const plaintext = await decrypt(envelope, envelope.content); @@ -46,8 +47,6 @@ async function decryptForMediumGroup( throw new Error(`Secret key is empty for group ${groupId}!`); } - const { senderIdentity } = envelope; - const { ciphertext: outerCiphertext, ephemeralKey, @@ -64,15 +63,27 @@ async function decryptForMediumGroup( outerCiphertext ); - const { ciphertext, keyIdx } = SignalService.MediumGroupCiphertext.decode( + const { + source, + ciphertext, + keyIdx, + } = SignalService.MediumGroupCiphertext.decode( new Uint8Array(mediumGroupCiphertext) ); + const ourNumber = (await UserUtil.getCurrentDevicePubKey()) as string; + + if (source === ourNumber) { + window.console.info( + 'Dropping message from ourself after decryptForMediumGroup' + ); + return; + } const plaintext = await decryptWithSenderKey( ciphertext, keyIdx, groupId, - senderIdentity + source ); return plaintext; diff --git a/ts/session/sending/MessageSender.ts b/ts/session/sending/MessageSender.ts index 1477e25ce..6d28cbcb9 100644 --- a/ts/session/sending/MessageSender.ts +++ b/ts/session/sending/MessageSender.ts @@ -39,7 +39,12 @@ export async function send( plainTextBuffer, encryption ); - const envelope = await buildEnvelope(envelopeType, timestamp, cipherText); + const envelope = await buildEnvelope( + envelopeType, + device.key, + timestamp, + cipherText + ); const data = wrapEnvelope(envelope); return pRetry( @@ -54,11 +59,15 @@ export async function send( async function buildEnvelope( type: SignalService.Envelope.Type, + sskSource: string | undefined, timestamp: number, content: Uint8Array ): Promise { let source: string | undefined; - if (type !== SignalService.Envelope.Type.UNIDENTIFIED_SENDER) { + + if (type === SignalService.Envelope.Type.MEDIUM_GROUP_CIPHERTEXT) { + source = sskSource; + } else if (type !== SignalService.Envelope.Type.UNIDENTIFIED_SENDER) { source = await UserUtil.getCurrentDevicePubKey(); } From 04063cd0fbdf0fb4f9a78abfa2ebb2d0f92c0497 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 15 Sep 2020 09:00:10 +1000 Subject: [PATCH 5/7] make medium group pubkey be in bytes rather than str --- protos/SignalService.proto | 2 +- ts/receiver/contentMessage.ts | 6 +++--- ts/session/crypto/MessageEncrypter.ts | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/protos/SignalService.proto b/protos/SignalService.proto index 54391519f..f7b76be2f 100644 --- a/protos/SignalService.proto +++ b/protos/SignalService.proto @@ -42,7 +42,7 @@ message Content { message MediumGroupCiphertext { optional bytes ciphertext = 1; - optional string source = 2; + optional bytes source = 2; optional uint32 keyIdx = 3; } diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts index 4425a528c..7c125267c 100644 --- a/ts/receiver/contentMessage.ts +++ b/ts/receiver/contentMessage.ts @@ -71,8 +71,8 @@ async function decryptForMediumGroup( new Uint8Array(mediumGroupCiphertext) ); const ourNumber = (await UserUtil.getCurrentDevicePubKey()) as string; - - if (source === ourNumber) { + const sourceAsStr = StringUtils.decode(source, 'hex'); + if (sourceAsStr === ourNumber) { window.console.info( 'Dropping message from ourself after decryptForMediumGroup' ); @@ -83,7 +83,7 @@ async function decryptForMediumGroup( ciphertext, keyIdx, groupId, - source + sourceAsStr ); return plaintext; diff --git a/ts/session/crypto/MessageEncrypter.ts b/ts/session/crypto/MessageEncrypter.ts index ba97ca7a2..3380cb205 100644 --- a/ts/session/crypto/MessageEncrypter.ts +++ b/ts/session/crypto/MessageEncrypter.ts @@ -4,6 +4,7 @@ import { UserUtil } from '../../util'; import { CipherTextObject } from '../../../libtextsecure/libsignal-protocol'; import { encryptWithSenderKey } from '../../session/medium_group/ratchet'; import { PubKey } from '../types'; +import { StringUtils } from '../utils'; /** * Add padding to a message buffer @@ -90,7 +91,7 @@ export async function encryptForMediumGroup( // We should include ciphertext idx in the message const content = SignalService.MediumGroupCiphertext.encode({ ciphertext, - source: ourKey, + source: new Uint8Array(StringUtils.encode(ourKey, 'hex')), keyIdx, }).finish(); From ff1c554e8a8d5b3fe765b724723fc49824422418 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 15 Sep 2020 09:40:50 +1000 Subject: [PATCH 6/7] make MediumGroupChatMessage share impl with ClosedGroupChatMessage --- .../data/mediumgroup/MediumGroupChatMessage.ts | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/ts/session/messages/outgoing/content/data/mediumgroup/MediumGroupChatMessage.ts b/ts/session/messages/outgoing/content/data/mediumgroup/MediumGroupChatMessage.ts index 1d5021c16..5cbeb8625 100644 --- a/ts/session/messages/outgoing/content/data/mediumgroup/MediumGroupChatMessage.ts +++ b/ts/session/messages/outgoing/content/data/mediumgroup/MediumGroupChatMessage.ts @@ -1,7 +1,6 @@ -import { SignalService } from '../../../../../../protobuf'; import { ChatMessage } from '../ChatMessage'; import { PubKey } from '../../../../../types'; -import { MediumGroupMessage } from './MediumGroupMessage'; +import { ClosedGroupChatMessage } from '../group/ClosedGroupChatMessage'; interface MediumGroupChatMessageParams { identifier?: string; @@ -9,21 +8,12 @@ interface MediumGroupChatMessageParams { chatMessage: ChatMessage; } -export class MediumGroupChatMessage extends MediumGroupMessage { - private readonly chatMessage: ChatMessage; - +export class MediumGroupChatMessage extends ClosedGroupChatMessage { constructor(params: MediumGroupChatMessageParams) { super({ - timestamp: params.chatMessage.timestamp, identifier: params.identifier ?? params.chatMessage.identifier, groupId: params.groupId, + chatMessage: params.chatMessage, }); - this.chatMessage = params.chatMessage; - } - - public dataProto(): SignalService.DataMessage { - const messageProto = this.chatMessage.dataProto(); - - return messageProto; } } From 28d2481389e2926892b614dd98cfd88462ea214f Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 15 Sep 2020 10:10:34 +1000 Subject: [PATCH 7/7] fix tests --- ts/test/session/unit/crypto/MessageEncrypter_test.ts | 2 +- ts/test/session/unit/sending/MessageSender_test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ts/test/session/unit/crypto/MessageEncrypter_test.ts b/ts/test/session/unit/crypto/MessageEncrypter_test.ts index eb85516e2..fc130eab7 100644 --- a/ts/test/session/unit/crypto/MessageEncrypter_test.ts +++ b/ts/test/session/unit/crypto/MessageEncrypter_test.ts @@ -12,7 +12,7 @@ import * as Ratchet from '../../../../session/medium_group/ratchet'; // tslint:disable-next-line: max-func-body-length describe('MessageEncrypter', () => { const sandbox = sinon.createSandbox(); - const ourNumber = 'ourNumber'; + const ourNumber = '0123456789abcdef'; beforeEach(() => { TestUtils.stubWindow('libsignal', { diff --git a/ts/test/session/unit/sending/MessageSender_test.ts b/ts/test/session/unit/sending/MessageSender_test.ts index 1b1411572..66ea30d39 100644 --- a/ts/test/session/unit/sending/MessageSender_test.ts +++ b/ts/test/session/unit/sending/MessageSender_test.ts @@ -36,7 +36,7 @@ describe('MessageSender', () => { }); describe('send', () => { - const ourNumber = 'ourNumber'; + const ourNumber = '0123456789abcdef'; let lokiMessageAPISendStub: sinon.SinonStub< [string, Uint8Array, number, number], Promise