rust: Add methods for the QR code verification

This commit is contained in:
Damir Jelić 2021-06-25 18:01:44 +02:00
parent 846242217b
commit d15269a4bd
4 changed files with 102 additions and 13 deletions

View file

@ -12,6 +12,7 @@ name = "matrix_crypto"
serde = "1.0.126" serde = "1.0.126"
serde_json = "1.0.64" serde_json = "1.0.64"
http = "0.2.4" http = "0.2.4"
base64 = "0.13.0"
thiserror = "1.0.25" thiserror = "1.0.25"
tracing = "0.1.26" tracing = "0.1.26"
@ -19,20 +20,20 @@ tracing-subscriber = "0.2.18"
uniffi = "0.12.0" uniffi = "0.12.0"
[dependencies.js_int] [dependencies.js_int]
version = "0.2.0" version = "0.2.1"
features = ["lax_deserialize"] features = ["lax_deserialize"]
[dependencies.matrix-sdk-common] [dependencies.matrix-sdk-common]
git = "https://github.com/matrix-org/matrix-rust-sdk/" git = "https://github.com/matrix-org/matrix-rust-sdk/"
rev = "710b519c110278a0857f26a86a0f8329609c1a5f" rev = "b62f725bead1f44b2038784e5321909f71a4af4a"
[dependencies.matrix-sdk-crypto] [dependencies.matrix-sdk-crypto]
git = "https://github.com/matrix-org/matrix-rust-sdk/" git = "https://github.com/matrix-org/matrix-rust-sdk/"
rev = "710b519c110278a0857f26a86a0f8329609c1a5f" rev = "b62f725bead1f44b2038784e5321909f71a4af4a"
features = ["sled_cryptostore"] features = ["sled_cryptostore"]
[dependencies.tokio] [dependencies.tokio]
version = "1.6.0" version = "1.7.1"
default_features = false default_features = false
features = ["rt-multi-thread"] features = ["rt-multi-thread"]

View file

@ -7,7 +7,7 @@ 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::{KeyRequestPair, OlmMachine, Sas, StartSasResult, VerificationRequest}; pub use machine::{KeyRequestPair, OlmMachine, Sas, StartSasResult, VerificationRequest, QrCode, Verification};
pub use responses::{ pub use responses::{
DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType,
}; };

View file

