diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractTwoUsersOmemoIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractTwoUsersOmemoIntegrationTest.java index 4903fe72b..68cd5f30c 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractTwoUsersOmemoIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractTwoUsersOmemoIntegrationTest.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.omemo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import java.io.IOException; import java.util.logging.Level; import org.jivesoftware.smack.SmackException; @@ -64,7 +65,7 @@ public abstract class AbstractTwoUsersOmemoIntegrationTest extends AbstractOmemo } @AfterClass - public void cleanUp() { + public void cleanUp() throws IOException { alice.stopStanzaAndPEPListeners(); bob.stopStanzaAndPEPListeners(); OmemoManagerSetupHelper.cleanUpPubSub(alice); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java index 2c3017e74..b562db8f8 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.omemo; import static org.junit.Assert.assertEquals; +import java.io.IOException; import java.util.List; import org.jivesoftware.smack.SmackException; @@ -50,7 +51,7 @@ public class OmemoMamDecryptionTest extends AbstractTwoUsersOmemoIntegrationTest @SmackIntegrationTest public void mamDecryptionTest() throws XMPPException.XMPPErrorException, SmackException.NotLoggedInException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, - CryptoFailedException, UndecidedOmemoIdentityException { + CryptoFailedException, UndecidedOmemoIdentityException, IOException { // Make sure, Bobs server stores messages in the archive MamManager bobsMamManager = MamManager.getInstanceFor(bob.getConnection()); bobsMamManager.enableMamForAllMessages(); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java index 83234924d..97fa93820 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.io.IOException; import java.util.HashMap; import org.jivesoftware.smack.SmackException; @@ -46,7 +47,7 @@ public class OmemoManagerSetupHelper { public static void trustAllIdentities(OmemoManager alice, OmemoManager bob) throws InterruptedException, SmackException.NotConnectedException, SmackException.NotLoggedInException, SmackException.NoResponseException, CannotEstablishOmemoSessionException, CorruptedOmemoKeyException, - XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException { + XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, IOException { Roster roster = Roster.getInstanceFor(alice.getConnection()); if (alice.getOwnJid() != bob.getOwnJid() && @@ -66,7 +67,7 @@ public class OmemoManagerSetupHelper { public static void trustAllIdentitiesWithTests(OmemoManager alice, OmemoManager bob) throws InterruptedException, SmackException.NotConnectedException, SmackException.NotLoggedInException, SmackException.NoResponseException, CannotEstablishOmemoSessionException, CorruptedOmemoKeyException, - XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException { + XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, IOException { alice.requestDeviceListUpdateFor(bob.getOwnJid()); HashMap fps1 = alice.getActiveFingerprints(bob.getOwnJid()); @@ -124,7 +125,7 @@ public class OmemoManagerSetupHelper { } } - public static void cleanUpPubSub(OmemoManager omemoManager) { + public static void cleanUpPubSub(OmemoManager omemoManager) throws IOException { PubSubManager pm = PubSubManager.getInstanceFor(omemoManager.getConnection(), omemoManager.getOwnJid()); try { omemoManager.requestDeviceListUpdateFor(omemoManager.getOwnJid()); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java index 3164d6668..815d4a032 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java @@ -20,6 +20,8 @@ import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertTrue; +import java.io.IOException; + import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException; @@ -37,7 +39,9 @@ public class ReadOnlyDeviceIntegrationTest extends AbstractTwoUsersOmemoIntegrat } @SmackIntegrationTest - public void test() throws InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException, SmackException.NotConnectedException, CryptoFailedException, UndecidedOmemoIdentityException { + public void test() throws InterruptedException, SmackException.NoResponseException, + SmackException.NotLoggedInException, SmackException.NotConnectedException, CryptoFailedException, + UndecidedOmemoIdentityException, IOException { boolean prevIgnoreReadOnlyConf = OmemoConfiguration.getIgnoreReadOnlyDevices(); int prevMaxMessageCounter = OmemoConfiguration.getMaxReadOnlyMessageCount(); diff --git a/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoRatchet.java b/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoRatchet.java index de20f69a9..c219b6f14 100644 --- a/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoRatchet.java +++ b/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoRatchet.java @@ -20,6 +20,7 @@ */ package org.jivesoftware.smackx.omemo.signal; +import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; @@ -73,7 +74,7 @@ public class SignalOmemoRatchet @Override public byte[] doubleRatchetDecrypt(OmemoDevice sender, byte[] encryptedKey) throws CorruptedOmemoKeyException, NoRawSessionException, CryptoFailedException, - UntrustedOmemoIdentityException { + UntrustedOmemoIdentityException, IOException { SessionCipher cipher = getCipher(sender); byte[] decryptedKey; diff --git a/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoStoreConnector.java b/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoStoreConnector.java index 0f607603a..1aae64856 100644 --- a/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoStoreConnector.java +++ b/smack-omemo-signal/src/main/java/org/jivesoftware/smackx/omemo/signal/SignalOmemoStoreConnector.java @@ -20,6 +20,7 @@ */ package org.jivesoftware.smackx.omemo.signal; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.TreeMap; @@ -79,7 +80,7 @@ public class SignalOmemoStoreConnector public IdentityKeyPair getIdentityKeyPair() { try { return omemoStore.loadOmemoIdentityKeyPair(getOurDevice()); - } catch (CorruptedOmemoKeyException e) { + } catch (CorruptedOmemoKeyException | IOException e) { LOGGER.log(Level.SEVERE, "IdentityKeyPair seems to be invalid.", e); return null; } @@ -103,7 +104,11 @@ public class SignalOmemoStoreConnector throw new AssertionError(e); } - omemoStore.storeOmemoIdentityKey(getOurDevice(), device, identityKey); + try { + omemoStore.storeOmemoIdentityKey(getOurDevice(), device, identityKey); + } catch (IOException e) { + throw new IllegalStateException(e); + } return true; } @@ -118,7 +123,12 @@ public class SignalOmemoStoreConnector @Override public PreKeyRecord loadPreKey(int i) throws InvalidKeyIdException { - PreKeyRecord preKey = omemoStore.loadOmemoPreKey(getOurDevice(), i); + PreKeyRecord preKey; + try { + preKey = omemoStore.loadOmemoPreKey(getOurDevice(), i); + } catch (IOException e) { + throw new IllegalStateException(e); + } if (preKey == null) { throw new InvalidKeyIdException("No PreKey with Id " + i + " found."); @@ -129,7 +139,11 @@ public class SignalOmemoStoreConnector @Override public void storePreKey(int i, PreKeyRecord preKeyRecord) { - omemoStore.storeOmemoPreKey(getOurDevice(), i, preKeyRecord); + try { + omemoStore.storeOmemoPreKey(getOurDevice(), i, preKeyRecord); + } catch (IOException e) { + throw new IllegalStateException(e); + } } @Override @@ -155,7 +169,12 @@ public class SignalOmemoStoreConnector throw new AssertionError(e); } - SessionRecord record = omemoStore.loadRawSession(getOurDevice(), device); + SessionRecord record; + try { + record = omemoStore.loadRawSession(getOurDevice(), device); + } catch (IOException e) { + throw new IllegalStateException(e); + } if (record != null) { return record; @@ -173,7 +192,11 @@ public class SignalOmemoStoreConnector throw new AssertionError(e); } - return new ArrayList<>(omemoStore.loadAllRawSessionsOf(getOurDevice(), jid).keySet()); + try { + return new ArrayList<>(omemoStore.loadAllRawSessionsOf(getOurDevice(), jid).keySet()); + } catch (IOException e) { + throw new IllegalStateException(e); + } } @Override @@ -185,7 +208,11 @@ public class SignalOmemoStoreConnector throw new AssertionError(e); } - omemoStore.storeRawSession(getOurDevice(), device, sessionRecord); + try { + omemoStore.storeRawSession(getOurDevice(), device, sessionRecord); + } catch (IOException e) { + throw new IllegalStateException(e); + } } @Override @@ -226,7 +253,12 @@ public class SignalOmemoStoreConnector @Override public SignedPreKeyRecord loadSignedPreKey(int i) throws InvalidKeyIdException { - SignedPreKeyRecord signedPreKeyRecord = omemoStore.loadOmemoSignedPreKey(getOurDevice(), i); + SignedPreKeyRecord signedPreKeyRecord; + try { + signedPreKeyRecord = omemoStore.loadOmemoSignedPreKey(getOurDevice(), i); + } catch (IOException e) { + throw new IllegalStateException(e); + } if (signedPreKeyRecord == null) { throw new InvalidKeyIdException("No signed preKey with id " + i + " found."); } @@ -236,14 +268,22 @@ public class SignalOmemoStoreConnector @Override public List loadSignedPreKeys() { - TreeMap signedPreKeyRecordHashMap = - omemoStore.loadOmemoSignedPreKeys(getOurDevice()); + TreeMap signedPreKeyRecordHashMap; + try { + signedPreKeyRecordHashMap = omemoStore.loadOmemoSignedPreKeys(getOurDevice()); + } catch (IOException e) { + throw new IllegalStateException(e); + } return new ArrayList<>(signedPreKeyRecordHashMap.values()); } @Override public void storeSignedPreKey(int i, SignedPreKeyRecord signedPreKeyRecord) { - omemoStore.storeOmemoSignedPreKey(getOurDevice(), i, signedPreKeyRecord); + try { + omemoStore.storeOmemoSignedPreKey(getOurDevice(), i, signedPreKeyRecord); + } catch (IOException e) { + throw new IllegalStateException(e); + } } @Override diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/CachingOmemoStore.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/CachingOmemoStore.java index 7ab0bcde6..d83984e6c 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/CachingOmemoStore.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/CachingOmemoStore.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.omemo; +import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.SortedSet; @@ -80,7 +81,7 @@ public class CachingOmemoStore loadOmemoPreKeys(OmemoDevice userDevice) { + public TreeMap loadOmemoPreKeys(OmemoDevice userDevice) throws IOException { TreeMap preKeys = getCache(userDevice).preKeys; if (preKeys.isEmpty() && persistent != null) { @@ -272,7 +273,7 @@ public class CachingOmemoStore loadOmemoSignedPreKeys(OmemoDevice userDevice) { + public TreeMap loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException { TreeMap sigPreKeys = getCache(userDevice).signedPreKeys; if (sigPreKeys.isEmpty() && persistent != null) { @@ -299,7 +300,7 @@ public class CachingOmemoStore contactSessions = getCache(userDevice).sessions.get(contactsDevice.getJid()); if (contactSessions == null) { contactSessions = new HashMap<>(); @@ -334,7 +335,7 @@ public class CachingOmemoStore loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) { + public HashMap loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException { HashMap sessions = getCache(userDevice).sessions.get(contact); if (sessions == null) { sessions = new HashMap<>(); @@ -349,7 +350,7 @@ public class CachingOmemoStore sessions = getCache(userDevice).sessions.get(contactsDevicece.getJid()); if (sessions == null) { sessions = new HashMap<>(); @@ -391,7 +392,7 @@ public class CachingOmemoStore loadOmemoPreKeys(OmemoDevice userDevice) { + public TreeMap loadOmemoPreKeys(OmemoDevice userDevice) throws IOException { File preKeyDirectory = hierarchy.getPreKeysDirectory(userDevice); TreeMap preKeys = new TreeMap<>(); @@ -221,7 +219,7 @@ public abstract class FileBasedOmemoStore loadOmemoSignedPreKeys(OmemoDevice userDevice) { + public TreeMap loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException { File signedPreKeysDirectory = hierarchy.getSignedPreKeysDirectory(userDevice); TreeMap signedPreKeys = new TreeMap<>(); @@ -263,7 +261,7 @@ public abstract class FileBasedOmemoStore loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) { + public HashMap loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException { File contactsDirectory = hierarchy.getContactsDir(userDevice, contact); HashMap sessions = new HashMap<>(); String[] devices = contactsDirectory.list(); @@ -322,7 +320,7 @@ public abstract class FileBasedOmemoStore integers = readIntegers(messageCounterFile); @@ -375,7 +373,7 @@ public abstract class FileBasedOmemoStore integers) { - if (target == null) { - LOGGER.log(Level.WARNING, "Could not write integers to null-path."); - return; - } - - DataOutputStream out = null; - - try { - out = new DataOutputStream(new FileOutputStream(target)); - for (int i : integers) { - out.writeInt(i); - } - - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Could not write integers to file.", e); - } finally { - CloseableUtil.maybeClose(out, LOGGER); - } - } - - private static Set readIntegers(File target) { - if (target == null) { - LOGGER.log(Level.WARNING, "Could not read integers from null-path."); - return null; - } - - HashSet integers = new HashSet<>(); - DataInputStream in = null; - - try { - in = new DataInputStream(new FileInputStream(target)); - - try { - while (true) { - integers.add(in.readInt()); - } - } catch (EOFException e) { - // Reached end of the list. - } - - } catch (FileNotFoundException e) { - integers = null; - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Could not read integers.", e); - } finally { - CloseableUtil.maybeClose(in, LOGGER); - } - - return integers; - } - - /** - * One day... *sheds a tear* - * TODO Use methods below once Smack's minimum Android API level is 19 or higher - */ - /* - private static void writeLong(File target, long i) - throws IOException - { + private static void writeLong(File target, long i) throws IOException { if (target == null) { throw new IOException("Could not write long to null-path."); } @@ -591,9 +430,7 @@ public abstract class FileBasedOmemoStore integers) - throws IOException - { + private static void writeIntegers(File target, Set integers) throws IOException { if (target == null) { throw new IOException("Could not write integers to null-path."); } @@ -657,9 +488,7 @@ public abstract class FileBasedOmemoStore readIntegers(File target) - throws IOException - { + private static Set readIntegers(File target) throws IOException { if (target == null) { throw new IOException("Could not write integers to null-path."); } @@ -682,7 +511,6 @@ public abstract class FileBasedOmemoStore getDevicesOf(BareJid contact) { + public Set getDevicesOf(BareJid contact) throws IOException { OmemoCachedDeviceList list = getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(getOwnDevice(), contact); HashSet devices = new HashSet<>(); @@ -304,11 +307,12 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException * @throws SmackException.NoResponseException * @throws SmackException.NotLoggedInException + * @throws IOException */ public OmemoMessage.Sent encrypt(BareJid recipient, String message) throws CryptoFailedException, UndecidedOmemoIdentityException, InterruptedException, SmackException.NotConnectedException, - SmackException.NoResponseException, SmackException.NotLoggedInException { + SmackException.NoResponseException, SmackException.NotLoggedInException, IOException { synchronized (LOCK) { Set recipients = new HashSet<>(); recipients.add(recipient); @@ -328,11 +332,12 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException * @throws SmackException.NoResponseException * @throws SmackException.NotLoggedInException + * @throws IOException */ public OmemoMessage.Sent encrypt(Set recipients, String message) throws CryptoFailedException, UndecidedOmemoIdentityException, InterruptedException, SmackException.NotConnectedException, - SmackException.NoResponseException, SmackException.NotLoggedInException { + SmackException.NoResponseException, SmackException.NotLoggedInException, IOException { synchronized (LOCK) { LoggedInOmemoManager guard = new LoggedInOmemoManager(this); Set devices = getDevicesOf(getOwnJid()); @@ -357,12 +362,13 @@ public final class OmemoManager extends Manager { * @throws SmackException.NoResponseException * @throws NoOmemoSupportException When the muc doesn't support OMEMO. * @throws SmackException.NotLoggedInException + * @throws IOException */ public OmemoMessage.Sent encrypt(MultiUserChat muc, String message) throws UndecidedOmemoIdentityException, CryptoFailedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, NoOmemoSupportException, - SmackException.NotLoggedInException { + SmackException.NotLoggedInException, IOException { synchronized (LOCK) { if (!multiUserChatSupportsOmemo(muc)) { throw new NoOmemoSupportException(); @@ -390,10 +396,11 @@ public final class OmemoManager extends Manager { * @throws CorruptedOmemoKeyException if our or their key is corrupted * @throws NoRawSessionException if the message was not a preKeyMessage, but we had no session with the contact * @throws CryptoFailedException if decryption fails + * @throws IOException */ public OmemoMessage.Received decrypt(BareJid sender, OmemoElement omemoElement) throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, NoRawSessionException, - CryptoFailedException { + CryptoFailedException, IOException { LoggedInOmemoManager managerGuard = new LoggedInOmemoManager(this); return getOmemoService().decryptMessage(managerGuard, sender, omemoElement); } @@ -404,9 +411,10 @@ public final class OmemoManager extends Manager { * @param mamQuery The MAM query * @return list of decrypted OmemoMessages * @throws SmackException.NotLoggedInException if the Manager is not authenticated. + * @throws IOException */ public List decryptMamQueryResult(MamManager.MamQuery mamQuery) - throws SmackException.NotLoggedInException { + throws SmackException.NotLoggedInException, IOException { return new ArrayList<>(getOmemoService().decryptMamQueryResult(new LoggedInOmemoManager(this), mamQuery)); } @@ -486,11 +494,12 @@ public final class OmemoManager extends Manager { * @throws SmackException.NoResponseException * @throws NoSuchAlgorithmException * @throws SmackException.NotConnectedException + * @throws IOException */ public void sendRatchetUpdateMessage(OmemoDevice recipient) throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException, NoSuchAlgorithmException, SmackException.NotConnectedException, - CryptoFailedException, CannotEstablishOmemoSessionException { + CryptoFailedException, CannotEstablishOmemoSessionException, IOException { synchronized (LOCK) { Message message = new Message(); message.setFrom(getOwnJid()); @@ -516,10 +525,11 @@ public final class OmemoManager extends Manager { * @throws SmackException.NoResponseException * @throws PubSubException.NotALeafNodeException * @throws XMPPException.XMPPErrorException + * @throws IOException */ public boolean contactSupportsOmemo(BareJid contact) throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, - SmackException.NotConnectedException, SmackException.NoResponseException { + SmackException.NotConnectedException, SmackException.NoResponseException, IOException { synchronized (LOCK) { OmemoCachedDeviceList deviceList = getOmemoService().refreshDeviceList(connection(), getOwnDevice(), contact); return !deviceList.getActiveDevices().isEmpty(); @@ -569,9 +579,10 @@ public final class OmemoManager extends Manager { * @return fingerprint * @throws SmackException.NotLoggedInException if we don't know our bareJid yet. * @throws CorruptedOmemoKeyException if our identityKey is corrupted. + * @throws IOException */ public OmemoFingerprint getOwnFingerprint() - throws SmackException.NotLoggedInException, CorruptedOmemoKeyException { + throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, IOException { synchronized (LOCK) { if (getOwnJid() == null) { throw new SmackException.NotLoggedInException(); @@ -591,11 +602,12 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException * @throws InterruptedException * @throws SmackException.NoResponseException + * @throws IOException */ public OmemoFingerprint getFingerprint(OmemoDevice device) throws CannotEstablishOmemoSessionException, SmackException.NotLoggedInException, CorruptedOmemoKeyException, SmackException.NotConnectedException, InterruptedException, - SmackException.NoResponseException { + SmackException.NoResponseException, IOException { synchronized (LOCK) { if (getOwnJid() == null) { throw new SmackException.NotLoggedInException(); @@ -621,11 +633,12 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException * @throws InterruptedException * @throws SmackException.NoResponseException + * @throws IOException */ public HashMap getActiveFingerprints(BareJid contact) throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, CannotEstablishOmemoSessionException, SmackException.NotConnectedException, InterruptedException, - SmackException.NoResponseException { + SmackException.NoResponseException, IOException { synchronized (LOCK) { if (getOwnJid() == null) { throw new SmackException.NotLoggedInException(); @@ -692,10 +705,11 @@ public final class OmemoManager extends Manager { * @throws XMPPException.XMPPErrorException * @throws SmackException.NotConnectedException * @throws SmackException.NoResponseException + * @throws IOException */ public void requestDeviceListUpdateFor(BareJid contact) throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, - SmackException.NotConnectedException, SmackException.NoResponseException { + SmackException.NotConnectedException, SmackException.NoResponseException, IOException { synchronized (LOCK) { getOmemoService().refreshDeviceList(connection(), getOwnDevice(), contact); } @@ -709,10 +723,11 @@ public final class OmemoManager extends Manager { * @throws XMPPException.XMPPErrorException * @throws SmackException.NotConnectedException * @throws SmackException.NoResponseException + * @throws IOException */ public void purgeDeviceList() throws SmackException.NotLoggedInException, InterruptedException, XMPPException.XMPPErrorException, - SmackException.NotConnectedException, SmackException.NoResponseException { + SmackException.NotConnectedException, SmackException.NoResponseException, IOException { synchronized (LOCK) { getOmemoService().purgeDeviceList(new LoggedInOmemoManager(this)); } @@ -729,10 +744,11 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException XMPP error * @throws SmackException.NoResponseException XMPP error * @throws SmackException.NotLoggedInException + * @throws IOException */ public void rotateSignedPreKey() throws CorruptedOmemoKeyException, SmackException.NotLoggedInException, XMPPException.XMPPErrorException, - SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { + SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, IOException { synchronized (LOCK) { if (!connection().isAuthenticated()) { throw new SmackException.NotLoggedInException(); @@ -956,8 +972,8 @@ public final class OmemoManager extends Manager { try { getOmemoService().onOmemoMessageStanzaReceived(packet, new LoggedInOmemoManager(OmemoManager.this)); - } catch (SmackException.NotLoggedInException e) { - LOGGER.warning("Received OMEMO stanza while being offline: " + e); + } catch (SmackException.NotLoggedInException | IOException e) { + LOGGER.log(Level.SEVERE, "Exception while processing OMEMO stanza", e); } } }); @@ -979,8 +995,8 @@ public final class OmemoManager extends Manager { try { getOmemoService().onOmemoCarbonCopyReceived(direction, carbonCopy, wrappingMessage, new LoggedInOmemoManager(OmemoManager.this)); - } catch (SmackException.NotLoggedInException e) { - LOGGER.warning("Received OMEMO carbon copy while being offline: " + e); + } catch (SmackException.NotLoggedInException | IOException e) { + LOGGER.log(Level.SEVERE, "Exception while processing OMEMO stanza", e); } } } @@ -1018,14 +1034,23 @@ public final class OmemoManager extends Manager { } // Device List + OmemoCachedDeviceList deviceList; OmemoDeviceListElement receivedDeviceList = (OmemoDeviceListElement) payloadItem.getPayload(); - getOmemoService().getOmemoStoreBackend().mergeCachedDeviceList(getOwnDevice(), from, receivedDeviceList); + try { + getOmemoService().getOmemoStoreBackend().mergeCachedDeviceList(getOwnDevice(), from, + receivedDeviceList); - if (!from.asBareJid().equals(getOwnJid())) { + if (!from.asBareJid().equals(getOwnJid())) { + continue; + } + + deviceList = getOmemoService().cleanUpDeviceList(getOwnDevice()); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, + "IOException while processing OMEMO PEP device updates. Message: " + message, + e); continue; } - - OmemoCachedDeviceList deviceList = getOmemoService().cleanUpDeviceList(getOwnDevice()); final OmemoDeviceListElement_VAxolotl newDeviceList = new OmemoDeviceListElement_VAxolotl(deviceList); if (!newDeviceList.copyDeviceIds().equals(receivedDeviceList.copyDeviceIds())) { diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java index 28ffc50ef..7ad0f6b6e 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.omemo; +import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -65,10 +66,11 @@ public abstract class OmemoRatchet decryptExceptions = new ArrayList<>(); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java index 91eb51034..1130e63fc 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.omemo; import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.KEYLENGTH; import static org.jivesoftware.smackx.omemo.util.OmemoConstants.Crypto.KEYTYPE; +import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -234,11 +235,12 @@ public abstract class OmemoService contactsDevices, @@ -341,7 +345,7 @@ public abstract class OmemoService contactsDevices, byte[] key, byte[] iv) throws InterruptedException, UndecidedOmemoIdentityException, CryptoFailedException, - SmackException.NotConnectedException, SmackException.NoResponseException { + SmackException.NotConnectedException, SmackException.NoResponseException, IOException { return encrypt(managerGuard, contactsDevices, key, iv, null); } @@ -511,12 +517,13 @@ public abstract class OmemoService contactsDevices, String message) throws InterruptedException, UndecidedOmemoIdentityException, CryptoFailedException, - SmackException.NotConnectedException, SmackException.NoResponseException { + SmackException.NotConnectedException, SmackException.NoResponseException, IOException { byte[] key, iv; iv = OmemoMessageBuilder.generateIv(); @@ -643,10 +650,11 @@ public abstract class OmemoService buildMissingSessionsWithDevices(XMPPConnection connection, OmemoDevice userDevice, Set devices) - throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { + throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, IOException { Set devicesWithSession = new HashSet<>(); for (OmemoDevice device : devices) { @@ -828,8 +839,9 @@ public abstract class OmemoService getUndecidedDevices(OmemoDevice userDevice, OmemoTrustCallback callback, Set devices) { + private Set getUndecidedDevices(OmemoDevice userDevice, OmemoTrustCallback callback, Set devices) throws IOException { Set undecidedDevices = new HashSet<>(); for (OmemoDevice device : devices) { @@ -858,8 +870,9 @@ public abstract class OmemoService decryptMamQueryResult(OmemoManager.LoggedInOmemoManager managerGuard, - MamManager.MamQuery mamQuery) { + MamManager.MamQuery mamQuery) throws IOException { List result = new ArrayList<>(); for (Message message : mamQuery.getMessages()) { if (OmemoManager.stanzaContainsOmemoElement(message)) { @@ -1055,7 +1072,7 @@ public abstract class OmemoService preKeyHashMap) { + public void storeOmemoPreKeys(OmemoDevice userDevice, TreeMap preKeyHashMap) throws IOException { for (Map.Entry entry : preKeyHashMap.entrySet()) { storeOmemoPreKey(userDevice, entry.getKey(), entry.getValue()); } @@ -422,8 +444,9 @@ public abstract class OmemoStore loadOmemoPreKeys(OmemoDevice userDevice); + public abstract TreeMap loadOmemoPreKeys(OmemoDevice userDevice) throws IOException; /** * Return the signedPreKey with the id 'singedPreKeyId'. @@ -431,10 +454,11 @@ public abstract class OmemoStore loadOmemoSignedPreKeys(OmemoDevice userDevice); + public abstract TreeMap loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException; /** * Generate a new signed preKey. @@ -465,8 +490,9 @@ public abstract class OmemoStore loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact); + public abstract HashMap loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException; /** * Store a crypto-lib specific session to storage. @@ -500,8 +528,9 @@ public abstract class OmemoStore sessions = store.loadAllRawSessionsOf(alice, bob.getJid()); assertNotNull(sessions); assertEquals(0, sessions.size()); } @Test - public void loadNonExistentRawSessionReturnsNullTest() { + public void loadNonExistentRawSessionReturnsNullTest() throws IOException { T_Sess session = store.loadRawSession(alice, bob); assertNull(session); } @Test - public void loadStoreMessageCounterTest() { + public void loadStoreMessageCounterTest() throws IOException { assertEquals(0, store.loadOmemoMessageCounter(alice, bob)); store.storeOmemoMessageCounter(alice, bob, 20); assertEquals(20, store.loadOmemoMessageCounter(alice, bob));