do local attachments decrypt/encrypt in worker

pull/1783/head
Audric Ackermann 4 years ago
parent e8f0c4aaec
commit 4ec1392aec
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -29,6 +29,9 @@ module.exports = grunt => {
'node_modules/bytebuffer/dist/bytebuffer.js',
'js/curve/curve25519_compiled.js',
'js/curve/curve25519_wrapper.js',
'node_modules/libsodium/dist/modules/libsodium.js',
'node_modules/libsodium-wrappers/dist/modules/libsodium-wrappers.js',
'libtextsecure/libsignal-protocol.js',
'js/util_worker_tasks.js',
];

@ -1,5 +1,5 @@
/* eslint-env browser */
/* global dcodeIO, libsignal */
/* global dcodeIO */
/* eslint-disable camelcase, no-bitwise */

@ -1,15 +1,18 @@
/* global dcodeIO, Internal */
/* global dcodeIO, Internal, libsignal, sodium */
/* eslint-disable no-console */
/* eslint-disable strict */
const functions = {
arrayBufferToStringBase64,
fromBase64ToArrayBuffer,
fromHexToArrayBuffer,
verifySignature,
DecryptAESGCM,
deriveSymmetricKey,
encryptForPubkey,
generateEphemeralKeyPair,
decryptAttachmentBuffer,
encryptAttachmentBuffer,
};
onmessage = async e => {
@ -196,3 +199,65 @@ async function DecryptAESGCM(symmetricKey, ivAndCiphertext) {
return crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, key, ciphertext);
}
async function getSodium() {
await sodium.ready;
return sodium;
}
// Uint8Array, ArrayBuffer
async function decryptAttachmentBuffer(encryptingKey, bufferIn) {
const sodium = await getSodium();
const header = new Uint8Array(
bufferIn.slice(0, sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES)
);
const encryptedBuffer = new Uint8Array(
bufferIn.slice(sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES)
);
try {
/* Decrypt the stream: initializes the state, using the key and a header */
const state = sodium.crypto_secretstream_xchacha20poly1305_init_pull(header, encryptingKey);
// what if ^ this call fail (? try to load as a unencrypted attachment?)
const messageTag = sodium.crypto_secretstream_xchacha20poly1305_pull(state, encryptedBuffer);
// we expect the final tag to be there. If not, we might have an issue with this file
// maybe not encrypted locally?
if (messageTag.tag === sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
return messageTag.message;
}
} catch (e) {
console.warn('Failed to load the file as an encrypted one', e);
}
return new Uint8Array();
}
// Uint8Array, ArrayBuffer
async function encryptAttachmentBuffer(encryptingKey, bufferIn) {
const sodium = await getSodium();
try {
const uintArrayIn = new Uint8Array(bufferIn);
/* Set up a new stream: initialize the state and create the header */
const { state, header } = sodium.crypto_secretstream_xchacha20poly1305_init_push(encryptingKey);
/* Now, encrypt the buffer. */
const bufferOut = sodium.crypto_secretstream_xchacha20poly1305_push(
state,
uintArrayIn,
null,
sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL
);
const encryptedBufferWithHeader = new Uint8Array(bufferOut.length + header.length);
encryptedBufferWithHeader.set(header);
encryptedBufferWithHeader.set(bufferOut, header.length);
return { encryptedBufferWithHeader, header };
} catch (e) {
console.warn('encryptAttachmentBuffer error: ', e);
return null;
}
}

@ -75,13 +75,6 @@ const { createTemplate } = require('./app/menu');
const { installFileHandler, installWebHandler } = require('./app/protocol_filter');
const { installPermissionsHandler } = require('./app/permissions');
const _sodium = require('libsodium-wrappers');
async function getSodium() {
await _sodium.ready;
return _sodium;
}
let appStartInitialSpellcheckSetting = true;
async function getSpellCheckSetting() {

@ -400,60 +400,18 @@ export const encryptAttachmentBuffer = async (bufferIn: ArrayBuffer) => {
if (!isArrayBuffer(bufferIn)) {
throw new TypeError("'bufferIn' must be an array buffer");
}
const uintArrayIn = new Uint8Array(bufferIn);
const sodium = await getSodium();
const encryptingKey = window.textsecure.storage.get('local_attachment_encrypted_key');
/* Set up a new stream: initialize the state and create the header */
const { state, header } = sodium.crypto_secretstream_xchacha20poly1305_init_push(
fromHexToArray(encryptingKey)
);
/* Now, encrypt the buffer. */
const bufferOut = sodium.crypto_secretstream_xchacha20poly1305_push(
state,
uintArrayIn,
null,
sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL
const encryptingKey = fromHexToArray(
window.textsecure.storage.get('local_attachment_encrypted_key')
);
const encryptedBufferWithHeader = new Uint8Array(bufferOut.length + header.length);
encryptedBufferWithHeader.set(header);
encryptedBufferWithHeader.set(bufferOut, header.length);
return { encryptedBufferWithHeader, header };
return window.callWorker('encryptAttachmentBuffer', encryptingKey, bufferIn);
};
export const decryptAttachmentBuffer = async (bufferIn: ArrayBuffer): Promise<Uint8Array> => {
if (!isArrayBuffer(bufferIn)) {
throw new TypeError("'bufferIn' must be an array buffer");
}
const sodium = await getSodium();
const encryptingKey = window.textsecure.storage.get('local_attachment_encrypted_key');
const header = new Uint8Array(
bufferIn.slice(0, sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES)
);
const encryptedBuffer = new Uint8Array(
bufferIn.slice(sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES)
const encryptingKey = fromHexToArray(
window.textsecure.storage.get('local_attachment_encrypted_key')
);
try {
/* Decrypt the stream: initializes the state, using the key and a header */
const state = sodium.crypto_secretstream_xchacha20poly1305_init_pull(
header,
fromHexToArray(encryptingKey)
);
// what if ^ this call fail (? try to load as a unencrypted attachment?)
const messageTag = sodium.crypto_secretstream_xchacha20poly1305_pull(state, encryptedBuffer);
// we expect the final tag to be there. If not, we might have an issue with this file
// maybe not encrypted locally?
if (messageTag.tag === sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
return messageTag.message;
}
} catch (e) {
window?.log?.warn('Failed to load the file as an encrypted one', e);
}
return new Uint8Array();
return window.callWorker('decryptAttachmentBuffer', encryptingKey, bufferIn);
};

Loading…
Cancel
Save