Don't display duplicate push messages.

This commit is contained in:
Moxie Marlinspike
2014-03-19 12:37:46 -07:00
parent ad5d6d5bb7
commit fd1a18d2d0
11 changed files with 60 additions and 14 deletions

View File

@@ -0,0 +1,7 @@
package org.whispersystems.textsecure.crypto;
public class DuplicateMessageException extends Exception {
public DuplicateMessageException(String s) {
super(s);
}
}

View File

@@ -29,7 +29,7 @@ public abstract class SessionCipher {
protected static final Object SESSION_LOCK = new Object();
public abstract CiphertextMessage encrypt(byte[] paddedMessage);
public abstract byte[] decrypt(byte[] decodedMessage) throws InvalidMessageException;
public abstract byte[] decrypt(byte[] decodedMessage) throws InvalidMessageException, DuplicateMessageException;
public abstract int getRemoteRegistrationId();
public static SessionCipher createFor(Context context,

View File

@@ -77,7 +77,9 @@ public class SessionCipherV2 extends SessionCipher {
}
@Override
public byte[] decrypt(byte[] decodedMessage) throws InvalidMessageException {
public byte[] decrypt(byte[] decodedMessage)
throws InvalidMessageException, DuplicateMessageException
{
synchronized (SESSION_LOCK) {
SessionRecordV2 sessionRecord = getSessionRecord();
SessionState sessionState = sessionRecord.getSessionState();
@@ -94,6 +96,7 @@ public class SessionCipherV2 extends SessionCipher {
for (SessionState previousState : previousStates) {
try {
Log.w("SessionCipherV2", "Attempting decrypt on previous state...");
byte[] plaintext = decrypt(previousState, decodedMessage);
sessionRecord.save();
@@ -108,7 +111,7 @@ public class SessionCipherV2 extends SessionCipher {
}
public byte[] decrypt(SessionState sessionState, byte[] decodedMessage)
throws InvalidMessageException
throws InvalidMessageException, DuplicateMessageException
{
if (!sessionState.hasSenderChain()) {
throw new InvalidMessageException("Uninitialized session!");
@@ -167,18 +170,19 @@ public class SessionCipherV2 extends SessionCipher {
private MessageKeys getOrCreateMessageKeys(SessionState sessionState,
ECPublicKey theirEphemeral,
ChainKey chainKey, int counter)
throws InvalidMessageException
throws InvalidMessageException, DuplicateMessageException
{
if (chainKey.getIndex() > counter) {
if (sessionState.hasMessageKeys(theirEphemeral, counter)) {
return sessionState.removeMessageKeys(theirEphemeral, counter);
} else {
throw new InvalidMessageException("Received message with old counter!");
throw new DuplicateMessageException("Received message with old counter: " +
chainKey.getIndex() + " , " + counter);
}
}
if (chainKey.getIndex() - counter > 500) {
throw new InvalidMessageException("Over 500 messages into the future!");
if (chainKey.getIndex() - counter > 2000) {
throw new InvalidMessageException("Over 2000 messages into the future!");
}
while (chainKey.getIndex() < counter) {