mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-09 17:19:39 +02:00
Merge branch '4.2'
This commit is contained in:
commit
f5ef42ec56
98 changed files with 11783 additions and 27 deletions
|
@ -11,6 +11,7 @@ dependencies {
|
|||
compile project(':smack-tcp')
|
||||
compile project(':smack-extensions')
|
||||
compile project(':smack-experimental')
|
||||
compile project(':smack-omemo')
|
||||
compile 'org.reflections:reflections:0.9.9-RC1'
|
||||
compile 'eu.geekplace.javapinning:java-pinning-java7:1.1.0-alpha1'
|
||||
compile "junit:junit:$junitVersion"
|
||||
|
|
|
@ -196,10 +196,14 @@ public final class Configuration {
|
|||
return addTestPackage(enabledTest.getPackage().getName());
|
||||
}
|
||||
|
||||
public Builder addTestPackage(String testPackage) {
|
||||
private void ensureTestPackagesIsSet(int length) {
|
||||
if (testPackages == null) {
|
||||
testPackages = new HashSet<>();
|
||||
testPackages = new HashSet<>(length);
|
||||
}
|
||||
}
|
||||
|
||||
public Builder addTestPackage(String testPackage) {
|
||||
ensureTestPackagesIsSet(4);
|
||||
testPackages.add(testPackage);
|
||||
return this;
|
||||
}
|
||||
|
@ -260,10 +264,12 @@ public final class Configuration {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setTestPackages(String testPackagesString) {
|
||||
public Builder addTestPackages(String testPackagesString) {
|
||||
if (testPackagesString != null) {
|
||||
String[] testPackagesArray = testPackagesString.split(",");
|
||||
testPackages = new HashSet<>(testPackagesArray.length);
|
||||
|
||||
ensureTestPackagesIsSet(testPackagesArray.length);
|
||||
|
||||
for (String s : testPackagesArray) {
|
||||
testPackages.add(s.trim());
|
||||
}
|
||||
|
@ -271,6 +277,19 @@ public final class Configuration {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder addTestPackages(String[] testPackagesString) {
|
||||
if (testPackagesString == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
ensureTestPackagesIsSet(testPackagesString.length);
|
||||
|
||||
for (String testPackage : testPackagesString) {
|
||||
testPackages.add(testPackage);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Configuration build() throws KeyManagementException, NoSuchAlgorithmException {
|
||||
return new Configuration(service, serviceTlsPin, securityMode, replyTimeout, debug, accountOneUsername,
|
||||
accountOnePassword, accountTwoUsername, accountTwoPassword, accountThreeUsername, accountThreePassword, enabledTests, disabledTests,
|
||||
|
@ -280,7 +299,7 @@ public final class Configuration {
|
|||
|
||||
private static final String SINTTEST = "sinttest.";
|
||||
|
||||
public static Configuration newConfiguration()
|
||||
public static Configuration newConfiguration(String[] testPackages)
|
||||
throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
Properties properties = new Properties();
|
||||
|
||||
|
@ -330,7 +349,9 @@ public final class Configuration {
|
|||
builder.setDebug(properties.getProperty("debug"));
|
||||
builder.setEnabledTests(properties.getProperty("enabledTests"));
|
||||
builder.setDisabledTests(properties.getProperty("disabledTests"));
|
||||
builder.setTestPackages(properties.getProperty("testPackages"));
|
||||
|
||||
builder.addTestPackages(properties.getProperty("testPackages"));
|
||||
builder.addTestPackages(testPackages);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ public class SmackIntegrationTestFramework {
|
|||
|
||||
public static void main(String[] args) throws IOException, KeyManagementException,
|
||||
NoSuchAlgorithmException, SmackException, XMPPException, InterruptedException {
|
||||
Configuration config = Configuration.newConfiguration();
|
||||
Configuration config = Configuration.newConfiguration(args);
|
||||
|
||||
SmackIntegrationTestFramework sinttest = new SmackIntegrationTestFramework(config);
|
||||
TestRunResult testRunResult = sinttest.run();
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
|||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||
import org.jivesoftware.smackx.mam.MamManager.MamQueryResult;
|
||||
import org.jivesoftware.smackx.mam.element.MamPrefsIQ;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
|
||||
public class MamIntegrationTest extends AbstractSmackIntegrationTest {
|
||||
|
@ -55,6 +56,9 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest {
|
|||
EntityBareJid userOne = conOne.getUser().asEntityBareJid();
|
||||
EntityBareJid userTwo = conTwo.getUser().asEntityBareJid();
|
||||
|
||||
//Make sure MAM is archiving messages
|
||||
mamManagerConTwo.updateArchivingPreferences(null, null, MamPrefsIQ.DefaultBehavior.always);
|
||||
|
||||
Message message = new Message(userTwo);
|
||||
String messageId = message.setStanzaId();
|
||||
String messageBody = "test message";
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus, 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.smackx.omemo;
|
||||
|
||||
import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Super class for OMEMO integration tests.
|
||||
*/
|
||||
public abstract class AbstractOmemoIntegrationTest extends AbstractSmackIntegrationTest {
|
||||
|
||||
static final File storePath;
|
||||
|
||||
static {
|
||||
String userHome = System.getProperty("user.home");
|
||||
if (userHome != null) {
|
||||
File f = new File(userHome);
|
||||
storePath = new File(f, ".config/smack-integration-test/store");
|
||||
} else {
|
||||
storePath = new File("int_test_omemo_store");
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractOmemoIntegrationTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, TestNotPossibleException {
|
||||
super(environment);
|
||||
if (OmemoConfiguration.getFileBasedOmemoStoreDefaultPath() == null) {
|
||||
OmemoConfiguration.setFileBasedOmemoStoreDefaultPath(storePath);
|
||||
}
|
||||
// Test for server support
|
||||
if (!OmemoManager.serverSupportsOmemo(connection, connection.getXMPPServiceDomain())) {
|
||||
throw new TestNotPossibleException("Server does not support OMEMO (PubSub)");
|
||||
}
|
||||
|
||||
//Check for OmemoService
|
||||
if (!OmemoService.isServiceRegistered()) {
|
||||
throw new TestNotPossibleException("No OmemoService registered.");
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public void beforeTest() {
|
||||
LOGGER.log(Level.INFO, "START EXECUTION");
|
||||
OmemoIntegrationTestHelper.deletePath(storePath);
|
||||
before();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void afterTest() {
|
||||
after();
|
||||
OmemoIntegrationTestHelper.deletePath(storePath);
|
||||
LOGGER.log(Level.INFO, "END EXECUTION");
|
||||
}
|
||||
|
||||
public abstract void before();
|
||||
|
||||
public abstract void after();
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus, 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.smackx.omemo;
|
||||
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException;
|
||||
import org.jivesoftware.smackx.omemo.util.OmemoConstants;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||
|
||||
import static junit.framework.TestCase.assertNotNull;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.cleanServerSideTraces;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.setUpOmemoManager;
|
||||
|
||||
public class OmemoInitializationTest extends AbstractOmemoIntegrationTest {
|
||||
|
||||
private OmemoManager alice;
|
||||
private OmemoStore<?,?,?,?,?,?,?,?,?> store;
|
||||
|
||||
@Override
|
||||
public void before() {
|
||||
alice = OmemoManager.getInstanceFor(conOne, 666);
|
||||
store = OmemoService.getInstance().getOmemoStoreBackend();
|
||||
}
|
||||
|
||||
public OmemoInitializationTest(SmackIntegrationTestEnvironment environment) throws TestNotPossibleException, XMPPErrorException, NotConnectedException, NoResponseException, InterruptedException {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests, if the initialization is done properly.
|
||||
*/
|
||||
@SmackIntegrationTest
|
||||
public void initializationTest() throws XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, SmackException.NotLoggedInException, CorruptedOmemoKeyException {
|
||||
//test keys.
|
||||
setUpOmemoManager(alice);
|
||||
assertNotNull("IdentityKey must not be null after initialization.", store.loadOmemoIdentityKeyPair(alice));
|
||||
assertTrue("We must have " + OmemoConstants.TARGET_PRE_KEY_COUNT + " preKeys.",
|
||||
store.loadOmemoPreKeys(alice).size() == OmemoConstants.TARGET_PRE_KEY_COUNT);
|
||||
assertNotNull("Our signedPreKey must not be null.", store.loadCurrentSignedPreKeyId(alice));
|
||||
|
||||
//Is deviceId published?
|
||||
assertTrue("Published deviceList must contain our deviceId.",
|
||||
OmemoService.fetchDeviceList(alice, alice.getOwnJid())
|
||||
.getDeviceIds().contains(alice.getDeviceId()));
|
||||
|
||||
assertTrue("Our fingerprint must be of correct length.",
|
||||
OmemoService.getInstance().getOmemoStoreBackend().getFingerprint(alice).length() == 64);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void after() {
|
||||
alice.shutdown();
|
||||
cleanServerSideTraces(alice);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus, 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.smackx.omemo;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.roster.Roster;
|
||||
import org.jivesoftware.smack.roster.RosterEntry;
|
||||
import org.jivesoftware.smackx.omemo.element.OmemoBundleElement;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CannotEstablishOmemoSessionException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException;
|
||||
import org.jivesoftware.smackx.omemo.internal.CachedDeviceList;
|
||||
import org.jivesoftware.smackx.omemo.util.OmemoConstants;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubAssertionError;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertNotNull;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
|
||||
/**
|
||||
* Class containing some helper methods for OmemoIntegrationTests.
|
||||
*/
|
||||
final class OmemoIntegrationTestHelper {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(OmemoIntegrationTestHelper.class.getSimpleName());
|
||||
|
||||
static void cleanServerSideTraces(OmemoManager omemoManager) {
|
||||
cleanUpPubSub(omemoManager);
|
||||
cleanUpRoster(omemoManager);
|
||||
}
|
||||
|
||||
static void deletePath(File storePath) {
|
||||
FileBasedOmemoStore.deleteDirectory(storePath);
|
||||
}
|
||||
|
||||
static void deletePath(OmemoManager omemoManager) {
|
||||
OmemoService.getInstance().getOmemoStoreBackend().purgeOwnDeviceKeys(omemoManager);
|
||||
}
|
||||
|
||||
static void cleanUpPubSub(OmemoManager omemoManager) {
|
||||
PubSubManager pm = PubSubManager.getInstance(omemoManager.getConnection(),omemoManager.getOwnJid());
|
||||
try {
|
||||
omemoManager.requestDeviceListUpdateFor(omemoManager.getOwnJid());
|
||||
} catch (SmackException.NotConnectedException | InterruptedException | SmackException.NoResponseException e) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
CachedDeviceList deviceList = OmemoService.getInstance().getOmemoStoreBackend().loadCachedDeviceList(omemoManager, omemoManager.getOwnJid());
|
||||
for (int id : deviceList.getAllDevices()) {
|
||||
try {
|
||||
pm.getLeafNode(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(id)).deleteAllItems();
|
||||
} catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | PubSubAssertionError.DiscoInfoNodeAssertionError e) {
|
||||
//Silent
|
||||
}
|
||||
|
||||
try {
|
||||
pm.deleteNode(OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID(id));
|
||||
} catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | PubSubAssertionError e) {
|
||||
//Silent
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
pm.getLeafNode(OmemoConstants.PEP_NODE_DEVICE_LIST).deleteAllItems();
|
||||
} catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException | PubSubAssertionError.DiscoInfoNodeAssertionError e) {
|
||||
//Silent
|
||||
}
|
||||
|
||||
try {
|
||||
pm.deleteNode(OmemoConstants.PEP_NODE_DEVICE_LIST);
|
||||
} catch (SmackException.NoResponseException | InterruptedException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | PubSubAssertionError e) {
|
||||
//Silent
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanUpRoster(OmemoManager omemoManager) {
|
||||
Roster roster = Roster.getInstanceFor(omemoManager.getConnection());
|
||||
for (RosterEntry r : roster.getEntries()) {
|
||||
try {
|
||||
roster.removeEntry(r);
|
||||
} catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException | SmackException.NotLoggedInException e) {
|
||||
//Silent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let Alice subscribe to Bob.
|
||||
* @param alice
|
||||
* @param bob
|
||||
* @throws SmackException.NotLoggedInException
|
||||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws SmackException.NoResponseException
|
||||
*/
|
||||
static void subscribe(OmemoManager alice, OmemoManager bob, String nick)
|
||||
throws SmackException.NotLoggedInException, XMPPException.XMPPErrorException,
|
||||
SmackException.NotConnectedException, InterruptedException,
|
||||
SmackException.NoResponseException {
|
||||
|
||||
Roster aliceRoster = Roster.getInstanceFor(alice.getConnection());
|
||||
Roster bobsRoster = Roster.getInstanceFor(bob.getConnection());
|
||||
bobsRoster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);
|
||||
aliceRoster.createEntry(bob.getOwnJid(), nick, null);
|
||||
}
|
||||
|
||||
|
||||
static void unidirectionalTrust(OmemoManager alice, OmemoManager bob) throws SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, CannotEstablishOmemoSessionException {
|
||||
//Fetch deviceList
|
||||
alice.requestDeviceListUpdateFor(bob.getOwnJid());
|
||||
LOGGER.log(Level.INFO, "Current deviceList state: " + alice.getOwnDevice() + " knows " + bob.getOwnDevice() + ": "
|
||||
+ OmemoService.getInstance().getOmemoStoreBackend().loadCachedDeviceList(alice, bob.getOwnJid()));
|
||||
assertTrue("Trusting party must know the others device at this point.",
|
||||
alice.getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(alice, bob.getOwnJid())
|
||||
.getActiveDevices().contains(bob.getDeviceId()));
|
||||
|
||||
//Create sessions
|
||||
alice.buildSessionsWith(bob.getOwnJid());
|
||||
assertTrue("Trusting party must have a session with the other end at this point.",
|
||||
!alice.getOmemoService().getOmemoStoreBackend().loadAllRawSessionsOf(alice, bob.getOwnJid()).isEmpty());
|
||||
|
||||
//Trust the other party
|
||||
alice.getOmemoService().getOmemoStoreBackend().trustOmemoIdentity(alice, bob.getOwnDevice(),
|
||||
alice.getOmemoService().getOmemoStoreBackend().getFingerprint(alice, bob.getOwnDevice()));
|
||||
|
||||
}
|
||||
|
||||
static void setUpOmemoManager(OmemoManager omemoManager) throws CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException, SmackException.NotConnectedException, XMPPException.XMPPErrorException, SmackException.NotLoggedInException, PubSubException.NotALeafNodeException {
|
||||
omemoManager.initialize();
|
||||
OmemoBundleElement bundle = OmemoService.fetchBundle(omemoManager, omemoManager.getOwnDevice());
|
||||
assertNotNull("Bundle must not be null.", bundle);
|
||||
assertEquals("Published Bundle must equal our local bundle.", bundle, omemoManager.getOmemoService().getOmemoStoreBackend().packOmemoBundle(omemoManager));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus, 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.smackx.omemo;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||
import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.chat2.ChatManager;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.omemo.element.OmemoElement;
|
||||
import org.jivesoftware.smackx.omemo.internal.CipherAndAuthTag;
|
||||
import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation;
|
||||
import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener;
|
||||
import org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.cleanServerSideTraces;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.setUpOmemoManager;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.subscribe;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.unidirectionalTrust;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test keyTransportMessages.
|
||||
*/
|
||||
public class OmemoKeyTransportTest extends AbstractOmemoIntegrationTest {
|
||||
|
||||
private OmemoManager alice, bob;
|
||||
|
||||
public OmemoKeyTransportTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, TestNotPossibleException {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void before() {
|
||||
alice = OmemoManager.getInstanceFor(conOne, 11111);
|
||||
bob = OmemoManager.getInstanceFor(conTwo, 222222);
|
||||
}
|
||||
|
||||
@SmackIntegrationTest
|
||||
public void keyTransportTest() throws Exception {
|
||||
final SimpleResultSyncPoint syncPoint = new SimpleResultSyncPoint();
|
||||
|
||||
subscribe(alice, bob, "Bob");
|
||||
subscribe(bob, alice, "Alice");
|
||||
|
||||
setUpOmemoManager(alice);
|
||||
setUpOmemoManager(bob);
|
||||
|
||||
unidirectionalTrust(alice, bob);
|
||||
unidirectionalTrust(bob, alice);
|
||||
|
||||
final byte[] key = OmemoMessageBuilder.generateKey();
|
||||
final byte[] iv = OmemoMessageBuilder.generateIv();
|
||||
|
||||
bob.addOmemoMessageListener(new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
//Don't care
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
LOGGER.log(Level.INFO, "Received a keyTransportMessage.");
|
||||
assertTrue("Key must match the one we sent.", Arrays.equals(key, cipherAndAuthTag.getKey()));
|
||||
assertTrue("IV must match the one we sent.", Arrays.equals(iv, cipherAndAuthTag.getIv()));
|
||||
syncPoint.signal();
|
||||
}
|
||||
});
|
||||
|
||||
OmemoElement keyTransportElement = alice.createKeyTransportElement(key, iv, bob.getOwnDevice());
|
||||
Message message = new Message(bob.getOwnJid());
|
||||
message.addExtension(keyTransportElement);
|
||||
ChatManager.getInstanceFor(alice.getConnection()).chatWith(bob.getOwnJid().asEntityBareJidIfPossible())
|
||||
.send(message);
|
||||
|
||||
try {
|
||||
syncPoint.waitForResult(10 * 1000);
|
||||
} catch (TimeoutException e) {
|
||||
TestCase.fail("We MUST have received the keyTransportMessage within 10 seconds.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void after() {
|
||||
alice.shutdown();
|
||||
bob.shutdown();
|
||||
cleanServerSideTraces(alice);
|
||||
cleanServerSideTraces(bob);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus, 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.smackx.omemo;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||
import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.chat2.ChatManager;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.omemo.element.OmemoBundleElement;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CannotEstablishOmemoSessionException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException;
|
||||
import org.jivesoftware.smackx.omemo.exceptions.UndecidedOmemoIdentityException;
|
||||
import org.jivesoftware.smackx.omemo.internal.CipherAndAuthTag;
|
||||
import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation;
|
||||
import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertNotSame;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.cleanServerSideTraces;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.setUpOmemoManager;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.subscribe;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.unidirectionalTrust;
|
||||
|
||||
/**
|
||||
* Test message sending.
|
||||
*/
|
||||
public class OmemoMessageSendingTest extends AbstractOmemoIntegrationTest {
|
||||
|
||||
private OmemoManager alice, bob;
|
||||
private OmemoStore<?,?,?,?,?,?,?,?,?> store;
|
||||
|
||||
public OmemoMessageSendingTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, TestNotPossibleException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void before() {
|
||||
alice = OmemoManager.getInstanceFor(conOne, 123);
|
||||
bob = OmemoManager.getInstanceFor(conTwo, 345);
|
||||
store = OmemoService.getInstance().getOmemoStoreBackend();
|
||||
}
|
||||
|
||||
/**
|
||||
* This Test tests sending and receiving messages.
|
||||
* Alice and Bob create fresh devices, then they add another to their rosters.
|
||||
* Next they build sessions with one another and Alice sends a message to Bob.
|
||||
* After receiving and successfully decrypting the message, its tested, if Bob
|
||||
* publishes a new Bundle. After that Bob replies to the message and its tested,
|
||||
* whether Alice can decrypt the message and if she does NOT publish a new Bundle.
|
||||
*
|
||||
* @throws CorruptedOmemoKeyException
|
||||
* @throws InterruptedException
|
||||
* @throws SmackException.NoResponseException
|
||||
* @throws SmackException.NotConnectedException
|
||||
* @throws XMPPException.XMPPErrorException
|
||||
* @throws SmackException.NotLoggedInException
|
||||
* @throws PubSubException.NotALeafNodeException
|
||||
* @throws CannotEstablishOmemoSessionException
|
||||
* @throws UndecidedOmemoIdentityException
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws CryptoFailedException
|
||||
*/
|
||||
@SmackIntegrationTest
|
||||
public void messageSendingTest() throws CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException, SmackException.NotConnectedException, XMPPException.XMPPErrorException, SmackException.NotLoggedInException, PubSubException.NotALeafNodeException, CannotEstablishOmemoSessionException, UndecidedOmemoIdentityException, NoSuchAlgorithmException, CryptoFailedException {
|
||||
final String alicesSecret = "Hey Bob! I love you!";
|
||||
final String bobsSecret = "I love you too, Alice."; //aww <3
|
||||
|
||||
final SimpleResultSyncPoint messageOneSyncPoint = new SimpleResultSyncPoint();
|
||||
final SimpleResultSyncPoint messageTwoSyncPoint = new SimpleResultSyncPoint();
|
||||
|
||||
//Subscribe to one another
|
||||
subscribe(alice, bob, "Bob");
|
||||
subscribe(bob, alice,"Alice");
|
||||
|
||||
//initialize OmemoManagers
|
||||
setUpOmemoManager(alice);
|
||||
setUpOmemoManager(bob);
|
||||
|
||||
//Save initial bundles
|
||||
OmemoBundleElement aliceBundle = store.packOmemoBundle(alice);
|
||||
OmemoBundleElement bobsBundle = store.packOmemoBundle(bob);
|
||||
|
||||
//Trust
|
||||
unidirectionalTrust(alice, bob);
|
||||
unidirectionalTrust(bob, alice);
|
||||
|
||||
//Register messageListeners
|
||||
bob.addOmemoMessageListener(new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
LOGGER.log(Level.INFO,"Bob received message: " + decryptedBody);
|
||||
if (decryptedBody.trim().equals(alicesSecret.trim())) {
|
||||
messageOneSyncPoint.signal();
|
||||
} else {
|
||||
messageOneSyncPoint.signal(new Exception("Received message must equal sent message."));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
}
|
||||
});
|
||||
|
||||
alice.addOmemoMessageListener(new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
LOGGER.log(Level.INFO, "Alice received message: " + decryptedBody);
|
||||
if (decryptedBody.trim().equals(bobsSecret.trim())) {
|
||||
messageTwoSyncPoint.signal();
|
||||
} else {
|
||||
messageTwoSyncPoint.signal(new Exception("Received message must equal sent message."));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//Prepare Alice message for Bob
|
||||
Message encryptedA = alice.encrypt(bob.getOwnJid(), alicesSecret);
|
||||
ChatManager.getInstanceFor(alice.getConnection()).chatWith(bob.getOwnJid().asEntityBareJidIfPossible())
|
||||
.send(encryptedA);
|
||||
|
||||
try {
|
||||
messageOneSyncPoint.waitForResult(10 * 1000);
|
||||
} catch (Exception e) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while waiting for message: " + e, e);
|
||||
TestCase.fail("Bob must have received Alice message.");
|
||||
}
|
||||
|
||||
//Check if Bob published a new Bundle
|
||||
assertNotSame("Bob must have published another bundle at this point, since we used a PreKeyMessage.",
|
||||
bobsBundle, OmemoService.fetchBundle(alice, bob.getOwnDevice()));
|
||||
|
||||
//Prepare Bobs response
|
||||
Message encryptedB = bob.encrypt(alice.getOwnJid(), bobsSecret);
|
||||
ChatManager.getInstanceFor(bob.getConnection()).chatWith(alice.getOwnJid().asEntityBareJidIfPossible())
|
||||
.send(encryptedB);
|
||||
|
||||
try {
|
||||
messageTwoSyncPoint.waitForResult(10 * 1000);
|
||||
} catch (Exception e) {
|
||||
LOGGER.log(Level.SEVERE, "Exception while waiting for response: " + e, e);
|
||||
TestCase.fail("Alice must have received a response from Bob.");
|
||||
}
|
||||
|
||||
assertEquals("Alice must not have published a new bundle, since we built the session using Bobs bundle.",
|
||||
aliceBundle, OmemoService.fetchBundle(bob, alice.getOwnDevice()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void after() {
|
||||
alice.shutdown();
|
||||
bob.shutdown();
|
||||
cleanServerSideTraces(alice);
|
||||
cleanServerSideTraces(bob);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus, 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.smackx.omemo;
|
||||
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||
import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.chat2.ChatManager;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.omemo.internal.CipherAndAuthTag;
|
||||
import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation;
|
||||
import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.fail;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.cleanServerSideTraces;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.setUpOmemoManager;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.subscribe;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.unidirectionalTrust;
|
||||
|
||||
/**
|
||||
* Test session renegotiation.
|
||||
*/
|
||||
public class OmemoSessionRenegotiationTest extends AbstractOmemoIntegrationTest {
|
||||
|
||||
private OmemoManager alice, bob;
|
||||
private OmemoStore<?,?,?,?,?,?,?,?,?> store;
|
||||
|
||||
public OmemoSessionRenegotiationTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, TestNotPossibleException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void before() {
|
||||
alice = OmemoManager.getInstanceFor(conOne, 1337);
|
||||
bob = OmemoManager.getInstanceFor(conTwo, 1009);
|
||||
store = OmemoService.getInstance().getOmemoStoreBackend();
|
||||
}
|
||||
|
||||
@SmackIntegrationTest
|
||||
public void sessionRenegotiationTest() throws Exception {
|
||||
|
||||
final boolean[] phaseTwo = new boolean[1];
|
||||
final SimpleResultSyncPoint sp1 = new SimpleResultSyncPoint();
|
||||
final SimpleResultSyncPoint sp2 = new SimpleResultSyncPoint();
|
||||
final SimpleResultSyncPoint sp3 = new SimpleResultSyncPoint();
|
||||
final SimpleResultSyncPoint sp4 = new SimpleResultSyncPoint();
|
||||
|
||||
final String m1 = "1: Alice says hello to bob.";
|
||||
final String m2 = "2: Bob replies to Alice.";
|
||||
final String m3 = "3. This message will arrive but Bob cannot decrypt it.";
|
||||
final String m4 = "4. This message is readable by Bob again.";
|
||||
|
||||
subscribe(alice, bob, "Bob");
|
||||
subscribe(bob, alice, "Alice");
|
||||
|
||||
setUpOmemoManager(alice);
|
||||
setUpOmemoManager(bob);
|
||||
|
||||
unidirectionalTrust(alice, bob);
|
||||
unidirectionalTrust(bob, alice);
|
||||
|
||||
OmemoMessageListener first = new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
LOGGER.log(Level.INFO, "Bob received OMEMO message: " + decryptedBody);
|
||||
assertEquals("Received message MUST match the one we sent.", decryptedBody, m1);
|
||||
sp1.signal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
|
||||
}
|
||||
};
|
||||
bob.addOmemoMessageListener(first);
|
||||
|
||||
ChatManager.getInstanceFor(alice.getConnection()).chatWith(bob.getOwnJid().asEntityBareJidIfPossible())
|
||||
.send(alice.encrypt(bob.getOwnJid(), m1));
|
||||
|
||||
sp1.waitForResult(10 * 1000);
|
||||
|
||||
bob.removeOmemoMessageListener(first);
|
||||
|
||||
OmemoMessageListener second = new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
LOGGER.log(Level.INFO, "Alice received OMEMO message: " + decryptedBody);
|
||||
assertEquals("Reply must match the messagewe sent.", decryptedBody, m2);
|
||||
sp2.signal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
|
||||
}
|
||||
};
|
||||
alice.addOmemoMessageListener(second);
|
||||
|
||||
ChatManager.getInstanceFor(bob.getConnection()).chatWith(alice.getOwnJid().asEntityBareJidIfPossible())
|
||||
.send(bob.encrypt(alice.getOwnJid(), m2));
|
||||
|
||||
sp2.waitForResult(10 * 1000);
|
||||
|
||||
alice.removeOmemoMessageListener(second);
|
||||
|
||||
store.forgetOmemoSessions(bob);
|
||||
store.removeAllRawSessionsOf(bob, alice.getOwnJid());
|
||||
|
||||
OmemoMessageListener third = new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
fail("Bob should not have received a decipherable message: " + decryptedBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
|
||||
}
|
||||
};
|
||||
bob.addOmemoMessageListener(third);
|
||||
|
||||
OmemoMessageListener fourth = new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
LOGGER.log(Level.INFO, "Alice received preKeyMessage.");
|
||||
sp3.signal();
|
||||
}
|
||||
};
|
||||
alice.addOmemoMessageListener(fourth);
|
||||
|
||||
ChatManager.getInstanceFor(alice.getConnection()).chatWith(bob.getOwnJid().asEntityBareJidIfPossible())
|
||||
.send(alice.encrypt(bob.getOwnJid(), m3));
|
||||
|
||||
sp3.waitForResult(10 * 1000);
|
||||
|
||||
bob.removeOmemoMessageListener(third);
|
||||
alice.removeOmemoMessageListener(fourth);
|
||||
|
||||
OmemoMessageListener fifth = new OmemoMessageListener() {
|
||||
@Override
|
||||
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
LOGGER.log(Level.INFO, "Bob received an OMEMO message: " + decryptedBody);
|
||||
assertEquals("The received message must match the one we sent.",
|
||||
decryptedBody, m4);
|
||||
sp4.signal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||
|
||||
}
|
||||
};
|
||||
bob.addOmemoMessageListener(fifth);
|
||||
|
||||
ChatManager.getInstanceFor(alice.getConnection()).chatWith(bob.getOwnJid().asEntityBareJidIfPossible())
|
||||
.send(alice.encrypt(bob.getOwnJid(), m4));
|
||||
|
||||
sp4.waitForResult(10 * 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void after() {
|
||||
alice.shutdown();
|
||||
bob.shutdown();
|
||||
cleanServerSideTraces(alice);
|
||||
cleanServerSideTraces(bob);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus, 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.smackx.omemo;
|
||||
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertFalse;
|
||||
import static junit.framework.TestCase.assertNotNull;
|
||||
import static junit.framework.TestCase.assertNotSame;
|
||||
import static junit.framework.TestCase.assertNull;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.deletePath;
|
||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.setUpOmemoManager;
|
||||
|
||||
/**
|
||||
* Test the OmemoStore.
|
||||
*/
|
||||
public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
|
||||
|
||||
private OmemoManager alice;
|
||||
private OmemoManager bob;
|
||||
|
||||
public OmemoStoreTest(SmackIntegrationTestEnvironment environment) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, TestNotPossibleException {
|
||||
super(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void before() {
|
||||
alice = OmemoManager.getInstanceFor(conOne);
|
||||
bob = OmemoManager.getInstanceFor(conOne);
|
||||
}
|
||||
|
||||
@SmackIntegrationTest
|
||||
public void storeTest() throws Exception {
|
||||
|
||||
//########### PRE-INITIALIZATION ############
|
||||
|
||||
assertEquals("Creating an OmemoManager without MUST have set the default deviceId.", alice.getDeviceId(), OmemoService.getInstance().getOmemoStoreBackend().getDefaultDeviceId(alice.getOwnJid()));
|
||||
assertEquals("OmemoManager must be equal, since both got created without giving a deviceId.", alice, bob);
|
||||
OmemoService.getInstance().getOmemoStoreBackend().setDefaultDeviceId(alice.getOwnJid(), -1); //Reset default deviceId
|
||||
|
||||
alice.shutdown();
|
||||
|
||||
alice = OmemoManager.getInstanceFor(conOne);
|
||||
assertNotSame("Instantiating OmemoManager without deviceId MUST assign random deviceId.", alice.getDeviceId(), bob.getDeviceId());
|
||||
|
||||
OmemoStore<?,?,?,?,?,?,?,?,?> store = OmemoService.getInstance().getOmemoStoreBackend();
|
||||
OmemoFingerprint finger = new OmemoFingerprint("FINGER");
|
||||
//DefaultDeviceId
|
||||
store.setDefaultDeviceId(alice.getOwnJid(), 777);
|
||||
assertEquals("defaultDeviceId setting/getting must equal.", 777, store.getDefaultDeviceId(alice.getOwnJid()));
|
||||
|
||||
//Trust/Distrust/Decide
|
||||
bob.shutdown();
|
||||
bob = OmemoManager.getInstanceFor(conTwo, 998);
|
||||
assertFalse("Bobs device MUST be undecided at this point",
|
||||
store.isDecidedOmemoIdentity(alice, bob.getOwnDevice(), finger));
|
||||
assertFalse("Bobs device MUST not be trusted at this point",
|
||||
store.isTrustedOmemoIdentity(alice, bob.getOwnDevice(), finger));
|
||||
store.trustOmemoIdentity(alice, bob.getOwnDevice(), finger);
|
||||
assertTrue("Bobs device MUST be trusted at this point.",
|
||||
store.isTrustedOmemoIdentity(alice, bob.getOwnDevice(), finger));
|
||||
assertTrue("Bobs device MUST be decided at this point.",
|
||||
store.isDecidedOmemoIdentity(alice, bob.getOwnDevice(), finger));
|
||||
store.distrustOmemoIdentity(alice, bob.getOwnDevice(), finger);
|
||||
assertFalse("Bobs device MUST be untrusted at this point.",
|
||||
store.isTrustedOmemoIdentity(alice, bob.getOwnDevice(), finger));
|
||||
|
||||
//Dates
|
||||
assertNull("Date of last received message must be null when no message was received ever.",
|
||||
store.getDateOfLastReceivedMessage(alice, bob.getOwnDevice()));
|
||||
Date now = new Date();
|
||||
store.setDateOfLastReceivedMessage(alice, bob.getOwnDevice(), now);
|
||||
assertEquals("Date of last reveived message must match the one we set.",
|
||||
now, store.getDateOfLastReceivedMessage(alice, bob.getOwnDevice()));
|
||||
assertNull("Date of last signed prekey renewal must be null.",
|
||||
store.getDateOfLastSignedPreKeyRenewal(alice));
|
||||
store.setDateOfLastSignedPreKeyRenewal(alice, now);
|
||||
assertEquals("Date of last signed prekey renewal must match our date.",
|
||||
now, store.getDateOfLastSignedPreKeyRenewal(alice));
|
||||
|
||||
//Keys
|
||||
assertNull("IdentityKeyPair must be null at this point.",
|
||||
store.loadOmemoIdentityKeyPair(alice));
|
||||
assertNull("IdentityKey of contact must be null at this point.",
|
||||
store.loadOmemoIdentityKey(alice, bob.getOwnDevice()));
|
||||
assertEquals("PreKeys list must be of length 0 at this point.",
|
||||
0, store.loadOmemoPreKeys(alice).size());
|
||||
assertEquals("SignedPreKeys list must be of length 0 at this point.",
|
||||
0, store.loadOmemoSignedPreKeys(alice).size());
|
||||
|
||||
assertNotNull("Generated IdentityKeyPair must not be null.",
|
||||
store.generateOmemoIdentityKeyPair());
|
||||
assertEquals("Generated PreKey list must be of correct length.",
|
||||
100, store.generateOmemoPreKeys(1, 100).size());
|
||||
|
||||
|
||||
//LastPreKeyId
|
||||
assertEquals("LastPreKeyId must be 0 at this point.",
|
||||
0, store.loadLastPreKeyId(alice));
|
||||
store.storeLastPreKeyId(alice, 1234);
|
||||
Thread.sleep(100);
|
||||
assertEquals("LastPreKeyId set/get must equal.", 1234, store.loadLastPreKeyId(alice));
|
||||
store.storeLastPreKeyId(alice, 0);
|
||||
|
||||
//CurrentSignedPreKeyId
|
||||
assertEquals("CurrentSignedPreKeyId must be 0 at this point.",
|
||||
0, store.loadCurrentSignedPreKeyId(alice));
|
||||
store.storeCurrentSignedPreKeyId(alice, 554);
|
||||
Thread.sleep(100);
|
||||
assertEquals("CurrentSignedPreKeyId must match the value we set.",
|
||||
554, store.loadCurrentSignedPreKeyId(alice));
|
||||
store.storeCurrentSignedPreKeyId(alice, 0);
|
||||
|
||||
deletePath(alice);
|
||||
|
||||
//################# POST-INITIALIZATION #################
|
||||
setUpOmemoManager(alice);
|
||||
|
||||
//Keys
|
||||
assertNotNull("IdentityKeyPair must not be null after initialization",
|
||||
store.loadOmemoIdentityKeyPair(alice));
|
||||
assertNotSame("LastPreKeyId must not be 0 after initialization.",
|
||||
0, store.loadLastPreKeyId(alice));
|
||||
assertNotSame("currentSignedPreKeyId must not be 0 after initialization.",
|
||||
0, store.loadCurrentSignedPreKeyId(alice));
|
||||
assertNotNull("The last PreKey must not be null.",
|
||||
store.loadOmemoPreKey(alice, store.loadLastPreKeyId(alice) - 1));
|
||||
assertNotNull("The current signedPreKey must not be null.",
|
||||
store.loadOmemoSignedPreKey(alice, store.loadCurrentSignedPreKeyId(alice)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void after() {
|
||||
alice.shutdown();
|
||||
bob.shutdown();
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
../../../../../../../../smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/package-info.java
|
Loading…
Add table
Add a link
Reference in a new issue