Display legacy message error when V1 message is received.

This commit is contained in:
Moxie Marlinspike 2014-04-10 15:20:43 -07:00
parent cebad39422
commit 0574ec170a
10 changed files with 39 additions and 12 deletions

View File

@ -133,4 +133,9 @@ public class WhisperMessage implements CiphertextMessage {
return CiphertextMessage.WHISPER_TYPE;
}
public static boolean isLegacy(byte[] message) {
return message != null && message.length >= 1 &&
Conversions.highBitsToInt(message[0]) <= CiphertextMessage.UNSUPPORTED_VERSION;
}
}

View File

@ -200,6 +200,9 @@
<!-- NotificationMmsMessageRecord -->
<string name="NotificationMmsMessageRecord_multimedia_message">Multimedia Message</string>
<!-- MessageRecord -->
<string name="MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported">Message encrypted with a legacy protocol version that is no longer supported. Please ask the sender to upgrade TextSecure to the most recent version.</string>
<!-- PassphraseChangeActivity -->
<string name="PassphraseChangeActivity_passphrases_dont_match_exclamation">Passphrases Don\'t Match!</string>
<string name="PassphraseChangeActivity_incorrect_old_passphrase_exclamation">Incorrect old passphrase!</string>

View File

@ -47,6 +47,7 @@ import org.whispersystems.textsecure.crypto.InvalidMessageException;
import org.whispersystems.textsecure.crypto.InvalidVersionException;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.whispersystems.textsecure.crypto.SessionCipher;
import org.whispersystems.textsecure.crypto.protocol.WhisperMessage;
import org.whispersystems.textsecure.push.IncomingPushMessage;
import org.whispersystems.textsecure.storage.RecipientDevice;
import org.whispersystems.textsecure.storage.Session;
@ -375,15 +376,17 @@ public class DecryptingQueue {
Recipient recipient = recipients.getPrimaryRecipient();
RecipientDevice recipientDevice = new RecipientDevice(recipient.getRecipientId(), deviceId);
SmsTransportDetails transportDetails = new SmsTransportDetails();
byte[] decodedCiphertext = transportDetails.getDecodedMessage(body.getBytes());
if (!Session.hasSession(context, masterSecret, recipient)) {
database.markAsNoSession(messageId);
if (WhisperMessage.isLegacy(decodedCiphertext)) database.markAsLegacyVersion(messageId);
else database.markAsNoSession(messageId);
return;
}
SmsTransportDetails transportDetails = new SmsTransportDetails();
SessionCipher sessionCipher = SessionCipher.createFor(context, masterSecret, recipientDevice);
byte[] decodedCiphertext = transportDetails.getDecodedMessage(body.getBytes());
byte[] paddedPlaintext = sessionCipher.decrypt(decodedCiphertext);
SessionCipher sessionCipher = SessionCipher.createFor(context, masterSecret, recipientDevice);
byte[] paddedPlaintext = sessionCipher.decrypt(decodedCiphertext);
plaintextBody = new String(transportDetails.getStrippedPaddingMessageBody(paddedPlaintext));

View File

@ -363,7 +363,7 @@ public class MmsDatabase extends Database implements MmsSmsColumns {
}
public void markAsLegacyVersion(long messageId, long threadId) {
updateMailboxBitmask(messageId, 0, Types.LEGACY_MESSAGE_BIT);
updateMailboxBitmask(messageId, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_LEGACY_BIT);
notifyConversationListeners(threadId);
}

View File

@ -47,7 +47,6 @@ public interface MmsSmsColumns {
protected static final long SECURE_MESSAGE_BIT = 0x800000;
protected static final long END_SESSION_BIT = 0x400000;
protected static final long PUSH_MESSAGE_BIT = 0x200000;
protected static final long LEGACY_MESSAGE_BIT = 0x100000;
// Group Message Information
protected static final long GROUP_UPDATE_BIT = 0x10000;
@ -61,6 +60,7 @@ public interface MmsSmsColumns {
protected static final long ENCRYPTION_REMOTE_FAILED_BIT = 0x10000000;
protected static final long ENCRYPTION_REMOTE_NO_SESSION_BIT = 0x08000000;
protected static final long ENCRYPTION_REMOTE_DUPLICATE_BIT = 0x04000000;
protected static final long ENCRYPTION_REMOTE_LEGACY_BIT = 0x02000000;
public static boolean isFailedMessageType(long type) {
return (type & BASE_TYPE_MASK) == BASE_SENT_FAILED_TYPE;
@ -172,6 +172,10 @@ public interface MmsSmsColumns {
return (type & ENCRYPTION_REMOTE_NO_SESSION_BIT) != 0;
}
public static boolean isLegacyType(long type) {
return (type & ENCRYPTION_REMOTE_LEGACY_BIT) != 0;
}
public static long translateFromSystemBaseType(long theirType) {
// public static final int NONE_TYPE = 0;
// public static final int INBOX_TYPE = 1;

View File

@ -170,10 +170,6 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
updateTypeBitmask(id, 0, Types.KEY_EXCHANGE_INVALID_VERSION_BIT);
}
public void markAsLegacyVersion(long id) {
updateTypeBitmask(id, 0, Types.LEGACY_MESSAGE_BIT);
}
public void markAsSecure(long id) {
updateTypeBitmask(id, 0, Types.SECURE_MESSAGE_BIT);
}
@ -206,6 +202,10 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_BIT);
}
public void markAsLegacyVersion(long id) {
updateTypeBitmask(id, Types.ENCRYPTION_MASK, Types.ENCRYPTION_REMOTE_LEGACY_BIT);
}
public void markAsOutbox(long id) {
updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_OUTBOX_TYPE);
}
@ -280,7 +280,7 @@ public class SmsDatabase extends Database implements MmsSmsColumns {
else if (((IncomingKeyExchangeMessage)message).isCorrupted()) type |= Types.KEY_EXCHANGE_CORRUPTED_BIT;
else if (((IncomingKeyExchangeMessage)message).isInvalidVersion()) type |= Types.KEY_EXCHANGE_INVALID_VERSION_BIT;
else if (((IncomingKeyExchangeMessage)message).isIdentityUpdate()) type |= Types.KEY_EXCHANGE_IDENTITY_UPDATE_BIT;
else if (((IncomingKeyExchangeMessage)message).isLegacyVersion()) type |= Types.LEGACY_MESSAGE_BIT;
else if (((IncomingKeyExchangeMessage)message).isLegacyVersion()) type |= Types.ENCRYPTION_REMOTE_LEGACY_BIT;
else if (((IncomingKeyExchangeMessage)message).isPreKeyBundle()) type |= Types.KEY_EXCHANGE_BUNDLE_BIT;
} else if (message.isSecureMessage()) {
type |= Types.SECURE_MESSAGE_BIT;

View File

@ -78,6 +78,8 @@ public class MediaMmsMessageRecord extends MessageRecord {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_duplicate_message));
} else if (MmsDatabase.Types.isNoRemoteSessionType(type)) {
return emphasisAdded(context.getString(R.string.MmsMessageRecord_mms_message_encrypted_for_non_existing_session));
} else if (isLegacyMessage()) {
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
} else if (!getBody().isPlaintext()) {
return emphasisAdded(context.getString(R.string.MessageNotifier_encrypted_message));
}

