mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-05 07:32:14 +00:00
Support for Axolotl protocol.
1) Split code into v1 and v2 message paths. 2) Do the Axolotl protocol for v2. 3) Switch all v2 entities to protobuf.
This commit is contained in:
@@ -8,7 +8,7 @@ import android.util.Pair;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.DecryptingQueue;
|
||||
import org.thoughtcrime.securesms.crypto.KeyExchangeProcessor;
|
||||
import org.thoughtcrime.securesms.crypto.KeyExchangeProcessorV2;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
@@ -24,9 +24,10 @@ import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.SmsTransportDetails;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.textsecure.crypto.InvalidKeyException;
|
||||
import org.whispersystems.textsecure.crypto.InvalidMessageException;
|
||||
import org.whispersystems.textsecure.crypto.InvalidVersionException;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.crypto.protocol.PreKeyBundleMessage;
|
||||
import org.whispersystems.textsecure.crypto.protocol.PreKeyWhisperMessage;
|
||||
import org.whispersystems.textsecure.push.IncomingPushMessage;
|
||||
import org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent;
|
||||
import org.whispersystems.textsecure.storage.InvalidKeyIdException;
|
||||
@@ -46,9 +47,9 @@ public class PushReceiver {
|
||||
}
|
||||
|
||||
public void process(MasterSecret masterSecret, Intent intent) {
|
||||
if (intent.getAction().equals(SendReceiveService.RECEIVE_PUSH_ACTION)) {
|
||||
if (SendReceiveService.RECEIVE_PUSH_ACTION.equals(intent.getAction())) {
|
||||
handleMessage(masterSecret, intent);
|
||||
} else if (intent.getAction().equals(SendReceiveService.DECRYPTED_PUSH_ACTION)) {
|
||||
} else if (SendReceiveService.DECRYPTED_PUSH_ACTION.equals(intent.getAction())) {
|
||||
handleDecrypt(masterSecret, intent);
|
||||
}
|
||||
}
|
||||
@@ -81,25 +82,25 @@ public class PushReceiver {
|
||||
} else {
|
||||
Recipients recipients = RecipientFactory.getRecipientsFromMessage(context, message, false);
|
||||
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
|
||||
MessageNotifier.updateNotification(context, masterSecret, threadId);
|
||||
MessageNotifier.updateNotification(context, null, threadId);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleReceivedPreKeyBundle(MasterSecret masterSecret, IncomingPushMessage message) {
|
||||
if (masterSecret == null) {
|
||||
handleReceivedSecureMessage(masterSecret, message);
|
||||
handleReceivedSecureMessage(null, message);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Recipient recipient = new Recipient(null, message.getSource(), null, null);
|
||||
KeyExchangeProcessor processor = new KeyExchangeProcessor(context, masterSecret, recipient);
|
||||
PreKeyBundleMessage preKeyExchange = new PreKeyBundleMessage(message.getBody());
|
||||
Recipient recipient = new Recipient(null, message.getSource(), null, null);
|
||||
KeyExchangeProcessorV2 processor = new KeyExchangeProcessorV2(context, masterSecret, recipient);
|
||||
PreKeyWhisperMessage preKeyExchange = new PreKeyWhisperMessage(message.getBody());
|
||||
|
||||
if (processor.isTrusted(preKeyExchange)) {
|
||||
processor.processKeyExchangeMessage(preKeyExchange);
|
||||
|
||||
IncomingPushMessage bundledMessage = message.withBody(preKeyExchange.getBundledMessage().serialize());
|
||||
IncomingPushMessage bundledMessage = message.withBody(preKeyExchange.getWhisperMessage().serialize());
|
||||
handleReceivedSecureMessage(masterSecret, bundledMessage);
|
||||
} else {
|
||||
SmsTransportDetails transportDetails = new SmsTransportDetails();
|
||||
@@ -110,13 +111,16 @@ public class PushReceiver {
|
||||
DatabaseFactory.getEncryptingSmsDatabase(context).insertMessageInbox(masterSecret, textMessage);
|
||||
}
|
||||
} catch (InvalidKeyException e) {
|
||||
Log.w("SmsReceiver", e);
|
||||
Log.w("PushReceiver", e);
|
||||
handleReceivedCorruptedKey(masterSecret, message, false);
|
||||
} catch (InvalidVersionException e) {
|
||||
Log.w("SmsReceiver", e);
|
||||
Log.w("PushReceiver", e);
|
||||
handleReceivedCorruptedKey(masterSecret, message, true);
|
||||
} catch (InvalidKeyIdException e) {
|
||||
Log.w("SmsReceiver", e);
|
||||
Log.w("PushReceiver", e);
|
||||
handleReceivedCorruptedKey(masterSecret, message, false);
|
||||
} catch (InvalidMessageException e) {
|
||||
Log.w("PushReceiver", e);
|
||||
handleReceivedCorruptedKey(masterSecret, message, false);
|
||||
}
|
||||
}
|
||||
@@ -237,9 +241,7 @@ public class PushReceiver {
|
||||
placeholder = new IncomingEncryptedMessage(placeholder, "");
|
||||
}
|
||||
|
||||
Pair<Long, Long> messageAndThreadId = DatabaseFactory.getEncryptingSmsDatabase(context)
|
||||
.insertMessageInbox(masterSecret,
|
||||
placeholder);
|
||||
return messageAndThreadId;
|
||||
return DatabaseFactory.getEncryptingSmsDatabase(context)
|
||||
.insertMessageInbox(masterSecret, placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.util.Pair;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.DecryptingQueue;
|
||||
import org.thoughtcrime.securesms.crypto.KeyExchangeProcessor;
|
||||
import org.thoughtcrime.securesms.crypto.KeyExchangeProcessorV2;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
||||
import org.thoughtcrime.securesms.crypto.protocol.KeyExchangeMessage;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
@@ -33,15 +34,17 @@ import org.thoughtcrime.securesms.protocol.WirePrefix;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingKeyExchangeMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingPreKeyBundleMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.MultipartSmsMessageHandler;
|
||||
import org.thoughtcrime.securesms.sms.SmsTransportDetails;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.textsecure.crypto.InvalidKeyException;
|
||||
import org.whispersystems.textsecure.crypto.InvalidMessageException;
|
||||
import org.whispersystems.textsecure.crypto.InvalidVersionException;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.crypto.protocol.CiphertextMessage;
|
||||
import org.whispersystems.textsecure.crypto.protocol.PreKeyBundleMessage;
|
||||
import org.whispersystems.textsecure.crypto.protocol.PreKeyWhisperMessage;
|
||||
import org.whispersystems.textsecure.crypto.protocol.WhisperMessageV2;
|
||||
import org.whispersystems.textsecure.storage.InvalidKeyIdException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -97,26 +100,27 @@ public class SmsReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private Pair<Long, Long> storePreKeyBundledMessage(MasterSecret masterSecret,
|
||||
IncomingKeyExchangeMessage message)
|
||||
private Pair<Long, Long> storePreKeyWhisperMessage(MasterSecret masterSecret,
|
||||
IncomingPreKeyBundleMessage message)
|
||||
{
|
||||
Log.w("SmsReceiver", "Processing prekey message...");
|
||||
|
||||
try {
|
||||
Recipient recipient = new Recipient(null, message.getSender(), null, null);
|
||||
KeyExchangeProcessor processor = new KeyExchangeProcessor(context, masterSecret, recipient);
|
||||
SmsTransportDetails transportDetails = new SmsTransportDetails();
|
||||
PreKeyBundleMessage preKeyExchange = new PreKeyBundleMessage(transportDetails.getDecodedMessage(message.getMessageBody().getBytes()));
|
||||
Recipient recipient = new Recipient(null, message.getSender(), null, null);
|
||||
KeyExchangeProcessorV2 processor = new KeyExchangeProcessorV2(context, masterSecret, recipient);
|
||||
SmsTransportDetails transportDetails = new SmsTransportDetails();
|
||||
byte[] rawMessage = transportDetails.getDecodedMessage(message.getMessageBody().getBytes());
|
||||
PreKeyWhisperMessage preKeyExchange = new PreKeyWhisperMessage(rawMessage);
|
||||
|
||||
if (processor.isTrusted(preKeyExchange)) {
|
||||
processor.processKeyExchangeMessage(preKeyExchange);
|
||||
|
||||
CiphertextMessage ciphertextMessage = preKeyExchange.getBundledMessage();
|
||||
WhisperMessageV2 ciphertextMessage = preKeyExchange.getWhisperMessage();
|
||||
String bundledMessageBody = new String(transportDetails.getEncodedMessage(ciphertextMessage.serialize()));
|
||||
IncomingEncryptedMessage bundledMessage = new IncomingEncryptedMessage(message, bundledMessageBody);
|
||||
Pair<Long, Long> messageAndThreadId = storeSecureMessage(masterSecret, bundledMessage);
|
||||
|
||||
Intent intent = new Intent(KeyExchangeProcessor.SECURITY_UPDATE_EVENT);
|
||||
Intent intent = new Intent(KeyExchangeProcessorV2.SECURITY_UPDATE_EVENT);
|
||||
intent.putExtra("thread_id", messageAndThreadId.second);
|
||||
intent.setPackage(context.getPackageName());
|
||||
context.sendBroadcast(intent, KeyCachingService.KEY_PERMISSION);
|
||||
@@ -135,6 +139,9 @@ public class SmsReceiver {
|
||||
} catch (IOException e) {
|
||||
Log.w("SmsReceive", e);
|
||||
message.setCorrupted(true);
|
||||
} catch (InvalidMessageException e) {
|
||||
Log.w("SmsReceiver", e);
|
||||
message.setCorrupted(true);
|
||||
}
|
||||
|
||||
return storeStandardMessage(masterSecret, message);
|
||||
@@ -145,19 +152,17 @@ public class SmsReceiver {
|
||||
{
|
||||
if (masterSecret != null && TextSecurePreferences.isAutoRespondKeyExchangeEnabled(context)) {
|
||||
try {
|
||||
Recipient recipient = new Recipient(null, message.getSender(), null, null);
|
||||
KeyExchangeMessage keyExchangeMessage = new KeyExchangeMessage(message.getMessageBody());
|
||||
KeyExchangeProcessor processor = new KeyExchangeProcessor(context, masterSecret, recipient);
|
||||
Recipient recipient = new Recipient(null, message.getSender(), null, null);
|
||||
KeyExchangeMessage exchangeMessage = KeyExchangeMessage.createFor(message.getMessageBody());
|
||||
KeyExchangeProcessor processor = KeyExchangeProcessor.createFor(context, masterSecret, recipient, exchangeMessage);
|
||||
|
||||
Log.w("SmsReceiver", "Received key with fingerprint: " + keyExchangeMessage.getPublicKey().getFingerprint());
|
||||
|
||||
if (processor.isStale(keyExchangeMessage)) {
|
||||
if (processor.isStale(exchangeMessage)) {
|
||||
message.setStale(true);
|
||||
} else if (processor.isTrusted(keyExchangeMessage)) {
|
||||
} else if (processor.isTrusted(exchangeMessage)) {
|
||||
message.setProcessed(true);
|
||||
|
||||
Pair<Long, Long> messageAndThreadId = storeStandardMessage(masterSecret, message);
|
||||
processor.processKeyExchangeMessage(keyExchangeMessage, messageAndThreadId.second);
|
||||
processor.processKeyExchangeMessage(exchangeMessage, messageAndThreadId.second);
|
||||
|
||||
return messageAndThreadId;
|
||||
}
|
||||
@@ -167,6 +172,9 @@ public class SmsReceiver {
|
||||
} catch (InvalidKeyException e) {
|
||||
Log.w("SmsReceiver", e);
|
||||
message.setCorrupted(true);
|
||||
} catch (InvalidMessageException e) {
|
||||
Log.w("SmsReceiver", e);
|
||||
message.setCorrupted(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +183,7 @@ public class SmsReceiver {
|
||||
|
||||
private Pair<Long, Long> storeMessage(MasterSecret masterSecret, IncomingTextMessage message) {
|
||||
if (message.isSecureMessage()) return storeSecureMessage(masterSecret, message);
|
||||
else if (message.isPreKeyBundle()) return storePreKeyBundledMessage(masterSecret, (IncomingKeyExchangeMessage) message);
|
||||
else if (message.isPreKeyBundle()) return storePreKeyWhisperMessage(masterSecret, (IncomingPreKeyBundleMessage) message);
|
||||
else if (message.isKeyExchange()) return storeKeyExchangeMessage(masterSecret, (IncomingKeyExchangeMessage) message);
|
||||
else return storeStandardMessage(masterSecret, message);
|
||||
}
|
||||
@@ -191,7 +199,7 @@ public class SmsReceiver {
|
||||
}
|
||||
|
||||
public void process(MasterSecret masterSecret, Intent intent) {
|
||||
if (intent.getAction().equals(SendReceiveService.RECEIVE_SMS_ACTION)) {
|
||||
if (SendReceiveService.RECEIVE_SMS_ACTION.equals(intent.getAction())) {
|
||||
handleReceiveMessage(masterSecret, intent);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user