generate attachment key on migration

This commit is contained in:
Audric Ackermann 2021-04-14 10:33:52 +10:00
parent 050739b0ab
commit 42f0d21740
No known key found for this signature in database
GPG key ID: 999F434D76324AD4
7 changed files with 34 additions and 26 deletions

View file

@ -1314,8 +1314,8 @@ async function updateGuardNodes(nodes) {
// irrespective of their Primary or Secondary status.
const ITEMS_TABLE = 'items';
async function createOrUpdateItem(data) {
return createOrUpdate(ITEMS_TABLE, data);
async function createOrUpdateItem(data, instance) {
return createOrUpdate(ITEMS_TABLE, data, instance);
}
async function getItemById(id) {
return getById(ITEMS_TABLE, id);
@ -1328,13 +1328,13 @@ async function removeItemById(id) {
return removeById(ITEMS_TABLE, id);
}
async function createOrUpdate(table, data) {
async function createOrUpdate(table, data, instance) {
const { id } = data;
if (!id) {
throw new Error('createOrUpdate: Provided data did not have a truthy id');
}
await db.run(
await (db || instance).run(
`INSERT OR REPLACE INTO ${table} (
id,
json

View file

@ -11,7 +11,6 @@ const {
saveMessage,
setAttachmentDownloadJobPending,
} = require('../../ts/data/data');
const { stringFromBytes } = require('./crypto');
module.exports = {
start,

View file

@ -3,14 +3,10 @@
const loadImage = require('blueimp-load-image');
const { toLogFormat } = require('./errors');
const toArrayBuffer = require('to-arraybuffer');
const dataURLToBlobSync = require('blueimp-canvas-to-blob');
const fse = require('fs-extra');
const { blobToArrayBuffer } = require('blob-util');
const AttachmentTS = require('../../../ts/types/Attachment');
const DecryptedAttachmentsManager = require('../../../ts/session/crypto/DecryptedAttachmentsManager');
exports.blobToArrayBuffer = blobToArrayBuffer;
@ -29,7 +25,7 @@ exports.getImageDimensions = ({ objectUrl, logger }) =>
logger.error('getImageDimensions error', toLogFormat(error));
reject(error);
});
//FIXME image/jpeg is hard coded
// TODO image/jpeg is hard coded, but it does not look to cause any issues
DecryptedAttachmentsManager.getDecryptedMediaUrl(
objectUrl,
'image/jpg'
@ -117,11 +113,10 @@ exports.makeVideoScreenshot = ({
logger.error('makeVideoScreenshot error', toLogFormat(error));
reject(error);
});
//FIXME image/jpeg is hard coded
DecryptedAttachmentsManager.getDecryptedMediaUrl(
objectUrl,
'image/jpg'
contentType
).then(decryptedUrl => {
video.src = decryptedUrl;
video.muted = true;

View file

@ -8,6 +8,7 @@ import { UserUtils } from '../../session/utils';
import { syncConfigurationIfNeeded } from '../../session/utils/syncUtils';
import { DAYS, MINUTES, SECONDS } from '../../session/utils/Number';
import {
generateAttachmentKeyIfEmpty,
getItemById,
hasSyncedInitialConfigurationItem,
removeItemById,
@ -29,6 +30,7 @@ import { clearSearch } from '../../state/ducks/search';
import { showLeftPaneSection } from '../../state/ducks/section';
import { cleanUpOldDecryptedMedias } from '../../session/crypto/DecryptedAttachmentsManager';
import { useTimeoutFn } from 'react-use';
import { getSodium } from '../../session/crypto';
// tslint:disable-next-line: no-import-side-effect no-submodule-imports
export enum SectionType {
@ -176,7 +178,7 @@ export const ActionsPanel = () => {
await syncConfigurationIfNeeded();
}
};
void generateAttachmentKeyIfEmpty();
// trigger a sync message if needed for our other devices
void syncConfiguration();
}, []);

View file

@ -11,6 +11,7 @@ import {
import { MessageCollection, MessageModel } from '../models/message';
import { MessageAttributes } from '../models/messageType';
import { HexKeyPair } from '../receiver/keypairs';
import { getSodium } from '../session/crypto';
import { PubKey } from '../session/types';
import {
fromArrayBufferToBase64,
@ -482,6 +483,19 @@ export async function getItemById(
return Array.isArray(keys) ? keysToArrayBuffer(keys, data) : data;
}
export async function generateAttachmentKeyIfEmpty() {
const existingKey = await getItemById('local_attachment_encrypted_key');
if (!existingKey) {
const sodium = await getSodium();
const encryptingKey = sodium.to_hex(sodium.randombytes_buf(32));
await createOrUpdateItem({
id: 'local_attachment_encrypted_key',
value: encryptingKey,
});
}
}
export async function getAllItems(): Promise<Array<StorageItem>> {
const items = await channels.getAllItems();
return _.map(items, item => {

View file

@ -9,13 +9,11 @@
import toArrayBuffer from 'to-arraybuffer';
import * as fse from 'fs-extra';
import { decryptAttachmentBuffer } from '../../types/Attachment';
import { HOURS, MINUTES, SECONDS } from '../utils/Number';
import { HOURS } from '../utils/Number';
// FIXME.
// add a way to clean those from time to time (like every hours?)
// add a way to remove the blob when the attachment file path is removed (message removed?)
// do not hardcode the password
// a few FIXME image/jpeg is hard coded
const urlToDecryptedBlobMap = new Map<
string,
{ decrypted: string; lastAccessTimestamp: number }

View file

@ -426,20 +426,17 @@ export const encryptAttachmentBuffer = async (bufferIn: ArrayBuffer) => {
const uintArrayIn = new Uint8Array(bufferIn);
const sodium = await getSodium();
/* Shared secret key required to encrypt/decrypt the stream */
// const key = sodium.crypto_secretstream_xchacha20poly1305_keygen();
const key = fromHexToArray(
'0c5f7147b6d3239cbb5a418814cee1bfca2df5c94bffddf22ee37eea3ede972b'
const encryptingKey = window.textsecure.storage.get(
'local_attachment_encrypted_key'
);
console.warn('key', toHex(key));
/* Set up a new stream: initialize the state and create the header */
const {
state,
header,
} = sodium.crypto_secretstream_xchacha20poly1305_init_push(key);
} = sodium.crypto_secretstream_xchacha20poly1305_init_push(
fromHexToArray(encryptingKey)
);
/* Now, encrypt the buffer. */
const bufferOut = sodium.crypto_secretstream_xchacha20poly1305_push(
state,
@ -454,7 +451,7 @@ export const encryptAttachmentBuffer = async (bufferIn: ArrayBuffer) => {
encryptedBufferWithHeader.set(header);
encryptedBufferWithHeader.set(bufferOut, header.length);
return { encryptedBufferWithHeader, header, key };
return { encryptedBufferWithHeader, header };
};
export const decryptAttachmentBuffer = async (
@ -465,6 +462,9 @@ export const decryptAttachmentBuffer = async (
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)
@ -476,7 +476,7 @@ export const decryptAttachmentBuffer = async (
/* Decrypt the stream: initializes the state, using the key and a header */
const state = sodium.crypto_secretstream_xchacha20poly1305_init_pull(
header,
fromHexToArray(key)
fromHexToArray(encryptingKey)
);
// what if ^ this call fail (? try to load as a unencrypted attachment?)