From 3af8b6050ce6ec277e1b0242fe4966e2c73489fb Mon Sep 17 00:00:00 2001 From: andrew-signal Date: Tue, 3 Mar 2026 11:02:30 -0500 Subject: [PATCH] Bump to libsignal v0.88.0. --- .../dependencies/KeyTransparencyApi.kt | 65 +------------------ .../securesms/jobs/CheckKeyTransparencyJob.kt | 41 +++++------- .../verify/VerifySafetyNumberRepository.kt | 14 ++-- gradle/libs.versions.toml | 2 +- gradle/verification-metadata.xml | 20 +++--- 5 files changed, 37 insertions(+), 105 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/KeyTransparencyApi.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/KeyTransparencyApi.kt index 51c4c62b31..0f99154983 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/KeyTransparencyApi.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/KeyTransparencyApi.kt @@ -1,18 +1,8 @@ package org.thoughtcrime.securesms.dependencies -import org.signal.libsignal.internal.mapWithCancellation import org.signal.libsignal.keytrans.KeyTransparencyException -import org.signal.libsignal.keytrans.VerificationFailedException -import org.signal.libsignal.net.AppExpiredException -import org.signal.libsignal.net.BadRequestError -import org.signal.libsignal.net.ChatServiceException import org.signal.libsignal.net.KeyTransparency -import org.signal.libsignal.net.NetworkException -import org.signal.libsignal.net.NetworkProtocolException import org.signal.libsignal.net.RequestResult -import org.signal.libsignal.net.RetryLaterException -import org.signal.libsignal.net.ServerSideErrorException -import org.signal.libsignal.net.TimeoutException import org.signal.libsignal.net.getOrError import org.signal.libsignal.protocol.IdentityKey import org.signal.libsignal.protocol.ServiceId @@ -27,69 +17,18 @@ class KeyTransparencyApi(private val unauthWebSocket: SignalWebSocket.Unauthenti /** * Uses KT to verify recipient. This is an unauthenticated and should only be called the first time KT is being requested for this recipient. */ - suspend fun search(aci: ServiceId.Aci, aciIdentityKey: IdentityKey, e164: String?, unidentifiedAccessKey: ByteArray?, usernameHash: ByteArray?, keyTransparencyStore: KeyTransparencyStore): RequestResult { + suspend fun search(aci: ServiceId.Aci, aciIdentityKey: IdentityKey, e164: String?, unidentifiedAccessKey: ByteArray?, usernameHash: ByteArray?, keyTransparencyStore: KeyTransparencyStore): RequestResult { return unauthWebSocket.runCatchingWithUnauthChatConnection { chatConnection -> chatConnection.keyTransparencyClient().search(aci, aciIdentityKey, e164, unidentifiedAccessKey, usernameHash, keyTransparencyStore) - .mapWithCancellation( - onSuccess = { RequestResult.Success(Unit) }, - onError = { throwable -> - when (throwable) { - is VerificationFailedException, - is KeyTransparencyException, - is AppExpiredException, - is IllegalArgumentException -> { - RequestResult.NonSuccess(KeyTransparencyError(throwable)) - } - is ChatServiceException, - is NetworkException, - is NetworkProtocolException -> { - RequestResult.RetryableNetworkError(throwable, null) - } - is RetryLaterException -> { - RequestResult.RetryableNetworkError(throwable, throwable.duration) - } - else -> { - RequestResult.ApplicationError(throwable) - } - } - } - ) }.getOrError() } /** * Monitors KT to verify recipient. This is an unauthenticated and should only be called following a successful [search]. */ - suspend fun monitor(monitorMode: KeyTransparency.MonitorMode, aci: ServiceId.Aci, aciIdentityKey: IdentityKey, e164: String?, unidentifiedAccessKey: ByteArray?, usernameHash: ByteArray?, keyTransparencyStore: KeyTransparencyStore): RequestResult { + suspend fun monitor(monitorMode: KeyTransparency.MonitorMode, aci: ServiceId.Aci, aciIdentityKey: IdentityKey, e164: String?, unidentifiedAccessKey: ByteArray?, usernameHash: ByteArray?, keyTransparencyStore: KeyTransparencyStore): RequestResult { return unauthWebSocket.runCatchingWithUnauthChatConnection { chatConnection -> chatConnection.keyTransparencyClient().monitor(monitorMode, aci, aciIdentityKey, e164, unidentifiedAccessKey, usernameHash, keyTransparencyStore) - .mapWithCancellation( - onSuccess = { RequestResult.Success(Unit) }, - onError = { throwable -> - when (throwable) { - is TimeoutException, - is ServerSideErrorException, - is NetworkException, - is NetworkProtocolException -> { - RequestResult.RetryableNetworkError(throwable, null) - } - is RetryLaterException -> { - RequestResult.RetryableNetworkError(throwable, throwable.duration) - } - is VerificationFailedException, - is KeyTransparencyException, - is AppExpiredException, - is IllegalArgumentException -> { - RequestResult.NonSuccess(KeyTransparencyError(throwable)) - } - else -> { - RequestResult.ApplicationError(throwable) - } - } - } - ) }.getOrError() } } - -data class KeyTransparencyError(val exception: Throwable) : BadRequestError diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckKeyTransparencyJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckKeyTransparencyJob.kt index 25e566918d..b4a0121ede 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckKeyTransparencyJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/CheckKeyTransparencyJob.kt @@ -1,9 +1,6 @@ package org.thoughtcrime.securesms.jobs import org.signal.core.util.logging.Log -import org.signal.libsignal.keytrans.KeyTransparencyException -import org.signal.libsignal.keytrans.VerificationFailedException -import org.signal.libsignal.net.AppExpiredException import org.signal.libsignal.net.KeyTransparency import org.signal.libsignal.net.RequestResult import org.signal.libsignal.usernames.Username @@ -142,28 +139,15 @@ class CheckKeyTransparencyJob private constructor( } is RequestResult.NonSuccess -> { - if (result.error.exception is IllegalArgumentException) { - Log.w(TAG, "KT store was corrupted. Restarting and then retrying.") - SignalStore.account.distinguishedHead = null - SignalDatabase.recipients.clearSelfKeyTransparencyData() - Result.retry(defaultBackoff()) - } else if (result.error.exception is VerificationFailedException || result.error.exception is KeyTransparencyException) { - if (!showFailure) { - Log.w(TAG, "Verification failure. Enqueuing this job again to run again a day.") - StorageSyncJob.forRemoteChange() - enqueueFollowingFailure() - } else { - Log.w(TAG, "Second verification failure. Showing failure sheet.") - markFailure() - } - Result.failure() - } else if (result.error.exception is AppExpiredException) { - Result.failure() + if (!showFailure) { + Log.w(TAG, "Verification failure. Enqueuing this job again to run again a day.") + StorageSyncJob.forRemoteChange() + enqueueFollowingFailure() } else { - Log.w(TAG, "Unknown nonsuccess failure. Showing failure sheet.") + Log.w(TAG, "Second verification failure. Showing failure sheet.") markFailure() - Result.failure() } + Result.failure() } is RequestResult.RetryableNetworkError -> { if (result.retryAfter != null) { @@ -173,9 +157,16 @@ class CheckKeyTransparencyJob private constructor( } } is RequestResult.ApplicationError -> { - Log.w(TAG, "Unknown application failure. Showing failure sheet.") - markFailure() - Result.failure() + if (result.cause is IllegalArgumentException) { + Log.w(TAG, "KT store was corrupted. Restarting and then retrying.") + SignalStore.account.distinguishedHead = null + SignalDatabase.recipients.clearSelfKeyTransparencyData() + Result.retry(defaultBackoff()) + } else { + Log.w(TAG, "Unknown application failure. Showing failure sheet.") + markFailure() + Result.failure() + } } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberRepository.kt index 5eb3037c43..9fbdc5722a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/verify/VerifySafetyNumberRepository.kt @@ -50,11 +50,7 @@ object VerifySafetyNumberRepository { VerifyResult.Success } is RequestResult.NonSuccess -> { - if (result.error.exception is IllegalArgumentException) { - VerifyResult.CorruptedFailure - } else { - VerifyResult.UnretryableFailure - } + VerifyResult.UnretryableFailure } is RequestResult.RetryableNetworkError -> { if (result.retryAfter != null) { @@ -63,7 +59,13 @@ object VerifySafetyNumberRepository { VerifyResult.UnretryableFailure } } - is RequestResult.ApplicationError -> VerifyResult.UnretryableFailure + is RequestResult.ApplicationError -> { + if (result.cause is IllegalArgumentException) { + VerifyResult.CorruptedFailure + } else { + VerifyResult.UnretryableFailure + } + } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3192b93e54..49daf59f95 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -26,7 +26,7 @@ androidx-navigation = "2.8.5" androidx-navigation3-core = "1.0.0" androidx-window = "1.3.0" glide = "4.15.1" -libsignal-client = "0.87.5" +libsignal-client = "0.88.0" mp4parser = "1.9.39" accompanist = "0.28.0" nanohttpd = "2.3.1" diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 4281dfda69..a68501b188 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -16740,20 +16740,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html - - - + + + - - + + - - - + + + - - + +