crypto: Support SAS verification up to showing emojis

This commit is contained in:
Damir Jelić 2021-06-28 11:37:14 +02:00
parent e97ce33ed9
commit 6649aaca2e
5 changed files with 83 additions and 25 deletions

View File

@ -185,11 +185,17 @@ internal class VerificationRequest(
return this.inner.isReady
}
suspend fun startSasVerification(): StartSasResult? {
suspend fun startSasVerification(): Pair<OutgoingVerificationRequest, SasVerification>? {
refreshData()
return withContext(Dispatchers.IO) {
machine.startSasVerification(inner.otherUserId, inner.flowId)
val response = machine.startSasVerification(inner.otherUserId, inner.flowId)
if (response != null) {
Pair(response.request, SasVerification(machine, response.sas))
} else {
null
}
}
}
@ -325,7 +331,22 @@ public class SasVerification(private val machine: InnerMachine, private var inne
override var state: VerificationTxState
get() {
TODO()
refreshData()
return when {
this.inner.canBePresented -> {
VerificationTxState.ShortCodeReady
}
this.inner.isCancelled -> {
// TODO fetch the cancel code from the rust side
VerificationTxState.Cancelled(CancelCode.User, false)
}
this.inner.isDone -> {
VerificationTxState.Verified
}
else -> {
VerificationTxState.Started
}
}
}
set(v) {
this.stateField = v
@ -353,11 +374,16 @@ public class SasVerification(private val machine: InnerMachine, private var inne
}
override fun supportsDecimal(): Boolean {
return false
// This is ignored anyways, throw it away?
// The spec also mandates that devices support
// at least decimal and the rust-sdk cancels if
// devices don't support it
return true
}
override fun supportsEmoji(): Boolean {
return false
refreshData()
return this.inner.supportsEmoji
}
override fun userHasVerifiedShortCode() {

View File

@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto.verification
import android.os.Handler
import android.os.Looper
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
import kotlin.collections.set
import kotlinx.coroutines.runBlocking
@ -31,6 +32,8 @@ import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.message.MessageType
import org.matrix.android.sdk.internal.crypto.OlmMachine
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationDone
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationKey
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
import org.matrix.android.sdk.internal.di.MoshiProvider
@ -132,10 +135,14 @@ constructor(
EventType.KEY_VERIFICATION_START -> {}
EventType.KEY_VERIFICATION_CANCEL -> {}
EventType.KEY_VERIFICATION_ACCEPT -> {}
EventType.KEY_VERIFICATION_KEY -> {}
EventType.KEY_VERIFICATION_KEY -> {
onKeyReceived(event)
}
EventType.KEY_VERIFICATION_MAC -> {}
EventType.KEY_VERIFICATION_READY -> {}
EventType.KEY_VERIFICATION_DONE -> {}
EventType.KEY_VERIFICATION_DONE -> {
onDone(event)
}
MessageType.MSGTYPE_VERIFICATION_REQUEST -> {
onRequestReceived(event)
}
@ -143,10 +150,23 @@ constructor(
// ignore
}
}
event == event
// TODO get the sender and flow id out of the event and depending on the
// event type either get the verification request or verification and
// dispatch updates here
}
private fun onDone(event: Event) {
val content = event.getClearContent().toModel<KeyVerificationDone>() ?: return
val flowId = content.transactionId ?: return
val sender = event.senderId ?: return
val verification = this.getExistingTransaction(sender, flowId) ?: return
dispatchTxUpdated(verification)
}
private fun onKeyReceived(event: Event) {
val content = event.getClearContent().toModel<KeyVerificationKey>() ?: return
val flowId = content.transactionId ?: return
val sender = event.senderId ?: return
val verification = this.getExistingTransaction(sender, flowId) ?: return
dispatchTxUpdated(verification)
}
private fun onRequestReceived(event: Event) {
@ -166,9 +186,9 @@ constructor(
// TODO All this methods should be delegated to a TransactionStore
override fun getExistingTransaction(
otherUserId: String,
tid: String
tid: String,
): VerificationTransaction? {
return null
return this.olmMachine.getVerification(otherUserId, tid)
}
override fun getExistingVerificationRequests(
@ -210,10 +230,19 @@ constructor(
transactionId: String?
): String? {
// should check if already one (and cancel it)
if (method == VerificationMethod.SAS) {
// TODO start SAS verification here, don't we need to see if there's
// a request?
TODO()
return if (method == VerificationMethod.SAS) {
val flowId = transactionId ?: return null
val request = this.olmMachine.getVerificationRequest(otherUserId, flowId)
runBlocking {
val response = request?.startSasVerification()
if (response != null) {
sendRequest(response.first)
dispatchTxAdded(response.second)
response.second.transactionId
} else {
null
}
}
} else {
throw IllegalArgumentException("Unknown verification method")
}

View File

@ -23,12 +23,10 @@ version = "0.2.0"
features = ["lax_deserialize"]
[dependencies.matrix-sdk-common]
git = "https://github.com/matrix-org/matrix-rust-sdk/"
rev = "0fb3dedd1cd3b0766fa7378754480d52d38e8ef2"
version = "0.3.0"
[dependencies.matrix-sdk-crypto]
git = "https://github.com/matrix-org/matrix-rust-sdk/"
rev = "0fb3dedd1cd3b0766fa7378754480d52d38e8ef2"
version = "0.3.0"
features = ["sled_cryptostore"]
[dependencies.tokio]
@ -37,7 +35,7 @@ default_features = false
features = ["rt-multi-thread"]
[dependencies.ruma]
version = "*"
version = "0.2.0"
features = ["client-api"]
[build-dependencies]

View File

@ -53,6 +53,7 @@ pub struct Sas {
pub is_cancelled: bool,
pub is_done: bool,
pub can_be_presented: bool,
pub supports_emoji: bool,
pub timed_out: bool,
}
@ -71,6 +72,7 @@ impl From<InnerSas> for Sas {
is_done: sas.is_done(),
can_be_presented: sas.can_be_presented(),
timed_out: sas.timed_out(),
supports_emoji: sas.supports_emoji(),
}
}
}
@ -649,9 +651,11 @@ impl OlmMachine {
todo!()
}
pub fn get_verification(&self, user_id: &str, _flow_id: &str) -> Option<Sas> {
let _user_id = UserId::try_from(user_id).ok()?;
todo!()
pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option<Sas> {
let user_id = UserId::try_from(user_id).ok()?;
self.inner
.get_verification(&user_id, flow_id)
.and_then(|v| v.sas_v1().map(|s| s.into()))
}
pub fn start_sas_verification(

View File

@ -76,6 +76,7 @@ dictionary Sas {
boolean is_cancelled;
boolean can_be_presented;
boolean timed_out;
boolean supports_emoji;
};
dictionary VerificationRequest {