View File

@ -81,6 +81,10 @@ public abstract class MessageRecord extends DisplayRecord {
return MmsSmsColumns.Types.isSecureType(type);
}
public boolean isLegacyMessage() {
return MmsSmsColumns.Types.isLegacyType(type);
}
@Override
public SpannableString getDisplayBody() {
if (isGroupUpdate() && isOutgoing()) {

View File

@ -21,6 +21,7 @@ import android.content.Context;
import android.text.SpannableString;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.protocol.Tag;
import org.thoughtcrime.securesms.recipients.Recipient;
@ -63,6 +64,8 @@ public class SmsMessageRecord extends MessageRecord {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_received_corrupted_key_exchange_message));
} else if (isInvalidVersionKeyExchange()) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_received_key_exchange_message_for_invalid_protocol_version));
} else if (MmsSmsColumns.Types.isLegacyType(type)) {
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
} else if (isBundleKeyExchange()) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_received_message_with_unknown_identity_key_click_to_process));
} else if (isIdentityUpdate()) {

View File

@ -22,6 +22,7 @@ import android.text.SpannableString;
import android.text.style.StyleSpan;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.util.GroupUtil;
@ -69,6 +70,8 @@ public class ThreadRecord extends DisplayRecord {
return emphasisAdded(context.getString(R.string.MessageNotifier_encrypted_message));
} else if (SmsDatabase.Types.isEndSessionType(type)) {
return emphasisAdded(context.getString(R.string.TheadRecord_secure_session_ended));
} else if (MmsSmsColumns.Types.isLegacyType(type)) {
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
} else {
if (Util.isEmpty(getBody().getBody())) {
return new SpannableString(context.getString(R.string.MessageNotifier_no_subject));