diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/testing/BobClient.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/testing/BobClient.kt
index 3eb4d602be..a648647344 100644
--- a/app/src/androidTest/java/org/thoughtcrime/securesms/testing/BobClient.kt
+++ b/app/src/androidTest/java/org/thoughtcrime/securesms/testing/BobClient.kt
@@ -9,6 +9,7 @@ import org.signal.libsignal.protocol.SignalProtocolAddress
import org.signal.libsignal.protocol.ecc.ECKeyPair
import org.signal.libsignal.protocol.groups.state.SenderKeyRecord
import org.signal.libsignal.protocol.state.IdentityKeyStore
+import org.signal.libsignal.protocol.state.IdentityKeyStore.IdentityChange
import org.signal.libsignal.protocol.state.KyberPreKeyRecord
import org.signal.libsignal.protocol.state.PreKeyBundle
import org.signal.libsignal.protocol.state.PreKeyRecord
@@ -137,7 +138,7 @@ class BobClient(val serviceId: ServiceId, val e164: String, val identityKeyPair:
override fun getLocalRegistrationId(): Int = registrationId
override fun isTrustedIdentity(address: SignalProtocolAddress?, identityKey: IdentityKey?, direction: IdentityKeyStore.Direction?): Boolean = true
override fun loadSession(address: SignalProtocolAddress?): SessionRecord = aliceSessionRecord ?: SessionRecord()
- override fun saveIdentity(address: SignalProtocolAddress?, identityKey: IdentityKey?): Boolean = false
+ override fun saveIdentity(address: SignalProtocolAddress?, identityKey: IdentityKey?): IdentityKeyStore.IdentityChange = IdentityChange.NEW_OR_UNCHANGED
override fun storeSession(address: SignalProtocolAddress?, record: SessionRecord?) {
aliceSessionRecord = record
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java
index 7eebcb0731..c1832b17b1 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java
@@ -63,8 +63,12 @@ public class SignalBaseIdentityKeyStore {
return SignalStore.account().getRegistrationId();
}
- public boolean saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) {
- return saveIdentity(address, identityKey, false) == SaveResult.UPDATE;
+ public IdentityKeyStore.IdentityChange saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) {
+ switch (saveIdentity(address, identityKey, false)) {
+ case NEW, NO_CHANGE, NON_BLOCKING_APPROVAL_REQUIRED -> { return IdentityKeyStore.IdentityChange.NEW_OR_UNCHANGED; }
+ case UPDATE -> { return IdentityKeyStore.IdentityChange.REPLACED_EXISTING; }
+ }
+ throw new AssertionError("unhandled save result");
}
public @NonNull SaveResult saveIdentity(SignalProtocolAddress address, IdentityKey identityKey, boolean nonBlockingApproval) {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalIdentityKeyStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalIdentityKeyStore.java
index b632ce96c6..6d02db05c0 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalIdentityKeyStore.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalIdentityKeyStore.java
@@ -42,7 +42,7 @@ public class SignalIdentityKeyStore implements IdentityKeyStore {
}
@Override
- public boolean saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) {
+ public IdentityChange saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) {
return baseStore.saveIdentity(address, identityKey);
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalServiceAccountDataStoreImpl.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalServiceAccountDataStoreImpl.java
index 549678a6cb..9a7a92ae26 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalServiceAccountDataStoreImpl.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalServiceAccountDataStoreImpl.java
@@ -68,7 +68,7 @@ public class SignalServiceAccountDataStoreImpl implements SignalServiceAccountDa
}
@Override
- public boolean saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) {
+ public IdentityChange saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) {
return identityKeyStore.saveIdentity(address, identityKey);
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/protocol/BufferedIdentityKeyStore.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/protocol/BufferedIdentityKeyStore.kt
index 79914ed550..9e594b3b82 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/messages/protocol/BufferedIdentityKeyStore.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/messages/protocol/BufferedIdentityKeyStore.kt
@@ -4,6 +4,7 @@ import org.signal.libsignal.protocol.IdentityKey
import org.signal.libsignal.protocol.IdentityKeyPair
import org.signal.libsignal.protocol.SignalProtocolAddress
import org.signal.libsignal.protocol.state.IdentityKeyStore
+import org.signal.libsignal.protocol.state.IdentityKeyStore.IdentityChange
import org.thoughtcrime.securesms.database.SignalDatabase
import org.whispersystems.signalservice.api.SignalServiceAccountDataStore
import org.whispersystems.signalservice.api.push.ServiceId
@@ -30,16 +31,16 @@ class BufferedIdentityKeyStore(
return selfRegistrationId
}
- override fun saveIdentity(address: SignalProtocolAddress, identityKey: IdentityKey): Boolean {
+ override fun saveIdentity(address: SignalProtocolAddress, identityKey: IdentityKey): IdentityChange {
val existing: IdentityKey? = getIdentity(address)
store[address] = identityKey
return if (identityKey != existing) {
updatedKeys[address] = identityKey
- true
+ IdentityChange.REPLACED_EXISTING
} else {
- false
+ IdentityChange.NEW_OR_UNCHANGED
}
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/protocol/BufferedSignalServiceAccountDataStore.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/protocol/BufferedSignalServiceAccountDataStore.kt
index 33ffcdf3af..aedb9dc956 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/messages/protocol/BufferedSignalServiceAccountDataStore.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/messages/protocol/BufferedSignalServiceAccountDataStore.kt
@@ -5,6 +5,7 @@ import org.signal.libsignal.protocol.IdentityKeyPair
import org.signal.libsignal.protocol.SignalProtocolAddress
import org.signal.libsignal.protocol.groups.state.SenderKeyRecord
import org.signal.libsignal.protocol.state.IdentityKeyStore
+import org.signal.libsignal.protocol.state.IdentityKeyStore.IdentityChange
import org.signal.libsignal.protocol.state.KyberPreKeyRecord
import org.signal.libsignal.protocol.state.PreKeyRecord
import org.signal.libsignal.protocol.state.SessionRecord
@@ -41,7 +42,7 @@ class BufferedSignalServiceAccountDataStore(selfServiceId: ServiceId) : SignalSe
return identityStore.localRegistrationId
}
- override fun saveIdentity(address: SignalProtocolAddress, identityKey: IdentityKey): Boolean {
+ override fun saveIdentity(address: SignalProtocolAddress, identityKey: IdentityKey): IdentityChange {
return identityStore.saveIdentity(address, identityKey)
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java
index bd754cd60a..b175e016c2 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java
@@ -14,6 +14,7 @@ import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.SignalProtocolAddress;
+import org.signal.libsignal.protocol.state.IdentityKeyStore;
import org.signal.libsignal.protocol.state.SessionRecord;
import org.signal.libsignal.protocol.state.SessionStore;
import org.thoughtcrime.securesms.R;
@@ -172,7 +173,7 @@ public final class IdentityUtil {
SessionStore sessionStore = AppDependencies.getProtocolStore().aci();
SignalProtocolAddress address = new SignalProtocolAddress(user, SignalServiceAddress.DEFAULT_DEVICE_ID);
- if (AppDependencies.getProtocolStore().aci().identities().saveIdentity(address, identityKey)) {
+ if (AppDependencies.getProtocolStore().aci().identities().saveIdentity(address, identityKey) == IdentityKeyStore.IdentityChange.REPLACED_EXISTING) {
if (sessionStore.containsSession(address)) {
SessionRecord sessionRecord = sessionStore.loadSession(address);
sessionRecord.archiveCurrentState();
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e440850611..2c1370df3e 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -13,7 +13,7 @@ androidx-window = "1.3.0"
glide = "4.15.1"
gradle = "8.9.0"
kotlin = "2.1.0"
-libsignal-client = "0.70.1"
+libsignal-client = "0.71.0"
mp4parser = "1.9.39"
android-gradle-plugin = "8.7.2"
accompanist = "0.28.0"
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index e93dda656d..fbbf5dacdc 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -7172,20 +7172,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
diff --git a/microbenchmark/src/androidTest/java/org/signal/util/InMemorySignalServiceAccountDataStore.kt b/microbenchmark/src/androidTest/java/org/signal/util/InMemorySignalServiceAccountDataStore.kt
index bbf2c96cbc..cc23a386e8 100644
--- a/microbenchmark/src/androidTest/java/org/signal/util/InMemorySignalServiceAccountDataStore.kt
+++ b/microbenchmark/src/androidTest/java/org/signal/util/InMemorySignalServiceAccountDataStore.kt
@@ -5,6 +5,7 @@ import org.signal.libsignal.protocol.IdentityKeyPair
import org.signal.libsignal.protocol.SignalProtocolAddress
import org.signal.libsignal.protocol.groups.state.SenderKeyRecord
import org.signal.libsignal.protocol.state.IdentityKeyStore
+import org.signal.libsignal.protocol.state.IdentityKeyStore.IdentityChange
import org.signal.libsignal.protocol.state.KyberPreKeyRecord
import org.signal.libsignal.protocol.state.PreKeyRecord
import org.signal.libsignal.protocol.state.SessionRecord
@@ -34,10 +35,13 @@ class InMemorySignalServiceAccountDataStore : SignalServiceAccountDataStore {
return 1
}
- override fun saveIdentity(address: SignalProtocolAddress, identityKey: IdentityKey): Boolean {
- val hadPrevious = identities.containsKey(address)
- identities[address] = identityKey
- return hadPrevious
+ override fun saveIdentity(address: SignalProtocolAddress, identityKey: IdentityKey): IdentityChange {
+ val previous = identities.put(address, identityKey)
+ return if (previous == null || previous == identityKey) {
+ IdentityChange.NEW_OR_UNCHANGED
+ } else {
+ IdentityChange.REPLACED_EXISTING
+ }
}
override fun isTrustedIdentity(address: SignalProtocolAddress?, identityKey: IdentityKey?, direction: IdentityKeyStore.Direction?): Boolean {