This commit is contained in:
Hugh Nimmo-Smith 2022-10-14 01:11:25 +01:00
parent c18439f99b
commit c00ce91214
7 changed files with 32 additions and 30 deletions

View file

@ -22,6 +22,10 @@ import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.rendezvous.channels.ECDHRendezvousChannel
import org.matrix.android.sdk.api.rendezvous.model.ECDHRendezvousCode
import org.matrix.android.sdk.api.rendezvous.model.RendezvousIntent
import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransport
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel
import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
@ -29,10 +33,6 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NA
import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
import org.matrix.android.sdk.api.util.MatrixJsonParser
import org.matrix.android.sdk.api.rendezvous.channels.ECDHRendezvousChannel
import org.matrix.android.sdk.api.rendezvous.model.ECDHRendezvousCode
import org.matrix.android.sdk.api.rendezvous.model.RendezvousIntent
import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransport
import timber.log.Timber
internal enum class PayloadType(val value: String) {
@ -80,6 +80,7 @@ class Rendezvous(
}
private val adapter = MatrixJsonParser.getMoshi().adapter(Payload::class.java)
// not yet implemented: RendezvousIntent.RECIPROCATE_LOGIN_ON_EXISTING_DEVICE
val ourIntent: RendezvousIntent = RendezvousIntent.LOGIN_ON_NEW_DEVICE
@ -98,7 +99,7 @@ class Rendezvous(
}
suspend fun startAfterScanningCode(): String? {
val checksum = channel.connect();
val checksum = channel.connect()
Timber.tag(TAG).i("Connected to secure channel with checksum: $checksum")
@ -107,7 +108,7 @@ class Rendezvous(
}
// get protocols
Timber.tag(TAG).i("Waiting for protocols");
Timber.tag(TAG).i("Waiting for protocols")
val protocolsResponse = receive()
if (protocolsResponse?.protocols == null || !protocolsResponse.protocols.contains("login_token")) {
@ -123,7 +124,7 @@ class Rendezvous(
}
suspend fun waitForLoginOnNewDevice(authenticationService: AuthenticationService): Session? {
Timber.tag(TAG).i("Waiting for login_token");
Timber.tag(TAG).i("Waiting for login_token")
val loginToken = receive()
@ -147,7 +148,7 @@ class Rendezvous(
val homeserver = loginToken?.homeserver ?: throw RuntimeException("No homeserver returned")
val login_token = loginToken.login_token ?: throw RuntimeException("No login token returned")
Timber.tag(TAG).i("Got login_token: $login_token for $homeserver");
Timber.tag(TAG).i("Got login_token: $login_token for $homeserver")
val hsConfig = HomeServerConnectionConfig(homeServerUri = Uri.parse(homeserver))
return authenticationService.loginUsingQrLoginToken(hsConfig, login_token)
@ -167,11 +168,11 @@ class Rendezvous(
val verifyingDeviceFromServer = crypto.getCryptoDeviceInfo(userId, verifyingDeviceId)
if (verifyingDeviceFromServer?.fingerprint() != verificationResponse.verifying_device_key) {
Timber.tag(TAG).w("Verifying device $verifyingDeviceId doesn't match: $verifyingDeviceFromServer")
return;
return
}
// set other device as verified
Timber.tag(TAG).i("Setting device $verifyingDeviceId as verified");
Timber.tag(TAG).i("Setting device $verifyingDeviceId as verified")
crypto.setDeviceVerification(DeviceTrustLevel(locallyVerified = true, crossSigningVerified = false), userId, verifyingDeviceId)
// TODO: what do we do with the master key?
@ -183,7 +184,7 @@ class Rendezvous(
// request secrets from the verifying device
Timber.tag(TAG).i("Requesting secrets from $verifyingDeviceId")
session.sharedSecretStorageService() .let {
session.sharedSecretStorageService().let {
it.requestSecret(MASTER_KEY_SSSS_NAME, verifyingDeviceId)
it.requestSecret(SELF_SIGNING_KEY_SSSS_NAME, verifyingDeviceId)
it.requestSecret(USER_SIGNING_KEY_SSSS_NAME, verifyingDeviceId)
@ -192,12 +193,12 @@ class Rendezvous(
}
private suspend fun receive(): Payload? {
val data = channel.receive()?: return null
val data = channel.receive() ?: return null
return adapter.fromJson(data.toString(Charsets.UTF_8))
}
private suspend fun send(payload: Payload) {
channel.send(adapter.toJson(payload).toByteArray(Charsets.UTF_8));
channel.send(adapter.toJson(payload).toByteArray(Charsets.UTF_8))
}
suspend fun cancel(reason: RendezvousFailureReason) {

View file

@ -20,25 +20,30 @@ import org.matrix.android.sdk.api.rendezvous.model.ECDHRendezvousCode
import org.matrix.android.sdk.api.rendezvous.model.RendezvousIntent
interface RendezvousChannel {
var transport: RendezvousTransport;
var transport: RendezvousTransport
/**
* @returns the checksum/confirmation digits to be shown to the user
*/
suspend fun connect(): String
/**
* Send a payload via the channel.
* @param data payload to send
*/
suspend fun send(data: ByteArray)
/**
* Receive a payload from the channel.
* @returns the received payload
*/
suspend fun receive(): ByteArray?
/**
* @returns a representation of the channel that can be encoded in a QR or similar
*/
suspend fun close()
// TODO: this should be transport independent in the future
suspend fun generateCode(intent: RendezvousIntent): ECDHRendezvousCode
suspend fun cancel(reason: RendezvousFailureReason)

View file

@ -20,10 +20,10 @@ import okhttp3.MediaType
import org.matrix.android.sdk.api.rendezvous.model.RendezvousTransportDetails
interface RendezvousTransport {
var ready: Boolean;
var onCancelled: ((reason: RendezvousFailureReason) -> Unit)?;
suspend fun details(): RendezvousTransportDetails;
suspend fun send(contentType: MediaType, data: ByteArray);
suspend fun receive(): ByteArray?;
suspend fun cancel(reason: RendezvousFailureReason);
var ready: Boolean
var onCancelled: ((reason: RendezvousFailureReason) -> Unit)?
suspend fun details(): RendezvousTransportDetails
suspend fun send(contentType: MediaType, data: ByteArray)
suspend fun receive(): ByteArray?
suspend fun cancel(reason: RendezvousFailureReason)
}

View file

@ -21,10 +21,8 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import okhttp3.MediaType.Companion.toMediaType
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.util.MatrixJsonParser
import org.matrix.android.sdk.internal.extensions.toUnsignedInt
import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
import org.matrix.android.sdk.api.rendezvous.RendezvousChannel
import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
import org.matrix.android.sdk.api.rendezvous.RendezvousTransport
import org.matrix.android.sdk.api.rendezvous.model.ECDHRendezvous
import org.matrix.android.sdk.api.rendezvous.model.ECDHRendezvousCode
@ -32,8 +30,9 @@ import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
import org.matrix.android.sdk.api.rendezvous.model.RendezvousIntent
import org.matrix.android.sdk.api.rendezvous.model.SecureRendezvousChannelAlgorithm
import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransportDetails
import org.matrix.android.sdk.api.util.MatrixJsonParser
import org.matrix.android.sdk.internal.extensions.toUnsignedInt
import org.matrix.olm.OlmSAS
import timber.log.Timber
import java.security.SecureRandom
import java.util.LinkedList
import javax.crypto.Cipher
@ -72,7 +71,7 @@ const val KEY_SPEC = "AES"
* Implements X25519 ECDH key agreement and AES-256-GCM encryption channel as per MSC3903:
* https://github.com/matrix-org/matrix-spec-proposals/pull/3903
*/
class ECDHRendezvousChannel(override var transport: RendezvousTransport, theirPublicKeyBase64: String?): RendezvousChannel {
class ECDHRendezvousChannel(override var transport: RendezvousTransport, theirPublicKeyBase64: String?) : RendezvousChannel {
private var olmSAS: OlmSAS?
private val ourPublicKey: ByteArray
private val ecdhAdapter = MatrixJsonParser.getMoshi().adapter(ECDHPayload::class.java)

View file

@ -18,5 +18,4 @@ package org.matrix.android.sdk.api.rendezvous.model
import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
class RendezvousError(val description: String, val reason: RendezvousFailureReason): RuntimeException(description) {
}
class RendezvousError(val description: String, val reason: RendezvousFailureReason) : RuntimeException(description)

View file

@ -36,7 +36,7 @@ private val TAG = LoggerTag(SimpleHttpRendezvousTransport::class.java.simpleName
@JsonClass(generateAdapter = true)
data class SimpleHttpRendezvousTransportDetails(
@Json val uri: String
): RendezvousTransportDetails(type = RendezvousTransportType.MSC3886_SIMPLE_HTTP_V1)
) : RendezvousTransportDetails(type = RendezvousTransportType.MSC3886_SIMPLE_HTTP_V1)
/**
* Implementation of the Simple HTTP transport MSC3886: https://github.com/matrix-org/matrix-spec-proposals/pull/3886

View file

@ -26,11 +26,9 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.configureAndStart
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.home.HomeActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.rendezvous.Rendezvous
import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
import timber.log.Timber