2014-04-23 17:12:47 -07:00
|
|
|
package org.whispersystems.test;
|
|
|
|
|
|
|
|
import android.test.AndroidTestCase;
|
|
|
|
|
|
|
|
import org.whispersystems.libaxolotl.DuplicateMessageException;
|
2014-09-03 02:51:20 -07:00
|
|
|
import org.whispersystems.libaxolotl.IdentityKey;
|
2014-04-23 17:12:47 -07:00
|
|
|
import org.whispersystems.libaxolotl.InvalidKeyException;
|
|
|
|
import org.whispersystems.libaxolotl.InvalidKeyIdException;
|
|
|
|
import org.whispersystems.libaxolotl.InvalidMessageException;
|
|
|
|
import org.whispersystems.libaxolotl.InvalidVersionException;
|
|
|
|
import org.whispersystems.libaxolotl.LegacyMessageException;
|
2014-07-22 17:47:35 -07:00
|
|
|
import org.whispersystems.libaxolotl.NoSessionException;
|
2014-04-23 17:12:47 -07:00
|
|
|
import org.whispersystems.libaxolotl.SessionBuilder;
|
|
|
|
import org.whispersystems.libaxolotl.SessionCipher;
|
2014-04-28 11:46:37 -07:00
|
|
|
import org.whispersystems.libaxolotl.StaleKeyExchangeException;
|
|
|
|
import org.whispersystems.libaxolotl.UntrustedIdentityException;
|
2014-04-23 17:12:47 -07:00
|
|
|
import org.whispersystems.libaxolotl.ecc.Curve;
|
|
|
|
import org.whispersystems.libaxolotl.ecc.ECKeyPair;
|
|
|
|
import org.whispersystems.libaxolotl.protocol.CiphertextMessage;
|
|
|
|
import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage;
|
|
|
|
import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage;
|
2014-07-22 17:47:35 -07:00
|
|
|
import org.whispersystems.libaxolotl.protocol.WhisperMessage;
|
2014-09-07 15:08:15 -07:00
|
|
|
import org.whispersystems.libaxolotl.state.AxolotlStore;
|
2014-04-23 17:12:47 -07:00
|
|
|
import org.whispersystems.libaxolotl.state.IdentityKeyStore;
|
2014-07-05 12:47:01 -07:00
|
|
|
import org.whispersystems.libaxolotl.state.PreKeyBundle;
|
2014-04-23 17:12:47 -07:00
|
|
|
import org.whispersystems.libaxolotl.state.PreKeyRecord;
|
|
|
|
import org.whispersystems.libaxolotl.state.PreKeyStore;
|
|
|
|
import org.whispersystems.libaxolotl.state.SessionStore;
|
2014-08-04 11:36:02 -07:00
|
|
|
import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
|
|
|
|
import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
|
2014-04-23 17:12:47 -07:00
|
|
|
import org.whispersystems.libaxolotl.util.Pair;
|
|
|
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
public class SessionBuilderTest extends AndroidTestCase {
|
|
|
|
|
|
|
|
private static final long ALICE_RECIPIENT_ID = 5L;
|
|
|
|
private static final long BOB_RECIPIENT_ID = 2L;
|
|
|
|
|
2014-07-05 12:47:01 -07:00
|
|
|
public void testBasicPreKeyV2()
|
2014-07-22 17:47:35 -07:00
|
|
|
throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException, NoSessionException {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-07-11 10:35:41 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore bobStore = new InMemoryAxolotlStore();
|
2014-07-26 13:29:40 -07:00
|
|
|
ECKeyPair bobPreKeyPair = Curve.generateKeyPair();
|
2014-09-07 15:08:15 -07:00
|
|
|
PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
|
2014-07-11 10:35:41 -07:00
|
|
|
31337, bobPreKeyPair.getPublicKey(),
|
|
|
|
0, null, null,
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.getIdentityKeyPair().getPublicKey());
|
2014-04-23 17:12:47 -07:00
|
|
|
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(aliceStore.containsSession(BOB_RECIPIENT_ID, 1));
|
|
|
|
assertTrue(aliceStore.loadSession(BOB_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 2);
|
2014-04-23 17:12:47 -07:00
|
|
|
|
|
|
|
String originalMessage = "L'homme est condamné à être libre";
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-04-23 17:12:47 -07:00
|
|
|
CiphertextMessage outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
assertTrue(outgoingMessage.getType() == CiphertextMessage.PREKEY_TYPE);
|
|
|
|
|
|
|
|
PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessage.serialize());
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
|
2014-07-22 17:47:35 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] plaintext = bobSessionCipher.decrypt(incomingMessage);
|
2014-04-23 17:12:47 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(bobStore.containsSession(ALICE_RECIPIENT_ID, 1));
|
|
|
|
assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 2);
|
2014-04-23 17:12:47 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(plaintext)));
|
2014-04-28 11:46:37 -07:00
|
|
|
|
|
|
|
CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
assertTrue(bobOutgoingMessage.getType() == CiphertextMessage.WHISPER_TYPE);
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] alicePlaintext = aliceSessionCipher.decrypt((WhisperMessage)bobOutgoingMessage);
|
2014-04-28 11:46:37 -07:00
|
|
|
assertTrue(new String(alicePlaintext).equals(originalMessage));
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
runInteraction(aliceStore, bobStore);
|
2014-04-28 11:46:37 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
aliceStore = new InMemoryAxolotlStore();
|
|
|
|
aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-04-28 11:46:37 -07:00
|
|
|
|
2014-07-26 13:29:40 -07:00
|
|
|
bobPreKeyPair = Curve.generateKeyPair();
|
2014-09-07 15:08:15 -07:00
|
|
|
bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(),
|
2014-07-05 12:47:01 -07:00
|
|
|
1, 31338, bobPreKeyPair.getPublicKey(),
|
2014-09-07 15:08:15 -07:00
|
|
|
0, null, null, bobStore.getIdentityKeyPair().getPublicKey());
|
2014-04-28 11:46:37 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.storePreKey(31338, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
|
2014-04-28 11:46:37 -07:00
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
|
|
|
|
outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
try {
|
2014-07-22 17:47:35 -07:00
|
|
|
bobSessionCipher.decrypt(new PreKeyWhisperMessage(outgoingMessage.serialize()));
|
2014-04-28 11:46:37 -07:00
|
|
|
throw new AssertionError("shouldn't be trusted!");
|
|
|
|
} catch (UntrustedIdentityException uie) {
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.saveIdentity(ALICE_RECIPIENT_ID, new PreKeyWhisperMessage(outgoingMessage.serialize()).getIdentityKey());
|
2014-04-28 11:46:37 -07:00
|
|
|
}
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
plaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(outgoingMessage.serialize()));
|
|
|
|
|
2014-04-28 11:46:37 -07:00
|
|
|
assertTrue(new String(plaintext).equals(originalMessage));
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
|
2014-07-26 13:29:40 -07:00
|
|
|
31337, Curve.generateKeyPair().getPublicKey(),
|
2014-07-05 12:47:01 -07:00
|
|
|
0, null, null,
|
2014-09-07 15:08:15 -07:00
|
|
|
aliceStore.getIdentityKeyPair().getPublicKey());
|
2014-04-28 11:46:37 -07:00
|
|
|
|
|
|
|
try {
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
throw new AssertionError("shoulnd't be trusted!");
|
|
|
|
} catch (UntrustedIdentityException uie) {
|
|
|
|
// good
|
|
|
|
}
|
2014-04-23 17:12:47 -07:00
|
|
|
}
|
|
|
|
|
2014-07-05 12:47:01 -07:00
|
|
|
public void testBasicPreKeyV3()
|
2014-07-22 17:47:35 -07:00
|
|
|
throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException, NoSessionException {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore bobStore = new InMemoryAxolotlStore();
|
|
|
|
ECKeyPair bobPreKeyPair = Curve.generateKeyPair();
|
|
|
|
ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();
|
|
|
|
byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
|
|
|
|
bobSignedPreKeyPair.getPublicKey().serialize());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
|
2014-07-05 12:47:01 -07:00
|
|
|
31337, bobPreKeyPair.getPublicKey(),
|
2014-07-23 01:00:32 -07:00
|
|
|
22, bobSignedPreKeyPair.getPublicKey(),
|
|
|
|
bobSignedPreKeySignature,
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.getIdentityKeyPair().getPublicKey());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(aliceStore.containsSession(BOB_RECIPIENT_ID, 1));
|
|
|
|
assertTrue(aliceStore.loadSession(BOB_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
String originalMessage = "L'homme est condamné à être libre";
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-07-05 12:47:01 -07:00
|
|
|
CiphertextMessage outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
assertTrue(outgoingMessage.getType() == CiphertextMessage.PREKEY_TYPE);
|
|
|
|
|
|
|
|
PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessage.serialize());
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
|
|
|
|
bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
|
2014-07-22 17:47:35 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] plaintext = bobSessionCipher.decrypt(incomingMessage);
|
|
|
|
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(bobStore.containsSession(ALICE_RECIPIENT_ID, 1));
|
|
|
|
assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3);
|
|
|
|
assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getAliceBaseKey() != null);
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(plaintext)));
|
|
|
|
|
|
|
|
CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
assertTrue(bobOutgoingMessage.getType() == CiphertextMessage.WHISPER_TYPE);
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] alicePlaintext = aliceSessionCipher.decrypt(new WhisperMessage(bobOutgoingMessage.serialize()));
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(new String(alicePlaintext).equals(originalMessage));
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
runInteraction(aliceStore, bobStore);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
aliceStore = new InMemoryAxolotlStore();
|
|
|
|
aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-07-26 13:29:40 -07:00
|
|
|
bobPreKeyPair = Curve.generateKeyPair();
|
|
|
|
bobSignedPreKeyPair = Curve.generateKeyPair();
|
2014-09-07 15:08:15 -07:00
|
|
|
bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(), bobSignedPreKeyPair.getPublicKey().serialize());
|
|
|
|
bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(),
|
2014-07-05 12:47:01 -07:00
|
|
|
1, 31338, bobPreKeyPair.getPublicKey(),
|
2014-07-11 10:35:41 -07:00
|
|
|
23, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.getIdentityKeyPair().getPublicKey());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.storePreKey(31338, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
|
|
|
|
bobStore.storeSignedPreKey(23, new SignedPreKeyRecord(23, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
|
2014-07-05 12:47:01 -07:00
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
|
|
|
|
outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
try {
|
2014-07-22 17:47:35 -07:00
|
|
|
plaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(outgoingMessage.serialize()));
|
2014-07-05 12:47:01 -07:00
|
|
|
throw new AssertionError("shouldn't be trusted!");
|
|
|
|
} catch (UntrustedIdentityException uie) {
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.saveIdentity(ALICE_RECIPIENT_ID, new PreKeyWhisperMessage(outgoingMessage.serialize()).getIdentityKey());
|
2014-07-05 12:47:01 -07:00
|
|
|
}
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
plaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(outgoingMessage.serialize()));
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(new String(plaintext).equals(originalMessage));
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
|
2014-07-26 13:29:40 -07:00
|
|
|
31337, Curve.generateKeyPair().getPublicKey(),
|
2014-07-11 10:35:41 -07:00
|
|
|
23, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
|
2014-09-07 15:08:15 -07:00
|
|
|
aliceStore.getIdentityKeyPair().getPublicKey());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
try {
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
throw new AssertionError("shoulnd't be trusted!");
|
|
|
|
} catch (UntrustedIdentityException uie) {
|
|
|
|
// good
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 10:35:41 -07:00
|
|
|
public void testBadSignedPreKeySignature() throws InvalidKeyException, UntrustedIdentityException {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
|
|
|
|
|
2014-07-26 13:29:40 -07:00
|
|
|
ECKeyPair bobPreKeyPair = Curve.generateKeyPair();
|
|
|
|
ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();
|
2014-07-11 10:35:41 -07:00
|
|
|
byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(),
|
|
|
|
bobSignedPreKeyPair.getPublicKey().serialize());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
|
2014-07-11 10:35:41 -07:00
|
|
|
for (int i=0;i<bobSignedPreKeySignature.length * 8;i++) {
|
|
|
|
byte[] modifiedSignature = new byte[bobSignedPreKeySignature.length];
|
|
|
|
System.arraycopy(bobSignedPreKeySignature, 0, modifiedSignature, 0, modifiedSignature.length);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
modifiedSignature[i/8] ^= (0x01 << (i % 8));
|
|
|
|
|
|
|
|
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
|
|
|
|
31337, bobPreKeyPair.getPublicKey(),
|
2014-07-11 10:35:41 -07:00
|
|
|
22, bobSignedPreKeyPair.getPublicKey(), modifiedSignature,
|
2014-07-05 12:47:01 -07:00
|
|
|
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
|
|
|
|
|
|
|
|
try {
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
throw new AssertionError("Accepted modified device key signature!");
|
|
|
|
} catch (InvalidKeyException ike) {
|
|
|
|
// good
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
|
|
|
|
31337, bobPreKeyPair.getPublicKey(),
|
2014-07-11 10:35:41 -07:00
|
|
|
22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
|
2014-07-05 12:47:01 -07:00
|
|
|
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
|
|
|
|
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
}
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
public void testRepeatBundleMessageV2() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, NoSessionException {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
|
|
|
|
AxolotlStore bobStore = new InMemoryAxolotlStore();
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-07-26 13:29:40 -07:00
|
|
|
ECKeyPair bobPreKeyPair = Curve.generateKeyPair();
|
|
|
|
ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();
|
2014-09-07 15:08:15 -07:00
|
|
|
byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
|
2014-07-11 10:35:41 -07:00
|
|
|
bobSignedPreKeyPair.getPublicKey().serialize());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
|
2014-07-05 12:47:01 -07:00
|
|
|
31337, bobPreKeyPair.getPublicKey(),
|
|
|
|
0, null, null,
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.getIdentityKeyPair().getPublicKey());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
|
|
|
|
bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
|
|
|
|
String originalMessage = "L'homme est condamné à être libre";
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-07-05 12:47:01 -07:00
|
|
|
CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
CiphertextMessage outgoingMessageTwo = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
assertTrue(outgoingMessageOne.getType() == CiphertextMessage.PREKEY_TYPE);
|
|
|
|
|
|
|
|
PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessageOne.serialize());
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] plaintext = bobSessionCipher.decrypt(incomingMessage);
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(plaintext)));
|
|
|
|
|
|
|
|
CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] alicePlaintext = aliceSessionCipher.decrypt(new WhisperMessage(bobOutgoingMessage.serialize()));
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(alicePlaintext)));
|
|
|
|
|
|
|
|
// The test
|
|
|
|
|
|
|
|
PreKeyWhisperMessage incomingMessageTwo = new PreKeyWhisperMessage(outgoingMessageTwo.serialize());
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
plaintext = bobSessionCipher.decrypt(incomingMessageTwo);
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(plaintext)));
|
|
|
|
|
|
|
|
bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes());
|
2014-07-22 17:47:35 -07:00
|
|
|
alicePlaintext = aliceSessionCipher.decrypt(new WhisperMessage(bobOutgoingMessage.serialize()));
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(alicePlaintext)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
public void testRepeatBundleMessageV3() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, NoSessionException {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
|
|
|
|
AxolotlStore bobStore = new InMemoryAxolotlStore();
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-07-26 13:29:40 -07:00
|
|
|
ECKeyPair bobPreKeyPair = Curve.generateKeyPair();
|
|
|
|
ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();
|
2014-09-07 15:08:15 -07:00
|
|
|
byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
|
2014-07-11 10:35:41 -07:00
|
|
|
bobSignedPreKeyPair.getPublicKey().serialize());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
|
2014-07-05 12:47:01 -07:00
|
|
|
31337, bobPreKeyPair.getPublicKey(),
|
2014-07-11 10:35:41 -07:00
|
|
|
22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.getIdentityKeyPair().getPublicKey());
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
|
|
|
|
bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
|
|
|
|
String originalMessage = "L'homme est condamné à être libre";
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-07-05 12:47:01 -07:00
|
|
|
CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
CiphertextMessage outgoingMessageTwo = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
assertTrue(outgoingMessageOne.getType() == CiphertextMessage.PREKEY_TYPE);
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(outgoingMessageTwo.getType() == CiphertextMessage.PREKEY_TYPE);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
|
|
|
PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessageOne.serialize());
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-07-05 12:47:01 -07:00
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] plaintext = bobSessionCipher.decrypt(incomingMessage);
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(plaintext)));
|
|
|
|
|
|
|
|
CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] alicePlaintext = aliceSessionCipher.decrypt(new WhisperMessage(bobOutgoingMessage.serialize()));
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(alicePlaintext)));
|
|
|
|
|
|
|
|
// The test
|
|
|
|
|
|
|
|
PreKeyWhisperMessage incomingMessageTwo = new PreKeyWhisperMessage(outgoingMessageTwo.serialize());
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
plaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(incomingMessageTwo.serialize()));
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(plaintext)));
|
|
|
|
|
|
|
|
bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes());
|
2014-07-22 17:47:35 -07:00
|
|
|
alicePlaintext = aliceSessionCipher.decrypt(new WhisperMessage(bobOutgoingMessage.serialize()));
|
2014-07-05 12:47:01 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(alicePlaintext)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-08-04 11:36:02 -07:00
|
|
|
public void testBadMessageBundle() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, DuplicateMessageException, LegacyMessageException, InvalidKeyIdException {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
|
|
|
|
AxolotlStore bobStore = new InMemoryAxolotlStore();
|
2014-08-04 11:36:02 -07:00
|
|
|
|
|
|
|
ECKeyPair bobPreKeyPair = Curve.generateKeyPair();
|
|
|
|
ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();
|
2014-09-07 15:08:15 -07:00
|
|
|
byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
|
2014-08-04 11:36:02 -07:00
|
|
|
bobSignedPreKeyPair.getPublicKey().serialize());
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
|
2014-08-04 11:36:02 -07:00
|
|
|
31337, bobPreKeyPair.getPublicKey(),
|
|
|
|
22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.getIdentityKeyPair().getPublicKey());
|
2014-08-04 11:36:02 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
|
|
|
|
bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
|
2014-08-04 11:36:02 -07:00
|
|
|
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
|
|
|
|
String originalMessage = "L'homme est condamné à être libre";
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-08-04 11:36:02 -07:00
|
|
|
CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
assertTrue(outgoingMessageOne.getType() == CiphertextMessage.PREKEY_TYPE);
|
|
|
|
|
|
|
|
byte[] goodMessage = outgoingMessageOne.serialize();
|
|
|
|
byte[] badMessage = new byte[goodMessage.length];
|
|
|
|
System.arraycopy(goodMessage, 0, badMessage, 0, badMessage.length);
|
|
|
|
|
|
|
|
badMessage[badMessage.length-10] ^= 0x01;
|
|
|
|
|
|
|
|
PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(badMessage);
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-08-04 11:36:02 -07:00
|
|
|
|
|
|
|
byte[] plaintext = new byte[0];
|
|
|
|
|
|
|
|
try {
|
|
|
|
plaintext = bobSessionCipher.decrypt(incomingMessage);
|
|
|
|
throw new AssertionError("Decrypt should have failed!");
|
|
|
|
} catch (InvalidMessageException e) {
|
|
|
|
// good.
|
|
|
|
}
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(bobStore.containsPreKey(31337));
|
2014-08-04 11:36:02 -07:00
|
|
|
|
|
|
|
plaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(goodMessage));
|
|
|
|
|
|
|
|
assertTrue(originalMessage.equals(new String(plaintext)));
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(!bobStore.containsPreKey(31337));
|
2014-08-04 11:36:02 -07:00
|
|
|
}
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
public void testBasicKeyExchange() throws InvalidKeyException, LegacyMessageException, InvalidMessageException, DuplicateMessageException, UntrustedIdentityException, StaleKeyExchangeException, InvalidVersionException, NoSessionException {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
|
|
|
|
AxolotlStore bobStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-04-23 17:12:47 -07:00
|
|
|
|
2014-07-08 19:54:07 -07:00
|
|
|
KeyExchangeMessage aliceKeyExchangeMessage = aliceSessionBuilder.process();
|
|
|
|
assertTrue(aliceKeyExchangeMessage != null);
|
|
|
|
|
|
|
|
byte[] aliceKeyExchangeMessageBytes = aliceKeyExchangeMessage.serialize();
|
|
|
|
KeyExchangeMessage bobKeyExchangeMessage = bobSessionBuilder.process(new KeyExchangeMessage(aliceKeyExchangeMessageBytes));
|
2014-04-23 17:12:47 -07:00
|
|
|
|
|
|
|
assertTrue(bobKeyExchangeMessage != null);
|
|
|
|
|
2014-07-08 19:54:07 -07:00
|
|
|
byte[] bobKeyExchangeMessageBytes = bobKeyExchangeMessage.serialize();
|
|
|
|
KeyExchangeMessage response = aliceSessionBuilder.process(new KeyExchangeMessage(bobKeyExchangeMessageBytes));
|
2014-04-23 17:12:47 -07:00
|
|
|
|
|
|
|
assertTrue(response == null);
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(aliceStore.containsSession(BOB_RECIPIENT_ID, 1));
|
|
|
|
assertTrue(bobStore.containsSession(ALICE_RECIPIENT_ID, 1));
|
2014-04-23 17:12:47 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
runInteraction(aliceStore, bobStore);
|
2014-04-28 11:46:37 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
aliceStore = new InMemoryAxolotlStore();
|
|
|
|
aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-04-28 11:46:37 -07:00
|
|
|
aliceKeyExchangeMessage = aliceSessionBuilder.process();
|
|
|
|
|
|
|
|
try {
|
|
|
|
bobKeyExchangeMessage = bobSessionBuilder.process(aliceKeyExchangeMessage);
|
|
|
|
throw new AssertionError("This identity shouldn't be trusted!");
|
|
|
|
} catch (UntrustedIdentityException uie) {
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.saveIdentity(ALICE_RECIPIENT_ID, aliceKeyExchangeMessage.getIdentityKey());
|
2014-04-28 11:46:37 -07:00
|
|
|
bobKeyExchangeMessage = bobSessionBuilder.process(aliceKeyExchangeMessage);
|
|
|
|
}
|
|
|
|
|
|
|
|
assertTrue(aliceSessionBuilder.process(bobKeyExchangeMessage) == null);
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
runInteraction(aliceStore, bobStore);
|
2014-04-23 17:12:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public void testSimultaneousKeyExchange()
|
2014-07-22 17:47:35 -07:00
|
|
|
throws InvalidKeyException, DuplicateMessageException, LegacyMessageException, InvalidMessageException, UntrustedIdentityException, StaleKeyExchangeException, NoSessionException {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
|
|
|
|
AxolotlStore bobStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-04-23 17:12:47 -07:00
|
|
|
|
|
|
|
KeyExchangeMessage aliceKeyExchange = aliceSessionBuilder.process();
|
|
|
|
KeyExchangeMessage bobKeyExchange = bobSessionBuilder.process();
|
|
|
|
|
|
|
|
assertTrue(aliceKeyExchange != null);
|
|
|
|
assertTrue(bobKeyExchange != null);
|
|
|
|
|
|
|
|
KeyExchangeMessage aliceResponse = aliceSessionBuilder.process(bobKeyExchange);
|
|
|
|
KeyExchangeMessage bobResponse = bobSessionBuilder.process(aliceKeyExchange);
|
|
|
|
|
|
|
|
assertTrue(aliceResponse != null);
|
|
|
|
assertTrue(bobResponse != null);
|
|
|
|
|
|
|
|
KeyExchangeMessage aliceAck = aliceSessionBuilder.process(bobResponse);
|
|
|
|
KeyExchangeMessage bobAck = bobSessionBuilder.process(aliceResponse);
|
|
|
|
|
|
|
|
assertTrue(aliceAck == null);
|
|
|
|
assertTrue(bobAck == null);
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
runInteraction(aliceStore, bobStore);
|
2014-04-23 17:12:47 -07:00
|
|
|
}
|
|
|
|
|
2014-09-03 02:51:20 -07:00
|
|
|
public void testOptionalOneTimePreKey() throws Exception {
|
2014-09-07 15:08:15 -07:00
|
|
|
AxolotlStore aliceStore = new InMemoryAxolotlStore();
|
|
|
|
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
|
|
|
|
AxolotlStore bobStore = new InMemoryAxolotlStore();
|
2014-09-03 02:51:20 -07:00
|
|
|
|
|
|
|
ECKeyPair bobPreKeyPair = Curve.generateKeyPair();
|
|
|
|
ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair();
|
2014-09-07 15:08:15 -07:00
|
|
|
byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
|
2014-09-03 02:51:20 -07:00
|
|
|
bobSignedPreKeyPair.getPublicKey().serialize());
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
|
2014-09-03 02:51:20 -07:00
|
|
|
0, null,
|
|
|
|
22, bobSignedPreKeyPair.getPublicKey(),
|
|
|
|
bobSignedPreKeySignature,
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.getIdentityKeyPair().getPublicKey());
|
2014-09-03 02:51:20 -07:00
|
|
|
|
|
|
|
aliceSessionBuilder.process(bobPreKey);
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(aliceStore.containsSession(BOB_RECIPIENT_ID, 1));
|
|
|
|
assertTrue(aliceStore.loadSession(BOB_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3);
|
2014-09-03 02:51:20 -07:00
|
|
|
|
|
|
|
String originalMessage = "L'homme est condamné à être libre";
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
2014-09-03 02:51:20 -07:00
|
|
|
CiphertextMessage outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
assertTrue(outgoingMessage.getType() == CiphertextMessage.PREKEY_TYPE);
|
|
|
|
|
|
|
|
PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessage.serialize());
|
|
|
|
assertTrue(!incomingMessage.getPreKeyId().isPresent());
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
|
|
|
|
bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
|
2014-09-03 02:51:20 -07:00
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-09-03 02:51:20 -07:00
|
|
|
byte[] plaintext = bobSessionCipher.decrypt(incomingMessage);
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
assertTrue(bobStore.containsSession(ALICE_RECIPIENT_ID, 1));
|
|
|
|
assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3);
|
|
|
|
assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getAliceBaseKey() != null);
|
2014-09-03 02:51:20 -07:00
|
|
|
assertTrue(originalMessage.equals(new String(plaintext)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-07 15:08:15 -07:00
|
|
|
private void runInteraction(AxolotlStore aliceStore, AxolotlStore bobStore)
|
2014-07-22 17:47:35 -07:00
|
|
|
throws DuplicateMessageException, LegacyMessageException, InvalidMessageException, NoSessionException
|
2014-04-23 17:12:47 -07:00
|
|
|
{
|
2014-09-07 15:08:15 -07:00
|
|
|
SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1);
|
|
|
|
SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1);
|
2014-04-23 17:12:47 -07:00
|
|
|
|
|
|
|
String originalMessage = "smert ze smert";
|
|
|
|
CiphertextMessage aliceMessage = aliceSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
assertTrue(aliceMessage.getType() == CiphertextMessage.WHISPER_TYPE);
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] plaintext = bobSessionCipher.decrypt(new WhisperMessage(aliceMessage.serialize()));
|
2014-04-23 17:12:47 -07:00
|
|
|
assertTrue(new String(plaintext).equals(originalMessage));
|
|
|
|
|
|
|
|
CiphertextMessage bobMessage = bobSessionCipher.encrypt(originalMessage.getBytes());
|
|
|
|
|
|
|
|
assertTrue(bobMessage.getType() == CiphertextMessage.WHISPER_TYPE);
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
plaintext = aliceSessionCipher.decrypt(new WhisperMessage(bobMessage.serialize()));
|
2014-04-23 17:12:47 -07:00
|
|
|
assertTrue(new String(plaintext).equals(originalMessage));
|
|
|
|
|
|
|
|
for (int i=0;i<10;i++) {
|
2014-04-24 12:28:38 -07:00
|
|
|
String loopingMessage = ("What do we mean by saying that existence precedes essence? " +
|
|
|
|
"We mean that man first of all exists, encounters himself, " +
|
|
|
|
"surges up in the world--and defines himself aftward. " + i);
|
2014-04-23 17:12:47 -07:00
|
|
|
CiphertextMessage aliceLoopingMessage = aliceSessionCipher.encrypt(loopingMessage.getBytes());
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] loopingPlaintext = bobSessionCipher.decrypt(new WhisperMessage(aliceLoopingMessage.serialize()));
|
2014-04-23 17:12:47 -07:00
|
|
|
assertTrue(new String(loopingPlaintext).equals(loopingMessage));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i=0;i<10;i++) {
|
2014-04-24 12:28:38 -07:00
|
|
|
String loopingMessage = ("What do we mean by saying that existence precedes essence? " +
|
|
|
|
"We mean that man first of all exists, encounters himself, " +
|
|
|
|
"surges up in the world--and defines himself aftward. " + i);
|
2014-04-23 17:12:47 -07:00
|
|
|
CiphertextMessage bobLoopingMessage = bobSessionCipher.encrypt(loopingMessage.getBytes());
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] loopingPlaintext = aliceSessionCipher.decrypt(new WhisperMessage(bobLoopingMessage.serialize()));
|
2014-04-23 17:12:47 -07:00
|
|
|
assertTrue(new String(loopingPlaintext).equals(loopingMessage));
|
|
|
|
}
|
|
|
|
|
|
|
|
Set<Pair<String, CiphertextMessage>> aliceOutOfOrderMessages = new HashSet<>();
|
|
|
|
|
|
|
|
for (int i=0;i<10;i++) {
|
2014-04-24 12:28:38 -07:00
|
|
|
String loopingMessage = ("What do we mean by saying that existence precedes essence? " +
|
|
|
|
"We mean that man first of all exists, encounters himself, " +
|
|
|
|
"surges up in the world--and defines himself aftward. " + i);
|
2014-04-23 17:12:47 -07:00
|
|
|
CiphertextMessage aliceLoopingMessage = aliceSessionCipher.encrypt(loopingMessage.getBytes());
|
|
|
|
|
|
|
|
aliceOutOfOrderMessages.add(new Pair<>(loopingMessage, aliceLoopingMessage));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i=0;i<10;i++) {
|
2014-04-24 12:28:38 -07:00
|
|
|
String loopingMessage = ("What do we mean by saying that existence precedes essence? " +
|
|
|
|
"We mean that man first of all exists, encounters himself, " +
|
|
|
|
"surges up in the world--and defines himself aftward. " + i);
|
2014-04-23 17:12:47 -07:00
|
|
|
CiphertextMessage aliceLoopingMessage = aliceSessionCipher.encrypt(loopingMessage.getBytes());
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] loopingPlaintext = bobSessionCipher.decrypt(new WhisperMessage(aliceLoopingMessage.serialize()));
|
2014-04-23 17:12:47 -07:00
|
|
|
assertTrue(new String(loopingPlaintext).equals(loopingMessage));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i=0;i<10;i++) {
|
|
|
|
String loopingMessage = ("You can only desire based on what you know: " + i);
|
|
|
|
CiphertextMessage bobLoopingMessage = bobSessionCipher.encrypt(loopingMessage.getBytes());
|
|
|
|
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] loopingPlaintext = aliceSessionCipher.decrypt(new WhisperMessage(bobLoopingMessage.serialize()));
|
2014-04-23 17:12:47 -07:00
|
|
|
assertTrue(new String(loopingPlaintext).equals(loopingMessage));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Pair<String, CiphertextMessage> aliceOutOfOrderMessage : aliceOutOfOrderMessages) {
|
2014-07-22 17:47:35 -07:00
|
|
|
byte[] outOfOrderPlaintext = bobSessionCipher.decrypt(new WhisperMessage(aliceOutOfOrderMessage.second().serialize()));
|
2014-04-23 17:12:47 -07:00
|
|
|
assertTrue(new String(outOfOrderPlaintext).equals(aliceOutOfOrderMessage.first()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|