diff --git a/java/src/main/java/org/whispersystems/libaxolotl/AxolotlAddress.java b/java/src/main/java/org/whispersystems/libaxolotl/AxolotlAddress.java new file mode 100644 index 000000000..9d0476c04 --- /dev/null +++ b/java/src/main/java/org/whispersystems/libaxolotl/AxolotlAddress.java @@ -0,0 +1,39 @@ +package org.whispersystems.libaxolotl; + +public class AxolotlAddress { + + private final String name; + private final int deviceId; + + public AxolotlAddress(String name, int deviceId) { + this.name = name; + this.deviceId = deviceId; + } + + public String getName() { + return name; + } + + public int getDeviceId() { + return deviceId; + } + + @Override + public String toString() { + return name + ":" + deviceId; + } + + @Override + public boolean equals(Object other) { + if (other == null) return false; + if (!(other instanceof AxolotlAddress)) return false; + + AxolotlAddress that = (AxolotlAddress)other; + return this.name.equals(that.name) && this.deviceId == that.deviceId; + } + + @Override + public int hashCode() { + return this.name.hashCode() ^ this.deviceId; + } +} diff --git a/java/src/main/java/org/whispersystems/libaxolotl/SessionBuilder.java b/java/src/main/java/org/whispersystems/libaxolotl/SessionBuilder.java index 736d9ab1f..826fcb448 100644 --- a/java/src/main/java/org/whispersystems/libaxolotl/SessionBuilder.java +++ b/java/src/main/java/org/whispersystems/libaxolotl/SessionBuilder.java @@ -49,8 +49,7 @@ public class SessionBuilder { private final PreKeyStore preKeyStore; private final SignedPreKeyStore signedPreKeyStore; private final IdentityKeyStore identityKeyStore; - private final long recipientId; - private final int deviceId; + private final AxolotlAddress remoteAddress; /** * Constructs a SessionBuilder. @@ -58,31 +57,28 @@ public class SessionBuilder { * @param sessionStore The {@link org.whispersystems.libaxolotl.state.SessionStore} to store the constructed session in. * @param preKeyStore The {@link org.whispersystems.libaxolotl.state.PreKeyStore} where the client's local {@link org.whispersystems.libaxolotl.state.PreKeyRecord}s are stored. * @param identityKeyStore The {@link org.whispersystems.libaxolotl.state.IdentityKeyStore} containing the client's identity key information. - * @param recipientId The recipient ID of the remote user to build a session with. - * @param deviceId The device ID of the remote user's physical device. + * @param remoteAddress The address of the remote user to build a session with. */ public SessionBuilder(SessionStore sessionStore, PreKeyStore preKeyStore, SignedPreKeyStore signedPreKeyStore, IdentityKeyStore identityKeyStore, - long recipientId, int deviceId) + AxolotlAddress remoteAddress) { this.sessionStore = sessionStore; this.preKeyStore = preKeyStore; this.signedPreKeyStore = signedPreKeyStore; this.identityKeyStore = identityKeyStore; - this.recipientId = recipientId; - this.deviceId = deviceId; + this.remoteAddress = remoteAddress; } /** * Constructs a SessionBuilder * @param store The {@link org.whispersystems.libaxolotl.state.AxolotlStore} to store all state information in. - * @param recipientId The recipient ID of the remote user to build a session with. - * @param deviceId The device ID of the remote user's physical device. + * @param remoteAddress The address of the remote user to build a session with. */ - public SessionBuilder(AxolotlStore store, long recipientId, int deviceId) { - this(store, store, store, store, recipientId, deviceId); + public SessionBuilder(AxolotlStore store, AxolotlAddress remoteAddress) { + this(store, store, store, store, remoteAddress); } /** @@ -107,7 +103,7 @@ public class SessionBuilder { Optional unsignedPreKeyId; - if (!identityKeyStore.isTrustedIdentity(recipientId, theirIdentityKey)) { + if (!identityKeyStore.isTrustedIdentity(remoteAddress.getName(), theirIdentityKey)) { throw new UntrustedIdentityException(); } @@ -117,7 +113,7 @@ public class SessionBuilder { default: throw new AssertionError("Unknown version: " + messageVersion); } - identityKeyStore.saveIdentity(recipientId, theirIdentityKey); + identityKeyStore.saveIdentity(remoteAddress.getName(), theirIdentityKey); return unsignedPreKeyId; } @@ -169,7 +165,7 @@ public class SessionBuilder { } if (!preKeyStore.containsPreKey(message.getPreKeyId().get()) && - sessionStore.containsSession(recipientId, deviceId)) + sessionStore.containsSession(remoteAddress)) { Log.w(TAG, "We've already processed the prekey part of this V2 session, letting bundled message fall through..."); return Optional.absent(); @@ -214,7 +210,7 @@ public class SessionBuilder { */ public void process(PreKeyBundle preKey) throws InvalidKeyException, UntrustedIdentityException { synchronized (SessionCipher.SESSION_LOCK) { - if (!identityKeyStore.isTrustedIdentity(recipientId, preKey.getIdentityKey())) { + if (!identityKeyStore.isTrustedIdentity(remoteAddress.getName(), preKey.getIdentityKey())) { throw new UntrustedIdentityException(); } @@ -231,7 +227,7 @@ public class SessionBuilder { } boolean supportsV3 = preKey.getSignedPreKey() != null; - SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId); + SessionRecord sessionRecord = sessionStore.loadSession(remoteAddress); ECKeyPair ourBaseKey = Curve.generateKeyPair(); ECPublicKey theirSignedPreKey = supportsV3 ? preKey.getSignedPreKey() : preKey.getPreKey(); Optional theirOneTimePreKey = Optional.fromNullable(preKey.getPreKey()); @@ -258,8 +254,8 @@ public class SessionBuilder { sessionRecord.getSessionState().setRemoteRegistrationId(preKey.getRegistrationId()); sessionRecord.getSessionState().setAliceBaseKey(ourBaseKey.getPublicKey().serialize()); - sessionStore.storeSession(recipientId, deviceId, sessionRecord); - identityKeyStore.saveIdentity(recipientId, preKey.getIdentityKey()); + sessionStore.storeSession(remoteAddress, sessionRecord); + identityKeyStore.saveIdentity(remoteAddress.getName(), preKey.getIdentityKey()); } } @@ -275,7 +271,7 @@ public class SessionBuilder { throws InvalidKeyException, UntrustedIdentityException, StaleKeyExchangeException { synchronized (SessionCipher.SESSION_LOCK) { - if (!identityKeyStore.isTrustedIdentity(recipientId, message.getIdentityKey())) { + if (!identityKeyStore.isTrustedIdentity(remoteAddress.getName(), message.getIdentityKey())) { throw new UntrustedIdentityException(); } @@ -290,7 +286,7 @@ public class SessionBuilder { private KeyExchangeMessage processInitiate(KeyExchangeMessage message) throws InvalidKeyException { int flags = KeyExchangeMessage.RESPONSE_FLAG; - SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId); + SessionRecord sessionRecord = sessionStore.loadSession(remoteAddress); if (message.getVersion() >= 3 && !Curve.verifySignature(message.getIdentityKey().getPublicKey(), @@ -325,8 +321,8 @@ public class SessionBuilder { Math.min(message.getMaxVersion(), CiphertextMessage.CURRENT_VERSION), parameters); - sessionStore.storeSession(recipientId, deviceId, sessionRecord); - identityKeyStore.saveIdentity(recipientId, message.getIdentityKey()); + sessionStore.storeSession(remoteAddress, sessionRecord); + identityKeyStore.saveIdentity(remoteAddress.getName(), message.getIdentityKey()); byte[] baseKeySignature = Curve.calculateSignature(parameters.getOurIdentityKey().getPrivateKey(), parameters.getOurBaseKey().getPublicKey().serialize()); @@ -341,7 +337,7 @@ public class SessionBuilder { private void processResponse(KeyExchangeMessage message) throws StaleKeyExchangeException, InvalidKeyException { - SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId); + SessionRecord sessionRecord = sessionStore.loadSession(remoteAddress); SessionState sessionState = sessionRecord.getSessionState(); boolean hasPendingKeyExchange = sessionState.hasPendingKeyExchange(); boolean isSimultaneousInitiateResponse = message.isResponseForSimultaneousInitiate(); @@ -375,8 +371,8 @@ public class SessionBuilder { throw new InvalidKeyException("Base key signature doesn't match!"); } - sessionStore.storeSession(recipientId, deviceId, sessionRecord); - identityKeyStore.saveIdentity(recipientId, message.getIdentityKey()); + sessionStore.storeSession(remoteAddress, sessionRecord); + identityKeyStore.saveIdentity(remoteAddress.getName(), message.getIdentityKey()); } @@ -394,10 +390,10 @@ public class SessionBuilder { ECKeyPair ratchetKey = Curve.generateKeyPair(); IdentityKeyPair identityKey = identityKeyStore.getIdentityKeyPair(); byte[] baseKeySignature = Curve.calculateSignature(identityKey.getPrivateKey(), baseKey.getPublicKey().serialize()); - SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId); + SessionRecord sessionRecord = sessionStore.loadSession(remoteAddress); sessionRecord.getSessionState().setPendingKeyExchange(sequence, baseKey, ratchetKey, identityKey); - sessionStore.storeSession(recipientId, deviceId, sessionRecord); + sessionStore.storeSession(remoteAddress, sessionRecord); return new KeyExchangeMessage(2, sequence, flags, baseKey.getPublicKey(), baseKeySignature, ratchetKey.getPublicKey(), identityKey.getPublicKey()); diff --git a/java/src/main/java/org/whispersystems/libaxolotl/SessionCipher.java b/java/src/main/java/org/whispersystems/libaxolotl/SessionCipher.java index 381dedb88..b9cc6ac1a 100644 --- a/java/src/main/java/org/whispersystems/libaxolotl/SessionCipher.java +++ b/java/src/main/java/org/whispersystems/libaxolotl/SessionCipher.java @@ -67,8 +67,7 @@ public class SessionCipher { private final SessionStore sessionStore; private final SessionBuilder sessionBuilder; private final PreKeyStore preKeyStore; - private final long recipientId; - private final int deviceId; + private final AxolotlAddress remoteAddress; /** * Construct a SessionCipher for encrypt/decrypt operations on a session. @@ -76,23 +75,21 @@ public class SessionCipher { * and stored using {@link SessionBuilder}. * * @param sessionStore The {@link SessionStore} that contains a session for this recipient. - * @param recipientId The remote ID that messages will be encrypted to or decrypted from. - * @param deviceId The device corresponding to the recipientId. + * @param remoteAddress The remote address that messages will be encrypted to or decrypted from. */ public SessionCipher(SessionStore sessionStore, PreKeyStore preKeyStore, SignedPreKeyStore signedPreKeyStore, IdentityKeyStore identityKeyStore, - long recipientId, int deviceId) + AxolotlAddress remoteAddress) { this.sessionStore = sessionStore; - this.recipientId = recipientId; - this.deviceId = deviceId; this.preKeyStore = preKeyStore; + this.remoteAddress = remoteAddress; this.sessionBuilder = new SessionBuilder(sessionStore, preKeyStore, signedPreKeyStore, - identityKeyStore, recipientId, deviceId); + identityKeyStore, remoteAddress); } - public SessionCipher(AxolotlStore store, long recipientId, int deviceId) { - this(store, store, store, store, recipientId, deviceId); + public SessionCipher(AxolotlStore store, AxolotlAddress remoteAddress) { + this(store, store, store, store, remoteAddress); } /** @@ -103,7 +100,7 @@ public class SessionCipher { */ public CiphertextMessage encrypt(byte[] paddedMessage) { synchronized (SESSION_LOCK) { - SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId); + SessionRecord sessionRecord = sessionStore.loadSession(remoteAddress); SessionState sessionState = sessionRecord.getSessionState(); ChainKey chainKey = sessionState.getSenderChainKey(); MessageKeys messageKeys = chainKey.getMessageKeys(); @@ -129,7 +126,7 @@ public class SessionCipher { } sessionState.setSenderChainKey(chainKey.getNextChainKey()); - sessionStore.storeSession(recipientId, deviceId, sessionRecord); + sessionStore.storeSession(remoteAddress, sessionRecord); return ciphertextMessage; } } @@ -182,13 +179,13 @@ public class SessionCipher { InvalidKeyIdException, InvalidKeyException, UntrustedIdentityException { synchronized (SESSION_LOCK) { - SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId); + SessionRecord sessionRecord = sessionStore.loadSession(remoteAddress); Optional unsignedPreKeyId = sessionBuilder.process(sessionRecord, ciphertext); byte[] plaintext = decrypt(sessionRecord, ciphertext.getWhisperMessage()); callback.handlePlaintext(plaintext); - sessionStore.storeSession(recipientId, deviceId, sessionRecord); + sessionStore.storeSession(remoteAddress, sessionRecord); if (unsignedPreKeyId.isPresent()) { preKeyStore.removePreKey(unsignedPreKeyId.get()); @@ -241,16 +238,16 @@ public class SessionCipher { { synchronized (SESSION_LOCK) { - if (!sessionStore.containsSession(recipientId, deviceId)) { - throw new NoSessionException("No session for: " + recipientId + ", " + deviceId); + if (!sessionStore.containsSession(remoteAddress)) { + throw new NoSessionException("No session for: " + remoteAddress); } - SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId); + SessionRecord sessionRecord = sessionStore.loadSession(remoteAddress); byte[] plaintext = decrypt(sessionRecord, ciphertext); callback.handlePlaintext(plaintext); - sessionStore.storeSession(recipientId, deviceId, sessionRecord); + sessionStore.storeSession(remoteAddress, sessionRecord); return plaintext; } @@ -325,18 +322,18 @@ public class SessionCipher { public int getRemoteRegistrationId() { synchronized (SESSION_LOCK) { - SessionRecord record = sessionStore.loadSession(recipientId, deviceId); + SessionRecord record = sessionStore.loadSession(remoteAddress); return record.getSessionState().getRemoteRegistrationId(); } } public int getSessionVersion() { synchronized (SESSION_LOCK) { - if (!sessionStore.containsSession(recipientId, deviceId)) { - throw new IllegalStateException(String.format("No session for (%d, %d)!", recipientId, deviceId)); + if (!sessionStore.containsSession(remoteAddress)) { + throw new IllegalStateException(String.format("No session for (%s)!", remoteAddress)); } - SessionRecord record = sessionStore.loadSession(recipientId, deviceId); + SessionRecord record = sessionStore.loadSession(remoteAddress); return record.getSessionState().getSessionVersion(); } } diff --git a/java/src/main/java/org/whispersystems/libaxolotl/groups/SenderKeyName.java b/java/src/main/java/org/whispersystems/libaxolotl/groups/SenderKeyName.java index ce4325ffa..cf2e48f24 100644 --- a/java/src/main/java/org/whispersystems/libaxolotl/groups/SenderKeyName.java +++ b/java/src/main/java/org/whispersystems/libaxolotl/groups/SenderKeyName.java @@ -16,35 +16,31 @@ */ package org.whispersystems.libaxolotl.groups; +import org.whispersystems.libaxolotl.AxolotlAddress; + /** * A representation of a (groupId + senderId + deviceId) tuple. */ public class SenderKeyName { - private final String groupId; - private final long senderId; - private final int deviceId; + private final String groupId; + private final AxolotlAddress sender; - public SenderKeyName(String groupId, long senderId, int deviceId) { + public SenderKeyName(String groupId, AxolotlAddress sender) { this.groupId = groupId; - this.senderId = senderId; - this.deviceId = deviceId; + this.sender = sender; } public String getGroupId() { return groupId; } - public long getSenderId() { - return senderId; - } - - public int getDeviceId() { - return deviceId; + public AxolotlAddress getSender() { + return sender; } public String serialize() { - return groupId + "::" + String.valueOf(senderId) + "::" + String.valueOf(deviceId); + return groupId + "::" + sender.getName() + "::" + String.valueOf(sender.getDeviceId()); } @Override @@ -56,13 +52,12 @@ public class SenderKeyName { return this.groupId.equals(that.groupId) && - this.senderId == that.senderId && - this.deviceId == that.deviceId; + this.sender.equals(that.sender); } @Override public int hashCode() { - return this.groupId.hashCode() ^ (int)this.senderId ^ this.deviceId; + return this.groupId.hashCode() ^ this.sender.hashCode(); } } diff --git a/java/src/main/java/org/whispersystems/libaxolotl/state/IdentityKeyStore.java b/java/src/main/java/org/whispersystems/libaxolotl/state/IdentityKeyStore.java index d2024f783..86e18adf9 100644 --- a/java/src/main/java/org/whispersystems/libaxolotl/state/IdentityKeyStore.java +++ b/java/src/main/java/org/whispersystems/libaxolotl/state/IdentityKeyStore.java @@ -32,10 +32,10 @@ public interface IdentityKeyStore { *

* Store a remote client's identity key as trusted. * - * @param recipientId The recipient ID of the remote client. + * @param name The name of the remote client. * @param identityKey The remote client's identity key. */ - public void saveIdentity(long recipientId, IdentityKey identityKey); + public void saveIdentity(String name, IdentityKey identityKey); /** @@ -48,10 +48,10 @@ public interface IdentityKeyStore { * store. Only if it mismatches an entry in the local store is it considered * 'untrusted.' * - * @param recipientId The recipient ID of the remote client. + * @param name The name of the remote client. * @param identityKey The identity key to verify. * @return true if trusted, false if untrusted. */ - public boolean isTrustedIdentity(long recipientId, IdentityKey identityKey); + public boolean isTrustedIdentity(String name, IdentityKey identityKey); } diff --git a/java/src/main/java/org/whispersystems/libaxolotl/state/SessionStore.java b/java/src/main/java/org/whispersystems/libaxolotl/state/SessionStore.java index c5ad00b0b..a2a207869 100644 --- a/java/src/main/java/org/whispersystems/libaxolotl/state/SessionStore.java +++ b/java/src/main/java/org/whispersystems/libaxolotl/state/SessionStore.java @@ -1,5 +1,7 @@ package org.whispersystems.libaxolotl.state; +import org.whispersystems.libaxolotl.AxolotlAddress; + import java.util.List; /** @@ -19,50 +21,46 @@ public interface SessionStore { * durable session state (what is returned by subsequent calls to this method) without the * store method being called here first. * - * @param recipientId The recipientID of the remote client. - * @param deviceId The deviceID of the remote client. + * @param address The name and device ID of the remote client. * @return a copy of the SessionRecord corresponding to the recipientId + deviceId tuple, or * a new SessionRecord if one does not currently exist. */ - public SessionRecord loadSession(long recipientId, int deviceId); + public SessionRecord loadSession(AxolotlAddress address); /** * Returns all known devices with active sessions for a recipient * - * @param recipientId the recipient ID. + * @param name the name of the client. * @return all known sub-devices with active sessions. */ - public List getSubDeviceSessions(long recipientId); + public List getSubDeviceSessions(String name); /** * Commit to storage the {@link SessionRecord} for a given recipientId + deviceId tuple. - * @param recipientId the recipient ID of the remote client. - * @param deviceId the device ID of the remote client. + * @param address the address of the remote client. * @param record the current SessionRecord for the remote client. */ - public void storeSession(long recipientId, int deviceId, SessionRecord record); + public void storeSession(AxolotlAddress address, SessionRecord record); /** * Determine whether there is a committed {@link SessionRecord} for a recipientId + deviceId tuple. - * @param recipientId the recipient ID of the remote client. - * @param deviceId the device ID of the remote client. + * @param address the address of the remote client. * @return true if a {@link SessionRecord} exists, false otherwise. */ - public boolean containsSession(long recipientId, int deviceId); + public boolean containsSession(AxolotlAddress address); /** * Remove a {@link SessionRecord} for a recipientId + deviceId tuple. * - * @param recipientId the recipient ID of the remote client. - * @param deviceId the device ID of the remote client. + * @param address the address of the remote client. */ - public void deleteSession(long recipientId, int deviceId); + public void deleteSession(AxolotlAddress address); /** * Remove the {@link SessionRecord}s corresponding to all devices of a recipientId. * - * @param recipientId the recipient ID of the remote client. + * @param name the name of the remote client. */ - public void deleteAllSessions(long recipientId); + public void deleteAllSessions(String name); } diff --git a/tests/src/test/java/org/whispersystems/libaxolotl/InMemoryAxolotlStore.java b/tests/src/test/java/org/whispersystems/libaxolotl/InMemoryAxolotlStore.java index e375c5747..f4bf38eb6 100644 --- a/tests/src/test/java/org/whispersystems/libaxolotl/InMemoryAxolotlStore.java +++ b/tests/src/test/java/org/whispersystems/libaxolotl/InMemoryAxolotlStore.java @@ -26,13 +26,13 @@ public class InMemoryAxolotlStore implements AxolotlStore { } @Override - public void saveIdentity(long recipientId, IdentityKey identityKey) { - identityKeyStore.saveIdentity(recipientId, identityKey); + public void saveIdentity(String name, IdentityKey identityKey) { + identityKeyStore.saveIdentity(name, identityKey); } @Override - public boolean isTrustedIdentity(long recipientId, IdentityKey identityKey) { - return identityKeyStore.isTrustedIdentity(recipientId, identityKey); + public boolean isTrustedIdentity(String name, IdentityKey identityKey) { + return identityKeyStore.isTrustedIdentity(name, identityKey); } @Override @@ -56,33 +56,33 @@ public class InMemoryAxolotlStore implements AxolotlStore { } @Override - public SessionRecord loadSession(long recipientId, int deviceId) { - return sessionStore.loadSession(recipientId, deviceId); + public SessionRecord loadSession(AxolotlAddress address) { + return sessionStore.loadSession(address); } @Override - public List getSubDeviceSessions(long recipientId) { - return sessionStore.getSubDeviceSessions(recipientId); + public List getSubDeviceSessions(String name) { + return sessionStore.getSubDeviceSessions(name); } @Override - public void storeSession(long recipientId, int deviceId, SessionRecord record) { - sessionStore.storeSession(recipientId, deviceId, record); + public void storeSession(AxolotlAddress address, SessionRecord record) { + sessionStore.storeSession(address, record); } @Override - public boolean containsSession(long recipientId, int deviceId) { - return sessionStore.containsSession(recipientId, deviceId); + public boolean containsSession(AxolotlAddress address) { + return sessionStore.containsSession(address); } @Override - public void deleteSession(long recipientId, int deviceId) { - sessionStore.deleteSession(recipientId, deviceId); + public void deleteSession(AxolotlAddress address) { + sessionStore.deleteSession(address); } @Override - public void deleteAllSessions(long recipientId) { - sessionStore.deleteAllSessions(recipientId); + public void deleteAllSessions(String name) { + sessionStore.deleteAllSessions(name); } @Override diff --git a/tests/src/test/java/org/whispersystems/libaxolotl/InMemoryIdentityKeyStore.java b/tests/src/test/java/org/whispersystems/libaxolotl/InMemoryIdentityKeyStore.java index acb6110a4..bf6dc3183 100644 --- a/tests/src/test/java/org/whispersystems/libaxolotl/InMemoryIdentityKeyStore.java +++ b/tests/src/test/java/org/whispersystems/libaxolotl/InMemoryIdentityKeyStore.java @@ -11,7 +11,7 @@ import java.util.Map; public class InMemoryIdentityKeyStore implements IdentityKeyStore { - private final Map trustedKeys = new HashMap<>(); + private final Map trustedKeys = new HashMap<>(); private final IdentityKeyPair identityKeyPair; private final int localRegistrationId; @@ -39,13 +39,13 @@ public class InMemoryIdentityKeyStore implements IdentityKeyStore { } @Override - public void saveIdentity(long recipientId, IdentityKey identityKey) { - trustedKeys.put(recipientId, identityKey); + public void saveIdentity(String name, IdentityKey identityKey) { + trustedKeys.put(name, identityKey); } @Override - public boolean isTrustedIdentity(long recipientId, IdentityKey identityKey) { - IdentityKey trusted = trustedKeys.get(recipientId); + public boolean isTrustedIdentity(String name, IdentityKey identityKey) { + IdentityKey trusted = trustedKeys.get(name); return (trusted == null || trusted.equals(identityKey)); } } diff --git a/tests/src/test/java/org/whispersystems/libaxolotl/InMemorySessionStore.java b/tests/src/test/java/org/whispersystems/libaxolotl/InMemorySessionStore.java index 2d03d4377..f707773e9 100644 --- a/tests/src/test/java/org/whispersystems/libaxolotl/InMemorySessionStore.java +++ b/tests/src/test/java/org/whispersystems/libaxolotl/InMemorySessionStore.java @@ -2,7 +2,6 @@ package org.whispersystems.libaxolotl; import org.whispersystems.libaxolotl.state.SessionRecord; import org.whispersystems.libaxolotl.state.SessionStore; -import org.whispersystems.libaxolotl.util.Pair; import java.io.IOException; import java.util.HashMap; @@ -12,15 +11,15 @@ import java.util.Map; public class InMemorySessionStore implements SessionStore { - private Map, byte[]> sessions = new HashMap<>(); + private Map sessions = new HashMap<>(); public InMemorySessionStore() {} @Override - public synchronized SessionRecord loadSession(long recipientId, int deviceId) { + public synchronized SessionRecord loadSession(AxolotlAddress remoteAddress) { try { - if (containsSession(recipientId, deviceId)) { - return new SessionRecord(sessions.get(new Pair<>(recipientId, deviceId))); + if (containsSession(remoteAddress)) { + return new SessionRecord(sessions.get(remoteAddress)); } else { return new SessionRecord(); } @@ -30,12 +29,12 @@ public class InMemorySessionStore implements SessionStore { } @Override - public synchronized List getSubDeviceSessions(long recipientId) { + public synchronized List getSubDeviceSessions(String name) { List deviceIds = new LinkedList<>(); - for (Pair key : sessions.keySet()) { - if (key.first() == recipientId) { - deviceIds.add(key.second()); + for (AxolotlAddress key : sessions.keySet()) { + if (key.getName().equals(name)) { + deviceIds.add(key.getDeviceId()); } } @@ -43,24 +42,24 @@ public class InMemorySessionStore implements SessionStore { } @Override - public synchronized void storeSession(long recipientId, int deviceId, SessionRecord record) { - sessions.put(new Pair<>(recipientId, deviceId), record.serialize()); + public synchronized void storeSession(AxolotlAddress address, SessionRecord record) { + sessions.put(address, record.serialize()); } @Override - public synchronized boolean containsSession(long recipientId, int deviceId) { - return sessions.containsKey(new Pair<>(recipientId, deviceId)); + public synchronized boolean containsSession(AxolotlAddress address) { + return sessions.containsKey(address); } @Override - public synchronized void deleteSession(long recipientId, int deviceId) { - sessions.remove(new Pair<>(recipientId, deviceId)); + public synchronized void deleteSession(AxolotlAddress address) { + sessions.remove(address); } @Override - public synchronized void deleteAllSessions(long recipientId) { - for (Pair key : sessions.keySet()) { - if (key.first() == recipientId) { + public synchronized void deleteAllSessions(String name) { + for (AxolotlAddress key : sessions.keySet()) { + if (key.getName().equals(name)) { sessions.remove(key); } } diff --git a/tests/src/test/java/org/whispersystems/libaxolotl/SessionBuilderTest.java b/tests/src/test/java/org/whispersystems/libaxolotl/SessionBuilderTest.java index 0912493ee..539131f07 100644 --- a/tests/src/test/java/org/whispersystems/libaxolotl/SessionBuilderTest.java +++ b/tests/src/test/java/org/whispersystems/libaxolotl/SessionBuilderTest.java @@ -20,13 +20,13 @@ import java.util.Set; public class SessionBuilderTest extends TestCase { - private static final long ALICE_RECIPIENT_ID = 5L; - private static final long BOB_RECIPIENT_ID = 2L; + private static final AxolotlAddress ALICE_ADDRESS = new AxolotlAddress("+14151111111", 1); + private static final AxolotlAddress BOB_ADDRESS = new AxolotlAddress("+14152222222", 1); public void testBasicPreKeyV2() throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException, NoSessionException { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); AxolotlStore bobStore = new InMemoryAxolotlStore(); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(); @@ -37,11 +37,11 @@ public class SessionBuilderTest extends TestCase { aliceSessionBuilder.process(bobPreKey); - assertTrue(aliceStore.containsSession(BOB_RECIPIENT_ID, 1)); - assertTrue(aliceStore.loadSession(BOB_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 2); + assertTrue(aliceStore.containsSession(BOB_ADDRESS)); + assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 2); String originalMessage = "L'homme est condamné à être libre"; - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes()); assertTrue(outgoingMessage.getType() == CiphertextMessage.PREKEY_TYPE); @@ -49,11 +49,11 @@ public class SessionBuilderTest extends TestCase { PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessage.serialize()); bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = bobSessionCipher.decrypt(incomingMessage); - assertTrue(bobStore.containsSession(ALICE_RECIPIENT_ID, 1)); - assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 2); + assertTrue(bobStore.containsSession(ALICE_ADDRESS)); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 2); assertTrue(originalMessage.equals(new String(plaintext))); CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes()); @@ -65,8 +65,8 @@ public class SessionBuilderTest extends TestCase { runInteraction(aliceStore, bobStore); aliceStore = new InMemoryAxolotlStore(); - aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); - aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); + aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); + aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); bobPreKeyPair = Curve.generateKeyPair(); bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), @@ -82,7 +82,7 @@ public class SessionBuilderTest extends TestCase { bobSessionCipher.decrypt(new PreKeyWhisperMessage(outgoingMessage.serialize())); throw new AssertionError("shouldn't be trusted!"); } catch (UntrustedIdentityException uie) { - bobStore.saveIdentity(ALICE_RECIPIENT_ID, new PreKeyWhisperMessage(outgoingMessage.serialize()).getIdentityKey()); + bobStore.saveIdentity(ALICE_ADDRESS.getName(), new PreKeyWhisperMessage(outgoingMessage.serialize()).getIdentityKey()); } plaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(outgoingMessage.serialize())); @@ -105,7 +105,7 @@ public class SessionBuilderTest extends TestCase { public void testBasicPreKeyV3() throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException, NoSessionException { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); final AxolotlStore bobStore = new InMemoryAxolotlStore(); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(); @@ -121,11 +121,11 @@ public class SessionBuilderTest extends TestCase { aliceSessionBuilder.process(bobPreKey); - assertTrue(aliceStore.containsSession(BOB_RECIPIENT_ID, 1)); - assertTrue(aliceStore.loadSession(BOB_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3); + assertTrue(aliceStore.containsSession(BOB_ADDRESS)); + assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3); final String originalMessage = "L'homme est condamné à être libre"; - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes()); assertTrue(outgoingMessage.getType() == CiphertextMessage.PREKEY_TYPE); @@ -134,18 +134,18 @@ public class SessionBuilderTest extends TestCase { bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature)); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = bobSessionCipher.decrypt(incomingMessage, new SessionCipher.DecryptionCallback() { @Override public void handlePlaintext(byte[] plaintext) { assertTrue(originalMessage.equals(new String(plaintext))); - assertFalse(bobStore.containsSession(ALICE_RECIPIENT_ID, 1)); + assertFalse(bobStore.containsSession(ALICE_ADDRESS)); } }); - 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); + assertTrue(bobStore.containsSession(ALICE_ADDRESS)); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getAliceBaseKey() != null); assertTrue(originalMessage.equals(new String(plaintext))); CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes()); @@ -157,8 +157,8 @@ public class SessionBuilderTest extends TestCase { runInteraction(aliceStore, bobStore); aliceStore = new InMemoryAxolotlStore(); - aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); - aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); + aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); + aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); bobPreKeyPair = Curve.generateKeyPair(); bobSignedPreKeyPair = Curve.generateKeyPair(); @@ -178,7 +178,7 @@ public class SessionBuilderTest extends TestCase { plaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(outgoingMessage.serialize())); throw new AssertionError("shouldn't be trusted!"); } catch (UntrustedIdentityException uie) { - bobStore.saveIdentity(ALICE_RECIPIENT_ID, new PreKeyWhisperMessage(outgoingMessage.serialize()).getIdentityKey()); + bobStore.saveIdentity(ALICE_ADDRESS.getName(), new PreKeyWhisperMessage(outgoingMessage.serialize()).getIdentityKey()); } plaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(outgoingMessage.serialize())); @@ -199,7 +199,7 @@ public class SessionBuilderTest extends TestCase { public void testBadSignedPreKeySignature() throws InvalidKeyException, UntrustedIdentityException { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); @@ -238,7 +238,7 @@ public class SessionBuilderTest extends TestCase { public void testRepeatBundleMessageV2() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, NoSessionException { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); AxolotlStore bobStore = new InMemoryAxolotlStore(); @@ -258,7 +258,7 @@ public class SessionBuilderTest extends TestCase { aliceSessionBuilder.process(bobPreKey); String originalMessage = "L'homme est condamné à être libre"; - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes()); CiphertextMessage outgoingMessageTwo = aliceSessionCipher.encrypt(originalMessage.getBytes()); @@ -266,7 +266,7 @@ public class SessionBuilderTest extends TestCase { PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessageOne.serialize()); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = bobSessionCipher.decrypt(incomingMessage); assertTrue(originalMessage.equals(new String(plaintext))); @@ -291,7 +291,7 @@ public class SessionBuilderTest extends TestCase { public void testRepeatBundleMessageV3() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, NoSessionException { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); AxolotlStore bobStore = new InMemoryAxolotlStore(); @@ -311,7 +311,7 @@ public class SessionBuilderTest extends TestCase { aliceSessionBuilder.process(bobPreKey); String originalMessage = "L'homme est condamné à être libre"; - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes()); CiphertextMessage outgoingMessageTwo = aliceSessionCipher.encrypt(originalMessage.getBytes()); @@ -320,7 +320,7 @@ public class SessionBuilderTest extends TestCase { PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessageOne.serialize()); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = bobSessionCipher.decrypt(incomingMessage); assertTrue(originalMessage.equals(new String(plaintext))); @@ -345,7 +345,7 @@ public class SessionBuilderTest extends TestCase { public void testBadMessageBundle() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, DuplicateMessageException, LegacyMessageException, InvalidKeyIdException { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); AxolotlStore bobStore = new InMemoryAxolotlStore(); @@ -365,7 +365,7 @@ public class SessionBuilderTest extends TestCase { aliceSessionBuilder.process(bobPreKey); String originalMessage = "L'homme est condamné à être libre"; - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes()); assertTrue(outgoingMessageOne.getType() == CiphertextMessage.PREKEY_TYPE); @@ -377,7 +377,7 @@ public class SessionBuilderTest extends TestCase { badMessage[badMessage.length-10] ^= 0x01; PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(badMessage); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = new byte[0]; @@ -398,10 +398,10 @@ public class SessionBuilderTest extends TestCase { public void testBasicKeyExchange() throws InvalidKeyException, LegacyMessageException, InvalidMessageException, DuplicateMessageException, UntrustedIdentityException, StaleKeyExchangeException, InvalidVersionException, NoSessionException { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); AxolotlStore bobStore = new InMemoryAxolotlStore(); - SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1); + SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_ADDRESS); KeyExchangeMessage aliceKeyExchangeMessage = aliceSessionBuilder.process(); assertTrue(aliceKeyExchangeMessage != null); @@ -415,20 +415,20 @@ public class SessionBuilderTest extends TestCase { KeyExchangeMessage response = aliceSessionBuilder.process(new KeyExchangeMessage(bobKeyExchangeMessageBytes)); assertTrue(response == null); - assertTrue(aliceStore.containsSession(BOB_RECIPIENT_ID, 1)); - assertTrue(bobStore.containsSession(ALICE_RECIPIENT_ID, 1)); + assertTrue(aliceStore.containsSession(BOB_ADDRESS)); + assertTrue(bobStore.containsSession(ALICE_ADDRESS)); runInteraction(aliceStore, bobStore); aliceStore = new InMemoryAxolotlStore(); - aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); aliceKeyExchangeMessage = aliceSessionBuilder.process(); try { bobKeyExchangeMessage = bobSessionBuilder.process(aliceKeyExchangeMessage); throw new AssertionError("This identity shouldn't be trusted!"); } catch (UntrustedIdentityException uie) { - bobStore.saveIdentity(ALICE_RECIPIENT_ID, aliceKeyExchangeMessage.getIdentityKey()); + bobStore.saveIdentity(ALICE_ADDRESS.getName(), aliceKeyExchangeMessage.getIdentityKey()); bobKeyExchangeMessage = bobSessionBuilder.process(aliceKeyExchangeMessage); } @@ -440,10 +440,10 @@ public class SessionBuilderTest extends TestCase { public void testSimultaneousKeyExchange() throws InvalidKeyException, DuplicateMessageException, LegacyMessageException, InvalidMessageException, UntrustedIdentityException, StaleKeyExchangeException, NoSessionException { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); AxolotlStore bobStore = new InMemoryAxolotlStore(); - SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1); + SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_ADDRESS); KeyExchangeMessage aliceKeyExchange = aliceSessionBuilder.process(); KeyExchangeMessage bobKeyExchange = bobSessionBuilder.process(); @@ -468,7 +468,7 @@ public class SessionBuilderTest extends TestCase { public void testOptionalOneTimePreKey() throws Exception { AxolotlStore aliceStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); AxolotlStore bobStore = new InMemoryAxolotlStore(); @@ -485,11 +485,11 @@ public class SessionBuilderTest extends TestCase { aliceSessionBuilder.process(bobPreKey); - assertTrue(aliceStore.containsSession(BOB_RECIPIENT_ID, 1)); - assertTrue(aliceStore.loadSession(BOB_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3); + assertTrue(aliceStore.containsSession(BOB_ADDRESS)); + assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3); String originalMessage = "L'homme est condamné à être libre"; - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); CiphertextMessage outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes()); assertTrue(outgoingMessage.getType() == CiphertextMessage.PREKEY_TYPE); @@ -500,12 +500,12 @@ public class SessionBuilderTest extends TestCase { bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature)); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); byte[] plaintext = bobSessionCipher.decrypt(incomingMessage); - 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); + assertTrue(bobStore.containsSession(ALICE_ADDRESS)); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getAliceBaseKey() != null); assertTrue(originalMessage.equals(new String(plaintext))); } @@ -513,8 +513,8 @@ public class SessionBuilderTest extends TestCase { private void runInteraction(AxolotlStore aliceStore, AxolotlStore bobStore) throws DuplicateMessageException, LegacyMessageException, InvalidMessageException, NoSessionException { - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPIENT_ID, 1); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); String originalMessage = "smert ze smert"; CiphertextMessage aliceMessage = aliceSessionCipher.encrypt(originalMessage.getBytes()); diff --git a/tests/src/test/java/org/whispersystems/libaxolotl/SessionCipherTest.java b/tests/src/test/java/org/whispersystems/libaxolotl/SessionCipherTest.java index e956ed775..a3b5db4cf 100644 --- a/tests/src/test/java/org/whispersystems/libaxolotl/SessionCipherTest.java +++ b/tests/src/test/java/org/whispersystems/libaxolotl/SessionCipherTest.java @@ -52,11 +52,11 @@ public class SessionCipherTest extends TestCase { AxolotlStore aliceStore = new InMemoryAxolotlStore(); AxolotlStore bobStore = new InMemoryAxolotlStore(); - aliceStore.storeSession(2L, 1, aliceSessionRecord); - bobStore.storeSession(3L, 1, bobSessionRecord); + aliceStore.storeSession(new AxolotlAddress("+14159999999", 1), aliceSessionRecord); + bobStore.storeSession(new AxolotlAddress("+14158888888", 1), bobSessionRecord); - SessionCipher aliceCipher = new SessionCipher(aliceStore, 2L, 1); - SessionCipher bobCipher = new SessionCipher(bobStore, 3L, 1); + SessionCipher aliceCipher = new SessionCipher(aliceStore, new AxolotlAddress("+14159999999", 1)); + SessionCipher bobCipher = new SessionCipher(bobStore, new AxolotlAddress("+14158888888", 1)); byte[] alicePlaintext = "This is a plaintext message.".getBytes(); CiphertextMessage message = aliceCipher.encrypt(alicePlaintext); diff --git a/tests/src/test/java/org/whispersystems/libaxolotl/SimultaneousInitiateTests.java b/tests/src/test/java/org/whispersystems/libaxolotl/SimultaneousInitiateTests.java index f09fedf8e..6e68508cc 100644 --- a/tests/src/test/java/org/whispersystems/libaxolotl/SimultaneousInitiateTests.java +++ b/tests/src/test/java/org/whispersystems/libaxolotl/SimultaneousInitiateTests.java @@ -18,8 +18,8 @@ import java.util.Random; public class SimultaneousInitiateTests extends TestCase { - private static final long BOB_RECIPENT_ID = 12345; - private static final long ALICE_RECIPIENT_ID = 6789; + private static final AxolotlAddress BOB_ADDRESS = new AxolotlAddress("+14151231234", 1); + private static final AxolotlAddress ALICE_ADDRESS = new AxolotlAddress("+14159998888", 1); private static final ECKeyPair aliceSignedPreKey = Curve.generateKeyPair(); private static final ECKeyPair bobSignedPreKey = Curve.generateKeyPair(); @@ -38,11 +38,11 @@ public class SimultaneousInitiateTests extends TestCase { PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore); PreKeyBundle bobPreKeyBundle = createBobPreKeyBundle(bobStore); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPENT_ID, 1); - SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); + SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_ADDRESS); - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPENT_ID, 1); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); aliceSessionBuilder.process(bobPreKeyBundle); bobSessionBuilder.process(alicePreKeyBundle); @@ -61,8 +61,8 @@ public class SimultaneousInitiateTests extends TestCase { assertTrue(new String(alicePlaintext).equals("sample message")); assertTrue(new String(bobPlaintext).equals("hey there")); - assertTrue(aliceStore.loadSession(BOB_RECIPENT_ID, 1).getSessionState().getSessionVersion() == 3); - assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3); + assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3); assertFalse(isSessionIdEqual(aliceStore, bobStore)); @@ -92,11 +92,11 @@ public class SimultaneousInitiateTests extends TestCase { PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore); PreKeyBundle bobPreKeyBundle = createBobPreKeyBundle(bobStore); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPENT_ID, 1); - SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); + SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_ADDRESS); - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPENT_ID, 1); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); aliceSessionBuilder.process(bobPreKeyBundle); bobSessionBuilder.process(alicePreKeyBundle); @@ -112,7 +112,7 @@ public class SimultaneousInitiateTests extends TestCase { byte[] bobPlaintext = bobSessionCipher.decrypt(new PreKeyWhisperMessage(messageForBob.serialize())); assertTrue(new String(bobPlaintext).equals("hey there")); - assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3); CiphertextMessage aliceResponse = aliceSessionCipher.encrypt("second message".getBytes()); @@ -144,11 +144,11 @@ public class SimultaneousInitiateTests extends TestCase { PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore); PreKeyBundle bobPreKeyBundle = createBobPreKeyBundle(bobStore); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPENT_ID, 1); - SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); + SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_ADDRESS); - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPENT_ID, 1); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); aliceSessionBuilder.process(bobPreKeyBundle); bobSessionBuilder.process(alicePreKeyBundle); @@ -167,8 +167,8 @@ public class SimultaneousInitiateTests extends TestCase { assertTrue(new String(alicePlaintext).equals("sample message")); assertTrue(new String(bobPlaintext).equals("hey there")); - assertTrue(aliceStore.loadSession(BOB_RECIPENT_ID, 1).getSessionState().getSessionVersion() == 3); - assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3); + assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3); assertFalse(isSessionIdEqual(aliceStore, bobStore)); @@ -203,11 +203,11 @@ public class SimultaneousInitiateTests extends TestCase { PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore); PreKeyBundle bobPreKeyBundle = createBobPreKeyBundle(bobStore); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPENT_ID, 1); - SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); + SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_ADDRESS); - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPENT_ID, 1); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); aliceSessionBuilder.process(bobPreKeyBundle); bobSessionBuilder.process(alicePreKeyBundle); @@ -226,8 +226,8 @@ public class SimultaneousInitiateTests extends TestCase { assertTrue(new String(alicePlaintext).equals("sample message")); assertTrue(new String(bobPlaintext).equals("hey there")); - assertTrue(aliceStore.loadSession(BOB_RECIPENT_ID, 1).getSessionState().getSessionVersion() == 3); - assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3); + assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3); assertFalse(isSessionIdEqual(aliceStore, bobStore)); @@ -277,11 +277,11 @@ public class SimultaneousInitiateTests extends TestCase { AxolotlStore bobStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPENT_ID, 1); - SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); + SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_ADDRESS); - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPENT_ID, 1); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); for (int i=0;i<15;i++) { PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore); @@ -304,8 +304,8 @@ public class SimultaneousInitiateTests extends TestCase { assertTrue(new String(alicePlaintext).equals("sample message")); assertTrue(new String(bobPlaintext).equals("hey there")); - assertTrue(aliceStore.loadSession(BOB_RECIPENT_ID, 1).getSessionState().getSessionVersion() == 3); - assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3); + assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3); assertFalse(isSessionIdEqual(aliceStore, bobStore)); } @@ -356,11 +356,11 @@ public class SimultaneousInitiateTests extends TestCase { AxolotlStore bobStore = new InMemoryAxolotlStore(); - SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_RECIPENT_ID, 1); - SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_RECIPIENT_ID, 1); + SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS); + SessionBuilder bobSessionBuilder = new SessionBuilder(bobStore, ALICE_ADDRESS); - SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_RECIPENT_ID, 1); - SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_RECIPIENT_ID, 1); + SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS); + SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS); // PreKeyBundle aliceLostPreKeyBundle = createAlicePreKeyBundle(aliceStore); PreKeyBundle bobLostPreKeyBundle = createBobPreKeyBundle(bobStore); @@ -392,8 +392,8 @@ public class SimultaneousInitiateTests extends TestCase { assertTrue(new String(alicePlaintext).equals("sample message")); assertTrue(new String(bobPlaintext).equals("hey there")); - assertTrue(aliceStore.loadSession(BOB_RECIPENT_ID, 1).getSessionState().getSessionVersion() == 3); - assertTrue(bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getSessionVersion() == 3); + assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3); + assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3); assertFalse(isSessionIdEqual(aliceStore, bobStore)); } @@ -447,8 +447,8 @@ public class SimultaneousInitiateTests extends TestCase { } private boolean isSessionIdEqual(AxolotlStore aliceStore, AxolotlStore bobStore) { - return Arrays.equals(aliceStore.loadSession(BOB_RECIPENT_ID, 1).getSessionState().getAliceBaseKey(), - bobStore.loadSession(ALICE_RECIPIENT_ID, 1).getSessionState().getAliceBaseKey()); + return Arrays.equals(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getAliceBaseKey(), + bobStore.loadSession(ALICE_ADDRESS).getSessionState().getAliceBaseKey()); } private PreKeyBundle createAlicePreKeyBundle(AxolotlStore aliceStore) throws InvalidKeyException { diff --git a/tests/src/test/java/org/whispersystems/libaxolotl/groups/GroupCipherTest.java b/tests/src/test/java/org/whispersystems/libaxolotl/groups/GroupCipherTest.java index b41adb58a..dd5a306fd 100644 --- a/tests/src/test/java/org/whispersystems/libaxolotl/groups/GroupCipherTest.java +++ b/tests/src/test/java/org/whispersystems/libaxolotl/groups/GroupCipherTest.java @@ -2,6 +2,7 @@ package org.whispersystems.libaxolotl.groups; import junit.framework.TestCase; +import org.whispersystems.libaxolotl.AxolotlAddress; import org.whispersystems.libaxolotl.DuplicateMessageException; import org.whispersystems.libaxolotl.InvalidMessageException; import org.whispersystems.libaxolotl.LegacyMessageException; @@ -14,6 +15,9 @@ import java.util.ArrayList; public class GroupCipherTest extends TestCase { + private static final AxolotlAddress SENDER_ADDRESS = new AxolotlAddress("+14150001111", 1); + private static final SenderKeyName GROUP_SENDER = new SenderKeyName("nihilist history reading group", SENDER_ADDRESS); + public void testBasicEncryptDecrypt() throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException { @@ -23,13 +27,12 @@ public class GroupCipherTest extends TestCase { GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore); GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore); - GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, new SenderKeyName("cool group", 1111, 0)); - GroupCipher bobGroupCipher = new GroupCipher(bobStore, new SenderKeyName("cool group", 1111, 0)); + GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, GROUP_SENDER); + GroupCipher bobGroupCipher = new GroupCipher(bobStore, GROUP_SENDER); - SenderKeyDistributionMessage aliceDistributionMessage = - aliceSessionBuilder.create(new SenderKeyName("cool group", 1111, 0)); + SenderKeyDistributionMessage aliceDistributionMessage = aliceSessionBuilder.create(GROUP_SENDER); - bobSessionBuilder.process(new SenderKeyName("cool group", 1111, 0), aliceDistributionMessage); + bobSessionBuilder.process(GROUP_SENDER, aliceDistributionMessage); byte[] ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert".getBytes()); byte[] plaintextFromAlice = bobGroupCipher.decrypt(ciphertextFromAlice); @@ -46,7 +49,7 @@ public class GroupCipherTest extends TestCase { GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore); GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore); - SenderKeyName aliceName = new SenderKeyName("cool group", 1111, 0); + SenderKeyName aliceName = GROUP_SENDER; GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName); GroupCipher bobGroupCipher = new GroupCipher(bobStore, aliceName); @@ -86,7 +89,7 @@ public class GroupCipherTest extends TestCase { GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore); GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore); - SenderKeyName aliceName = new SenderKeyName("cool group", 1111, 0); + SenderKeyName aliceName = GROUP_SENDER; GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName); GroupCipher bobGroupCipher = new GroupCipher(bobStore, aliceName); @@ -113,7 +116,7 @@ public class GroupCipherTest extends TestCase { public void testEncryptNoSession() { InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore(); - GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, new SenderKeyName("coolio groupio", 1111, 0)); + GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, new SenderKeyName("coolio groupio", new AxolotlAddress("+10002223333", 1))); try { aliceGroupCipher.encrypt("up the punks".getBytes()); throw new AssertionError("Should have failed!");