move libloki to webworker and remove unused stuff in it

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

@ -7,10 +7,8 @@ mnemonic_languages/**
js/curve/* js/curve/*
js/components.js js/components.js
js/libtextsecure.js js/libtextsecure.js
js/libloki.js
js/util_worker.js js/util_worker.js
libtextsecure/components.js libtextsecure/components.js
libloki/test/test.js
libtextsecure/test/test.js libtextsecure/test/test.js
test/test.js test/test.js
@ -24,8 +22,3 @@ test/blanket_mocha.js
# TypeScript generated files # TypeScript generated files
ts/**/*.js ts/**/*.js
**/ts/**/*.js **/ts/**/*.js
# Libloki specific files
libloki/test/components.js
libloki/modules/mnemonic.js

3
.gitignore vendored

@ -18,11 +18,8 @@ sql/
js/components.js js/components.js
js/util_worker.js js/util_worker.js
js/libtextsecure.js js/libtextsecure.js
js/libloki.js
libtextsecure/components.js libtextsecure/components.js
libtextsecure/test/test.js libtextsecure/test/test.js
libloki/test/components.js
libloki/test/test.js
stylesheets/*.css stylesheets/*.css
test/test.js test/test.js

@ -8,7 +8,6 @@ dist/**
js/components.js js/components.js
js/util_worker.js js/util_worker.js
js/libtextsecure.js js/libtextsecure.js
js/libloki.js
libtextsecure/components.js libtextsecure/components.js
libtextsecure/test/test.js libtextsecure/test/test.js
stylesheets/*.css stylesheets/*.css
@ -20,10 +19,6 @@ ts/protobuf/*.js
stylesheets/manifest.css stylesheets/manifest.css
ts/util/lint/exceptions.json ts/util/lint/exceptions.json
# Libloki specific files
libloki/test/test.js
libloki/test/components.js
# Third-party files # Third-party files
node_modules/** node_modules/**
components/** components/**

@ -25,16 +25,11 @@ module.exports = grunt => {
libtextsecurecomponents.push(bower.concat.libtextsecure[i]); libtextsecurecomponents.push(bower.concat.libtextsecure[i]);
} }
const liblokicomponents = [];
// eslint-disable-next-line guard-for-in, no-restricted-syntax
for (const i in bower.concat.libloki) {
liblokicomponents.push(bower.concat.libloki[i]);
}
const utilWorkerComponents = [ const utilWorkerComponents = [
'node_modules/bytebuffer/dist/bytebuffer.js', 'node_modules/bytebuffer/dist/bytebuffer.js',
'js/curve/curve25519_compiled.js', 'js/curve/curve25519_compiled.js',
'js/curve/curve25519_wrapper.js', 'js/curve/curve25519_wrapper.js',
'libtextsecure/libsignal-protocol.js',
'js/util_worker_tasks.js', 'js/util_worker_tasks.js',
]; ];
@ -55,10 +50,6 @@ module.exports = grunt => {
src: libtextsecurecomponents, src: libtextsecurecomponents,
dest: 'libtextsecure/components.js', dest: 'libtextsecure/components.js',
}, },
liblokicomponents: {
src: liblokicomponents,
dest: 'libloki/test/components.js',
},
test: { test: {
src: ['node_modules/mocha/mocha.js', 'node_modules/chai/chai.js', 'test/_test.js'], src: ['node_modules/mocha/mocha.js', 'node_modules/chai/chai.js', 'test/_test.js'],
dest: 'test/test.js', dest: 'test/test.js',
@ -84,14 +75,6 @@ module.exports = grunt => {
], ],
dest: 'js/libtextsecure.js', dest: 'js/libtextsecure.js',
}, },
libloki: {
src: ['libloki/crypto.js', 'libloki/service_nodes.js', 'libloki/storage.js'],
dest: 'js/libloki.js',
},
lokitest: {
src: ['node_modules/mocha/mocha.js', 'node_modules/chai/chai.js', 'libloki/test/_test.js'],
dest: 'libloki/test/test.js',
},
libtextsecuretest: { libtextsecuretest: {
src: [ src: [
'node_modules/jquery/dist/jquery.js', 'node_modules/jquery/dist/jquery.js',
@ -123,10 +106,6 @@ module.exports = grunt => {
files: utilWorkerComponents, files: utilWorkerComponents,
tasks: ['concat:util_worker'], tasks: ['concat:util_worker'],
}, },
libloki: {
files: ['./libloki/*.js'],
tasks: ['concat:libloki'],
},
protobuf: { protobuf: {
files: ['./protos/SignalService.proto'], files: ['./protos/SignalService.proto'],
tasks: ['exec:build-protobuf'], tasks: ['exec:build-protobuf'],

@ -45,7 +45,6 @@
<script type="text/javascript" src="js/storage.js"></script> <script type="text/javascript" src="js/storage.js"></script>
<script type="text/javascript" src="js/legacy_storage.js"></script> <script type="text/javascript" src="js/legacy_storage.js"></script>
<script type="text/javascript" src="js/libtextsecure.js"></script> <script type="text/javascript" src="js/libtextsecure.js"></script>
<script type="text/javascript" src="js/libloki.js"></script>
<script type="text/javascript" src="js/focus_listener.js"></script> <script type="text/javascript" src="js/focus_listener.js"></script>
<script type="text/javascript" src="js/notifications.js"></script> <script type="text/javascript" src="js/notifications.js"></script>

@ -45,7 +45,6 @@
<script type="text/javascript" src="js/storage.js"></script> <script type="text/javascript" src="js/storage.js"></script>
<script type="text/javascript" src="js/legacy_storage.js"></script> <script type="text/javascript" src="js/legacy_storage.js"></script>
<script type="text/javascript" src="js/libtextsecure.js"></script> <script type="text/javascript" src="js/libtextsecure.js"></script>
<script type="text/javascript" src="js/libloki.js"></script>
<script type="text/javascript" src="js/focus_listener.js"></script> <script type="text/javascript" src="js/focus_listener.js"></script>
<script type="text/javascript" src="js/notifications.js"></script> <script type="text/javascript" src="js/notifications.js"></script>

@ -35,9 +35,6 @@
"libtextsecure": [ "libtextsecure": [
"node_modules/long/dist/long.js", "node_modules/long/dist/long.js",
"components/protobuf/**/*.js" "components/protobuf/**/*.js"
],
"libloki": [
"node_modules/long/dist/long.js"
] ]
} }
} }

@ -6,6 +6,10 @@ const functions = {
arrayBufferToStringBase64, arrayBufferToStringBase64,
fromBase64ToArrayBuffer, fromBase64ToArrayBuffer,
verifySignature, verifySignature,
DecryptAESGCM,
deriveSymmetricKey,
encryptForPubkey,
generateEphemeralKeyPair,
}; };
onmessage = async e => { onmessage = async e => {
@ -40,17 +44,43 @@ function arrayBufferToStringBase64(arrayBuffer) {
return dcodeIO.ByteBuffer.wrap(arrayBuffer).toString('base64'); return dcodeIO.ByteBuffer.wrap(arrayBuffer).toString('base64');
} }
function fromBase64ToArrayBuffer(value) { function fromBase64ToArrayBuffer(base64Str) {
return dcodeIO.ByteBuffer.wrap(value, 'base64').toArrayBuffer(); return dcodeIO.ByteBuffer.wrap(base64Str, 'base64').toArrayBuffer();
} }
function fromHexToArray(hexStr) {
return new Uint8Array(dcodeIO.ByteBuffer.wrap(hexStr, 'hex').toArrayBuffer());
}
function fromHexToArrayBuffer(hexStr) {
return dcodeIO.ByteBuffer.wrap(hexStr, 'hex').toArrayBuffer();
}
function bytesFromString(string) {
return dcodeIO.ByteBuffer.wrap(string, 'utf8').toArrayBuffer();
}
// hexString, base64String, base64String
async function verifySignature(senderPubKey, messageBase64, signatureBase64) { async function verifySignature(senderPubKey, messageBase64, signatureBase64) {
try { try {
if (typeof senderPubKey !== 'string') {
throw new Error('senderPubKey type not correct');
}
if (typeof messageBase64 !== 'string') {
throw new Error('messageBase64 type not correct');
}
if (typeof signatureBase64 !== 'string') {
throw new Error('signatureBase64 type not correct');
}
const messageData = new Uint8Array(fromBase64ToArrayBuffer(messageBase64)); const messageData = new Uint8Array(fromBase64ToArrayBuffer(messageBase64));
const signature = new Uint8Array(fromBase64ToArrayBuffer(signatureBase64)); const signature = new Uint8Array(fromBase64ToArrayBuffer(signatureBase64));
// verify returns true if the signature is not correct // verify returns true if the signature is not correct
const verifyRet = Internal.curve25519.verify(senderPubKey, messageData, signature); const verifyRet = Internal.curve25519.verify(
fromHexToArray(senderPubKey),
messageData,
signature
);
if (verifyRet) { if (verifyRet) {
console.warn('Invalid signature'); console.warn('Invalid signature');
return false; return false;
@ -62,3 +92,107 @@ async function verifySignature(senderPubKey, messageBase64, signatureBase64) {
return false; return false;
} }
} }
const NONCE_LENGTH = 12;
// uint8array, uint8array
async function deriveSymmetricKey(x25519PublicKey, x25519PrivateKey) {
assertArrayBufferView(x25519PublicKey);
assertArrayBufferView(x25519PrivateKey);
const ephemeralSecret = await libsignal.Curve.async.calculateAgreement(
x25519PublicKey.buffer,
x25519PrivateKey.buffer
);
const salt = bytesFromString('LOKI');
const key = await crypto.subtle.importKey(
'raw',
salt,
{ name: 'HMAC', hash: { name: 'SHA-256' } },
false,
['sign']
);
const symmetricKey = await crypto.subtle.sign(
{ name: 'HMAC', hash: 'SHA-256' },
key,
ephemeralSecret
);
return symmetricKey;
}
async function generateEphemeralKeyPair() {
const keys = await libsignal.Curve.async.generateKeyPair();
// Signal protocol prepends with "0x05"
keys.pubKey = keys.pubKey.slice(1);
return keys;
}
function assertArrayBufferView(val) {
if (!ArrayBuffer.isView(val)) {
throw new Error('val type not correct');
}
}
// encryptForPubkey: hexString, payloadBytes: Uint8Array
async function encryptForPubkey(pubkeyX25519str, payloadBytes) {
try {
if (typeof pubkeyX25519str !== 'string') {
throw new Error('pubkeyX25519str type not correct');
}
assertArrayBufferView(payloadBytes);
const ephemeral = await generateEphemeralKeyPair();
const pubkeyX25519Buffer = fromHexToArray(pubkeyX25519str);
const symmetricKey = await deriveSymmetricKey(
pubkeyX25519Buffer,
new Uint8Array(ephemeral.privKey)
);
const ciphertext = await EncryptAESGCM(symmetricKey, payloadBytes);
return { ciphertext, symmetricKey, ephemeralKey: ephemeral.pubKey };
} catch (e) {
console.warn('encryptForPubkey got an error:', e);
return null;
}
}
async function EncryptAESGCM(symmetricKey, plaintext) {
const nonce = crypto.getRandomValues(new Uint8Array(NONCE_LENGTH));
const key = await crypto.subtle.importKey('raw', symmetricKey, { name: 'AES-GCM' }, false, [
'encrypt',
]);
const ciphertext = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: nonce, tagLength: 128 },
key,
plaintext
);
const ivAndCiphertext = new Uint8Array(NONCE_LENGTH + ciphertext.byteLength);
ivAndCiphertext.set(nonce);
ivAndCiphertext.set(new Uint8Array(ciphertext), nonce.byteLength);
return ivAndCiphertext;
}
// uint8array, uint8array
async function DecryptAESGCM(symmetricKey, ivAndCiphertext) {
assertArrayBufferView(symmetricKey);
assertArrayBufferView(ivAndCiphertext);
const nonce = ivAndCiphertext.buffer.slice(0, NONCE_LENGTH);
const ciphertext = ivAndCiphertext.buffer.slice(NONCE_LENGTH);
const key = await crypto.subtle.importKey(
'raw',
symmetricKey.buffer,
{ name: 'AES-GCM' },
false,
['decrypt']
);
return crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, key, ciphertext);
}

@ -1,8 +0,0 @@
export interface CryptoInterface {
DecryptAESGCM: (symmetricKey: ArrayBuffer, ivAndCiphertext: ArrayBuffer) => Promise<ArrayBuffer>; // AES-GCM
deriveSymmetricKey: (pubkey: ArrayBuffer, seckey: ArrayBuffer) => Promise<ArrayBuffer>;
encryptForPubkey: (
publicKey: string,
data: Uint8Array
) => Promise<{ ciphertext: Uint8Array; symmetricKey: ArrayBuffer; ephemeralKey: ArrayBuffer }>;
}

@ -1,95 +0,0 @@
/* global
window,
libsignal,
StringView,
TextEncoder,
TextDecoder,
crypto,
libloki
*/
// eslint-disable-next-line func-names
(function() {
window.libloki = window.libloki || {};
const NONCE_LENGTH = 12;
async function deriveSymmetricKey(x25519PublicKey, x25519PrivateKey) {
const ephemeralSecret = await libsignal.Curve.async.calculateAgreement(
x25519PublicKey,
x25519PrivateKey
);
const salt = window.Signal.Crypto.bytesFromString('LOKI');
const key = await crypto.subtle.importKey(
'raw',
salt,
{ name: 'HMAC', hash: { name: 'SHA-256' } },
false,
['sign']
);
const symmetricKey = await crypto.subtle.sign(
{ name: 'HMAC', hash: 'SHA-256' },
key,
ephemeralSecret
);
return symmetricKey;
}
// encryptForPubkey: string, payloadBytes: Uint8Array
async function encryptForPubkey(pubkeyX25519, payloadBytes) {
const ephemeral = await libloki.crypto.generateEphemeralKeyPair();
const snPubkey = StringView.hexToArrayBuffer(pubkeyX25519);
const symmetricKey = await deriveSymmetricKey(snPubkey, ephemeral.privKey);
const ciphertext = await EncryptAESGCM(symmetricKey, payloadBytes);
return { ciphertext, symmetricKey, ephemeralKey: ephemeral.pubKey };
}
async function EncryptAESGCM(symmetricKey, plaintext) {
const nonce = crypto.getRandomValues(new Uint8Array(NONCE_LENGTH));
const key = await crypto.subtle.importKey('raw', symmetricKey, { name: 'AES-GCM' }, false, [
'encrypt',
]);
const ciphertext = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: nonce, tagLength: 128 },
key,
plaintext
);
const ivAndCiphertext = new Uint8Array(NONCE_LENGTH + ciphertext.byteLength);
ivAndCiphertext.set(nonce);
ivAndCiphertext.set(new Uint8Array(ciphertext), nonce.byteLength);
return ivAndCiphertext;
}
async function DecryptAESGCM(symmetricKey, ivAndCiphertext) {
const nonce = ivAndCiphertext.slice(0, NONCE_LENGTH);
const ciphertext = ivAndCiphertext.slice(NONCE_LENGTH);
const key = await crypto.subtle.importKey('raw', symmetricKey, { name: 'AES-GCM' }, false, [
'decrypt',
]);
return crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, key, ciphertext);
}
async function generateEphemeralKeyPair() {
const keys = await libsignal.Curve.async.generateKeyPair();
// Signal protocol prepends with "0x05"
keys.pubKey = keys.pubKey.slice(1);
return keys;
}
window.libloki.crypto = {
EncryptAESGCM, // AES-GCM
DecryptAESGCM, // AES-GCM
deriveSymmetricKey,
generateEphemeralKeyPair,
encryptForPubkey,
};
})();

@ -1,7 +0,0 @@
import { CryptoInterface } from './crypto';
export interface Libloki {
api: any;
crypto: CryptoInterface;
storage: any;
}

@ -1,6 +1,12 @@
var libsignal
; (function () { ; (function () {
var Internal = {}; var Internal = {};
window.libsignal = {}; libsignal = typeof window === 'undefined' ? {} : window.libsignal || {};
if (typeof window !== 'undefined') {
window.libsignal = libsignal;
}
// The Module object: Our interface to the outside world. We import // The Module object: Our interface to the outside world. We import
// and export values on it, and do the work to get that through // and export values on it, and do the work to get that through
// closure compiler if necessary. There are various ways Module can be used: // closure compiler if necessary. There are various ways Module can be used:
@ -35178,7 +35184,7 @@
(function () { (function () {
'use strict'; 'use strict';
var crypto = window.crypto; var crypto = typeof window === 'undefined' ? self.crypto : window.crypto || {};
if (!crypto || !crypto.subtle || typeof crypto.getRandomValues !== 'function') { if (!crypto || !crypto.subtle || typeof crypto.getRandomValues !== 'function') {
throw new Error('WebCrypto not found'); throw new Error('WebCrypto not found');

@ -290,7 +290,6 @@
"password.html", "password.html",
"debug_log.html", "debug_log.html",
"_locales/**", "_locales/**",
"libloki/modules/*.js",
"mnemonic_languages/**", "mnemonic_languages/**",
"protos/*", "protos/*",
"js/**", "js/**",

@ -28,7 +28,6 @@
<script type="text/javascript" src="../js/database.js" data-cover></script> <script type="text/javascript" src="../js/database.js" data-cover></script>
<script type="text/javascript" src="../js/storage.js" data-cover></script> <script type="text/javascript" src="../js/storage.js" data-cover></script>
<script type="text/javascript" src="../js/libtextsecure.js" data-cover></script> <script type="text/javascript" src="../js/libtextsecure.js" data-cover></script>
<script type="text/javascript" src="../js/libloki.js" data-cover></script>
<!-- needs the network comms libraries to work --> <!-- needs the network comms libraries to work -->
<script type="text/javascript" src="../js/expire.js" data-cover></script> <script type="text/javascript" src="../js/expire.js" data-cover></script>

@ -281,7 +281,6 @@ export const SessionRightPanelWithDetails = (props: Props) => {
} = props; } = props;
const showMemberCount = !!(memberCount && memberCount > 0); const showMemberCount = !!(memberCount && memberCount > 0);
const commonNoShow = isKickedFromGroup || left || isBlocked; const commonNoShow = isKickedFromGroup || left || isBlocked;
console.warn('AUDRIC: render right panel');
const hasDisappearingMessages = !isPublic && !commonNoShow; const hasDisappearingMessages = !isPublic && !commonNoShow;
const leaveGroupString = isPublic const leaveGroupString = isPublic
? window.i18n('leaveGroup') ? window.i18n('leaveGroup')

@ -169,7 +169,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
public updateLastMessage: () => any; public updateLastMessage: () => any;
public throttledBumpTyping: any; public throttledBumpTyping: any;
public throttledNotify: any; public throttledNotify: any;
public markRead: any; public markRead: (newestUnreadDate: number, providedOptions: any) => Promise<void>;
public initialPromise: any; public initialPromise: any;
private typingRefreshTimer?: NodeJS.Timeout | null; private typingRefreshTimer?: NodeJS.Timeout | null;

@ -153,19 +153,27 @@ export async function requestNewAuthToken({
window?.log?.warn('Parsing failed'); window?.log?.warn('Parsing failed');
return null; return null;
} }
const ciphertext = await window.callWorker('fromBase64ToArrayBuffer', base64EncodedCiphertext); const ciphertext = (await window.callWorker(
const ephemeralPublicKey = await window.callWorker( 'fromBase64ToArrayBuffer',
base64EncodedCiphertext
)) as ArrayBuffer;
const ephemeralPublicKey = (await window.callWorker(
'fromBase64ToArrayBuffer', 'fromBase64ToArrayBuffer',
base64EncodedEphemeralPublicKey base64EncodedEphemeralPublicKey
); )) as ArrayBuffer;
try { try {
const symmetricKey = await window.libloki.crypto.deriveSymmetricKey( const symmetricKey = (await window.callWorker(
ephemeralPublicKey, 'deriveSymmetricKey',
userKeyPair.privKey new Uint8Array(ephemeralPublicKey),
new Uint8Array(userKeyPair.privKey)
)) as ArrayBuffer;
const plaintextBuffer = await window.callWorker(
'DecryptAESGCM',
new Uint8Array(symmetricKey),
new Uint8Array(ciphertext)
); );
const plaintextBuffer = await window.libloki.crypto.DecryptAESGCM(symmetricKey, ciphertext);
const token = toHex(plaintextBuffer); const token = toHex(plaintextBuffer);
return token; return token;

@ -68,7 +68,7 @@ export const parseMessages = async (
const signatureValid = (await window.callWorker( const signatureValid = (await window.callWorker(
'verifySignature', 'verifySignature',
fromHexToArray(senderPubKey), senderPubKey,
opengroupv2Message.base64EncodedData, opengroupv2Message.base64EncodedData,
opengroupv2Message.base64EncodedSignature opengroupv2Message.base64EncodedSignature
)) as boolean; )) as boolean;

@ -51,11 +51,10 @@ export async function downloadAttachment(attachment: any) {
throw new Error('Attachment is not raw but we do not have a key to decode it'); throw new Error('Attachment is not raw but we do not have a key to decode it');
} }
data = await window.textsecure.crypto.decryptAttachment( const keyBuffer = await window.callWorker('fromBase64ToArrayBuffer', key);
data, const digestBuffer = await window.callWorker('fromBase64ToArrayBuffer', digest);
await window.callWorker('fromBase64ToArrayBuffer', key),
await window.callWorker('fromBase64ToArrayBuffer', digest) data = await window.textsecure.crypto.decryptAttachment(data, keyBuffer, digestBuffer);
);
if (!size || size !== data.byteLength) { if (!size || size !== data.byteLength) {
// we might have padding, check that all the remaining bytes are padding bytes // we might have padding, check that all the remaining bytes are padding bytes

@ -45,7 +45,7 @@ const cacheOfClosedGroupKeyPairs: Map<string, Array<HexKeyPair>> = new Map();
export async function getAllCachedECKeyPair(groupPubKey: string) { export async function getAllCachedECKeyPair(groupPubKey: string) {
let keyPairsFound = cacheOfClosedGroupKeyPairs.get(groupPubKey); let keyPairsFound = cacheOfClosedGroupKeyPairs.get(groupPubKey);
if (!keyPairsFound) { if (!keyPairsFound || keyPairsFound.length === 0) {
keyPairsFound = (await getAllEncryptionKeyPairsForGroup(groupPubKey)) || []; keyPairsFound = (await getAllEncryptionKeyPairsForGroup(groupPubKey)) || [];
cacheOfClosedGroupKeyPairs.set(groupPubKey, keyPairsFound); cacheOfClosedGroupKeyPairs.set(groupPubKey, keyPairsFound);
} }
@ -414,6 +414,7 @@ async function handleClosedGroupEncryptionKeyPair(
ourWrapper.encryptedKeyPair, ourWrapper.encryptedKeyPair,
ECKeyPair.fromKeyPair(ourKeyPair) ECKeyPair.fromKeyPair(ourKeyPair)
); );
if (!buffer || buffer.byteLength === 0) { if (!buffer || buffer.byteLength === 0) {
throw new Error(); throw new Error();
} }

@ -1,5 +1,3 @@
// TODO: fix libloki and textsecure not being available here yet
import { EnvelopePlus } from './types'; import { EnvelopePlus } from './types';
export { downloadAttachment } from './attachments'; export { downloadAttachment } from './attachments';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';

@ -4,7 +4,7 @@ import https from 'https';
import { dropSnodeFromSnodePool, dropSnodeFromSwarmIfNeeded, updateSwarmFor } from './snodePool'; import { dropSnodeFromSnodePool, dropSnodeFromSwarmIfNeeded, updateSwarmFor } from './snodePool';
import ByteBuffer from 'bytebuffer'; import ByteBuffer from 'bytebuffer';
import { OnionPaths } from '../onions'; import { OnionPaths } from '../onions';
import { toHex } from '../utils/String'; import { fromHex, toHex } from '../utils/String';
import pRetry from 'p-retry'; import pRetry from 'p-retry';
import { incrementBadPathCountOrDrop } from '../onions/onionPath'; import { incrementBadPathCountOrDrop } from '../onions/onionPath';
import _ from 'lodash'; import _ from 'lodash';
@ -49,7 +49,7 @@ async function encryptForPubKey(pubKeyX25519hex: string, reqObj: any): Promise<D
const textEncoder = new TextEncoder(); const textEncoder = new TextEncoder();
const plaintext = textEncoder.encode(reqStr); const plaintext = textEncoder.encode(reqStr);
return window.libloki.crypto.encryptForPubkey(pubKeyX25519hex, plaintext); return window.callWorker('encryptForPubkey', pubKeyX25519hex, plaintext);
} }
export type DestinationRelayV2 = { export type DestinationRelayV2 = {
@ -77,8 +77,7 @@ async function encryptForRelayV2(
}; };
const plaintext = encodeCiphertextPlusJson(ctx.ciphertext, reqObj); const plaintext = encodeCiphertextPlusJson(ctx.ciphertext, reqObj);
return window.callWorker('encryptForPubkey', relayX25519hex, plaintext);
return window.libloki.crypto.encryptForPubkey(relayX25519hex, plaintext);
} }
/// Encode ciphertext as (len || binary) and append payloadJson as utf8 /// Encode ciphertext as (len || binary) and append payloadJson as utf8
@ -397,7 +396,11 @@ export async function decodeOnionResult(symmetricKey: ArrayBuffer, ciphertext: s
} }
const ciphertextBuffer = await window.callWorker('fromBase64ToArrayBuffer', parsedCiphertext); const ciphertextBuffer = await window.callWorker('fromBase64ToArrayBuffer', parsedCiphertext);
const plaintextBuffer = await window.libloki.crypto.DecryptAESGCM(symmetricKey, ciphertextBuffer); const plaintextBuffer = await window.callWorker(
'DecryptAESGCM',
new Uint8Array(symmetricKey),
new Uint8Array(ciphertextBuffer)
);
return { plaintext: new TextDecoder().decode(plaintextBuffer), ciphertextBuffer }; return { plaintext: new TextDecoder().decode(plaintextBuffer), ciphertextBuffer };
} }
@ -765,7 +768,7 @@ const sendOnionRequest = async ({
const bodyEncoded = textEncoder.encode(body); const bodyEncoded = textEncoder.encode(body);
const plaintext = encodeCiphertextPlusJson(bodyEncoded, options); const plaintext = encodeCiphertextPlusJson(bodyEncoded, options);
destCtx = await window.libloki.crypto.encryptForPubkey(destX25519hex, plaintext); destCtx = await window.callWorker('encryptForPubkey', destX25519hex, plaintext);
} else { } else {
destCtx = await encryptForPubKey(destX25519hex, options); destCtx = await encryptForPubKey(destX25519hex, options);
} }

@ -104,12 +104,6 @@ describe('MessageEncrypter', () => {
}, },
}); });
TestUtils.stubWindow('libloki', {
crypto: {
encryptForPubkey: sinon.fake.returns(''),
} as any,
});
sandbox.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(ourNumber); sandbox.stub(UserUtils, 'getOurPubKeyStrFromCache').returns(ourNumber);
sandbox.stub(UserUtils, 'getUserED25519KeyPair').resolves(ourUserEd25516Keypair); sandbox.stub(UserUtils, 'getUserED25519KeyPair').resolves(ourUserEd25516Keypair);
}); });

