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.events.model.Content
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.internal.crypto.crosssigning.DeviceTrustLevel
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.MXUsersDevicesMap
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.session.sync.model.DeviceListResponse
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 uniffi.olm.CryptoStoreErrorException
import uniffi.olm.DecryptionErrorException
import uniffi.olm.Sas as InnerSas
import uniffi.olm.OutgoingVerificationRequest
import uniffi.olm.Device
import uniffi.olm.DeviceLists
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) {
private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString())
private val deviceUpdateObserver = deviceObserver
@ -533,4 +596,17 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
fun discardRoomKey(roomId: String) {
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::{
store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError,
};
use ruma::identifiers::Error as RumaIdentifierError;
#[derive(Debug, thiserror::Error)]
pub enum MachineCreationError {

View File

@ -7,8 +7,10 @@ mod responses;
pub use device::Device;
pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError};
pub use logger::{set_logger, Logger};
pub use machine::{OlmMachine, Sas, KeyRequestPair};
pub use responses::{DeviceLists, KeysImportResult, Request, RequestType};
pub use machine::{KeyRequestPair, OlmMachine, Sas};
pub use responses::{
DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType,
};
pub trait ProgressListener {
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_crypto::{
decrypt_key_export, encrypt_key_export, EncryptionSettings, OlmMachine as InnerMachine,
OutgoingVerificationRequest, Sas as InnerSas,
Sas as InnerSas,
};
use crate::{
error::{CryptoStoreError, DecryptionError, MachineCreationError},
responses::{response_from_string, OwnedResponse},
responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse},
DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, ProgressListener,
Request, RequestType,
};
@ -252,13 +252,11 @@ impl OlmMachine {
})
.collect();
let events = self
.runtime
.block_on(
self.inner
.receive_sync_changes(events, &device_changes, &key_counts),
)
.unwrap();
let events = self.runtime.block_on(self.inner.receive_sync_changes(
events,
&device_changes,
&key_counts,
))?;
Ok(serde_json::to_string(&events)?)
}
@ -570,6 +568,7 @@ impl OlmMachine {
pub fn start_verification(&self, device: &Device) -> Result<Sas, CryptoStoreError> {
let user_id = UserId::try_from(device.user_id.clone())?;
let device_id = device.device_id.as_str().into();
// TODO remove the unwrap
let device = self
.runtime
.block_on(self.inner.get_device(&user_id, device_id))?

View File

@ -78,6 +78,12 @@ dictionary KeyRequestPair {
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]
interface Request {
ToDevice(string request_id, string event_type, string body);
@ -130,8 +136,17 @@ interface OlmMachine {
[Throws=CryptoStoreError]
sequence<Request> share_room_key([ByRef] string room_id, sequence<string> users);
Sas? get_verification([ByRef] string flow_id);
[Throws=CryptoStoreError]
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]
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,
},
assign,
events::EventContent,
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 {
ToDevice {
@ -74,7 +111,7 @@ impl From<ToDeviceRequest> for Request {
Request::ToDevice {
request_id: r.txn_id_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_id: r.txn_id_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"),
}
}
}