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/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/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; diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts index 87439cb82..7c125267c 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; + const sourceAsStr = StringUtils.decode(source, 'hex'); + if (sourceAsStr === ourNumber) { + window.console.info( + 'Dropping message from ourself after decryptForMediumGroup' + ); + return; + } const plaintext = await decryptWithSenderKey( ciphertext, keyIdx, groupId, - senderIdentity + 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(); 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; } } 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(); } 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