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

This change reverts the significant part of 1dfdb36d20

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.
This commit is contained in:
JC Brand 2019-07-05 19:15:23 +02:00
parent fa3c6604ac
commit 3ca6ac7f50
3 changed files with 35 additions and 13 deletions

View File

@ -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

View File

@ -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>`+

View File

@ -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;
}