diff --git a/js/modules/loki_rpc.js b/js/modules/loki_rpc.js
index 89d2ba615..14d01f8aa 100644
--- a/js/modules/loki_rpc.js
+++ b/js/modules/loki_rpc.js
@@ -15,23 +15,6 @@ const endpointBase = '/storage_rpc/v1';
// Request index for debugging
let onionReqIdx = 0;
-const decryptResponse = async (response, address) => {
- let plaintext = false;
- try {
- const ciphertext = await response.text();
- plaintext = await libloki.crypto.snodeCipher.decrypt(address, ciphertext);
- const result = plaintext === '' ? {} : JSON.parse(plaintext);
- return result;
- } catch (e) {
- log.warn(
- `Could not decrypt response [${plaintext}] from [${address}],`,
- e.code,
- e.message
- );
- }
- return {};
-};
-
const timeoutDelay = ms => new Promise(resolve => setTimeout(resolve, ms));
const encryptForNode = async (node, payload) => {
@@ -234,7 +217,7 @@ const sendToProxy = async (options = {}, targetNode, retryNumber = 0) => {
const snPubkeyHex = StringView.hexToArrayBuffer(targetNode.pubkey_x25519);
- const myKeys = window.libloki.crypto.snodeCipher._ephemeralKeyPair;
+ const myKeys = window.libloki.crypto.generateEphemeralKeyPair();
const symmetricKey = libsignal.Curve.calculateAgreement(
snPubkeyHex,
@@ -428,25 +411,6 @@ const lokiFetch = async (url, options = {}, targetNode = null) => {
const method = options.method || 'GET';
const address = parse(url).hostname;
- // const doEncryptChannel = address.endsWith('.snode');
- const doEncryptChannel = false; // ENCRYPTION DISABLED
- if (doEncryptChannel) {
- try {
- // eslint-disable-next-line no-param-reassign
- options.body = await libloki.crypto.snodeCipher.encrypt(
- address,
- options.body
- );
- // eslint-disable-next-line no-param-reassign
- options.headers = {
- ...options.headers,
- 'Content-Type': 'text/plain',
- [LOKI_EPHEMKEY_HEADER]: libloki.crypto.snodeCipher.getChannelPublicKeyHex(),
- };
- } catch (e) {
- log.warn(`Could not encrypt channel for ${address}: `, e);
- }
- }
const fetchOptions = {
...options,
@@ -512,22 +476,14 @@ const lokiFetch = async (url, options = {}, targetNode = null) => {
let result;
// Wrong swarm
if (response.status === 421) {
- if (doEncryptChannel) {
- result = decryptResponse(response, address);
- } else {
- result = await response.json();
- }
+ result = await response.json();
const newSwarm = result.snodes ? result.snodes : [];
throw new textsecure.WrongSwarmError(newSwarm);
}
// Wrong PoW difficulty
if (response.status === 432) {
- if (doEncryptChannel) {
- result = decryptResponse(response, address);
- } else {
- result = await response.json();
- }
+ result = await response.json();
const { difficulty } = result;
throw new textsecure.WrongDifficultyError(difficulty);
}
@@ -546,8 +502,6 @@ const lokiFetch = async (url, options = {}, targetNode = null) => {
result = await response.json();
} else if (options.responseType === 'arraybuffer') {
result = await response.buffer();
- } else if (doEncryptChannel) {
- result = decryptResponse(response, address);
} else {
result = await response.text();
}
diff --git a/libloki/crypto.js b/libloki/crypto.js
index d5a23c619..23a7f68c7 100644
--- a/libloki/crypto.js
+++ b/libloki/crypto.js
@@ -136,15 +136,6 @@
const base32zIndex = Multibase.names.indexOf('base32z');
const base32zCode = Multibase.codes[base32zIndex];
- function bufferToArrayBuffer(buf) {
- const ab = new ArrayBuffer(buf.length);
- const view = new Uint8Array(ab);
- for (let i = 0; i < buf.length; i += 1) {
- view[i] = buf[i];
- }
- return ab;
- }
-
function decodeSnodeAddressToPubKey(snodeAddress) {
const snodeAddressClean = snodeAddress
.replace('.snode', '')
@@ -160,64 +151,6 @@
return keys;
}
- class LokiSnodeChannel {
- constructor() {
- this._ephemeralKeyPair = generateEphemeralKeyPair();
- this._ephemeralPubKeyHex = StringView.arrayBufferToHex(
- this._ephemeralKeyPair.pubKey
- );
- this._cache = {};
- }
-
- async _getSymmetricKey(snodeAddress) {
- if (snodeAddress in this._cache) {
- return this._cache[snodeAddress];
- }
- const ed25519PubKey = decodeSnodeAddressToPubKey(snodeAddress);
- const sodium = await window.getSodium();
- const curve25519PubKey = sodium.crypto_sign_ed25519_pk_to_curve25519(
- ed25519PubKey
- );
- const snodePubKeyArrayBuffer = bufferToArrayBuffer(curve25519PubKey);
- const symmetricKey = libsignal.Curve.calculateAgreement(
- snodePubKeyArrayBuffer,
- this._ephemeralKeyPair.privKey
- );
- this._cache[snodeAddress] = symmetricKey;
- return symmetricKey;
- }
-
- getChannelPublicKeyHex() {
- return this._ephemeralPubKeyHex;
- }
-
- async decrypt(snodeAddress, ivAndCiphertextBase64) {
- const ivAndCiphertext = dcodeIO.ByteBuffer.wrap(
- ivAndCiphertextBase64,
- 'base64'
- ).toArrayBuffer();
- const symmetricKey = await this._getSymmetricKey(snodeAddress);
- try {
- const decrypted = await DHDecrypt(symmetricKey, ivAndCiphertext);
- const decoder = new TextDecoder();
- return decoder.decode(decrypted);
- } catch (e) {
- return ivAndCiphertext;
- }
- }
-
- async encrypt(snodeAddress, plainText) {
- if (typeof plainText === 'string') {
- const textEncoder = new TextEncoder();
- // eslint-disable-next-line no-param-reassign
- plainText = textEncoder.encode(plainText);
- }
- const symmetricKey = await this._getSymmetricKey(snodeAddress);
- const ciphertext = await DHEncrypt(symmetricKey, plainText);
- return dcodeIO.ByteBuffer.wrap(ciphertext).toString('base64');
- }
- }
-
async function generateSignatureForPairing(secondaryPubKey, type) {
const pubKeyArrayBuffer = StringView.hexToArrayBuffer(secondaryPubKey);
// Make sure the signature includes the pairing action (pairing or unpairing)
@@ -367,7 +300,6 @@
const tokenString = dcodeIO.ByteBuffer.wrap(token).toString('utf8');
return tokenString;
}
- const snodeCipher = new LokiSnodeChannel();
const sha512 = data => crypto.subtle.digest('SHA-512', data);
@@ -531,7 +463,6 @@
DecryptGCM, // AES-GCM
FallBackSessionCipher,
FallBackDecryptionError,
- snodeCipher,
decryptToken,
generateSignatureForPairing,
verifyPairingSignature,
@@ -540,8 +471,6 @@
PairingType,
LokiSessionCipher,
generateEphemeralKeyPair,
- // for testing
- _LokiSnodeChannel: LokiSnodeChannel,
_decodeSnodeAddressToPubKey: decodeSnodeAddressToPubKey,
sha512,
};
diff --git a/libloki/test/index.html b/libloki/test/index.html
index 4d1c2a5e7..f9eb9c2e4 100644
--- a/libloki/test/index.html
+++ b/libloki/test/index.html
@@ -33,7 +33,6 @@
-
diff --git a/libloki/test/snode_channel_test.js b/libloki/test/snode_channel_test.js
deleted file mode 100644
index cb535c73e..000000000
--- a/libloki/test/snode_channel_test.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/* global libloki, Multibase, libsignal, StringView, dcodeIO */
-
-'use strict';
-
-async function generateSnodeKeysAndAddress() {
- // snode identitys is a ed25519 keypair
- const sodium = await window.getSodium();
- const ed25519KeyPair = sodium.crypto_sign_keypair();
- const keyPair = {
- pubKey: ed25519KeyPair.publicKey,
- privKey: ed25519KeyPair.privateKey,
- };
- // snode address is the pubkey in base32z
- let address = Multibase.encode(
- 'base32z',
- Multibase.Buffer.from(keyPair.pubKey)
- ).toString();
- // remove first letter, which is the encoding code
- address = address.substring(1);
- return { keyPair, address };
-}
-
-describe('Snode Channel', () => {
- describe('snodeCipher singleton', () => {
- it('should be defined at libloki.crypto', () => {
- assert.isDefined(libloki.crypto.snodeCipher);
- assert.isTrue(
- libloki.crypto.snodeCipher instanceof libloki.crypto._LokiSnodeChannel
- );
- });
- });
-
- describe('#decodeSnodeAddressToPubKey', () => {
- it('should decode a base32z encoded .snode address', async () => {
- const { keyPair, address } = await generateSnodeKeysAndAddress();
-
- const buffer = libloki.crypto._decodeSnodeAddressToPubKey(
- `http://${address}.snode`
- );
-
- const expected = new Uint8Array(keyPair.pubKey);
- assert.strictEqual(expected.length, 32);
- assert.strictEqual(buffer.length, 32);
- for (let i = 0; i < buffer.length; i += 1) {
- assert.strictEqual(buffer[i], expected[i]);
- }
- });
- });
-
- describe('#LokiSnodeChannel', () => {
- it('should generate an ephemeral key pair', () => {
- const channel = new libloki.crypto._LokiSnodeChannel();
-
- assert.isDefined(channel._ephemeralKeyPair);
- assert.isTrue(channel._ephemeralKeyPair.privKey instanceof ArrayBuffer);
- assert.isTrue(channel._ephemeralKeyPair.pubKey instanceof ArrayBuffer);
- const pubKeyHex = StringView.arrayBufferToHex(
- channel._ephemeralKeyPair.pubKey
- );
- assert.strictEqual(channel.getChannelPublicKeyHex(), pubKeyHex);
- });
-
- it('should cache something by snode address', async () => {
- const { address } = await generateSnodeKeysAndAddress();
-
- const channel = new libloki.crypto._LokiSnodeChannel();
- // cache should be empty
- assert.strictEqual(Object.keys(channel._cache).length, 0);
-
- // push to cache
- await channel._getSymmetricKey(address);
-
- assert.strictEqual(Object.keys(channel._cache).length, 1);
- assert.strictEqual(Object.keys(channel._cache)[0], address);
- });
-
- it('should encrypt data correctly', async () => {
- // message sent by Session
- const snode = await generateSnodeKeysAndAddress();
- const messageSent = 'I am Groot';
- const textEncoder = new TextEncoder();
- const data = textEncoder.encode(messageSent);
-
- const channel = new libloki.crypto._LokiSnodeChannel();
- const encrypted = await channel.encrypt(snode.address, data);
-
- assert.strictEqual(typeof encrypted, 'string');
-
- // message received by storage server
- const senderPubKey = StringView.hexToArrayBuffer(
- channel.getChannelPublicKeyHex()
- );
- const sodium = await window.getSodium();
- const snodePrivKey = sodium.crypto_sign_ed25519_sk_to_curve25519(
- snode.keyPair.privKey
- ).buffer;
- const symmetricKey = libsignal.Curve.calculateAgreement(
- senderPubKey,
- snodePrivKey
- );
- const encryptedArrayBuffer = dcodeIO.ByteBuffer.wrap(
- encrypted,
- 'base64'
- ).toArrayBuffer();
- const decrypted = await libloki.crypto.DHDecrypt(
- symmetricKey,
- encryptedArrayBuffer
- );
- const textDecoder = new TextDecoder();
- const messageReceived = textDecoder.decode(decrypted);
- assert.strictEqual(messageSent, messageReceived);
- });
-
- it('should decrypt data correctly', async () => {
- const channel = new libloki.crypto._LokiSnodeChannel();
- // message sent by storage server
- const snode = await generateSnodeKeysAndAddress();
- const messageSent = 'You are Groot';
- const textEncoder = new TextEncoder();
- const data = textEncoder.encode(messageSent);
- const senderPubKey = StringView.hexToArrayBuffer(
- channel.getChannelPublicKeyHex()
- );
- const sodium = await window.getSodium();
- const snodePrivKey = sodium.crypto_sign_ed25519_sk_to_curve25519(
- snode.keyPair.privKey
- ).buffer;
- const symmetricKey = libsignal.Curve.calculateAgreement(
- senderPubKey,
- snodePrivKey
- );
- const encrypted = await libloki.crypto.DHEncrypt(symmetricKey, data);
- const encryptedBase64 = dcodeIO.ByteBuffer.wrap(encrypted).toString(
- 'base64'
- );
- // message received by Session
- const decrypted = await channel.decrypt(snode.address, encryptedBase64);
- assert.strictEqual(messageSent, decrypted);
- });
- });
-});
diff --git a/package.json b/package.json
index 7df33965b..265076aa2 100644
--- a/package.json
+++ b/package.json
@@ -92,7 +92,6 @@
"js-sha512": "0.8.0",
"js-yaml": "3.13.0",
"jsbn": "1.1.0",
- "libsodium-wrappers": "^0.7.4",
"linkify-it": "2.0.3",
"lodash": "4.17.11",
"mkdirp": "0.5.1",
diff --git a/preload.js b/preload.js
index c61462fc0..9e3144c16 100644
--- a/preload.js
+++ b/preload.js
@@ -347,13 +347,6 @@ window.React = require('react');
window.ReactDOM = require('react-dom');
window.moment = require('moment');
-const _sodium = require('libsodium-wrappers');
-
-window.getSodium = async () => {
- await _sodium.ready;
- return _sodium;
-};
-
window.clipboard = clipboard;
const Signal = require('./js/modules/signal');
diff --git a/yarn.lock b/yarn.lock
index 6180d9ce1..c978424f2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5926,18 +5926,6 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
-libsodium-wrappers@^0.7.4:
- version "0.7.6"
- resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.6.tgz#baed4c16d4bf9610104875ad8a8e164d259d48fb"
- integrity sha512-OUO2CWW5bHdLr6hkKLHIKI4raEkZrf3QHkhXsJ1yCh6MZ3JDA7jFD3kCATNquuGSG6MjjPHQIQms0y0gBDzjQg==
- dependencies:
- libsodium "0.7.6"
-
-libsodium@0.7.6:
- version "0.7.6"
- resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.6.tgz#018b80c5728054817845fbffa554274441bda277"
- integrity sha512-hPb/04sEuLcTRdWDtd+xH3RXBihpmbPCsKW/Jtf4PsvdyKh+D6z2D2gvp/5BfoxseP+0FCOg66kE+0oGUE/loQ==
-
lie@*:
version "3.3.0"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"