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 {