Replace usages of old getEncryptedUsernameFromLinkServerId for libsignal's lookUpUsernameLink.

This commit is contained in:
andrew-signal
2026-02-19 22:17:49 -05:00
committed by Cody Henthorne
parent caf2e555dd
commit 402f49edd9
3 changed files with 57 additions and 53 deletions

View File

@@ -4,6 +4,7 @@ import android.text.TextUtils
import org.signal.core.util.Base64
import org.signal.core.util.Util
import org.signal.core.util.logging.Log
import org.signal.libsignal.net.RequestResult
import org.signal.libsignal.usernames.BaseUsernameException
import org.signal.libsignal.usernames.Username
import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredential
@@ -26,7 +27,6 @@ import org.thoughtcrime.securesms.profiles.manage.UsernameRepository
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.ProfileUtil
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.NetworkResultUtil
import org.whispersystems.signalservice.api.crypto.InvalidCiphertextException
import org.whispersystems.signalservice.api.crypto.ProfileCipher
import org.whispersystems.signalservice.api.profiles.ProfileAndCredential
@@ -384,9 +384,7 @@ class RefreshOwnProfileJob private constructor(parameters: Parameters) : BaseJob
val displayBadgesOnProfile = SignalStore.inAppPayments.getDisplayBadgesOnProfile()
Log.d(
TAG,
"Detected mixed visibility of badges. Telling the server to mark them all " +
(if (displayBadgesOnProfile) "" else "not") +
" visible.",
"Detected mixed visibility of badges. Telling the server to mark them all ${if (displayBadgesOnProfile) "" else "not"} visible.",
true
)
@@ -399,8 +397,6 @@ class RefreshOwnProfileJob private constructor(parameters: Parameters) : BaseJob
}
private fun checkUsernameIsInSync() {
var validated = false
try {
val localUsername = SignalStore.account.username
@@ -429,32 +425,37 @@ class RefreshOwnProfileJob private constructor(parameters: Parameters) : BaseJob
return
}
try {
val localUsernameLink = SignalStore.account.usernameLink
val localUsernameLink = SignalStore.account.usernameLink ?: return
if (localUsernameLink != null) {
val remoteEncryptedUsername = NetworkResultUtil.toBasicLegacy<ByteArray>(SignalNetwork.username.getEncryptedUsernameFromLinkServerId(localUsernameLink.serverId))
val combinedLink = Username.UsernameLink(localUsernameLink.entropy, remoteEncryptedUsername)
val remoteUsername = Username.fromLink(combinedLink)
when (val usernameFetchResult = SignalNetwork.username.getDecryptedUsernameFromLinkServerIdAndEntropy(localUsernameLink.serverId, localUsernameLink.entropy)) {
is RequestResult.Success -> {
val remoteUsername = usernameFetchResult.result
if (remoteUsername == null) {
Log.w(TAG, "Local username link was not found on remote. Marking as mismatched.")
UsernameRepository.onUsernameLinkMismatchDetected()
return
}
if (remoteUsername.getUsername() != SignalStore.account.username) {
Log.w(TAG, "The remote username decrypted ok, but the decrypted username did not match our local username!")
UsernameRepository.onUsernameLinkMismatchDetected()
} else {
Log.d(TAG, "Username link validated.")
return
}
validated = true
Log.d(TAG, "Username link validated.")
UsernameRepository.onUsernameConsistencyValidated()
}
is RequestResult.NonSuccess -> {
Log.w(TAG, "Failed to decrypt username link using our local link data. ${usernameFetchResult.error}")
UsernameRepository.onUsernameLinkMismatchDetected()
}
is RequestResult.RetryableNetworkError -> {
Log.w(TAG, "Failed perform synchronization check during the username link phase, skipping.", usernameFetchResult.networkError)
}
is RequestResult.ApplicationError -> {
throw usernameFetchResult.cause
}
} catch (e: IOException) {
Log.w(TAG, "Failed perform synchronization check during the username link phase.", e)
} catch (e: BaseUsernameException) {
Log.w(TAG, "Failed to decrypt username link using the remote encrypted username and our local entropy!", e)
UsernameRepository.onUsernameLinkMismatchDetected()
}
if (validated) {
UsernameRepository.onUsernameConsistencyValidated()
}
}

View File

@@ -14,6 +14,8 @@ import org.signal.core.util.toByteArray
import org.signal.libsignal.net.RequestResult
import org.signal.libsignal.usernames.BaseUsernameException
import org.signal.libsignal.usernames.Username
import org.signal.libsignal.usernames.UsernameLinkInvalidEntropyDataLength
import org.signal.libsignal.usernames.UsernameLinkInvalidLinkData
import org.thoughtcrime.securesms.components.settings.app.usernamelinks.main.UsernameLinkResetResult
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.dependencies.AppDependencies
@@ -234,25 +236,24 @@ object UsernameRepository {
return Single
.fromCallable {
val encryptedUsername = when (val result = SignalNetwork.username.getEncryptedUsernameFromLinkServerId(components.serverId)) {
is NetworkResult.Success -> result.result
is NetworkResult.StatusCodeError -> {
return@fromCallable when (result.code) {
404 -> UsernameLinkConversionResult.NotFound(null)
422 -> UsernameLinkConversionResult.Invalid
else -> UsernameLinkConversionResult.NetworkError
val username = when (val result = SignalNetwork.username.getDecryptedUsernameFromLinkServerIdAndEntropy(components.serverId, components.entropy)) {
is RequestResult.Success ->
result.result ?: return@fromCallable UsernameLinkConversionResult.NotFound(null)
is RequestResult.NonSuccess -> {
when (result.error) {
is UsernameLinkInvalidEntropyDataLength,
is UsernameLinkInvalidLinkData -> {
Log.w(TAG, "[convertLinkToUsername] Bad username conversion. ${result.error}")
return@fromCallable UsernameLinkConversionResult.Invalid
}
}
}
is NetworkResult.NetworkError -> return@fromCallable UsernameLinkConversionResult.NetworkError
is NetworkResult.ApplicationError -> throw result.throwable
}
val link = Username.UsernameLink(components.entropy, encryptedUsername)
val username: Username = try {
Username.fromLink(link)
} catch (e: BaseUsernameException) {
Log.w(TAG, "[convertLinkToUsername] Bad username conversion.", e)
return@fromCallable UsernameLinkConversionResult.Invalid
is RequestResult.RetryableNetworkError -> {
return@fromCallable UsernameLinkConversionResult.NetworkError
}
is RequestResult.ApplicationError -> {
throw result.cause
}
}
when (val result = SignalNetwork.username.getAciByUsername(username)) {