@ -132,12 +132,6 @@ describe('OnionPathsErrors', () => {
await OnionPaths.getOnionPath(); await OnionPaths.getOnionPath();
oldOnionPaths = OnionPaths.TEST_getTestOnionPath(); oldOnionPaths = OnionPaths.TEST_getTestOnionPath();
TestUtils.stubWindow('libloki', {
crypto: {
DecryptAESGCM: async (s: any, e: string) => e,
} as any,
});
sandbox sandbox
.stub(SNodeAPI.Onions, 'decodeOnionResult') .stub(SNodeAPI.Onions, 'decodeOnionResult')
.callsFake((_symkey: ArrayBuffer, plaintext: string) => .callsFake((_symkey: ArrayBuffer, plaintext: string) =>

@ -56,7 +56,6 @@ const excludedFiles = [
'^js/components.js', '^js/components.js',
'^js/curve/', '^js/curve/',
'^js/libtextsecure.js', '^js/libtextsecure.js',
'^js/libloki.js',
'^js/util_worker.js', '^js/util_worker.js',
'^libtextsecure/components.js', '^libtextsecure/components.js',
'^libtextsecure/test/test.js', '^libtextsecure/test/test.js',
@ -66,7 +65,6 @@ const excludedFiles = [
'^libtextsecure/libsignal-protocol.js', '^libtextsecure/libsignal-protocol.js',
// Test files // Test files
'^libloki/test/*',
'^libtextsecure/test/*', '^libtextsecure/test/*',
'^test/*', '^test/*',

9
ts/window.d.ts vendored

@ -3,7 +3,6 @@ import {} from 'styled-components/cssprop';
import { LocalizerType } from '../types/Util'; import { LocalizerType } from '../types/Util';
import { LibsignalProtocol } from '../../libtextsecure/libsignal-protocol'; import { LibsignalProtocol } from '../../libtextsecure/libsignal-protocol';
import { SignalInterface } from '../../js/modules/signal'; import { SignalInterface } from '../../js/modules/signal';
import { Libloki } from '../libloki';
import { LibTextsecure } from '../libtextsecure'; import { LibTextsecure } from '../libtextsecure';
import { ConfirmationDialogParams } from '../background'; import { ConfirmationDialogParams } from '../background';
@ -19,6 +18,8 @@ We declare window stuff here instead of global.d.ts because we are importing oth
If you import anything in global.d.ts, the type system won't work correctly. If you import anything in global.d.ts, the type system won't work correctly.
*/ */
type UtilWorkerFunctionType = (fnName: string, ...args: any) => Promise<any>;
declare global { declare global {
interface Window { interface Window {
CONSTANTS: any; CONSTANTS: any;
@ -40,7 +41,6 @@ declare global {
getFriendsFromContacts: any; getFriendsFromContacts: any;
getSettingValue: any; getSettingValue: any;
i18n: LocalizerType; i18n: LocalizerType;
libloki: Libloki;
libsignal: LibsignalProtocol; libsignal: LibsignalProtocol;
log: any; log: any;
lokiFeatureFlags: { lokiFeatureFlags: {
@ -81,9 +81,6 @@ declare global {
LokiPushNotificationServer: any; LokiPushNotificationServer: any;
globalOnlineStatus: boolean; globalOnlineStatus: boolean;
confirmationDialog: any; confirmationDialog: any;
callWorker: ( callWorker: (fnName: string, ...args: any) => Promise<any>;
fnName: 'arrayBufferToStringBase64' | 'fromBase64ToArrayBuffer' | 'verifySignature',
...args
) => Promise<any>;
} }
} }

Loading…
Cancel
Save