From a925b17419db5ea5267b25888aa3fd0549bb7fa6 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 23 Jul 2019 10:35:03 +1000 Subject: [PATCH] Fix session handling --- AndroidManifest.xml | 4 ++-- res/layout/registration_activity.xml | 2 +- res/layout/registration_welcome_activity.xml | 1 + .../securesms/crypto/IdentityKeyUtil.java | 2 +- .../securesms/crypto/PreKeyUtil.java | 2 -- .../storage/TextSecureSessionStore.java | 4 ++-- .../securesms/jobs/PushDecryptJob.java | 19 ++++++++++----- .../loki/LokiPreKeyBundleDatabase.kt | 23 +++++++++---------- .../loki/LokiPreKeyRecordDatabase.kt | 13 +++++------ 9 files changed, 37 insertions(+), 33 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 1ba77dee44..b8b0cd6140 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -93,7 +93,7 @@ android:supportsRtl="true" tools:replace="android:allowBackup" android:allowBackup="false" - android:theme="@style/TextSecure.LightTheme" + android:theme="@style/TextSecure.DarkTheme" android:largeHeap="true"> diff --git a/res/layout/registration_activity.xml b/res/layout/registration_activity.xml index 9cfc92a0ad..044870c405 100644 --- a/res/layout/registration_activity.xml +++ b/res/layout/registration_activity.xml @@ -5,7 +5,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:background="@color/white" + android:background="@color/loki_darkest_gray" android:fillViewport="true" tools:context=".RegistrationActivity"> diff --git a/res/layout/registration_welcome_activity.xml b/res/layout/registration_welcome_activity.xml index 032f2077e8..e93dc7a62d 100644 --- a/res/layout/registration_welcome_activity.xml +++ b/res/layout/registration_welcome_activity.xml @@ -2,6 +2,7 @@ diff --git a/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java b/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java index 592df407dd..ca6928f2ec 100644 --- a/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java +++ b/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java @@ -94,7 +94,7 @@ public class IdentityKeyUtil { save(context, IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(publicKey.serialize())); save(context, IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(keyPair.getPrivateKey().serialize())); } catch (Exception e) { - Log.d("Loki", "Couldn't restore key pair from seed due to error: " + e.getMessage()); + Log.d("Loki", "Couldn't restore key pair from seed due to error: " + e.getMessage() + "."); } } diff --git a/src/org/thoughtcrime/securesms/crypto/PreKeyUtil.java b/src/org/thoughtcrime/securesms/crypto/PreKeyUtil.java index ac346da9c3..7f7d939395 100644 --- a/src/org/thoughtcrime/securesms/crypto/PreKeyUtil.java +++ b/src/org/thoughtcrime/securesms/crypto/PreKeyUtil.java @@ -102,14 +102,12 @@ public class PreKeyUtil { } public synchronized static List generatePreKeys(Context context, int amount) { - PreKeyStore preKeyStore = new TextSecurePreKeyStore(context); List records = new LinkedList<>(); int preKeyIDOffset = TextSecurePreferences.getNextPreKeyId(context); for (int i = 0; i < amount; i++) { int preKeyID = (preKeyIDOffset + i) % Medium.MAX_VALUE; ECKeyPair keyPair = Curve.generateKeyPair(); PreKeyRecord record = new PreKeyRecord(preKeyID, keyPair); - preKeyStore.storePreKey(preKeyID, record); records.add(record); } TextSecurePreferences.setNextPreKeyId(context, (preKeyIDOffset + BATCH_SIZE + 1) % Medium.MAX_VALUE); diff --git a/src/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java b/src/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java index 0c1e7940de..38237484f5 100644 --- a/src/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java +++ b/src/org/thoughtcrime/securesms/crypto/storage/TextSecureSessionStore.java @@ -92,8 +92,8 @@ public class TextSecureSessionStore implements LokiSessionDatabaseProtocol { } } - public void archiveAllSessions(@NonNull String name) { - SignalProtocolAddress address = new SignalProtocolAddress(name, -1); + public void archiveAllSessions(@NonNull String hexEncodedPublicKey) { + SignalProtocolAddress address = new SignalProtocolAddress(hexEncodedPublicKey, -1); archiveSiblingSessions(address); } diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 6b5a5f9828..e731c702b8 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -244,9 +244,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType { LokiPreKeyRecordDatabase lokiPreKeyRecordDatabase = DatabaseFactory.getLokiPreKeyRecordDatabase(context); SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalNumber(context)); LokiServiceCipher cipher = new LokiServiceCipher(localAddress, axolotlStore, lokiThreadDatabase, lokiPreKeyRecordDatabase, UnidentifiedAccessUtil.getCertificateValidator()); - /* Loki - Original code - SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, UnidentifiedAccessUtil.getCertificateValidator()); - */ + + // Loki - Handle session reset logic + if (!envelope.isFriendRequest() && cipher.getSessionStatus(envelope) == null && envelope.isPreKeySignalMessage()) { + cipher.validateBackgroundMessage(envelope, envelope.getContent()); + } SignalServiceContent content = cipher.decrypt(envelope); @@ -255,7 +257,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { return; } - // Loki - Handle Loki specific logic if needed + // Loki - Store pre key bundle if needed if (content.lokiMessage.isPresent()) { LokiServiceMessage lokiMessage = content.lokiMessage.get(); if (lokiMessage.getPreKeyBundleMessage() != null) { @@ -272,6 +274,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } + // Loki - Get the sender display name if needed Optional senderDisplayName = content.senderDisplayName; if (senderDisplayName.isPresent()) { DatabaseFactory.getLokiUserDisplayNameDatabase(context).setDisplayName(envelope.getSource(), senderDisplayName.get()); @@ -299,7 +302,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { handleNeedsDeliveryReceipt(content, message); } - // Loki - Handle friend request logic if needed + // Loki - Handle friend request logic handleFriendRequestIfNeeded(envelope, content, message); } else if (content.getSyncMessage().isPresent()) { TextSecurePreferences.setMultiDevice(context, true); @@ -336,6 +339,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType { if (envelope.isPreKeySignalMessage()) { ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob()); } + + // Loki - Handle session reset logic + if (!envelope.isFriendRequest()) { + cipher.handleSessionResetRequestIfNeeded(envelope, cipher.getSessionStatus(envelope)); + } } catch (ProtocolInvalidVersionException e) { Log.w(TAG, e); handleInvalidVersionMessage(e.getSender(), e.getSenderDevice(), envelope.getTimestamp(), smsMessageId); @@ -471,7 +479,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { if (threadId != null) { TextSecureSessionStore sessionStore = new TextSecureSessionStore(context); LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context); -// sessionStore.deleteAllSessions(content.getSender()); Log.d("Loki", "Received a session reset request from: " + content.getSender() + "; archiving the session."); diff --git a/src/org/thoughtcrime/securesms/loki/LokiPreKeyBundleDatabase.kt b/src/org/thoughtcrime/securesms/loki/LokiPreKeyBundleDatabase.kt index 7b58fb3102..9f213d8fd9 100644 --- a/src/org/thoughtcrime/securesms/loki/LokiPreKeyBundleDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/LokiPreKeyBundleDatabase.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.loki import android.content.ContentValues import android.content.Context -import net.sqlcipher.database.SQLiteDatabase import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.crypto.PreKeyUtil import org.thoughtcrime.securesms.database.Database @@ -73,17 +72,17 @@ class LokiPreKeyBundleDatabase(context: Context, helper: SQLCipherOpenHelper) : fun setPreKeyBundle(hexEncodedPublicKey: String, preKeyBundle: PreKeyBundle) { val database = databaseHelper.writableDatabase - val contentValues = ContentValues(9) - contentValues.put(registrationID, preKeyBundle.registrationId) - contentValues.put(deviceID, preKeyBundle.deviceId) - contentValues.put(preKeyID, preKeyBundle.preKeyId) - contentValues.put(preKeyPublic, Base64.encodeBytes(preKeyBundle.preKey.serialize())) - contentValues.put(signedPreKeyID, preKeyBundle.signedPreKeyId) - contentValues.put(signedPreKeyPublic, Base64.encodeBytes(preKeyBundle.signedPreKey.serialize())) - contentValues.put(signedPreKeySignature, Base64.encodeBytes(preKeyBundle.signedPreKeySignature)) - contentValues.put(identityKey, Base64.encodeBytes(preKeyBundle.identityKey.serialize())) - contentValues.put(Companion.hexEncodedPublicKey, hexEncodedPublicKey) - database.insertWithOnConflict(tableName, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE) + val values = ContentValues(9) + values.put(registrationID, preKeyBundle.registrationId) + values.put(deviceID, preKeyBundle.deviceId) + values.put(preKeyID, preKeyBundle.preKeyId) + values.put(preKeyPublic, Base64.encodeBytes(preKeyBundle.preKey.serialize())) + values.put(signedPreKeyID, preKeyBundle.signedPreKeyId) + values.put(signedPreKeyPublic, Base64.encodeBytes(preKeyBundle.signedPreKey.serialize())) + values.put(signedPreKeySignature, Base64.encodeBytes(preKeyBundle.signedPreKeySignature)) + values.put(identityKey, Base64.encodeBytes(preKeyBundle.identityKey.serialize())) + values.put(Companion.hexEncodedPublicKey, hexEncodedPublicKey) + database.insertOrUpdate(tableName, values, "${Companion.hexEncodedPublicKey} = ?", arrayOf( hexEncodedPublicKey )) } override fun removePreKeyBundle(hexEncodedPublicKey: String) { diff --git a/src/org/thoughtcrime/securesms/loki/LokiPreKeyRecordDatabase.kt b/src/org/thoughtcrime/securesms/loki/LokiPreKeyRecordDatabase.kt index 3a6bcc19ab..4d006e7d36 100644 --- a/src/org/thoughtcrime/securesms/loki/LokiPreKeyRecordDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/LokiPreKeyRecordDatabase.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.loki import android.content.ContentValues import android.content.Context -import net.sqlcipher.database.SQLiteDatabase import org.thoughtcrime.securesms.crypto.PreKeyUtil import org.thoughtcrime.securesms.database.Database import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper @@ -13,9 +12,9 @@ class LokiPreKeyRecordDatabase(context: Context, helper: SQLCipherOpenHelper) : companion object { private val tableName = "loki_pre_key_record_database" - private val preKeyID = "pre_key_id" private val hexEncodedPublicKey = "public_key" - @JvmStatic val createTableCommand = "CREATE TABLE $tableName ($preKeyID INTEGER PRIMARY KEY, $hexEncodedPublicKey TEXT);" + private val preKeyID = "pre_key_id" + @JvmStatic val createTableCommand = "CREATE TABLE $tableName ($hexEncodedPublicKey TEXT PRIMARY KEY, $preKeyID INTEGER);" } fun hasPreKey(hexEncodedPublicKey: String): Boolean { @@ -36,14 +35,14 @@ class LokiPreKeyRecordDatabase(context: Context, helper: SQLCipherOpenHelper) : } private fun generateAndStorePreKeyRecord(hexEncodedPublicKey: String): PreKeyRecord { - val preKeyRecords = PreKeyUtil.generatePreKeys(context, 1) - PreKeyUtil.storePreKeyRecords(context, preKeyRecords) - val record = preKeyRecords.first() + val records = PreKeyUtil.generatePreKeys(context, 1) + PreKeyUtil.storePreKeyRecords(context, records) + val record = records.first() val database = databaseHelper.writableDatabase val values = ContentValues(2) values.put(Companion.hexEncodedPublicKey, hexEncodedPublicKey) values.put(preKeyID, record.id) - database.insertWithOnConflict(tableName, null, values, SQLiteDatabase.CONFLICT_REPLACE) + database.insertOrUpdate(tableName, values, "${Companion.hexEncodedPublicKey} = ?", arrayOf( hexEncodedPublicKey )) return record } } \ No newline at end of file