@ -5,6 +5,7 @@ use std::{
}; };
use js_int::UInt; use js_int::UInt;
use base64::encode;
use ruma::{ use ruma::{
api::{ api::{
client::r0::{ client::r0::{
@ -30,7 +31,8 @@ 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,
Sas as InnerSas, Verification, VerificationRequest as InnerVerificationRequest, QrVerification as InnerQr, Sas as InnerSas, Verification as RustVerification,
VerificationRequest as InnerVerificationRequest,
}; };
use crate::{ use crate::{
@ -46,6 +48,11 @@ pub struct OlmMachine {
runtime: Runtime, runtime: Runtime,
} }
pub enum Verification {
SasV1 { sas: Sas },
QrCodeV1 { qrcode: QrCode },
}
pub struct Sas { pub struct Sas {
pub other_user_id: String, pub other_user_id: String,
pub other_device_id: String, pub other_device_id: String,
@ -62,6 +69,36 @@ pub struct Sas {
pub timed_out: bool, pub timed_out: bool,
} }
pub struct QrCode {
pub other_user_id: String,
pub flow_id: String,
pub other_device_id: String,
pub room_id: Option<String>,
pub is_cancelled: bool,
pub is_done: bool,
pub we_started: bool,
pub other_side_scanned: bool,
pub cancel_code: Option<String>,
pub cancelled_by_us: Option<bool>,
}
impl From<InnerQr> for QrCode {
fn from(qr: InnerQr) -> Self {
Self {
other_user_id: qr.other_user_id().to_string(),
flow_id: qr.flow_id().as_str().to_owned(),
is_cancelled: qr.is_cancelled(),
is_done: qr.is_done(),
cancel_code: qr.cancel_code().map(|c| c.to_string()),
cancelled_by_us: qr.cancelled_by_us(),
we_started: qr.we_started(),
other_side_scanned: qr.is_scanned(),
other_device_id: qr.other_device_id().to_string(),
room_id: qr.room_id().map(|r| r.to_string()),
}
}
}
pub struct StartSasResult { pub struct StartSasResult {
pub sas: Sas, pub sas: Sas,
pub request: OutgoingVerificationRequest, pub request: OutgoingVerificationRequest,
@ -661,11 +698,38 @@ impl OlmMachine {
todo!() todo!()
} }
pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option<Sas> { pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option<Verification> {
let user_id = UserId::try_from(user_id).ok()?; let user_id = UserId::try_from(user_id).ok()?;
self.inner self.inner
.get_verification(&user_id, flow_id) .get_verification(&user_id, flow_id)
.and_then(|v| v.sas_v1().map(|s| s.into())) .map(|v| match v {
RustVerification::SasV1(s) => Verification::SasV1 { sas: s.into() },
RustVerification::QrV1(qr) => Verification::QrCodeV1 { qrcode: qr.into() },
})
}
pub fn start_qr_verification(
&self,
user_id: &str,
flow_id: &str,
) -> Result<Option<QrCode>, CryptoStoreError> {
let user_id = UserId::try_from(user_id)?;
if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) {
Ok(self
.runtime
.block_on(verification.generate_qr_code())?
.map(|qr| qr.into()))
} else {
Ok(None)
}
}
pub fn generate_qr_code(&self, user_id: &str, flow_id: &str) -> Option<String> {
let user_id = UserId::try_from(user_id).ok()?;
self.inner
.get_verification(&user_id, flow_id)
.and_then(|v| v.qr_v1().and_then(|qr| qr.to_bytes().map(|b| encode(b)).ok()))
} }
pub fn start_sas_verification( pub fn start_sas_verification(
@ -711,8 +775,10 @@ impl OlmMachine {
if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { if let Some(verification) = self.inner.get_verification(&user_id, flow_id) {
match verification { match verification {
Verification::SasV1(v) => v.cancel_with_code(cancel_code.into()).map(|r| r.into()), RustVerification::SasV1(v) => {
Verification::QrV1(v) => v.cancel().map(|r| r.into()), v.cancel_with_code(cancel_code.into()).map(|r| r.into())
}
RustVerification::QrV1(v) => v.cancel().map(|r| r.into()),
} }
} else { } else {
None None
@ -729,10 +795,10 @@ impl OlmMachine {
Ok( Ok(
if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { if let Some(verification) = self.inner.get_verification(&user_id, flow_id) {
match verification { match verification {
Verification::SasV1(v) => { RustVerification::SasV1(v) => {
self.runtime.block_on(v.confirm())?.0.map(|r| r.into()) self.runtime.block_on(v.confirm())?.0.map(|r| r.into())
} }
Verification::QrV1(v) => v.confirm_scanning().map(|r| r.into()), RustVerification::QrV1(v) => v.confirm_scanning().map(|r| r.into()),
} }
} else { } else {
None None

View file

@ -86,6 +86,19 @@ dictionary Sas {
boolean supports_emoji; boolean supports_emoji;
}; };
dictionary QrCode {
string other_user_id;
string other_device_id;
string flow_id;
string? cancel_code;
string? room_id;
boolean we_started;
boolean? cancelled_by_us;
boolean is_done;
boolean is_cancelled;
boolean other_side_scanned;
};
dictionary VerificationRequest { dictionary VerificationRequest {
string other_user_id; string other_user_id;
string? other_device_id; string? other_device_id;
@ -102,6 +115,12 @@ dictionary VerificationRequest {
}; };
[Enum]
interface Verification {
SasV1(Sas sas);
QrCodeV1(QrCode qrcode);
};
dictionary KeyRequestPair { dictionary KeyRequestPair {
Request? cancellation; Request? cancellation;
Request key_request; Request key_request;
@ -167,7 +186,7 @@ interface OlmMachine {
sequence<VerificationRequest> get_verification_requests([ByRef] string user_id); sequence<VerificationRequest> get_verification_requests([ByRef] string user_id);
VerificationRequest? get_verification_request([ByRef] string user_id, [ByRef] string flow_id); VerificationRequest? get_verification_request([ByRef] string user_id, [ByRef] string flow_id);
Sas? get_verification([ByRef] string user_id, [ByRef] string flow_id); Verification? get_verification([ByRef] string user_id, [ByRef] string flow_id);
OutgoingVerificationRequest? accept_verification_request( OutgoingVerificationRequest? accept_verification_request(
[ByRef] string user_id, [ByRef] string user_id,
@ -185,6 +204,9 @@ interface OlmMachine {
[ByRef] string cancel_code [ByRef] string cancel_code
); );
OutgoingVerificationRequest? accept_sas_verification([ByRef] string user_id, [ByRef] string flow_id); OutgoingVerificationRequest? accept_sas_verification([ByRef] string user_id, [ByRef] string flow_id);
[Throws=CryptoStoreError]
QrCode? start_qr_verification([ByRef] string user_id, [ByRef] string flow_id);
string? generate_qr_code([ByRef] string user_id, [ByRef] string flow_id);
sequence<i32>? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); sequence<i32>? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id);
sequence<i32>? get_decimals([ByRef] string user_id, [ByRef] string flow_id); sequence<i32>? get_decimals([ByRef] string user_id, [ByRef] string flow_id);