From 3ae1ac6118276d53b0efbf6770cf215a263f3c89 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Mon, 12 Jul 2021 10:38:03 +1000 Subject: [PATCH] remove unused libsignal stuff --- js/util_worker_tasks.js | 22 +--- libtextsecure/libsignal-protocol.js | 162 ---------------------------- ts/opengroup/opengroupV2/ApiUtil.ts | 114 +++++++++++--------- 3 files changed, 66 insertions(+), 232 deletions(-) diff --git a/js/util_worker_tasks.js b/js/util_worker_tasks.js index e2f5d9dac..8a2b596fd 100644 --- a/js/util_worker_tasks.js +++ b/js/util_worker_tasks.js @@ -45,29 +45,9 @@ function fromBase64ToArrayBuffer(value) { async function verifySignature(senderPubKey, messageData, signature) { try { - console.warn('sodium', sodium); - console.warn('senderPubKey', senderPubKey); - console.warn('messageData', messageData); - console.warn('signature', signature); - - let res = sodium.cr(key); - let [state_out, header] = [res.state, res.header]; - let c1 = sodium.crypto_secretstream_xchacha20poly1305_push( - state_out, - sodium.from_string('message 1'), - null, - sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE - ); - let c2 = sodium.crypto_secretstream_xchacha20poly1305_push( - state_out, - sodium.from_string('message 2'), - null, - sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL - ); - const result = sodium.crypto_sign_verify_detached(signature, messageData, senderPubKey); console.warn('sodium result', result); - + return result; // libsignal.Curve.async.verifySignature(senderPubKey, messageData, signature); } catch (e) { console.warn('verifySignature:', e); diff --git a/libtextsecure/libsignal-protocol.js b/libtextsecure/libsignal-protocol.js index cc34557ce..653de97fd 100644 --- a/libtextsecure/libsignal-protocol.js +++ b/libtextsecure/libsignal-protocol.js @@ -35210,27 +35210,6 @@ return crypto.subtle.digest({ name: 'SHA-512' }, data); }, - HKDF: function (input, salt, info) { - // Specific implementation of RFC 5869 that only returns the first 3 32-byte chunks - // TODO: We dont always need the third chunk, we might skip it - return Internal.crypto.sign(salt, input).then(function (PRK) { - var infoBuffer = new ArrayBuffer(info.byteLength + 1 + 32); - var infoArray = new Uint8Array(infoBuffer); - infoArray.set(new Uint8Array(info), 32); - infoArray[infoArray.length - 1] = 1; - return Internal.crypto.sign(PRK, infoBuffer.slice(32)).then(function (T1) { - infoArray.set(new Uint8Array(T1)); - infoArray[infoArray.length - 1] = 2; - return Internal.crypto.sign(PRK, infoBuffer).then(function (T2) { - infoArray.set(new Uint8Array(T2)); - infoArray[infoArray.length - 1] = 3; - return Internal.crypto.sign(PRK, infoBuffer).then(function (T3) { - return [T1, T2, T3]; - }); - }); - }); - }); - }, // Curve 25519 crypto createKeyPair: function (privKey) { @@ -35251,11 +35230,6 @@ }; - // HKDF for TextSecure has a bit of additional handling - salts always end up being 32 bytes - Internal.HKDF = function (input, salt, info) { - return Internal.crypto.HKDF(input, salt, util.toArrayBuffer(info)); - }; - Internal.verifyMAC = function (data, key, mac, length) { return Internal.crypto.sign(key, data).then(function (calculated_mac) { if (mac.byteLength != length || calculated_mac.byteLength < length) { @@ -35273,12 +35247,6 @@ }); }; - libsignal.HKDF = { - deriveSecrets: function (input, salt, info) { - return Internal.HKDF(input, salt, info); - } - }; - libsignal.crypto = { encrypt: function (key, data, iv) { return Internal.crypto.encrypt(key, data, iv); @@ -35333,26 +35301,8 @@ } return new dcodeIO.ByteBuffer.wrap(thing, 'binary').toArrayBuffer(); }, - isEqual: function (a, b) { - // TODO: Special-case arraybuffers, etc - if (a === undefined || b === undefined) { - return false; - } - a = util.toString(a); - b = util.toString(b); - var maxLength = Math.max(a.length, b.length); - if (maxLength < 5) { - throw new Error("a/b compare too short"); - } - return a.substring(0, Math.min(maxLength, a.length)) == b.substring(0, Math.min(maxLength, b.length)); - } }; })(); - - function isNonNegativeInteger(n) { - return (typeof n === 'number' && (n % 1) === 0 && n >= 0); - } - var KeyHelper = { generateIdentityKeyPair: function () { return Internal.crypto.createKeyPair(); @@ -35361,117 +35311,5 @@ libsignal.KeyHelper = KeyHelper; - var Internal = Internal || {}; - - /* - * vim: ts=4:sw=4 - */ - - var Internal = Internal || {}; - - Internal.BaseKeyType = { - OURS: 1, - THEIRS: 2 - }; - Internal.ChainType = { - SENDING: 1, - RECEIVING: 2 - }; - - /* - * jobQueue manages multiple queues indexed by device to serialize - * session io ops on the database. - */ - ; (function () { - 'use strict'; - - Internal.SessionLock = {}; - - var jobQueue = {}; - - Internal.SessionLock.queueJobForNumber = function queueJobForNumber(number, runJob) { - var runPrevious = jobQueue[number] || Promise.resolve(); - var runCurrent = jobQueue[number] = runPrevious.then(runJob, runJob); - runCurrent.then(function () { - if (jobQueue[number] === runCurrent) { - delete jobQueue[number]; - } - }); - return runCurrent; - }; - - })(); - - (function () { - var VERSION = 0; - - function iterateHash(data, key, count) { - data = dcodeIO.ByteBuffer.concat([data, key]).toArrayBuffer(); - return Internal.crypto.hash(data).then(function (result) { - if (--count === 0) { - return result; - } else { - return iterateHash(result, key, count); - } - }); - } - - function shortToArrayBuffer(number) { - return new Uint16Array([number]).buffer; - } - - function getEncodedChunk(hash, offset) { - var chunk = (hash[offset] * Math.pow(2, 32) + - hash[offset + 1] * Math.pow(2, 24) + - hash[offset + 2] * Math.pow(2, 16) + - hash[offset + 3] * Math.pow(2, 8) + - hash[offset + 4]) % 100000; - var s = chunk.toString(); - while (s.length < 5) { - s = '0' + s; - } - return s; - } - - function getDisplayStringFor(identifier, key, iterations) { - var bytes = dcodeIO.ByteBuffer.concat([ - shortToArrayBuffer(VERSION), key, identifier - ]).toArrayBuffer(); - return iterateHash(bytes, key, iterations).then(function (output) { - output = new Uint8Array(output); - return getEncodedChunk(output, 0) + - getEncodedChunk(output, 5) + - getEncodedChunk(output, 10) + - getEncodedChunk(output, 15) + - getEncodedChunk(output, 20) + - getEncodedChunk(output, 25); - }); - } - - libsignal.FingerprintGenerator = function (iterations) { - this.iterations = iterations; - }; - libsignal.FingerprintGenerator.prototype = { - createFor: function (localIdentifier, localIdentityKey, - remoteIdentifier, remoteIdentityKey) { - if (typeof localIdentifier !== 'string' || - typeof remoteIdentifier !== 'string' || - !(localIdentityKey instanceof ArrayBuffer) || - !(remoteIdentityKey instanceof ArrayBuffer)) { - - throw new Error('Invalid arguments'); - } - - return Promise.all([ - getDisplayStringFor(localIdentifier, localIdentityKey, this.iterations), - getDisplayStringFor(remoteIdentifier, remoteIdentityKey, this.iterations) - ]).then(function (fingerprints) { - return fingerprints.sort().join(''); - }); - } - }; - - })(); - })(); \ No newline at end of file diff --git a/ts/opengroup/opengroupV2/ApiUtil.ts b/ts/opengroup/opengroupV2/ApiUtil.ts index c1613deae..51a402b3b 100644 --- a/ts/opengroup/opengroupV2/ApiUtil.ts +++ b/ts/opengroup/opengroupV2/ApiUtil.ts @@ -1,8 +1,9 @@ import _ from 'lodash'; import { FileServerV2Request } from '../../fileserver/FileServerApiV2'; +import { getSodium } from '../../session/crypto'; import { PubKey } from '../../session/types'; import { allowOnlyOneAtATime, sleepFor } from '../../session/utils/Promise'; -import { fromBase64ToArrayBuffer, fromHex } from '../../session/utils/String'; +import { fromBase64ToArrayBuffer, fromHex, fromHexToArray } from '../../session/utils/String'; import { updateDefaultRooms, updateDefaultRoomsInProgress } from '../../state/ducks/defaultRooms'; import { getCompleteUrlFromRoom } from '../utils/OpenGroupUtils'; import { parseOpenGroupV2 } from './JoinOpenGroupV2'; @@ -47,57 +48,72 @@ export const parseMessages = async ( window?.log?.info('no new messages'); return []; } - const chunks = _.chunk(rawMessages, 1000); + const parsedMessages = []; - const handleChunk = async (chunk: Array>) => { - return Promise.all( - chunk.map(async r => { - try { - const opengroupv2Message = OpenGroupMessageV2.fromJson(r); - if ( - !opengroupv2Message?.serverId || - !opengroupv2Message.sentTimestamp || // this is our serverTimestamp - !opengroupv2Message.base64EncodedData || - !opengroupv2Message.base64EncodedSignature - ) { - window?.log?.warn('invalid open group message received'); - return null; - } - // Validate the message signature - const senderPubKey = PubKey.cast(opengroupv2Message.sender).withoutPrefix(); - const signature = await window.callWorker( - 'fromBase64ToArrayBuffer', - opengroupv2Message.base64EncodedSignature - ); - const messageData = await window.callWorker( - 'fromBase64ToArrayBuffer', - opengroupv2Message.base64EncodedData - ); - // throws if signature failed - await window.libsignal.Curve.async.verifySignature( - fromHex(senderPubKey), - messageData, - signature - ); - return opengroupv2Message; - } catch (e) { - window?.log?.error('An error happened while fetching getMessages output:', e); - return null; - } - }) - ); - }; - - const allHandledMessages = []; - for (const currentChunk of chunks) { - window?.log?.info('Handling rawMessage chunk of size', currentChunk.length); - const messagesHandled = await handleChunk(currentChunk); - allHandledMessages.push(...messagesHandled); - // as we are not running in a worker, just give some time for UI events - await sleepFor(2); + // tslint:disable-next-line: prefer-for-of + for (let i = 0; i < rawMessages.length; i++) { + try { + const opengroupv2Message = OpenGroupMessageV2.fromJson(rawMessages[i]); + if ( + !opengroupv2Message?.serverId || + !opengroupv2Message.sentTimestamp || // this is our serverTimestamp + !opengroupv2Message.base64EncodedData || + !opengroupv2Message.base64EncodedSignature + ) { + window?.log?.warn('invalid open group message received'); + continue; + } + // Validate the message signature + console.time(`worker1-${opengroupv2Message?.serverId}`); + const senderPubKey = PubKey.cast(opengroupv2Message.sender).withoutPrefix(); + const signature = (await window.callWorker( + 'fromBase64ToArrayBuffer', + opengroupv2Message.base64EncodedSignature + )) as ArrayBuffer; + console.timeEnd(`worker1-${opengroupv2Message?.serverId}`); + console.time(`worker2-${opengroupv2Message?.serverId}`); + + const messageData = (await window.callWorker( + 'fromBase64ToArrayBuffer', + opengroupv2Message.base64EncodedData + )) as ArrayBuffer; + console.timeEnd(`worker2-${opengroupv2Message?.serverId}`); + + // throws if signature failed + console.time(`verifySignature-${opengroupv2Message?.serverId}`); + + // const senderEd = (await getSodium()).crypto_sign_ed25519_sk_to_curve25519( + // fromHexToArray(senderPubKey), + // 'uint8array' + // ); + + const valid = (await getSodium()).crypto_sign_verify_detached( + new Uint8Array(signature), + new Uint8Array(messageData), + fromHexToArray(senderPubKey) + ); + + // const signatureValid = (await window.callWorker( + // 'verifySignature', + // fromHexToArray(senderPubKey), + // new Uint8Array(messageData), + // new Uint8Array(signature) + // )) as boolean; + if (!valid) { + console.timeEnd(`verifySignature-${opengroupv2Message?.serverId}`); + throw new Error('opengroup message signature invalisd'); + } + console.timeEnd(`verifySignature-${opengroupv2Message?.serverId}`); + + parsedMessages.push(opengroupv2Message); + // as we are not running in a worker, just give some time for UI events + await sleepFor(5); + } catch (e) { + window?.log?.error('An error happened while fetching getMessages output:', e); + } } - return _.compact(allHandledMessages).sort((a, b) => (a.serverId || 0) - (b.serverId || 0)); + return _.compact(parsedMessages).sort((a, b) => (a.serverId || 0) - (b.serverId || 0)); }; // tslint:disable: no-http-string const defaultServerUrl = 'http://116.203.70.33';