mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
Add SessionRenegotiationIntegrationTest
This commit is contained in:
parent
36dae1ece4
commit
53b70da90e
1 changed files with 163 additions and 0 deletions
|
@ -0,0 +1,163 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.smackx.omemo;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
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 org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||||
|
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||||
|
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||||
|
import org.igniterealtime.smack.inttest.util.ResultSyncPoint;
|
||||||
|
import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint;
|
||||||
|
|
||||||
|
public class SessionRenegotiationIntegrationTest extends AbstractTwoUsersOmemoIntegrationTest {
|
||||||
|
|
||||||
|
public SessionRenegotiationIntegrationTest(SmackIntegrationTestEnvironment environment)
|
||||||
|
throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException,
|
||||||
|
SmackException.NoResponseException, TestNotPossibleException {
|
||||||
|
super(environment);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String m1 = "P = NP is true for all N,P from the set of complex numbers, where P is equal to 0";
|
||||||
|
private final SimpleResultSyncPoint bsp1 = new SimpleResultSyncPoint();
|
||||||
|
private final OmemoMessageListener bml1 = new OmemoTestMessageListener(m1, bsp1);
|
||||||
|
|
||||||
|
private static final String m2 = "P = NP is also true for all N,P from the set of complex numbers, where N is equal to 1.";
|
||||||
|
private final ResultSyncPoint<Boolean, IllegalStateException> bsp2 = new ResultSyncPoint<>();
|
||||||
|
private final OmemoMessageListener bml2 = new OmemoMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||||
|
if (decryptedBody.equals(m2)) {
|
||||||
|
bsp2.signal(new IllegalStateException("Message MUST NOT be decryptable!"));
|
||||||
|
} else {
|
||||||
|
bsp2.signal(new IllegalStateException("OmemoMessageListener MUST NOT be called for this message."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private final SimpleResultSyncPoint asp2 = new SimpleResultSyncPoint();
|
||||||
|
private final OmemoMessageListener aml2 = 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) {
|
||||||
|
asp2.signal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String m3 = "P = NP would be a disaster for the world of cryptography.";
|
||||||
|
private final SimpleResultSyncPoint bsp3 = new SimpleResultSyncPoint();
|
||||||
|
private final OmemoMessageListener bml3 = new OmemoTestMessageListener(m3, bsp3);
|
||||||
|
|
||||||
|
@SmackIntegrationTest
|
||||||
|
public void sessionRenegotiationTest() throws Exception {
|
||||||
|
/*
|
||||||
|
Send (PreKey-)message from Alice to Bob to initiate a session.
|
||||||
|
*/
|
||||||
|
Message e1 = alice.encrypt(bob.getOwnJid(), m1);
|
||||||
|
e1.setTo(bob.getOwnJid());
|
||||||
|
|
||||||
|
bob.addOmemoMessageListener(bml1);
|
||||||
|
alice.getConnection().sendStanza(e1);
|
||||||
|
bsp1.waitForResult(10 * 1000);
|
||||||
|
bob.removeOmemoMessageListener(bml1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete the session records on Bobs side to render the session invalid.
|
||||||
|
*/
|
||||||
|
bob.getOmemoService().getOmemoStoreBackend().removeRawSession(bob.getOwnDevice(), alice.getOwnDevice());
|
||||||
|
|
||||||
|
/*
|
||||||
|
Send normal message from Alice to Bob (Alice assumes, that Bob still has a valid session).
|
||||||
|
*/
|
||||||
|
Message e2 = alice.encrypt(bob.getOwnJid(), m2);
|
||||||
|
e2.setTo(bob.getOwnJid());
|
||||||
|
|
||||||
|
bob.addOmemoMessageListener(bml2);
|
||||||
|
alice.addOmemoMessageListener(aml2);
|
||||||
|
alice.getConnection().sendStanza(e2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Wait for the timeout on Bobs side, since message decryption will fail now.
|
||||||
|
Bob will respond with an empty PreKeyMessage though, in order to repair the session.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
bsp2.waitForResult(10 * 1000);
|
||||||
|
fail("This MUST throw a TimeoutException.");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
// Expected.
|
||||||
|
}
|
||||||
|
asp2.waitForResult(10 * 1000);
|
||||||
|
bob.removeOmemoMessageListener(bml2);
|
||||||
|
alice.removeOmemoMessageListener(aml2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Since Bob responded with a PreKeyMessage to repair the broken session, Alice should now be able to send messages
|
||||||
|
which Bob can decrypt successfully again.
|
||||||
|
*/
|
||||||
|
Message e3 = alice.encrypt(bob.getOwnJid(), m3);
|
||||||
|
e3.setTo(bob.getOwnJid());
|
||||||
|
|
||||||
|
bob.addOmemoMessageListener(bml3);
|
||||||
|
alice.getConnection().sendStanza(e3);
|
||||||
|
bsp3.waitForResult(10 * 1000);
|
||||||
|
bob.removeOmemoMessageListener(bml3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class OmemoTestMessageListener implements OmemoMessageListener {
|
||||||
|
|
||||||
|
private final String expectedMessage;
|
||||||
|
private final SimpleResultSyncPoint syncPoint;
|
||||||
|
|
||||||
|
OmemoTestMessageListener(String expectedMessage, SimpleResultSyncPoint syncPoint) {
|
||||||
|
this.expectedMessage = expectedMessage;
|
||||||
|
this.syncPoint = syncPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOmemoMessageReceived(String decryptedBody, Message encryptedMessage, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||||
|
if (decryptedBody.equals(expectedMessage)) {
|
||||||
|
syncPoint.signal();
|
||||||
|
} else {
|
||||||
|
syncPoint.signalFailure("Received decrypted message was not equal to sent message.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOmemoKeyTransportReceived(CipherAndAuthTag cipherAndAuthTag, Message message, Message wrappingMessage, OmemoMessageInformation omemoInformation) {
|
||||||
|
// Ignored.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue