From 7b96aba1bf2a9e98897ed81baa0c5082e7612f1e Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 7 May 2021 10:16:15 +1000 Subject: [PATCH 1/3] padd Message buffer for all outgoing messages (even opengroupv2) --- app/tray_icon.js | 8 +++- .../session/SessionPasswordModal.tsx | 4 +- ts/receiver/contentMessage.ts | 23 ++-------- ts/receiver/receiver.ts | 6 ++- ts/session/crypto/MessageEncrypter.ts | 26 +---------- ts/session/crypto/MessagePadding.ts | 45 +++++++++++++++++++ ts/session/sending/MessageSender.ts | 5 ++- ts/session/utils/Attachments.ts | 1 + .../unit/crypto/MessageEncrypter_test.ts | 3 +- 9 files changed, 69 insertions(+), 52 deletions(-) create mode 100644 ts/session/crypto/MessagePadding.ts diff --git a/app/tray_icon.js b/app/tray_icon.js index 503174882..66489e6fd 100644 --- a/app/tray_icon.js +++ b/app/tray_icon.js @@ -9,7 +9,13 @@ let tray = null; function createTrayIcon(getMainWindow, messages) { // A smaller icon is needed on macOS const iconSize = process.platform === 'darwin' ? '16' : '256'; - const iconNoNewMessages = path.join(__dirname, '..', 'images', 'session', `session_icon_${iconSize}.png`); + const iconNoNewMessages = path.join( + __dirname, + '..', + 'images', + 'session', + `session_icon_${iconSize}.png` + ); tray = new Tray(iconNoNewMessages); diff --git a/ts/components/session/SessionPasswordModal.tsx b/ts/components/session/SessionPasswordModal.tsx index bbe1bde16..24c2dd72a 100644 --- a/ts/components/session/SessionPasswordModal.tsx +++ b/ts/components/session/SessionPasswordModal.tsx @@ -208,9 +208,7 @@ class SessionPasswordModalInner extends React.Component { return; } - const isValidWithStoredInDB = Boolean( - await this.validatePasswordHash(oldPassword) - ); + const isValidWithStoredInDB = Boolean(await this.validatePasswordHash(oldPassword)); if (!isValidWithStoredInDB) { this.setState({ error: window.i18n('changePasswordInvalid'), diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts index 137cb4dc2..06666d7e0 100644 --- a/ts/receiver/contentMessage.ts +++ b/ts/receiver/contentMessage.ts @@ -17,6 +17,7 @@ import { KeyPairRequestManager } from './keyPairRequestManager'; import { requestEncryptionKeyPair } from '../session/group'; import { handleConfigurationMessage } from './configMessage'; import { ConversationTypeEnum } from '../models/conversation'; +import { removeMessagePadding } from '../session/crypto/MessagePadding'; export async function handleContentMessage(envelope: EnvelopePlus) { try { @@ -94,7 +95,7 @@ async function decryptForClosedGroup(envelope: EnvelopePlus, ciphertext: ArrayBu } window.log.info('ClosedGroup Message decrypted successfully with keyIndex:', keyIndex); - return unpad(decryptedContent); + return removeMessagePadding(decryptedContent); } catch (e) { /** * If an error happened during the decoding, @@ -130,7 +131,7 @@ async function decryptForClosedGroup(envelope: EnvelopePlus, ciphertext: ArrayBu * or a message sent to a closed group. * * We do not unpad the result here, as in the case of the keypair wrapper, there is not padding. - * Instead, it is the called who needs to unpad() the content. + * Instead, it is the called who needs to removeMessagePadding() the content. */ export async function decryptWithSessionProtocol( envelope: EnvelopePlus, @@ -191,22 +192,6 @@ export async function decryptWithSessionProtocol( return plaintext; } -export function unpad(paddedData: ArrayBuffer): ArrayBuffer { - const paddedPlaintext = new Uint8Array(paddedData); - - for (let i = paddedPlaintext.length - 1; i >= 0; i -= 1) { - if (paddedPlaintext[i] === 0x80) { - const plaintext = new Uint8Array(i); - plaintext.set(paddedPlaintext.subarray(0, i)); - return plaintext.buffer; - } else if (paddedPlaintext[i] !== 0x00) { - throw new Error('Invalid padding'); - } - } - - throw new Error('Invalid padding'); -} - export async function isBlocked(number: string) { return BlockedNumberController.isBlockedAsync(number); } @@ -227,7 +212,7 @@ async function decryptUnidentifiedSender( ); // keep the await so the try catch works as expected const retSessionProtocol = await decryptWithSessionProtocol(envelope, ciphertext, ecKeyPair); - return unpad(retSessionProtocol); + return removeMessagePadding(retSessionProtocol); } catch (e) { window.log.warn('decryptWithSessionProtocol for unidentified message throw:', e); return null; diff --git a/ts/receiver/receiver.ts b/ts/receiver/receiver.ts index b4590e6dc..fe85f4309 100644 --- a/ts/receiver/receiver.ts +++ b/ts/receiver/receiver.ts @@ -9,7 +9,7 @@ import { processMessage } from '../session/snode_api/swarmPolling'; import { onError } from './errors'; // innerHandleContentMessage is only needed because of code duplication in handleDecryptedEnvelope... -import { handleContentMessage, innerHandleContentMessage, unpad } from './contentMessage'; +import { handleContentMessage, innerHandleContentMessage } from './contentMessage'; import _, { noop } from 'lodash'; export { processMessage }; @@ -36,6 +36,7 @@ import { OpenGroupMessageV2 } from '../opengroup/opengroupV2/OpenGroupMessageV2' import { OpenGroupRequestCommonType } from '../opengroup/opengroupV2/ApiUtil'; import { handleMessageJob } from './queuedJob'; import { fromBase64ToArray } from '../session/utils/String'; +import { removeMessagePadding } from '../session/crypto/MessagePadding'; // TODO: check if some of these exports no longer needed @@ -315,7 +316,8 @@ export async function handleOpenGroupV2Message( return; } - const dataUint = new Uint8Array(unpad(fromBase64ToArray(base64EncodedData))); + // Note: opengroup messages are not padded + const dataUint = new Uint8Array(removeMessagePadding(fromBase64ToArray(base64EncodedData))); const decoded = SignalService.Content.decode(dataUint); diff --git a/ts/session/crypto/MessageEncrypter.ts b/ts/session/crypto/MessageEncrypter.ts index a3cf2a988..63b177dd1 100644 --- a/ts/session/crypto/MessageEncrypter.ts +++ b/ts/session/crypto/MessageEncrypter.ts @@ -6,29 +6,7 @@ import { fromHexToArray } from '../utils/String'; export { concatUInt8Array, getSodium }; import { getLatestClosedGroupEncryptionKeyPair } from '../../../ts/data/data'; import { UserUtils } from '../utils'; - -/** - * Add padding to a message buffer - * @param messageBuffer The buffer to add padding to. - */ -export function padPlainTextBuffer(messageBuffer: Uint8Array): Uint8Array { - const plaintext = new Uint8Array(getPaddedMessageLength(messageBuffer.byteLength + 1) - 1); - plaintext.set(new Uint8Array(messageBuffer)); - plaintext[messageBuffer.byteLength] = 0x80; - - return plaintext; -} - -function getPaddedMessageLength(originalLength: number): number { - const messageLengthWithTerminator = originalLength + 1; - let messagePartCount = Math.floor(messageLengthWithTerminator / 160); - - if (messageLengthWithTerminator % 160 !== 0) { - messagePartCount += 1; - } - - return messagePartCount * 160; -} +import { addMessagePadding } from './MessagePadding'; type EncryptResult = { envelopeType: SignalService.Envelope.Type; @@ -53,7 +31,7 @@ export async function encrypt( throw new Error(`Invalid encryption type:${encryptionType}`); } const encryptForClosedGroup = encryptionType === EncryptionType.ClosedGroup; - const plainText = padPlainTextBuffer(plainTextBuffer); + const plainText = addMessagePadding(plainTextBuffer); if (encryptForClosedGroup) { window?.log?.info( diff --git a/ts/session/crypto/MessagePadding.ts b/ts/session/crypto/MessagePadding.ts new file mode 100644 index 000000000..f8e6868ab --- /dev/null +++ b/ts/session/crypto/MessagePadding.ts @@ -0,0 +1,45 @@ +/** + * Unpad the buffer from its padding. + * An error is thrown if there is no padding. + * A padded buffer is + * * whatever at start + * * ends with 0x80 and any number of 0x00 until the end + */ +export function removeMessagePadding(paddedData: ArrayBuffer): ArrayBuffer { + const paddedPlaintext = new Uint8Array(paddedData); + + for (let i = paddedPlaintext.length - 1; i >= 0; i -= 1) { + if (paddedPlaintext[i] === 0x80) { + const plaintext = new Uint8Array(i); + plaintext.set(paddedPlaintext.subarray(0, i)); + return plaintext.buffer; + } else if (paddedPlaintext[i] !== 0x00) { + throw new Error('Invalid padding'); + } + } + + throw new Error('Invalid padding'); +} + +/** + * Add padding to a message buffer + * @param messageBuffer The buffer to add padding to. + */ +export function addMessagePadding(messageBuffer: Uint8Array): Uint8Array { + const plaintext = new Uint8Array(getPaddedMessageLength(messageBuffer.byteLength + 1) - 1); + plaintext.set(new Uint8Array(messageBuffer)); + plaintext[messageBuffer.byteLength] = 0x80; + + return plaintext; +} + +function getPaddedMessageLength(originalLength: number): number { + const messageLengthWithTerminator = originalLength + 1; + let messagePartCount = Math.floor(messageLengthWithTerminator / 160); + + if (messageLengthWithTerminator % 160 !== 0) { + messagePartCount += 1; + } + + return messagePartCount * 160; +} diff --git a/ts/session/sending/MessageSender.ts b/ts/session/sending/MessageSender.ts index 481aabbc4..c9fe43183 100644 --- a/ts/session/sending/MessageSender.ts +++ b/ts/session/sending/MessageSender.ts @@ -10,10 +10,10 @@ import { UserUtils } from '../utils'; import { OpenGroupRequestCommonType } from '../../opengroup/opengroupV2/ApiUtil'; import { postMessage } from '../../opengroup/opengroupV2/OpenGroupAPIV2'; import { OpenGroupMessageV2 } from '../../opengroup/opengroupV2/OpenGroupMessageV2'; -import { padPlainTextBuffer } from '../crypto/MessageEncrypter'; import { fromUInt8ArrayToBase64 } from '../utils/String'; import { OpenGroupVisibleMessage } from '../messages/outgoing/visibleMessage/OpenGroupVisibleMessage'; import * as LokiMessageApi from './LokiMessageApi'; +import { addMessagePadding } from '../crypto/MessagePadding'; // ================ Regular ================ @@ -136,7 +136,8 @@ export async function sendToOpenGroupV2( rawMessage: OpenGroupVisibleMessage, roomInfos: OpenGroupRequestCommonType ): Promise { - const paddedBody = padPlainTextBuffer(rawMessage.plainTextBuffer()); + // we agreed to pad message for opengroupv2 + const paddedBody = addMessagePadding(rawMessage.plainTextBuffer()); const v2Message = new OpenGroupMessageV2({ sentTimestamp: Date.now(), sender: UserUtils.getOurPubKeyStrFromCache(), diff --git a/ts/session/utils/Attachments.ts b/ts/session/utils/Attachments.ts index 63a39301f..212f38537 100644 --- a/ts/session/utils/Attachments.ts +++ b/ts/session/utils/Attachments.ts @@ -74,6 +74,7 @@ export class AttachmentUtils { let attachmentData: ArrayBuffer; + // We don't pad attachments for opengroup as they are unencrypted if (isRaw || openGroup) { attachmentData = attachment.data; } else { diff --git a/ts/test/session/unit/crypto/MessageEncrypter_test.ts b/ts/test/session/unit/crypto/MessageEncrypter_test.ts index b5697e913..9c6603f49 100644 --- a/ts/test/session/unit/crypto/MessageEncrypter_test.ts +++ b/ts/test/session/unit/crypto/MessageEncrypter_test.ts @@ -11,6 +11,7 @@ import { StringUtils, UserUtils } from '../../../../session/utils'; import chaiBytes from 'chai-bytes'; import { PubKey } from '../../../../session/types'; import { fromHex, toHex } from '../../../../session/utils/String'; +import { addMessagePadding } from '../../../../session/crypto/MessagePadding'; chai.use(chaiBytes); @@ -187,7 +188,7 @@ describe('MessageEncrypter', () => { const spy = sinon.spy(MessageEncrypter, 'encryptUsingSessionProtocol'); await MessageEncrypter.encrypt(TestUtils.generateFakePubKey(), data, EncryptionType.Fallback); chai.expect(spy.callCount).to.be.equal(1); - const paddedData = MessageEncrypter.padPlainTextBuffer(data); + const paddedData = addMessagePadding(data); const firstArgument = new Uint8Array(spy.args[0][1]); chai.expect(firstArgument).to.deep.equal(paddedData); spy.restore(); From c063848167aa4435342f9bf69a4c6fb881cbfc17 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 7 May 2021 10:56:14 +1000 Subject: [PATCH 2/3] pad and unpad message everywhere attachment not padded for opengroup only --- ts/receiver/attachments.ts | 20 ++-- ts/receiver/contentMessage.ts | 2 +- ts/receiver/receiver.ts | 2 +- ts/session/crypto/BufferPadding.ts | 94 +++++++++++++++++++ ts/session/crypto/MessageEncrypter.ts | 2 +- ts/session/crypto/MessagePadding.ts | 45 --------- ts/session/sending/MessageSender.ts | 2 +- ts/session/utils/Attachments.ts | 39 +------- ts/session/utils/AttachmentsV2.ts | 10 +- .../unit/crypto/MessageEncrypter_test.ts | 2 +- 10 files changed, 116 insertions(+), 102 deletions(-) create mode 100644 ts/session/crypto/BufferPadding.ts delete mode 100644 ts/session/crypto/MessagePadding.ts diff --git a/ts/receiver/attachments.ts b/ts/receiver/attachments.ts index edbe253b1..7430f0f64 100644 --- a/ts/receiver/attachments.ts +++ b/ts/receiver/attachments.ts @@ -11,6 +11,7 @@ import { } from '../opengroup/opengroupV2/OpenGroupAPIV2'; import { OpenGroupRequestCommonType } from '../opengroup/opengroupV2/ApiUtil'; import { FSv2 } from '../fileserver'; +import { getUnpaddedAttachment } from '../session/crypto/BufferPadding'; export async function downloadAttachment(attachment: any) { const serverUrl = new URL(attachment.url).origin; @@ -69,14 +70,13 @@ export async function downloadAttachment(attachment: any) { if (!size || size !== data.byteLength) { // we might have padding, check that all the remaining bytes are padding bytes // otherwise we have an error. - if (AttachmentUtils.isLeftOfBufferPaddingOnly(data, size)) { - // we can safely remove the padding - data = data.slice(0, size); - } else { + const unpaddedData = getUnpaddedAttachment(data, size); + if (!unpaddedData) { throw new Error( `downloadAttachment: Size ${size} did not match downloaded attachment size ${data.byteLength}` ); } + data = unpaddedData; } } @@ -120,17 +120,17 @@ export async function downloadAttachmentOpenGroupV2( if (attachment.size !== dataUint.length) { // we might have padding, check that all the remaining bytes are padding bytes // otherwise we have an error. - if (AttachmentUtils.isLeftOfBufferPaddingOnly(dataUint.buffer, attachment.size)) { - // we can safely remove the padding - data = data.slice(0, attachment.size); - } else { + const unpaddedData = getUnpaddedAttachment(dataUint.buffer, attachment.size); + if (!unpaddedData) { throw new Error( `downloadAttachment: Size ${attachment.size} did not match downloaded attachment size ${data.byteLength}` ); } + data = new Uint8Array(unpaddedData); } else { - // nothing to do, the attachment has already the correct size. There is just no padding included, which is bas - window.log.warn('Received opengroupv2 unpadded attachment'); + // nothing to do, the attachment has already the correct size. + // There is just no padding included, which is what we agreed on + window.log.info('Received opengroupv2 unpadded attachment'); } return { diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts index 06666d7e0..85058a6de 100644 --- a/ts/receiver/contentMessage.ts +++ b/ts/receiver/contentMessage.ts @@ -17,7 +17,7 @@ import { KeyPairRequestManager } from './keyPairRequestManager'; import { requestEncryptionKeyPair } from '../session/group'; import { handleConfigurationMessage } from './configMessage'; import { ConversationTypeEnum } from '../models/conversation'; -import { removeMessagePadding } from '../session/crypto/MessagePadding'; +import { removeMessagePadding } from '../session/crypto/BufferPadding'; export async function handleContentMessage(envelope: EnvelopePlus) { try { diff --git a/ts/receiver/receiver.ts b/ts/receiver/receiver.ts index fe85f4309..c37e8ecb7 100644 --- a/ts/receiver/receiver.ts +++ b/ts/receiver/receiver.ts @@ -36,7 +36,7 @@ import { OpenGroupMessageV2 } from '../opengroup/opengroupV2/OpenGroupMessageV2' import { OpenGroupRequestCommonType } from '../opengroup/opengroupV2/ApiUtil'; import { handleMessageJob } from './queuedJob'; import { fromBase64ToArray } from '../session/utils/String'; -import { removeMessagePadding } from '../session/crypto/MessagePadding'; +import { removeMessagePadding } from '../session/crypto/BufferPadding'; // TODO: check if some of these exports no longer needed diff --git a/ts/session/crypto/BufferPadding.ts b/ts/session/crypto/BufferPadding.ts new file mode 100644 index 000000000..2c998b0e9 --- /dev/null +++ b/ts/session/crypto/BufferPadding.ts @@ -0,0 +1,94 @@ +/** + * This file is used to pad message buffer and attachments + */ +const PADDING_BYTE = 0x00; + +/** + * Unpad the buffer from its padding. + * An error is thrown if there is no padding. + * A padded buffer is + * * whatever at start + * * ends with 0x80 and any number of 0x00 until the end + */ +export function removeMessagePadding(paddedData: ArrayBuffer): ArrayBuffer { + const paddedPlaintext = new Uint8Array(paddedData); + window.log.info('Removing message padding...'); + for (let i = paddedPlaintext.length - 1; i >= 0; i -= 1) { + if (paddedPlaintext[i] === 0x80) { + const plaintext = new Uint8Array(i); + plaintext.set(paddedPlaintext.subarray(0, i)); + return plaintext.buffer; + } else if (paddedPlaintext[i] !== PADDING_BYTE) { + throw new Error('Invalid padding'); + } + } + + throw new Error('Invalid padding'); +} + +/** + * Add padding to a message buffer + * @param messageBuffer The buffer to add padding to. + */ +export function addMessagePadding(messageBuffer: Uint8Array): Uint8Array { + window.log.info('Adding message padding...'); + + const plaintext = new Uint8Array(getPaddedMessageLength(messageBuffer.byteLength + 1) - 1); + plaintext.set(new Uint8Array(messageBuffer)); + plaintext[messageBuffer.byteLength] = 0x80; + + return plaintext; +} + +function getPaddedMessageLength(originalLength: number): number { + const messageLengthWithTerminator = originalLength + 1; + let messagePartCount = Math.floor(messageLengthWithTerminator / 160); + + if (messageLengthWithTerminator % 160 !== 0) { + messagePartCount += 1; + } + + return messagePartCount * 160; +} + +/** + * + * If the attachment has padding, remove the padding and return the unpad attachment + + */ +export function getUnpaddedAttachment( + data: ArrayBuffer, + unpaddedExpectedSize: number +): ArrayBuffer | null { + window.log.info('Removing attachment padding...'); + + // to have a padding we must have a strictly longer length expected + if (data.byteLength <= unpaddedExpectedSize) { + return null; + } + const dataUint = new Uint8Array(data); + for (let i = unpaddedExpectedSize; i < data.byteLength; i++) { + if (dataUint[i] !== PADDING_BYTE) { + return null; + } + } + + return data.slice(0, unpaddedExpectedSize); +} + +export function addAttachmentPadding(data: ArrayBuffer): ArrayBuffer { + const originalUInt = new Uint8Array(data); + window.log.info('Adding attchment padding...'); + + const paddedSize = Math.max( + 541, + Math.floor(Math.pow(1.05, Math.ceil(Math.log(originalUInt.length) / Math.log(1.05)))) + ); + const paddedData = new ArrayBuffer(paddedSize); + const paddedUInt = new Uint8Array(paddedData); + + paddedUInt.fill(PADDING_BYTE, originalUInt.length); + paddedUInt.set(originalUInt); + + return paddedUInt.buffer; +} diff --git a/ts/session/crypto/MessageEncrypter.ts b/ts/session/crypto/MessageEncrypter.ts index 63b177dd1..8e5f9045b 100644 --- a/ts/session/crypto/MessageEncrypter.ts +++ b/ts/session/crypto/MessageEncrypter.ts @@ -6,7 +6,7 @@ import { fromHexToArray } from '../utils/String'; export { concatUInt8Array, getSodium }; import { getLatestClosedGroupEncryptionKeyPair } from '../../../ts/data/data'; import { UserUtils } from '../utils'; -import { addMessagePadding } from './MessagePadding'; +import { addMessagePadding } from './BufferPadding'; type EncryptResult = { envelopeType: SignalService.Envelope.Type; diff --git a/ts/session/crypto/MessagePadding.ts b/ts/session/crypto/MessagePadding.ts deleted file mode 100644 index f8e6868ab..000000000 --- a/ts/session/crypto/MessagePadding.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Unpad the buffer from its padding. - * An error is thrown if there is no padding. - * A padded buffer is - * * whatever at start - * * ends with 0x80 and any number of 0x00 until the end - */ -export function removeMessagePadding(paddedData: ArrayBuffer): ArrayBuffer { - const paddedPlaintext = new Uint8Array(paddedData); - - for (let i = paddedPlaintext.length - 1; i >= 0; i -= 1) { - if (paddedPlaintext[i] === 0x80) { - const plaintext = new Uint8Array(i); - plaintext.set(paddedPlaintext.subarray(0, i)); - return plaintext.buffer; - } else if (paddedPlaintext[i] !== 0x00) { - throw new Error('Invalid padding'); - } - } - - throw new Error('Invalid padding'); -} - -/** - * Add padding to a message buffer - * @param messageBuffer The buffer to add padding to. - */ -export function addMessagePadding(messageBuffer: Uint8Array): Uint8Array { - const plaintext = new Uint8Array(getPaddedMessageLength(messageBuffer.byteLength + 1) - 1); - plaintext.set(new Uint8Array(messageBuffer)); - plaintext[messageBuffer.byteLength] = 0x80; - - return plaintext; -} - -function getPaddedMessageLength(originalLength: number): number { - const messageLengthWithTerminator = originalLength + 1; - let messagePartCount = Math.floor(messageLengthWithTerminator / 160); - - if (messageLengthWithTerminator % 160 !== 0) { - messagePartCount += 1; - } - - return messagePartCount * 160; -} diff --git a/ts/session/sending/MessageSender.ts b/ts/session/sending/MessageSender.ts index c9fe43183..caf483d94 100644 --- a/ts/session/sending/MessageSender.ts +++ b/ts/session/sending/MessageSender.ts @@ -13,7 +13,7 @@ import { OpenGroupMessageV2 } from '../../opengroup/opengroupV2/OpenGroupMessage import { fromUInt8ArrayToBase64 } from '../utils/String'; import { OpenGroupVisibleMessage } from '../messages/outgoing/visibleMessage/OpenGroupVisibleMessage'; import * as LokiMessageApi from './LokiMessageApi'; -import { addMessagePadding } from '../crypto/MessagePadding'; +import { addMessagePadding } from '../crypto/BufferPadding'; // ================ Regular ================ diff --git a/ts/session/utils/Attachments.ts b/ts/session/utils/Attachments.ts index 212f38537..060f387c9 100644 --- a/ts/session/utils/Attachments.ts +++ b/ts/session/utils/Attachments.ts @@ -9,6 +9,7 @@ import { } from '../messages/outgoing/visibleMessage/VisibleMessage'; import { OpenGroup } from '../../opengroup/opengroupV1/OpenGroup'; import { FSv2 } from '../../fileserver'; +import { addAttachmentPadding } from '../crypto/BufferPadding'; interface UploadParams { attachment: Attachment; @@ -39,8 +40,6 @@ interface RawQuote { // tslint:disable-next-line: no-unnecessary-class export class AttachmentUtils { - public static readonly PADDING_BYTE = 0; - private constructor() {} public static async uploadV1(params: UploadParams): Promise { @@ -85,7 +84,7 @@ export class AttachmentUtils { const dataToEncrypt = !shouldPad || !window.lokiFeatureFlags.padOutgoingAttachments ? attachment.data - : AttachmentUtils.addAttachmentPadding(attachment.data); + : addAttachmentPadding(attachment.data); const data = await window.textsecure.crypto.encryptAttachment( dataToEncrypt, pointer.key.buffer, @@ -196,38 +195,4 @@ export class AttachmentUtils { attachments, }; } - - public static isLeftOfBufferPaddingOnly( - data: ArrayBuffer, - unpaddedExpectedSize: number - ): boolean { - // to have a padding we must have a strictly longer length expected - if (data.byteLength <= unpaddedExpectedSize) { - return false; - } - const dataUint = new Uint8Array(data); - for (let i = unpaddedExpectedSize; i < data.byteLength; i++) { - if (dataUint[i] !== this.PADDING_BYTE) { - return false; - } - } - - return true; - } - - public static addAttachmentPadding(data: ArrayBuffer): ArrayBuffer { - const originalUInt = new Uint8Array(data); - - const paddedSize = Math.max( - 541, - Math.floor(Math.pow(1.05, Math.ceil(Math.log(originalUInt.length) / Math.log(1.05)))) - ); - const paddedData = new ArrayBuffer(paddedSize); - const paddedUInt = new Uint8Array(paddedData); - - paddedUInt.fill(AttachmentUtils.PADDING_BYTE, originalUInt.length); - paddedUInt.set(originalUInt); - - return paddedUInt.buffer; - } } diff --git a/ts/session/utils/AttachmentsV2.ts b/ts/session/utils/AttachmentsV2.ts index e877ae0c9..e5023d42a 100644 --- a/ts/session/utils/AttachmentsV2.ts +++ b/ts/session/utils/AttachmentsV2.ts @@ -10,6 +10,7 @@ import { } from '../messages/outgoing/visibleMessage/VisibleMessage'; import { AttachmentUtils } from './Attachments'; import { uploadFileOpenGroupV2 } from '../../opengroup/opengroupV2/OpenGroupAPIV2'; +import { addAttachmentPadding } from '../crypto/BufferPadding'; interface UploadParamsV2 { attachment: Attachment; @@ -35,8 +36,6 @@ interface RawQuote { attachments?: Array; } -const PADDING_BYTE = 0; - export async function uploadV2(params: UploadParamsV2): Promise { const { attachment, openGroup } = params; if (typeof attachment !== 'object' || attachment == null) { @@ -57,9 +56,10 @@ export async function uploadV2(params: UploadParamsV2): Promise Date: Fri, 7 May 2021 11:41:28 +1000 Subject: [PATCH 3/3] lint --- ts/session/crypto/BufferPadding.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ts/session/crypto/BufferPadding.ts b/ts/session/crypto/BufferPadding.ts index 2c998b0e9..ea640ac7f 100644 --- a/ts/session/crypto/BufferPadding.ts +++ b/ts/session/crypto/BufferPadding.ts @@ -31,7 +31,7 @@ export function removeMessagePadding(paddedData: ArrayBuffer): ArrayBuffer { * @param messageBuffer The buffer to add padding to. */ export function addMessagePadding(messageBuffer: Uint8Array): Uint8Array { - window.log.info('Adding message padding...'); + window.log?.info('Adding message padding...'); const plaintext = new Uint8Array(getPaddedMessageLength(messageBuffer.byteLength + 1) - 1); plaintext.set(new Uint8Array(messageBuffer)); @@ -51,16 +51,14 @@ function getPaddedMessageLength(originalLength: number): number { return messagePartCount * 160; } -/** - * +/* * If the attachment has padding, remove the padding and return the unpad attachment - */ export function getUnpaddedAttachment( data: ArrayBuffer, unpaddedExpectedSize: number ): ArrayBuffer | null { - window.log.info('Removing attachment padding...'); + window.log?.info('Removing attachment padding...'); // to have a padding we must have a strictly longer length expected if (data.byteLength <= unpaddedExpectedSize) {