mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 00:59:49 +01:00
Add key transparency backend support.
This commit is contained in:
committed by
Greyson Parrelli
parent
26739491a5
commit
423b8c942c
@@ -369,6 +369,9 @@ object AppDependencies {
|
||||
val donationsApi: DonationsApi
|
||||
get() = networkModule.donationsApi
|
||||
|
||||
val keyTransparencyApi: KeyTransparencyApi
|
||||
get() = networkModule.keyTransparencyApi
|
||||
|
||||
@JvmStatic
|
||||
val okHttpClient: OkHttpClient
|
||||
get() = networkModule.okHttpClient
|
||||
@@ -463,5 +466,6 @@ object AppDependencies {
|
||||
fun provideRemoteConfigApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, pushServiceSocket: PushServiceSocket): RemoteConfigApi
|
||||
fun provideDonationsApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket): DonationsApi
|
||||
fun provideSvrBApi(libSignalNetwork: Network): SvrBApi
|
||||
fun provideKeyTransparencyApi(unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket): KeyTransparencyApi
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +579,11 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
|
||||
return new SvrBApi(libSignalNetwork);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull KeyTransparencyApi provideKeyTransparencyApi(@NonNull SignalWebSocket.UnauthenticatedWebSocket unauthWebSocket) {
|
||||
return new KeyTransparencyApi(unauthWebSocket);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class DynamicCredentialsProvider implements CredentialsProvider {
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
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.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
|
||||
import org.thoughtcrime.securesms.database.model.KeyTransparencyStore
|
||||
import org.whispersystems.signalservice.api.websocket.SignalWebSocket
|
||||
|
||||
/**
|
||||
* Operations used when interacting with [org.signal.libsignal.net.KeyTransparencyClient]
|
||||
*/
|
||||
class KeyTransparencyApi(private val unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket) {
|
||||
|
||||
/**
|
||||
* 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, keyTransparencyStore: KeyTransparencyStore): RequestResult<Unit, KeyTransparencyError> {
|
||||
return unauthWebSocket.runCatchingWithUnauthChatConnection { chatConnection ->
|
||||
chatConnection.keyTransparencyClient().search(aci, aciIdentityKey, e164, unidentifiedAccessKey, null, 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()
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, keyTransparencyStore: KeyTransparencyStore): RequestResult<Unit, KeyTransparencyError> {
|
||||
return unauthWebSocket.runCatchingWithUnauthChatConnection { chatConnection ->
|
||||
chatConnection.keyTransparencyClient().monitor(monitorMode, aci, aciIdentityKey, e164, unidentifiedAccessKey, null, 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
|
||||
@@ -225,6 +225,10 @@ class NetworkDependenciesModule(
|
||||
provider.provideSvrBApi(libsignalNetwork)
|
||||
}
|
||||
|
||||
val keyTransparencyApi: KeyTransparencyApi by lazy {
|
||||
provider.provideKeyTransparencyApi(unauthWebSocket)
|
||||
}
|
||||
|
||||
val okHttpClient: OkHttpClient by lazy {
|
||||
OkHttpClient.Builder()
|
||||
.addInterceptor(StandardUserAgentInterceptor())
|
||||
|
||||
Reference in New Issue
Block a user