Use set instead of list for handling OmemoDevice

This commit is contained in:
Paul Schaub 2018-01-24 14:17:22 +01:00
parent 2d79cc981f
commit 38d9d96d1f
3 changed files with 50 additions and 46 deletions

View File

@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.WeakHashMap; import java.util.WeakHashMap;
@ -270,15 +271,15 @@ public final class OmemoManager extends Manager {
} }
/** /**
* Return a list of all OMEMO capable devices of a contact. * Return a set of all OMEMO capable devices of a contact.
* Note, that this method does not explicitly refresh the device list of the contact, so it might be outdated. * Note, that this method does not explicitly refresh the device list of the contact, so it might be outdated.
* @see #requestDeviceListUpdateFor(BareJid) * @see #requestDeviceListUpdateFor(BareJid)
* @param contact contact we want to get a list of device of. * @param contact contact we want to get a set of device of.
* @return list of known devices of that contact. * @return set of known devices of that contact.
*/ */
public List<OmemoDevice> getDevicesOf(BareJid contact) { public Set<OmemoDevice> getDevicesOf(BareJid contact) {
OmemoCachedDeviceList list = getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(getOwnDevice(), contact); OmemoCachedDeviceList list = getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(getOwnDevice(), contact);
ArrayList<OmemoDevice> devices = new ArrayList<>(); HashSet<OmemoDevice> devices = new HashSet<>();
for (int deviceId : list.getActiveDevices()) { for (int deviceId : list.getActiveDevices()) {
devices.add(new OmemoDevice(contact, deviceId)); devices.add(new OmemoDevice(contact, deviceId));
@ -307,7 +308,7 @@ public final class OmemoManager extends Manager {
SmackException.NoResponseException, SmackException.NotLoggedInException SmackException.NoResponseException, SmackException.NotLoggedInException
{ {
synchronized (LOCK) { synchronized (LOCK) {
ArrayList<BareJid> recipients = new ArrayList<>(); Set<BareJid> recipients = new HashSet<>();
recipients.add(recipient); recipients.add(recipient);
return encrypt(recipients, message); return encrypt(recipients, message);
} }
@ -326,14 +327,14 @@ public final class OmemoManager extends Manager {
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
* @throws SmackException.NotLoggedInException * @throws SmackException.NotLoggedInException
*/ */
public OmemoMessage.Sent encrypt(ArrayList<BareJid> recipients, String message) public OmemoMessage.Sent encrypt(Set<BareJid> recipients, String message)
throws CryptoFailedException, UndecidedOmemoIdentityException, throws CryptoFailedException, UndecidedOmemoIdentityException,
InterruptedException, SmackException.NotConnectedException, InterruptedException, SmackException.NotConnectedException,
SmackException.NoResponseException, SmackException.NotLoggedInException SmackException.NoResponseException, SmackException.NotLoggedInException
{ {
synchronized (LOCK) { synchronized (LOCK) {
LoggedInOmemoManager guard = new LoggedInOmemoManager(this); LoggedInOmemoManager guard = new LoggedInOmemoManager(this);
List<OmemoDevice> devices = getDevicesOf(getOwnJid()); Set<OmemoDevice> devices = getDevicesOf(getOwnJid());
for (BareJid recipient : recipients) { for (BareJid recipient : recipients) {
devices.addAll(getDevicesOf(recipient)); devices.addAll(getDevicesOf(recipient));
} }
@ -367,7 +368,7 @@ public final class OmemoManager extends Manager {
throw new NoOmemoSupportException(); throw new NoOmemoSupportException();
} }
ArrayList<BareJid> recipients = new ArrayList<>(); Set<BareJid> recipients = new HashSet<>();
for (EntityFullJid e : muc.getOccupants()) { for (EntityFullJid e : muc.getOccupants()) {
recipients.add(muc.getOccupant(e).getJid().asBareJid()); recipients.add(muc.getOccupant(e).getJid().asBareJid());

View File

@ -20,9 +20,9 @@ import static org.jivesoftware.smackx.omemo.util.OmemoConstants.BODY_OMEMO_HINT;
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO; import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO;
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL; import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.HashSet;
import java.util.Set;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement; import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement;
@ -74,7 +74,7 @@ public class OmemoMessage {
* Outgoing OMEMO message. * Outgoing OMEMO message.
*/ */
public static class Sent extends OmemoMessage { public static class Sent extends OmemoMessage {
private final ArrayList<OmemoDevice> intendedDevices = new ArrayList<>(); private final Set<OmemoDevice> intendedDevices = new HashSet<>();
private final HashMap<OmemoDevice, Throwable> skippedDevices = new HashMap<>(); private final HashMap<OmemoDevice, Throwable> skippedDevices = new HashMap<>();
/** /**
@ -86,7 +86,7 @@ public class OmemoMessage {
* @param skippedDevices devices which were skipped during encryption process because encryption * @param skippedDevices devices which were skipped during encryption process because encryption
* failed for some reason * failed for some reason
*/ */
Sent(OmemoElement element, byte[] key, byte[] iv, List<OmemoDevice> intendedDevices, HashMap<OmemoDevice, Throwable> skippedDevices) { Sent(OmemoElement element, byte[] key, byte[] iv, Set<OmemoDevice> intendedDevices, HashMap<OmemoDevice, Throwable> skippedDevices) {
super(element, key, iv); super(element, key, iv);
this.intendedDevices.addAll(intendedDevices); this.intendedDevices.addAll(intendedDevices);
this.skippedDevices.putAll(skippedDevices); this.skippedDevices.putAll(skippedDevices);
@ -96,7 +96,7 @@ public class OmemoMessage {
* Return a list of all devices the sender originally intended to encrypt the message for. * Return a list of all devices the sender originally intended to encrypt the message for.
* @return list of intended recipients. * @return list of intended recipients.
*/ */
public List<OmemoDevice> getIntendedDevices() { public Set<OmemoDevice> getIntendedDevices() {
return intendedDevices; return intendedDevices;
} }

View File

@ -30,6 +30,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
@ -326,7 +327,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* Encrypt a message with a messageKey and an IV and create an OmemoMessage from it. * Encrypt a message with a messageKey and an IV and create an OmemoMessage from it.
* *
* @param managerGuard authenticated OmemoManager * @param managerGuard authenticated OmemoManager
* @param contactsDevices list of recipient OmemoDevices * @param contactsDevices set of recipient OmemoDevices
* @param messageKey AES key to encrypt the message * @param messageKey AES key to encrypt the message
* @param iv iv to be used with the messageKey * @param iv iv to be used with the messageKey
* @return OmemoMessage object which contains the OmemoElement and some information. * @return OmemoMessage object which contains the OmemoElement and some information.
@ -338,7 +339,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* @throws CryptoFailedException if we are lacking some crypto primitives * @throws CryptoFailedException if we are lacking some crypto primitives
*/ */
private OmemoMessage.Sent encrypt(OmemoManager.LoggedInOmemoManager managerGuard, private OmemoMessage.Sent encrypt(OmemoManager.LoggedInOmemoManager managerGuard,
List<OmemoDevice> contactsDevices, Set<OmemoDevice> contactsDevices,
byte[] messageKey, byte[] messageKey,
byte[] iv, byte[] iv,
String message) String message)
@ -353,7 +354,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
buildMissingSessionsWithDevices(manager.getConnection(), userDevice, contactsDevices); buildMissingSessionsWithDevices(manager.getConnection(), userDevice, contactsDevices);
ArrayList<OmemoDevice> undecidedDevices = getUndecidedDevices(userDevice, manager.getTrustCallback(), contactsDevices); Set<OmemoDevice> undecidedDevices = getUndecidedDevices(userDevice, manager.getTrustCallback(), contactsDevices);
if (!undecidedDevices.isEmpty()) { if (!undecidedDevices.isEmpty()) {
throw new UndecidedOmemoIdentityException(undecidedDevices); throw new UndecidedOmemoIdentityException(undecidedDevices);
} }
@ -472,7 +473,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* @see <a href="https://xmpp.org/extensions/xep-0384.html#usecases-keysend">XEP-0384: Sending a key</a>. * @see <a href="https://xmpp.org/extensions/xep-0384.html#usecases-keysend">XEP-0384: Sending a key</a>.
* *
* @param managerGuard Initialized OmemoManager. * @param managerGuard Initialized OmemoManager.
* @param contactsDevices recipient devices. * @param contactsDevices set of recipient devices.
* @param key AES-Key to be transported. * @param key AES-Key to be transported.
* @param iv initialization vector to be used with the key. * @param iv initialization vector to be used with the key.
* @return KeyTransportElement * @return KeyTransportElement
@ -484,7 +485,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
*/ */
OmemoMessage.Sent createKeyTransportElement(OmemoManager.LoggedInOmemoManager managerGuard, OmemoMessage.Sent createKeyTransportElement(OmemoManager.LoggedInOmemoManager managerGuard,
List<OmemoDevice> contactsDevices, Set<OmemoDevice> contactsDevices,
byte[] key, byte[] key,
byte[] iv) byte[] iv)
throws InterruptedException, UndecidedOmemoIdentityException, CryptoFailedException, throws InterruptedException, UndecidedOmemoIdentityException, CryptoFailedException,
@ -494,11 +495,13 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
} }
/** /**
* Create an OmemoMessage.
*
* @param managerGuard initialized OmemoManager
* @param contactsDevices set of recipient devices
* @param message message we want to send
* @return encrypted OmemoMessage
* *
* @param managerGuard
* @param contactsDevices
* @param message
* @return
* @throws InterruptedException * @throws InterruptedException
* @throws UndecidedOmemoIdentityException if the list of recipient devices contains an undecided device. * @throws UndecidedOmemoIdentityException if the list of recipient devices contains an undecided device.
* @throws CryptoFailedException if we are lacking some cryptographic algorithms * @throws CryptoFailedException if we are lacking some cryptographic algorithms
@ -506,7 +509,7 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
*/ */
OmemoMessage.Sent createOmemoMessage(OmemoManager.LoggedInOmemoManager managerGuard, OmemoMessage.Sent createOmemoMessage(OmemoManager.LoggedInOmemoManager managerGuard,
List<OmemoDevice> contactsDevices, Set<OmemoDevice> contactsDevices,
String message) String message)
throws InterruptedException, UndecidedOmemoIdentityException, CryptoFailedException, throws InterruptedException, UndecidedOmemoIdentityException, CryptoFailedException,
SmackException.NotConnectedException, SmackException.NoResponseException SmackException.NotConnectedException, SmackException.NoResponseException
@ -764,24 +767,24 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
/** /**
* Build OMEMO sessions with all devices of the contact, we haven't had sessions with before. * Build OMEMO sessions with all devices of the contact, we haven't had sessions with before.
* This method returns a list of OmemoDevices. This list contains all devices, with which we either had sessions * This method returns a set of OmemoDevices. This set contains all devices, with which we either had sessions
* before, plus those devices with which we just built sessions. * before, plus those devices with which we just built sessions.
* *
* @param connection authenticated XMPP connection. * @param connection authenticated XMPP connection.
* @param userDevice our OmemoDevice * @param userDevice our OmemoDevice
* @param contact the BareJid of the contact with whom we want to build sessions with. * @param contact the BareJid of the contact with whom we want to build sessions with.
* @return list of devices with a session. * @return set of devices with a session.
* @throws SmackException.NotConnectedException * @throws SmackException.NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
*/ */
private ArrayList<OmemoDevice> buildMissingSessionsWithContact(XMPPConnection connection, private Set<OmemoDevice> buildMissingSessionsWithContact(XMPPConnection connection,
OmemoDevice userDevice, OmemoDevice userDevice,
BareJid contact) BareJid contact)
throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException
{ {
OmemoCachedDeviceList contactsDeviceIds = getOmemoStoreBackend().loadCachedDeviceList(userDevice, contact); OmemoCachedDeviceList contactsDeviceIds = getOmemoStoreBackend().loadCachedDeviceList(userDevice, contact);
ArrayList<OmemoDevice> contactsDevices = new ArrayList<>(); Set<OmemoDevice> contactsDevices = new HashSet<>();
for (int deviceId : contactsDeviceIds.getActiveDevices()) { for (int deviceId : contactsDeviceIds.getActiveDevices()) {
contactsDevices.add(new OmemoDevice(contact, deviceId)); contactsDevices.add(new OmemoDevice(contact, deviceId));
} }
@ -790,22 +793,22 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
} }
/** /**
* Build sessions with all devices from the list, we don't have a session with yet. * Build sessions with all devices from the set, we don't have a session with yet.
* Return the list of all devices we have a session with afterwards. * Return the set of all devices we have a session with afterwards.
* @param connection authenticated XMPP connection * @param connection authenticated XMPP connection
* @param userDevice our OmemoDevice * @param userDevice our OmemoDevice
* @param devices list of devices we may want to build a session with if necessary * @param devices set of devices we may want to build a session with if necessary
* @return list of all devices with sessions * @return set of all devices with sessions
* *
* @throws SmackException.NotConnectedException * @throws SmackException.NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
*/ */
private ArrayList<OmemoDevice> buildMissingSessionsWithDevices(XMPPConnection connection, private Set<OmemoDevice> buildMissingSessionsWithDevices(XMPPConnection connection,
OmemoDevice userDevice, OmemoDevice userDevice,
List<OmemoDevice> devices) Set<OmemoDevice> devices)
throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
ArrayList<OmemoDevice> devicesWithSession = new ArrayList<>(); Set<OmemoDevice> devicesWithSession = new HashSet<>();
for (OmemoDevice device : devices) { for (OmemoDevice device : devices) {
if (hasSession(userDevice, device)) { if (hasSession(userDevice, device)) {
@ -831,34 +834,34 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
/** /**
* Build OMEMO sessions with all devices of the contacts, we haven't had sessions with before. * Build OMEMO sessions with all devices of the contacts, we haven't had sessions with before.
* This method returns a list of OmemoDevices. This list contains all devices, with which we either had sessions * This method returns a set of OmemoDevices. This set contains all devices, with which we either had sessions
* before, plus those devices with which we just built sessions. * before, plus those devices with which we just built sessions.
* *
* @param connection authenticated XMPP connection. * @param connection authenticated XMPP connection.
* @param userDevice our OmemoDevice * @param userDevice our OmemoDevice
* @param contacts list of BareJids of contacts, we want to build sessions with. * @param contacts set of BareJids of contacts, we want to build sessions with.
* @return list of devices, we have sessions with. * @return set of devices, we have sessions with.
* @throws SmackException.NotConnectedException * @throws SmackException.NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
*/ */
private ArrayList<OmemoDevice> buildMissingSessionsWithContacts(XMPPConnection connection, private Set<OmemoDevice> buildMissingSessionsWithContacts(XMPPConnection connection,
OmemoDevice userDevice, OmemoDevice userDevice,
List<BareJid> contacts) Set<BareJid> contacts)
throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException
{ {
ArrayList<OmemoDevice> devicesWithSessions = new ArrayList<>(); Set<OmemoDevice> devicesWithSessions = new HashSet<>();
for (BareJid contact : contacts) { for (BareJid contact : contacts) {
ArrayList<OmemoDevice> devices = buildMissingSessionsWithContact(connection, userDevice, contact); Set<OmemoDevice> devices = buildMissingSessionsWithContact(connection, userDevice, contact);
devicesWithSessions.addAll(devices); devicesWithSessions.addAll(devices);
} }
return devicesWithSessions; return devicesWithSessions;
} }
private ArrayList<OmemoDevice> getUndecidedDevices(OmemoDevice userDevice, OmemoTrustCallback callback, List<OmemoDevice> devices) { private Set<OmemoDevice> getUndecidedDevices(OmemoDevice userDevice, OmemoTrustCallback callback, Set<OmemoDevice> devices) {
ArrayList<OmemoDevice> undecidedDevices = new ArrayList<>(); Set<OmemoDevice> undecidedDevices = new HashSet<>();
for (OmemoDevice device : devices) { for (OmemoDevice device : devices) {
@ -880,8 +883,8 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
return undecidedDevices; return undecidedDevices;
} }
private ArrayList<OmemoDevice> getUntrustedDeviced(OmemoDevice userDevice, OmemoTrustCallback trustCallback, List<OmemoDevice> devices) { private Set<OmemoDevice> getUntrustedDeviced(OmemoDevice userDevice, OmemoTrustCallback trustCallback, Set<OmemoDevice> devices) {
ArrayList<OmemoDevice> untrustedDevices = new ArrayList<>(); Set<OmemoDevice> untrustedDevices = new HashSet<>();
for (OmemoDevice device : devices) { for (OmemoDevice device : devices) {