diff --git a/ts/session/crypto/MessageEncrypter.ts b/ts/session/crypto/MessageEncrypter.ts index ded12577b..9898d7f92 100644 --- a/ts/session/crypto/MessageEncrypter.ts +++ b/ts/session/crypto/MessageEncrypter.ts @@ -2,6 +2,7 @@ import { EncryptionType } from '../types/EncryptionType'; import { SignalService } from '../../protobuf'; import { UserUtil } from '../../util'; import { CipherTextObject } from '../../../libtextsecure/libsignal-protocol'; +import { PubKey } from '../types'; /** * Add padding to a message buffer @@ -31,13 +32,13 @@ function getPaddedMessageLength(originalLength: number): number { /** * Encrypt `plainTextBuffer` with given `encryptionType` for `device`. * - * @param device The device to encrypt for. + * @param device The device `PubKey` to encrypt for. * @param plainTextBuffer The unpadded plaintext buffer. * @param encryptionType The type of encryption. * @returns The envelope type and the base64 encoded cipher text */ export async function encrypt( - device: string, + device: PubKey, plainTextBuffer: Uint8Array, encryptionType: EncryptionType ): Promise<{ @@ -45,7 +46,7 @@ export async function encrypt( cipherText: Uint8Array; }> { const plainText = padPlainTextBuffer(plainTextBuffer); - const address = new window.libsignal.SignalProtocolAddress(device, 1); + const address = new window.libsignal.SignalProtocolAddress(device.key, 1); if (encryptionType === EncryptionType.MediumGroup) { // TODO: Do medium group stuff here @@ -68,7 +69,7 @@ export async function encrypt( } async function encryptUsingSealedSender( - device: string, + device: PubKey, innerCipherText: CipherTextObject ): Promise<{ envelopeType: SignalService.Envelope.Type; @@ -88,7 +89,7 @@ async function encryptUsingSealedSender( window.textsecure.storage.protocol ); const cipherTextBuffer = await cipher.encrypt( - device, + device.key, certificate, innerCipherText ); diff --git a/ts/session/protocols/SessionProtocol.ts b/ts/session/protocols/SessionProtocol.ts index 8e58f465c..dcb584a19 100644 --- a/ts/session/protocols/SessionProtocol.ts +++ b/ts/session/protocols/SessionProtocol.ts @@ -276,7 +276,7 @@ export class SessionProtocol { } /** - * timestamp undefined to remove the key/value pair, otherwise updates the processed timestamp and writes to DB + * Timestamp undefined to remove the `key`/`value` pair, otherwise updates the processed timestamp and writes to database */ private static async updateProcessedSessionTimestamp( device: string, diff --git a/ts/session/sending/MessageSender.ts b/ts/session/sending/MessageSender.ts index 5af656a94..d138cba81 100644 --- a/ts/session/sending/MessageSender.ts +++ b/ts/session/sending/MessageSender.ts @@ -6,6 +6,7 @@ import { SignalService } from '../../protobuf'; import { UserUtil } from '../../util'; import { MessageEncrypter } from '../crypto'; import pRetry from 'p-retry'; +import { PubKey } from '../types'; // ================ Regular ================ @@ -31,7 +32,8 @@ export async function send( throw new Error('lokiMessageAPI is not initialized.'); } - const { device, plainTextBuffer, encryption, timestamp, ttl } = message; + const device = PubKey.cast(message.device); + const { plainTextBuffer, encryption, timestamp, ttl } = message; const { envelopeType, cipherText } = await MessageEncrypter.encrypt( device, plainTextBuffer, @@ -41,7 +43,8 @@ export async function send( const data = wrapEnvelope(envelope); return pRetry( - async () => window.lokiMessageAPI.sendMessage(device, data, timestamp, ttl), + async () => + window.lokiMessageAPI.sendMessage(device.key, data, timestamp, ttl), { retries: Math.max(attempts - 1, 0), factor: 1, diff --git a/ts/test/session/crypto/MessageEncrypter_test.ts b/ts/test/session/crypto/MessageEncrypter_test.ts index d46b80fae..ecf534690 100644 --- a/ts/test/session/crypto/MessageEncrypter_test.ts +++ b/ts/test/session/crypto/MessageEncrypter_test.ts @@ -49,7 +49,7 @@ describe('MessageEncrypter', () => { it('should throw an error', async () => { const data = crypto.randomBytes(10); const promise = MessageEncrypter.encrypt( - '1', + TestUtils.generateFakePubKey(), data, EncryptionType.MediumGroup ); @@ -66,7 +66,11 @@ describe('MessageEncrypter', () => { Stubs.FallBackSessionCipherStub.prototype, 'encrypt' ); - await MessageEncrypter.encrypt('1', data, EncryptionType.Fallback); + await MessageEncrypter.encrypt( + TestUtils.generateFakePubKey(), + data, + EncryptionType.Fallback + ); expect(spy.called).to.equal( true, 'FallbackSessionCipher.encrypt should be called.' @@ -79,7 +83,11 @@ describe('MessageEncrypter', () => { Stubs.FallBackSessionCipherStub.prototype, 'encrypt' ); - await MessageEncrypter.encrypt('1', data, EncryptionType.Fallback); + await MessageEncrypter.encrypt( + TestUtils.generateFakePubKey(), + data, + EncryptionType.Fallback + ); const paddedData = MessageEncrypter.padPlainTextBuffer(data); const firstArgument = new Uint8Array(spy.args[0][0]); @@ -89,7 +97,7 @@ describe('MessageEncrypter', () => { it('should return an UNIDENTIFIED SENDER envelope type', async () => { const data = crypto.randomBytes(10); const result = await MessageEncrypter.encrypt( - '1', + TestUtils.generateFakePubKey(), data, EncryptionType.Fallback ); @@ -103,7 +111,11 @@ describe('MessageEncrypter', () => { it('should call SessionCipher encrypt', async () => { const data = crypto.randomBytes(10); const spy = sandbox.spy(Stubs.SessionCipherStub.prototype, 'encrypt'); - await MessageEncrypter.encrypt('1', data, EncryptionType.Signal); + await MessageEncrypter.encrypt( + TestUtils.generateFakePubKey(), + data, + EncryptionType.Signal + ); expect(spy.called).to.equal( true, 'SessionCipher.encrypt should be called.' @@ -113,7 +125,11 @@ describe('MessageEncrypter', () => { it('should pass the padded message body to encrypt', async () => { const data = crypto.randomBytes(10); const spy = sandbox.spy(Stubs.SessionCipherStub.prototype, 'encrypt'); - await MessageEncrypter.encrypt('1', data, EncryptionType.Signal); + await MessageEncrypter.encrypt( + TestUtils.generateFakePubKey(), + data, + EncryptionType.Signal + ); const paddedData = MessageEncrypter.padPlainTextBuffer(data); const firstArgument = new Uint8Array(spy.args[0][0]); @@ -123,7 +139,7 @@ describe('MessageEncrypter', () => { it('should return an UNIDENTIFIED SENDER envelope type', async () => { const data = crypto.randomBytes(10); const result = await MessageEncrypter.encrypt( - '1', + TestUtils.generateFakePubKey(), data, EncryptionType.Signal ); @@ -142,7 +158,9 @@ describe('MessageEncrypter', () => { Stubs.SecretSessionCipherStub.prototype, 'encrypt' ); - await MessageEncrypter.encrypt('user', crypto.randomBytes(10), type); + + const user = TestUtils.generateFakePubKey(); + await MessageEncrypter.encrypt(user, crypto.randomBytes(10), type); const args = spy.args[0]; const [device, certificate] = args; @@ -152,7 +170,7 @@ describe('MessageEncrypter', () => { senderDevice: 1, }); - expect(device).to.equal('user'); + expect(device).to.equal(user.key); expect(certificate.toJSON()).to.deep.equal( expectedCertificate.toJSON() ); diff --git a/ts/test/session/sending/MessageSender_test.ts b/ts/test/session/sending/MessageSender_test.ts index b71c508a5..1a6e33ee0 100644 --- a/ts/test/session/sending/MessageSender_test.ts +++ b/ts/test/session/sending/MessageSender_test.ts @@ -10,6 +10,7 @@ import { MessageEncrypter } from '../../../session/crypto'; import { SignalService } from '../../../protobuf'; import { OpenGroupMessage } from '../../../session/messages/outgoing'; import { EncryptionType } from '../../../session/types/EncryptionType'; +import { PubKey } from '../../../session/types'; describe('MessageSender', () => { const sandbox = sinon.createSandbox(); @@ -40,7 +41,7 @@ describe('MessageSender', () => { [string, Uint8Array, number, number], Promise >; - let encryptStub: sinon.SinonStub<[string, Uint8Array, EncryptionType]>; + let encryptStub: sinon.SinonStub<[PubKey, Uint8Array, EncryptionType]>; beforeEach(() => { // We can do this because LokiMessageAPI has a module export in it @@ -63,7 +64,7 @@ describe('MessageSender', () => { describe('retry', () => { const rawMessage = { identifier: '1', - device: '0', + device: TestUtils.generateFakePubKey().key, plainTextBuffer: crypto.randomBytes(10), encryption: EncryptionType.Signal, timestamp: Date.now(), @@ -109,7 +110,7 @@ describe('MessageSender', () => { }); it('should pass the correct values to lokiMessageAPI', async () => { - const device = '0'; + const device = TestUtils.generateFakePubKey().key; const timestamp = Date.now(); const ttl = 100; @@ -133,12 +134,13 @@ describe('MessageSender', () => { SignalService.Envelope.Type.CIPHERTEXT; // This test assumes the encryption stub returns the plainText passed into it. + const device = TestUtils.generateFakePubKey().key; const plainTextBuffer = crypto.randomBytes(10); const timestamp = Date.now(); await MessageSender.send({ identifier: '1', - device: '0', + device, plainTextBuffer, encryption: EncryptionType.Signal, timestamp, @@ -172,12 +174,13 @@ describe('MessageSender', () => { SignalService.Envelope.Type.UNIDENTIFIED_SENDER; // This test assumes the encryption stub returns the plainText passed into it. + const device = TestUtils.generateFakePubKey().key; const plainTextBuffer = crypto.randomBytes(10); const timestamp = Date.now(); await MessageSender.send({ identifier: '1', - device: '0', + device, plainTextBuffer, encryption: EncryptionType.Signal, timestamp,