fix cryptoWorker singleton import

This commit is contained in:
Abhinav 2023-01-09 10:30:31 +05:30
parent ab4ab4f72c
commit 8613a3ef6a
16 changed files with 111 additions and 93 deletions

View file

@ -3,7 +3,7 @@ import SingleInputForm, {
SingleInputFormProps, SingleInputFormProps,
} from 'components/SingleInputForm'; } from 'components/SingleInputForm';
import React from 'react'; import React from 'react';
import CryptoWorker from 'utils/crypto'; import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
import constants from 'utils/strings/constants'; import constants from 'utils/strings/constants';
export function PublicLinkSetPassword({ export function PublicLinkSetPassword({
@ -28,7 +28,7 @@ export function PublicLinkSetPassword({
}; };
const enablePublicUrlPassword = async (password: string) => { const enablePublicUrlPassword = async (password: string) => {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const kekSalt = await cryptoWorker.generateSaltToDeriveKey(); const kekSalt = await cryptoWorker.generateSaltToDeriveKey();
const kek = await cryptoWorker.deriveInteractiveKey(password, kekSalt); const kek = await cryptoWorker.deriveInteractiveKey(password, kekSalt);

View file

@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import constants from 'utils/strings/constants'; import constants from 'utils/strings/constants';
import CryptoWorker from 'utils/crypto';
import SingleInputForm, { import SingleInputForm, {
SingleInputFormProps, SingleInputFormProps,
} from 'components/SingleInputForm'; } from 'components/SingleInputForm';
@ -10,6 +9,7 @@ import { CustomError } from 'utils/error';
import { Input } from '@mui/material'; import { Input } from '@mui/material';
import { KeyAttributes, User } from 'types/user'; import { KeyAttributes, User } from 'types/user';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
export interface VerifyMasterPasswordFormProps { export interface VerifyMasterPasswordFormProps {
user: User; user: User;
@ -29,7 +29,7 @@ export default function VerifyMasterPasswordForm({
setFieldError setFieldError
) => { ) => {
try { try {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
let kek: string = null; let kek: string = null;
try { try {
kek = await cryptoWorker.deriveKey( kek = await cryptoWorker.deriveKey(

View file

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import constants from 'utils/strings/constants'; import constants from 'utils/strings/constants';
import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; import { getData, LS_KEYS, setData } from 'utils/storage/localStorage';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import CryptoWorker, { import {
saveKeyInSessionStore, saveKeyInSessionStore,
generateAndSaveIntermediateKeyAttributes, generateAndSaveIntermediateKeyAttributes,
} from 'utils/crypto'; } from 'utils/crypto';
@ -19,6 +19,7 @@ import VerticallyCentered from 'components/Container';
import FormPaper from 'components/Form/FormPaper'; import FormPaper from 'components/Form/FormPaper';
import FormPaperFooter from 'components/Form/FormPaper/Footer'; import FormPaperFooter from 'components/Form/FormPaper/Footer';
import FormPaperTitle from 'components/Form/FormPaper/Title'; import FormPaperTitle from 'components/Form/FormPaper/Title';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
export default function ChangePassword() { export default function ChangePassword() {
const [token, setToken] = useState<string>(); const [token, setToken] = useState<string>();
@ -39,7 +40,7 @@ export default function ChangePassword() {
passphrase, passphrase,
setFieldError setFieldError
) => { ) => {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const key = await getActualKey(); const key = await getActualKey();
const keyAttributes: KeyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES); const keyAttributes: KeyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
const kekSalt = await cryptoWorker.generateSaltToDeriveKey(); const kekSalt = await cryptoWorker.generateSaltToDeriveKey();

View file

@ -8,10 +8,7 @@ import {
} from 'utils/storage/localStorage'; } from 'utils/storage/localStorage';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { PAGES } from 'constants/pages'; import { PAGES } from 'constants/pages';
import CryptoWorker, { import { decryptAndStoreToken, saveKeyInSessionStore } from 'utils/crypto';
decryptAndStoreToken,
saveKeyInSessionStore,
} from 'utils/crypto';
import SingleInputForm, { import SingleInputForm, {
SingleInputFormProps, SingleInputFormProps,
} from 'components/SingleInputForm'; } from 'components/SingleInputForm';
@ -24,6 +21,7 @@ import FormPaper from 'components/Form/FormPaper';
import FormPaperTitle from 'components/Form/FormPaper/Title'; import FormPaperTitle from 'components/Form/FormPaper/Title';
import FormPaperFooter from 'components/Form/FormPaper/Footer'; import FormPaperFooter from 'components/Form/FormPaper/Footer';
import LinkButton from 'components/pages/gallery/LinkButton'; import LinkButton from 'components/pages/gallery/LinkButton';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const bip39 = require('bip39'); const bip39 = require('bip39');
// mobile client library only supports english. // mobile client library only supports english.
bip39.setDefaultWordlist('english'); bip39.setDefaultWordlist('english');
@ -72,7 +70,7 @@ export default function Recover() {
} }
recoveryKey = bip39.mnemonicToEntropy(recoveryKey); recoveryKey = bip39.mnemonicToEntropy(recoveryKey);
} }
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const masterKey = await cryptoWorker.decryptB64( const masterKey = await cryptoWorker.decryptB64(
keyAttributes.masterKeyEncryptedWithRecoveryKey, keyAttributes.masterKeyEncryptedWithRecoveryKey,
keyAttributes.masterKeyDecryptionNonce, keyAttributes.masterKeyDecryptionNonce,

View file

@ -23,7 +23,6 @@ import { CustomError, parseSharingErrorCodes } from 'utils/error';
import VerticallyCentered, { CenteredFlex } from 'components/Container'; import VerticallyCentered, { CenteredFlex } from 'components/Container';
import constants from 'utils/strings/constants'; import constants from 'utils/strings/constants';
import EnteSpinner from 'components/EnteSpinner'; import EnteSpinner from 'components/EnteSpinner';
import CryptoWorker from 'utils/crypto';
import { PAGES } from 'constants/pages'; import { PAGES } from 'constants/pages';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import SingleInputForm, { import SingleInputForm, {
@ -48,6 +47,7 @@ import { logoutUser } from 'services/userService';
import UploadButton from 'components/Upload/UploadButton'; import UploadButton from 'components/Upload/UploadButton';
import bs58 from 'bs58'; import bs58 from 'bs58';
import AddPhotoAlternateOutlined from '@mui/icons-material/AddPhotoAlternateOutlined'; import AddPhotoAlternateOutlined from '@mui/icons-material/AddPhotoAlternateOutlined';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const Loader = () => ( const Loader = () => (
<VerticallyCentered> <VerticallyCentered>
@ -149,7 +149,8 @@ export default function PublicCollectionGallery() {
} }
const main = async () => { const main = async () => {
try { try {
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
url.current = window.location.href; url.current = window.location.href;
const currentURL = new URL(url.current); const currentURL = new URL(url.current);
const t = currentURL.searchParams.get('t'); const t = currentURL.searchParams.get('t');
@ -159,8 +160,8 @@ export default function PublicCollectionGallery() {
} }
const dck = const dck =
ck.length < 50 ck.length < 50
? await worker.toB64(bs58.decode(ck)) ? await cryptoWorker.toB64(bs58.decode(ck))
: await worker.fromHex(ck); : await cryptoWorker.fromHex(ck);
token.current = t; token.current = t;
collectionKey.current = dck; collectionKey.current = dck;
url.current = window.location.href; url.current = window.location.href;
@ -304,7 +305,7 @@ export default function PublicCollectionGallery() {
setFieldError setFieldError
) => { ) => {
try { try {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
let hashedPassword: string = null; let hashedPassword: string = null;
try { try {
const publicUrl = publicCollection.publicURLs[0]; const publicUrl = publicCollection.publicURLs[0];

View file

@ -2,7 +2,6 @@ import React, { useContext, useEffect, useState } from 'react';
import constants from 'utils/strings/constants'; import constants from 'utils/strings/constants';
import { getData, LS_KEYS, setData } from 'utils/storage/localStorage'; import { getData, LS_KEYS, setData } from 'utils/storage/localStorage';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import CryptoWorker from 'utils/crypto';
import SingleInputForm, { import SingleInputForm, {
SingleInputFormProps, SingleInputFormProps,
} from 'components/SingleInputForm'; } from 'components/SingleInputForm';
@ -16,6 +15,7 @@ import FormPaperTitle from 'components/Form/FormPaper/Title';
import FormPaperFooter from 'components/Form/FormPaper/Footer'; import FormPaperFooter from 'components/Form/FormPaper/Footer';
import LinkButton from 'components/pages/gallery/LinkButton'; import LinkButton from 'components/pages/gallery/LinkButton';
import { B64EncryptionResult } from 'types/crypto'; import { B64EncryptionResult } from 'types/crypto';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const bip39 = require('bip39'); const bip39 = require('bip39');
// mobile client library only supports english. // mobile client library only supports english.
bip39.setDefaultWordlist('english'); bip39.setDefaultWordlist('english');
@ -66,7 +66,7 @@ export default function Recover() {
} }
recoveryKey = bip39.mnemonicToEntropy(recoveryKey); recoveryKey = bip39.mnemonicToEntropy(recoveryKey);
} }
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const twoFactorSecret = await cryptoWorker.decryptB64( const twoFactorSecret = await cryptoWorker.decryptB64(
encryptedTwoFactorSecret.encryptedData, encryptedTwoFactorSecret.encryptedData,
encryptedTwoFactorSecret.nonce, encryptedTwoFactorSecret.nonce,

View file

@ -3,7 +3,6 @@ import { getData, LS_KEYS } from 'utils/storage/localStorage';
import localForage from 'utils/storage/localForage'; import localForage from 'utils/storage/localForage';
import { getActualKey, getToken } from 'utils/common/key'; import { getActualKey, getToken } from 'utils/common/key';
import CryptoWorker from 'utils/crypto';
import { getPublicKey } from './userService'; import { getPublicKey } from './userService';
import HTTPService from './HTTPService'; import HTTPService from './HTTPService';
import { EnteFile } from 'types/file'; import { EnteFile } from 'types/file';
@ -52,6 +51,7 @@ import {
getNonHiddenCollections, getNonHiddenCollections,
isQuickLinkCollection, isQuickLinkCollection,
} from 'utils/collection'; } from 'utils/collection';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const ENDPOINT = getEndpoint(); const ENDPOINT = getEndpoint();
const COLLECTION_TABLE = 'collections'; const COLLECTION_TABLE = 'collections';
@ -61,23 +61,23 @@ const getCollectionWithSecrets = async (
collection: EncryptedCollection, collection: EncryptedCollection,
masterKey: string masterKey: string
): Promise<Collection> => { ): Promise<Collection> => {
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const userID = getData(LS_KEYS.USER).id; const userID = getData(LS_KEYS.USER).id;
let collectionKey: string; let collectionKey: string;
if (collection.owner.id === userID) { if (collection.owner.id === userID) {
collectionKey = await worker.decryptB64( collectionKey = await cryptoWorker.decryptB64(
collection.encryptedKey, collection.encryptedKey,
collection.keyDecryptionNonce, collection.keyDecryptionNonce,
masterKey masterKey
); );
} else { } else {
const keyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES); const keyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
const secretKey = await worker.decryptB64( const secretKey = await cryptoWorker.decryptB64(
keyAttributes.encryptedSecretKey, keyAttributes.encryptedSecretKey,
keyAttributes.secretKeyDecryptionNonce, keyAttributes.secretKeyDecryptionNonce,
masterKey masterKey
); );
collectionKey = await worker.boxSealOpen( collectionKey = await cryptoWorker.boxSealOpen(
collection.encryptedKey, collection.encryptedKey,
keyAttributes.publicKey, keyAttributes.publicKey,
secretKey secretKey
@ -85,7 +85,7 @@ const getCollectionWithSecrets = async (
} }
const collectionName = const collectionName =
collection.name || collection.name ||
(await worker.decryptToUTF8( (await cryptoWorker.decryptToUTF8(
collection.encryptedName, collection.encryptedName,
collection.nameDecryptionNonce, collection.nameDecryptionNonce,
collectionKey collectionKey
@ -95,7 +95,7 @@ const getCollectionWithSecrets = async (
if (collection.magicMetadata?.data) { if (collection.magicMetadata?.data) {
collectionMagicMetadata = { collectionMagicMetadata = {
...collection.magicMetadata, ...collection.magicMetadata,
data: await worker.decryptMetadata( data: await cryptoWorker.decryptMetadata(
collection.magicMetadata.data, collection.magicMetadata.data,
collection.magicMetadata.header, collection.magicMetadata.header,
collectionKey collectionKey
@ -286,14 +286,14 @@ export const createCollection = async (
return collection; return collection;
} }
} }
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const encryptionKey = await getActualKey(); const encryptionKey = await getActualKey();
const token = getToken(); const token = getToken();
const collectionKey = await worker.generateEncryptionKey(); const collectionKey = await cryptoWorker.generateEncryptionKey();
const { encryptedData: encryptedKey, nonce: keyDecryptionNonce } = const { encryptedData: encryptedKey, nonce: keyDecryptionNonce } =
await worker.encryptToB64(collectionKey, encryptionKey); await cryptoWorker.encryptToB64(collectionKey, encryptionKey);
const { encryptedData: encryptedName, nonce: nameDecryptionNonce } = const { encryptedData: encryptedName, nonce: nameDecryptionNonce } =
await worker.encryptUTF8(collectionName, collectionKey); await cryptoWorker.encryptUTF8(collectionName, collectionKey);
const newCollection: EncryptedCollection = { const newCollection: EncryptedCollection = {
id: null, id: null,
owner: null, owner: null,
@ -456,9 +456,9 @@ const encryptWithNewCollectionKey = async (
files: EnteFile[] files: EnteFile[]
): Promise<EncryptedFileKey[]> => { ): Promise<EncryptedFileKey[]> => {
const fileKeysEncryptedWithNewCollection: EncryptedFileKey[] = []; const fileKeysEncryptedWithNewCollection: EncryptedFileKey[] = [];
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
for (const file of files) { for (const file of files) {
const newEncryptedKey = await worker.encryptToB64( const newEncryptedKey = await cryptoWorker.encryptToB64(
file.key, file.key,
newCollection.key newCollection.key
); );
@ -518,9 +518,9 @@ export const updateCollectionMagicMetadata = async (collection: Collection) => {
return; return;
} }
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const { file: encryptedMagicMetadata } = await worker.encryptMetadata( const { file: encryptedMagicMetadata } = await cryptoWorker.encryptMetadata(
collection.magicMetadata.data, collection.magicMetadata.data,
collection.key collection.key
); );
@ -562,9 +562,9 @@ export const renameCollection = async (
await updateCollectionSubType(collection, SUB_TYPE.DEFAULT); await updateCollectionSubType(collection, SUB_TYPE.DEFAULT);
} }
const token = getToken(); const token = getToken();
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const { encryptedData: encryptedName, nonce: nameDecryptionNonce } = const { encryptedData: encryptedName, nonce: nameDecryptionNonce } =
await worker.encryptUTF8(newCollectionName, collection.key); await cryptoWorker.encryptUTF8(newCollectionName, collection.key);
const collectionRenameRequest = { const collectionRenameRequest = {
collectionID: collection.id, collectionID: collection.id,
encryptedName, encryptedName,
@ -603,11 +603,13 @@ export const shareCollection = async (
withUserEmail: string withUserEmail: string
) => { ) => {
try { try {
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const token = getToken(); const token = getToken();
const publicKey: string = await getPublicKey(withUserEmail); const publicKey: string = await getPublicKey(withUserEmail);
const encryptedKey = await worker.boxSeal(collection.key, publicKey); const encryptedKey = await cryptoWorker.boxSeal(
collection.key,
publicKey
);
const shareCollectionRequest = { const shareCollectionRequest = {
collectionID: collection.id, collectionID: collection.id,
email: withUserEmail, email: withUserEmail,

View file

@ -1,6 +1,5 @@
import { getToken } from 'utils/common/key'; import { getToken } from 'utils/common/key';
import { getFileURL, getThumbnailURL } from 'utils/common/apiUtil'; import { getFileURL, getThumbnailURL } from 'utils/common/apiUtil';
import CryptoWorker from 'utils/crypto';
import { import {
generateStreamFromArrayBuffer, generateStreamFromArrayBuffer,
getRenderableFileURL, getRenderableFileURL,
@ -14,6 +13,7 @@ import { FILE_TYPE } from 'constants/file';
import { CustomError } from 'utils/error'; import { CustomError } from 'utils/error';
import { openThumbnailCache } from './cacheService'; import { openThumbnailCache } from './cacheService';
import QueueProcessor, { PROCESSING_STRATEGY } from './queueProcessor'; import QueueProcessor, { PROCESSING_STRATEGY } from './queueProcessor';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const MAX_PARALLEL_DOWNLOADS = 10; const MAX_PARALLEL_DOWNLOADS = 10;
@ -80,10 +80,10 @@ class DownloadManager {
if (typeof resp.data === 'undefined') { if (typeof resp.data === 'undefined') {
throw Error(CustomError.REQUEST_FAILED); throw Error(CustomError.REQUEST_FAILED);
} }
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const decrypted = await worker.decryptThumbnail( const decrypted = await cryptoWorker.decryptThumbnail(
new Uint8Array(resp.data), new Uint8Array(resp.data),
await worker.fromB64(file.thumbnail.decryptionHeader), await cryptoWorker.fromB64(file.thumbnail.decryptionHeader),
file.key file.key
); );
return decrypted; return decrypted;
@ -122,7 +122,8 @@ class DownloadManager {
} }
async downloadFile(file: EnteFile) { async downloadFile(file: EnteFile) {
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const token = getToken(); const token = getToken();
if (!token) { if (!token) {
return null; return null;
@ -140,9 +141,9 @@ class DownloadManager {
if (typeof resp.data === 'undefined') { if (typeof resp.data === 'undefined') {
throw Error(CustomError.REQUEST_FAILED); throw Error(CustomError.REQUEST_FAILED);
} }
const decrypted = await worker.decryptFile( const decrypted = await cryptoWorker.decryptFile(
new Uint8Array(resp.data), new Uint8Array(resp.data),
await worker.fromB64(file.file.decryptionHeader), await cryptoWorker.fromB64(file.file.decryptionHeader),
file.key file.key
); );
return generateStreamFromArrayBuffer(decrypted); return generateStreamFromArrayBuffer(decrypted);
@ -155,12 +156,15 @@ class DownloadManager {
const reader = resp.body.getReader(); const reader = resp.body.getReader();
const stream = new ReadableStream({ const stream = new ReadableStream({
async start(controller) { async start(controller) {
const decryptionHeader = await worker.fromB64( const decryptionHeader = await cryptoWorker.fromB64(
file.file.decryptionHeader file.file.decryptionHeader
); );
const fileKey = await worker.fromB64(file.key); const fileKey = await cryptoWorker.fromB64(file.key);
const { pullState, decryptionChunkSize } = const { pullState, decryptionChunkSize } =
await worker.initDecryption(decryptionHeader, fileKey); await cryptoWorker.initDecryption(
decryptionHeader,
fileKey
);
let data = new Uint8Array(); let data = new Uint8Array();
// The following function handles each data chunk // The following function handles each data chunk
function push() { function push() {
@ -179,7 +183,7 @@ class DownloadManager {
decryptionChunkSize decryptionChunkSize
); );
const { decryptedData } = const { decryptedData } =
await worker.decryptChunk( await cryptoWorker.decryptChunk(
fileData, fileData,
pullState pullState
); );
@ -192,7 +196,10 @@ class DownloadManager {
} else { } else {
if (data) { if (data) {
const { decryptedData } = const { decryptedData } =
await worker.decryptChunk(data, pullState); await cryptoWorker.decryptChunk(
data,
pullState
);
controller.enqueue(decryptedData); controller.enqueue(decryptedData);
data = null; data = null;
} }

View file

@ -11,7 +11,6 @@ import {
preservePhotoswipeProps, preservePhotoswipeProps,
sortFiles, sortFiles,
} from 'utils/file'; } from 'utils/file';
import CryptoWorker from 'utils/crypto';
import { EnteFile, EncryptedEnteFile, TrashRequest } from 'types/file'; import { EnteFile, EncryptedEnteFile, TrashRequest } from 'types/file';
import { SetFiles } from 'types/gallery'; import { SetFiles } from 'types/gallery';
import { MAX_TRASH_BATCH_SIZE } from 'constants/file'; import { MAX_TRASH_BATCH_SIZE } from 'constants/file';
@ -19,6 +18,7 @@ import { BulkUpdateMagicMetadataRequest } from 'types/magicMetadata';
import { addLogLine } from 'utils/logging'; import { addLogLine } from 'utils/logging';
import { isCollectionHidden } from 'utils/collection'; import { isCollectionHidden } from 'utils/collection';
import { CustomError } from 'utils/error'; import { CustomError } from 'utils/error';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const ENDPOINT = getEndpoint(); const ENDPOINT = getEndpoint();
const FILES_TABLE = 'files'; const FILES_TABLE = 'files';
@ -250,9 +250,10 @@ export const updateFileMagicMetadata = async (files: EnteFile[]) => {
return; return;
} }
const reqBody: BulkUpdateMagicMetadataRequest = { metadataList: [] }; const reqBody: BulkUpdateMagicMetadataRequest = { metadataList: [] };
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
for (const file of files) { for (const file of files) {
const { file: encryptedMagicMetadata } = await worker.encryptMetadata( const { file: encryptedMagicMetadata } =
await cryptoWorker.encryptMetadata(
file.magicMetadata.data, file.magicMetadata.data,
file.key file.key
); );
@ -286,10 +287,13 @@ export const updateFilePublicMagicMetadata = async (files: EnteFile[]) => {
return; return;
} }
const reqBody: BulkUpdateMagicMetadataRequest = { metadataList: [] }; const reqBody: BulkUpdateMagicMetadataRequest = { metadataList: [] };
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
for (const file of files) { for (const file of files) {
const { file: encryptedPubMagicMetadata } = const { file: encryptedPubMagicMetadata } =
await worker.encryptMetadata(file.pubMagicMetadata.data, file.key); await cryptoWorker.encryptMetadata(
file.pubMagicMetadata.data,
file.key
);
reqBody.metadataList.push({ reqBody.metadataList.push({
id: file.id, id: file.id,
magicMetadata: { magicMetadata: {

View file

@ -5,7 +5,6 @@ import { getToken } from 'utils/common/key';
import { logError } from 'utils/sentry'; import { logError } from 'utils/sentry';
import { getEndpoint } from 'utils/common/apiUtil'; import { getEndpoint } from 'utils/common/apiUtil';
import HTTPService from 'services/HTTPService'; import HTTPService from 'services/HTTPService';
import CryptoWorker from 'utils/crypto';
import uploadHttpClient from 'services/upload/uploadHttpClient'; import uploadHttpClient from 'services/upload/uploadHttpClient';
import { SetProgressTracker } from 'components/FixLargeThumbnail'; import { SetProgressTracker } from 'components/FixLargeThumbnail';
import { getFileType } from 'services/typeDetectionService'; import { getFileType } from 'services/typeDetectionService';
@ -15,6 +14,7 @@ import { FileAttributes } from 'types/file';
import { USE_CF_PROXY } from 'constants/upload'; import { USE_CF_PROXY } from 'constants/upload';
import { Remote } from 'comlink'; import { Remote } from 'comlink';
import { DedicatedCryptoWorker } from 'worker/crypto.worker'; import { DedicatedCryptoWorker } from 'worker/crypto.worker';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const ENDPOINT = getEndpoint(); const ENDPOINT = getEndpoint();
const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB const REPLACE_THUMBNAIL_THRESHOLD = 500 * 1024; // 500KB
@ -46,7 +46,7 @@ export async function replaceThumbnail(
let completedWithError = false; let completedWithError = false;
try { try {
const token = getToken(); const token = getToken();
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const files = await getLocalFiles(); const files = await getLocalFiles();
const trash = await getLocalTrash(); const trash = await getLocalTrash();
const trashFiles = getTrashedFiles(trash); const trashFiles = getTrashedFiles(trash);
@ -85,7 +85,7 @@ export async function replaceThumbnail(
fileTypeInfo fileTypeInfo
); );
const newUploadedThumbnail = await uploadThumbnail( const newUploadedThumbnail = await uploadThumbnail(
worker, cryptoWorker,
file.key, file.key,
newThumbnail, newThumbnail,
uploadURLs.pop() uploadURLs.pop()

View file

@ -2,7 +2,6 @@ import {
getPublicCollectionFileURL, getPublicCollectionFileURL,
getPublicCollectionThumbnailURL, getPublicCollectionThumbnailURL,
} from 'utils/common/apiUtil'; } from 'utils/common/apiUtil';
import CryptoWorker from 'utils/crypto';
import { import {
generateStreamFromArrayBuffer, generateStreamFromArrayBuffer,
getRenderableFileURL, getRenderableFileURL,
@ -15,6 +14,7 @@ import { logError } from 'utils/sentry';
import { FILE_TYPE } from 'constants/file'; import { FILE_TYPE } from 'constants/file';
import { CustomError } from 'utils/error'; import { CustomError } from 'utils/error';
import QueueProcessor from './queueProcessor'; import QueueProcessor from './queueProcessor';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
class PublicCollectionDownloadManager { class PublicCollectionDownloadManager {
private fileObjectURLPromise = new Map< private fileObjectURLPromise = new Map<
@ -97,10 +97,10 @@ class PublicCollectionDownloadManager {
if (typeof resp.data === 'undefined') { if (typeof resp.data === 'undefined') {
throw Error(CustomError.REQUEST_FAILED); throw Error(CustomError.REQUEST_FAILED);
} }
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const decrypted = await worker.decryptThumbnail( const decrypted = await cryptoWorker.decryptThumbnail(
new Uint8Array(resp.data), new Uint8Array(resp.data),
await worker.fromB64(file.thumbnail.decryptionHeader), await cryptoWorker.fromB64(file.thumbnail.decryptionHeader),
file.key file.key
); );
return decrypted; return decrypted;
@ -148,7 +148,7 @@ class PublicCollectionDownloadManager {
} }
async downloadFile(token: string, passwordToken: string, file: EnteFile) { async downloadFile(token: string, passwordToken: string, file: EnteFile) {
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
if (!token) { if (!token) {
return null; return null;
} }
@ -170,9 +170,9 @@ class PublicCollectionDownloadManager {
if (typeof resp.data === 'undefined') { if (typeof resp.data === 'undefined') {
throw Error(CustomError.REQUEST_FAILED); throw Error(CustomError.REQUEST_FAILED);
} }
const decrypted = await worker.decryptFile( const decrypted = await cryptoWorker.decryptFile(
new Uint8Array(resp.data), new Uint8Array(resp.data),
await worker.fromB64(file.file.decryptionHeader), await cryptoWorker.fromB64(file.file.decryptionHeader),
file.key file.key
); );
return generateStreamFromArrayBuffer(decrypted); return generateStreamFromArrayBuffer(decrypted);
@ -188,12 +188,15 @@ class PublicCollectionDownloadManager {
const reader = resp.body.getReader(); const reader = resp.body.getReader();
const stream = new ReadableStream({ const stream = new ReadableStream({
async start(controller) { async start(controller) {
const decryptionHeader = await worker.fromB64( const decryptionHeader = await cryptoWorker.fromB64(
file.file.decryptionHeader file.file.decryptionHeader
); );
const fileKey = await worker.fromB64(file.key); const fileKey = await cryptoWorker.fromB64(file.key);
const { pullState, decryptionChunkSize } = const { pullState, decryptionChunkSize } =
await worker.initDecryption(decryptionHeader, fileKey); await cryptoWorker.initDecryption(
decryptionHeader,
fileKey
);
let data = new Uint8Array(); let data = new Uint8Array();
// The following function handles each data chunk // The following function handles each data chunk
function push() { function push() {
@ -212,7 +215,7 @@ class PublicCollectionDownloadManager {
decryptionChunkSize decryptionChunkSize
); );
const { decryptedData } = const { decryptedData } =
await worker.decryptChunk( await cryptoWorker.decryptChunk(
fileData, fileData,
pullState pullState
); );
@ -225,7 +228,10 @@ class PublicCollectionDownloadManager {
} else { } else {
if (data) { if (data) {
const { decryptedData } = const { decryptedData } =
await worker.decryptChunk(data, pullState); await cryptoWorker.decryptChunk(
data,
pullState
);
controller.enqueue(decryptedData); controller.enqueue(decryptedData);
data = null; data = null;
} }

View file

@ -10,9 +10,9 @@ import {
AbuseReportRequest, AbuseReportRequest,
LocalSavedPublicCollectionFiles, LocalSavedPublicCollectionFiles,
} from 'types/publicCollection'; } from 'types/publicCollection';
import CryptoWorker from 'utils/crypto';
import { REPORT_REASON } from 'constants/publicCollection'; import { REPORT_REASON } from 'constants/publicCollection';
import { CustomError, parseSharingErrorCodes } from 'utils/error'; import { CustomError, parseSharingErrorCodes } from 'utils/error';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const ENDPOINT = getEndpoint(); const ENDPOINT = getEndpoint();
const PUBLIC_COLLECTION_FILES_TABLE = 'public-collection-files'; const PUBLIC_COLLECTION_FILES_TABLE = 'public-collection-files';
@ -343,11 +343,11 @@ const decryptCollectionName = async (
collection: EncryptedCollection, collection: EncryptedCollection,
collectionKey: string collectionKey: string
) => { ) => {
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
return (collection.name = return (collection.name =
collection.name || collection.name ||
(await worker.decryptToUTF8( (await cryptoWorker.decryptToUTF8(
collection.encryptedName, collection.encryptedName,
collection.nameDecryptionNonce, collection.nameDecryptionNonce,
collectionKey collectionKey

View file

@ -1,5 +1,5 @@
import { B64EncryptionResult } from 'types/crypto'; import { B64EncryptionResult } from 'types/crypto';
import CryptoWorker from 'utils/crypto'; import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { getData, LS_KEYS } from 'utils/storage/localStorage';
import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage'; import { getKey, SESSION_KEYS } from 'utils/storage/sessionStorage';
import { CustomError } from '../error'; import { CustomError } from '../error';
@ -10,7 +10,7 @@ export const getActualKey = async () => {
SESSION_KEYS.ENCRYPTION_KEY SESSION_KEYS.ENCRYPTION_KEY
); );
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const key = await cryptoWorker.decryptB64( const key = await cryptoWorker.decryptB64(
encryptionKeyAttributes.encryptedData, encryptionKeyAttributes.encryptedData,
encryptionKeyAttributes.nonce, encryptionKeyAttributes.nonce,

View file

@ -6,12 +6,12 @@ import { setRecoveryKey } from 'services/userService';
import { logError } from 'utils/sentry'; import { logError } from 'utils/sentry';
import isElectron from 'is-electron'; import isElectron from 'is-electron';
import safeStorageService from 'services/electron/safeStorage'; import safeStorageService from 'services/electron/safeStorage';
import { CryptoWorker } from 'utils/comlink'; import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
export async function generateKeyAttributes( export async function generateKeyAttributes(
passphrase: string passphrase: string
): Promise<{ keyAttributes: KeyAttributes; masterKey: string }> { ): Promise<{ keyAttributes: KeyAttributes; masterKey: string }> {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const masterKey = await cryptoWorker.generateEncryptionKey(); const masterKey = await cryptoWorker.generateEncryptionKey();
const recoveryKey = await cryptoWorker.generateEncryptionKey(); const recoveryKey = await cryptoWorker.generateEncryptionKey();
const kekSalt = await cryptoWorker.generateSaltToDeriveKey(); const kekSalt = await cryptoWorker.generateSaltToDeriveKey();
@ -61,7 +61,7 @@ export async function generateAndSaveIntermediateKeyAttributes(
existingKeyAttributes: KeyAttributes, existingKeyAttributes: KeyAttributes,
key: string key: string
): Promise<KeyAttributes> { ): Promise<KeyAttributes> {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const intermediateKekSalt = await cryptoWorker.generateSaltToDeriveKey(); const intermediateKekSalt = await cryptoWorker.generateSaltToDeriveKey();
const intermediateKek = await cryptoWorker.deriveInteractiveKey( const intermediateKek = await cryptoWorker.deriveInteractiveKey(
passphrase, passphrase,
@ -88,7 +88,7 @@ export const saveKeyInSessionStore = async (
key: string, key: string,
fromDesktop?: boolean fromDesktop?: boolean
) => { ) => {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const sessionKeyAttributes = await cryptoWorker.encryptToB64(key); const sessionKeyAttributes = await cryptoWorker.encryptToB64(key);
setKey(keyType, sessionKeyAttributes); setKey(keyType, sessionKeyAttributes);
if (isElectron() && !fromDesktop) { if (isElectron() && !fromDesktop) {
@ -99,7 +99,7 @@ export const saveKeyInSessionStore = async (
export const getRecoveryKey = async () => { export const getRecoveryKey = async () => {
let recoveryKey: string = null; let recoveryKey: string = null;
try { try {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const keyAttributes: KeyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES); const keyAttributes: KeyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
const { const {
@ -128,7 +128,7 @@ async function createNewRecoveryKey() {
const masterKey = await getActualKey(); const masterKey = await getActualKey();
const existingAttributes = getData(LS_KEYS.KEY_ATTRIBUTES); const existingAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const recoveryKey = await cryptoWorker.generateEncryptionKey(); const recoveryKey = await cryptoWorker.generateEncryptionKey();
const encryptedMasterKey = await cryptoWorker.encryptToB64( const encryptedMasterKey = await cryptoWorker.encryptToB64(
@ -156,7 +156,7 @@ async function createNewRecoveryKey() {
return recoveryKey; return recoveryKey;
} }
export async function decryptAndStoreToken(masterKey: string) { export async function decryptAndStoreToken(masterKey: string) {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const user = getData(LS_KEYS.USER); const user = getData(LS_KEYS.USER);
const keyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES); const keyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
let decryptedToken = null; let decryptedToken = null;
@ -185,7 +185,7 @@ export async function decryptAndStoreToken(masterKey: string) {
} }
export async function encryptWithRecoveryKey(key: string) { export async function encryptWithRecoveryKey(key: string) {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const hexRecoveryKey = await getRecoveryKey(); const hexRecoveryKey = await getRecoveryKey();
const recoveryKey = await cryptoWorker.fromHex(hexRecoveryKey); const recoveryKey = await cryptoWorker.fromHex(hexRecoveryKey);
const encryptedKey = await cryptoWorker.encryptToB64(key, recoveryKey); const encryptedKey = await cryptoWorker.encryptToB64(key, recoveryKey);
@ -195,7 +195,7 @@ export async function encryptWithRecoveryKey(key: string) {
export async function decryptDeleteAccountChallenge( export async function decryptDeleteAccountChallenge(
encryptedChallenge: string encryptedChallenge: string
) { ) {
const cryptoWorker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
const masterKey = await getActualKey(); const masterKey = await getActualKey();
const keyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES); const keyAttributes = getData(LS_KEYS.KEY_ATTRIBUTES);
const secretKey = await cryptoWorker.decryptB64( const secretKey = await cryptoWorker.decryptB64(
@ -211,4 +211,3 @@ export async function decryptDeleteAccountChallenge(
const utf8DecryptedChallenge = atob(b64DecryptedChallenge); const utf8DecryptedChallenge = atob(b64DecryptedChallenge);
return utf8DecryptedChallenge; return utf8DecryptedChallenge;
} }
export default CryptoWorker;

View file

@ -5,7 +5,6 @@ import { getFileType } from 'services/typeDetectionService';
import DownloadManager from 'services/downloadManager'; import DownloadManager from 'services/downloadManager';
import { logError } from 'utils/sentry'; import { logError } from 'utils/sentry';
import { User } from 'types/user'; import { User } from 'types/user';
import CryptoWorker from 'utils/crypto';
import { getData, LS_KEYS } from 'utils/storage/localStorage'; import { getData, LS_KEYS } from 'utils/storage/localStorage';
import { updateFileCreationDateInEXIF } from 'services/upload/exifService'; import { updateFileCreationDateInEXIF } from 'services/upload/exifService';
import { import {
@ -31,6 +30,7 @@ import { IsArchived, updateMagicMetadataProps } from 'utils/magicMetadata';
import { addLogLine } from 'utils/logging'; import { addLogLine } from 'utils/logging';
import { CustomError } from 'utils/error'; import { CustomError } from 'utils/error';
import { convertBytesToHumanReadable } from './size'; import { convertBytesToHumanReadable } from './size';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000; const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000;
@ -198,7 +198,7 @@ export async function decryptFile(
collectionKey: string collectionKey: string
): Promise<EnteFile> { ): Promise<EnteFile> {
try { try {
const worker = await new CryptoWorker(); const worker = await ComlinkCryptoWorker.getInstance();
const { const {
encryptedKey, encryptedKey,
keyDecryptionNonce, keyDecryptionNonce,

View file

@ -5,7 +5,7 @@ import {
MagicMetadataCore, MagicMetadataCore,
VISIBILITY_STATE, VISIBILITY_STATE,
} from 'types/magicMetadata'; } from 'types/magicMetadata';
import CryptoWorker from 'utils/crypto'; import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
export function IsArchived(item: Collection | EnteFile) { export function IsArchived(item: Collection | EnteFile) {
if ( if (
@ -25,13 +25,13 @@ export async function updateMagicMetadataProps(
decryptionKey: string, decryptionKey: string,
magicMetadataUpdates: Record<string, any> magicMetadataUpdates: Record<string, any>
) { ) {
const worker = await new CryptoWorker(); const cryptoWorker = await ComlinkCryptoWorker.getInstance();
if (!originalMagicMetadata) { if (!originalMagicMetadata) {
throw Error('invalid originalMagicMetadata '); throw Error('invalid originalMagicMetadata ');
} }
if (typeof originalMagicMetadata.data === 'string') { if (typeof originalMagicMetadata.data === 'string') {
originalMagicMetadata.data = (await worker.decryptMetadata( originalMagicMetadata.data = (await cryptoWorker.decryptMetadata(
originalMagicMetadata.data, originalMagicMetadata.data,
originalMagicMetadata.header, originalMagicMetadata.header,
decryptionKey decryptionKey