Uint8Array migration
This commit is contained in:
parent
daf75190b8
commit
4ef0bf96cc
137 changed files with 2202 additions and 3170 deletions
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { AvatarColorMap, AvatarColorType } from '../types/Colors';
|
||||
import { AvatarDataType } from '../types/Avatar';
|
||||
import { canvasToArrayBuffer } from './canvasToArrayBuffer';
|
||||
import { canvasToBytes } from './canvasToBytes';
|
||||
import { getFittedFontSize } from './avatarTextSizeCalculator';
|
||||
|
||||
const CANVAS_SIZE = 1024;
|
||||
|
@ -74,9 +74,9 @@ async function getFont(text: string): Promise<string> {
|
|||
return `${fontSize}px Inter`;
|
||||
}
|
||||
|
||||
export async function avatarDataToArrayBuffer(
|
||||
export async function avatarDataToBytes(
|
||||
avatarData: AvatarDataType
|
||||
): Promise<ArrayBuffer> {
|
||||
): Promise<Uint8Array> {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = CANVAS_SIZE;
|
||||
canvas.height = CANVAS_SIZE;
|
||||
|
@ -84,7 +84,7 @@ export async function avatarDataToArrayBuffer(
|
|||
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
'avatarDataToArrayBuffer: could not get canvas rendering context'
|
||||
'avatarDataToBytes: could not get canvas rendering context'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -117,5 +117,5 @@ export async function avatarDataToArrayBuffer(
|
|||
setCanvasBackground(bg, context, canvas);
|
||||
}
|
||||
|
||||
return canvasToArrayBuffer(canvas);
|
||||
return canvasToBytes(canvas);
|
||||
}
|
|
@ -6,9 +6,6 @@ import { SignalService as Proto } from '../protobuf';
|
|||
import * as log from '../logging/log';
|
||||
import { missingCaseError } from './missingCaseError';
|
||||
|
||||
// TODO: remove once we move away from ArrayBuffers
|
||||
const FIXMEU8 = Uint8Array;
|
||||
|
||||
export function callingMessageToProto(
|
||||
{
|
||||
offer,
|
||||
|
@ -88,7 +85,7 @@ function bufferToProto(
|
|||
return value;
|
||||
}
|
||||
|
||||
return new FIXMEU8(value.toArrayBuffer());
|
||||
return new Uint8Array(value.toArrayBuffer());
|
||||
}
|
||||
|
||||
function urgencyToProto(
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
import { canvasToBlob } from './canvasToBlob';
|
||||
import { MIMEType } from '../types/MIME';
|
||||
|
||||
export async function canvasToArrayBuffer(
|
||||
export async function canvasToBytes(
|
||||
canvas: HTMLCanvasElement,
|
||||
mimeType?: MIMEType,
|
||||
quality?: number
|
||||
): Promise<ArrayBuffer> {
|
||||
): Promise<Uint8Array> {
|
||||
const blob = await canvasToBlob(canvas, mimeType, quality);
|
||||
return blob.arrayBuffer();
|
||||
return new Uint8Array(await blob.arrayBuffer());
|
||||
}
|
|
@ -1,23 +1,21 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import Crypto, { PaddedLengths } from '../textsecure/Crypto';
|
||||
import { ConversationType } from '../state/ducks/conversations';
|
||||
import { ProfileRequestDataType } from '../textsecure/WebAPI';
|
||||
import { assert } from './assert';
|
||||
import * as Bytes from '../Bytes';
|
||||
import {
|
||||
arrayBufferToBase64,
|
||||
base64ToArrayBuffer,
|
||||
bytesFromString,
|
||||
PaddedLengths,
|
||||
encryptProfile,
|
||||
encryptProfileItemWithPadding,
|
||||
} from '../Crypto';
|
||||
import { deriveProfileKeyCommitment, deriveProfileKeyVersion } from './zkgroup';
|
||||
|
||||
const { encryptProfile, encryptProfileItemWithPadding } = Crypto;
|
||||
|
||||
export async function encryptProfileData(
|
||||
conversation: ConversationType,
|
||||
avatarBuffer?: ArrayBuffer
|
||||
): Promise<[ProfileRequestDataType, ArrayBuffer | undefined]> {
|
||||
avatarBuffer?: Uint8Array
|
||||
): Promise<[ProfileRequestDataType, Uint8Array | undefined]> {
|
||||
const {
|
||||
aboutEmoji,
|
||||
aboutText,
|
||||
|
@ -30,43 +28,41 @@ export async function encryptProfileData(
|
|||
assert(profileKey, 'profileKey');
|
||||
assert(uuid, 'uuid');
|
||||
|
||||
const keyBuffer = base64ToArrayBuffer(profileKey);
|
||||
const keyBuffer = Bytes.fromBase64(profileKey);
|
||||
|
||||
const fullName = [firstName, familyName].filter(Boolean).join('\0');
|
||||
|
||||
const [
|
||||
bytesName,
|
||||
bytesAbout,
|
||||
bytesAboutEmoji,
|
||||
encryptedAvatarData,
|
||||
] = await Promise.all([
|
||||
encryptProfileItemWithPadding(
|
||||
bytesFromString(fullName),
|
||||
keyBuffer,
|
||||
PaddedLengths.Name
|
||||
),
|
||||
aboutText
|
||||
? encryptProfileItemWithPadding(
|
||||
bytesFromString(aboutText),
|
||||
keyBuffer,
|
||||
PaddedLengths.About
|
||||
)
|
||||
: null,
|
||||
aboutEmoji
|
||||
? encryptProfileItemWithPadding(
|
||||
bytesFromString(aboutEmoji),
|
||||
keyBuffer,
|
||||
PaddedLengths.AboutEmoji
|
||||
)
|
||||
: null,
|
||||
avatarBuffer ? encryptProfile(avatarBuffer, keyBuffer) : undefined,
|
||||
]);
|
||||
const bytesName = encryptProfileItemWithPadding(
|
||||
Bytes.fromString(fullName),
|
||||
keyBuffer,
|
||||
PaddedLengths.Name
|
||||
);
|
||||
|
||||
const bytesAbout = aboutText
|
||||
? encryptProfileItemWithPadding(
|
||||
Bytes.fromString(aboutText),
|
||||
keyBuffer,
|
||||
PaddedLengths.About
|
||||
)
|
||||
: null;
|
||||
|
||||
const bytesAboutEmoji = aboutEmoji
|
||||
? encryptProfileItemWithPadding(
|
||||
Bytes.fromString(aboutEmoji),
|
||||
keyBuffer,
|
||||
PaddedLengths.AboutEmoji
|
||||
)
|
||||
: null;
|
||||
|
||||
const encryptedAvatarData = avatarBuffer
|
||||
? encryptProfile(avatarBuffer, keyBuffer)
|
||||
: undefined;
|
||||
|
||||
const profileData = {
|
||||
version: deriveProfileKeyVersion(profileKey, uuid),
|
||||
name: arrayBufferToBase64(bytesName),
|
||||
about: bytesAbout ? arrayBufferToBase64(bytesAbout) : null,
|
||||
aboutEmoji: bytesAboutEmoji ? arrayBufferToBase64(bytesAboutEmoji) : null,
|
||||
name: Bytes.toBase64(bytesName),
|
||||
about: bytesAbout ? Bytes.toBase64(bytesAbout) : null,
|
||||
aboutEmoji: bytesAboutEmoji ? Bytes.toBase64(bytesAboutEmoji) : null,
|
||||
paymentAddress: window.storage.get('paymentAddress') || null,
|
||||
avatar: Boolean(avatarBuffer),
|
||||
commitment: deriveProfileKeyCommitment(profileKey, uuid),
|
||||
|
|
|
@ -6,12 +6,8 @@ import { SEALED_SENDER } from '../types/SealedSender';
|
|||
import { Address } from '../types/Address';
|
||||
import { QualifiedAddress } from '../types/QualifiedAddress';
|
||||
import { UUID } from '../types/UUID';
|
||||
import {
|
||||
base64ToArrayBuffer,
|
||||
stringFromBytes,
|
||||
trimForDisplay,
|
||||
verifyAccessKey,
|
||||
} from '../Crypto';
|
||||
import * as Bytes from '../Bytes';
|
||||
import { trimForDisplay, verifyAccessKey, decryptProfile } from '../Crypto';
|
||||
import {
|
||||
generateProfileKeyCredentialRequest,
|
||||
getClientZkProfileOperations,
|
||||
|
@ -118,7 +114,7 @@ export async function getProfile(
|
|||
});
|
||||
}
|
||||
|
||||
const identityKey = base64ToArrayBuffer(profile.identityKey);
|
||||
const identityKey = Bytes.fromBase64(profile.identityKey);
|
||||
const changed = await window.textsecure.storage.protocol.saveIdentity(
|
||||
new Address(targetUuid, 1),
|
||||
identityKey,
|
||||
|
@ -142,9 +138,9 @@ export async function getProfile(
|
|||
sealedSender: SEALED_SENDER.UNRESTRICTED,
|
||||
});
|
||||
} else if (accessKey && profile.unidentifiedAccess) {
|
||||
const haveCorrectKey = await verifyAccessKey(
|
||||
base64ToArrayBuffer(accessKey),
|
||||
base64ToArrayBuffer(profile.unidentifiedAccess)
|
||||
const haveCorrectKey = verifyAccessKey(
|
||||
Bytes.fromBase64(accessKey),
|
||||
Bytes.fromBase64(profile.unidentifiedAccess)
|
||||
);
|
||||
|
||||
if (haveCorrectKey) {
|
||||
|
@ -174,12 +170,12 @@ export async function getProfile(
|
|||
if (profile.about) {
|
||||
const key = c.get('profileKey');
|
||||
if (key) {
|
||||
const keyBuffer = base64ToArrayBuffer(key);
|
||||
const decrypted = await window.textsecure.crypto.decryptProfile(
|
||||
base64ToArrayBuffer(profile.about),
|
||||
const keyBuffer = Bytes.fromBase64(key);
|
||||
const decrypted = decryptProfile(
|
||||
Bytes.fromBase64(profile.about),
|
||||
keyBuffer
|
||||
);
|
||||
c.set('about', stringFromBytes(trimForDisplay(decrypted)));
|
||||
c.set('about', Bytes.toString(trimForDisplay(decrypted)));
|
||||
}
|
||||
} else {
|
||||
c.unset('about');
|
||||
|
@ -188,12 +184,12 @@ export async function getProfile(
|
|||
if (profile.aboutEmoji) {
|
||||
const key = c.get('profileKey');
|
||||
if (key) {
|
||||
const keyBuffer = base64ToArrayBuffer(key);
|
||||
const decrypted = await window.textsecure.crypto.decryptProfile(
|
||||
base64ToArrayBuffer(profile.aboutEmoji),
|
||||
const keyBuffer = Bytes.fromBase64(key);
|
||||
const decrypted = decryptProfile(
|
||||
Bytes.fromBase64(profile.aboutEmoji),
|
||||
keyBuffer
|
||||
);
|
||||
c.set('aboutEmoji', stringFromBytes(trimForDisplay(decrypted)));
|
||||
c.set('aboutEmoji', Bytes.toString(trimForDisplay(decrypted)));
|
||||
}
|
||||
} else {
|
||||
c.unset('aboutEmoji');
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { arrayBufferToBase64 } from '../Crypto';
|
||||
import * as Bytes from '../Bytes';
|
||||
|
||||
export function getProvisioningUrl(
|
||||
uuid: string,
|
||||
publicKey: ArrayBuffer
|
||||
publicKey: Uint8Array
|
||||
): string {
|
||||
const url = new URL('sgnl://linkdevice');
|
||||
url.searchParams.set('uuid', uuid);
|
||||
url.searchParams.set('pub_key', arrayBufferToBase64(publicKey));
|
||||
url.searchParams.set('pub_key', Bytes.toBase64(publicKey));
|
||||
return url.toString();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
import { ConversationAttributesType } from '../model-types.d';
|
||||
import { SendMetadataType, SendOptionsType } from '../textsecure/SendMessage';
|
||||
import { arrayBufferToBase64, getRandomBytes } from '../Crypto';
|
||||
import * as Bytes from '../Bytes';
|
||||
import { getRandomBytes } from '../Crypto';
|
||||
import { getConversationMembers } from './getConversationMembers';
|
||||
import { isDirectConversation, isMe } from './whatTypeOfConversation';
|
||||
import { isInSystemContacts } from './isInSystemContacts';
|
||||
|
@ -68,7 +69,7 @@ export async function getSendOptions(
|
|||
// If we've never fetched user's profile, we default to what we have
|
||||
if (sealedSender === SEALED_SENDER.UNKNOWN) {
|
||||
const identifierData = {
|
||||
accessKey: accessKey || arrayBufferToBase64(getRandomBytes(16)),
|
||||
accessKey: accessKey || Bytes.toBase64(getRandomBytes(16)),
|
||||
senderCertificate,
|
||||
};
|
||||
return {
|
||||
|
@ -89,7 +90,7 @@ export async function getSendOptions(
|
|||
accessKey:
|
||||
accessKey && sealedSender === SEALED_SENDER.ENABLED
|
||||
? accessKey
|
||||
: arrayBufferToBase64(getRandomBytes(16)),
|
||||
: Bytes.toBase64(getRandomBytes(16)),
|
||||
senderCertificate,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import path from 'path';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { v4 as genUuid } from 'uuid';
|
||||
|
||||
import { blobToArrayBuffer } from '../types/VisualAttachment';
|
||||
import { IMAGE_JPEG, MIMEType, isHeic, stringToMIMEType } from '../types/MIME';
|
||||
import {
|
||||
InMemoryAttachmentDraftType,
|
||||
|
@ -20,7 +21,7 @@ export async function handleImageAttachment(
|
|||
|
||||
if (isHeic(file.type)) {
|
||||
const uuid = genUuid();
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const bytes = new Uint8Array(await file.arrayBuffer());
|
||||
|
||||
const convertedFile = await new Promise<File>((resolve, reject) => {
|
||||
ipcRenderer.once(`convert-image:${uuid}`, (_, { error, response }) => {
|
||||
|
@ -30,7 +31,7 @@ export async function handleImageAttachment(
|
|||
reject(error);
|
||||
}
|
||||
});
|
||||
ipcRenderer.send('convert-image', uuid, arrayBuffer);
|
||||
ipcRenderer.send('convert-image', uuid, bytes);
|
||||
});
|
||||
|
||||
processedFile = new Blob([convertedFile]);
|
||||
|
@ -42,15 +43,13 @@ export async function handleImageAttachment(
|
|||
file: processedFile,
|
||||
});
|
||||
|
||||
const data = await window.Signal.Types.VisualAttachment.blobToArrayBuffer(
|
||||
resizedBlob
|
||||
);
|
||||
const data = await blobToArrayBuffer(resizedBlob);
|
||||
const blurHash = await imageToBlurHash(resizedBlob);
|
||||
|
||||
return {
|
||||
blurHash,
|
||||
contentType,
|
||||
data,
|
||||
data: new Uint8Array(data),
|
||||
fileName: fileName || file.name,
|
||||
path: file.name,
|
||||
pending: false,
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { canvasToArrayBuffer } from './canvasToArrayBuffer';
|
||||
import { canvasToBytes } from './canvasToBytes';
|
||||
|
||||
export async function imagePathToArrayBuffer(
|
||||
src: string
|
||||
): Promise<ArrayBuffer> {
|
||||
export async function imagePathToBytes(src: string): Promise<Uint8Array> {
|
||||
const image = new Image();
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
|
@ -23,6 +21,5 @@ export async function imagePathToArrayBuffer(
|
|||
|
||||
context.drawImage(image, 0, 0);
|
||||
|
||||
const result = await canvasToArrayBuffer(canvas);
|
||||
return result;
|
||||
return canvasToBytes(canvas);
|
||||
}
|
|
@ -34,7 +34,7 @@ import { toWebSafeBase64, fromWebSafeBase64 } from './webSafeBase64';
|
|||
import { mapToSupportLocale } from './mapToSupportLocale';
|
||||
import {
|
||||
sessionRecordToProtobuf,
|
||||
sessionStructureToArrayBuffer,
|
||||
sessionStructureToBytes,
|
||||
} from './sessionTranslation';
|
||||
import * as zkgroup from './zkgroup';
|
||||
import { StartupQueue } from './StartupQueue';
|
||||
|
@ -78,7 +78,7 @@ export {
|
|||
sendToGroup,
|
||||
setBatchingStrategy,
|
||||
sessionRecordToProtobuf,
|
||||
sessionStructureToArrayBuffer,
|
||||
sessionStructureToBytes,
|
||||
sleep,
|
||||
toWebSafeBase64,
|
||||
zkgroup,
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { AttachmentType } from '../types/Attachment';
|
||||
import { AttachmentType, getUploadSizeLimitKb } from '../types/Attachment';
|
||||
import { showToast } from './showToast';
|
||||
import { ToastFileSize } from '../components/ToastFileSize';
|
||||
|
||||
export function isAttachmentSizeOkay(
|
||||
attachment: Readonly<AttachmentType>
|
||||
): boolean {
|
||||
const limitKb = window.Signal.Types.Attachment.getUploadSizeLimitKb(
|
||||
attachment.contentType
|
||||
);
|
||||
const limitKb = getUploadSizeLimitKb(attachment.contentType);
|
||||
// this needs to be cast properly
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
|
|
|
@ -13057,14 +13057,14 @@
|
|||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/util/avatarDataToArrayBuffer.js",
|
||||
"path": "ts/util/avatarDataToBytes.js",
|
||||
"line": " await font.load();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-03T21:17:38.615Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-load(",
|
||||
"path": "ts/util/avatarDataToArrayBuffer.ts",
|
||||
"path": "ts/util/avatarDataToBytes.ts",
|
||||
"line": " await font.load();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-08-03T21:17:38.615Z"
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import loadImage, { LoadImageOptions } from 'blueimp-load-image';
|
||||
import { canvasToArrayBuffer } from './canvasToArrayBuffer';
|
||||
import { canvasToBytes } from './canvasToBytes';
|
||||
|
||||
export async function processImageFile(file: File): Promise<ArrayBuffer> {
|
||||
export async function processImageFile(file: File): Promise<Uint8Array> {
|
||||
const { image } = await loadImage(file, {
|
||||
canvas: true,
|
||||
cover: true,
|
||||
|
@ -26,5 +26,5 @@ export async function processImageFile(file: File): Promise<ArrayBuffer> {
|
|||
throw new Error('Loaded image was not a canvas');
|
||||
}
|
||||
|
||||
return canvasToArrayBuffer(image);
|
||||
return canvasToBytes(image);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ import * as log from '../logging/log';
|
|||
|
||||
export async function generateSecurityNumber(
|
||||
ourNumber: string,
|
||||
ourKey: ArrayBuffer,
|
||||
ourKey: Uint8Array,
|
||||
theirNumber: string,
|
||||
theirKey: ArrayBuffer
|
||||
theirKey: Uint8Array
|
||||
): Promise<string> {
|
||||
const ourNumberBuf = Buffer.from(ourNumber);
|
||||
const ourKeyObj = PublicKey.deserialize(Buffer.from(ourKey));
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
SenderCertificate,
|
||||
UnidentifiedSenderMessageContent,
|
||||
} from '@signalapp/signal-client';
|
||||
import { typedArrayToArrayBuffer as toArrayBuffer } from '../Crypto';
|
||||
import * as Bytes from '../Bytes';
|
||||
import { senderCertificateService } from '../services/senderCertificate';
|
||||
import {
|
||||
|
@ -69,9 +68,6 @@ const MAX_RECURSION = 10;
|
|||
const ACCESS_KEY_LENGTH = 16;
|
||||
const ZERO_ACCESS_KEY = Bytes.toBase64(new Uint8Array(ACCESS_KEY_LENGTH));
|
||||
|
||||
// TODO: remove once we move away from ArrayBuffers
|
||||
const FIXMEU8 = Uint8Array;
|
||||
|
||||
// Public API:
|
||||
|
||||
export async function sendToGroup({
|
||||
|
@ -453,16 +449,14 @@ export async function sendToGroupViaSenderKey(options: {
|
|||
contentHint,
|
||||
devices: devicesForSenderKey,
|
||||
distributionId,
|
||||
contentMessage: toArrayBuffer(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
),
|
||||
contentMessage: Proto.Content.encode(contentMessage).finish(),
|
||||
groupId,
|
||||
});
|
||||
const accessKeys = getXorOfAccessKeys(devicesForSenderKey);
|
||||
|
||||
const result = await window.textsecure.messaging.sendWithSenderKey(
|
||||
toArrayBuffer(messageBuffer),
|
||||
toArrayBuffer(accessKeys),
|
||||
messageBuffer,
|
||||
accessKeys,
|
||||
timestamp,
|
||||
online
|
||||
);
|
||||
|
@ -554,9 +548,7 @@ export async function sendToGroupViaSenderKey(options: {
|
|||
if (normalSendRecipients.length === 0) {
|
||||
return {
|
||||
dataMessage: contentMessage.dataMessage
|
||||
? toArrayBuffer(
|
||||
Proto.DataMessage.encode(contentMessage.dataMessage).finish()
|
||||
)
|
||||
? Proto.DataMessage.encode(contentMessage.dataMessage).finish()
|
||||
: undefined,
|
||||
successfulIdentifiers: senderKeyRecipients,
|
||||
unidentifiedDeliveries: senderKeyRecipients,
|
||||
|
@ -617,9 +609,7 @@ export async function sendToGroupViaSenderKey(options: {
|
|||
|
||||
return {
|
||||
dataMessage: contentMessage.dataMessage
|
||||
? toArrayBuffer(
|
||||
Proto.DataMessage.encode(contentMessage.dataMessage).finish()
|
||||
)
|
||||
? Proto.DataMessage.encode(contentMessage.dataMessage).finish()
|
||||
: undefined,
|
||||
errors: normalSendResult.errors,
|
||||
failoverIdentifiers: normalSendResult.failoverIdentifiers,
|
||||
|
@ -838,7 +828,7 @@ async function encryptForSenderKey({
|
|||
groupId,
|
||||
}: {
|
||||
contentHint: number;
|
||||
contentMessage: ArrayBuffer;
|
||||
contentMessage: Uint8Array;
|
||||
devices: Array<DeviceType>;
|
||||
distributionId: string;
|
||||
groupId: string;
|
||||
|
@ -857,7 +847,7 @@ async function encryptForSenderKey({
|
|||
);
|
||||
const ourAddress = getOurAddress();
|
||||
const senderKeyStore = new SenderKeys({ ourUuid });
|
||||
const message = Buffer.from(padMessage(new FIXMEU8(contentMessage)));
|
||||
const message = Buffer.from(padMessage(contentMessage));
|
||||
|
||||
const ciphertextMessage = await window.textsecure.storage.protocol.enqueueSenderKeyJob(
|
||||
new QualifiedAddress(ourUuid, ourAddress),
|
||||
|
|
|
@ -4,12 +4,8 @@
|
|||
import { get, isFinite, isInteger, isString } from 'lodash';
|
||||
|
||||
import { signal } from '../protobuf/compiled';
|
||||
import {
|
||||
bytesFromString,
|
||||
deriveSecrets,
|
||||
fromEncodedBinaryToArrayBuffer,
|
||||
typedArrayToArrayBuffer,
|
||||
} from '../Crypto';
|
||||
import * as Bytes from '../Bytes';
|
||||
import { deriveSecrets } from '../Crypto';
|
||||
|
||||
const { RecordStructure, SessionStructure } = signal.proto.storage;
|
||||
const { Chain } = SessionStructure;
|
||||
|
@ -75,16 +71,14 @@ type SessionRecordType = {
|
|||
};
|
||||
|
||||
export type LocalUserDataType = {
|
||||
identityKeyPublic: ArrayBuffer;
|
||||
identityKeyPublic: Uint8Array;
|
||||
registrationId: number;
|
||||
};
|
||||
|
||||
export function sessionStructureToArrayBuffer(
|
||||
export function sessionStructureToBytes(
|
||||
recordStructure: signal.proto.storage.RecordStructure
|
||||
): ArrayBuffer {
|
||||
return typedArrayToArrayBuffer(
|
||||
signal.proto.storage.RecordStructure.encode(recordStructure).finish()
|
||||
);
|
||||
): Uint8Array {
|
||||
return signal.proto.storage.RecordStructure.encode(recordStructure).finish();
|
||||
}
|
||||
|
||||
export function sessionRecordToProtobuf(
|
||||
|
@ -139,7 +133,7 @@ function toProtobufSession(
|
|||
// Core Fields
|
||||
|
||||
proto.aliceBaseKey = binaryToUint8Array(session, 'indexInfo.baseKey', 33);
|
||||
proto.localIdentityPublic = new Uint8Array(ourData.identityKeyPublic);
|
||||
proto.localIdentityPublic = ourData.identityKeyPublic;
|
||||
proto.localRegistrationId = ourData.registrationId;
|
||||
|
||||
proto.previousCounter =
|
||||
|
@ -306,9 +300,9 @@ function toProtobufChain(
|
|||
|
||||
const { cipherKey, macKey, iv } = translateMessageKey(key);
|
||||
|
||||
protoMessageKey.cipherKey = new Uint8Array(cipherKey);
|
||||
protoMessageKey.macKey = new Uint8Array(macKey);
|
||||
protoMessageKey.iv = new Uint8Array(iv);
|
||||
protoMessageKey.cipherKey = cipherKey;
|
||||
protoMessageKey.macKey = macKey;
|
||||
protoMessageKey.iv = iv;
|
||||
|
||||
return protoMessageKey;
|
||||
});
|
||||
|
@ -321,9 +315,9 @@ function toProtobufChain(
|
|||
const WHISPER_MESSAGE_KEYS = 'WhisperMessageKeys';
|
||||
|
||||
function translateMessageKey(key: Uint8Array) {
|
||||
const input = key.buffer;
|
||||
const salt = new ArrayBuffer(32);
|
||||
const info = bytesFromString(WHISPER_MESSAGE_KEYS);
|
||||
const input = key;
|
||||
const salt = new Uint8Array(32);
|
||||
const info = Bytes.fromString(WHISPER_MESSAGE_KEYS);
|
||||
|
||||
const [cipherKey, macKey, ivContainer] = deriveSecrets(input, salt, info);
|
||||
|
||||
|
@ -349,14 +343,14 @@ function binaryToUint8Array(
|
|||
throw new Error(`binaryToUint8Array: String not found at path ${path}`);
|
||||
}
|
||||
|
||||
const buffer = fromEncodedBinaryToArrayBuffer(target);
|
||||
const buffer = Bytes.fromBinary(target);
|
||||
if (length && buffer.byteLength !== length) {
|
||||
throw new Error(
|
||||
`binaryToUint8Array: Got unexpected length ${buffer.byteLength} instead of ${length} at path ${path}`
|
||||
);
|
||||
}
|
||||
|
||||
return new Uint8Array(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
|
|
@ -16,13 +16,10 @@ import {
|
|||
*
|
||||
* [0]: https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern
|
||||
*/
|
||||
export function sniffImageMimeType(
|
||||
bytes: ArrayBuffer | Uint8Array
|
||||
): undefined | MIMEType {
|
||||
const asTypedArray = new Uint8Array(bytes);
|
||||
export function sniffImageMimeType(bytes: Uint8Array): undefined | MIMEType {
|
||||
for (let i = 0; i < TYPES.length; i += 1) {
|
||||
const type = TYPES[i];
|
||||
if (matchesType(asTypedArray, type)) {
|
||||
if (matchesType(bytes, type)) {
|
||||
return type.mimeType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2018-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
export function stringToArrayBuffer(string: string): ArrayBuffer {
|
||||
if (typeof string !== 'string') {
|
||||
throw new TypeError("'string' must be a string");
|
||||
}
|
||||
|
||||
const array = new Uint8Array(string.length);
|
||||
for (let i = 0; i < string.length; i += 1) {
|
||||
array[i] = string.charCodeAt(i);
|
||||
}
|
||||
return array.buffer;
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import crypto from 'crypto';
|
||||
|
||||
import { typedArrayToArrayBuffer as toArrayBuffer } from '../Crypto';
|
||||
|
||||
export function sign(key: ArrayBuffer, data: ArrayBuffer): ArrayBuffer {
|
||||
return toArrayBuffer(
|
||||
crypto
|
||||
.createHmac('sha256', Buffer.from(key))
|
||||
.update(Buffer.from(data))
|
||||
.digest()
|
||||
);
|
||||
}
|
||||
|
||||
export enum HashType {
|
||||
size256 = 'sha256',
|
||||
size512 = 'sha512',
|
||||
}
|
||||
|
||||
export function hash(type: HashType, data: ArrayBuffer): ArrayBuffer {
|
||||
return toArrayBuffer(
|
||||
crypto.createHash(type).update(Buffer.from(data)).digest()
|
||||
);
|
||||
}
|
||||
|
||||
export enum CipherType {
|
||||
AES256CBC = 'aes-256-cbc',
|
||||
AES256CTR = 'aes-256-ctr',
|
||||
}
|
||||
|
||||
export function encrypt(
|
||||
key: ArrayBuffer,
|
||||
data: ArrayBuffer,
|
||||
iv: ArrayBuffer,
|
||||
cipherType: CipherType = CipherType.AES256CBC
|
||||
): ArrayBuffer {
|
||||
const cipher = crypto.createCipheriv(
|
||||
cipherType,
|
||||
Buffer.from(key),
|
||||
Buffer.from(iv)
|
||||
);
|
||||
const encrypted = Buffer.concat([
|
||||
cipher.update(Buffer.from(data)),
|
||||
cipher.final(),
|
||||
]);
|
||||
|
||||
return toArrayBuffer(encrypted);
|
||||
}
|
||||
|
||||
export function decrypt(
|
||||
key: ArrayBuffer,
|
||||
data: ArrayBuffer,
|
||||
iv: ArrayBuffer,
|
||||
cipherType: CipherType = CipherType.AES256CBC
|
||||
): ArrayBuffer {
|
||||
const cipher = crypto.createDecipheriv(
|
||||
cipherType,
|
||||
Buffer.from(key),
|
||||
Buffer.from(iv)
|
||||
);
|
||||
const decrypted = Buffer.concat([
|
||||
cipher.update(Buffer.from(data)),
|
||||
cipher.final(),
|
||||
]);
|
||||
|
||||
return toArrayBuffer(decrypted);
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { ConversationAttributesType } from '../model-types.d';
|
||||
import { ConversationType } from '../state/ducks/conversations';
|
||||
import { base64ToArrayBuffer, fromEncodedBinaryToArrayBuffer } from '../Crypto';
|
||||
import * as Bytes from '../Bytes';
|
||||
import * as log from '../logging/log';
|
||||
|
||||
export enum ConversationTypes {
|
||||
|
@ -38,7 +38,7 @@ export function isGroupV1(
|
|||
return false;
|
||||
}
|
||||
|
||||
const buffer = fromEncodedBinaryToArrayBuffer(groupId);
|
||||
const buffer = Bytes.fromBinary(groupId);
|
||||
return buffer.byteLength === window.Signal.Groups.ID_V1_LENGTH;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ export function isGroupV2(
|
|||
try {
|
||||
return (
|
||||
groupVersion === 2 &&
|
||||
base64ToArrayBuffer(groupId).byteLength === window.Signal.Groups.ID_LENGTH
|
||||
Bytes.fromBase64(groupId).byteLength === window.Signal.Groups.ID_LENGTH
|
||||
);
|
||||
} catch (error) {
|
||||
log.error('isGroupV2: Failed to process groupId in base64!');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue