crypto: Bind more verification methods and types

This commit is contained in:
Damir Jelić 2021-05-07 19:36:37 +02:00
parent a144b1f7b5
commit 5ad596c3bc
6 changed files with 144 additions and 15 deletions

View file

@ -28,12 +28,14 @@ import org.matrix.android.sdk.api.listeners.ProgressListener
import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation
import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo
import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode
import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.session.sync.model.DeviceListResponse import org.matrix.android.sdk.internal.session.sync.model.DeviceListResponse
import org.matrix.android.sdk.internal.session.sync.model.DeviceOneTimeKeysCountSyncResponse import org.matrix.android.sdk.internal.session.sync.model.DeviceOneTimeKeysCountSyncResponse
@ -41,6 +43,8 @@ import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse
import timber.log.Timber import timber.log.Timber
import uniffi.olm.CryptoStoreErrorException import uniffi.olm.CryptoStoreErrorException
import uniffi.olm.DecryptionErrorException import uniffi.olm.DecryptionErrorException
import uniffi.olm.Sas as InnerSas
import uniffi.olm.OutgoingVerificationRequest
import uniffi.olm.Device import uniffi.olm.Device
import uniffi.olm.DeviceLists import uniffi.olm.DeviceLists
import uniffi.olm.KeyRequestPair import uniffi.olm.KeyRequestPair
@ -122,6 +126,65 @@ internal class DeviceUpdateObserver {
} }
} }
internal class Sas(private val machine: InnerMachine, private var inner: InnerSas) {
private fun refreshData() {
val sas = this.machine.getVerification(this.inner.flowId)
if (sas != null) {
this.inner = sas
}
return
}
fun isCanceled(): Boolean {
refreshData()
return this.inner.isCanceled
}
fun isDone(): Boolean {
refreshData()
return this.inner.isDone
}
fun timedOut(): Boolean {
refreshData()
return this.inner.timedOut
}
fun canBePresented(): Boolean {
refreshData()
return this.inner.canBePresented
}
fun accept(): OutgoingVerificationRequest? {
return this.machine.acceptVerification(inner.flowId)
}
@Throws(CryptoStoreErrorException::class)
suspend fun confirm(): OutgoingVerificationRequest? = withContext(Dispatchers.IO) {
machine.confirmVerification(inner.flowId)
}
fun cancel(): OutgoingVerificationRequest? {
return this.machine.cancelVerification(inner.flowId)
}
fun emoji(): List<EmojiRepresentation> {
val emojiIndex = this.machine.getEmojiIndex(this.inner.flowId)
return if (emojiIndex != null) {
emojiIndex.map { getEmojiForCode(it) }
} else {
listOf()
}
}
fun decimals(): List<Int>? {
return this.machine.getDecimals(this.inner.flowId)
}
}
internal class OlmMachine(user_id: String, device_id: String, path: File, deviceObserver: DeviceUpdateObserver) { internal class OlmMachine(user_id: String, device_id: String, path: File, deviceObserver: DeviceUpdateObserver) {
private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString())
private val deviceUpdateObserver = deviceObserver private val deviceUpdateObserver = deviceObserver
@ -533,4 +596,17 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
fun discardRoomKey(roomId: String) { fun discardRoomKey(roomId: String) {
runBlocking { inner.discardRoomKey(roomId) } runBlocking { inner.discardRoomKey(roomId) }
} }
/**
* Get an active verification
*/
fun getVerification(flowId: String): Sas? {
val sas = this.inner.getVerification(flowId)
return if (sas == null) {
null
} else {
Sas(this.inner, sas)
}
}
} }

View file

@ -1,7 +1,7 @@
use ruma::identifiers::Error as RumaIdentifierError;
use matrix_sdk_crypto::{ use matrix_sdk_crypto::{
store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError, store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError,
}; };
use ruma::identifiers::Error as RumaIdentifierError;
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum MachineCreationError { pub enum MachineCreationError {

View file

@ -7,8 +7,10 @@ mod responses;
pub use device::Device; pub use device::Device;
pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError};
pub use logger::{set_logger, Logger}; pub use logger::{set_logger, Logger};
pub use machine::{OlmMachine, Sas, KeyRequestPair}; pub use machine::{KeyRequestPair, OlmMachine, Sas};
pub use responses::{DeviceLists, KeysImportResult, Request, RequestType}; pub use responses::{
DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType,
};
pub trait ProgressListener { pub trait ProgressListener {
fn on_progress(&self, progress: i32, total: i32); fn on_progress(&self, progress: i32, total: i32);

View file

@ -30,12 +30,12 @@ use tokio::runtime::Runtime;
use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid};
use matrix_sdk_crypto::{ use matrix_sdk_crypto::{
decrypt_key_export, encrypt_key_export, EncryptionSettings, OlmMachine as InnerMachine, decrypt_key_export, encrypt_key_export, EncryptionSettings, OlmMachine as InnerMachine,
OutgoingVerificationRequest, Sas as InnerSas, Sas as InnerSas,
}; };
use crate::{ use crate::{
error::{CryptoStoreError, DecryptionError, MachineCreationError}, error::{CryptoStoreError, DecryptionError, MachineCreationError},
responses::{response_from_string, OwnedResponse}, responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse},
DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, ProgressListener,
Request, RequestType, Request, RequestType,
}; };
@ -252,13 +252,11 @@ impl OlmMachine {
}) })
.collect(); .collect();
let events = self let events = self.runtime.block_on(self.inner.receive_sync_changes(
.runtime events,
.block_on( &device_changes,
self.inner &key_counts,
.receive_sync_changes(events, &device_changes, &key_counts), ))?;
)
.unwrap();
Ok(serde_json::to_string(&events)?) Ok(serde_json::to_string(&events)?)
} }
@ -570,6 +568,7 @@ impl OlmMachine {
pub fn start_verification(&self, device: &Device) -> Result<Sas, CryptoStoreError> { pub fn start_verification(&self, device: &Device) -> Result<Sas, CryptoStoreError> {
let user_id = UserId::try_from(device.user_id.clone())?; let user_id = UserId::try_from(device.user_id.clone())?;
let device_id = device.device_id.as_str().into(); let device_id = device.device_id.as_str().into();
// TODO remove the unwrap
let device = self let device = self
.runtime .runtime
.block_on(self.inner.get_device(&user_id, device_id))? .block_on(self.inner.get_device(&user_id, device_id))?

View file

@ -78,6 +78,12 @@ dictionary KeyRequestPair {
Request key_request; Request key_request;
}; };
[Enum]
interface OutgoingVerificationRequest {
ToDevice(string request_id, string event_type, string body);
InRoom(string request_id, string room_id, string event_type, string content);
};
[Enum] [Enum]
interface Request { interface Request {
ToDevice(string request_id, string event_type, string body); ToDevice(string request_id, string event_type, string body);
@ -130,8 +136,17 @@ interface OlmMachine {
[Throws=CryptoStoreError] [Throws=CryptoStoreError]
sequence<Request> share_room_key([ByRef] string room_id, sequence<string> users); sequence<Request> share_room_key([ByRef] string room_id, sequence<string> users);
Sas? get_verification([ByRef] string flow_id);
[Throws=CryptoStoreError] [Throws=CryptoStoreError]
Sas start_verification([ByRef] Device device); Sas start_verification([ByRef] Device device);
[Throws=CryptoStoreError]
OutgoingVerificationRequest? confirm_verification([ByRef] string flow_id);
OutgoingVerificationRequest? cancel_verification([ByRef] string flow_id);
OutgoingVerificationRequest? accept_verification([ByRef] string flow_id);
sequence<i32>? get_emoji_index([ByRef] string flow_id);
sequence<i32>? get_decimals([ByRef] string flow_id);
[Throws=DecryptionError] [Throws=DecryptionError]
KeyRequestPair request_room_key([ByRef] string event, [ByRef] string room_id); KeyRequestPair request_room_key([ByRef] string event, [ByRef] string room_id);

View file

@ -13,10 +13,47 @@ use ruma::{
to_device::send_event_to_device::Response as ToDeviceResponse, to_device::send_event_to_device::Response as ToDeviceResponse,
}, },
assign, assign,
events::EventContent,
identifiers::UserId, identifiers::UserId,
}; };
use matrix_sdk_crypto::{IncomingResponse, OutgoingRequest, ToDeviceRequest}; use matrix_sdk_crypto::{
IncomingResponse, OutgoingRequest, OutgoingVerificationRequest as SdkVerificationRequest,
ToDeviceRequest,
};
pub enum OutgoingVerificationRequest {
ToDevice {
request_id: String,
event_type: String,
body: String,
},
InRoom {
request_id: String,
room_id: String,
event_type: String,
content: String,
},
}
impl From<SdkVerificationRequest> for OutgoingVerificationRequest {
fn from(r: SdkVerificationRequest) -> Self {
match r {
SdkVerificationRequest::ToDevice(r) => Self::ToDevice {
request_id: r.txn_id_string(),
event_type: r.event_type.to_string(),
body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
},
SdkVerificationRequest::InRoom(r) => Self::InRoom {
request_id: r.txn_id.to_string(),
room_id: r.room_id.to_string(),
content: serde_json::to_string(&r.content)
.expect("Can't serialize message content"),
event_type: r.content.event_type().to_string(),
},
}
}
}
pub enum Request { pub enum Request {
ToDevice { ToDevice {
@ -74,7 +111,7 @@ impl From<ToDeviceRequest> for Request {
Request::ToDevice { Request::ToDevice {
request_id: r.txn_id_string(), request_id: r.txn_id_string(),
event_type: r.event_type.to_string(), event_type: r.event_type.to_string(),
body: serde_json::to_string(&r.messages).unwrap(), body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
} }
} }
} }
@ -84,7 +121,7 @@ impl From<&ToDeviceRequest> for Request {
Request::ToDevice { Request::ToDevice {
request_id: r.txn_id_string(), request_id: r.txn_id_string(),
event_type: r.event_type.to_string(), event_type: r.event_type.to_string(),
body: serde_json::to_string(&r.messages).unwrap(), body: serde_json::to_string(&r.messages).expect("Can't serialize to-device body"),
} }
} }
} }