Commit 3ca6ac7f authored by JC Brand's avatar JC Brand

Fixes #1524 Don't include own device in OMEMO message

This change reverts the significant part of 1dfdb36d

I can't say that I understand why libsignal throws `Error: Invalid signature`
when you try to build a session for your own (sending) device, but given that
messages can only be decrypted once, I guess it isn't really necessary
to encrypt for your own device, since you already have the plaintext.

In addition I've added some error handling so that we can recover
gracefully when session building fails for a subset of devices.
parent fa3c6604
......@@ -41,6 +41,7 @@
- #1494: Trim whitespace around messages
- #1495: Mentions should always include a URI attribute
- #1502: Fatal error when using prebind
- #1524: OMEMO libsignal-protocol.js Invalid signature
- #1532: Converse reloads on enter pressed in the filter box
- #1538: Allow adding self as contact
- #1550: Legitimate carbons being blocked due to erroneous forgery check
......@@ -50,8 +51,8 @@
- #1575: MUC invitation autocomplete list doesn't appear
- #1576: Converse gets stuck with spinner when logging out with `auto_login` set to `true`
- #1579: Trim spaces at the beginning and end of a JID (when adding contact)
- #1586: Not possible to kick someone with a space in their nickname
- #1585: Upload files by pasting from clipboard
- #1586: Not possible to kick someone with a space in their nickname
### Breaking changes
......
......@@ -179,7 +179,6 @@
`<encrypted xmlns="eu.siacs.conversations.axolotl">`+
`<header sid="123456789">`+
`<key rid="482886413b977930064a5888b92134fe">YzFwaDNSNzNYNw==</key>`+
`<key rid="123456789">YzFwaDNSNzNYNw==</key>`+
`<key rid="555">YzFwaDNSNzNYNw==</key>`+
`<iv>${sent_stanza.nodeTree.querySelector("iv").textContent}</iv>`+
`</header>`+
......@@ -370,7 +369,6 @@
`<encrypted xmlns="eu.siacs.conversations.axolotl">`+
`<header sid="123456789">`+
`<key rid="482886413b977930064a5888b92134fe">YzFwaDNSNzNYNw==</key>`+
`<key rid="123456789">YzFwaDNSNzNYNw==</key>`+
`<key rid="4e30f35051b7b8b42abe083742187228">YzFwaDNSNzNYNw==</key>`+
`<iv>${sent_stanza.nodeTree.querySelector("iv").textContent}</iv>`+
`</header>`+
......
......@@ -545,18 +545,28 @@ converse.plugins.add('converse-omemo', {
});
}
function getSession (device) {
async function getSession (device) {
const address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id'));
return _converse.omemo_store.loadSession(address.toString()).then(session => {
if (session) {
return Promise.resolve();
} else {
return buildSession(device);
const session = await _converse.omemo_store.loadSession(address.toString());
if (session) {
return Promise.resolve(session);
} else {
try {
const session = await buildSession(device);
return session;
} catch (e) {
_converse.log(
`Could not build an OMEMO session for device ${device.get('id')}`,
Strophe.LogLevel.ERROR
);
_converse.log(e, Strophe.LogLevel.ERROR);
return null;
}
});
}
}
_converse.getBundlesAndBuildSessions = async function (chatbox) {
const no_devices_err = __("Sorry, no devices found to which we can send an OMEMO encrypted message.");
let devices;
if (chatbox.get('type') === _converse.CHATROOMS_TYPE) {
const collections = await Promise.all(chatbox.occupants.map(o => getDevicesForContact(o.get('jid'))));
......@@ -564,15 +574,28 @@ converse.plugins.add('converse-omemo', {
} else if (chatbox.get('type') === _converse.PRIVATE_CHAT_TYPE) {
const their_devices = await getDevicesForContact(chatbox.get('jid'));
if (their_devices.length === 0) {
const err = new Error(__("Sorry, we aren't able to fetch any devices to send an OMEMO encrypted message to."));
const err = new Error(no_devices_err);
err.user_facing = true;
throw err;
}
const own_devices = _converse.devicelists.get(_converse.bare_jid).devices;
devices = _.concat(own_devices.models, their_devices.models);
devices = [...own_devices.models, ...their_devices.models];
}
// Filter out our own device
const id = _converse.omemo_store.get('device_id');
devices = devices.filter(d => d.get('id') !== id);
await Promise.all(devices.map(d => d.getBundle()));
await Promise.all(devices.map(d => getSession(d)));
const sessions = await Promise.all(devices.map(d => getSession(d)));
if (sessions.includes(null)) {
// We couldn't build a session for certain devices.
devices = devices.filter(d => sessions[devices.indexOf(d)]);
if (devices.length === 0) {
const err = new Error(no_devices_err);
err.user_facing = true;
throw err;
}
}
return devices;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment