mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-12-06 02:51:11 +01:00
Add OMEMO support
This commit adds the modules smack-omemo and smack-omemo-signal. smack-omemo is licensed under the Apache license like the rest of the smack project. smack-omemo-signal on the other hand is licensed under the GPLv3. Due to the fact, that smack-omemo is not of much use without smack-omemo-signal, the OMEMO feature can currently only be used by GPLv3 compatible software. This may change in the future, when a more permissively licensed module becomes available. Fixes SMACK-743.
This commit is contained in:
parent
ce36fb468c
commit
e86700b040
95 changed files with 11770 additions and 22 deletions
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.jivesoftware.smackx.omemo.internal.CachedDeviceList;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* Test behavior of device lists.
|
||||
*
|
||||
* @author Paul Schaub
|
||||
*/
|
||||
public class DeviceListTest {
|
||||
|
||||
|
||||
/**
|
||||
* Test, whether deviceList updates are correctly merged into the cached device list.
|
||||
* IDs in the update become active devices, active IDs that were not in the update become inactive.
|
||||
* Inactive IDs that were not in the update stay inactive.
|
||||
*/
|
||||
@Test
|
||||
public void mergeDeviceListsTest() {
|
||||
CachedDeviceList cached = new CachedDeviceList();
|
||||
assertNotNull(cached.getActiveDevices());
|
||||
assertNotNull(cached.getInactiveDevices());
|
||||
|
||||
cached.getInactiveDevices().add(1);
|
||||
cached.getInactiveDevices().add(2);
|
||||
cached.getActiveDevices().add(3);
|
||||
|
||||
Set<Integer> update = new HashSet<>();
|
||||
update.add(4);
|
||||
update.add(1);
|
||||
|
||||
cached.merge(update);
|
||||
|
||||
assertTrue(cached.getActiveDevices().contains(1) &&
|
||||
!cached.getActiveDevices().contains(2) &&
|
||||
!cached.getActiveDevices().contains(3) &&
|
||||
cached.getActiveDevices().contains(4));
|
||||
|
||||
assertTrue(!cached.getInactiveDevices().contains(1) &&
|
||||
cached.getInactiveDevices().contains(2) &&
|
||||
cached.getInactiveDevices().contains(3) &&
|
||||
!cached.getInactiveDevices().contains(4));
|
||||
|
||||
assertTrue(cached.getAllDevices().size() == 4);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||
import org.jivesoftware.smackx.omemo.element.OmemoBundleVAxolotlElement;
|
||||
import org.jivesoftware.smackx.omemo.provider.OmemoBundleVAxolotlProvider;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test serialization and parsing of the OmemoBundleVAxolotlElement.
|
||||
*/
|
||||
public class OmemoBundleVAxolotlElementTest extends SmackTestSuite {
|
||||
|
||||
@Test
|
||||
public void serializationTest() throws Exception {
|
||||
int signedPreKeyId = 420;
|
||||
String signedPreKeyB64 = Base64.encodeToString("SignedPreKey".getBytes(StringUtils.UTF8));
|
||||
String signedPreKeySigB64 = Base64.encodeToString("SignedPreKeySignature".getBytes(StringUtils.UTF8));
|
||||
String identityKeyB64 = Base64.encodeToString("IdentityKey".getBytes(StringUtils.UTF8));
|
||||
int preKeyId1 = 220, preKeyId2 = 284;
|
||||
String preKey1B64 = Base64.encodeToString("FirstPreKey".getBytes(StringUtils.UTF8)),
|
||||
preKey2B64 = Base64.encodeToString("SecondPreKey".getBytes(StringUtils.UTF8));
|
||||
HashMap<Integer, String> preKeysB64 = new HashMap<>();
|
||||
preKeysB64.put(preKeyId1, preKey1B64);
|
||||
preKeysB64.put(preKeyId2, preKey2B64);
|
||||
|
||||
OmemoBundleVAxolotlElement bundle = new OmemoBundleVAxolotlElement(signedPreKeyId,
|
||||
signedPreKeyB64, signedPreKeySigB64, identityKeyB64, preKeysB64);
|
||||
|
||||
assertEquals("ElementName must match.", "bundle", bundle.getElementName());
|
||||
assertEquals("Namespace must match.", "eu.siacs.conversations.axolotl", bundle.getNamespace());
|
||||
|
||||
String expected =
|
||||
"<bundle xmlns='eu.siacs.conversations.axolotl'>" +
|
||||
"<signedPreKeyPublic signedPreKeyId='420'>" +
|
||||
signedPreKeyB64 +
|
||||
"</signedPreKeyPublic>" +
|
||||
"<signedPreKeySignature>" +
|
||||
signedPreKeySigB64 +
|
||||
"</signedPreKeySignature>" +
|
||||
"<identityKey>" +
|
||||
identityKeyB64 +
|
||||
"</identityKey>" +
|
||||
"<prekeys>" +
|
||||
"<preKeyPublic preKeyId='220'>" +
|
||||
preKey1B64 +
|
||||
"</preKeyPublic>" +
|
||||
"<preKeyPublic preKeyId='284'>" +
|
||||
preKey2B64 +
|
||||
"</preKeyPublic>" +
|
||||
"</prekeys>" +
|
||||
"</bundle>";
|
||||
String actual = bundle.toXML().toString();
|
||||
assertEquals("Bundles XML must match.", expected, actual);
|
||||
|
||||
byte[] signedPreKey = "SignedPreKey".getBytes(StringUtils.UTF8);
|
||||
byte[] signedPreKeySig = "SignedPreKeySignature".getBytes(StringUtils.UTF8);
|
||||
byte[] identityKey = "IdentityKey".getBytes(StringUtils.UTF8);
|
||||
byte[] firstPreKey = "FirstPreKey".getBytes(StringUtils.UTF8);
|
||||
byte[] secondPreKey = "SecondPreKey".getBytes(StringUtils.UTF8);
|
||||
|
||||
OmemoBundleVAxolotlElement parsed = new OmemoBundleVAxolotlProvider().parse(TestUtils.getParser(actual));
|
||||
|
||||
assertTrue("B64-decoded signedPreKey must match.", Arrays.equals(signedPreKey, parsed.getSignedPreKey()));
|
||||
assertEquals("SignedPreKeyId must match", signedPreKeyId, parsed.getSignedPreKeyId());
|
||||
assertTrue("B64-decoded signedPreKey signature must match.", Arrays.equals(signedPreKeySig, parsed.getSignedPreKeySignature()));
|
||||
assertTrue("B64-decoded identityKey must match.", Arrays.equals(identityKey, parsed.getIdentityKey()));
|
||||
assertTrue("B64-decoded first preKey must match.", Arrays.equals(firstPreKey, parsed.getPreKey(220)));
|
||||
assertTrue("B64-decoded second preKey must match.", Arrays.equals(secondPreKey, parsed.getPreKey(284)));
|
||||
assertEquals("toString outputs must match.", bundle.toString(), parsed.toString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.jivesoftware.smackx.omemo.OmemoConfiguration;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* Test the OmemoConfiguration class.
|
||||
*/
|
||||
public class OmemoConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void omemoConfigurationTest() {
|
||||
@SuppressWarnings("unused") OmemoConfiguration configuration = new OmemoConfiguration();
|
||||
// Default Store Path
|
||||
File storePath = new File("test");
|
||||
assertNull("getFileBasedOmemoStoreDefaultPath MUST return null at this point.",
|
||||
OmemoConfiguration.getFileBasedOmemoStoreDefaultPath());
|
||||
OmemoConfiguration.setFileBasedOmemoStoreDefaultPath(storePath);
|
||||
assertEquals("FileBasedOmemoStoreDefaultPath must equal the one we set.", storePath.getAbsolutePath(),
|
||||
OmemoConfiguration.getFileBasedOmemoStoreDefaultPath().getAbsolutePath());
|
||||
|
||||
// EME
|
||||
OmemoConfiguration.setAddEmeEncryptionHint(false);
|
||||
assertEquals(false, OmemoConfiguration.getAddEmeEncryptionHint());
|
||||
OmemoConfiguration.setAddEmeEncryptionHint(true);
|
||||
assertEquals(true, OmemoConfiguration.getAddEmeEncryptionHint());
|
||||
|
||||
// MAM
|
||||
OmemoConfiguration.setAddMAMStorageProcessingHint(false);
|
||||
assertEquals(false, OmemoConfiguration.getAddMAMStorageProcessingHint());
|
||||
OmemoConfiguration.setAddMAMStorageProcessingHint(true);
|
||||
assertEquals(true, OmemoConfiguration.getAddMAMStorageProcessingHint());
|
||||
|
||||
// Body hint
|
||||
OmemoConfiguration.setAddOmemoHintBody(false);
|
||||
assertEquals(false, OmemoConfiguration.getAddOmemoHintBody());
|
||||
OmemoConfiguration.setAddOmemoHintBody(true);
|
||||
assertEquals(true, OmemoConfiguration.getAddOmemoHintBody());
|
||||
|
||||
// Delete stale devices
|
||||
OmemoConfiguration.setDeleteStaleDevices(false);
|
||||
assertEquals(false, OmemoConfiguration.getDeleteStaleDevices());
|
||||
OmemoConfiguration.setDeleteStaleDevices(true);
|
||||
assertEquals(true, OmemoConfiguration.getDeleteStaleDevices());
|
||||
OmemoConfiguration.setDeleteStaleDevicesAfterHours(25);
|
||||
assertEquals(25, OmemoConfiguration.getDeleteStaleDevicesAfterHours());
|
||||
try {
|
||||
OmemoConfiguration.setDeleteStaleDevicesAfterHours(-3);
|
||||
TestCase.fail("OmemoConfiguration.setDeleteStaleDevicesAfterHours should not accept values <= 0.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Expected.
|
||||
}
|
||||
|
||||
// Ignore stale device
|
||||
OmemoConfiguration.setIgnoreStaleDevices(false);
|
||||
assertEquals(false, OmemoConfiguration.getIgnoreStaleDevices());
|
||||
OmemoConfiguration.setIgnoreStaleDevices(true);
|
||||
assertEquals(true, OmemoConfiguration.getIgnoreStaleDevices());
|
||||
OmemoConfiguration.setIgnoreStaleDevicesAfterHours(44);
|
||||
assertEquals(44, OmemoConfiguration.getIgnoreStaleDevicesAfterHours());
|
||||
try {
|
||||
OmemoConfiguration.setIgnoreStaleDevicesAfterHours(-5);
|
||||
TestCase.fail("OmemoConfiguration.setIgnoreStaleDevicesAfterHours should not accept values <= 0.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
// Renew signedPreKeys
|
||||
OmemoConfiguration.setRenewOldSignedPreKeys(false);
|
||||
assertEquals(false, OmemoConfiguration.getRenewOldSignedPreKeys());
|
||||
OmemoConfiguration.setRenewOldSignedPreKeys(true);
|
||||
assertEquals(true, OmemoConfiguration.getRenewOldSignedPreKeys());
|
||||
OmemoConfiguration.setRenewOldSignedPreKeysAfterHours(77);
|
||||
assertEquals(77, OmemoConfiguration.getRenewOldSignedPreKeysAfterHours());
|
||||
try {
|
||||
OmemoConfiguration.setRenewOldSignedPreKeysAfterHours(0);
|
||||
TestCase.fail("OmemoConfiguration.setRenewOldSignedPreKeysAfterHours should not accept values <= 0");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Expected
|
||||
}
|
||||
OmemoConfiguration.setMaxNumberOfStoredSignedPreKeys(6);
|
||||
assertEquals(6, OmemoConfiguration.getMaxNumberOfStoredSignedPreKeys());
|
||||
try {
|
||||
OmemoConfiguration.setMaxNumberOfStoredSignedPreKeys(0);
|
||||
TestCase.fail("OmemoConfiguration.setMaxNumberOfStoredSignedPreKeys should not accept values <= 0");
|
||||
} catch (IllegalArgumentException e) {
|
||||
//Expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smackx.omemo.element.OmemoDeviceListVAxolotlElement;
|
||||
import org.jivesoftware.smackx.omemo.provider.OmemoDeviceListVAxolotlProvider;
|
||||
import org.junit.Test;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test serialization and parsing of DeviceListElement.
|
||||
*/
|
||||
public class OmemoDeviceListVAxolotlElementTest extends SmackTestSuite {
|
||||
|
||||
@Test
|
||||
public void serializationTest() throws Exception {
|
||||
HashSet<Integer> ids = new HashSet<>();
|
||||
ids.add(1234);
|
||||
ids.add(9876);
|
||||
|
||||
OmemoDeviceListVAxolotlElement element = new OmemoDeviceListVAxolotlElement(ids);
|
||||
String xml = element.toXML().toString();
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
OmemoDeviceListVAxolotlElement parsed = new OmemoDeviceListVAxolotlProvider().parse(parser);
|
||||
|
||||
assertTrue("Parsed element must equal the original.", parsed.getDeviceIds().equals(element.getDeviceIds()));
|
||||
assertEquals("Generated XML must match.",
|
||||
"<list xmlns='eu.siacs.conversations.axolotl'>" +
|
||||
"<device id='1234'/>" +
|
||||
"<device id='9876'/>" +
|
||||
"</list>",
|
||||
xml);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test the OmemoDevice class.
|
||||
*
|
||||
* @author Paul Schaub
|
||||
*/
|
||||
public class OmemoDeviceTest {
|
||||
|
||||
/**
|
||||
* Test, if the equals() method works as intended.
|
||||
*/
|
||||
@Test
|
||||
public void testEquals() {
|
||||
BareJid romeo, juliet, guyUnderTheBalcony;
|
||||
try {
|
||||
romeo = JidCreate.bareFrom("romeo@shakespeare.lit");
|
||||
guyUnderTheBalcony = JidCreate.bareFrom("romeo@shakespeare.lit/underTheBalcony");
|
||||
juliet = JidCreate.bareFrom("juliet@shakespeare.lit");
|
||||
} catch (XmppStringprepException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
OmemoDevice r = new OmemoDevice(romeo, 1);
|
||||
OmemoDevice g = new OmemoDevice(guyUnderTheBalcony, 1);
|
||||
OmemoDevice r2 = new OmemoDevice(romeo, 2);
|
||||
OmemoDevice j = new OmemoDevice(juliet, 3);
|
||||
OmemoDevice j2 = new OmemoDevice(juliet, 1);
|
||||
|
||||
assertTrue(r.equals(g));
|
||||
assertFalse(r.equals(r2));
|
||||
assertFalse(j.equals(j2));
|
||||
assertFalse(j2.equals(r2));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CannotEstablishOmemoSessionException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.MultipleCryptoFailedException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.UndecidedOmemoIdentityException;
|
||||
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static junit.framework.TestCase.fail;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test Omemo related Exceptions.
|
||||
*/
|
||||
public class OmemoExceptionsTest {
|
||||
|
||||
@Test
|
||||
public void undecidedOmemoIdentityExceptionTest() throws XmppStringprepException {
|
||||
OmemoDevice alice = new OmemoDevice(JidCreate.bareFrom("alice@server.tld"), 1234);
|
||||
OmemoDevice bob = new OmemoDevice(JidCreate.bareFrom("bob@server.tld"), 5678);
|
||||
OmemoDevice mallory = new OmemoDevice(JidCreate.bareFrom("mallory@server.tld"), 9876);
|
||||
|
||||
UndecidedOmemoIdentityException u = new UndecidedOmemoIdentityException(alice);
|
||||
assertTrue(u.getUntrustedDevices().contains(alice));
|
||||
assertTrue(u.getUntrustedDevices().size() == 1);
|
||||
|
||||
UndecidedOmemoIdentityException v = new UndecidedOmemoIdentityException(bob);
|
||||
v.getUntrustedDevices().add(mallory);
|
||||
assertTrue(v.getUntrustedDevices().size() == 2);
|
||||
assertTrue(v.getUntrustedDevices().contains(bob));
|
||||
assertTrue(v.getUntrustedDevices().contains(mallory));
|
||||
|
||||
u.getUntrustedDevices().add(bob);
|
||||
u.join(v);
|
||||
assertTrue(u.getUntrustedDevices().size() == 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cannotEstablishOmemoSessionExceptionTest() throws XmppStringprepException {
|
||||
OmemoDevice alice1 = new OmemoDevice(JidCreate.bareFrom("alice@server.tld"), 1234);
|
||||
OmemoDevice alice2 = new OmemoDevice(JidCreate.bareFrom("alice@server.tld"), 2345);
|
||||
OmemoDevice bob = new OmemoDevice(JidCreate.bareFrom("bob@server.tld"), 5678);
|
||||
|
||||
CannotEstablishOmemoSessionException c = new CannotEstablishOmemoSessionException(alice1, null);
|
||||
assertEquals(1, c.getFailures().size());
|
||||
assertTrue(c.getFailures().containsKey(alice1.getJid()));
|
||||
|
||||
c.addSuccess(alice2);
|
||||
assertFalse(c.requiresThrowing());
|
||||
|
||||
c.addFailures(new CannotEstablishOmemoSessionException(bob, null));
|
||||
assertTrue(c.requiresThrowing());
|
||||
assertEquals(1, c.getSuccesses().size());
|
||||
assertEquals(2, c.getFailures().size());
|
||||
|
||||
c.getSuccesses().remove(alice2.getJid());
|
||||
c.addFailures(new CannotEstablishOmemoSessionException(alice2, null));
|
||||
assertEquals(2, c.getFailures().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCryptoFailedExceptionTest() {
|
||||
CryptoFailedException e1 = new CryptoFailedException("Fail");
|
||||
CryptoFailedException e2 = new CryptoFailedException("EpicFail");
|
||||
ArrayList<CryptoFailedException> l = new ArrayList<>();
|
||||
l.add(e1); l.add(e2);
|
||||
MultipleCryptoFailedException m = MultipleCryptoFailedException.from(l);
|
||||
|
||||
assertEquals(2, m.getCryptoFailedExceptions().size());
|
||||
assertTrue(m.getCryptoFailedExceptions().contains(e1));
|
||||
assertTrue(m.getCryptoFailedExceptions().contains(e2));
|
||||
|
||||
ArrayList<CryptoFailedException> el = new ArrayList<>();
|
||||
try {
|
||||
MultipleCryptoFailedException m2 = MultipleCryptoFailedException.from(el);
|
||||
fail("MultipleCryptoFailedException must not allow empty list.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.jivesoftware.smackx.omemo.OmemoFingerprint;
|
||||
import org.junit.Test;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertNotSame;
|
||||
|
||||
/**
|
||||
* Test the OmemoFingerprint class.
|
||||
*/
|
||||
public class OmemoFingerprintTest {
|
||||
|
||||
@Test
|
||||
public void fingerprintTest() {
|
||||
OmemoFingerprint first = new OmemoFingerprint("FINGER");
|
||||
OmemoFingerprint second = new OmemoFingerprint("TOE");
|
||||
|
||||
assertNotSame(first, second);
|
||||
assertEquals(first, new OmemoFingerprint("FINGER"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.jivesoftware.smackx.omemo.util.OmemoKeyUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
/**
|
||||
* Test KeyUtil functions.
|
||||
*
|
||||
* @author Paul Schaub
|
||||
*/
|
||||
public class OmemoKeyUtilTest {
|
||||
|
||||
@Test
|
||||
public void testAddInBounds() {
|
||||
int high = Integer.MAX_VALUE - 2;
|
||||
int max = Integer.MAX_VALUE;
|
||||
assertEquals(OmemoKeyUtil.addInBounds(high, 3), 1);
|
||||
assertEquals(OmemoKeyUtil.addInBounds(1,2), 3);
|
||||
assertEquals(OmemoKeyUtil.addInBounds(max, 5), 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrettyFingerprint() {
|
||||
String ugly = "FFFFFFFFEEEEEEEEDDDDDDDDCCCCCCCCBBBBBBBBAAAAAAAA9999999988888888";
|
||||
String pretty = OmemoKeyUtil.prettyFingerprint(ugly);
|
||||
assertEquals(pretty, "FFFFFFFF EEEEEEEE DDDDDDDD CCCCCCCC BBBBBBBB AAAAAAAA 99999999 88888888");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||
import org.jivesoftware.smackx.omemo.element.OmemoElement;
|
||||
import org.jivesoftware.smackx.omemo.element.OmemoVAxolotlElement;
|
||||
import org.jivesoftware.smackx.omemo.provider.OmemoVAxolotlProvider;
|
||||
import org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Test serialization and parsing of OmemoVAxolotlElements.
|
||||
*/
|
||||
public class OmemoVAxolotlElementTest extends SmackTestSuite {
|
||||
|
||||
@Test
|
||||
public void serializationTest() throws Exception {
|
||||
byte[] payload = "This is payload.".getBytes(StringUtils.UTF8);
|
||||
int keyId1 = 8;
|
||||
int keyId2 = 33333;
|
||||
byte[] keyData1 = "KEYDATA".getBytes(StringUtils.UTF8);
|
||||
byte[] keyData2 = "DATAKEY".getBytes(StringUtils.UTF8);
|
||||
int sid = 12131415;
|
||||
byte[] iv = OmemoMessageBuilder.generateIv();
|
||||
|
||||
ArrayList<OmemoElement.OmemoHeader.Key> keys = new ArrayList<>();
|
||||
keys.add(new OmemoElement.OmemoHeader.Key(keyData1, keyId1));
|
||||
keys.add(new OmemoElement.OmemoHeader.Key(keyData2, keyId2, true));
|
||||
|
||||
OmemoVAxolotlElement.OmemoHeader header = new OmemoElement.OmemoHeader(sid, keys, iv);
|
||||
OmemoVAxolotlElement element = new OmemoVAxolotlElement(header, payload);
|
||||
|
||||
String expected =
|
||||
"<encrypted xmlns='eu.siacs.conversations.axolotl'>" +
|
||||
"<header sid='12131415'>" +
|
||||
"<key rid='8'>" + Base64.encodeToString(keyData1) + "</key>" +
|
||||
"<key prekey='true' rid='33333'>" + Base64.encodeToString(keyData2) + "</key>" +
|
||||
"<iv>" + Base64.encodeToString(iv) + "</iv>" +
|
||||
"</header>" +
|
||||
"<payload>" +
|
||||
Base64.encodeToString(payload) +
|
||||
"</payload>" +
|
||||
"</encrypted>";
|
||||
|
||||
String actual = element.toXML().toString();
|
||||
assertEquals("Serialized xml of OmemoElement must match.", expected, actual);
|
||||
|
||||
OmemoVAxolotlElement parsed = new OmemoVAxolotlProvider().parse(TestUtils.getParser(actual));
|
||||
assertEquals("Parsed OmemoElement must equal the original.", element.toXML().toString(), parsed.toXML().toString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.omemo;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.omemo.element.OmemoElement;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException;
|
||||
import org.jivesoftware.smackx.omemo.internal.CipherAndAuthTag;
|
||||
import org.jivesoftware.smackx.omemo.internal.CiphertextTuple;
|
||||
import org.jivesoftware.smackx.omemo.internal.ClearTextMessage;
|
||||
import org.jivesoftware.smackx.omemo.internal.IdentityKeyWrapper;
|
||||
import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
|
||||
import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation;
|
||||
import org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Security;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Test the identityKeyWrapper.
|
||||
*/
|
||||
public class WrapperObjectsTest {
|
||||
|
||||
@Test
|
||||
public void identityKeyWrapperTest() {
|
||||
Object pseudoKey = new Object();
|
||||
IdentityKeyWrapper wrapper = new IdentityKeyWrapper(pseudoKey);
|
||||
assertEquals(pseudoKey, wrapper.getIdentityKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ciphertextTupleTest() {
|
||||
byte[] c = OmemoMessageBuilder.generateIv();
|
||||
CiphertextTuple c1 = new CiphertextTuple(c, OmemoElement.TYPE_OMEMO_PREKEY_MESSAGE);
|
||||
assertTrue(c1.isPreKeyMessage());
|
||||
assertArrayEquals(c, c1.getCiphertext());
|
||||
assertEquals(OmemoElement.TYPE_OMEMO_PREKEY_MESSAGE, c1.getMessageType());
|
||||
|
||||
CiphertextTuple c2 = new CiphertextTuple(c, OmemoElement.TYPE_OMEMO_MESSAGE);
|
||||
assertFalse(c2.isPreKeyMessage());
|
||||
assertEquals(OmemoElement.TYPE_OMEMO_MESSAGE, c2.getMessageType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearTextMessageTest() throws Exception {
|
||||
Object pseudoKey = new Object();
|
||||
IdentityKeyWrapper wrapper = new IdentityKeyWrapper(pseudoKey);
|
||||
BareJid senderJid = JidCreate.bareFrom("bob@server.tld");
|
||||
OmemoDevice sender = new OmemoDevice(senderJid, 1234);
|
||||
OmemoMessageInformation information = new OmemoMessageInformation(wrapper, sender, OmemoMessageInformation.CARBON.NONE);
|
||||
|
||||
assertTrue("OmemoInformation must state that the message is an OMEMO message.",
|
||||
information.isOmemoMessage());
|
||||
assertEquals(OmemoMessageInformation.CARBON.NONE, information.getCarbon());
|
||||
assertEquals(sender, information.getSenderDevice());
|
||||
assertEquals(wrapper, information.getSenderIdentityKey());
|
||||
|
||||
String body = "Decrypted Body";
|
||||
Message message = new Message(senderJid, body);
|
||||
ClearTextMessage c = new ClearTextMessage(body, message, information);
|
||||
|
||||
assertEquals(message, c.getOriginalMessage());
|
||||
assertEquals(information, c.getMessageInformation());
|
||||
assertEquals(body, c.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cipherAndAuthTagTest() throws NoSuchAlgorithmException, CryptoFailedException {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
byte[] key = OmemoMessageBuilder.generateKey();
|
||||
byte[] iv = OmemoMessageBuilder.generateIv();
|
||||
byte[] authTag = OmemoMessageBuilder.generateIv();
|
||||
|
||||
CipherAndAuthTag cat = new CipherAndAuthTag(key, iv, authTag);
|
||||
|
||||
assertNotNull(cat.getCipher());
|
||||
assertArrayEquals(key, cat.getKey());
|
||||
assertArrayEquals(iv, cat.getIv());
|
||||
assertArrayEquals(authTag, cat.getAuthTag());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue