From de5a02b02a034bda43e843564ef18a8a99b0c27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 9 Feb 2021 15:41:01 +0100 Subject: [PATCH 001/252] matrix-sdk: Initial import of the rust-sdk crypto layer. --- matrix-sdk-android/build.gradle | 16 ++ .../internal/crypto/DefaultCryptoService.kt | 9 + .../matrix/android/sdk/internal/newCrypto.kt | 72 +++++++ rust-sdk/Cargo.toml | 25 +++ rust-sdk/build.rs | 3 + rust-sdk/src/lib.rs | 178 ++++++++++++++++++ rust-sdk/src/olm.udl | 56 ++++++ 7 files changed, 359 insertions(+) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt create mode 100644 rust-sdk/Cargo.toml create mode 100644 rust-sdk/build.rs create mode 100644 rust-sdk/src/lib.rs create mode 100644 rust-sdk/src/olm.udl diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 836b49b3f2..707a8ddc3d 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -90,6 +90,20 @@ android { } } +android.libraryVariants.all { variant -> + def t = tasks.register("generate${variant.name.capitalize()}UniffiBindings", Exec) { + // Runs the bindings generation, note that you must have uniffi-bindgen installed + // and in your PATH environment variable + commandLine 'uniffi-bindgen', 'generate', '../rust-sdk/src/olm.udl', + '--language', 'kotlin', + '--out-dir', "${buildDir}/generated/source/uniffi/${variant.name}/java" + } + + variant.javaCompileProvider.get().dependsOn(t) + def sourceSet = variant.sourceSets.find { it.name == variant.name } + sourceSet.java.srcDir new File(buildDir, "generated/source/uniffi/${variant.name}/java") +} + static def gitRevision() { def cmd = "git rev-parse --short=8 HEAD" return cmd.execute().text.trim() @@ -116,6 +130,8 @@ dependencies { def work_version = '2.4.0' def retrofit_version = '2.6.2' + implementation 'net.java.dev.jna:jna:5.6.0@aar' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 678bc9819f..d230008b71 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -50,6 +50,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent import org.matrix.android.sdk.api.session.room.model.RoomMemberContent +import org.matrix.android.sdk.internal.OlmMachine import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting @@ -362,6 +363,14 @@ internal class DefaultCryptoService @Inject constructor( return } isStarting.set(true) + try { + val dataDir = "/data/data/im.vector.app.debug/files" + val olmMachine = OlmMachine("@example:localhost", "DEVICEID", dataDir) + Timber.v("HELLLO WORLD STARTING CRYPTO ${olmMachine.identityKeys()}") + } catch (throwable: Throwable) { + Timber.v("HELLLO WORLD FAILED CRYPTO $throwable") + } + Timber.v("HELLLO WORLD STARTING CRYPTO") // Open the store cryptoStore.open() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt new file mode 100644 index 0000000000..e48bc0f1f7 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal + +import kotlinx.coroutines.withContext +import kotlinx.coroutines.Dispatchers + +import uniffi.olm.OlmMachine as InnerMachine +import uniffi.olm.Device as InnerDevice +import uniffi.olm.Sas as InnerSas + +class Device(inner: InnerDevice, machine: InnerMachine) { + private val machine: InnerMachine = machine + private val inner: InnerDevice = inner + + fun userId(): String { + return this.inner.userId + } + + fun deviceId(): String { + return this.inner.deviceId + } + + fun keys(): Map { + return this.inner.keys + } + + fun startVerification(): InnerSas { + return this.machine.startVerification(this.inner) + } +} + +class OlmMachine(user_id: String, device_id: String, path: String) { + private val inner: InnerMachine = InnerMachine(user_id, device_id, path) + + fun userId(): String { + return this.inner.userId() + } + + fun deviceId(): String { + return this.inner.deviceId() + } + + fun identityKeys(): Map { + return this.inner.identityKeys() + } + + suspend fun slowUserId(): String = withContext(Dispatchers.Default) { + inner.slowUserId() + } + + suspend fun getDevice(user_id: String, device_id: String): Device? = withContext(Dispatchers.IO) { + when (val device: InnerDevice? = inner.getDevice(user_id, device_id)) { + null -> null + else -> Device(device, inner) + } + } +} diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml new file mode 100644 index 0000000000..e582648437 --- /dev/null +++ b/rust-sdk/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "matrix-crypto-bindings" +version = "0.1.0" +authors = ["Damir Jelić "] +edition = "2018" + +[lib] +crate-type = ["cdylib", "lib"] +name = "matrix_crypto" + +[dependencies] +matrix-sdk-crypto = { git = "https://github.com/matrix-org/matrix-rust-sdk/", features = ["sled_cryptostore"] } +matrix-sdk-common = { git = "https://github.com/matrix-org/matrix-rust-sdk/"} +futures = { version = "0.3.12", default_features = false, features = ["executor"] } +tokio = { version = "1.1.1", default_features = false, features = ["rt-multi-thread", "time"] } +serde_json = "1.0.61" +thiserror = "1.0.23" +http = "0.2.3" +uniffi = "0.7.0" + +[build-dependencies] +uniffi_build = "0.7.0" + +[patch.crates-io] +olm-sys = { git = "https://gitlab.gnome.org/poljar/olm-sys/", branch = "android-cross" } diff --git a/rust-sdk/build.rs b/rust-sdk/build.rs new file mode 100644 index 0000000000..bfce95467f --- /dev/null +++ b/rust-sdk/build.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi_build::generate_scaffolding("./src/olm.udl").unwrap(); +} diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs new file mode 100644 index 0000000000..cdc164f629 --- /dev/null +++ b/rust-sdk/src/lib.rs @@ -0,0 +1,178 @@ +use std::{collections::HashMap, convert::TryFrom, time::Duration}; + +use futures::{ + executor::block_on, + future::{abortable, AbortHandle, Aborted}, + Future, +}; +use http::Response; +use tokio::{runtime::Runtime, time::sleep}; + +use matrix_sdk_common::{ + api::r0::sync::sync_events::Response as SyncResponse, + api::r0::to_device::send_event_to_device::METADATA, + identifiers::{Error as RumaIdentifierError, UserId}, +}; +use matrix_sdk_crypto::{ + store::CryptoStoreError as InnerStoreError, OlmMachine as InnerMachine, ToDeviceRequest, +}; + +pub struct OlmMachine { + inner: InnerMachine, + runtime: Runtime, +} + +#[derive(Debug, thiserror::Error)] +pub enum MachineCreationError { + #[error(transparent)] + Identifier(#[from] RumaIdentifierError), + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), +} + +#[derive(Debug, thiserror::Error)] +pub enum CryptoStoreError { + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), +} + +pub enum RequestType { + KeysQuery, + KeysUpload, + ToDevice, +} + +pub struct Device { + pub user_id: String, + pub device_id: String, + pub keys: HashMap, +} + +pub struct Sas { + pub other_user_id: String, + pub other_device_id: String, + pub flow_id: String, + pub request: Request, +} + +pub struct Request { + pub request_id: String, + pub request_type: RequestType, + pub request_body: String, +} + +impl From for Request { + fn from(r: ToDeviceRequest) -> Self { + Request { + request_id: r.txn_id_string(), + request_type: RequestType::ToDevice, + request_body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +fn response_from_string(body: &str) -> Response> { + Response::builder() + .status(200) + .body(body.as_bytes().to_vec()) + .expect("Can't create HTTP response") +} + +impl OlmMachine { + pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { + let user_id = UserId::try_from(user_id)?; + let device_id = device_id.into(); + + Ok(OlmMachine { + inner: block_on(InnerMachine::new_with_default_store( + &user_id, + device_id, + path, + Some("DEFAULT_PASSPHRASE"), + ))?, + runtime: Runtime::new().unwrap(), + }) + } + + pub fn user_id(&self) -> String { + self.inner.user_id().to_string() + } + + pub fn device_id(&self) -> String { + self.inner.device_id().to_string() + } + + pub fn get_device(&self, user_id: &str, device_id: &str) -> Option { + let user_id = UserId::try_from(user_id).unwrap(); + + block_on(self.inner.get_device(&user_id, device_id.into())) + .unwrap() + .map(|d| Device { + user_id: d.user_id().to_string(), + device_id: d.device_id().to_string(), + keys: d + .keys() + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + }) + } + + pub fn get_user_devices(&self, user_id: &str) -> Vec { + let user_id = UserId::try_from(user_id).unwrap(); + block_on(self.inner.get_user_devices(&user_id)) + .unwrap() + .devices() + .map(|d| Device { + user_id: d.user_id().to_string(), + device_id: d.device_id().to_string(), + keys: d + .keys() + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + }) + .collect() + } + + pub fn identity_keys(&self) -> HashMap { + self.inner + .identity_keys() + .iter() + .map(|(k, v)| (k.to_owned(), v.to_owned())) + .collect() + } + + pub fn slow_user_id(&self) -> String { + let machine = self.inner.clone(); + + self.runtime.block_on(async { + sleep(Duration::from_secs(10)).await; + machine.user_id().to_string() + }) + } + + pub fn start_verification(&self, device: &Device) -> Result { + let user_id = UserId::try_from(device.user_id.clone()).unwrap(); + let device_id = device.device_id.as_str().into(); + let device = block_on(self.inner.get_device(&user_id, device_id))?.unwrap(); + + let (sas, request) = block_on(device.start_verification())?; + + Ok(Sas { + other_user_id: sas.other_user_id().to_string(), + other_device_id: sas.other_device_id().to_string(), + flow_id: sas.flow_id().as_str().to_owned(), + request: request.into(), + }) + } + + pub fn receive_sync_response(&self, response: &str) { + let response = response_from_string(response); + let mut response = SyncResponse::try_from(response).expect("Can't parse response"); + + block_on(self.inner.receive_sync_response(&mut response)).unwrap(); + } +} + +include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl new file mode 100644 index 0000000000..cb308e8fa3 --- /dev/null +++ b/rust-sdk/src/olm.udl @@ -0,0 +1,56 @@ +namespace olm {}; + +[Error] +enum MachineCreationError { + "Identifier", + "CryptoStore", +}; + +[Error] +enum CryptoStoreError { + "CryptoStore", +}; + +dictionary Device { + string user_id; + string device_id; + record keys; +}; + +dictionary Sas { + string other_user_id; + string other_device_id; + string flow_id; + Request request; +}; + +dictionary Request { + string request_id; + RequestType request_type; + string request_body; +}; + +enum RequestType { + "KeysQuery", + "KeysUpload", + "ToDevice", +}; + +interface OlmMachine { + [Throws=MachineCreationError] + constructor([ByRef] string user_id, [ByRef] string device_id, [ByRef] string path); + + void receive_sync_response([ByRef] string response); + + record identity_keys(); + + string user_id(); + string slow_user_id(); + string device_id(); + + Device? get_device([ByRef] string user_id, [ByRef] string device_id); + sequence get_user_devices([ByRef] string user_id); + + [Throws=CryptoStoreError] + Sas start_verification([ByRef] Device device); +}; From 5886dc1cbc16dc8decd7643ed623c9757d2c5dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 9 Feb 2021 17:14:30 +0100 Subject: [PATCH 002/252] gitignore: Update the gitignore file for the rust-sdk --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 4a264a28d8..95f3c23914 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ /build /captures .externalNativeBuild +rust-sdk/target/* +Cargo.lock /tmp From a557c058908b3cb7c1bc150a8458c6cec8dac957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 9 Feb 2021 17:14:56 +0100 Subject: [PATCH 003/252] rust-sdk: Add a Makefile to build the bindings and put them into the jni folder --- rust-sdk/Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 rust-sdk/Makefile diff --git a/rust-sdk/Makefile b/rust-sdk/Makefile new file mode 100644 index 0000000000..3d2be7c95b --- /dev/null +++ b/rust-sdk/Makefile @@ -0,0 +1,11 @@ +x86_64: + cargo build --target x86_64-linux-android + install -D target/x86_64-linux-android/debug/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86_64/libuniffi_olm.so + +x86: + cargo build --target i686-linux-android + install -D target/i686-linux-android/debug/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86/libuniffi_olm.so + +aarch64: + cargo build --target aarch64-linux-android + install -D target/aarch64-linux-android/debug/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/aarch64/libuniffi_olm.so From 0b9be11d852511929ffc94c96198f5b49f2aa341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 10 Feb 2021 16:31:34 +0100 Subject: [PATCH 004/252] rust-sdk: Change the sync receiving API to make it a bit more type safe --- rust-sdk/Cargo.toml | 11 ++++++- rust-sdk/src/lib.rs | 76 ++++++++++++++++++++++++++++++++------------ rust-sdk/src/olm.udl | 9 +++++- 3 files changed, 74 insertions(+), 22 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index e582648437..a7f7a5e663 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -9,7 +9,6 @@ crate-type = ["cdylib", "lib"] name = "matrix_crypto" [dependencies] -matrix-sdk-crypto = { git = "https://github.com/matrix-org/matrix-rust-sdk/", features = ["sled_cryptostore"] } matrix-sdk-common = { git = "https://github.com/matrix-org/matrix-rust-sdk/"} futures = { version = "0.3.12", default_features = false, features = ["executor"] } tokio = { version = "1.1.1", default_features = false, features = ["rt-multi-thread", "time"] } @@ -18,6 +17,16 @@ thiserror = "1.0.23" http = "0.2.3" uniffi = "0.7.0" +[dependencies.matrix-sdk-crypto] +git = "https://github.com/matrix-org/matrix-rust-sdk/" +features = ["sled_cryptostore"] + +[dependencies.ruma] +version = "0.0.2" +git = "https://github.com/ruma/ruma" +rev = "d6aa37c848b7f682a98c25b346899e284ffc6df7" +features = ["client-api", "compat", "unstable-pre-spec", "unstable-exhaustive-types"] + [build-dependencies] uniffi_build = "0.7.0" diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index cdc164f629..4033f4b659 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,17 +1,18 @@ -use std::{collections::HashMap, convert::TryFrom, time::Duration}; - -use futures::{ - executor::block_on, - future::{abortable, AbortHandle, Aborted}, - Future, +use std::{ + collections::{BTreeMap, HashMap}, + convert::TryFrom, + time::Duration, }; -use http::Response; + +use futures::executor::block_on; use tokio::{runtime::Runtime, time::sleep}; use matrix_sdk_common::{ - api::r0::sync::sync_events::Response as SyncResponse, - api::r0::to_device::send_event_to_device::METADATA, - identifiers::{Error as RumaIdentifierError, UserId}, + api::r0::sync::sync_events::{ + DeviceLists as RumaDeviceLists, ToDevice, + }, + identifiers::{DeviceKeyAlgorithm, Error as RumaIdentifierError, UserId}, + UInt, }; use matrix_sdk_crypto::{ store::CryptoStoreError as InnerStoreError, OlmMachine as InnerMachine, ToDeviceRequest, @@ -22,6 +23,28 @@ pub struct OlmMachine { runtime: Runtime, } +pub struct DeviceLists { + pub changed: Vec, + pub left: Vec, +} + +impl Into for DeviceLists { + fn into(self) -> RumaDeviceLists { + RumaDeviceLists { + changed: self + .changed + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(), + left: self + .left + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(), + } + } +} + #[derive(Debug, thiserror::Error)] pub enum MachineCreationError { #[error(transparent)] @@ -71,12 +94,12 @@ impl From for Request { } } -fn response_from_string(body: &str) -> Response> { - Response::builder() - .status(200) - .body(body.as_bytes().to_vec()) - .expect("Can't create HTTP response") -} +// fn response_from_string(body: &str) -> Response> { +// Response::builder() +// .status(200) +// .body(body.as_bytes().to_vec()) +// .expect("Can't create HTTP response") +// } impl OlmMachine { pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { @@ -167,11 +190,24 @@ impl OlmMachine { }) } - pub fn receive_sync_response(&self, response: &str) { - let response = response_from_string(response); - let mut response = SyncResponse::try_from(response).expect("Can't parse response"); + pub fn receive_sync_changes( + &self, + events: &str, + device_changes: DeviceLists, + key_counts: HashMap, + ) { + let events: ToDevice = serde_json::from_str(events).unwrap(); + let device_changes: RumaDeviceLists = device_changes.into(); + let key_counts: BTreeMap = key_counts + .into_iter() + .map(|(k, v)| (DeviceKeyAlgorithm::from(k), v.into())) + .collect(); - block_on(self.inner.receive_sync_response(&mut response)).unwrap(); + block_on( + self.inner + .receive_sync_changes(&events, &device_changes, &key_counts), + ) + .unwrap(); } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index cb308e8fa3..685371f0ed 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -11,6 +11,11 @@ enum CryptoStoreError { "CryptoStore", }; +dictionary DeviceLists { + sequence changed; + sequence left; +}; + dictionary Device { string user_id; string device_id; @@ -40,7 +45,9 @@ interface OlmMachine { [Throws=MachineCreationError] constructor([ByRef] string user_id, [ByRef] string device_id, [ByRef] string path); - void receive_sync_response([ByRef] string response); + void receive_sync_changes([ByRef] string events, + DeviceLists device_changes, + record key_counts); record identity_keys(); From 628f5306334980685698583f7a8799e3adc30410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 11 Feb 2021 11:11:25 +0100 Subject: [PATCH 005/252] rust-sdk: Add a method to get the ougtoing requests --- rust-sdk/Cargo.toml | 6 +- rust-sdk/src/lib.rs | 164 ++++++++++++++++++++++++++++++++++++++----- rust-sdk/src/olm.udl | 20 ++++-- 3 files changed, 165 insertions(+), 25 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index a7f7a5e663..54709d0928 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -15,12 +15,16 @@ tokio = { version = "1.1.1", default_features = false, features = ["rt-multi-thr serde_json = "1.0.61" thiserror = "1.0.23" http = "0.2.3" -uniffi = "0.7.0" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" features = ["sled_cryptostore"] +[dependencies.uniffi] +version = "0.7.0" +git = "https://github.com/mozilla/uniffi-rs" +branch = "tagged-unions" + [dependencies.ruma] version = "0.0.2" git = "https://github.com/ruma/ruma" diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 4033f4b659..f5ed343a74 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -5,17 +5,25 @@ use std::{ }; use futures::executor::block_on; +use http::Response; +use serde_json::json; use tokio::{runtime::Runtime, time::sleep}; use matrix_sdk_common::{ - api::r0::sync::sync_events::{ - DeviceLists as RumaDeviceLists, ToDevice, + api::r0::{ + keys::{ + claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, + upload_keys::Response as KeysUploadResponse, + }, + sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, }, identifiers::{DeviceKeyAlgorithm, Error as RumaIdentifierError, UserId}, + uuid::Uuid, UInt, }; use matrix_sdk_crypto::{ - store::CryptoStoreError as InnerStoreError, OlmMachine as InnerMachine, ToDeviceRequest, + store::CryptoStoreError as InnerStoreError, IncomingResponse, OlmError, + OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, }; pub struct OlmMachine { @@ -45,6 +53,40 @@ impl Into for DeviceLists { } } +enum OwnedResponse { + KeysClaim(KeysClaimResponse), + KeysUpload(KeysUploadResponse), + KeysQuery(KeysQueryResponse), +} + +impl From for OwnedResponse { + fn from(response: KeysClaimResponse) -> Self { + OwnedResponse::KeysClaim(response) + } +} + +impl From for OwnedResponse { + fn from(response: KeysQueryResponse) -> Self { + OwnedResponse::KeysQuery(response) + } +} + +impl From for OwnedResponse { + fn from(response: KeysUploadResponse) -> Self { + OwnedResponse::KeysUpload(response) + } +} + +impl<'a> Into> for &'a OwnedResponse { + fn into(self) -> IncomingResponse<'a> { + match self { + OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), + OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), + OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), + } + } +} + #[derive(Debug, thiserror::Error)] pub enum MachineCreationError { #[error(transparent)] @@ -57,6 +99,8 @@ pub enum MachineCreationError { pub enum CryptoStoreError { #[error(transparent)] CryptoStore(#[from] InnerStoreError), + #[error(transparent)] + OlmError(#[from] OlmError), } pub enum RequestType { @@ -78,28 +122,81 @@ pub struct Sas { pub request: Request, } -pub struct Request { - pub request_id: String, - pub request_type: RequestType, - pub request_body: String, +pub enum Request { + ToDevice { + request_id: String, + event_type: String, + body: String, + }, + KeysUpload { + request_id: String, + body: String, + }, + KeysQuery { + request_id: String, + body: String, + }, } -impl From for Request { - fn from(r: ToDeviceRequest) -> Self { - Request { - request_id: r.txn_id_string(), - request_type: RequestType::ToDevice, - request_body: serde_json::to_string(&r.messages).unwrap(), +impl From for Request { + fn from(r: OutgoingRequest) -> Self { + use matrix_sdk_crypto::OutgoingRequests::*; + + match r.request() { + KeysUpload(u) => { + let body = json!({ + "device_keys": u.device_keys, + "one_time_keys": u.one_time_keys, + }); + + Request::KeysUpload { + request_id: r.request_id().to_string(), + body: serde_json::to_string(&body) + .expect("Can't serialize keys upload request"), + } + } + KeysQuery(k) => { + let body = json!({ + "device_keys": k.device_keys, + }); + Request::KeysQuery { + request_id: r.request_id().to_string(), + body: serde_json::to_string(&body).expect("Can't serialize keys query request"), + } + } + ToDeviceRequest(t) => Request::from(t), + SignatureUpload(_) => todo!(), + RoomMessage(_) => todo!(), } } } -// fn response_from_string(body: &str) -> Response> { -// Response::builder() -// .status(200) -// .body(body.as_bytes().to_vec()) -// .expect("Can't create HTTP response") -// } +impl From for Request { + fn from(r: ToDeviceRequest) -> Self { + Request::ToDevice { + request_id: r.txn_id_string(), + event_type: r.event_type.to_string(), + body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +impl From<&ToDeviceRequest> for Request { + fn from(r: &ToDeviceRequest) -> Self { + Request::ToDevice { + request_id: r.txn_id_string(), + event_type: r.event_type.to_string(), + body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +fn response_from_string(body: &str) -> Response> { + Response::builder() + .status(200) + .body(body.as_bytes().to_vec()) + .expect("Can't create HTTP response") +} impl OlmMachine { pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { @@ -175,6 +272,28 @@ impl OlmMachine { }) } + pub fn mark_request_as_sent( + &self, + request_id: &str, + request_type: RequestType, + response_body: &str, + ) -> Result<(), CryptoStoreError> { + let id = Uuid::parse_str(request_id).expect("Can't parse request id"); + + let response = response_from_string(&response_body); + + let response: OwnedResponse = match request_type { + RequestType::KeysUpload => KeysUploadResponse::try_from(response).map(Into::into), + RequestType::KeysQuery => KeysQueryResponse::try_from(response).map(Into::into), + RequestType::ToDevice => KeysClaimResponse::try_from(response).map(Into::into), + } + .expect("Can't convert json string to response"); + + block_on(self.inner.mark_request_as_sent(&id, &response))?; + + Ok(()) + } + pub fn start_verification(&self, device: &Device) -> Result { let user_id = UserId::try_from(device.user_id.clone()).unwrap(); let device_id = device.device_id.as_str().into(); @@ -190,6 +309,13 @@ impl OlmMachine { }) } + pub fn outgoing_requests(&self) -> Vec { + block_on(self.inner.outgoing_requests()) + .into_iter() + .map(|r| r.into()) + .collect() + } + pub fn receive_sync_changes( &self, events: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 685371f0ed..1a49fee8d9 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -9,6 +9,7 @@ enum MachineCreationError { [Error] enum CryptoStoreError { "CryptoStore", + "OlmError", }; dictionary DeviceLists { @@ -29,10 +30,11 @@ dictionary Sas { Request request; }; -dictionary Request { - string request_id; - RequestType request_type; - string request_body; +[TaggedUnion] +interface Request { + ToDevice(string request_id, string event_type, string body); + KeysUpload(string request_id, string body); + KeysQuery(string request_id, string body); }; enum RequestType { @@ -41,6 +43,7 @@ enum RequestType { "ToDevice", }; +[Threadsafe] interface OlmMachine { [Throws=MachineCreationError] constructor([ByRef] string user_id, [ByRef] string device_id, [ByRef] string path); @@ -52,11 +55,18 @@ interface OlmMachine { record identity_keys(); string user_id(); - string slow_user_id(); string device_id(); Device? get_device([ByRef] string user_id, [ByRef] string device_id); sequence get_user_devices([ByRef] string user_id); + sequence outgoing_requests(); + + [Throws=CryptoStoreError] + void mark_request_as_sent( + [ByRef] string request_id, + RequestType request_type, + [ByRef] string response + ); [Throws=CryptoStoreError] Sas start_verification([ByRef] Device device); From f01e2460e1acc809e2b00d0bacec5d19dd364c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 11 Feb 2021 12:01:49 +0100 Subject: [PATCH 006/252] crypto: Enable the use of unsigned ints for now and update the bindings wrapper --- build.gradle | 1 + .../sdk/internal/crypto/DefaultCryptoService.kt | 15 ++++++++++----- .../org/matrix/android/sdk/internal/newCrypto.kt | 14 +++++--------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index 625ed348be..370006d1c9 100644 --- a/build.gradle +++ b/build.gradle @@ -70,6 +70,7 @@ allprojects { // Warnings are potential errors, so stop ignoring them // You can override by passing `-PallWarningsAsErrors=false` in the command line kotlinOptions.allWarningsAsErrors = project.getProperties().getOrDefault("allWarningsAsErrors", "true").toBoolean() + kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.ExperimentalUnsignedTypes" } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index d230008b71..257f1c9a05 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -84,6 +84,7 @@ import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope @@ -97,6 +98,7 @@ import org.matrix.android.sdk.internal.util.JsonCanonicalizer import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.olm.OlmManager import timber.log.Timber +import java.io.File import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import kotlin.jvm.Throws @@ -120,6 +122,8 @@ internal class DefaultCryptoService @Inject constructor( private val userId: String, @DeviceId private val deviceId: String?, + @SessionFilesDirectory + private val dataDir: File, private val myDeviceInfoHolder: Lazy, // the crypto store private val cryptoStore: IMXCryptoStore, @@ -171,6 +175,7 @@ internal class DefaultCryptoService @Inject constructor( private val isStarting = AtomicBoolean(false) private val isStarted = AtomicBoolean(false) + private var olmMachine: OlmMachine? = null fun onStateEvent(roomId: String, event: Event) { when (event.getClearType()) { @@ -310,7 +315,7 @@ internal class DefaultCryptoService @Inject constructor( * devices. * */ - fun start() { + suspend fun start() { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { internalStart() } @@ -363,14 +368,14 @@ internal class DefaultCryptoService @Inject constructor( return } isStarting.set(true) + Timber.v("HELLLO WORLD STARTING CRYPTO") + try { - val dataDir = "/data/data/im.vector.app.debug/files" - val olmMachine = OlmMachine("@example:localhost", "DEVICEID", dataDir) - Timber.v("HELLLO WORLD STARTING CRYPTO ${olmMachine.identityKeys()}") + olmMachine = OlmMachine(userId, deviceId!!, dataDir) + Timber.v("HELLLO WORLD STARTING CRYPTO ${olmMachine?.identityKeys()}") } catch (throwable: Throwable) { Timber.v("HELLLO WORLD FAILED CRYPTO $throwable") } - Timber.v("HELLLO WORLD STARTING CRYPTO") // Open the store cryptoStore.open() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index e48bc0f1f7..2e1308f4b6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal -import kotlinx.coroutines.withContext +import java.io.File import kotlinx.coroutines.Dispatchers - -import uniffi.olm.OlmMachine as InnerMachine +import kotlinx.coroutines.withContext import uniffi.olm.Device as InnerDevice +import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.Sas as InnerSas class Device(inner: InnerDevice, machine: InnerMachine) { @@ -44,8 +44,8 @@ class Device(inner: InnerDevice, machine: InnerMachine) { } } -class OlmMachine(user_id: String, device_id: String, path: String) { - private val inner: InnerMachine = InnerMachine(user_id, device_id, path) +class OlmMachine(user_id: String, device_id: String, path: File) { + private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) fun userId(): String { return this.inner.userId() @@ -59,10 +59,6 @@ class OlmMachine(user_id: String, device_id: String, path: String) { return this.inner.identityKeys() } - suspend fun slowUserId(): String = withContext(Dispatchers.Default) { - inner.slowUserId() - } - suspend fun getDevice(user_id: String, device_id: String): Device? = withContext(Dispatchers.IO) { when (val device: InnerDevice? = inner.getDevice(user_id, device_id)) { null -> null From e16c5d07e5fcf84f0ca2f3cffad374876f150ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 11 Feb 2021 12:12:03 +0100 Subject: [PATCH 007/252] gradle.properties: Increase the heap size since it seems to run out of memory --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 200866be25..9282f3c84e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ # The setting is particularly useful for tweaking memory settings. android.enableJetifier=true android.useAndroidX=true -org.gradle.jvmargs=-Xmx2048m +org.gradle.jvmargs=-Xmx4096m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects From 1eeb97ec518dc11a8e6180cb941d4a38ad9a0f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 11 Feb 2021 15:18:06 +0100 Subject: [PATCH 008/252] crypto: Expose the new outgoing request method --- .../internal/crypto/DefaultCryptoService.kt | 23 ++++++++++++++----- .../matrix/android/sdk/internal/newCrypto.kt | 14 +++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 257f1c9a05..dc321c0a88 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -22,6 +22,11 @@ import androidx.lifecycle.LiveData import androidx.paging.PagedList import com.squareup.moshi.Types import dagger.Lazy +import java.io.File +import java.util.concurrent.atomic.AtomicBoolean +import javax.inject.Inject +import kotlin.jvm.Throws +import kotlin.math.max import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancelChildren @@ -98,11 +103,7 @@ import org.matrix.android.sdk.internal.util.JsonCanonicalizer import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.olm.OlmManager import timber.log.Timber -import java.io.File -import java.util.concurrent.atomic.AtomicBoolean -import javax.inject.Inject -import kotlin.jvm.Throws -import kotlin.math.max +import uniffi.olm.Request /** * A `CryptoService` class instance manages the end-to-end crypto for a session. @@ -363,7 +364,7 @@ internal class DefaultCryptoService @Inject constructor( } } - private fun internalStart() { + private suspend fun internalStart() { if (isStarted.get() || isStarting.get()) { return } @@ -372,7 +373,17 @@ internal class DefaultCryptoService @Inject constructor( try { olmMachine = OlmMachine(userId, deviceId!!, dataDir) + Timber.v("HELLLO WORLD STARTING CRYPTO ${olmMachine?.identityKeys()}") + + // TODO sent out those requests in a sensible place. + for (request in olmMachine!!.outgoingRequests()) { + when (request) { + is Request.KeysUpload -> Timber.v("HELLO KEYS UPLOAD REQUEST ${request.body}") + is Request.KeysQuery -> Timber.v("HELLO KEYS QUERY REQUEST ${request.body}") + is Request.ToDevice -> Timber.v("HELLO TO DEVICE REQUEST ${request.body}") + } + } } catch (throwable: Throwable) { Timber.v("HELLLO WORLD FAILED CRYPTO $throwable") } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 2e1308f4b6..22da46ee33 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -21,6 +21,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import uniffi.olm.Device as InnerDevice import uniffi.olm.OlmMachine as InnerMachine +import uniffi.olm.Request +import uniffi.olm.RequestType import uniffi.olm.Sas as InnerSas class Device(inner: InnerDevice, machine: InnerMachine) { @@ -59,6 +61,18 @@ class OlmMachine(user_id: String, device_id: String, path: File) { return this.inner.identityKeys() } + suspend fun outgoingRequests(): List = withContext(Dispatchers.IO) { + inner.outgoingRequests() + } + + suspend fun markRequestAsSent( + request_id: String, + request_type: RequestType, + response_body: String + ) = withContext(Dispatchers.IO) { + inner.markRequestAsSent(request_id, request_type, response_body) + } + suspend fun getDevice(user_id: String, device_id: String): Device? = withContext(Dispatchers.IO) { when (val device: InnerDevice? = inner.getDevice(user_id, device_id)) { null -> null From 3ddbe7e69ba1c6f2f9010bd0f2cddf5762d4e1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 12 Feb 2021 16:45:31 +0100 Subject: [PATCH 009/252] crypto: Use the rust crypto layer to upload device/one-time keys --- .../sdk/internal/crypto/CryptoModule.kt | 5 ++ .../internal/crypto/DefaultCryptoService.kt | 78 ++++++++++++------- .../sdk/internal/crypto/api/CryptoApi.kt | 8 ++ .../internal/crypto/tasks/UploadKeysTask.kt | 20 +++++ .../session/sync/CryptoSyncHandler.kt | 2 +- 5 files changed, 83 insertions(+), 30 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index a786ebd4b2..b9070994e4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -72,6 +72,7 @@ import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultSetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadKeysTask +import org.matrix.android.sdk.internal.crypto.tasks.NewDefaultUploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadSignaturesTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadSigningKeysTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask @@ -86,6 +87,7 @@ import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.SendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask +import org.matrix.android.sdk.internal.crypto.tasks.NewUploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask import org.matrix.android.sdk.internal.crypto.tasks.UploadSigningKeysTask import org.matrix.android.sdk.internal.database.RealmKeysUtils @@ -177,6 +179,9 @@ internal abstract class CryptoModule { @Binds abstract fun bindUploadKeysTask(task: DefaultUploadKeysTask): UploadKeysTask + @Binds + abstract fun bindNewUploadKeysTask(task: NewDefaultUploadKeysTask): NewUploadKeysTask + @Binds abstract fun bindUploadSigningKeysTask(task: DefaultUploadSigningKeysTask): UploadSigningKeysTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index dc321c0a88..ac51e1dca0 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -55,6 +55,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent import org.matrix.android.sdk.api.session.room.model.RoomMemberContent +import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.OlmMachine import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction @@ -76,14 +77,15 @@ import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse +import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody -import org.matrix.android.sdk.internal.crypto.model.toRest import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceWithUserPasswordTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask +import org.matrix.android.sdk.internal.crypto.tasks.NewUploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService @@ -99,11 +101,11 @@ import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.TaskThread import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.task.launchToCallback -import org.matrix.android.sdk.internal.util.JsonCanonicalizer import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.olm.OlmManager import timber.log.Timber import uniffi.olm.Request +import uniffi.olm.RequestType /** * A `CryptoService` class instance manages the end-to-end crypto for a session. @@ -166,6 +168,7 @@ internal class DefaultCryptoService @Inject constructor( private val getDeviceInfoTask: GetDeviceInfoTask, private val setDeviceNameTask: SetDeviceNameTask, private val uploadKeysTask: UploadKeysTask, + private val newUploadKeysTask: NewUploadKeysTask, private val loadRoomMembersTask: LoadRoomMembersTask, private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, private val coroutineDispatchers: MatrixCoroutineDispatchers, @@ -337,7 +340,7 @@ internal class DefaultCryptoService @Inject constructor( uploadDeviceKeys() } - oneTimeKeysUploader.maybeUploadOneTimeKeys() + // oneTimeKeysUploader.maybeUploadOneTimeKeys() // this can throw if no backup tryOrNull { keysBackupService.checkAndStartKeysBackup() @@ -374,16 +377,7 @@ internal class DefaultCryptoService @Inject constructor( try { olmMachine = OlmMachine(userId, deviceId!!, dataDir) - Timber.v("HELLLO WORLD STARTING CRYPTO ${olmMachine?.identityKeys()}") - - // TODO sent out those requests in a sensible place. - for (request in olmMachine!!.outgoingRequests()) { - when (request) { - is Request.KeysUpload -> Timber.v("HELLO KEYS UPLOAD REQUEST ${request.body}") - is Request.KeysQuery -> Timber.v("HELLO KEYS QUERY REQUEST ${request.body}") - is Request.ToDevice -> Timber.v("HELLO TO DEVICE REQUEST ${request.body}") - } - } + Timber.v("HELLLO WORLD STARTING $dataDir CRYPTO ${olmMachine?.identityKeys()}") } catch (throwable: Throwable) { Timber.v("HELLLO WORLD FAILED CRYPTO $throwable") } @@ -444,7 +438,11 @@ internal class DefaultCryptoService @Inject constructor( * * @param syncResponse the syncResponse */ - fun onSyncCompleted(syncResponse: SyncResponse) { + suspend fun onSyncCompleted(syncResponse: SyncResponse) { + if (isStarted()) { + sendOutgoingRequests() + } + cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { runCatching { if (syncResponse.deviceLists != null) { @@ -457,7 +455,7 @@ internal class DefaultCryptoService @Inject constructor( if (isStarted()) { // Make sure we process to-device messages before generating new one-time-keys #2782 deviceListManager.refreshOutdatedDeviceLists() - oneTimeKeysUploader.maybeUploadOneTimeKeys() + // oneTimeKeysUploader.maybeUploadOneTimeKeys() incomingGossipingRequestManager.processReceivedGossipingRequests() } } @@ -939,27 +937,49 @@ internal class DefaultCryptoService @Inject constructor( } } + private suspend fun sendOutgoingRequests() { + // TODO these requests should be sent out in parallel + for (outgoingRequest in olmMachine!!.outgoingRequests()) { + when (outgoingRequest) { + is Request.KeysUpload -> { + Timber.v("HELLO UPLOADING RUSTY KEYS") + val body = MoshiProvider.providesMoshi().adapter(Map::class.java).fromJson(outgoingRequest.body)!! + val request = NewUploadKeysTask.Params(body) + + val response = newUploadKeysTask.execute(request) + val adapter = MoshiProvider.providesMoshi().adapter(KeysUploadResponse::class.java) + val json_response = adapter.toJson(response)!! + olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_UPLOAD, json_response) + Timber.v("HELLO UPLOADED KEYS $response") + } + is Request.KeysQuery -> Timber.v("HELLO KEYS QUERY REQUEST ${outgoingRequest.body}") + is Request.ToDevice -> Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") + } + } + } + /** * Upload my user's device keys. */ private suspend fun uploadDeviceKeys() { - if (cryptoStore.getDeviceKeysUploaded()) { - Timber.d("Keys already uploaded, nothing to do") - return - } - // Prepare the device keys data to send - // Sign it - val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, getMyDevice().signalableJSONDictionary()) - var rest = getMyDevice().toRest() + // sendOutgoingRequests() + // if (cryptoStore.getDeviceKeysUploaded()) { + // Timber.d("Keys already uploaded, nothing to do") + // return + // } + // // Prepare the device keys data to send + // // Sign it + // val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, getMyDevice().signalableJSONDictionary()) + // var rest = getMyDevice().toRest() - rest = rest.copy( - signatures = objectSigner.signObject(canonicalJson) - ) + // rest = rest.copy( + // signatures = objectSigner.signObject(canonicalJson) + // ) - val uploadDeviceKeysParams = UploadKeysTask.Params(rest, null) - uploadKeysTask.execute(uploadDeviceKeysParams) + // val uploadDeviceKeysParams = UploadKeysTask.Params(rest, null) + // uploadKeysTask.execute(uploadDeviceKeysParams) - cryptoStore.setDeviceKeysUploaded(true) + // cryptoStore.setDeviceKeysUploaded(true) } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt index 5604e97152..104cb1e97f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt @@ -15,6 +15,7 @@ */ package org.matrix.android.sdk.internal.crypto.api +import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse @@ -64,6 +65,13 @@ internal interface CryptoApi { @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "keys/upload") fun uploadKeys(@Body body: KeysUploadBody): Call + /** + * Upload device and one-time keys + * @param body the keys to be sent. + */ + @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "keys/upload") + fun newUploadKeys(@Body body: JsonDict): Call + /** * Download device keys. * Doc: https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-keys-query diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt index eb53bbbf8d..0dbd87c537 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt @@ -54,3 +54,23 @@ internal class DefaultUploadKeysTask @Inject constructor( } } } + +internal interface NewUploadKeysTask : Task { + data class Params( + val body: JsonDict + ) +} + +internal class NewDefaultUploadKeysTask @Inject constructor( + private val cryptoApi: CryptoApi, + private val globalErrorReceiver: GlobalErrorReceiver +) : NewUploadKeysTask { + + override suspend fun execute(params: NewUploadKeysTask.Params): KeysUploadResponse { + Timber.i("## Uploading device keys -> $params.body") + + return executeRequest(globalErrorReceiver) { + apiCall = cryptoApi.newUploadKeys(params.body) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt index fc476a3dd6..1e08b86d4b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt @@ -52,7 +52,7 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService: } } - fun onSyncCompleted(syncResponse: SyncResponse) { + suspend fun onSyncCompleted(syncResponse: SyncResponse) { cryptoService.onSyncCompleted(syncResponse) } From 4589b882c051cdfd83a6c408b57d74e1ae2c0ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 16 Feb 2021 11:18:31 +0100 Subject: [PATCH 010/252] rust: Add support to forward rust logs to the kotlin side --- rust-sdk/Cargo.toml | 7 ++++-- rust-sdk/src/lib.rs | 55 ++++++++++++++++++++++++++++++++++++++++---- rust-sdk/src/olm.udl | 8 ++++++- 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 54709d0928..ce3afcd490 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -11,10 +11,13 @@ name = "matrix_crypto" [dependencies] matrix-sdk-common = { git = "https://github.com/matrix-org/matrix-rust-sdk/"} futures = { version = "0.3.12", default_features = false, features = ["executor"] } -tokio = { version = "1.1.1", default_features = false, features = ["rt-multi-thread", "time"] } -serde_json = "1.0.61" +tokio = { version = "1.2.0", default_features = false, features = ["rt-multi-thread", "time"] } +serde_json = "1.0.62" thiserror = "1.0.23" http = "0.2.3" +tracing = "0.1.23" +tracing-subscriber = "0.2.15" +once_cell = "1.5.2" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index f5ed343a74..3b84ce53c9 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,6 +1,7 @@ use std::{ collections::{BTreeMap, HashMap}, convert::TryFrom, + sync::{Arc, Mutex}, time::Duration, }; @@ -25,6 +26,55 @@ use matrix_sdk_crypto::{ store::CryptoStoreError as InnerStoreError, IncomingResponse, OlmError, OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, }; +use tracing_subscriber::{fmt::MakeWriter, EnvFilter}; + +pub trait Logger: Send { + fn log(&self, log_line: String); +} + +impl std::io::Write for LoggerWrapper { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + let data = String::from_utf8_lossy(buf).to_string(); + self.inner.lock().unwrap().log(data); + + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +impl MakeWriter for LoggerWrapper { + type Writer = LoggerWrapper; + + fn make_writer(&self) -> Self::Writer { + self.clone() + } +} + +#[derive(Clone)] +pub struct LoggerWrapper { + inner: Arc>>, +} + +pub fn set_logger(logger: Box) { + let logger = LoggerWrapper { + inner: Arc::new(Mutex::new(logger)), + }; + + let filter = EnvFilter::from_default_env().add_directive( + "matrix_sdk_crypto=trace" + .parse() + .expect("Can't parse logging filter directive"), + ); + + let _ = tracing_subscriber::fmt() + .with_writer(logger) + .with_env_filter(filter) + .without_time() + .try_init(); +} pub struct OlmMachine { inner: InnerMachine, @@ -205,10 +255,7 @@ impl OlmMachine { Ok(OlmMachine { inner: block_on(InnerMachine::new_with_default_store( - &user_id, - device_id, - path, - Some("DEFAULT_PASSPHRASE"), + &user_id, device_id, path, None, ))?, runtime: Runtime::new().unwrap(), }) diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 1a49fee8d9..8d90cbadd4 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -1,4 +1,10 @@ -namespace olm {}; +namespace olm { + void set_logger(Logger logger); +}; + +callback interface Logger { + void log(string log_line); +}; [Error] enum MachineCreationError { From d50df9537cc6f7d8a698087862a4f5e6a1d39223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 16 Feb 2021 11:26:24 +0100 Subject: [PATCH 011/252] crypto: Connect the rust logger to timber --- .../sdk/internal/crypto/DefaultCryptoService.kt | 2 ++ .../org/matrix/android/sdk/internal/newCrypto.kt | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index ac51e1dca0..de73e04f12 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -57,6 +57,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityConten import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.OlmMachine +import org.matrix.android.sdk.internal.setRustLogger import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting @@ -375,6 +376,7 @@ internal class DefaultCryptoService @Inject constructor( Timber.v("HELLLO WORLD STARTING CRYPTO") try { + setRustLogger() olmMachine = OlmMachine(userId, deviceId!!, dataDir) Timber.v("HELLLO WORLD STARTING $dataDir CRYPTO ${olmMachine?.identityKeys()}") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 22da46ee33..20bde0ca1d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -24,6 +24,20 @@ import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.Request import uniffi.olm.RequestType import uniffi.olm.Sas as InnerSas +import uniffi.olm.Logger +import uniffi.olm.setLogger + +import timber.log.Timber + +class CryptoLogger(): Logger { + override fun log(logLine: String) { + Timber.d(logLine) + } +} + +fun setRustLogger() { + setLogger(CryptoLogger() as Logger) +} class Device(inner: InnerDevice, machine: InnerMachine) { private val machine: InnerMachine = machine From 75838fda2afbe91a4b2be43d72653d30cbab9b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 16 Feb 2021 11:34:01 +0100 Subject: [PATCH 012/252] rust: Move the olm machine into a separate module --- rust-sdk/src/lib.rs | 343 +--------------------------------------- rust-sdk/src/machine.rs | 337 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 345 insertions(+), 335 deletions(-) create mode 100644 rust-sdk/src/machine.rs diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 3b84ce53c9..f2a55309be 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,33 +1,14 @@ -use std::{ - collections::{BTreeMap, HashMap}, - convert::TryFrom, - sync::{Arc, Mutex}, - time::Duration, -}; +use std::sync::{Arc, Mutex}; -use futures::executor::block_on; -use http::Response; -use serde_json::json; -use tokio::{runtime::Runtime, time::sleep}; - -use matrix_sdk_common::{ - api::r0::{ - keys::{ - claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, - upload_keys::Response as KeysUploadResponse, - }, - sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, - }, - identifiers::{DeviceKeyAlgorithm, Error as RumaIdentifierError, UserId}, - uuid::Uuid, - UInt, -}; -use matrix_sdk_crypto::{ - store::CryptoStoreError as InnerStoreError, IncomingResponse, OlmError, - OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, -}; use tracing_subscriber::{fmt::MakeWriter, EnvFilter}; +mod machine; + +pub use machine::{ + CryptoStoreError, Device, DeviceLists, MachineCreationError, OlmMachine, Request, RequestType, + Sas, +}; + pub trait Logger: Send { fn log(&self, log_line: String); } @@ -76,312 +57,4 @@ pub fn set_logger(logger: Box) { .try_init(); } -pub struct OlmMachine { - inner: InnerMachine, - runtime: Runtime, -} - -pub struct DeviceLists { - pub changed: Vec, - pub left: Vec, -} - -impl Into for DeviceLists { - fn into(self) -> RumaDeviceLists { - RumaDeviceLists { - changed: self - .changed - .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) - .collect(), - left: self - .left - .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) - .collect(), - } - } -} - -enum OwnedResponse { - KeysClaim(KeysClaimResponse), - KeysUpload(KeysUploadResponse), - KeysQuery(KeysQueryResponse), -} - -impl From for OwnedResponse { - fn from(response: KeysClaimResponse) -> Self { - OwnedResponse::KeysClaim(response) - } -} - -impl From for OwnedResponse { - fn from(response: KeysQueryResponse) -> Self { - OwnedResponse::KeysQuery(response) - } -} - -impl From for OwnedResponse { - fn from(response: KeysUploadResponse) -> Self { - OwnedResponse::KeysUpload(response) - } -} - -impl<'a> Into> for &'a OwnedResponse { - fn into(self) -> IncomingResponse<'a> { - match self { - OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), - OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), - OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), - } - } -} - -#[derive(Debug, thiserror::Error)] -pub enum MachineCreationError { - #[error(transparent)] - Identifier(#[from] RumaIdentifierError), - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), -} - -#[derive(Debug, thiserror::Error)] -pub enum CryptoStoreError { - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), - #[error(transparent)] - OlmError(#[from] OlmError), -} - -pub enum RequestType { - KeysQuery, - KeysUpload, - ToDevice, -} - -pub struct Device { - pub user_id: String, - pub device_id: String, - pub keys: HashMap, -} - -pub struct Sas { - pub other_user_id: String, - pub other_device_id: String, - pub flow_id: String, - pub request: Request, -} - -pub enum Request { - ToDevice { - request_id: String, - event_type: String, - body: String, - }, - KeysUpload { - request_id: String, - body: String, - }, - KeysQuery { - request_id: String, - body: String, - }, -} - -impl From for Request { - fn from(r: OutgoingRequest) -> Self { - use matrix_sdk_crypto::OutgoingRequests::*; - - match r.request() { - KeysUpload(u) => { - let body = json!({ - "device_keys": u.device_keys, - "one_time_keys": u.one_time_keys, - }); - - Request::KeysUpload { - request_id: r.request_id().to_string(), - body: serde_json::to_string(&body) - .expect("Can't serialize keys upload request"), - } - } - KeysQuery(k) => { - let body = json!({ - "device_keys": k.device_keys, - }); - Request::KeysQuery { - request_id: r.request_id().to_string(), - body: serde_json::to_string(&body).expect("Can't serialize keys query request"), - } - } - ToDeviceRequest(t) => Request::from(t), - SignatureUpload(_) => todo!(), - RoomMessage(_) => todo!(), - } - } -} - -impl From for Request { - fn from(r: ToDeviceRequest) -> Self { - Request::ToDevice { - request_id: r.txn_id_string(), - event_type: r.event_type.to_string(), - body: serde_json::to_string(&r.messages).unwrap(), - } - } -} - -impl From<&ToDeviceRequest> for Request { - fn from(r: &ToDeviceRequest) -> Self { - Request::ToDevice { - request_id: r.txn_id_string(), - event_type: r.event_type.to_string(), - body: serde_json::to_string(&r.messages).unwrap(), - } - } -} - -fn response_from_string(body: &str) -> Response> { - Response::builder() - .status(200) - .body(body.as_bytes().to_vec()) - .expect("Can't create HTTP response") -} - -impl OlmMachine { - pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { - let user_id = UserId::try_from(user_id)?; - let device_id = device_id.into(); - - Ok(OlmMachine { - inner: block_on(InnerMachine::new_with_default_store( - &user_id, device_id, path, None, - ))?, - runtime: Runtime::new().unwrap(), - }) - } - - pub fn user_id(&self) -> String { - self.inner.user_id().to_string() - } - - pub fn device_id(&self) -> String { - self.inner.device_id().to_string() - } - - pub fn get_device(&self, user_id: &str, device_id: &str) -> Option { - let user_id = UserId::try_from(user_id).unwrap(); - - block_on(self.inner.get_device(&user_id, device_id.into())) - .unwrap() - .map(|d| Device { - user_id: d.user_id().to_string(), - device_id: d.device_id().to_string(), - keys: d - .keys() - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - }) - } - - pub fn get_user_devices(&self, user_id: &str) -> Vec { - let user_id = UserId::try_from(user_id).unwrap(); - block_on(self.inner.get_user_devices(&user_id)) - .unwrap() - .devices() - .map(|d| Device { - user_id: d.user_id().to_string(), - device_id: d.device_id().to_string(), - keys: d - .keys() - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - }) - .collect() - } - - pub fn identity_keys(&self) -> HashMap { - self.inner - .identity_keys() - .iter() - .map(|(k, v)| (k.to_owned(), v.to_owned())) - .collect() - } - - pub fn slow_user_id(&self) -> String { - let machine = self.inner.clone(); - - self.runtime.block_on(async { - sleep(Duration::from_secs(10)).await; - machine.user_id().to_string() - }) - } - - pub fn mark_request_as_sent( - &self, - request_id: &str, - request_type: RequestType, - response_body: &str, - ) -> Result<(), CryptoStoreError> { - let id = Uuid::parse_str(request_id).expect("Can't parse request id"); - - let response = response_from_string(&response_body); - - let response: OwnedResponse = match request_type { - RequestType::KeysUpload => KeysUploadResponse::try_from(response).map(Into::into), - RequestType::KeysQuery => KeysQueryResponse::try_from(response).map(Into::into), - RequestType::ToDevice => KeysClaimResponse::try_from(response).map(Into::into), - } - .expect("Can't convert json string to response"); - - block_on(self.inner.mark_request_as_sent(&id, &response))?; - - Ok(()) - } - - pub fn start_verification(&self, device: &Device) -> Result { - let user_id = UserId::try_from(device.user_id.clone()).unwrap(); - let device_id = device.device_id.as_str().into(); - let device = block_on(self.inner.get_device(&user_id, device_id))?.unwrap(); - - let (sas, request) = block_on(device.start_verification())?; - - Ok(Sas { - other_user_id: sas.other_user_id().to_string(), - other_device_id: sas.other_device_id().to_string(), - flow_id: sas.flow_id().as_str().to_owned(), - request: request.into(), - }) - } - - pub fn outgoing_requests(&self) -> Vec { - block_on(self.inner.outgoing_requests()) - .into_iter() - .map(|r| r.into()) - .collect() - } - - pub fn receive_sync_changes( - &self, - events: &str, - device_changes: DeviceLists, - key_counts: HashMap, - ) { - let events: ToDevice = serde_json::from_str(events).unwrap(); - let device_changes: RumaDeviceLists = device_changes.into(); - let key_counts: BTreeMap = key_counts - .into_iter() - .map(|(k, v)| (DeviceKeyAlgorithm::from(k), v.into())) - .collect(); - - block_on( - self.inner - .receive_sync_changes(&events, &device_changes, &key_counts), - ) - .unwrap(); - } -} - include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs new file mode 100644 index 0000000000..e83cd48670 --- /dev/null +++ b/rust-sdk/src/machine.rs @@ -0,0 +1,337 @@ +use std::{ + collections::{BTreeMap, HashMap}, + convert::TryFrom, + time::Duration, +}; + +use futures::executor::block_on; +use http::Response; +use serde_json::json; +use tokio::{runtime::Runtime, time::sleep}; + +use matrix_sdk_common::{ + api::r0::{ + keys::{ + claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, + upload_keys::Response as KeysUploadResponse, + }, + sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, + }, + identifiers::{DeviceKeyAlgorithm, Error as RumaIdentifierError, UserId}, + uuid::Uuid, + UInt, +}; + +use matrix_sdk_crypto::{ + store::CryptoStoreError as InnerStoreError, IncomingResponse, OlmError, + OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, +}; + +pub struct OlmMachine { + inner: InnerMachine, + runtime: Runtime, +} + +pub struct DeviceLists { + pub changed: Vec, + pub left: Vec, +} + +impl Into for DeviceLists { + fn into(self) -> RumaDeviceLists { + RumaDeviceLists { + changed: self + .changed + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(), + left: self + .left + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(), + } + } +} + +enum OwnedResponse { + KeysClaim(KeysClaimResponse), + KeysUpload(KeysUploadResponse), + KeysQuery(KeysQueryResponse), +} + +impl From for OwnedResponse { + fn from(response: KeysClaimResponse) -> Self { + OwnedResponse::KeysClaim(response) + } +} + +impl From for OwnedResponse { + fn from(response: KeysQueryResponse) -> Self { + OwnedResponse::KeysQuery(response) + } +} + +impl From for OwnedResponse { + fn from(response: KeysUploadResponse) -> Self { + OwnedResponse::KeysUpload(response) + } +} + +impl<'a> Into> for &'a OwnedResponse { + fn into(self) -> IncomingResponse<'a> { + match self { + OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), + OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), + OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), + } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum MachineCreationError { + #[error(transparent)] + Identifier(#[from] RumaIdentifierError), + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), +} + +#[derive(Debug, thiserror::Error)] +pub enum CryptoStoreError { + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), + #[error(transparent)] + OlmError(#[from] OlmError), +} + +pub enum RequestType { + KeysQuery, + KeysUpload, + ToDevice, +} + +pub struct Device { + pub user_id: String, + pub device_id: String, + pub keys: HashMap, +} + +pub struct Sas { + pub other_user_id: String, + pub other_device_id: String, + pub flow_id: String, + pub request: Request, +} + +pub enum Request { + ToDevice { + request_id: String, + event_type: String, + body: String, + }, + KeysUpload { + request_id: String, + body: String, + }, + KeysQuery { + request_id: String, + body: String, + }, +} + +impl From for Request { + fn from(r: OutgoingRequest) -> Self { + use matrix_sdk_crypto::OutgoingRequests::*; + + match r.request() { + KeysUpload(u) => { + let body = json!({ + "device_keys": u.device_keys, + "one_time_keys": u.one_time_keys, + }); + + Request::KeysUpload { + request_id: r.request_id().to_string(), + body: serde_json::to_string(&body) + .expect("Can't serialize keys upload request"), + } + } + KeysQuery(k) => { + let body = json!({ + "device_keys": k.device_keys, + }); + Request::KeysQuery { + request_id: r.request_id().to_string(), + body: serde_json::to_string(&body).expect("Can't serialize keys query request"), + } + } + ToDeviceRequest(t) => Request::from(t), + SignatureUpload(_) => todo!(), + RoomMessage(_) => todo!(), + } + } +} + +impl From for Request { + fn from(r: ToDeviceRequest) -> Self { + Request::ToDevice { + request_id: r.txn_id_string(), + event_type: r.event_type.to_string(), + body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +impl From<&ToDeviceRequest> for Request { + fn from(r: &ToDeviceRequest) -> Self { + Request::ToDevice { + request_id: r.txn_id_string(), + event_type: r.event_type.to_string(), + body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +fn response_from_string(body: &str) -> Response> { + Response::builder() + .status(200) + .body(body.as_bytes().to_vec()) + .expect("Can't create HTTP response") +} + +impl OlmMachine { + pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { + let user_id = UserId::try_from(user_id)?; + let device_id = device_id.into(); + + Ok(OlmMachine { + inner: block_on(InnerMachine::new_with_default_store( + &user_id, device_id, path, None, + ))?, + runtime: Runtime::new().unwrap(), + }) + } + + pub fn user_id(&self) -> String { + self.inner.user_id().to_string() + } + + pub fn device_id(&self) -> String { + self.inner.device_id().to_string() + } + + pub fn get_device(&self, user_id: &str, device_id: &str) -> Option { + let user_id = UserId::try_from(user_id).unwrap(); + + block_on(self.inner.get_device(&user_id, device_id.into())) + .unwrap() + .map(|d| Device { + user_id: d.user_id().to_string(), + device_id: d.device_id().to_string(), + keys: d + .keys() + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + }) + } + + pub fn get_user_devices(&self, user_id: &str) -> Vec { + let user_id = UserId::try_from(user_id).unwrap(); + block_on(self.inner.get_user_devices(&user_id)) + .unwrap() + .devices() + .map(|d| Device { + user_id: d.user_id().to_string(), + device_id: d.device_id().to_string(), + keys: d + .keys() + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + }) + .collect() + } + + pub fn identity_keys(&self) -> HashMap { + self.inner + .identity_keys() + .iter() + .map(|(k, v)| (k.to_owned(), v.to_owned())) + .collect() + } + + pub fn slow_user_id(&self) -> String { + let machine = self.inner.clone(); + + self.runtime.block_on(async { + sleep(Duration::from_secs(10)).await; + machine.user_id().to_string() + }) + } + + pub fn mark_request_as_sent( + &self, + request_id: &str, + request_type: RequestType, + response_body: &str, + ) -> Result<(), CryptoStoreError> { + let id = Uuid::parse_str(request_id).expect("Can't parse request id"); + + let response = response_from_string(&response_body); + + let response: OwnedResponse = match request_type { + RequestType::KeysUpload => KeysUploadResponse::try_from(response).map(Into::into), + RequestType::KeysQuery => KeysQueryResponse::try_from(response).map(Into::into), + RequestType::ToDevice => KeysClaimResponse::try_from(response).map(Into::into), + } + .expect("Can't convert json string to response"); + + block_on(self.inner.mark_request_as_sent(&id, &response))?; + + Ok(()) + } + + pub fn start_verification(&self, device: &Device) -> Result { + let user_id = UserId::try_from(device.user_id.clone()).unwrap(); + let device_id = device.device_id.as_str().into(); + let device = block_on(self.inner.get_device(&user_id, device_id))?.unwrap(); + + let (sas, request) = block_on(device.start_verification())?; + + Ok(Sas { + other_user_id: sas.other_user_id().to_string(), + other_device_id: sas.other_device_id().to_string(), + flow_id: sas.flow_id().as_str().to_owned(), + request: request.into(), + }) + } + + pub fn outgoing_requests(&self) -> Vec { + block_on(self.inner.outgoing_requests()) + .into_iter() + .map(|r| r.into()) + .collect() + } + + pub fn receive_sync_changes( + &self, + events: &str, + device_changes: DeviceLists, + key_counts: HashMap, + ) { + let events: ToDevice = serde_json::from_str(events).unwrap(); + let device_changes: RumaDeviceLists = device_changes.into(); + let key_counts: BTreeMap = key_counts + .into_iter() + .map(|(k, v)| (DeviceKeyAlgorithm::from(k), v.into())) + .collect(); + + block_on( + self.inner + .receive_sync_changes(&events, &device_changes, &key_counts), + ) + .unwrap(); + } +} + From 2d620e2ddf3ede1085002b59fb2e3e746d353830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 16 Feb 2021 11:37:18 +0100 Subject: [PATCH 013/252] rust: Move the errors into a separate module --- rust-sdk/src/error.rs | 19 +++++++++++++++++++ rust-sdk/src/lib.rs | 7 +++---- rust-sdk/src/machine.rs | 24 ++++-------------------- 3 files changed, 26 insertions(+), 24 deletions(-) create mode 100644 rust-sdk/src/error.rs diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs new file mode 100644 index 0000000000..a2f3c57684 --- /dev/null +++ b/rust-sdk/src/error.rs @@ -0,0 +1,19 @@ +use matrix_sdk_common::identifiers::Error as RumaIdentifierError; + +use matrix_sdk_crypto::{store::CryptoStoreError as InnerStoreError, OlmError}; + +#[derive(Debug, thiserror::Error)] +pub enum MachineCreationError { + #[error(transparent)] + Identifier(#[from] RumaIdentifierError), + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), +} + +#[derive(Debug, thiserror::Error)] +pub enum CryptoStoreError { + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), + #[error(transparent)] + OlmError(#[from] OlmError), +} diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index f2a55309be..52becf3f1d 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -2,12 +2,11 @@ use std::sync::{Arc, Mutex}; use tracing_subscriber::{fmt::MakeWriter, EnvFilter}; +mod error; mod machine; -pub use machine::{ - CryptoStoreError, Device, DeviceLists, MachineCreationError, OlmMachine, Request, RequestType, - Sas, -}; +pub use error::*; +pub use machine::{Device, DeviceLists, OlmMachine, Request, RequestType, Sas}; pub trait Logger: Send { fn log(&self, log_line: String); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index e83cd48670..4894fd7074 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -17,16 +17,17 @@ use matrix_sdk_common::{ }, sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, }, - identifiers::{DeviceKeyAlgorithm, Error as RumaIdentifierError, UserId}, + identifiers::{DeviceKeyAlgorithm, UserId}, uuid::Uuid, UInt, }; use matrix_sdk_crypto::{ - store::CryptoStoreError as InnerStoreError, IncomingResponse, OlmError, - OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, + IncomingResponse, OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, }; +use crate::error::{CryptoStoreError, MachineCreationError}; + pub struct OlmMachine { inner: InnerMachine, runtime: Runtime, @@ -88,22 +89,6 @@ impl<'a> Into> for &'a OwnedResponse { } } -#[derive(Debug, thiserror::Error)] -pub enum MachineCreationError { - #[error(transparent)] - Identifier(#[from] RumaIdentifierError), - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), -} - -#[derive(Debug, thiserror::Error)] -pub enum CryptoStoreError { - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), - #[error(transparent)] - OlmError(#[from] OlmError), -} - pub enum RequestType { KeysQuery, KeysUpload, @@ -334,4 +319,3 @@ impl OlmMachine { .unwrap(); } } - From 504e1e31bd5702d43d354e2df7b4c5db5fc6fc5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 16 Feb 2021 11:38:54 +0100 Subject: [PATCH 014/252] rust: Move the logger into a separate module --- rust-sdk/src/lib.rs | 54 ++---------------------------------------- rust-sdk/src/logger.rs | 53 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 52 deletions(-) create mode 100644 rust-sdk/src/logger.rs diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 52becf3f1d..01f7e1c3c7 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,59 +1,9 @@ -use std::sync::{Arc, Mutex}; - -use tracing_subscriber::{fmt::MakeWriter, EnvFilter}; - mod error; +mod logger; mod machine; pub use error::*; +pub use logger::{set_logger, Logger}; pub use machine::{Device, DeviceLists, OlmMachine, Request, RequestType, Sas}; -pub trait Logger: Send { - fn log(&self, log_line: String); -} - -impl std::io::Write for LoggerWrapper { - fn write(&mut self, buf: &[u8]) -> std::io::Result { - let data = String::from_utf8_lossy(buf).to_string(); - self.inner.lock().unwrap().log(data); - - Ok(buf.len()) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } -} - -impl MakeWriter for LoggerWrapper { - type Writer = LoggerWrapper; - - fn make_writer(&self) -> Self::Writer { - self.clone() - } -} - -#[derive(Clone)] -pub struct LoggerWrapper { - inner: Arc>>, -} - -pub fn set_logger(logger: Box) { - let logger = LoggerWrapper { - inner: Arc::new(Mutex::new(logger)), - }; - - let filter = EnvFilter::from_default_env().add_directive( - "matrix_sdk_crypto=trace" - .parse() - .expect("Can't parse logging filter directive"), - ); - - let _ = tracing_subscriber::fmt() - .with_writer(logger) - .with_env_filter(filter) - .without_time() - .try_init(); -} - include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/logger.rs b/rust-sdk/src/logger.rs new file mode 100644 index 0000000000..3ddef223fd --- /dev/null +++ b/rust-sdk/src/logger.rs @@ -0,0 +1,53 @@ +use std::{ + io::{Result, Write}, + sync::{Arc, Mutex}, +}; +use tracing_subscriber::{fmt::MakeWriter, EnvFilter}; + +pub trait Logger: Send { + fn log(&self, log_line: String); +} + +impl Write for LoggerWrapper { + fn write(&mut self, buf: &[u8]) -> Result { + let data = String::from_utf8_lossy(buf).to_string(); + self.inner.lock().unwrap().log(data); + + Ok(buf.len()) + } + + fn flush(&mut self) -> Result<()> { + Ok(()) + } +} + +impl MakeWriter for LoggerWrapper { + type Writer = LoggerWrapper; + + fn make_writer(&self) -> Self::Writer { + self.clone() + } +} + +#[derive(Clone)] +pub struct LoggerWrapper { + inner: Arc>>, +} + +pub fn set_logger(logger: Box) { + let logger = LoggerWrapper { + inner: Arc::new(Mutex::new(logger)), + }; + + let filter = EnvFilter::from_default_env().add_directive( + "matrix_sdk_crypto=trace" + .parse() + .expect("Can't parse logging filter directive"), + ); + + let _ = tracing_subscriber::fmt() + .with_writer(logger) + .with_env_filter(filter) + .without_time() + .try_init(); +} From 930e6f4e9bf825eea7587d2b42c6365a47efc274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 16 Feb 2021 13:10:10 +0100 Subject: [PATCH 015/252] rust: Remove an unused method --- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 01f7e1c3c7..a45c788d26 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -2,7 +2,7 @@ mod error; mod logger; mod machine; -pub use error::*; +pub use error::{CryptoStoreError, MachineCreationError}; pub use logger::{set_logger, Logger}; pub use machine::{Device, DeviceLists, OlmMachine, Request, RequestType, Sas}; diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 4894fd7074..7f96f61ae6 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -246,15 +246,6 @@ impl OlmMachine { .collect() } - pub fn slow_user_id(&self) -> String { - let machine = self.inner.clone(); - - self.runtime.block_on(async { - sleep(Duration::from_secs(10)).await; - machine.user_id().to_string() - }) - } - pub fn mark_request_as_sent( &self, request_id: &str, From 01149c8d459c7ff4dbca8a39ab7dfb2b1f91b8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 16 Feb 2021 15:13:31 +0100 Subject: [PATCH 016/252] rust: Clean up our deps --- rust-sdk/Cargo.toml | 18 ++++++++--------- rust-sdk/src/machine.rs | 44 ++++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index ce3afcd490..25030e115b 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -10,30 +10,28 @@ name = "matrix_crypto" [dependencies] matrix-sdk-common = { git = "https://github.com/matrix-org/matrix-rust-sdk/"} -futures = { version = "0.3.12", default_features = false, features = ["executor"] } -tokio = { version = "1.2.0", default_features = false, features = ["rt-multi-thread", "time"] } + serde_json = "1.0.62" -thiserror = "1.0.23" http = "0.2.3" + +thiserror = "1.0.23" tracing = "0.1.23" tracing-subscriber = "0.2.15" -once_cell = "1.5.2" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" features = ["sled_cryptostore"] +[dependencies.tokio] +version = "1.2.0" +default_features = false +features = ["rt-multi-thread"] + [dependencies.uniffi] version = "0.7.0" git = "https://github.com/mozilla/uniffi-rs" branch = "tagged-unions" -[dependencies.ruma] -version = "0.0.2" -git = "https://github.com/ruma/ruma" -rev = "d6aa37c848b7f682a98c25b346899e284ffc6df7" -features = ["client-api", "compat", "unstable-pre-spec", "unstable-exhaustive-types"] - [build-dependencies] uniffi_build = "0.7.0" diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 7f96f61ae6..e1a9d01b8c 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -1,13 +1,11 @@ use std::{ collections::{BTreeMap, HashMap}, convert::TryFrom, - time::Duration, }; -use futures::executor::block_on; use http::Response; use serde_json::json; -use tokio::{runtime::Runtime, time::sleep}; +use tokio::runtime::Runtime; use matrix_sdk_common::{ api::r0::{ @@ -17,6 +15,7 @@ use matrix_sdk_common::{ }, sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, }, + assign, identifiers::{DeviceKeyAlgorithm, UserId}, uuid::Uuid, UInt, @@ -40,7 +39,7 @@ pub struct DeviceLists { impl Into for DeviceLists { fn into(self) -> RumaDeviceLists { - RumaDeviceLists { + assign!(RumaDeviceLists::new(), { changed: self .changed .into_iter() @@ -51,7 +50,7 @@ impl Into for DeviceLists { .into_iter() .filter_map(|u| UserId::try_from(u).ok()) .collect(), - } + }) } } @@ -188,12 +187,13 @@ impl OlmMachine { pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { let user_id = UserId::try_from(user_id)?; let device_id = device_id.into(); + let runtime = Runtime::new().unwrap(); Ok(OlmMachine { - inner: block_on(InnerMachine::new_with_default_store( + inner: runtime.block_on(InnerMachine::new_with_default_store( &user_id, device_id, path, None, ))?, - runtime: Runtime::new().unwrap(), + runtime, }) } @@ -208,7 +208,8 @@ impl OlmMachine { pub fn get_device(&self, user_id: &str, device_id: &str) -> Option { let user_id = UserId::try_from(user_id).unwrap(); - block_on(self.inner.get_device(&user_id, device_id.into())) + self.runtime + .block_on(self.inner.get_device(&user_id, device_id.into())) .unwrap() .map(|d| Device { user_id: d.user_id().to_string(), @@ -223,7 +224,8 @@ impl OlmMachine { pub fn get_user_devices(&self, user_id: &str) -> Vec { let user_id = UserId::try_from(user_id).unwrap(); - block_on(self.inner.get_user_devices(&user_id)) + self.runtime + .block_on(self.inner.get_user_devices(&user_id)) .unwrap() .devices() .map(|d| Device { @@ -263,7 +265,8 @@ impl OlmMachine { } .expect("Can't convert json string to response"); - block_on(self.inner.mark_request_as_sent(&id, &response))?; + self.runtime + .block_on(self.inner.mark_request_as_sent(&id, &response))?; Ok(()) } @@ -271,9 +274,12 @@ impl OlmMachine { pub fn start_verification(&self, device: &Device) -> Result { let user_id = UserId::try_from(device.user_id.clone()).unwrap(); let device_id = device.device_id.as_str().into(); - let device = block_on(self.inner.get_device(&user_id, device_id))?.unwrap(); + let device = self + .runtime + .block_on(self.inner.get_device(&user_id, device_id))? + .unwrap(); - let (sas, request) = block_on(device.start_verification())?; + let (sas, request) = self.runtime.block_on(device.start_verification())?; Ok(Sas { other_user_id: sas.other_user_id().to_string(), @@ -284,7 +290,8 @@ impl OlmMachine { } pub fn outgoing_requests(&self) -> Vec { - block_on(self.inner.outgoing_requests()) + self.runtime + .block_on(self.inner.outgoing_requests()) .into_iter() .map(|r| r.into()) .collect() @@ -303,10 +310,11 @@ impl OlmMachine { .map(|(k, v)| (DeviceKeyAlgorithm::from(k), v.into())) .collect(); - block_on( - self.inner - .receive_sync_changes(&events, &device_changes, &key_counts), - ) - .unwrap(); + self.runtime + .block_on( + self.inner + .receive_sync_changes(&events, &device_changes, &key_counts), + ) + .unwrap(); } } From e2692ec6045ae62c40e46019f3ce7810579f4041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 17 Feb 2021 15:50:49 +0100 Subject: [PATCH 017/252] crypto: Forward sync crypto chagnes to the rust side --- .../internal/crypto/DefaultCryptoService.kt | 14 ++++++-- .../matrix/android/sdk/internal/newCrypto.kt | 32 ++++++++++++++++--- .../session/sync/SyncResponseHandler.kt | 14 ++++---- rust-sdk/Cargo.toml | 4 +++ rust-sdk/src/machine.rs | 13 ++++++-- rust-sdk/src/olm.udl | 2 +- 6 files changed, 61 insertions(+), 18 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index de73e04f12..fdbfc8148f 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -98,6 +98,9 @@ import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.session.sync.model.SyncResponse +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.ToDeviceSyncResponse import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.TaskThread import org.matrix.android.sdk.internal.task.configureWith @@ -321,9 +324,7 @@ internal class DefaultCryptoService @Inject constructor( * */ suspend fun start() { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - internalStart() - } + internalStart() // Just update fetchDevicesList(NoOpMatrixCallback()) @@ -939,6 +940,13 @@ internal class DefaultCryptoService @Inject constructor( } } + suspend fun receiveSyncChanges( + toDevice: ToDeviceSyncResponse?, + deviceChanges: DeviceListResponse?, + keyCounts: DeviceOneTimeKeysCountSyncResponse?) { + olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) + } + private suspend fun sendOutgoingRequests() { // TODO these requests should be sent out in parallel for (outgoingRequest in olmMachine!!.outgoingRequests()) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 20bde0ca1d..d654fa5520 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -19,17 +19,21 @@ package org.matrix.android.sdk.internal import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +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 +import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse +import timber.log.Timber import uniffi.olm.Device as InnerDevice +import uniffi.olm.DeviceLists +import uniffi.olm.Logger import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.Request import uniffi.olm.RequestType import uniffi.olm.Sas as InnerSas -import uniffi.olm.Logger import uniffi.olm.setLogger -import timber.log.Timber - -class CryptoLogger(): Logger { +class CryptoLogger() : Logger { override fun log(logLine: String) { Timber.d(logLine) } @@ -60,7 +64,7 @@ class Device(inner: InnerDevice, machine: InnerMachine) { } } -class OlmMachine(user_id: String, device_id: String, path: File) { +internal class OlmMachine(user_id: String, device_id: String, path: File) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) fun userId(): String { @@ -79,6 +83,24 @@ class OlmMachine(user_id: String, device_id: String, path: File) { inner.outgoingRequests() } + suspend fun receiveSyncChanges( + toDevice: ToDeviceSyncResponse?, + deviceChanges: DeviceListResponse?, + keyCounts: DeviceOneTimeKeysCountSyncResponse? + ) = withContext(Dispatchers.IO) { + var counts: MutableMap = mutableMapOf() + + if (keyCounts?.signedCurve25519 != null) { + counts.put("signed_curve25519", keyCounts.signedCurve25519) + } + + val devices = DeviceLists(deviceChanges?.changed ?: listOf(), deviceChanges?.left ?: listOf()) + val adapter = MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) + val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! + + inner.receiveSyncChanges(events, devices, counts) + } + suspend fun markRequestAsSent( request_id: String, request_type: RequestType, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index a80b062427..e306c1ad4c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -62,9 +62,10 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private measureTimeMillis { if (!cryptoService.isStarted()) { Timber.v("Should start cryptoService") + // TODO shirley there's a better place for this than the sync + // loop? cryptoService.start() } - cryptoService.onSyncWillProcess(isInitialSync) }.also { Timber.v("Finish handling start cryptoService in $it ms") } @@ -73,11 +74,12 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private // to ensure to decrypt them properly measureTimeMillis { Timber.v("Handle toDevice") - reportSubtask(reporter, R.string.initial_sync_start_importing_account_crypto, 100, 0.1f) { - if (syncResponse.toDevice != null) { - cryptoSyncHandler.handleToDevice(syncResponse.toDevice, reporter) - } - } + + cryptoService.receiveSyncChanges( + syncResponse.toDevice, + syncResponse.deviceLists, + syncResponse.deviceOneTimeKeysCount + ) }.also { Timber.v("Finish handling toDevice in $it ms") } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 25030e115b..b82f8ef7ff 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -18,6 +18,10 @@ thiserror = "1.0.23" tracing = "0.1.23" tracing-subscriber = "0.2.15" +[dependencies.js_int] +version = "0.2.0" +features = ["lax_deserialize"] + [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" features = ["sled_cryptostore"] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index e1a9d01b8c..b96bb653af 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -1,6 +1,6 @@ use std::{ collections::{BTreeMap, HashMap}, - convert::TryFrom, + convert::{TryFrom, TryInto}, }; use http::Response; @@ -301,13 +301,20 @@ impl OlmMachine { &self, events: &str, device_changes: DeviceLists, - key_counts: HashMap, + key_counts: HashMap, ) { let events: ToDevice = serde_json::from_str(events).unwrap(); let device_changes: RumaDeviceLists = device_changes.into(); let key_counts: BTreeMap = key_counts .into_iter() - .map(|(k, v)| (DeviceKeyAlgorithm::from(k), v.into())) + .map(|(k, v)| { + ( + DeviceKeyAlgorithm::from(k), + v.clamp(0, i32::MAX) + .try_into() + .expect("Couldn't convert key counts into an UInt"), + ) + }) .collect(); self.runtime diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 8d90cbadd4..b863641dfc 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -56,7 +56,7 @@ interface OlmMachine { void receive_sync_changes([ByRef] string events, DeviceLists device_changes, - record key_counts); + record key_counts); record identity_keys(); From f6d31f15f13d39f7ab165dea719c268681241080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 17 Feb 2021 16:08:05 +0100 Subject: [PATCH 018/252] gradle: Remove support for unsigned integers --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 370006d1c9..625ed348be 100644 --- a/build.gradle +++ b/build.gradle @@ -70,7 +70,6 @@ allprojects { // Warnings are potential errors, so stop ignoring them // You can override by passing `-PallWarningsAsErrors=false` in the command line kotlinOptions.allWarningsAsErrors = project.getProperties().getOrDefault("allWarningsAsErrors", "true").toBoolean() - kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.ExperimentalUnsignedTypes" } } From 8b1b771ae6a82332494d3ca0a0c9ad9cdbe9fb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 17 Feb 2021 16:09:12 +0100 Subject: [PATCH 019/252] gitignore: Ignore the generated uniffi sources --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 95f3c23914..0e02d3a959 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ /captures .externalNativeBuild rust-sdk/target/* +rust-sdk/src/uniffi/* Cargo.lock /tmp From 3b73adf3c57e237a55416f99d6da0936697ac79e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 19 Feb 2021 15:42:07 +0100 Subject: [PATCH 020/252] crypto: Connect the decryption logic to the rust olm machine --- .../internal/crypto/DefaultCryptoService.kt | 6 ++- .../matrix/android/sdk/internal/newCrypto.kt | 20 ++++++++ rust-sdk/Cargo.toml | 10 ++-- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 48 ++++++++++++++++++- rust-sdk/src/olm.udl | 9 ++++ 6 files changed, 87 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index fdbfc8148f..afec7d17d3 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -717,7 +717,11 @@ internal class DefaultCryptoService @Inject constructor( */ @Throws(MXCryptoError::class) override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { - return internalDecryptEvent(event, timeline) + val decrypted = runBlocking { + olmMachine!!.decryptRoomEvent(event) + } + + return decrypted } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index d654fa5520..261d469854 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -19,6 +19,9 @@ package org.matrix.android.sdk.internal import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult 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 @@ -115,4 +118,21 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { else -> Device(device, inner) } } + + suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val serializedEvent = adapter.toJson(event) + + val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId!!) + + val deserializationAdapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent)!! + + MXEventDecryptionResult( + clearEvent, + decrypted.senderCurve25519Key, + decrypted.claimedEd25519Key, + decrypted.forwardingCurve25519Chain + ) + } } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index b82f8ef7ff..f5a2e20e3c 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -9,8 +9,6 @@ crate-type = ["cdylib", "lib"] name = "matrix_crypto" [dependencies] -matrix-sdk-common = { git = "https://github.com/matrix-org/matrix-rust-sdk/"} - serde_json = "1.0.62" http = "0.2.3" @@ -22,8 +20,13 @@ tracing-subscriber = "0.2.15" version = "0.2.0" features = ["lax_deserialize"] +[dependencies.matrix-sdk-common] +git = "https://github.com/matrix-org/matrix-rust-sdk/" +branch = "encryption-info" + [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" +branch = "encryption-info" features = ["sled_cryptostore"] [dependencies.tokio] @@ -38,6 +41,3 @@ branch = "tagged-unions" [build-dependencies] uniffi_build = "0.7.0" - -[patch.crates-io] -olm-sys = { git = "https://gitlab.gnome.org/poljar/olm-sys/", branch = "android-cross" } diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index a45c788d26..799f045a3c 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -4,6 +4,6 @@ mod machine; pub use error::{CryptoStoreError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{Device, DeviceLists, OlmMachine, Request, RequestType, Sas}; +pub use machine::{DecryptedEvent, Device, DeviceLists, OlmMachine, Request, RequestType, Sas}; include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index b96bb653af..6ac6db6d76 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -16,7 +16,9 @@ use matrix_sdk_common::{ sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, }, assign, - identifiers::{DeviceKeyAlgorithm, UserId}, + deserialized_responses::events::{AlgorithmInfo, SyncMessageEvent}, + events::{room::encrypted::EncryptedEventContent, EventContent}, + identifiers::{DeviceKeyAlgorithm, RoomId, UserId}, uuid::Uuid, UInt, }; @@ -32,6 +34,13 @@ pub struct OlmMachine { runtime: Runtime, } +pub struct DecryptedEvent { + pub clear_event: String, + pub sender_curve25519_key: String, + pub claimed_ed25519_key: Option, + pub forwarding_curve25519_chain: Vec, +} + pub struct DeviceLists { pub changed: Vec, pub left: Vec, @@ -324,4 +333,41 @@ impl OlmMachine { ) .unwrap(); } + + pub fn decrypt_room_event(&self, event: &str, room_id: &str) -> DecryptedEvent { + let event: SyncMessageEvent = serde_json::from_str(event).unwrap(); + let room_id = RoomId::try_from(room_id).unwrap(); + + let decrypted = self + .runtime + .block_on(self.inner.decrypt_room_event(&event, &room_id)) + .unwrap(); + + let encryption_info = decrypted + .encryption_info() + .expect("Decrypted event didn't contain any encryption info"); + + let content = decrypted.content(); + + let clear_event = json!({ + "type": content.event_type(), + "content": content, + }); + + match &encryption_info.algorithm_info { + AlgorithmInfo::MegolmV1AesSha2 { + curve25519_key, + sender_claimed_keys, + forwarding_curve25519_key_chain, + } => DecryptedEvent { + clear_event: serde_json::to_string(&clear_event) + .expect("Can't serialize the decrypted json object"), + sender_curve25519_key: curve25519_key.to_owned(), + claimed_ed25519_key: sender_claimed_keys + .get(&DeviceKeyAlgorithm::Ed25519) + .cloned(), + forwarding_curve25519_chain: forwarding_curve25519_key_chain.to_owned(), + }, + } + } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index b863641dfc..6e0c9b5a50 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -23,6 +23,13 @@ dictionary DeviceLists { sequence left; }; +dictionary DecryptedEvent { + string clear_event; + string sender_curve25519_key; + string? claimed_ed25519_key; + sequence forwarding_curve25519_chain; +}; + dictionary Device { string user_id; string device_id; @@ -58,6 +65,8 @@ interface OlmMachine { DeviceLists device_changes, record key_counts); + DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id); + record identity_keys(); string user_id(); From 891622d64b8129aaf2fdf57a201fc481efe6bc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 19 Feb 2021 16:33:30 +0100 Subject: [PATCH 021/252] crypto: Propagate decryption errors to the kotlin side --- .../matrix/android/sdk/internal/newCrypto.kt | 25 ++++++++++++------- rust-sdk/src/error.rs | 13 ++++++++-- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 22 ++++++++-------- rust-sdk/src/olm.udl | 8 ++++++ 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 261d469854..7712da129b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult @@ -119,20 +120,26 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { } } + @Throws(MXCryptoError::class) suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) val serializedEvent = adapter.toJson(event) - val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId!!) + try { + val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId!!) - val deserializationAdapter = MoshiProvider.providesMoshi().adapter(Map::class.java) - val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent)!! + val deserializationAdapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent)!! - MXEventDecryptionResult( - clearEvent, - decrypted.senderCurve25519Key, - decrypted.claimedEd25519Key, - decrypted.forwardingCurve25519Chain - ) + MXEventDecryptionResult( + clearEvent, + decrypted.senderCurve25519Key, + decrypted.claimedEd25519Key, + decrypted.forwardingCurve25519Chain + ) + } catch (throwable: Throwable) { + val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, throwable.message, "m.megolm.v1.aes-sha2") + throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason) + } } } diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index a2f3c57684..d2e4afb5f1 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -1,6 +1,5 @@ use matrix_sdk_common::identifiers::Error as RumaIdentifierError; - -use matrix_sdk_crypto::{store::CryptoStoreError as InnerStoreError, OlmError}; +use matrix_sdk_crypto::{store::CryptoStoreError as InnerStoreError, MegolmError, OlmError}; #[derive(Debug, thiserror::Error)] pub enum MachineCreationError { @@ -17,3 +16,13 @@ pub enum CryptoStoreError { #[error(transparent)] OlmError(#[from] OlmError), } + +#[derive(Debug, thiserror::Error)] +pub enum DecryptionError { + #[error(transparent)] + Serialization(#[from] serde_json::Error), + #[error(transparent)] + Identifier(#[from] RumaIdentifierError), + #[error(transparent)] + Megolm(#[from] MegolmError), +} diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 799f045a3c..9ca691778e 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -2,7 +2,7 @@ mod error; mod logger; mod machine; -pub use error::{CryptoStoreError, MachineCreationError}; +pub use error::{CryptoStoreError, DecryptionError, MachineCreationError}; pub use logger::{set_logger, Logger}; pub use machine::{DecryptedEvent, Device, DeviceLists, OlmMachine, Request, RequestType, Sas}; diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 6ac6db6d76..12072f4e73 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -27,7 +27,7 @@ use matrix_sdk_crypto::{ IncomingResponse, OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, }; -use crate::error::{CryptoStoreError, MachineCreationError}; +use crate::error::{CryptoStoreError, DecryptionError, MachineCreationError}; pub struct OlmMachine { inner: InnerMachine, @@ -334,14 +334,17 @@ impl OlmMachine { .unwrap(); } - pub fn decrypt_room_event(&self, event: &str, room_id: &str) -> DecryptedEvent { - let event: SyncMessageEvent = serde_json::from_str(event).unwrap(); - let room_id = RoomId::try_from(room_id).unwrap(); + pub fn decrypt_room_event( + &self, + event: &str, + room_id: &str, + ) -> Result { + let event: SyncMessageEvent = serde_json::from_str(event)?; + let room_id = RoomId::try_from(room_id)?; let decrypted = self .runtime - .block_on(self.inner.decrypt_room_event(&event, &room_id)) - .unwrap(); + .block_on(self.inner.decrypt_room_event(&event, &room_id))?; let encryption_info = decrypted .encryption_info() @@ -354,20 +357,19 @@ impl OlmMachine { "content": content, }); - match &encryption_info.algorithm_info { + Ok(match &encryption_info.algorithm_info { AlgorithmInfo::MegolmV1AesSha2 { curve25519_key, sender_claimed_keys, forwarding_curve25519_key_chain, } => DecryptedEvent { - clear_event: serde_json::to_string(&clear_event) - .expect("Can't serialize the decrypted json object"), + clear_event: serde_json::to_string(&clear_event)?, sender_curve25519_key: curve25519_key.to_owned(), claimed_ed25519_key: sender_claimed_keys .get(&DeviceKeyAlgorithm::Ed25519) .cloned(), forwarding_curve25519_chain: forwarding_curve25519_key_chain.to_owned(), }, - } + }) } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 6e0c9b5a50..7107a8b40e 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -18,6 +18,13 @@ enum CryptoStoreError { "OlmError", }; +[Error] +enum DecryptionError { + "Identifier", + "Serialization", + "Megolm", +}; + dictionary DeviceLists { sequence changed; sequence left; @@ -65,6 +72,7 @@ interface OlmMachine { DeviceLists device_changes, record key_counts); + [Throws=DecryptionError] DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id); record identity_keys(); From c33a4710fe3717dac619d353e135aaff2299279c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 22 Feb 2021 16:04:18 +0100 Subject: [PATCH 022/252] ruts: Use the latest master of uniffi. --- rust-sdk/Cargo.toml | 2 +- rust-sdk/src/olm.udl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index f5a2e20e3c..ee9a950ed0 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -37,7 +37,7 @@ features = ["rt-multi-thread"] [dependencies.uniffi] version = "0.7.0" git = "https://github.com/mozilla/uniffi-rs" -branch = "tagged-unions" +rev = "f7c8ccda783494ee507ea0f8a61f35b39527394f" [build-dependencies] uniffi_build = "0.7.0" diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 7107a8b40e..30eee9a50d 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -50,7 +50,7 @@ dictionary Sas { Request request; }; -[TaggedUnion] +[Enum] interface Request { ToDevice(string request_id, string event_type, string body); KeysUpload(string request_id, string body); From c828326755f22f1c2988b86bf004c6befcd078b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 22 Feb 2021 16:04:32 +0100 Subject: [PATCH 023/252] rust: Fix the aarch64 target install dir --- rust-sdk/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-sdk/Makefile b/rust-sdk/Makefile index 3d2be7c95b..150e2e9752 100644 --- a/rust-sdk/Makefile +++ b/rust-sdk/Makefile @@ -8,4 +8,4 @@ x86: aarch64: cargo build --target aarch64-linux-android - install -D target/aarch64-linux-android/debug/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/aarch64/libuniffi_olm.so + install -D target/aarch64-linux-android/debug/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/arm64-v8a/libuniffi_olm.so From c8c7f232982ce0a30e8ca97a94eafee532686aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 26 Feb 2021 16:40:38 +0100 Subject: [PATCH 024/252] rust: Add a README explaining how to build the bindings --- rust-sdk/README.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 rust-sdk/README.md diff --git a/rust-sdk/README.md b/rust-sdk/README.md new file mode 100644 index 0000000000..57fecd4c92 --- /dev/null +++ b/rust-sdk/README.md @@ -0,0 +1,96 @@ +# Kotlin bindings for the Rust SDK crypto layer. + +## Prerequisites + +### Rust + +To build the bindings [Rust] will be needed it can be either installed using an +OS specific package manager or directly with the provided [installer](https://rustup.rs/). + + +### Android NDK + +The Android NDK will be required as well, it can be installed either through +Android Studio or directly using an [installer](https://developer.android.com/ndk/downloads). + +### Uniffi + +The bindings are using [uniffi] to generate the C translation layer between Rust +and Kotlin. Uniffi is a Rust project and can be installed with our freshly +installed Rust setup using: + +``` +$ cargo install uniffi_bindgen +``` + +### Configuring Rust for cross compilation + +First we'll need to install the Rust target for our desired Android architecture, +for example: + +``` +# rustup target add aarch64-linux-android +``` + +This will add support to cross-compile for the aarch64-linux-android target, +Rust supports many different [targets], you'll have to make sure to pick the +right one for your device or emulator. + +After this is done, we'll have to configure [Cargo] to use the correct linker +for our target. Cargo is configured using a TOML file that will be found in +`%USERPROFILE%\.cargo\config.toml` on Windows or `$HOME/.cargo/config` on Unix +platforms. More details and configuration options for Cargo can be found in the +official docs over [here](https://doc.rust-lang.org/cargo/reference/config.html). + +``` +[target.aarch64-linux-android] +ar = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/ar" +linker = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang" +``` + +## Building + +A `Makefile` is provided that builds and installs the dynamic library into the +appropriate target specific `jniLibs` directory. But before we can get started +we'll need to tweak our Rust setup to allow cross compilation. + +To enable cross compilation fro `olm-sys` which builds our libolm C library +we'll need to set the `ANDROID_NDK` environment variable to the location of our +Android NDK installation. + +``` +$ export ANDROID_NDK=$HOME/Android/Sdk/ndk/22.0.7026061/ +``` + +### Makefile build + +After the prerequisites have been installed and the environment variable has +been set a build for the `aarch64` target can be build using: + +``` +make aarch64 +``` + +### Manual build + +If the `Makefile` doesn't work on your system, the bindings can built for the `aarch64` +target with: + +``` +$ cargo build --target aarch64-linux-android +``` + +After that, a dynamic library can be found in the `target/aarch64-linux-android/debug` directory. +The library will be called `libmatrix_crypto.so` and needs to be renamed and +copied into the `jniLibs` directory: + +``` +$ cp target/aarch64-linux-android/debug/libmatrix_crypto.so \ + ../matrix-sdk-android/src/main/jniLibs/aarch64/libuniffi_olm.so +``` + +[Rust]: https://www.rust-lang.org/ +[installer]: https://rustup.rs/ +[targets]: https://doc.rust-lang.org/nightly/rustc/platform-support.html +[Cargo]: https://doc.rust-lang.org/cargo/ +[uniffi]: https://github.com/mozilla/uniffi-rs/ From da35c9b6bd49e80bd25271b210ecbb8cc08e7c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 4 Mar 2021 13:12:16 +0100 Subject: [PATCH 025/252] crypto: Send out key query requests that the rust-sdk gives us. --- .../internal/crypto/DefaultCryptoService.kt | 31 ++++++++++++++++--- .../matrix/android/sdk/internal/newCrypto.kt | 4 +++ .../internal/session/sync/RoomSyncHandler.kt | 8 ++--- rust-sdk/src/machine.rs | 20 ++++++++---- rust-sdk/src/olm.udl | 3 +- 5 files changed, 50 insertions(+), 16 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index afec7d17d3..5a18241534 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -79,11 +79,13 @@ import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse +import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceWithUserPasswordTask +import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask import org.matrix.android.sdk.internal.crypto.tasks.NewUploadKeysTask @@ -169,6 +171,7 @@ internal class DefaultCryptoService @Inject constructor( private val deleteDeviceWithUserPasswordTask: DeleteDeviceWithUserPasswordTask, // Tasks private val getDevicesTask: GetDevicesTask, + private val downloadKeysForUsersTask: DownloadKeysForUsersTask, private val getDeviceInfoTask: GetDeviceInfoTask, private val setDeviceNameTask: SetDeviceNameTask, private val uploadKeysTask: UploadKeysTask, @@ -185,7 +188,7 @@ internal class DefaultCryptoService @Inject constructor( private val isStarted = AtomicBoolean(false) private var olmMachine: OlmMachine? = null - fun onStateEvent(roomId: String, event: Event) { + suspend fun onStateEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) @@ -193,7 +196,7 @@ internal class DefaultCryptoService @Inject constructor( } } - fun onLiveEvent(roomId: String, event: Event) { + suspend fun onLiveEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) @@ -899,6 +902,7 @@ internal class DefaultCryptoService @Inject constructor( Timber.e(throwable, "## CRYPTO | onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ") } finally { val userIds = getRoomUserIds(roomId) + olmMachine!!.updateTrackedUsers(userIds) setEncryptionInRoom(roomId, event.content?.get("algorithm")?.toString(), true, userIds) } } @@ -915,13 +919,14 @@ internal class DefaultCryptoService @Inject constructor( * * @param event the membership event causing the change */ - private fun onRoomMembershipEvent(roomId: String, event: Event) { + private suspend fun onRoomMembershipEvent(roomId: String, event: Event) { roomEncryptorsStore.get(roomId) ?: /* No encrypting in this room */ return event.stateKey?.let { userId -> val roomMember: RoomMemberContent? = event.content.toModel() val membership = roomMember?.membership if (membership == Membership.JOIN) { + olmMachine!!.updateTrackedUsers(listOf(userId)) // make sure we are tracking the deviceList for this user. deviceListManager.startTrackingDeviceList(listOf(userId)) } else if (membership == Membership.INVITE @@ -966,8 +971,24 @@ internal class DefaultCryptoService @Inject constructor( olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_UPLOAD, json_response) Timber.v("HELLO UPLOADED KEYS $response") } - is Request.KeysQuery -> Timber.v("HELLO KEYS QUERY REQUEST ${outgoingRequest.body}") - is Request.ToDevice -> Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") + is Request.KeysQuery -> { + Timber.v("HELLO KEYS QUERY REQUEST ${outgoingRequest.users}") + val params = DownloadKeysForUsersTask.Params(outgoingRequest.users, null) + + try { + val response = downloadKeysForUsersTask.execute(params) + val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) + val json_response = adapter.toJson(response)!! + olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_QUERY, json_response) + } catch (throwable: Throwable) { + Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") + } + + + } + is Request.ToDevice -> { + // Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") + } } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 7712da129b..d6fb5035a8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -87,6 +87,10 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.outgoingRequests() } + suspend fun updateTrackedUsers(users: List) = withContext(Dispatchers.IO) { + inner.updateTrackedUsers(users) + } + suspend fun receiveSyncChanges( toDevice: ToDeviceSyncResponse?, deviceChanges: DeviceListResponse?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt index 6d1b3ae034..974041a59a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt @@ -83,7 +83,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle data class LEFT(val data: Map) : HandlingStrategy() } - fun handle( + suspend fun handle( realm: Realm, roomsSyncResponse: RoomsSyncResponse, isInitialSync: Boolean, @@ -97,7 +97,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle // PRIVATE METHODS ***************************************************************************** - private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy, isInitialSync: Boolean, reporter: DefaultInitialSyncProgressService?) { + private suspend fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy, isInitialSync: Boolean, reporter: DefaultInitialSyncProgressService?) { val insertType = if (isInitialSync) { EventInsertType.INITIAL_SYNC } else { @@ -123,7 +123,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle realm.insertOrUpdate(rooms) } - private fun handleJoinedRoom(realm: Realm, + private suspend fun handleJoinedRoom(realm: Realm, roomId: String, roomSync: RoomSync, isInitialSync: Boolean, @@ -271,7 +271,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle return roomEntity } - private fun handleTimelineEvents(realm: Realm, + private suspend fun handleTimelineEvents(realm: Realm, roomId: String, roomEntity: RoomEntity, eventList: List, diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 12072f4e73..4f0b8b0b12 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -17,7 +17,7 @@ use matrix_sdk_common::{ }, assign, deserialized_responses::events::{AlgorithmInfo, SyncMessageEvent}, - events::{room::encrypted::EncryptedEventContent, EventContent}, + events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent}, identifiers::{DeviceKeyAlgorithm, RoomId, UserId}, uuid::Uuid, UInt, @@ -128,7 +128,7 @@ pub enum Request { }, KeysQuery { request_id: String, - body: String, + users: Vec, }, } @@ -150,12 +150,10 @@ impl From for Request { } } KeysQuery(k) => { - let body = json!({ - "device_keys": k.device_keys, - }); + let users: Vec = k.device_keys.keys().map(|u| u.to_string()).collect(); Request::KeysQuery { request_id: r.request_id().to_string(), - body: serde_json::to_string(&body).expect("Can't serialize keys query request"), + users, } } ToDeviceRequest(t) => Request::from(t), @@ -334,6 +332,16 @@ impl OlmMachine { .unwrap(); } + pub fn update_tracked_users(&self, users: Vec) { + let users: Vec = users + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(); + + self.runtime + .block_on(self.inner.update_tracked_users(users.iter())); + } + pub fn decrypt_room_event( &self, event: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 30eee9a50d..0d38c07081 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -54,7 +54,7 @@ dictionary Sas { interface Request { ToDevice(string request_id, string event_type, string body); KeysUpload(string request_id, string body); - KeysQuery(string request_id, string body); + KeysQuery(string request_id, sequence users); }; enum RequestType { @@ -83,6 +83,7 @@ interface OlmMachine { Device? get_device([ByRef] string user_id, [ByRef] string device_id); sequence get_user_devices([ByRef] string user_id); sequence outgoing_requests(); + void update_tracked_users(sequence users); [Throws=CryptoStoreError] void mark_request_as_sent( From 4c44a5e108dfba9b6a790511943a89d607e859c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 4 Mar 2021 17:14:48 +0100 Subject: [PATCH 026/252] crypto: Add support to claim one-time keys --- .../internal/crypto/DefaultCryptoService.kt | 24 +++++ .../EnsureOlmSessionsForDevicesAction.kt | 88 +++++++++---------- .../crypto/model/rest/KeysClaimResponse.kt | 5 ++ .../ClaimOneTimeKeysForUsersDeviceTask.kt | 25 ++---- .../matrix/android/sdk/internal/newCrypto.kt | 4 + rust-sdk/src/machine.rs | 49 ++++++++++- rust-sdk/src/olm.udl | 5 ++ 7 files changed, 134 insertions(+), 66 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 5a18241534..33b434ee15 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -79,6 +79,7 @@ import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse +import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository @@ -91,6 +92,7 @@ import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask import org.matrix.android.sdk.internal.crypto.tasks.NewUploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask +import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.MoshiProvider @@ -171,6 +173,7 @@ internal class DefaultCryptoService @Inject constructor( private val deleteDeviceWithUserPasswordTask: DeleteDeviceWithUserPasswordTask, // Tasks private val getDevicesTask: GetDevicesTask, + private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, private val downloadKeysForUsersTask: DownloadKeysForUsersTask, private val getDeviceInfoTask: GetDeviceInfoTask, private val setDeviceNameTask: SetDeviceNameTask, @@ -691,6 +694,7 @@ internal class DefaultCryptoService @Inject constructor( val t0 = System.currentTimeMillis() Timber.v("## CRYPTO | encryptEventContent() starts") runCatching { + preshareGroupSession(roomId, userIds) val content = safeAlgorithm.encryptEventContent(eventContent, eventType, userIds) Timber.v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms") MXEncryptEventContentResult(content, EventType.ENCRYPTED) @@ -956,6 +960,26 @@ internal class DefaultCryptoService @Inject constructor( olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) } + private suspend fun preshareGroupSession(roomId: String, roomMembers: List) { + val request = olmMachine!!.getMissingSessions(roomMembers) + roomId == "est" + + if (request != null) { + when (request) { + is Request.KeysClaim -> { + val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) + val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) + val adapter = MoshiProvider.providesMoshi().adapter(KeysClaimResponse::class.java) + val json_response = adapter.toJson(response)!! + olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, json_response) + } + } + } + } + + // private suspend fun encrypt(roomId: String, eventType: String, content: Content) { + // } + private suspend fun sendOutgoingRequests() { // TODO these requests should be sent out in parallel for (outgoingRequest in olmMachine!!.outgoingRequests()) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt index 95b99c54e8..5bb9967581 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt @@ -50,56 +50,56 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor( } } - if (devicesWithoutSession.size == 0) { - return results - } + //if (devicesWithoutSession.size == 0) { + // return results + //} - // Prepare the request for claiming one-time keys - val usersDevicesToClaim = MXUsersDevicesMap() + //// Prepare the request for claiming one-time keys + //val usersDevicesToClaim = MXUsersDevicesMap() - val oneTimeKeyAlgorithm = MXKey.KEY_SIGNED_CURVE_25519_TYPE + //val oneTimeKeyAlgorithm = MXKey.KEY_SIGNED_CURVE_25519_TYPE - for (device in devicesWithoutSession) { - usersDevicesToClaim.setObject(device.userId, device.deviceId, oneTimeKeyAlgorithm) - } + //for (device in devicesWithoutSession) { + // usersDevicesToClaim.setObject(device.userId, device.deviceId, oneTimeKeyAlgorithm) + //} - // TODO: this has a race condition - if we try to send another message - // while we are claiming a key, we will end up claiming two and setting up - // two sessions. - // - // That should eventually resolve itself, but it's poor form. + //// TODO: this has a race condition - if we try to send another message + //// while we are claiming a key, we will end up claiming two and setting up + //// two sessions. + //// + //// That should eventually resolve itself, but it's poor form. - Timber.i("## CRYPTO | claimOneTimeKeysForUsersDevices() : $usersDevicesToClaim") + //Timber.i("## CRYPTO | claimOneTimeKeysForUsersDevices() : $usersDevicesToClaim") - val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(usersDevicesToClaim) - val oneTimeKeys = oneTimeKeysForUsersDeviceTask.execute(claimParams) - Timber.v("## CRYPTO | claimOneTimeKeysForUsersDevices() : keysClaimResponse.oneTimeKeys: $oneTimeKeys") - for ((userId, deviceInfos) in devicesByUser) { - for (deviceInfo in deviceInfos) { - var oneTimeKey: MXKey? = null - val deviceIds = oneTimeKeys.getUserDeviceIds(userId) - if (null != deviceIds) { - for (deviceId in deviceIds) { - val olmSessionResult = results.getObject(userId, deviceId) - if (olmSessionResult!!.sessionId != null && !force) { - // We already have a result for this device - continue - } - val key = oneTimeKeys.getObject(userId, deviceId) - if (key?.type == oneTimeKeyAlgorithm) { - oneTimeKey = key - } - if (oneTimeKey == null) { - Timber.w("## CRYPTO | ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm - + " for device " + userId + " : " + deviceId) - continue - } - // Update the result for this device in results - olmSessionResult.sessionId = verifyKeyAndStartSession(oneTimeKey, userId, deviceInfo) - } - } - } - } + //val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(usersDevicesToClaim) + //val oneTimeKeys = oneTimeKeysForUsersDeviceTask.execute(claimParams) + //Timber.v("## CRYPTO | claimOneTimeKeysForUsersDevices() : keysClaimResponse.oneTimeKeys: $oneTimeKeys") + //for ((userId, deviceInfos) in devicesByUser) { + // for (deviceInfo in deviceInfos) { + // var oneTimeKey: MXKey? = null + // val deviceIds = oneTimeKeys.getUserDeviceIds(userId) + // if (null != deviceIds) { + // for (deviceId in deviceIds) { + // val olmSessionResult = results.getObject(userId, deviceId) + // if (olmSessionResult!!.sessionId != null && !force) { + // // We already have a result for this device + // continue + // } + // val key = oneTimeKeys.getObject(userId, deviceId) + // if (key?.type == oneTimeKeyAlgorithm) { + // oneTimeKey = key + // } + // if (oneTimeKey == null) { + // Timber.w("## CRYPTO | ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm + // + " for device " + userId + " : " + deviceId) + // continue + // } + // // Update the result for this device in results + // olmSessionResult.sessionId = verifyKeyAndStartSession(oneTimeKey, userId, deviceInfo) + // } + // } + // } + //} return results } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeysClaimResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeysClaimResponse.kt index 22f4ce5a59..2dfdfe09a8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeysClaimResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeysClaimResponse.kt @@ -24,6 +24,11 @@ import com.squareup.moshi.JsonClass */ @JsonClass(generateAdapter = true) internal data class KeysClaimResponse( + /// If any remote homeservers could not be reached, they are recorded here. + /// The names of the properties are the names of the unreachable servers. + @Json(name = "failures") + val failures: Map, + /** * The requested keys ordered by device by user. * TODO Type does not match spec, should be Map diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt index 3df6312adb..68e366ae03 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt @@ -27,10 +27,10 @@ import org.matrix.android.sdk.internal.task.Task import timber.log.Timber import javax.inject.Inject -internal interface ClaimOneTimeKeysForUsersDeviceTask : Task> { +internal interface ClaimOneTimeKeysForUsersDeviceTask : Task { data class Params( // a list of users, devices and key types to retrieve keys for. - val usersDevicesKeyTypesMap: MXUsersDevicesMap + val usersDevicesKeyTypesMap: Map> ) } @@ -39,26 +39,11 @@ internal class DefaultClaimOneTimeKeysForUsersDevice @Inject constructor( private val globalErrorReceiver: GlobalErrorReceiver ) : ClaimOneTimeKeysForUsersDeviceTask { - override suspend fun execute(params: ClaimOneTimeKeysForUsersDeviceTask.Params): MXUsersDevicesMap { - val body = KeysClaimBody(oneTimeKeys = params.usersDevicesKeyTypesMap.map) + override suspend fun execute(params: ClaimOneTimeKeysForUsersDeviceTask.Params): KeysClaimResponse { + val body = KeysClaimBody(oneTimeKeys = params.usersDevicesKeyTypesMap) - val keysClaimResponse = executeRequest(globalErrorReceiver) { + return executeRequest(globalErrorReceiver) { apiCall = cryptoApi.claimOneTimeKeysForUsersDevices(body) } - val map = MXUsersDevicesMap() - keysClaimResponse.oneTimeKeys?.let { oneTimeKeys -> - for ((userId, mapByUserId) in oneTimeKeys) { - for ((deviceId, deviceKey) in mapByUserId) { - val mxKey = MXKey.from(deviceKey) - - if (mxKey != null) { - map.setObject(userId, deviceId, mxKey) - } else { - Timber.e("## claimOneTimeKeysForUsersDevices : fail to create a MXKey") - } - } - } - } - return map } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index d6fb5035a8..21c463c08f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -87,6 +87,10 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.outgoingRequests() } + suspend fun getMissingSessions(users: List): Request? = withContext(Dispatchers.IO) { + inner.getMissingSessions(users) + } + suspend fun updateTrackedUsers(users: List) = withContext(Dispatchers.IO) { inner.updateTrackedUsers(users) } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 4f0b8b0b12..77c5cc064b 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -10,10 +10,12 @@ use tokio::runtime::Runtime; use matrix_sdk_common::{ api::r0::{ keys::{ - claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, + claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse}, + get_keys::Response as KeysQueryResponse, upload_keys::Response as KeysUploadResponse, }, sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, + to_device::send_event_to_device::Response as ToDeviceResponse, }, assign, deserialized_responses::events::{AlgorithmInfo, SyncMessageEvent}, @@ -67,6 +69,7 @@ enum OwnedResponse { KeysClaim(KeysClaimResponse), KeysUpload(KeysUploadResponse), KeysQuery(KeysQueryResponse), + ToDevice(ToDeviceResponse), } impl From for OwnedResponse { @@ -87,18 +90,26 @@ impl From for OwnedResponse { } } +impl From for OwnedResponse { + fn from(response: ToDeviceResponse) -> Self { + OwnedResponse::ToDevice(response) + } +} + impl<'a> Into> for &'a OwnedResponse { fn into(self) -> IncomingResponse<'a> { match self { OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), + OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r), } } } pub enum RequestType { KeysQuery, + KeysClaim, KeysUpload, ToDevice, } @@ -130,6 +141,10 @@ pub enum Request { request_id: String, users: Vec, }, + KeysClaim { + request_id: String, + one_time_keys: HashMap>, + }, } impl From for Request { @@ -268,7 +283,8 @@ impl OlmMachine { let response: OwnedResponse = match request_type { RequestType::KeysUpload => KeysUploadResponse::try_from(response).map(Into::into), RequestType::KeysQuery => KeysQueryResponse::try_from(response).map(Into::into), - RequestType::ToDevice => KeysClaimResponse::try_from(response).map(Into::into), + RequestType::ToDevice => ToDeviceResponse::try_from(response).map(Into::into), + RequestType::KeysClaim => KeysClaimResponse::try_from(response).map(Into::into), } .expect("Can't convert json string to response"); @@ -342,6 +358,35 @@ impl OlmMachine { .block_on(self.inner.update_tracked_users(users.iter())); } + pub fn get_missing_sessions( + &self, + users: Vec, + ) -> Result, CryptoStoreError> { + let users: Vec = users + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(); + + Ok(self + .runtime + .block_on(self.inner.get_missing_sessions(users.iter()))? + .map(|(request_id, request)| Request::KeysClaim { + request_id: request_id.to_string(), + one_time_keys: request + .one_time_keys + .into_iter() + .map(|(u, d)| { + ( + u.to_string(), + d.into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + ) + }) + .collect(), + })) + } + pub fn decrypt_room_event( &self, event: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 0d38c07081..d534a1cb36 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -55,10 +55,12 @@ interface Request { ToDevice(string request_id, string event_type, string body); KeysUpload(string request_id, string body); KeysQuery(string request_id, sequence users); + KeysClaim(string request_id, record> one_time_keys); }; enum RequestType { "KeysQuery", + "KeysClaim", "KeysUpload", "ToDevice", }; @@ -85,6 +87,9 @@ interface OlmMachine { sequence outgoing_requests(); void update_tracked_users(sequence users); + [Throws=CryptoStoreError] + Request? get_missing_sessions(sequence users); + [Throws=CryptoStoreError] void mark_request_as_sent( [ByRef] string request_id, From 5f848093b9a9a1c29bfb16e1659c7fe97e3d3f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 5 Mar 2021 13:27:32 +0100 Subject: [PATCH 027/252] crypto: Send out to-device requests to share the room key --- .../internal/crypto/DefaultCryptoService.kt | 21 +++++++++++++++++- .../crypto/model/MXUsersDevicesMap.kt | 4 ++++ .../matrix/android/sdk/internal/newCrypto.kt | 4 ++++ rust-sdk/src/machine.rs | 22 ++++++++++++++++++- rust-sdk/src/olm.udl | 6 +++-- 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 33b434ee15..1ed7e39db2 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -91,6 +91,7 @@ import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask import org.matrix.android.sdk.internal.crypto.tasks.NewUploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask +import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService @@ -174,6 +175,7 @@ internal class DefaultCryptoService @Inject constructor( // Tasks private val getDevicesTask: GetDevicesTask, private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, + private val sendToDeviceTask: SendToDeviceTask, private val downloadKeysForUsersTask: DownloadKeysForUsersTask, private val getDeviceInfoTask: GetDeviceInfoTask, private val setDeviceNameTask: SetDeviceNameTask, @@ -962,9 +964,9 @@ internal class DefaultCryptoService @Inject constructor( private suspend fun preshareGroupSession(roomId: String, roomMembers: List) { val request = olmMachine!!.getMissingSessions(roomMembers) - roomId == "est" if (request != null) { + // This request can only be a keys claim request. when (request) { is Request.KeysClaim -> { val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) @@ -975,6 +977,23 @@ internal class DefaultCryptoService @Inject constructor( } } } + + for (toDeviceRequest in olmMachine!!.shareGroupSession(roomId, roomMembers)) { + // This request can only be a to-device request. + when (toDeviceRequest) { + is Request.ToDevice -> { + val adapter = MoshiProvider.providesMoshi().adapter>>(Map::class.java) + val body = adapter.fromJson(toDeviceRequest.body)!! + + val userMap = MXUsersDevicesMap() + userMap.join(body) + + val sendToDeviceParams = SendToDeviceTask.Params(toDeviceRequest.eventType, userMap) + sendToDeviceTask.execute(sendToDeviceParams) + olmMachine!!.markRequestAsSent(toDeviceRequest.requestId, RequestType.TO_DEVICE, "{}") + } + } + } } // private suspend fun encrypt(roomId: String, eventType: String, content: Content) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt index 9d7f2d9883..2c910c3bee 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt @@ -115,6 +115,10 @@ class MXUsersDevicesMap { } } + fun join(other: Map>) { + map.putAll(other) + } + override fun toString(): String { return "MXUsersDevicesMap $map" } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 21c463c08f..8a3be1c74d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -87,6 +87,10 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.outgoingRequests() } + suspend fun shareGroupSession(roomId: String, users: List): List = withContext(Dispatchers.IO) { + inner.shareGroupSession(roomId, users) + } + suspend fun getMissingSessions(users: List): Request? = withContext(Dispatchers.IO) { inner.getMissingSessions(users) } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 77c5cc064b..b4d3f475f1 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -26,7 +26,8 @@ use matrix_sdk_common::{ }; use matrix_sdk_crypto::{ - IncomingResponse, OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, + EncryptionSettings, IncomingResponse, OlmMachine as InnerMachine, OutgoingRequest, + ToDeviceRequest, }; use crate::error::{CryptoStoreError, DecryptionError, MachineCreationError}; @@ -358,6 +359,25 @@ impl OlmMachine { .block_on(self.inner.update_tracked_users(users.iter())); } + pub fn share_group_session(&self, room_id: &str, users: Vec) -> Vec { + let users: Vec = users + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(); + + let room_id = RoomId::try_from(room_id).unwrap(); + let requests = self + .runtime + .block_on(self.inner.share_group_session( + &room_id, + users.iter(), + EncryptionSettings::default(), + )) + .unwrap(); + + requests.into_iter().map(|r| (&*r).into()).collect() + } + pub fn get_missing_sessions( &self, users: Vec, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index d534a1cb36..c7faef71bc 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -84,11 +84,13 @@ interface OlmMachine { Device? get_device([ByRef] string user_id, [ByRef] string device_id); sequence get_user_devices([ByRef] string user_id); - sequence outgoing_requests(); - void update_tracked_users(sequence users); + sequence outgoing_requests(); + + void update_tracked_users(sequence users); [Throws=CryptoStoreError] Request? get_missing_sessions(sequence users); + sequence share_group_session([ByRef] string room_id, sequence users); [Throws=CryptoStoreError] void mark_request_as_sent( From c97e38479089074e740ebe36138ae40d1b29ead2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 5 Mar 2021 16:12:24 +0100 Subject: [PATCH 028/252] crypto: Hook up the event encryption to use the rust-sdk --- .../sdk/internal/crypto/DefaultCryptoService.kt | 9 ++++++--- .../org/matrix/android/sdk/internal/newCrypto.kt | 8 ++++++++ rust-sdk/src/machine.rs | 15 ++++++++++++++- rust-sdk/src/olm.udl | 1 + 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 1ed7e39db2..b6f72e6d27 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -697,7 +697,7 @@ internal class DefaultCryptoService @Inject constructor( Timber.v("## CRYPTO | encryptEventContent() starts") runCatching { preshareGroupSession(roomId, userIds) - val content = safeAlgorithm.encryptEventContent(eventContent, eventType, userIds) + val content = encrypt(roomId, eventType, eventContent) Timber.v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms") MXEncryptEventContentResult(content, EventType.ENCRYPTED) }.foldToCallback(callback) @@ -982,6 +982,8 @@ internal class DefaultCryptoService @Inject constructor( // This request can only be a to-device request. when (toDeviceRequest) { is Request.ToDevice -> { + // TODO this produces floats for the Olm type fields, which + // are integers originally. val adapter = MoshiProvider.providesMoshi().adapter>>(Map::class.java) val body = adapter.fromJson(toDeviceRequest.body)!! @@ -996,8 +998,9 @@ internal class DefaultCryptoService @Inject constructor( } } - // private suspend fun encrypt(roomId: String, eventType: String, content: Content) { - // } + private suspend fun encrypt(roomId: String, eventType: String, content: Content): Content { + return olmMachine!!.encrypt(roomId, eventType, content) + } private suspend fun sendOutgoingRequests() { // TODO these requests should be sent out in parallel diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 8a3be1c74d..c3f123ac6d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -27,6 +27,7 @@ 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 import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse +import org.matrix.android.sdk.api.session.events.model.Content import timber.log.Timber import uniffi.olm.Device as InnerDevice import uniffi.olm.DeviceLists @@ -87,6 +88,13 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.outgoingRequests() } + suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val contentString = adapter.toJson(content) + val encrypted = inner.encrypt(roomId, eventType, contentString) + adapter.fromJson(encrypted)!! + } + suspend fun shareGroupSession(roomId: String, users: List): List = withContext(Dispatchers.IO) { inner.shareGroupSession(roomId, users) } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index b4d3f475f1..3c8a041111 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -4,7 +4,7 @@ use std::{ }; use http::Response; -use serde_json::json; +use serde_json::{json, value::RawValue}; use tokio::runtime::Runtime; use matrix_sdk_common::{ @@ -407,6 +407,19 @@ impl OlmMachine { })) } + pub fn encrypt(&self, room_id: &str, event_type: &str, content: &str) -> String { + let room_id = RoomId::try_from(room_id).unwrap(); + let content: Box = serde_json::from_str(content).unwrap(); + + let content = AnyMessageEventContent::from_parts(event_type, content).unwrap(); + let encrypted_content = self + .runtime + .block_on(self.inner.encrypt(&room_id, content)) + .unwrap(); + + serde_json::to_string(&encrypted_content).unwrap() + } + pub fn decrypt_room_event( &self, event: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index c7faef71bc..36bda6c96f 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -76,6 +76,7 @@ interface OlmMachine { [Throws=DecryptionError] DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id); + string encrypt([ByRef] string room_id, [ByRef] string event_type, [ByRef] string content); record identity_keys(); From ab8d365c10543a8432d18b811f7215cf33425a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 15 Mar 2021 13:47:51 +0100 Subject: [PATCH 029/252] rust: Build the bindings in release mode --- rust-sdk/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rust-sdk/Makefile b/rust-sdk/Makefile index 150e2e9752..131e26bdec 100644 --- a/rust-sdk/Makefile +++ b/rust-sdk/Makefile @@ -1,11 +1,11 @@ x86_64: - cargo build --target x86_64-linux-android - install -D target/x86_64-linux-android/debug/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86_64/libuniffi_olm.so + cargo build --release --target x86_64-linux-android + install -D target/x86_64-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86_64/libuniffi_olm.so x86: - cargo build --target i686-linux-android - install -D target/i686-linux-android/debug/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86/libuniffi_olm.so + cargo build --release --target i686-linux-android + install -D target/i686-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86/libuniffi_olm.so aarch64: - cargo build --target aarch64-linux-android - install -D target/aarch64-linux-android/debug/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/arm64-v8a/libuniffi_olm.so + cargo build --release --target aarch64-linux-android + install -D target/aarch64-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/arm64-v8a/libuniffi_olm.so From 7f86f512ed6c1045c951d557a1b4a78ad2682108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 12:28:41 +0100 Subject: [PATCH 030/252] crypto: Remove the one-time key uploader since Rust is handling this --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index b6f72e6d27..b6d927af22 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -152,8 +152,6 @@ internal class DefaultCryptoService @Inject constructor( // private val objectSigner: ObjectSigner, // - private val oneTimeKeysUploader: OneTimeKeysUploader, - // private val roomDecryptorProvider: RoomDecryptorProvider, // The verification service. private val verificationService: DefaultVerificationService, @@ -350,7 +348,6 @@ internal class DefaultCryptoService @Inject constructor( uploadDeviceKeys() } - // oneTimeKeysUploader.maybeUploadOneTimeKeys() // this can throw if no backup tryOrNull { keysBackupService.checkAndStartKeysBackup() @@ -459,14 +456,9 @@ internal class DefaultCryptoService @Inject constructor( if (syncResponse.deviceLists != null) { deviceListManager.handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left) } - if (syncResponse.deviceOneTimeKeysCount != null) { - val currentCount = syncResponse.deviceOneTimeKeysCount.signedCurve25519 ?: 0 - oneTimeKeysUploader.updateOneTimeKeyCount(currentCount) - } if (isStarted()) { // Make sure we process to-device messages before generating new one-time-keys #2782 deviceListManager.refreshOutdatedDeviceLists() - // oneTimeKeysUploader.maybeUploadOneTimeKeys() incomingGossipingRequestManager.processReceivedGossipingRequests() } } From 669a5f98150f36e53830b6f5f98c73d77f0ab789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 12:35:21 +0100 Subject: [PATCH 031/252] crypto: Remove the MXOlmDevice --- .../sdk/internal/crypto/DefaultCryptoService.kt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index b6d927af22..8a0b344445 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -141,8 +141,6 @@ internal class DefaultCryptoService @Inject constructor( private val cryptoStore: IMXCryptoStore, // Room encryptors store private val roomEncryptorsStore: RoomEncryptorsStore, - // Olm device - private val olmDevice: MXOlmDevice, // Set of parameters used to configure/customize the end-to-end crypto. private val mxCryptoConfig: MXCryptoConfig, // Device list manager @@ -422,7 +420,6 @@ internal class DefaultCryptoService @Inject constructor( fun close() = runBlocking(coroutineDispatchers.crypto) { cryptoCoroutineScope.coroutineContext.cancelChildren(CancellationException("Closing crypto module")) incomingGossipingRequestManager.close() - olmDevice.release() cryptoStore.close() } @@ -748,15 +745,6 @@ internal class DefaultCryptoService @Inject constructor( return eventDecryptor.decryptEvent(event, timeline) } - /** - * Reset replay attack data for the given timeline. - * - * @param timelineId the timeline id - */ - fun resetReplayAttackCheckInTimeline(timelineId: String) { - olmDevice.resetReplayAttackCheckInTimeline(timelineId) - } - /** * Handle the 'toDevice' event * From e4ac5f6c1325e38a2a64d8abfc63ba3b8934f4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 13:45:15 +0100 Subject: [PATCH 032/252] crypto: Don't track users on the kotlin side of things --- .../internal/crypto/DefaultCryptoService.kt | 48 +++---------------- .../session/sync/CryptoSyncHandler.kt | 4 +- .../session/sync/SyncResponseHandler.kt | 2 +- 3 files changed, 9 insertions(+), 45 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 8a0b344445..936d3fb5cb 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -440,22 +440,16 @@ internal class DefaultCryptoService @Inject constructor( /** * A sync response has been received - * - * @param syncResponse the syncResponse */ - suspend fun onSyncCompleted(syncResponse: SyncResponse) { + suspend fun onSyncCompleted() { if (isStarted()) { sendOutgoingRequests() } cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { runCatching { - if (syncResponse.deviceLists != null) { - deviceListManager.handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left) - } if (isStarted()) { // Make sure we process to-device messages before generating new one-time-keys #2782 - deviceListManager.refreshOutdatedDeviceLists() incomingGossipingRequestManager.processReceivedGossipingRequests() } } @@ -566,13 +560,11 @@ internal class DefaultCryptoService @Inject constructor( * * @param roomId the room id to enable encryption in. * @param algorithm the encryption config for the room. - * @param inhibitDeviceQuery true to suppress device list query for users in the room (for now) * @param membersId list of members to start tracking their devices * @return true if the operation succeeds. */ private suspend fun setEncryptionInRoom(roomId: String, algorithm: String?, - inhibitDeviceQuery: Boolean, membersId: List): Boolean { // If we already have encryption in this room, we should ignore this event // (for now at least. Maybe we should alert the user somehow?) @@ -608,12 +600,7 @@ internal class DefaultCryptoService @Inject constructor( Timber.v("Enabling encryption in $roomId for the first time; invalidating device lists for all users therein") val userIds = ArrayList(membersId) - - deviceListManager.startTrackingDeviceList(userIds) - - if (!inhibitDeviceQuery) { - deviceListManager.refreshOutdatedDeviceLists() - } + olmMachine!!.updateTrackedUsers(userIds) } return true @@ -675,7 +662,7 @@ internal class DefaultCryptoService @Inject constructor( if (alg == null) { val algorithm = getEncryptionAlgorithm(roomId) if (algorithm != null) { - if (setEncryptionInRoom(roomId, algorithm, false, userIds)) { + if (setEncryptionInRoom(roomId, algorithm, userIds)) { alg = roomEncryptorsStore.get(roomId) } } @@ -889,7 +876,7 @@ internal class DefaultCryptoService @Inject constructor( } finally { val userIds = getRoomUserIds(roomId) olmMachine!!.updateTrackedUsers(userIds) - setEncryptionInRoom(roomId, event.content?.get("algorithm")?.toString(), true, userIds) + setEncryptionInRoom(roomId, event.content?.get("algorithm")?.toString(), userIds) } } } @@ -912,9 +899,8 @@ internal class DefaultCryptoService @Inject constructor( val roomMember: RoomMemberContent? = event.content.toModel() val membership = roomMember?.membership if (membership == Membership.JOIN) { - olmMachine!!.updateTrackedUsers(listOf(userId)) // make sure we are tracking the deviceList for this user. - deviceListManager.startTrackingDeviceList(listOf(userId)) + olmMachine!!.updateTrackedUsers(listOf(userId)) } else if (membership == Membership.INVITE && shouldEncryptForInvitedMembers(roomId) && isEncryptionEnabledForInvitedUser()) { @@ -923,7 +909,7 @@ internal class DefaultCryptoService @Inject constructor( // know what other servers are in the room at the time they've been invited. // They therefore will not send device updates if a user logs in whilst // their state is invite. - deviceListManager.startTrackingDeviceList(listOf(userId)) + olmMachine!!.updateTrackedUsers(listOf(userId)) } } } @@ -1130,28 +1116,6 @@ internal class DefaultCryptoService @Inject constructor( warnOnUnknownDevicesRepository.setWarnOnUnknownDevices(warn) } - /** - * Check if the user ids list have some unknown devices. - * A success means there is no unknown devices. - * If there are some unknown devices, a MXCryptoError.UnknownDevice exception is triggered. - * - * @param userIds the user ids list - * @param callback the asynchronous callback. - */ - fun checkUnknownDevices(userIds: List, callback: MatrixCallback) { - // force the refresh to ensure that the devices list is up-to-date - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - runCatching { - val keys = deviceListManager.downloadKeys(userIds, true) - val unknownDevices = getUnknownDevices(keys) - if (unknownDevices.map.isNotEmpty()) { - // trigger an an unknown devices exception - throw Failure.CryptoError(MXCryptoError.UnknownDevice(unknownDevices)) - } - }.foldToCallback(callback) - } - } - /** * Set the global override for whether the client should ever send encrypted * messages to unverified devices. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt index 1e08b86d4b..9d3328eb43 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt @@ -52,8 +52,8 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService: } } - suspend fun onSyncCompleted(syncResponse: SyncResponse) { - cryptoService.onSyncCompleted(syncResponse) + suspend fun onSyncCompleted() { + cryptoService.onSyncCompleted() } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index e306c1ad4c..b456f87648 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -127,7 +127,7 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private } Timber.v("On sync completed") - cryptoSyncHandler.onSyncCompleted(syncResponse) + cryptoSyncHandler.onSyncCompleted() } /** From f5348d6c9d78f96454d7d443c42f1392a76080a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 14:02:32 +0100 Subject: [PATCH 033/252] crypto: Remove the object signer from the crypto service --- .../internal/crypto/DefaultCryptoService.kt | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 936d3fb5cb..83f20a9b17 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -148,8 +148,6 @@ internal class DefaultCryptoService @Inject constructor( // The key backup service. private val keysBackupService: DefaultKeysBackupService, // - private val objectSigner: ObjectSigner, - // private val roomDecryptorProvider: RoomDecryptorProvider, // The verification service. private val verificationService: DefaultVerificationService, @@ -341,11 +339,6 @@ internal class DefaultCryptoService @Inject constructor( cryptoCoroutineScope.launchToCallback(coroutineDispatchers.crypto, NoOpMatrixCallback()) { // Open the store cryptoStore.open() - // this can throw if no network - tryOrNull { - uploadDeviceKeys() - } - // this can throw if no backup tryOrNull { keysBackupService.checkAndStartKeysBackup() @@ -1005,30 +998,6 @@ internal class DefaultCryptoService @Inject constructor( } } - /** - * Upload my user's device keys. - */ - private suspend fun uploadDeviceKeys() { - // sendOutgoingRequests() - // if (cryptoStore.getDeviceKeysUploaded()) { - // Timber.d("Keys already uploaded, nothing to do") - // return - // } - // // Prepare the device keys data to send - // // Sign it - // val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, getMyDevice().signalableJSONDictionary()) - // var rest = getMyDevice().toRest() - - // rest = rest.copy( - // signatures = objectSigner.signObject(canonicalJson) - // ) - - // val uploadDeviceKeysParams = UploadKeysTask.Params(rest, null) - // uploadKeysTask.execute(uploadDeviceKeysParams) - - // cryptoStore.setDeviceKeysUploaded(true) - } - /** * Export the crypto keys * From 515c9be2d96f0a60b83691c7602e29ba298916db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 14:17:26 +0100 Subject: [PATCH 034/252] crypto: Remove the CryptoSyncHandler --- .../internal/crypto/DefaultCryptoService.kt | 1 + .../session/sync/CryptoSyncHandler.kt | 98 ------------------- .../session/sync/SyncResponseHandler.kt | 3 +- 3 files changed, 2 insertions(+), 100 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 83f20a9b17..9f3c5845a9 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -339,6 +339,7 @@ internal class DefaultCryptoService @Inject constructor( cryptoCoroutineScope.launchToCallback(coroutineDispatchers.crypto, NoOpMatrixCallback()) { // Open the store cryptoStore.open() + // this can throw if no backup tryOrNull { keysBackupService.checkAndStartKeysBackup() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt deleted file mode 100644 index 9d3328eb43..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/CryptoSyncHandler.kt +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.session.sync - -import org.matrix.android.sdk.api.session.crypto.MXCryptoError -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.room.model.message.MessageContent -import org.matrix.android.sdk.internal.crypto.DefaultCryptoService -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult -import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent -import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService -import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse -import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse -import timber.log.Timber -import javax.inject.Inject - -internal class CryptoSyncHandler @Inject constructor(private val cryptoService: DefaultCryptoService, - private val verificationService: DefaultVerificationService) { - - fun handleToDevice(toDevice: ToDeviceSyncResponse, initialSyncProgressService: DefaultInitialSyncProgressService? = null) { - val total = toDevice.events?.size ?: 0 - toDevice.events?.forEachIndexed { index, event -> - initialSyncProgressService?.reportProgress(((index / total.toFloat()) * 100).toInt()) - // Decrypt event if necessary - Timber.i("## CRYPTO | To device event from ${event.senderId} of type:${event.type}") - decryptToDeviceEvent(event, null) - if (event.getClearType() == EventType.MESSAGE - && event.getClearContent()?.toModel()?.msgType == "m.bad.encrypted") { - Timber.e("## CRYPTO | handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}") - } else { - verificationService.onToDeviceEvent(event) - cryptoService.onToDeviceEvent(event) - } - } - } - - suspend fun onSyncCompleted() { - cryptoService.onSyncCompleted() - } - - /** - * Decrypt an encrypted event - * - * @param event the event to decrypt - * @param timelineId the timeline identifier - * @return true if the event has been decrypted - */ - private fun decryptToDeviceEvent(event: Event, timelineId: String?): Boolean { - Timber.v("## CRYPTO | decryptToDeviceEvent") - if (event.getClearType() == EventType.ENCRYPTED) { - var result: MXEventDecryptionResult? = null - try { - result = cryptoService.decryptEvent(event, timelineId ?: "") - } catch (exception: MXCryptoError) { - event.mCryptoError = (exception as? MXCryptoError.Base)?.errorType // setCryptoError(exception.cryptoError) - val senderKey = event.content.toModel()?.senderKey ?: "" - // try to find device id to ease log reading - val deviceId = cryptoService.getCryptoDeviceInfo(event.senderId!!).firstOrNull { - it.identityKey() == senderKey - }?.deviceId ?: senderKey - Timber.e("## CRYPTO | Failed to decrypt to device event from ${event.senderId}|$deviceId reason:<${event.mCryptoError ?: exception}>") - } - - if (null != result) { - event.mxDecryptionResult = OlmDecryptionResult( - payload = result.clearEvent, - senderKey = result.senderCurve25519Key, - keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) }, - forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain - ) - return true - } else { - // should not happen - Timber.e("## CRYPTO | ERROR NULL DECRYPTION RESULT from ${event.senderId}") - } - } - - return false - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index b456f87648..95a5f980c1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -47,7 +47,6 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private private val roomSyncHandler: RoomSyncHandler, private val userAccountDataSyncHandler: UserAccountDataSyncHandler, private val groupSyncHandler: GroupSyncHandler, - private val cryptoSyncHandler: CryptoSyncHandler, private val cryptoService: DefaultCryptoService, private val tokenStore: SyncTokenStore, private val processEventForPushTask: ProcessEventForPushTask, @@ -127,7 +126,7 @@ internal class SyncResponseHandler @Inject constructor(@SessionDatabase private } Timber.v("On sync completed") - cryptoSyncHandler.onSyncCompleted() + cryptoService.onSyncCompleted() } /** From 981e6b65b0d076452578c18e7dd56cdda2d6e7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 14:20:39 +0100 Subject: [PATCH 035/252] crypto: Remove the requestRoomKeyForEvent method This method doesn't seem to be used anywhere, only a single tests seems to call it. The funcionality has been moved to the rust-sdk and tested there. --- .../crypto/gossiping/KeyShareTests.kt | 133 ------------------ .../sdk/api/session/crypto/CryptoService.kt | 2 - .../internal/crypto/DefaultCryptoService.kt | 18 --- 3 files changed, 153 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 8c3917adc1..7d17b07c28 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -66,139 +66,6 @@ class KeyShareTests : InstrumentedTest { private val mTestHelper = CommonTestHelper(context()) private val mCryptoTestHelper = CryptoTestHelper(mTestHelper) - @Test - fun test_DoNotSelfShareIfNotTrusted() { - val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true)) - - // Create an encrypted room and add a message - val roomId = mTestHelper.doSync { - aliceSession.createRoom( - CreateRoomParams().apply { - visibility = RoomDirectoryVisibility.PRIVATE - enableEncryption() - }, - it - ) - } - val room = aliceSession.getRoom(roomId) - assertNotNull(room) - Thread.sleep(4_000) - assertTrue(room?.isEncrypted() == true) - val sentEventId = mTestHelper.sendTextMessage(room!!, "My Message", 1).first().eventId - - // Open a new sessionx - - val aliceSession2 = mTestHelper.logIntoAccount(aliceSession.myUserId, SessionTestParams(true)) - - val roomSecondSessionPOV = aliceSession2.getRoom(roomId) - - val receivedEvent = roomSecondSessionPOV?.getTimeLineEvent(sentEventId) - assertNotNull(receivedEvent) - assert(receivedEvent!!.isEncrypted()) - - try { - aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") - fail("should fail") - } catch (failure: Throwable) { - } - - val outgoingRequestsBefore = aliceSession2.cryptoService().getOutgoingRoomKeyRequests() - // Try to request - aliceSession2.cryptoService().requestRoomKeyForEvent(receivedEvent.root) - - val waitLatch = CountDownLatch(1) - val eventMegolmSessionId = receivedEvent.root.content.toModel()?.sessionId - - var outGoingRequestId: String? = null - - mTestHelper.retryPeriodicallyWithLatch(waitLatch) { - aliceSession2.cryptoService().getOutgoingRoomKeyRequests() - .filter { req -> - // filter out request that was known before - !outgoingRequestsBefore.any { req.requestId == it.requestId } - } - .let { - val outgoing = it.firstOrNull { it.sessionId == eventMegolmSessionId } - outGoingRequestId = outgoing?.requestId - outgoing != null - } - } - mTestHelper.await(waitLatch) - - Log.v("TEST", "=======> Outgoing requet Id is $outGoingRequestId") - - val outgoingRequestAfter = aliceSession2.cryptoService().getOutgoingRoomKeyRequests() - - // We should have a new request - Assert.assertTrue(outgoingRequestAfter.size > outgoingRequestsBefore.size) - Assert.assertNotNull(outgoingRequestAfter.first { it.sessionId == eventMegolmSessionId }) - - // The first session should see an incoming request - // the request should be refused, because the device is not trusted - mTestHelper.waitWithLatch { latch -> - mTestHelper.retryPeriodicallyWithLatch(latch) { - // DEBUG LOGS - aliceSession.cryptoService().getIncomingRoomKeyRequests().let { - Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)") - Log.v("TEST", "=========================") - it.forEach { keyRequest -> - Log.v("TEST", "[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}") - } - Log.v("TEST", "=========================") - } - - val incoming = aliceSession.cryptoService().getIncomingRoomKeyRequests().firstOrNull { it.requestId == outGoingRequestId } - incoming?.state == GossipingRequestState.REJECTED - } - } - - try { - aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") - fail("should fail") - } catch (failure: Throwable) { - } - - // Mark the device as trusted - aliceSession.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession.myUserId, - aliceSession2.sessionParams.deviceId ?: "") - - // Re request - aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root) - - mTestHelper.waitWithLatch { latch -> - mTestHelper.retryPeriodicallyWithLatch(latch) { - aliceSession.cryptoService().getIncomingRoomKeyRequests().let { - Log.v("TEST", "Incoming request Session 1") - Log.v("TEST", "=========================") - it.forEach { - Log.v("TEST", "requestId ${it.requestId}, for sessionId ${it.requestBody?.sessionId} is ${it.state}") - } - Log.v("TEST", "=========================") - - it.any { it.requestBody?.sessionId == eventMegolmSessionId && it.state == GossipingRequestState.ACCEPTED } - } - } - } - - Thread.sleep(6_000) - mTestHelper.waitWithLatch { latch -> - mTestHelper.retryPeriodicallyWithLatch(latch) { - aliceSession2.cryptoService().getOutgoingRoomKeyRequests().let { - it.any { it.requestBody?.sessionId == eventMegolmSessionId && it.state == OutgoingGossipingRequestState.CANCELLED } - } - } - } - - try { - aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") - } catch (failure: Throwable) { - fail("should have been able to decrypt") - } - - mTestHelper.signOutAndClose(aliceSession) - mTestHelper.signOutAndClose(aliceSession2) - } - @Test fun test_ShareSSSSSecret() { val aliceSession1 = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true)) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index fa5ea359e8..595d38f704 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -92,8 +92,6 @@ interface CryptoService { fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? - fun requestRoomKeyForEvent(event: Event) - fun reRequestRoomKeyForEvent(event: Event) fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 9f3c5845a9..54ae6e43bc 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -1191,24 +1191,6 @@ internal class DefaultCryptoService @Inject constructor( outgoingGossipingRequestManager.resendRoomKeyRequest(requestBody) } - override fun requestRoomKeyForEvent(event: Event) { - val wireContent = event.content.toModel() ?: return Unit.also { - Timber.e("## CRYPTO | requestRoomKeyForEvent Failed to request key, null content eventId: ${event.eventId}") - } - - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// if (!isStarted()) { -// Timber.v("## CRYPTO | requestRoomKeyForEvent() : wait after e2e init") -// internalStart(false) -// } - roomDecryptorProvider - .getOrCreateRoomDecryptor(event.roomId, wireContent.algorithm) - ?.requestKeysForEvent(event, false) ?: run { - Timber.v("## CRYPTO | requestRoomKeyForEvent() : No room decryptor for roomId:${event.roomId} algorithm:${wireContent.algorithm}") - } - } - } - /** * Add a GossipingRequestListener listener. * From 5b2629ba0046c09c1b2dc7e15b53f10b6f3ba0e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 15:21:39 +0100 Subject: [PATCH 036/252] crypto: Remove the incoming gossipping manager --- .../internal/crypto/DefaultCryptoService.kt | 70 +------------------ 1 file changed, 2 insertions(+), 68 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 54ae6e43bc..53ab64e4eb 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -154,8 +154,6 @@ internal class DefaultCryptoService @Inject constructor( private val crossSigningService: DefaultCrossSigningService, // - private val incomingGossipingRequestManager: IncomingGossipingRequestManager, - // private val outgoingGossipingRequestManager: OutgoingGossipingRequestManager, // Actions private val setDeviceVerificationAction: SetDeviceVerificationAction, @@ -386,15 +384,6 @@ internal class DefaultCryptoService @Inject constructor( cryptoStore.open() runCatching { -// if (isInitialSync) { -// // refresh the devices list for each known room members -// deviceListManager.invalidateAllDeviceLists() -// deviceListManager.refreshOutdatedDeviceLists() -// } else { - - // Why would we do that? it will be called at end of syn - incomingGossipingRequestManager.processReceivedGossipingRequests() -// } }.fold( { isStarting.set(false) @@ -413,7 +402,6 @@ internal class DefaultCryptoService @Inject constructor( */ fun close() = runBlocking(coroutineDispatchers.crypto) { cryptoCoroutineScope.coroutineContext.cancelChildren(CancellationException("Closing crypto module")) - incomingGossipingRequestManager.close() cryptoStore.close() } @@ -441,13 +429,6 @@ internal class DefaultCryptoService @Inject constructor( } cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - runCatching { - if (isStarted()) { - // Make sure we process to-device messages before generating new one-time-keys #2782 - incomingGossipingRequestManager.processReceivedGossipingRequests() - } - } - tryOrNull { gossipingBuffer.toList().let { cryptoStore.saveGossipingEvents(it) @@ -714,53 +695,6 @@ internal class DefaultCryptoService @Inject constructor( eventDecryptor.decryptEventAsync(event, timeline, callback) } - /** - * Decrypt an event - * - * @param event the raw event. - * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. - * @return the MXEventDecryptionResult data, or null in case of error - */ - @Throws(MXCryptoError::class) - private fun internalDecryptEvent(event: Event, timeline: String): MXEventDecryptionResult { - return eventDecryptor.decryptEvent(event, timeline) - } - - /** - * Handle the 'toDevice' event - * - * @param event the event - */ - fun onToDeviceEvent(event: Event) { - // event have already been decrypted - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - when (event.getClearType()) { - EventType.ROOM_KEY, EventType.FORWARDED_ROOM_KEY -> { - gossipingBuffer.add(event) - // Keys are imported directly, not waiting for end of sync - onRoomKeyEvent(event) - } - EventType.REQUEST_SECRET, - EventType.ROOM_KEY_REQUEST -> { - // save audit trail - gossipingBuffer.add(event) - // Requests are stacked, and will be handled one by one at the end of the sync (onSyncComplete) - incomingGossipingRequestManager.onGossipingRequestEvent(event) - } - EventType.SEND_SECRET -> { - gossipingBuffer.add(event) - onSecretSendReceived(event) - } - EventType.ROOM_KEY_WITHHELD -> { - onKeyWithHeldReceived(event) - } - else -> { - // ignore - } - } - } - } - /** * Handle a key event. * @@ -1197,7 +1131,7 @@ internal class DefaultCryptoService @Inject constructor( * @param listener listener */ override fun addRoomKeysRequestListener(listener: GossipingRequestListener) { - incomingGossipingRequestManager.addRoomKeysRequestListener(listener) + // TODO } /** @@ -1206,7 +1140,7 @@ internal class DefaultCryptoService @Inject constructor( * @param listener listener */ override fun removeRoomKeysRequestListener(listener: GossipingRequestListener) { - incomingGossipingRequestManager.removeRoomKeysRequestListener(listener) + // TODO } // private fun markOlmSessionForUnwedging(senderId: String, deviceInfo: CryptoDeviceInfo) { From 67f238069abaf6a2f7660685555fd5bd673e8d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 15:44:33 +0100 Subject: [PATCH 037/252] crypto: Remove the gossipping managers from the crypto service --- .../internal/crypto/DefaultCryptoService.kt | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 53ab64e4eb..8112a6b70e 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -153,10 +153,7 @@ internal class DefaultCryptoService @Inject constructor( private val verificationService: DefaultVerificationService, private val crossSigningService: DefaultCrossSigningService, - // - private val outgoingGossipingRequestManager: OutgoingGossipingRequestManager, // Actions - private val setDeviceVerificationAction: SetDeviceVerificationAction, private val megolmSessionDataImporter: MegolmSessionDataImporter, private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository, // Repository @@ -527,7 +524,7 @@ internal class DefaultCryptoService @Inject constructor( * @param deviceId the unique identifier for the device. */ override fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) { - setDeviceVerificationAction.handle(trustLevel, userId, deviceId) + // TODO } /** @@ -1102,7 +1099,7 @@ internal class DefaultCryptoService @Inject constructor( * @param requestBody requestBody */ override fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody) { - outgoingGossipingRequestManager.cancelRoomKeyRequest(requestBody) + // TODO } /** @@ -1111,18 +1108,7 @@ internal class DefaultCryptoService @Inject constructor( * @param event the event to decrypt again. */ override fun reRequestRoomKeyForEvent(event: Event) { - val wireContent = event.content.toModel() ?: return Unit.also { - Timber.e("## CRYPTO | reRequestRoomKeyForEvent Failed to re-request key, null content") - } - - val requestBody = RoomKeyRequestBody( - algorithm = wireContent.algorithm, - roomId = event.roomId, - senderKey = wireContent.senderKey, - sessionId = wireContent.sessionId - ) - - outgoingGossipingRequestManager.resendRoomKeyRequest(requestBody) + // TODO } /** From 758e8f7fb639bb31c86b839b7cec290a6dbd94e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 15:45:03 +0100 Subject: [PATCH 038/252] crypto: Remove the cancelRoomKeyRequest method --- .../android/sdk/api/session/crypto/CryptoService.kt | 2 -- .../sdk/internal/crypto/DefaultCryptoService.kt | 13 ++----------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 595d38f704..6cfd49b886 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -94,8 +94,6 @@ interface CryptoService { fun reRequestRoomKeyForEvent(event: Event) - fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody) - fun addRoomKeysRequestListener(listener: GossipingRequestListener) fun removeRoomKeysRequestListener(listener: GossipingRequestListener) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 8112a6b70e..307006d764 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -154,6 +154,7 @@ internal class DefaultCryptoService @Inject constructor( private val crossSigningService: DefaultCrossSigningService, // Actions + private val setDeviceVerificationAction: SetDeviceVerificationAction, private val megolmSessionDataImporter: MegolmSessionDataImporter, private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository, // Repository @@ -524,7 +525,7 @@ internal class DefaultCryptoService @Inject constructor( * @param deviceId the unique identifier for the device. */ override fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) { - // TODO + setDeviceVerificationAction.handle(trustLevel, userId, deviceId) } /** @@ -1092,16 +1093,6 @@ internal class DefaultCryptoService @Inject constructor( setRoomBlacklistUnverifiedDevices(roomId, false) } -// TODO Check if this method is still necessary - /** - * Cancel any earlier room key request - * - * @param requestBody requestBody - */ - override fun cancelRoomKeyRequest(requestBody: RoomKeyRequestBody) { - // TODO - } - /** * Re request the encryption keys required to decrypt an event. * From 1773a361d1b96120bef54000755e18531f13d227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 15:49:31 +0100 Subject: [PATCH 039/252] crypto: Remove the method to delete devices with an user password --- .../android/sdk/api/session/crypto/CryptoService.kt | 2 -- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 9 --------- 2 files changed, 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 6cfd49b886..49c27625f8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -56,8 +56,6 @@ interface CryptoService { fun deleteDevice(deviceId: String, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, callback: MatrixCallback) - fun deleteDeviceWithUserPassword(deviceId: String, authSession: String?, password: String, callback: MatrixCallback) - fun getCryptoVersion(context: Context, longFormat: Boolean): String fun isCryptoEnabled(): Boolean diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 307006d764..40b6a727eb 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -229,15 +229,6 @@ internal class DefaultCryptoService @Inject constructor( .executeBy(taskExecutor) } - override fun deleteDeviceWithUserPassword(deviceId: String, authSession: String?, password: String, callback: MatrixCallback) { - deleteDeviceWithUserPasswordTask - .configureWith(DeleteDeviceWithUserPasswordTask.Params(deviceId, authSession, password)) { - this.executionThread = TaskThread.CRYPTO - this.callback = callback - } - .executeBy(taskExecutor) - } - override fun getCryptoVersion(context: Context, longFormat: Boolean): String { return if (longFormat) olmManager.getDetailedVersion(context) else olmManager.version } From 555d24fea5b2aae017215ddc21712bbcd7167425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 15:54:56 +0100 Subject: [PATCH 040/252] crypto: Remove the delete device with password task --- .../sdk/internal/crypto/CryptoModule.kt | 5 -- .../internal/crypto/DefaultCryptoService.kt | 2 - .../tasks/DeleteDeviceWithUserPasswordTask.kt | 57 ------------------- 3 files changed, 64 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index b9070994e4..297979afc7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -61,7 +61,6 @@ import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultClaimOneTimeKeysForUsersDevice import org.matrix.android.sdk.internal.crypto.tasks.DefaultDeleteDeviceTask -import org.matrix.android.sdk.internal.crypto.tasks.DefaultDeleteDeviceWithUserPasswordTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultDownloadKeysForUsers import org.matrix.android.sdk.internal.crypto.tasks.DefaultEncryptEventTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultGetDeviceInfoTask @@ -76,7 +75,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.NewDefaultUploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadSignaturesTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadSigningKeysTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask -import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceWithUserPasswordTask import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.crypto.tasks.EncryptEventTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask @@ -245,9 +243,6 @@ internal abstract class CryptoModule { @Binds abstract fun bindClaimOneTimeKeysForUsersDeviceTask(task: DefaultClaimOneTimeKeysForUsersDevice): ClaimOneTimeKeysForUsersDeviceTask - @Binds - abstract fun bindDeleteDeviceWithUserPasswordTask(task: DefaultDeleteDeviceWithUserPasswordTask): DeleteDeviceWithUserPasswordTask - @Binds abstract fun bindCrossSigningService(service: DefaultCrossSigningService): CrossSigningService diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 40b6a727eb..5747ca7bf8 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -85,7 +85,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask -import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceWithUserPasswordTask import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask @@ -161,7 +160,6 @@ internal class DefaultCryptoService @Inject constructor( private val megolmEncryptionFactory: MXMegolmEncryptionFactory, private val olmEncryptionFactory: MXOlmEncryptionFactory, private val deleteDeviceTask: DeleteDeviceTask, - private val deleteDeviceWithUserPasswordTask: DeleteDeviceWithUserPasswordTask, // Tasks private val getDevicesTask: GetDevicesTask, private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt deleted file mode 100644 index dc0077425e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/DeleteDeviceWithUserPasswordTask.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.tasks - -import org.matrix.android.sdk.api.auth.data.LoginFlowTypes -import org.matrix.android.sdk.internal.crypto.api.CryptoApi -import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams -import org.matrix.android.sdk.api.auth.UserPasswordAuth -import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.network.GlobalErrorReceiver -import org.matrix.android.sdk.internal.network.executeRequest -import org.matrix.android.sdk.internal.task.Task -import javax.inject.Inject - -internal interface DeleteDeviceWithUserPasswordTask : Task { - data class Params( - val deviceId: String, - val authSession: String?, - val password: String - ) -} - -internal class DefaultDeleteDeviceWithUserPasswordTask @Inject constructor( - private val cryptoApi: CryptoApi, - @UserId private val userId: String, - private val globalErrorReceiver: GlobalErrorReceiver -) : DeleteDeviceWithUserPasswordTask { - - override suspend fun execute(params: DeleteDeviceWithUserPasswordTask.Params) { - return executeRequest(globalErrorReceiver) { - apiCall = cryptoApi.deleteDevice(params.deviceId, - DeleteDeviceParams( - auth = UserPasswordAuth( - type = LoginFlowTypes.PASSWORD, - session = params.authSession, - user = userId, - password = params.password - ).asMap() - ) - ) - } - } -} From 629623f720539862cf2756d5a225e9b35f4539be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 16:00:51 +0100 Subject: [PATCH 041/252] crypto: Remove the one-time keys uploader --- .../internal/crypto/OneTimeKeysUploader.kt | 168 ------------------ 1 file changed, 168 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt deleted file mode 100644 index 6695234d62..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto - -import org.matrix.android.sdk.internal.crypto.model.MXKey -import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse -import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask -import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.util.JsonCanonicalizer -import org.matrix.olm.OlmAccount -import timber.log.Timber -import javax.inject.Inject -import kotlin.math.floor -import kotlin.math.min - -@SessionScope -internal class OneTimeKeysUploader @Inject constructor( - private val olmDevice: MXOlmDevice, - private val objectSigner: ObjectSigner, - private val uploadKeysTask: UploadKeysTask -) { - // tell if there is a OTK check in progress - private var oneTimeKeyCheckInProgress = false - - // last OTK check timestamp - private var lastOneTimeKeyCheck: Long = 0 - private var oneTimeKeyCount: Int? = null - - /** - * Stores the current one_time_key count which will be handled later (in a call of - * _onSyncCompleted). The count is e.g. coming from a /sync response. - * - * @param currentCount the new count - */ - fun updateOneTimeKeyCount(currentCount: Int) { - oneTimeKeyCount = currentCount - } - - /** - * Check if the OTK must be uploaded. - */ - suspend fun maybeUploadOneTimeKeys() { - if (oneTimeKeyCheckInProgress) { - Timber.v("maybeUploadOneTimeKeys: already in progress") - return - } - if (System.currentTimeMillis() - lastOneTimeKeyCheck < ONE_TIME_KEY_UPLOAD_PERIOD) { - // we've done a key upload recently. - Timber.v("maybeUploadOneTimeKeys: executed too recently") - return - } - - lastOneTimeKeyCheck = System.currentTimeMillis() - oneTimeKeyCheckInProgress = true - - // We then check how many keys we can store in the Account object. - val maxOneTimeKeys = olmDevice.getMaxNumberOfOneTimeKeys() - - // Try to keep at most half that number on the server. This leaves the - // rest of the slots free to hold keys that have been claimed from the - // server but we haven't received a message for. - // If we run out of slots when generating new keys then olm will - // discard the oldest private keys first. This will eventually clean - // out stale private keys that won't receive a message. - val keyLimit = floor(maxOneTimeKeys / 2.0).toInt() - val oneTimeKeyCountFromSync = oneTimeKeyCount - if (oneTimeKeyCountFromSync != null) { - // We need to keep a pool of one time public keys on the server so that - // other devices can start conversations with us. But we can only store - // a finite number of private keys in the olm Account object. - // To complicate things further then can be a delay between a device - // claiming a public one time key from the server and it sending us a - // message. We need to keep the corresponding private key locally until - // we receive the message. - // But that message might never arrive leaving us stuck with duff - // private keys clogging up our local storage. - // So we need some kind of engineering compromise to balance all of - // these factors. - try { - val uploadedKeys = uploadOTK(oneTimeKeyCountFromSync, keyLimit) - Timber.v("## uploadKeys() : success, $uploadedKeys key(s) sent") - } finally { - oneTimeKeyCheckInProgress = false - } - } else { - Timber.w("maybeUploadOneTimeKeys: waiting to know the number of OTK from the sync") - oneTimeKeyCheckInProgress = false - lastOneTimeKeyCheck = 0 - } - } - - /** - * Upload some the OTKs. - * - * @param keyCount the key count - * @param keyLimit the limit - * @return the number of uploaded keys - */ - private suspend fun uploadOTK(keyCount: Int, keyLimit: Int): Int { - if (keyLimit <= keyCount) { - // If we don't need to generate any more keys then we are done. - return 0 - } - val keysThisLoop = min(keyLimit - keyCount, ONE_TIME_KEY_GENERATION_MAX_NUMBER) - olmDevice.generateOneTimeKeys(keysThisLoop) - val response = uploadOneTimeKeys(olmDevice.getOneTimeKeys()) - olmDevice.markKeysAsPublished() - - if (response.hasOneTimeKeyCountsForAlgorithm(MXKey.KEY_SIGNED_CURVE_25519_TYPE)) { - // Maybe upload other keys - return keysThisLoop + uploadOTK(response.oneTimeKeyCountsForAlgorithm(MXKey.KEY_SIGNED_CURVE_25519_TYPE), keyLimit) - } else { - Timber.e("## uploadOTK() : response for uploading keys does not contain one_time_key_counts.signed_curve25519") - throw Exception("response for uploading keys does not contain one_time_key_counts.signed_curve25519") - } - } - - /** - * Upload curve25519 one time keys. - */ - private suspend fun uploadOneTimeKeys(oneTimeKeys: Map>?): KeysUploadResponse { - val oneTimeJson = mutableMapOf() - - val curve25519Map = oneTimeKeys?.get(OlmAccount.JSON_KEY_ONE_TIME_KEY).orEmpty() - - curve25519Map.forEach { (key_id, value) -> - val k = mutableMapOf() - k["key"] = value - - // the key is also signed - val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, k) - - k["signatures"] = objectSigner.signObject(canonicalJson) - - oneTimeJson["signed_curve25519:$key_id"] = k - } - - // For now, we set the device id explicitly, as we may not be using the - // same one as used in login. - val uploadParams = UploadKeysTask.Params(null, oneTimeJson) - return uploadKeysTask.execute(uploadParams) - } - - companion object { - // max number of keys to upload at once - // Creating keys can be an expensive operation so we limit the - // number we generate in one go to avoid blocking the application - // for too long. - private const val ONE_TIME_KEY_GENERATION_MAX_NUMBER = 5 - - // frequency with which to check & upload one-time keys - private const val ONE_TIME_KEY_UPLOAD_PERIOD = (60 * 1000).toLong() // one minute - } -} From 6e53ab2bcfe3f26216f4bd599a3d4944048735d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 16:01:19 +0100 Subject: [PATCH 042/252] crypto: Remove an unused method --- .../internal/crypto/DefaultCryptoService.kt | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 5747ca7bf8..80e3c8a2a5 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -1142,28 +1142,6 @@ internal class DefaultCryptoService @Inject constructor( // } // } - /** - * Provides the list of unknown devices - * - * @param devicesInRoom the devices map - * @return the unknown devices map - */ - private fun getUnknownDevices(devicesInRoom: MXUsersDevicesMap): MXUsersDevicesMap { - val unknownDevices = MXUsersDevicesMap() - val userIds = devicesInRoom.userIds - for (userId in userIds) { - devicesInRoom.getUserDeviceIds(userId)?.forEach { deviceId -> - devicesInRoom.getObject(userId, deviceId) - ?.takeIf { it.isUnknown } - ?.let { - unknownDevices.setObject(userId, deviceId, it) - } - } - } - - return unknownDevices - } - override fun downloadKeys(userIds: List, forceDownload: Boolean, callback: MatrixCallback>) { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { runCatching { From 36451e54108f33cd7a17764caaf83f10e58f81ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 16:01:40 +0100 Subject: [PATCH 043/252] crypto: Remove the unused olm unwedging method --- .../internal/crypto/DefaultCryptoService.kt | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 80e3c8a2a5..52a617053e 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -1109,39 +1109,6 @@ internal class DefaultCryptoService @Inject constructor( // TODO } -// private fun markOlmSessionForUnwedging(senderId: String, deviceInfo: CryptoDeviceInfo) { -// val deviceKey = deviceInfo.identityKey() -// -// val lastForcedDate = lastNewSessionForcedDates.getObject(senderId, deviceKey) ?: 0 -// val now = System.currentTimeMillis() -// if (now - lastForcedDate < CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS) { -// Timber.d("## CRYPTO | markOlmSessionForUnwedging: New session already forced with device at $lastForcedDate. Not forcing another") -// return -// } -// -// Timber.d("## CRYPTO | markOlmSessionForUnwedging from $senderId:${deviceInfo.deviceId}") -// lastNewSessionForcedDates.setObject(senderId, deviceKey, now) -// -// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// ensureOlmSessionsForDevicesAction.handle(mapOf(senderId to listOf(deviceInfo)), force = true) -// -// // Now send a blank message on that session so the other side knows about it. -// // (The keyshare request is sent in the clear so that won't do) -// // We send this first such that, as long as the toDevice messages arrive in the -// // same order we sent them, the other end will get this first, set up the new session, -// // then get the keyshare request and send the key over this new session (because it -// // is the session it has most recently received a message on). -// val payloadJson = mapOf("type" to EventType.DUMMY) -// -// val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo)) -// val sendToDeviceMap = MXUsersDevicesMap() -// sendToDeviceMap.setObject(senderId, deviceInfo.deviceId, encodedPayload) -// Timber.v("## CRYPTO | markOlmSessionForUnwedging() : sending to $senderId:${deviceInfo.deviceId}") -// val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap) -// sendToDeviceTask.execute(sendToDeviceParams) -// } -// } - override fun downloadKeys(userIds: List, forceDownload: Boolean, callback: MatrixCallback>) { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { runCatching { From 6bc825b0bcc611425e05a352c57ccb00336d8045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 16:15:52 +0100 Subject: [PATCH 044/252] crypto: Remove the UploadKeysTask copy --- .../sdk/internal/crypto/CryptoModule.kt | 5 --- .../internal/crypto/DefaultCryptoService.kt | 8 ++--- .../sdk/internal/crypto/api/CryptoApi.kt | 11 +------ .../internal/crypto/tasks/UploadKeysTask.kt | 32 ++----------------- 4 files changed, 6 insertions(+), 50 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index 297979afc7..e114f86a99 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -71,7 +71,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultSetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadKeysTask -import org.matrix.android.sdk.internal.crypto.tasks.NewDefaultUploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadSignaturesTask import org.matrix.android.sdk.internal.crypto.tasks.DefaultUploadSigningKeysTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask @@ -85,7 +84,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.SendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask -import org.matrix.android.sdk.internal.crypto.tasks.NewUploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask import org.matrix.android.sdk.internal.crypto.tasks.UploadSigningKeysTask import org.matrix.android.sdk.internal.database.RealmKeysUtils @@ -177,9 +175,6 @@ internal abstract class CryptoModule { @Binds abstract fun bindUploadKeysTask(task: DefaultUploadKeysTask): UploadKeysTask - @Binds - abstract fun bindNewUploadKeysTask(task: NewDefaultUploadKeysTask): NewUploadKeysTask - @Binds abstract fun bindUploadSigningKeysTask(task: DefaultUploadSigningKeysTask): UploadSigningKeysTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 52a617053e..73e0c9da2f 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -88,10 +88,9 @@ import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask -import org.matrix.android.sdk.internal.crypto.tasks.NewUploadKeysTask +import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask -import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService import org.matrix.android.sdk.internal.di.DeviceId @@ -168,7 +167,6 @@ internal class DefaultCryptoService @Inject constructor( private val getDeviceInfoTask: GetDeviceInfoTask, private val setDeviceNameTask: SetDeviceNameTask, private val uploadKeysTask: UploadKeysTask, - private val newUploadKeysTask: NewUploadKeysTask, private val loadRoomMembersTask: LoadRoomMembersTask, private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, private val coroutineDispatchers: MatrixCoroutineDispatchers, @@ -890,9 +888,9 @@ internal class DefaultCryptoService @Inject constructor( is Request.KeysUpload -> { Timber.v("HELLO UPLOADING RUSTY KEYS") val body = MoshiProvider.providesMoshi().adapter(Map::class.java).fromJson(outgoingRequest.body)!! - val request = NewUploadKeysTask.Params(body) + val request = UploadKeysTask.Params(body) - val response = newUploadKeysTask.execute(request) + val response = uploadKeysTask.execute(request) val adapter = MoshiProvider.providesMoshi().adapter(KeysUploadResponse::class.java) val json_response = adapter.toJson(response)!! olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_UPLOAD, json_response) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt index 104cb1e97f..3c02670b9b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt @@ -56,21 +56,12 @@ internal interface CryptoApi { @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "devices/{deviceId}") fun getDeviceInfo(@Path("deviceId") deviceId: String): Call - /** - * Upload device and/or one-time keys. - * Doc: https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-keys-upload - * - * @param body the keys to be sent. - */ - @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "keys/upload") - fun uploadKeys(@Body body: KeysUploadBody): Call - /** * Upload device and one-time keys * @param body the keys to be sent. */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "keys/upload") - fun newUploadKeys(@Body body: JsonDict): Call + fun UploadKeys(@Body body: JsonDict): Call /** * Download device keys. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt index 0dbd87c537..b485de702a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt @@ -29,10 +29,7 @@ import javax.inject.Inject internal interface UploadKeysTask : Task { data class Params( - // the device keys to send. - val deviceKeys: DeviceKeys?, - // the one-time keys to send. - val oneTimeKeys: JsonDict? + val body: JsonDict ) } @@ -42,35 +39,10 @@ internal class DefaultUploadKeysTask @Inject constructor( ) : UploadKeysTask { override suspend fun execute(params: UploadKeysTask.Params): KeysUploadResponse { - val body = KeysUploadBody( - deviceKeys = params.deviceKeys, - oneTimeKeys = params.oneTimeKeys - ) - - Timber.i("## Uploading device keys -> $body") - - return executeRequest(globalErrorReceiver) { - apiCall = cryptoApi.uploadKeys(body) - } - } -} - -internal interface NewUploadKeysTask : Task { - data class Params( - val body: JsonDict - ) -} - -internal class NewDefaultUploadKeysTask @Inject constructor( - private val cryptoApi: CryptoApi, - private val globalErrorReceiver: GlobalErrorReceiver -) : NewUploadKeysTask { - - override suspend fun execute(params: NewUploadKeysTask.Params): KeysUploadResponse { Timber.i("## Uploading device keys -> $params.body") return executeRequest(globalErrorReceiver) { - apiCall = cryptoApi.newUploadKeys(params.body) + apiCall = cryptoApi.UploadKeys(params.body) } } } From 4eeb47dc5604ba5853670353c81487bd3ebd9ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 16:27:38 +0100 Subject: [PATCH 045/252] crypto: Remove more unused methods --- .../internal/crypto/DefaultCryptoService.kt | 89 ------------------- 1 file changed, 89 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 73e0c9da2f..368febe2d8 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -680,95 +680,6 @@ internal class DefaultCryptoService @Inject constructor( eventDecryptor.decryptEventAsync(event, timeline, callback) } - /** - * Handle a key event. - * - * @param event the key event. - */ - private fun onRoomKeyEvent(event: Event) { - val roomKeyContent = event.getClearContent().toModel() ?: return - Timber.i("## CRYPTO | onRoomKeyEvent() from: ${event.senderId} type<${event.getClearType()}> , sessionId<${roomKeyContent.sessionId}>") - if (roomKeyContent.roomId.isNullOrEmpty() || roomKeyContent.algorithm.isNullOrEmpty()) { - Timber.e("## CRYPTO | onRoomKeyEvent() : missing fields") - return - } - val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(roomKeyContent.roomId, roomKeyContent.algorithm) - if (alg == null) { - Timber.e("## CRYPTO | GOSSIP onRoomKeyEvent() : Unable to handle keys for ${roomKeyContent.algorithm}") - return - } - alg.onRoomKeyEvent(event, keysBackupService) - } - - private fun onKeyWithHeldReceived(event: Event) { - val withHeldContent = event.getClearContent().toModel() ?: return Unit.also { - Timber.i("## CRYPTO | Malformed onKeyWithHeldReceived() : missing fields") - } - Timber.i("## CRYPTO | onKeyWithHeldReceived() received from:${event.senderId}, content <$withHeldContent>") - val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(withHeldContent.roomId, withHeldContent.algorithm) - if (alg is IMXWithHeldExtension) { - alg.onRoomKeyWithHeldEvent(withHeldContent) - } else { - Timber.e("## CRYPTO | onKeyWithHeldReceived() from:${event.senderId}: Unable to handle WithHeldContent for ${withHeldContent.algorithm}") - return - } - } - - private fun onSecretSendReceived(event: Event) { - Timber.i("## CRYPTO | GOSSIP onSecretSend() from ${event.senderId} : onSecretSendReceived ${event.content?.get("sender_key")}") - if (!event.isEncrypted()) { - // secret send messages must be encrypted - Timber.e("## CRYPTO | GOSSIP onSecretSend() :Received unencrypted secret send event") - return - } - - // Was that sent by us? - if (event.senderId != userId) { - Timber.e("## CRYPTO | GOSSIP onSecretSend() : Ignore secret from other user ${event.senderId}") - return - } - - val secretContent = event.getClearContent().toModel() ?: return - - val existingRequest = cryptoStore - .getOutgoingSecretKeyRequests().firstOrNull { it.requestId == secretContent.requestId } - - if (existingRequest == null) { - Timber.i("## CRYPTO | GOSSIP onSecretSend() : Ignore secret that was not requested: ${secretContent.requestId}") - return - } - - if (!handleSDKLevelGossip(existingRequest.secretName, secretContent.secretValue)) { - // TODO Ask to application layer? - Timber.v("## CRYPTO | onSecretSend() : secret not handled by SDK") - } - } - - /** - * Returns true if handled by SDK, otherwise should be sent to application layer - */ - private fun handleSDKLevelGossip(secretName: String?, secretValue: String): Boolean { - return when (secretName) { - MASTER_KEY_SSSS_NAME -> { - crossSigningService.onSecretMSKGossip(secretValue) - true - } - SELF_SIGNING_KEY_SSSS_NAME -> { - crossSigningService.onSecretSSKGossip(secretValue) - true - } - USER_SIGNING_KEY_SSSS_NAME -> { - crossSigningService.onSecretUSKGossip(secretValue) - true - } - KEYBACKUP_SECRET_SSSS_NAME -> { - keysBackupService.onSecretKeyGossip(secretValue) - true - } - else -> false - } - } - /** * Handle an m.room.encryption event. * From 4b157f79150713bbc5fbec59c0024c546751745c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Mar 2021 17:03:36 +0100 Subject: [PATCH 046/252] crypto: Don't use the device list manager in onSyncWillProcess --- .../sdk/internal/crypto/DefaultCryptoService.kt | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 368febe2d8..8cb5fdbe82 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -333,18 +333,7 @@ internal class DefaultCryptoService @Inject constructor( fun onSyncWillProcess(isInitialSync: Boolean) { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { if (isInitialSync) { - try { - // On initial sync, we start all our tracking from - // scratch, so mark everything as untracked. onCryptoEvent will - // be called for all e2e rooms during the processing of the sync, - // at which point we'll start tracking all the users of that room. - deviceListManager.invalidateAllDeviceLists() - // always track my devices? - deviceListManager.startTrackingDeviceList(listOf(userId)) - deviceListManager.refreshOutdatedDeviceLists() - } catch (failure: Throwable) { - Timber.e(failure, "## CRYPTO onSyncWillProcess ") - } + // TODO } } } From 3812162f4f5def6d18d8f58b78d4566ed0efaa76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 25 Mar 2021 13:17:06 +0100 Subject: [PATCH 047/252] crypto: Move the outgoing request sending logic into separate methods --- .../internal/crypto/DefaultCryptoService.kt | 105 +++++++++++------- 1 file changed, 67 insertions(+), 38 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 8cb5fdbe82..a04fba6239 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -748,11 +748,7 @@ internal class DefaultCryptoService @Inject constructor( // This request can only be a keys claim request. when (request) { is Request.KeysClaim -> { - val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) - val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) - val adapter = MoshiProvider.providesMoshi().adapter(KeysClaimResponse::class.java) - val json_response = adapter.toJson(response)!! - olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, json_response) + claimKeys(request) } } } @@ -761,17 +757,7 @@ internal class DefaultCryptoService @Inject constructor( // This request can only be a to-device request. when (toDeviceRequest) { is Request.ToDevice -> { - // TODO this produces floats for the Olm type fields, which - // are integers originally. - val adapter = MoshiProvider.providesMoshi().adapter>>(Map::class.java) - val body = adapter.fromJson(toDeviceRequest.body)!! - - val userMap = MXUsersDevicesMap() - userMap.join(body) - - val sendToDeviceParams = SendToDeviceTask.Params(toDeviceRequest.eventType, userMap) - sendToDeviceTask.execute(sendToDeviceParams) - olmMachine!!.markRequestAsSent(toDeviceRequest.requestId, RequestType.TO_DEVICE, "{}") + sendToDevice(toDeviceRequest) } } } @@ -781,35 +767,78 @@ internal class DefaultCryptoService @Inject constructor( return olmMachine!!.encrypt(roomId, eventType, content) } + private suspend fun uploadKeys(outgoingRequest: Request.KeysUpload) { + val body = MoshiProvider + .providesMoshi() + .adapter(Map::class.java) + .fromJson(outgoingRequest.body)!! + + val request = UploadKeysTask.Params(body) + + val response = uploadKeysTask.execute(request) + val adapter = MoshiProvider + .providesMoshi() + .adapter(KeysUploadResponse::class.java) + + val json_response = adapter.toJson(response)!! + + olmMachine!!.markRequestAsSent( + outgoingRequest.requestId, + RequestType.KEYS_UPLOAD, + json_response + ) + } + + private suspend fun queryKeys(outgoingRequest: Request.KeysQuery) { + Timber.v("HELLO KEYS QUERY REQUEST ${outgoingRequest.users}") + val params = DownloadKeysForUsersTask.Params(outgoingRequest.users, null) + + try { + val response = downloadKeysForUsersTask.execute(params) + val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) + val json_response = adapter.toJson(response)!! + olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_QUERY, json_response) + } catch (throwable: Throwable) { + Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") + } + } + + private suspend fun sendToDevice(request: Request.ToDevice) { + // TODO this produces floats for the Olm type fields, which + // are integers originally. + val adapter = MoshiProvider + .providesMoshi() + .adapter>>(Map::class.java) + val body = adapter.fromJson(request.body)!! + + val userMap = MXUsersDevicesMap() + userMap.join(body) + + val sendToDeviceParams = SendToDeviceTask.Params(request.eventType, userMap) + sendToDeviceTask.execute(sendToDeviceParams) + olmMachine!!.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}") + } + + private suspend fun claimKeys(request: Request.KeysClaim) { + val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) + val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) + val adapter = MoshiProvider + .providesMoshi() + .adapter(KeysClaimResponse::class.java) + val json_response = adapter.toJson(response)!! + + olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, json_response) + } + private suspend fun sendOutgoingRequests() { // TODO these requests should be sent out in parallel for (outgoingRequest in olmMachine!!.outgoingRequests()) { when (outgoingRequest) { is Request.KeysUpload -> { - Timber.v("HELLO UPLOADING RUSTY KEYS") - val body = MoshiProvider.providesMoshi().adapter(Map::class.java).fromJson(outgoingRequest.body)!! - val request = UploadKeysTask.Params(body) - - val response = uploadKeysTask.execute(request) - val adapter = MoshiProvider.providesMoshi().adapter(KeysUploadResponse::class.java) - val json_response = adapter.toJson(response)!! - olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_UPLOAD, json_response) - Timber.v("HELLO UPLOADED KEYS $response") + uploadKeys(outgoingRequest) } is Request.KeysQuery -> { - Timber.v("HELLO KEYS QUERY REQUEST ${outgoingRequest.users}") - val params = DownloadKeysForUsersTask.Params(outgoingRequest.users, null) - - try { - val response = downloadKeysForUsersTask.execute(params) - val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) - val json_response = adapter.toJson(response)!! - olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_QUERY, json_response) - } catch (throwable: Throwable) { - Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") - } - - + queryKeys(outgoingRequest) } is Request.ToDevice -> { // Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") From dace959d699a8f04f880b9b276c6a29f2cc3db94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 25 Mar 2021 15:53:18 +0100 Subject: [PATCH 048/252] crypto: Get rid of the roomEncryptorsStore --- .../internal/crypto/DefaultCryptoService.kt | 53 +++++-------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index a04fba6239..e8c750888b 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -59,7 +59,6 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.OlmMachine import org.matrix.android.sdk.internal.setRustLogger import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter -import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting import org.matrix.android.sdk.internal.crypto.algorithms.IMXWithHeldExtension import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXMegolmEncryptionFactory @@ -137,8 +136,6 @@ internal class DefaultCryptoService @Inject constructor( private val myDeviceInfoHolder: Lazy, // the crypto store private val cryptoStore: IMXCryptoStore, - // Room encryptors store - private val roomEncryptorsStore: RoomEncryptorsStore, // Set of parameters used to configure/customize the end-to-end crypto. private val mxCryptoConfig: MXCryptoConfig, // Device list manager @@ -152,14 +149,10 @@ internal class DefaultCryptoService @Inject constructor( private val crossSigningService: DefaultCrossSigningService, // Actions - private val setDeviceVerificationAction: SetDeviceVerificationAction, private val megolmSessionDataImporter: MegolmSessionDataImporter, private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository, - // Repository - private val megolmEncryptionFactory: MXMegolmEncryptionFactory, - private val olmEncryptionFactory: MXOlmEncryptionFactory, - private val deleteDeviceTask: DeleteDeviceTask, // Tasks + private val deleteDeviceTask: DeleteDeviceTask, private val getDevicesTask: GetDevicesTask, private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, private val sendToDeviceTask: SendToDeviceTask, @@ -501,7 +494,7 @@ internal class DefaultCryptoService @Inject constructor( * @param deviceId the unique identifier for the device. */ override fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) { - setDeviceVerificationAction.handle(trustLevel, userId, deviceId) + // TODO } /** @@ -524,21 +517,12 @@ internal class DefaultCryptoService @Inject constructor( return false } - val encryptingClass = MXCryptoAlgorithms.hasEncryptorClassForAlgorithm(algorithm) - - if (!encryptingClass) { + if (algorithm != MXCRYPTO_ALGORITHM_MEGOLM) { Timber.e("## CRYPTO | setEncryptionInRoom() : Unable to encrypt room $roomId with $algorithm") return false } - cryptoStore.storeRoomAlgorithm(roomId, algorithm!!) - - val alg: IMXEncrypting = when (algorithm) { - MXCRYPTO_ALGORITHM_MEGOLM -> megolmEncryptionFactory.create(roomId) - else -> olmEncryptionFactory.create(roomId) - } - - roomEncryptorsStore.put(roomId, alg) + cryptoStore.storeRoomAlgorithm(roomId, algorithm) // if encryption was not previously enabled in this room, we will have been // ignoring new device events for these users so far. We may well have @@ -606,18 +590,10 @@ internal class DefaultCryptoService @Inject constructor( callback: MatrixCallback) { // moved to crypto scope to have uptodate values cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - val userIds = getRoomUserIds(roomId) - var alg = roomEncryptorsStore.get(roomId) - if (alg == null) { - val algorithm = getEncryptionAlgorithm(roomId) - if (algorithm != null) { - if (setEncryptionInRoom(roomId, algorithm, userIds)) { - alg = roomEncryptorsStore.get(roomId) - } - } - } - val safeAlgorithm = alg - if (safeAlgorithm != null) { + val algorithm = getEncryptionAlgorithm(roomId) + + if (algorithm != null) { + val userIds = getRoomUserIds(roomId) val t0 = System.currentTimeMillis() Timber.v("## CRYPTO | encryptEventContent() starts") runCatching { @@ -627,9 +603,7 @@ internal class DefaultCryptoService @Inject constructor( MXEncryptEventContentResult(content, EventType.ENCRYPTED) }.foldToCallback(callback) } else { - val algorithm = getEncryptionAlgorithm(roomId) - val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, - algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON) + val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, MXCryptoError.NO_MORE_ALGORITHM_REASON) Timber.e("## CRYPTO | encryptEventContent() : $reason") callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason))) } @@ -637,9 +611,7 @@ internal class DefaultCryptoService @Inject constructor( } override fun discardOutboundSession(roomId: String) { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - roomEncryptorsStore.get(roomId)?.discardSessionKey() - } + // TODO } /** @@ -706,7 +678,10 @@ internal class DefaultCryptoService @Inject constructor( * @param event the membership event causing the change */ private suspend fun onRoomMembershipEvent(roomId: String, event: Event) { - roomEncryptorsStore.get(roomId) ?: /* No encrypting in this room */ return + // We only care about the memberships if this room is encrypted + if (isRoomEncrypted(roomId)) { + return + } event.stateKey?.let { userId -> val roomMember: RoomMemberContent? = event.content.toModel() From 1bff219197f6c475140c36f2a498b3ff5eece373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 25 Mar 2021 16:07:44 +0100 Subject: [PATCH 049/252] crypto: Remove the event decryptor --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index e8c750888b..e849501915 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -165,7 +165,6 @@ internal class DefaultCryptoService @Inject constructor( private val coroutineDispatchers: MatrixCoroutineDispatchers, private val taskExecutor: TaskExecutor, private val cryptoCoroutineScope: CoroutineScope, - private val eventDecryptor: EventDecryptor ) : CryptoService { private val isStarting = AtomicBoolean(false) @@ -638,7 +637,8 @@ internal class DefaultCryptoService @Inject constructor( * @param callback the callback to return data or null */ override fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback) { - eventDecryptor.decryptEventAsync(event, timeline, callback) + // This isn't really used anywhere, maybe just remove it? + // TODO } /** From 32c1fd9c857574edaf4a450780a1d59816f5afe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 26 Mar 2021 10:58:58 +0100 Subject: [PATCH 050/252] crypto: Remove the OlmManager --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index e849501915..997263c37f 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -108,7 +108,6 @@ import org.matrix.android.sdk.internal.task.TaskThread import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.task.launchToCallback import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import org.matrix.olm.OlmManager import timber.log.Timber import uniffi.olm.Request import uniffi.olm.RequestType @@ -125,8 +124,6 @@ import uniffi.olm.RequestType */ @SessionScope internal class DefaultCryptoService @Inject constructor( - // Olm Manager - private val olmManager: OlmManager, @UserId private val userId: String, @DeviceId @@ -218,7 +215,8 @@ internal class DefaultCryptoService @Inject constructor( } override fun getCryptoVersion(context: Context, longFormat: Boolean): String { - return if (longFormat) olmManager.getDetailedVersion(context) else olmManager.version + // TODO we should provide olm and rust-sdk version from the rust-sdk + return if (longFormat) "Rust SDK 0.3" else "0.3" } override fun getMyDevice(): CryptoDeviceInfo { From d49bdbe016a402b5a263d48229636ae12e913151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 26 Mar 2021 14:02:04 +0100 Subject: [PATCH 051/252] crypto: Remove the RoomDecryptorProvider --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 997263c37f..c9dfa06126 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -139,8 +139,6 @@ internal class DefaultCryptoService @Inject constructor( private val deviceListManager: DeviceListManager, // The key backup service. private val keysBackupService: DefaultKeysBackupService, - // - private val roomDecryptorProvider: RoomDecryptorProvider, // The verification service. private val verificationService: DefaultVerificationService, @@ -1018,11 +1016,12 @@ internal class DefaultCryptoService @Inject constructor( } override fun addNewSessionListener(newSessionListener: NewSessionListener) { - roomDecryptorProvider.addNewSessionListener(newSessionListener) + // TODO we need to notify the listener when we receive a new inbound + // group session } override fun removeSessionListener(listener: NewSessionListener) { - roomDecryptorProvider.removeSessionListener(listener) + // TODO } /* ========================================================================================== * DEBUG INFO From 32cf645c5f02affa240c8d76a846346d27576743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 26 Mar 2021 16:01:01 +0100 Subject: [PATCH 052/252] crypto: Remove the myDeviceInfoHolder --- .../internal/crypto/DefaultCryptoService.kt | 3 +- .../matrix/android/sdk/internal/newCrypto.kt | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index c9dfa06126..4b6d0fde63 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -130,7 +130,6 @@ internal class DefaultCryptoService @Inject constructor( private val deviceId: String?, @SessionFilesDirectory private val dataDir: File, - private val myDeviceInfoHolder: Lazy, // the crypto store private val cryptoStore: IMXCryptoStore, // Set of parameters used to configure/customize the end-to-end crypto. @@ -218,7 +217,7 @@ internal class DefaultCryptoService @Inject constructor( } override fun getMyDevice(): CryptoDeviceInfo { - return myDeviceInfoHolder.get().myDevice + return olmMachine!!.ownDevice() } override fun fetchDevicesList(callback: MatrixCallback) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index c3f123ac6d..ff651d0de0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -27,6 +27,9 @@ 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 import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse +import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo import org.matrix.android.sdk.api.session.events.model.Content import timber.log.Timber import uniffi.olm.Device as InnerDevice @@ -67,6 +70,26 @@ class Device(inner: InnerDevice, machine: InnerMachine) { fun startVerification(): InnerSas { return this.machine.startVerification(this.inner) } + + fun toCryptoDeviceInfo(): CryptoDeviceInfo { + return CryptoDeviceInfo( + this.deviceId(), + this.userId(), + // TODO pass the algorithms here. + listOf(), + this.keys(), + // TODO pass the signatures here. + mapOf(), + // TODO pass the display name here. + UnsignedDeviceInfo(), + // TODO pass trust levels here + DeviceTrustLevel(false, false), + // TODO is the device blacklisted + false, + // TODO + null + ) + } } internal class OlmMachine(user_id: String, device_id: String, path: File) { @@ -84,6 +107,22 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { return this.inner.identityKeys() } + fun ownDevice(): CryptoDeviceInfo { + return CryptoDeviceInfo( + this.deviceId(), + this.userId(), + // TODO pass the algorithms here. + listOf(), + this.identityKeys(), + mapOf(), + UnsignedDeviceInfo(), + DeviceTrustLevel(false, true), + false, + null + ) + + } + suspend fun outgoingRequests(): List = withContext(Dispatchers.IO) { inner.outgoingRequests() } From 7f89e3303739546e441d04ceb2921b7b0df57b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 29 Mar 2021 16:36:40 +0200 Subject: [PATCH 053/252] crypto: Connect the key exporting to the rust-sdk export method --- .../sdk/internal/crypto/DefaultCryptoService.kt | 12 +++--------- .../org/matrix/android/sdk/internal/newCrypto.kt | 6 ++++++ rust-sdk/src/error.rs | 2 ++ rust-sdk/src/machine.rs | 16 ++++++++++++---- rust-sdk/src/olm.udl | 4 ++++ 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 4b6d0fde63..c5df78b3cc 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -835,18 +835,12 @@ internal class DefaultCryptoService @Inject constructor( * Export the crypto keys * * @param password the password - * @param anIterationCount the encryption iteration count (0 means no encryption) + * @param anIterationCount the encryption iteration count */ private suspend fun exportRoomKeys(password: String, anIterationCount: Int): ByteArray { return withContext(coroutineDispatchers.crypto) { - val iterationCount = max(0, anIterationCount) - - val exportedSessions = cryptoStore.getInboundGroupSessions().mapNotNull { it.exportKeys() } - - val adapter = MoshiProvider.providesMoshi() - .adapter(List::class.java) - - MXMegolmExportEncryption.encryptMegolmKeyFile(adapter.toJson(exportedSessions), password, iterationCount) + val iterationCount = max(10000, anIterationCount) + olmMachine!!.exportKeys(password, iterationCount) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index ff651d0de0..a8e536bf76 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -38,6 +38,7 @@ import uniffi.olm.Logger import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.Request import uniffi.olm.RequestType +import uniffi.olm.CryptoStoreErrorException import uniffi.olm.Sas as InnerSas import uniffi.olm.setLogger @@ -179,6 +180,11 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { } } + @Throws(CryptoStoreErrorException::class) + suspend fun exportKeys(passphrase: String, rounds: Int): ByteArray = withContext(Dispatchers.IO) { + inner.exportKeys(passphrase, rounds).toByteArray() + } + @Throws(MXCryptoError::class) suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index d2e4afb5f1..ec2e2c07ac 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -15,6 +15,8 @@ pub enum CryptoStoreError { CryptoStore(#[from] InnerStoreError), #[error(transparent)] OlmError(#[from] OlmError), + #[error(transparent)] + Serialization(#[from] serde_json::Error), } #[derive(Debug, thiserror::Error)] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 3c8a041111..8baebb3db3 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -10,8 +10,7 @@ use tokio::runtime::Runtime; use matrix_sdk_common::{ api::r0::{ keys::{ - claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse}, - get_keys::Response as KeysQueryResponse, + claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, upload_keys::Response as KeysUploadResponse, }, sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, @@ -26,8 +25,8 @@ use matrix_sdk_common::{ }; use matrix_sdk_crypto::{ - EncryptionSettings, IncomingResponse, OlmMachine as InnerMachine, OutgoingRequest, - ToDeviceRequest, + encrypt_key_export, EncryptionSettings, IncomingResponse, OlmMachine as InnerMachine, + OutgoingRequest, ToDeviceRequest, }; use crate::error::{CryptoStoreError, DecryptionError, MachineCreationError}; @@ -420,6 +419,15 @@ impl OlmMachine { serde_json::to_string(&encrypted_content).unwrap() } + pub fn export_keys(&self, passphrase: &str, rounds: i32) -> Result { + let keys = self.runtime.block_on(self.inner.export_keys(|_| true))?; + + let encrypted = encrypt_key_export(&keys, passphrase, rounds as u32) + .map_err(CryptoStoreError::Serialization)?; + + Ok(encrypted) + } + pub fn decrypt_room_event( &self, event: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 36bda6c96f..367de7cec3 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -16,6 +16,7 @@ enum MachineCreationError { enum CryptoStoreError { "CryptoStore", "OlmError", + "Serialization", }; [Error] @@ -102,4 +103,7 @@ interface OlmMachine { [Throws=CryptoStoreError] Sas start_verification([ByRef] Device device); + + [Throws=CryptoStoreError] + string export_keys([ByRef] string passphrase, i32 rounds); }; From 57bb723baca1ebd54694214d484bef3f834c374a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 30 Mar 2021 13:46:35 +0200 Subject: [PATCH 054/252] crypto: Connect the key importing to the rust-sdk --- .../internal/crypto/DefaultCryptoService.kt | 26 +------------- .../matrix/android/sdk/internal/newCrypto.kt | 35 +++++++++++++++---- rust-sdk/src/lib.rs | 8 ++++- rust-sdk/src/machine.rs | 29 +++++++++++++-- rust-sdk/src/olm.udl | 15 ++++++++ 5 files changed, 79 insertions(+), 34 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index c5df78b3cc..a3369c45e8 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -859,31 +859,7 @@ internal class DefaultCryptoService @Inject constructor( cryptoCoroutineScope.launch(coroutineDispatchers.main) { runCatching { withContext(coroutineDispatchers.crypto) { - Timber.v("## CRYPTO | importRoomKeys starts") - - val t0 = System.currentTimeMillis() - val roomKeys = MXMegolmExportEncryption.decryptMegolmKeyFile(roomKeysAsArray, password) - val t1 = System.currentTimeMillis() - - Timber.v("## CRYPTO | importRoomKeys : decryptMegolmKeyFile done in ${t1 - t0} ms") - - val importedSessions = MoshiProvider.providesMoshi() - .adapter>(Types.newParameterizedType(List::class.java, MegolmSessionData::class.java)) - .fromJson(roomKeys) - - val t2 = System.currentTimeMillis() - - Timber.v("## CRYPTO | importRoomKeys : JSON parsing ${t2 - t1} ms") - - if (importedSessions == null) { - throw Exception("Error") - } - - megolmSessionDataImporter.handle( - megolmSessionsData = importedSessions, - fromBackup = false, - progressListener = progressListener - ) + olmMachine!!.importKeys(roomKeysAsArray, password, progressListener) } }.foldToCallback(callback) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index a8e536bf76..76f47ecc4f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -19,26 +19,29 @@ package org.matrix.android.sdk.internal import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +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.util.JsonDict import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult +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.rest.UnsignedDeviceInfo 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 import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo -import org.matrix.android.sdk.api.session.events.model.Content import timber.log.Timber +import uniffi.olm.CryptoStoreErrorException import uniffi.olm.Device as InnerDevice import uniffi.olm.DeviceLists import uniffi.olm.Logger import uniffi.olm.OlmMachine as InnerMachine +import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType -import uniffi.olm.CryptoStoreErrorException import uniffi.olm.Sas as InnerSas import uniffi.olm.setLogger @@ -48,6 +51,16 @@ class CryptoLogger() : Logger { } } +private class CryptoProgressListener(listener: ProgressListener?) : RustProgressListener { + private val inner: ProgressListener? = listener + + override fun onProgress(progress: Int, total: Int) { + if (this.inner != null) { + this.inner.onProgress(progress, total) + } + } +} + fun setRustLogger() { setLogger(CryptoLogger() as Logger) } @@ -121,7 +134,6 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { false, null ) - } suspend fun outgoingRequests(): List = withContext(Dispatchers.IO) { @@ -185,6 +197,17 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.exportKeys(passphrase, rounds).toByteArray() } + @Throws(CryptoStoreErrorException::class) + suspend fun importKeys(keys: ByteArray, passphrase: String, listener: ProgressListener?): ImportRoomKeysResult = withContext(Dispatchers.IO) { + var decodedKeys = keys.toString() + + var rustListener = CryptoProgressListener(listener) + + var result = inner.importKeys(decodedKeys, passphrase, rustListener) + + ImportRoomKeysResult(result.total, result.imported) + } + @Throws(MXCryptoError::class) suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 9ca691778e..2f22012c78 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -4,6 +4,12 @@ mod machine; pub use error::{CryptoStoreError, DecryptionError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{DecryptedEvent, Device, DeviceLists, OlmMachine, Request, RequestType, Sas}; +pub use machine::{ + DecryptedEvent, Device, DeviceLists, KeysImportResult, OlmMachine, Request, RequestType, Sas, +}; + +pub trait ProgressListener { + fn on_progress(&self, progress: i32, total: i32); +} include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 8baebb3db3..d7dc13ca1f 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -1,6 +1,7 @@ use std::{ collections::{BTreeMap, HashMap}, convert::{TryFrom, TryInto}, + io::Cursor, }; use http::Response; @@ -25,11 +26,12 @@ use matrix_sdk_common::{ }; use matrix_sdk_crypto::{ - encrypt_key_export, EncryptionSettings, IncomingResponse, OlmMachine as InnerMachine, - OutgoingRequest, ToDeviceRequest, + decrypt_key_export, encrypt_key_export, EncryptionSettings, IncomingResponse, + OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, }; use crate::error::{CryptoStoreError, DecryptionError, MachineCreationError}; +use crate::ProgressListener; pub struct OlmMachine { inner: InnerMachine, @@ -65,6 +67,11 @@ impl Into for DeviceLists { } } +pub struct KeysImportResult { + pub total: i32, + pub imported: i32, +} + enum OwnedResponse { KeysClaim(KeysClaimResponse), KeysUpload(KeysUploadResponse), @@ -428,6 +435,24 @@ impl OlmMachine { Ok(encrypted) } + pub fn import_keys( + &self, + keys: &str, + passphrase: &str, + _: Box, + ) -> Result { + let keys = Cursor::new(keys); + let keys = decrypt_key_export(keys, passphrase).unwrap(); + + // TODO use the progress listener + let result = self.runtime.block_on(self.inner.import_keys(keys))?; + + Ok(KeysImportResult { + total: result.1 as i32, + imported: result.0 as i32, + }) + } + pub fn decrypt_room_event( &self, event: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 367de7cec3..7c61cdfb60 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -6,6 +6,10 @@ callback interface Logger { void log(string log_line); }; +callback interface ProgressListener { + void on_progress(i32 progress, i32 total); +}; + [Error] enum MachineCreationError { "Identifier", @@ -31,6 +35,11 @@ dictionary DeviceLists { sequence left; }; +dictionary KeysImportResult { + i32 total; + i32 imported; +}; + dictionary DecryptedEvent { string clear_event; string sender_curve25519_key; @@ -106,4 +115,10 @@ interface OlmMachine { [Throws=CryptoStoreError] string export_keys([ByRef] string passphrase, i32 rounds); + [Throws=CryptoStoreError] + KeysImportResult import_keys( + [ByRef] string keys, + [ByRef] string passphrase, + ProgressListener progress_listener + ); }; From 5533c2acae4777ba6b33fa6f61e16b8f14f5eecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 30 Mar 2021 13:46:58 +0200 Subject: [PATCH 055/252] crypto: Remove more unused code --- .../sdk/api/session/crypto/CryptoService.kt | 2 -- .../internal/crypto/DefaultCryptoService.kt | 26 ------------------- 2 files changed, 28 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 49c27625f8..a9578838d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -70,8 +70,6 @@ interface CryptoService { fun setDevicesKnown(devices: List, callback: MatrixCallback?) - fun deviceWithIdentityKey(senderKey: String, algorithm: String): CryptoDeviceInfo? - fun getMyDevice(): CryptoDeviceInfo fun getGlobalBlacklistUnverifiedDevices(): Boolean diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index a3369c45e8..990474e262 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -42,10 +42,6 @@ import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError -import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME -import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME -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.session.crypto.keyshare.GossipingRequestListener import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event @@ -59,10 +55,6 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.OlmMachine import org.matrix.android.sdk.internal.setRustLogger import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter -import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting -import org.matrix.android.sdk.internal.crypto.algorithms.IMXWithHeldExtension -import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXMegolmEncryptionFactory -import org.matrix.android.sdk.internal.crypto.algorithms.olm.MXOlmEncryptionFactory import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService @@ -71,16 +63,12 @@ import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent -import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask @@ -399,20 +387,6 @@ internal class DefaultCryptoService @Inject constructor( } } - /** - * Find a device by curve25519 identity key - * - * @param senderKey the curve25519 key to match. - * @param algorithm the encryption algorithm. - * @return the device info, or null if not found / unsupported algorithm / crypto released - */ - override fun deviceWithIdentityKey(senderKey: String, algorithm: String): CryptoDeviceInfo? { - return if (algorithm != MXCRYPTO_ALGORITHM_MEGOLM && algorithm != MXCRYPTO_ALGORITHM_OLM) { - // We only deal in olm keys - null - } else cryptoStore.deviceWithIdentityKey(senderKey) - } - /** * Provides the device information for a user id and a device Id * From 9d5ef01ce0eef666523e5593d2db6b09b2bfc97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 30 Mar 2021 13:47:15 +0200 Subject: [PATCH 056/252] crypto: Get devices from the rust-sdk --- .../sdk/internal/crypto/DefaultCryptoService.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 990474e262..4de42be3a4 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -395,7 +395,15 @@ internal class DefaultCryptoService @Inject constructor( */ override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) { - cryptoStore.getUserDevice(userId, deviceId) + val device = runBlocking { + olmMachine!!.getDevice(userId, deviceId) + } + + if (device != null) { + device.toCryptoDeviceInfo() + } else { + null + } } else { null } From 6af8041fb44aa6cfbb9ae765a61c88b6854c3315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 30 Mar 2021 13:47:30 +0200 Subject: [PATCH 057/252] crypto: Remove the second key export method --- .../sdk/internal/crypto/DefaultCryptoService.kt | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 4de42be3a4..e14f6f4e0b 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -808,24 +808,12 @@ internal class DefaultCryptoService @Inject constructor( override fun exportRoomKeys(password: String, callback: MatrixCallback) { cryptoCoroutineScope.launch(coroutineDispatchers.main) { runCatching { - exportRoomKeys(password, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT) + val iterationCount = max(10000, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT) + olmMachine!!.exportKeys(password, iterationCount) }.foldToCallback(callback) } } - /** - * Export the crypto keys - * - * @param password the password - * @param anIterationCount the encryption iteration count - */ - private suspend fun exportRoomKeys(password: String, anIterationCount: Int): ByteArray { - return withContext(coroutineDispatchers.crypto) { - val iterationCount = max(10000, anIterationCount) - olmMachine!!.exportKeys(password, iterationCount) - } - } - /** * Import the room keys * From 10c7f5b989817746b1287dce520bffa0d96e18c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 30 Mar 2021 14:28:53 +0200 Subject: [PATCH 058/252] crypto: Handle key export decyrption errors --- rust-sdk/src/error.rs | 12 +++++++++++- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 10 ++++++---- rust-sdk/src/olm.udl | 8 +++++++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index ec2e2c07ac..8e66539131 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -1,5 +1,7 @@ use matrix_sdk_common::identifiers::Error as RumaIdentifierError; -use matrix_sdk_crypto::{store::CryptoStoreError as InnerStoreError, MegolmError, OlmError}; +use matrix_sdk_crypto::{ + store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError, +}; #[derive(Debug, thiserror::Error)] pub enum MachineCreationError { @@ -9,6 +11,14 @@ pub enum MachineCreationError { CryptoStore(#[from] InnerStoreError), } +#[derive(Debug, thiserror::Error)] +pub enum KeyImportError { + #[error(transparent)] + Export(#[from] KeyExportError), + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), +} + #[derive(Debug, thiserror::Error)] pub enum CryptoStoreError { #[error(transparent)] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 2f22012c78..e6799e9801 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -2,7 +2,7 @@ mod error; mod logger; mod machine; -pub use error::{CryptoStoreError, DecryptionError, MachineCreationError}; +pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; pub use machine::{ DecryptedEvent, Device, DeviceLists, KeysImportResult, OlmMachine, Request, RequestType, Sas, diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index d7dc13ca1f..1ef9a30379 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -30,8 +30,10 @@ use matrix_sdk_crypto::{ OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, }; -use crate::error::{CryptoStoreError, DecryptionError, MachineCreationError}; -use crate::ProgressListener; +use crate::{ + error::{CryptoStoreError, DecryptionError, MachineCreationError}, + KeyImportError, ProgressListener, +}; pub struct OlmMachine { inner: InnerMachine, @@ -440,9 +442,9 @@ impl OlmMachine { keys: &str, passphrase: &str, _: Box, - ) -> Result { + ) -> Result { let keys = Cursor::new(keys); - let keys = decrypt_key_export(keys, passphrase).unwrap(); + let keys = decrypt_key_export(keys, passphrase)?; // TODO use the progress listener let result = self.runtime.block_on(self.inner.import_keys(keys))?; diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 7c61cdfb60..1d32503e15 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -16,6 +16,12 @@ enum MachineCreationError { "CryptoStore", }; +[Error] +enum KeyImportError { + "Export", + "CryptoStore", +}; + [Error] enum CryptoStoreError { "CryptoStore", @@ -115,7 +121,7 @@ interface OlmMachine { [Throws=CryptoStoreError] string export_keys([ByRef] string passphrase, i32 rounds); - [Throws=CryptoStoreError] + [Throws=KeyImportError] KeysImportResult import_keys( [ByRef] string keys, [ByRef] string passphrase, From dc8711be30f69847ad90146ffb4c244b0a144f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 31 Mar 2021 11:38:15 +0200 Subject: [PATCH 059/252] crypto: Add some TODOs about locking --- .../matrix/android/sdk/internal/crypto/DefaultCryptoService.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index e14f6f4e0b..e60e2a7a0d 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -694,6 +694,7 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun preshareGroupSession(roomId: String, roomMembers: List) { + // TODO this needs to be locked per room val request = olmMachine!!.getMissingSessions(roomMembers) if (request != null) { @@ -772,6 +773,7 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun claimKeys(request: Request.KeysClaim) { + // TODO this needs to be locked per call val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) val adapter = MoshiProvider @@ -783,6 +785,7 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun sendOutgoingRequests() { + // TODO this needs to be locked per call // TODO these requests should be sent out in parallel for (outgoingRequest in olmMachine!!.outgoingRequests()) { when (outgoingRequest) { From ef93d9e6254da36a1600970130ba2a865b18aa92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 1 Apr 2021 15:59:36 +0200 Subject: [PATCH 060/252] crypto: Remove some more unused methods --- .../sdk/api/session/crypto/CryptoService.kt | 4 -- .../internal/crypto/DefaultCryptoService.kt | 41 ------------------- 2 files changed, 45 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index a9578838d6..c8c6b618b4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -68,8 +68,6 @@ interface CryptoService { fun getUserDevices(userId: String): MutableList - fun setDevicesKnown(devices: List, callback: MatrixCallback?) - fun getMyDevice(): CryptoDeviceInfo fun getGlobalBlacklistUnverifiedDevices(): Boolean @@ -126,8 +124,6 @@ interface CryptoService { fun getCryptoDeviceInfo(userId: String): List - fun getLiveCryptoDeviceInfo(): LiveData> - fun getLiveCryptoDeviceInfo(userId: String): LiveData> fun getLiveCryptoDeviceInfo(userIds: List): LiveData> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index e60e2a7a0d..7af7451901 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -413,10 +413,6 @@ internal class DefaultCryptoService @Inject constructor( return cryptoStore.getUserDeviceList(userId).orEmpty() } - override fun getLiveCryptoDeviceInfo(): LiveData> { - return cryptoStore.getLiveDeviceList() - } - override fun getLiveCryptoDeviceInfo(userId: String): LiveData> { return cryptoStore.getLiveDeviceList(userId) } @@ -425,43 +421,6 @@ internal class DefaultCryptoService @Inject constructor( return cryptoStore.getLiveDeviceList(userIds) } - /** - * Set the devices as known - * - * @param devices the devices. Note that the verified member of the devices in this list will not be updated by this method. - * @param callback the asynchronous callback - */ - override fun setDevicesKnown(devices: List, callback: MatrixCallback?) { - // build a devices map - val devicesIdListByUserId = devices.groupBy({ it.userId }, { it.deviceId }) - - for ((userId, deviceIds) in devicesIdListByUserId) { - val storedDeviceIDs = cryptoStore.getUserDevices(userId) - - // sanity checks - if (null != storedDeviceIDs) { - var isUpdated = false - - deviceIds.forEach { deviceId -> - val device = storedDeviceIDs[deviceId] - - // assume if the device is either verified or blocked - // it means that the device is known - if (device?.isUnknown == true) { - device.trustLevel = DeviceTrustLevel(crossSigningVerified = false, locallyVerified = false) - isUpdated = true - } - } - - if (isUpdated) { - cryptoStore.storeUserDevices(userId, storedDeviceIDs) - } - } - } - - callback?.onSuccess(Unit) - } - /** * Update the blocked/verified state of the given device. * From 0b064f647ae481b70c99a15e36484cf98cb44b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 1 Apr 2021 17:44:41 +0200 Subject: [PATCH 061/252] crypto: Connect the live CryptoDeviceInfo getter methods to the rust-sdk --- .../internal/crypto/DefaultCryptoService.kt | 10 ++- .../matrix/android/sdk/internal/newCrypto.kt | 65 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 7af7451901..894eb04a11 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -410,15 +410,19 @@ internal class DefaultCryptoService @Inject constructor( } override fun getCryptoDeviceInfo(userId: String): List { - return cryptoStore.getUserDeviceList(userId).orEmpty() + return runBlocking { + olmMachine!!.getUserDevices(userId) + } } override fun getLiveCryptoDeviceInfo(userId: String): LiveData> { - return cryptoStore.getLiveDeviceList(userId) + return getLiveCryptoDeviceInfo(listOf(userId)) } override fun getLiveCryptoDeviceInfo(userIds: List): LiveData> { - return cryptoStore.getLiveDeviceList(userIds) + return runBlocking { + olmMachine!!.getLiveDevices(userIds) + } } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 76f47ecc4f..973b8977d5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.LiveData import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -61,6 +63,26 @@ private class CryptoProgressListener(listener: ProgressListener?) : RustProgress } } +internal class LiveDevice( + userIds: List, + machine: OlmMachine +) : MutableLiveData>() { + var userIds: List = userIds + private var machine: OlmMachine = machine + + private val listener = { devices: List -> + value = devices + } + + override fun onActive() { + machine.addDeviceUpdateListener(this) + } + + override fun onInactive() { + machine.removeDeviceUpdateListener(this) + } +} + fun setRustLogger() { setLogger(CryptoLogger() as Logger) } @@ -108,6 +130,7 @@ class Device(inner: InnerDevice, machine: InnerMachine) { internal class OlmMachine(user_id: String, device_id: String, path: File) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) + private val deviceUpdateListeners = HashMap>() fun userId(): String { return this.inner.userId() @@ -136,6 +159,21 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { ) } + fun addDeviceUpdateListener(device: LiveDevice) { + deviceUpdateListeners.set(device, device.userIds) + } + + fun removeDeviceUpdateListener(device: LiveDevice) { + deviceUpdateListeners.remove(device) + } + + suspend fun updateLiveDevices() { + for ((liveDevice, users) in deviceUpdateListeners) { + val devices = getUserDevices(users) + liveDevice.postValue(devices) + } + } + suspend fun outgoingRequests(): List = withContext(Dispatchers.IO) { inner.outgoingRequests() } @@ -183,6 +221,10 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { response_body: String ) = withContext(Dispatchers.IO) { inner.markRequestAsSent(request_id, request_type, response_body) + + if (request_type == RequestType.KEYS_QUERY) { + updateLiveDevices() + } } suspend fun getDevice(user_id: String, device_id: String): Device? = withContext(Dispatchers.IO) { @@ -192,6 +234,29 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { } } + suspend fun getUserDevices(userId: String): List { + return inner.getUserDevices(userId).map { Device(it, inner).toCryptoDeviceInfo() } + } + + suspend fun getUserDevices(userIds: List): List { + val plainDevices: ArrayList = arrayListOf() + + for (user in userIds) { + val devices = getUserDevices(user) + plainDevices.addAll(devices) + } + + return plainDevices + } + + suspend fun getLiveDevices(userIds: List): LiveData> { + val plainDevices = getUserDevices(userIds) + val devices = LiveDevice(userIds, this) + devices.setValue(plainDevices) + + return devices + } + @Throws(CryptoStoreErrorException::class) suspend fun exportKeys(passphrase: String, rounds: Int): ByteArray = withContext(Dispatchers.IO) { inner.exportKeys(passphrase, rounds).toByteArray() From 182fc84186c69d9a194c5502e0574c4a2264a087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 2 Apr 2021 15:30:07 +0200 Subject: [PATCH 062/252] crypto: Split out the live devices observer --- .../matrix/android/sdk/internal/newCrypto.kt | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 973b8977d5..86d57d9a31 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -65,21 +65,21 @@ private class CryptoProgressListener(listener: ProgressListener?) : RustProgress internal class LiveDevice( userIds: List, - machine: OlmMachine + observer: DeviceUpdateObserver ) : MutableLiveData>() { var userIds: List = userIds - private var machine: OlmMachine = machine + private var observer: DeviceUpdateObserver = observer private val listener = { devices: List -> value = devices } override fun onActive() { - machine.addDeviceUpdateListener(this) + observer.addDeviceUpdateListener(this) } override fun onInactive() { - machine.removeDeviceUpdateListener(this) + observer.removeDeviceUpdateListener(this) } } @@ -128,9 +128,21 @@ class Device(inner: InnerDevice, machine: InnerMachine) { } } +internal class DeviceUpdateObserver() { + internal val listeners = HashMap>() + + fun addDeviceUpdateListener(device: LiveDevice) { + listeners.set(device, device.userIds) + } + + fun removeDeviceUpdateListener(device: LiveDevice) { + listeners.remove(device) + } +} + internal class OlmMachine(user_id: String, device_id: String, path: File) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) - private val deviceUpdateListeners = HashMap>() + private val deviceUpdateObserver = DeviceUpdateObserver() fun userId(): String { return this.inner.userId() @@ -159,16 +171,8 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { ) } - fun addDeviceUpdateListener(device: LiveDevice) { - deviceUpdateListeners.set(device, device.userIds) - } - - fun removeDeviceUpdateListener(device: LiveDevice) { - deviceUpdateListeners.remove(device) - } - suspend fun updateLiveDevices() { - for ((liveDevice, users) in deviceUpdateListeners) { + for ((liveDevice, users) in deviceUpdateObserver.listeners) { val devices = getUserDevices(users) liveDevice.postValue(devices) } @@ -251,7 +255,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { suspend fun getLiveDevices(userIds: List): LiveData> { val plainDevices = getUserDevices(userIds) - val devices = LiveDevice(userIds, this) + val devices = LiveDevice(userIds, deviceUpdateObserver) devices.setValue(plainDevices) return devices From 336697a38cf1141c67a313ef4c0d3b124381a143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 6 Apr 2021 15:36:21 +0200 Subject: [PATCH 063/252] crypto: Some refactoring on the rust side --- rust-sdk/src/lib.rs | 20 +++- rust-sdk/src/machine.rs | 206 ++++---------------------------------- rust-sdk/src/responses.rs | 179 +++++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+), 187 deletions(-) create mode 100644 rust-sdk/src/responses.rs diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index e6799e9801..44f8daaf64 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,15 +1,29 @@ mod error; mod logger; mod machine; +mod responses; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{ - DecryptedEvent, Device, DeviceLists, KeysImportResult, OlmMachine, Request, RequestType, Sas, -}; +pub use machine::{Device, OlmMachine, Sas}; +pub use responses::{DeviceLists, KeysImportResult, Request, RequestType}; pub trait ProgressListener { fn on_progress(&self, progress: i32, total: i32); } +/// An event that was successfully decrypted. +pub struct DecryptedEvent { + /// The decrypted version of the event. + pub clear_event: String, + /// The claimed curve25519 key of the sender. + pub sender_curve25519_key: String, + /// The claimed ed25519 key of the sender. + pub claimed_ed25519_key: Option, + /// The curve25519 chain of the senders that forwarded the Megolm decryption + /// key to us. Is empty if the key came directly from the sender of the + /// event. + pub forwarding_curve25519_chain: Vec, +} + include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 1ef9a30379..27bc93634b 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -4,7 +4,6 @@ use std::{ io::Cursor, }; -use http::Response; use serde_json::{json, value::RawValue}; use tokio::runtime::Runtime; @@ -17,7 +16,6 @@ use matrix_sdk_common::{ sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, to_device::send_event_to_device::Response as ToDeviceResponse, }, - assign, deserialized_responses::events::{AlgorithmInfo, SyncMessageEvent}, events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent}, identifiers::{DeviceKeyAlgorithm, RoomId, UserId}, @@ -26,109 +24,43 @@ use matrix_sdk_common::{ }; use matrix_sdk_crypto::{ - decrypt_key_export, encrypt_key_export, EncryptionSettings, IncomingResponse, - OlmMachine as InnerMachine, OutgoingRequest, ToDeviceRequest, + decrypt_key_export, encrypt_key_export, Device as InnerDevice, EncryptionSettings, + OlmMachine as InnerMachine, }; use crate::{ error::{CryptoStoreError, DecryptionError, MachineCreationError}, - KeyImportError, ProgressListener, + responses::{response_from_string, OwnedResponse}, + DecryptedEvent, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, Request, + RequestType, }; +/// A high level state machine that handles E2EE for Matrix. pub struct OlmMachine { inner: InnerMachine, runtime: Runtime, } -pub struct DecryptedEvent { - pub clear_event: String, - pub sender_curve25519_key: String, - pub claimed_ed25519_key: Option, - pub forwarding_curve25519_chain: Vec, -} - -pub struct DeviceLists { - pub changed: Vec, - pub left: Vec, -} - -impl Into for DeviceLists { - fn into(self) -> RumaDeviceLists { - assign!(RumaDeviceLists::new(), { - changed: self - .changed - .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) - .collect(), - left: self - .left - .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) - .collect(), - }) - } -} - -pub struct KeysImportResult { - pub total: i32, - pub imported: i32, -} - -enum OwnedResponse { - KeysClaim(KeysClaimResponse), - KeysUpload(KeysUploadResponse), - KeysQuery(KeysQueryResponse), - ToDevice(ToDeviceResponse), -} - -impl From for OwnedResponse { - fn from(response: KeysClaimResponse) -> Self { - OwnedResponse::KeysClaim(response) - } -} - -impl From for OwnedResponse { - fn from(response: KeysQueryResponse) -> Self { - OwnedResponse::KeysQuery(response) - } -} - -impl From for OwnedResponse { - fn from(response: KeysUploadResponse) -> Self { - OwnedResponse::KeysUpload(response) - } -} - -impl From for OwnedResponse { - fn from(response: ToDeviceResponse) -> Self { - OwnedResponse::ToDevice(response) - } -} - -impl<'a> Into> for &'a OwnedResponse { - fn into(self) -> IncomingResponse<'a> { - match self { - OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), - OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), - OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), - OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r), - } - } -} - -pub enum RequestType { - KeysQuery, - KeysClaim, - KeysUpload, - ToDevice, -} - pub struct Device { pub user_id: String, pub device_id: String, pub keys: HashMap, } +impl From for Device { + fn from(d: InnerDevice) -> Self { + Device { + user_id: d.user_id().to_string(), + device_id: d.device_id().to_string(), + keys: d + .keys() + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + } + } +} + pub struct Sas { pub other_user_id: String, pub other_device_id: String, @@ -136,84 +68,6 @@ pub struct Sas { pub request: Request, } -pub enum Request { - ToDevice { - request_id: String, - event_type: String, - body: String, - }, - KeysUpload { - request_id: String, - body: String, - }, - KeysQuery { - request_id: String, - users: Vec, - }, - KeysClaim { - request_id: String, - one_time_keys: HashMap>, - }, -} - -impl From for Request { - fn from(r: OutgoingRequest) -> Self { - use matrix_sdk_crypto::OutgoingRequests::*; - - match r.request() { - KeysUpload(u) => { - let body = json!({ - "device_keys": u.device_keys, - "one_time_keys": u.one_time_keys, - }); - - Request::KeysUpload { - request_id: r.request_id().to_string(), - body: serde_json::to_string(&body) - .expect("Can't serialize keys upload request"), - } - } - KeysQuery(k) => { - let users: Vec = k.device_keys.keys().map(|u| u.to_string()).collect(); - Request::KeysQuery { - request_id: r.request_id().to_string(), - users, - } - } - ToDeviceRequest(t) => Request::from(t), - SignatureUpload(_) => todo!(), - RoomMessage(_) => todo!(), - } - } -} - -impl From for Request { - fn from(r: ToDeviceRequest) -> Self { - Request::ToDevice { - request_id: r.txn_id_string(), - event_type: r.event_type.to_string(), - body: serde_json::to_string(&r.messages).unwrap(), - } - } -} - -impl From<&ToDeviceRequest> for Request { - fn from(r: &ToDeviceRequest) -> Self { - Request::ToDevice { - request_id: r.txn_id_string(), - event_type: r.event_type.to_string(), - body: serde_json::to_string(&r.messages).unwrap(), - } - } -} - -fn response_from_string(body: &str) -> Response> { - Response::builder() - .status(200) - .body(body.as_bytes().to_vec()) - .expect("Can't create HTTP response") -} - impl OlmMachine { pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { let user_id = UserId::try_from(user_id)?; @@ -242,15 +96,7 @@ impl OlmMachine { self.runtime .block_on(self.inner.get_device(&user_id, device_id.into())) .unwrap() - .map(|d| Device { - user_id: d.user_id().to_string(), - device_id: d.device_id().to_string(), - keys: d - .keys() - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - }) + .map(|d| d.into()) } pub fn get_user_devices(&self, user_id: &str) -> Vec { @@ -259,15 +105,7 @@ impl OlmMachine { .block_on(self.inner.get_user_devices(&user_id)) .unwrap() .devices() - .map(|d| Device { - user_id: d.user_id().to_string(), - device_id: d.device_id().to_string(), - keys: d - .keys() - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - }) + .map(|d| d.into()) .collect() } diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs new file mode 100644 index 0000000000..4861920598 --- /dev/null +++ b/rust-sdk/src/responses.rs @@ -0,0 +1,179 @@ +use std::{ + collections::HashMap, + convert::TryFrom, +}; + +use http::Response; +use serde_json::json; + +use matrix_sdk_common::{ + api::r0::{ + keys::{ + claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, + upload_keys::Response as KeysUploadResponse, + }, + sync::sync_events::DeviceLists as RumaDeviceLists, + to_device::send_event_to_device::Response as ToDeviceResponse, + }, + assign, + identifiers::UserId, +}; + +use matrix_sdk_crypto::{ + IncomingResponse, OutgoingRequest, ToDeviceRequest, +}; + +pub enum Request { + ToDevice { + request_id: String, + event_type: String, + body: String, + }, + KeysUpload { + request_id: String, + body: String, + }, + KeysQuery { + request_id: String, + users: Vec, + }, + KeysClaim { + request_id: String, + one_time_keys: HashMap>, + }, +} + +impl From for Request { + fn from(r: OutgoingRequest) -> Self { + use matrix_sdk_crypto::OutgoingRequests::*; + + match r.request() { + KeysUpload(u) => { + let body = json!({ + "device_keys": u.device_keys, + "one_time_keys": u.one_time_keys, + }); + + Request::KeysUpload { + request_id: r.request_id().to_string(), + body: serde_json::to_string(&body) + .expect("Can't serialize keys upload request"), + } + } + KeysQuery(k) => { + let users: Vec = k.device_keys.keys().map(|u| u.to_string()).collect(); + Request::KeysQuery { + request_id: r.request_id().to_string(), + users, + } + } + ToDeviceRequest(t) => Request::from(t), + SignatureUpload(_) => todo!(), + RoomMessage(_) => todo!(), + } + } +} + +impl From for Request { + fn from(r: ToDeviceRequest) -> Self { + Request::ToDevice { + request_id: r.txn_id_string(), + event_type: r.event_type.to_string(), + body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +impl From<&ToDeviceRequest> for Request { + fn from(r: &ToDeviceRequest) -> Self { + Request::ToDevice { + request_id: r.txn_id_string(), + event_type: r.event_type.to_string(), + body: serde_json::to_string(&r.messages).unwrap(), + } + } +} + +pub(crate) fn response_from_string(body: &str) -> Response> { + Response::builder() + .status(200) + .body(body.as_bytes().to_vec()) + .expect("Can't create HTTP response") +} + + +pub enum RequestType { + KeysQuery, + KeysClaim, + KeysUpload, + ToDevice, +} + +pub struct DeviceLists { + pub changed: Vec, + pub left: Vec, +} + +impl Into for DeviceLists { + fn into(self) -> RumaDeviceLists { + assign!(RumaDeviceLists::new(), { + changed: self + .changed + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(), + left: self + .left + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(), + }) + } +} + +pub struct KeysImportResult { + pub total: i32, + pub imported: i32, +} + +pub(crate) enum OwnedResponse { + KeysClaim(KeysClaimResponse), + KeysUpload(KeysUploadResponse), + KeysQuery(KeysQueryResponse), + ToDevice(ToDeviceResponse), +} + +impl From for OwnedResponse { + fn from(response: KeysClaimResponse) -> Self { + OwnedResponse::KeysClaim(response) + } +} + +impl From for OwnedResponse { + fn from(response: KeysQueryResponse) -> Self { + OwnedResponse::KeysQuery(response) + } +} + +impl From for OwnedResponse { + fn from(response: KeysUploadResponse) -> Self { + OwnedResponse::KeysUpload(response) + } +} + +impl From for OwnedResponse { + fn from(response: ToDeviceResponse) -> Self { + OwnedResponse::ToDevice(response) + } +} + +impl<'a> Into> for &'a OwnedResponse { + fn into(self) -> IncomingResponse<'a> { + match self { + OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), + OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), + OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), + OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r), + } + } +} From 533895cb3867941c11754666953874913be74ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 7 Apr 2021 15:04:22 +0200 Subject: [PATCH 064/252] crypto: Document the Rust side of things --- rust-sdk/src/device.rs | 23 +++ rust-sdk/src/lib.rs | 4 +- rust-sdk/src/machine.rs | 329 +++++++++++++++++++++++++++----------- rust-sdk/src/responses.rs | 10 +- 4 files changed, 261 insertions(+), 105 deletions(-) create mode 100644 rust-sdk/src/device.rs diff --git a/rust-sdk/src/device.rs b/rust-sdk/src/device.rs new file mode 100644 index 0000000000..2e3a0a78e1 --- /dev/null +++ b/rust-sdk/src/device.rs @@ -0,0 +1,23 @@ +use std::collections::HashMap; + +use matrix_sdk_crypto::Device as InnerDevice; + +pub struct Device { + pub user_id: String, + pub device_id: String, + pub keys: HashMap, +} + +impl From for Device { + fn from(d: InnerDevice) -> Self { + Device { + user_id: d.user_id().to_string(), + device_id: d.device_id().to_string(), + keys: d + .keys() + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + } + } +} diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 44f8daaf64..998182d793 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,11 +1,13 @@ +mod device; mod error; mod logger; mod machine; mod responses; +pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{Device, OlmMachine, Sas}; +pub use machine::{OlmMachine, Sas}; pub use responses::{DeviceLists, KeysImportResult, Request, RequestType}; pub trait ProgressListener { diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 27bc93634b..f6626c2929 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -24,15 +24,14 @@ use matrix_sdk_common::{ }; use matrix_sdk_crypto::{ - decrypt_key_export, encrypt_key_export, Device as InnerDevice, EncryptionSettings, - OlmMachine as InnerMachine, + decrypt_key_export, encrypt_key_export, EncryptionSettings, OlmMachine as InnerMachine, }; use crate::{ error::{CryptoStoreError, DecryptionError, MachineCreationError}, responses::{response_from_string, OwnedResponse}, - DecryptedEvent, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, Request, - RequestType, + DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, + Request, RequestType, }; /// A high level state machine that handles E2EE for Matrix. @@ -41,26 +40,6 @@ pub struct OlmMachine { runtime: Runtime, } -pub struct Device { - pub user_id: String, - pub device_id: String, - pub keys: HashMap, -} - -impl From for Device { - fn from(d: InnerDevice) -> Self { - Device { - user_id: d.user_id().to_string(), - device_id: d.device_id().to_string(), - keys: d - .keys() - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - } - } -} - pub struct Sas { pub other_user_id: String, pub other_device_id: String, @@ -69,6 +48,15 @@ pub struct Sas { } impl OlmMachine { + /// Create a new `OlmMachine` + /// + /// # Arguments + /// + /// * `user_id` - The unique ID of the user that owns this machine. + /// + /// * `device_id` - The unique ID of the device that owns this machine. + /// + /// * `path` - The path where the state of the machine should be persisted. pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { let user_id = UserId::try_from(user_id)?; let device_id = device_id.into(); @@ -82,14 +70,23 @@ impl OlmMachine { }) } + /// Get the user ID of the owner of this `OlmMachine`. pub fn user_id(&self) -> String { self.inner.user_id().to_string() } + /// Get the device ID of the device of this `OlmMachine`. pub fn device_id(&self) -> String { self.inner.device_id().to_string() } + /// Get a `Device` from the store. + /// + /// # Arguments + /// + /// * `user_id` - The id of the device owner. + /// + /// * `device_id` - The id of the device itsefl. pub fn get_device(&self, user_id: &str, device_id: &str) -> Option { let user_id = UserId::try_from(user_id).unwrap(); @@ -99,6 +96,11 @@ impl OlmMachine { .map(|d| d.into()) } + /// Get all devices of an user. + /// + /// # Arguments + /// + /// * `user_id` - The id of the device owner. pub fn get_user_devices(&self, user_id: &str) -> Vec { let user_id = UserId::try_from(user_id).unwrap(); self.runtime @@ -109,6 +111,7 @@ impl OlmMachine { .collect() } + /// Get our own identity keys. pub fn identity_keys(&self) -> HashMap { self.inner .identity_keys() @@ -117,6 +120,32 @@ impl OlmMachine { .collect() } + /// Get the list of outgoing requests that need to be sent to the + /// homeserver. + /// + /// After the request was sent out and a successful response was received + /// the response body should be passed back to the state machine using the + /// [mark_request_as_sent()](#method.mark_request_as_sent) method. + /// + /// **Note**: This method call should be locked per call. + pub fn outgoing_requests(&self) -> Vec { + self.runtime + .block_on(self.inner.outgoing_requests()) + .into_iter() + .map(|r| r.into()) + .collect() + } + + /// Mark a request that was sent to the server as sent. + /// + /// # Arguments + /// + /// * `request_id` - The unique ID of the request that was sent out. This + /// needs to be an UUID. + /// + /// * `request_type` - The type of the request that was sent out. + /// + /// * `response_body` - The body of the response that was received. pub fn mark_request_as_sent( &self, request_id: &str, @@ -141,32 +170,21 @@ impl OlmMachine { Ok(()) } - pub fn start_verification(&self, device: &Device) -> Result { - let user_id = UserId::try_from(device.user_id.clone()).unwrap(); - let device_id = device.device_id.as_str().into(); - let device = self - .runtime - .block_on(self.inner.get_device(&user_id, device_id))? - .unwrap(); - - let (sas, request) = self.runtime.block_on(device.start_verification())?; - - Ok(Sas { - other_user_id: sas.other_user_id().to_string(), - other_device_id: sas.other_device_id().to_string(), - flow_id: sas.flow_id().as_str().to_owned(), - request: request.into(), - }) - } - - pub fn outgoing_requests(&self) -> Vec { - self.runtime - .block_on(self.inner.outgoing_requests()) - .into_iter() - .map(|r| r.into()) - .collect() - } - + /// Let the state machine know about E2EE related sync changes that we + /// received from the server. + /// + /// This needs to be called after every sync, ideally before processing + /// any other sync changes. + /// + /// # Arguments + /// + /// * `events` - A serialized array of to-device events we received in the + /// current sync resposne. + /// + /// * `device_changes` - The list of devices that have changed in some way + /// since the previous sync. + /// + /// * `key_counts` - The map of uploaded one-time key types and counts. pub fn receive_sync_changes( &self, events: &str, @@ -195,6 +213,16 @@ impl OlmMachine { .unwrap(); } + /// Add the given list of users to be tracked, triggering a key query request + /// for them. + /// + /// *Note*: Only users that aren't already tracked will be considered for an + /// update. It's safe to call this with already tracked users, it won't + /// result in excessive keys query requests. + /// + /// # Arguments + /// + /// `users` - The users that should be queued up for a key query. pub fn update_tracked_users(&self, users: Vec) { let users: Vec = users .into_iter() @@ -205,25 +233,20 @@ impl OlmMachine { .block_on(self.inner.update_tracked_users(users.iter())); } - pub fn share_group_session(&self, room_id: &str, users: Vec) -> Vec { - let users: Vec = users - .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) - .collect(); - - let room_id = RoomId::try_from(room_id).unwrap(); - let requests = self - .runtime - .block_on(self.inner.share_group_session( - &room_id, - users.iter(), - EncryptionSettings::default(), - )) - .unwrap(); - - requests.into_iter().map(|r| (&*r).into()).collect() - } - + /// Generate one-time key claiming requests for all the users we are missing + /// sessions for. + /// + /// After the request was sent out and a successful response was received + /// the response body should be passed back to the state machine using the + /// [mark_request_as_sent()](#method.mark_request_as_sent) method. + /// + /// This method should be called every time before a call to + /// [`share_group_session()`](#method.share_group_session) is made. + /// + /// # Arguments + /// + /// * `users` - The list of users for which we would like to establish 1:1 + /// Olm sessions for. pub fn get_missing_sessions( &self, users: Vec, @@ -253,6 +276,76 @@ impl OlmMachine { })) } + /// Generate one-time key claiming requests for all the users we are missing + /// sessions for. + /// + /// After the request was sent out and a successful response was received + /// the response body should be passed back to the state machine using the + /// [mark_request_as_sent()](#method.mark_request_as_sent) method. + /// + /// This method should be called every time before a call to + /// [`encrypt()`](#method.encrypt) with the given `room_id` is made. + /// + /// # Arguments + /// + /// * `room_id` - The unique id of the room, note that this doesn't strictly + /// need to be a Matrix room, it just needs to be an unique identifier for + /// the group that will participate in the conversation. + /// + /// * `users` - The list of users which are considered to be members of the + /// room and should receive the room key. + pub fn share_group_session(&self, room_id: &str, users: Vec) -> Vec { + let users: Vec = users + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(); + + let room_id = RoomId::try_from(room_id).unwrap(); + let requests = self + .runtime + .block_on(self.inner.share_group_session( + &room_id, + users.iter(), + EncryptionSettings::default(), + )) + .unwrap(); + + requests.into_iter().map(|r| (&*r).into()).collect() + } + + /// Encrypt the given event with the given type and content for the given + /// room. + /// + /// **Note**: A room key needs to be shared with the group of users that are + /// members in the given room. If this is not done this method will panic. + /// + /// The usual flow to encrypt an evnet using this state machine is as + /// follows: + /// + /// 1. Get the one-time key claim request to establish 1:1 Olm sessions for + /// the room members of the room we wish to participate in. This is done + /// using the [`get_missing_sessions()`](#method.get_missing_sessions) + /// method. This method call should be locked per call. + /// + /// 2. Share a room key with all the room members using the + /// [`share_group_session()`](#method.share_group_session). This method + /// call should be locked per room. + /// + /// 3. Encrypt the event using this method. + /// + /// 4. Send the encrypted event to the server. + /// + /// After the room key is shared steps 1 and 2 will become noops, unless + /// there's some changes in the room membership or in the list of devices a + /// member has. + /// + /// # Arguments + /// + /// * `room_id` - The unique id of the room where the event will be sent to. + /// + /// * `even_type` - The type of the event. + /// + /// * `content` - The serialized content of the event. pub fn encrypt(&self, room_id: &str, event_type: &str, content: &str) -> String { let room_id = RoomId::try_from(room_id).unwrap(); let content: Box = serde_json::from_str(content).unwrap(); @@ -266,33 +359,13 @@ impl OlmMachine { serde_json::to_string(&encrypted_content).unwrap() } - pub fn export_keys(&self, passphrase: &str, rounds: i32) -> Result { - let keys = self.runtime.block_on(self.inner.export_keys(|_| true))?; - - let encrypted = encrypt_key_export(&keys, passphrase, rounds as u32) - .map_err(CryptoStoreError::Serialization)?; - - Ok(encrypted) - } - - pub fn import_keys( - &self, - keys: &str, - passphrase: &str, - _: Box, - ) -> Result { - let keys = Cursor::new(keys); - let keys = decrypt_key_export(keys, passphrase)?; - - // TODO use the progress listener - let result = self.runtime.block_on(self.inner.import_keys(keys))?; - - Ok(KeysImportResult { - total: result.1 as i32, - imported: result.0 as i32, - }) - } - + /// Decrypt the given event that was sent in the given room. + /// + /// # Arguments + /// + /// * `event` - The serialized encrypted version of the event. + /// + /// * `room_id` - The unique id of the room where the event was sent to. pub fn decrypt_room_event( &self, event: &str, @@ -331,4 +404,68 @@ impl OlmMachine { }, }) } + + /// Export all of our room keys. + /// + /// # Arguments + /// + /// * `passphrase` - The passphrase that should be used to encrypt the key + /// export. + /// + /// * `rounds` - The number of rounds that should be used when expanding the + /// passphrase into an key. + pub fn export_keys(&self, passphrase: &str, rounds: i32) -> Result { + let keys = self.runtime.block_on(self.inner.export_keys(|_| true))?; + + let encrypted = encrypt_key_export(&keys, passphrase, rounds as u32) + .map_err(CryptoStoreError::Serialization)?; + + Ok(encrypted) + } + + /// Import room keys from the given serialized key export. + /// + /// # Arguments + /// + /// * `keys` - The serialized version of the key export. + /// + /// * `passphrase` - The passphrase that was used to encrypt the key export. + /// + /// * `progress_listener` - A callback that can be used to introspect the + /// progress of the key import. + pub fn import_keys( + &self, + keys: &str, + passphrase: &str, + _progress_listener: Box, + ) -> Result { + let keys = Cursor::new(keys); + let keys = decrypt_key_export(keys, passphrase)?; + + // TODO use the progress listener + let result = self.runtime.block_on(self.inner.import_keys(keys))?; + + Ok(KeysImportResult { + total: result.1 as i32, + imported: result.0 as i32, + }) + } + + pub fn start_verification(&self, device: &Device) -> Result { + let user_id = UserId::try_from(device.user_id.clone()).unwrap(); + let device_id = device.device_id.as_str().into(); + let device = self + .runtime + .block_on(self.inner.get_device(&user_id, device_id))? + .unwrap(); + + let (sas, request) = self.runtime.block_on(device.start_verification())?; + + Ok(Sas { + other_user_id: sas.other_user_id().to_string(), + other_device_id: sas.other_device_id().to_string(), + flow_id: sas.flow_id().as_str().to_owned(), + request: request.into(), + }) + } } diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index 4861920598..d7d52fef98 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -1,7 +1,4 @@ -use std::{ - collections::HashMap, - convert::TryFrom, -}; +use std::{collections::HashMap, convert::TryFrom}; use http::Response; use serde_json::json; @@ -19,9 +16,7 @@ use matrix_sdk_common::{ identifiers::UserId, }; -use matrix_sdk_crypto::{ - IncomingResponse, OutgoingRequest, ToDeviceRequest, -}; +use matrix_sdk_crypto::{IncomingResponse, OutgoingRequest, ToDeviceRequest}; pub enum Request { ToDevice { @@ -101,7 +96,6 @@ pub(crate) fn response_from_string(body: &str) -> Response> { .expect("Can't create HTTP response") } - pub enum RequestType { KeysQuery, KeysClaim, From 6d05f5b993723c8fb9fba8897922ae488d171975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 7 Apr 2021 15:41:27 +0200 Subject: [PATCH 065/252] crypto: Rename newCrypto to OlmMachine.kt --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 4 ++-- .../sdk/internal/{newCrypto.kt => crypto/OlmMachine.kt} | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/{newCrypto.kt => crypto/OlmMachine.kt} (98%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 894eb04a11..d9d6344de8 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -52,8 +52,8 @@ import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.OlmMachine -import org.matrix.android.sdk.internal.setRustLogger +import org.matrix.android.sdk.internal.crypto.OlmMachine +import org.matrix.android.sdk.internal.crypto.setRustLogger import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt similarity index 98% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 86d57d9a31..768b86d17f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal +package org.matrix.android.sdk.internal.crypto -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -26,7 +26,6 @@ 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.util.JsonDict -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult 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 @@ -243,7 +242,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { } suspend fun getUserDevices(userIds: List): List { - val plainDevices: ArrayList = arrayListOf() + val plainDevices: ArrayList = arrayListOf() for (user in userIds) { val devices = getUserDevices(user) From 08d0787cc9eee4bde1468c17ed8c26d41430c3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 8 Apr 2021 11:09:05 +0200 Subject: [PATCH 066/252] crypto: More docs --- .../android/sdk/internal/crypto/OlmMachine.kt | 337 ++++++++++++++---- rust-sdk/src/machine.rs | 5 +- 2 files changed, 266 insertions(+), 76 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 768b86d17f..bc7835db11 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -143,14 +143,23 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) private val deviceUpdateObserver = DeviceUpdateObserver() + /** + * Get our own user ID. + */ fun userId(): String { return this.inner.userId() } + /** + * Get our own device ID. + */ fun deviceId(): String { return this.inner.deviceId() } + /** + * Get our own public identity keys ID. + */ fun identityKeys(): Map { return this.inner.identityKeys() } @@ -170,36 +179,56 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { ) } - suspend fun updateLiveDevices() { - for ((liveDevice, users) in deviceUpdateObserver.listeners) { - val devices = getUserDevices(users) - liveDevice.postValue(devices) - } - } - + /** + * Get the list of outgoing requests that need to be sent to the homeserver. + * + * After the request was sent out and a successful response was received + * the response body should be passed back to the state machine using the + * mark_request_as_sent method. + * + * @return the list of requests that needs to be sent to the homeserver + */ suspend fun outgoingRequests(): List = withContext(Dispatchers.IO) { inner.outgoingRequests() } - suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = withContext(Dispatchers.IO) { - val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) - val contentString = adapter.toJson(content) - val encrypted = inner.encrypt(roomId, eventType, contentString) - adapter.fromJson(encrypted)!! + /** + * Mark a request that was sent to the server as sent. + * + * @param requestId The unique ID of the request that was sent out. This needs to be an UUID. + * + * @param requestType The type of the request that was sent out. + * + * @param responseBody The body of the response that was received. + */ + suspend fun markRequestAsSent( + requestId: String, + requestType: RequestType, + responseBody: String + ) = withContext(Dispatchers.IO) { + inner.markRequestAsSent(requestId, requestType, responseBody) + + if (requestType == RequestType.KEYS_QUERY) { + updateLiveDevices() + } } - suspend fun shareGroupSession(roomId: String, users: List): List = withContext(Dispatchers.IO) { - inner.shareGroupSession(roomId, users) - } - - suspend fun getMissingSessions(users: List): Request? = withContext(Dispatchers.IO) { - inner.getMissingSessions(users) - } - - suspend fun updateTrackedUsers(users: List) = withContext(Dispatchers.IO) { - inner.updateTrackedUsers(users) - } + /** + * Let the state machine know about E2EE related sync changes that we + * received from the server. + * + * This needs to be called after every sync, ideally before processing + * any other sync changes. + * + * @param toDevice A serialized array of to-device events we received in the + * current sync resposne. + * + * @param deviceChanges The list of devices that have changed in some way + * since the previous sync. + * + * @param keyCounts The map of uploaded one-time key types and counts. + */ suspend fun receiveSyncChanges( toDevice: ToDeviceSyncResponse?, deviceChanges: DeviceListResponse?, @@ -218,64 +247,114 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.receiveSyncChanges(events, devices, counts) } - suspend fun markRequestAsSent( - request_id: String, - request_type: RequestType, - response_body: String - ) = withContext(Dispatchers.IO) { - inner.markRequestAsSent(request_id, request_type, response_body) - - if (request_type == RequestType.KEYS_QUERY) { - updateLiveDevices() - } + /** + * Mark the given list of users to be tracked, triggering a key query request + * for them. + * + * *Note*: Only users that aren't already tracked will be considered for an + * update. It's safe to call this with already tracked users, it won't + * result in excessive keys query requests. + * + * @param users The users that should be queued up for a key query. + */ + suspend fun updateTrackedUsers(users: List) = withContext(Dispatchers.IO) { + inner.updateTrackedUsers(users) } - suspend fun getDevice(user_id: String, device_id: String): Device? = withContext(Dispatchers.IO) { - when (val device: InnerDevice? = inner.getDevice(user_id, device_id)) { - null -> null - else -> Device(device, inner) - } + + /** + * Generate one-time key claiming requests for all the users we are missing + * sessions for. + * + * After the request was sent out and a successful response was received + * the response body should be passed back to the state machine using the + * mark_request_as_sent() method. + * + * This method should be called every time before a call to + * share_group_session() is made. + * + * @param users The list of users for which we would like to establish 1:1 + * Olm sessions for. + * + * @return A keys claim request that needs to be sent out to the server. + */ + suspend fun getMissingSessions(users: List): Request? = withContext(Dispatchers.IO) { + inner.getMissingSessions(users) } - suspend fun getUserDevices(userId: String): List { - return inner.getUserDevices(userId).map { Device(it, inner).toCryptoDeviceInfo() } + /** + * Share a room key with the given list of users for the given room. + * + * After the request was sent out and a successful response was received + * the response body should be passed back to the state machine using the + * mark_request_as_sent() method. + * + * This method should be called every time before a call to + * `encrypt()` with the given `room_id` is made. + * + * @param roomId The unique id of the room, note that this doesn't strictly + * need to be a Matrix room, it just needs to be an unique identifier for + * the group that will participate in the conversation. + * + * @param users The list of users which are considered to be members of the + * room and should receive the room key. + * + * @return The list of requests that need to be sent out. + */ + suspend fun shareGroupSession(roomId: String, users: List): List = withContext(Dispatchers.IO) { + inner.shareGroupSession(roomId, users) } - suspend fun getUserDevices(userIds: List): List { - val plainDevices: ArrayList = arrayListOf() - - for (user in userIds) { - val devices = getUserDevices(user) - plainDevices.addAll(devices) - } - - return plainDevices - } - - suspend fun getLiveDevices(userIds: List): LiveData> { - val plainDevices = getUserDevices(userIds) - val devices = LiveDevice(userIds, deviceUpdateObserver) - devices.setValue(plainDevices) - - return devices - } - - @Throws(CryptoStoreErrorException::class) - suspend fun exportKeys(passphrase: String, rounds: Int): ByteArray = withContext(Dispatchers.IO) { - inner.exportKeys(passphrase, rounds).toByteArray() - } - - @Throws(CryptoStoreErrorException::class) - suspend fun importKeys(keys: ByteArray, passphrase: String, listener: ProgressListener?): ImportRoomKeysResult = withContext(Dispatchers.IO) { - var decodedKeys = keys.toString() - - var rustListener = CryptoProgressListener(listener) - - var result = inner.importKeys(decodedKeys, passphrase, rustListener) - - ImportRoomKeysResult(result.total, result.imported) + /** + * Encrypt the given event with the given type and content for the given + * room. + * + * **Note**: A room key needs to be shared with the group of users that are + * members in the given room. If this is not done this method will panic. + * + * The usual flow to encrypt an evnet using this state machine is as + * follows: + * + * 1. Get the one-time key claim request to establish 1:1 Olm sessions for + * the room members of the room we wish to participate in. This is done + * using the [`get_missing_sessions()`](#method.get_missing_sessions) + * method. This method call should be locked per call. + * + * 2. Share a room key with all the room members using the share_group_session(). + * This method call should be locked per room. + * + * 3. Encrypt the event using this method. + * + * 4. Send the encrypted event to the server. + * + * After the room key is shared steps 1 and 2 will become noops, unless + * there's some changes in the room membership or in the list of devices a + * member has. + * + * @param roomId the ID of the room where the encrypted event will be sent to + * + * @param eventType the type of the event + * + * @param content the JSON content of the event + * + * @return The encrypted version of the content + */ + suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val contentString = adapter.toJson(content) + val encrypted = inner.encrypt(roomId, eventType, contentString) + adapter.fromJson(encrypted)!! } + /** + * Decrypt the given event that was sent in the given room. + * + * # Arguments + * + * @param event The serialized encrypted version of the event. + * + * @return the decrypted version of the event. + */ @Throws(MXCryptoError::class) suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) @@ -298,4 +377,116 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason) } } + + /** + * Export all of our room keys. + * + * @param passphrase The passphrase that should be used to encrypt the key + * export. + * + * @param rounds The number of rounds that should be used when expanding the + * passphrase into an key. + * + * @return the encrypted key export as a bytearray. + */ + @Throws(CryptoStoreErrorException::class) + suspend fun exportKeys(passphrase: String, rounds: Int): ByteArray = withContext(Dispatchers.IO) { + inner.exportKeys(passphrase, rounds).toByteArray() + } + + + /** + * Import room keys from the given serialized key export. + * + * @param keys The serialized version of the key export. + * + * @param passphrase The passphrase that was used to encrypt the key export. + * + * @param listener A callback that can be used to introspect the + * progress of the key import. + */ + @Throws(CryptoStoreErrorException::class) + suspend fun importKeys(keys: ByteArray, passphrase: String, listener: ProgressListener?): ImportRoomKeysResult = withContext(Dispatchers.IO) { + var decodedKeys = keys.toString() + + var rustListener = CryptoProgressListener(listener) + + var result = inner.importKeys(decodedKeys, passphrase, rustListener) + + ImportRoomKeysResult(result.total, result.imported) + } + + + /** + * Get a `Device` from the store. + * + * @param userId The id of the device owner. + * + * @param deviceId The id of the device itself. + * + * @return The Device if it found one. + */ + suspend fun getDevice(userId: String, deviceId: String): Device? = withContext(Dispatchers.IO) { + when (val device: InnerDevice? = inner.getDevice(userId, deviceId)) { + null -> null + else -> Device(device, inner) + } + } + + /** + * Get all devices of an user. + * + * @param userId The id of the device owner. + * + * @return The list of Devices or an empty list if there aren't any. + */ + suspend fun getUserDevices(userId: String): List { + return inner.getUserDevices(userId).map { Device(it, inner).toCryptoDeviceInfo() } + } + + /** + * Get all the devices of multiple users. + * + * @param userId The ids of the device owners. + * + * @return The list of Devices or an empty list if there aren't any. + */ + suspend fun getUserDevices(userIds: List): List { + val plainDevices: ArrayList = arrayListOf() + + for (user in userIds) { + val devices = getUserDevices(user) + plainDevices.addAll(devices) + } + + return plainDevices + } + + /** + * Update all of our live device listeners. + */ + private suspend fun updateLiveDevices() { + for ((liveDevice, users) in deviceUpdateObserver.listeners) { + val devices = getUserDevices(users) + liveDevice.postValue(devices) + } + } + + /** + * Get all the devices of multiple users as a live version. + * + * The live version will update the list of devices if some of the data + * changes, or if new devices arrive for a certain user. + * + * @param userId The ids of the device owners. + * + * @return The list of Devices or an empty list if there aren't any. + */ + suspend fun getLiveDevices(userIds: List): LiveData> { + val plainDevices = getUserDevices(userIds) + val devices = LiveDevice(userIds, deviceUpdateObserver) + devices.setValue(plainDevices) + + return devices + } } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index f6626c2929..dc84e7b021 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -86,7 +86,7 @@ impl OlmMachine { /// /// * `user_id` - The id of the device owner. /// - /// * `device_id` - The id of the device itsefl. + /// * `device_id` - The id of the device itself. pub fn get_device(&self, user_id: &str, device_id: &str) -> Option { let user_id = UserId::try_from(user_id).unwrap(); @@ -276,8 +276,7 @@ impl OlmMachine { })) } - /// Generate one-time key claiming requests for all the users we are missing - /// sessions for. + /// Share a room key with the given list of users for the given room. /// /// After the request was sent out and a successful response was received /// the response body should be passed back to the state machine using the From edfd1b2fe06f6b183bc91d96366101b6926d9469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 8 Apr 2021 15:55:10 +0200 Subject: [PATCH 067/252] crypto: Get rid of the DeviceKeysManager --- .../internal/crypto/DefaultCryptoService.kt | 10 +++++++--- .../android/sdk/internal/crypto/OlmMachine.kt | 19 +++++++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index d9d6344de8..d6a47dee0a 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -122,8 +122,6 @@ internal class DefaultCryptoService @Inject constructor( private val cryptoStore: IMXCryptoStore, // Set of parameters used to configure/customize the end-to-end crypto. private val mxCryptoConfig: MXCryptoConfig, - // Device list manager - private val deviceListManager: DeviceListManager, // The key backup service. private val keysBackupService: DefaultKeysBackupService, // The verification service. @@ -915,7 +913,13 @@ internal class DefaultCryptoService @Inject constructor( override fun downloadKeys(userIds: List, forceDownload: Boolean, callback: MatrixCallback>) { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { runCatching { - deviceListManager.downloadKeys(userIds, forceDownload) + if (forceDownload) { + // TODO replicate the logic from the device list manager + // where we would download the fresh info from the server. + olmMachine?.getUserDevicesMap(userIds) ?: MXUsersDevicesMap() + } else { + olmMachine?.getUserDevicesMap(userIds) ?: MXUsersDevicesMap() + } }.foldToCallback(callback) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index bc7835db11..646ce03046 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -29,6 +29,7 @@ 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.di.MoshiProvider import org.matrix.android.sdk.internal.session.sync.model.DeviceListResponse @@ -213,7 +214,6 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { } } - /** * Let the state machine know about E2EE related sync changes that we * received from the server. @@ -261,7 +261,6 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.updateTrackedUsers(users) } - /** * Generate one-time key claiming requests for all the users we are missing * sessions for. @@ -394,7 +393,6 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.exportKeys(passphrase, rounds).toByteArray() } - /** * Import room keys from the given serialized key export. * @@ -416,7 +414,6 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { ImportRoomKeysResult(result.total, result.imported) } - /** * Get a `Device` from the store. * @@ -444,6 +441,20 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { return inner.getUserDevices(userId).map { Device(it, inner).toCryptoDeviceInfo() } } + suspend fun getUserDevicesMap(userIds: List): MXUsersDevicesMap { + val userMap = MXUsersDevicesMap() + + for (user in userIds) { + val devices = getUserDevices(user) + + for (device in devices) { + userMap.setObject(user, device.deviceId, device) + } + } + + return userMap + } + /** * Get all the devices of multiple users. * From 5253f9708cdcbcb910243e9cac01c1785da74b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 8 Apr 2021 15:55:38 +0200 Subject: [PATCH 068/252] crypto: Fix a crash when we access the devices before the olmMachine is set up The crypto service is fully initialized only after the first sync but EA seems to access live devices before that. This results in a crash since we now use the olm machine to access devices. --- .../sdk/internal/crypto/DefaultCryptoService.kt | 17 ++++++----------- .../android/sdk/internal/crypto/OlmMachine.kt | 8 ++------ 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index d6a47dee0a..857424926a 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -150,6 +150,7 @@ internal class DefaultCryptoService @Inject constructor( private val isStarting = AtomicBoolean(false) private val isStarted = AtomicBoolean(false) private var olmMachine: OlmMachine? = null + private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() suspend fun onStateEvent(roomId: String, event: Event) { when (event.getClearType()) { @@ -320,7 +321,7 @@ internal class DefaultCryptoService @Inject constructor( try { setRustLogger() - olmMachine = OlmMachine(userId, deviceId!!, dataDir) + olmMachine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) Timber.v("HELLLO WORLD STARTING $dataDir CRYPTO ${olmMachine?.identityKeys()}") } catch (throwable: Throwable) { @@ -393,14 +394,8 @@ internal class DefaultCryptoService @Inject constructor( */ override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) { - val device = runBlocking { - olmMachine!!.getDevice(userId, deviceId) - } - - if (device != null) { - device.toCryptoDeviceInfo() - } else { - null + runBlocking { + olmMachine?.getDevice(userId, deviceId)?.toCryptoDeviceInfo() } } else { null @@ -409,7 +404,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getCryptoDeviceInfo(userId: String): List { return runBlocking { - olmMachine!!.getUserDevices(userId) + olmMachine?.getUserDevices(userId) ?: listOf() } } @@ -419,7 +414,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getLiveCryptoDeviceInfo(userIds: List): LiveData> { return runBlocking { - olmMachine!!.getLiveDevices(userIds) + olmMachine?.getLiveDevices(userIds) ?: LiveDevice(userIds, deviceObserver) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 646ce03046..44a0434f77 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -70,10 +70,6 @@ internal class LiveDevice( var userIds: List = userIds private var observer: DeviceUpdateObserver = observer - private val listener = { devices: List -> - value = devices - } - override fun onActive() { observer.addDeviceUpdateListener(this) } @@ -140,9 +136,9 @@ internal class DeviceUpdateObserver() { } } -internal class OlmMachine(user_id: String, device_id: String, path: File) { +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 = DeviceUpdateObserver() + private val deviceUpdateObserver = deviceObserver /** * Get our own user ID. From 8692f05e34cde3269963ef07cca0503a6cc03eaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 9 Apr 2021 12:35:13 +0200 Subject: [PATCH 069/252] crypto: Connect the room key discarding logic --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 2 +- .../org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 7 +++++++ rust-sdk/src/machine.rs | 8 ++++++++ rust-sdk/src/olm.udl | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 43010475d6..8e0620507f 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -543,7 +543,7 @@ internal class DefaultCryptoService @Inject constructor( } override fun discardOutboundSession(roomId: String) { - // TODO + olmMachine?.discardRoomKey(roomId) } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 44a0434f77..49773428c6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -496,4 +496,11 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device return devices } + + /** + * Discard the currently active room key for the given room if there is one. + */ + fun discardRoomKey(roomId: String) { + this.inner.discardRoomKey(roomId) + } } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index dc84e7b021..4462707b2f 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -450,6 +450,14 @@ impl OlmMachine { }) } + /// Discard the currently active room key for the given room if there is + /// one. + pub fn discard_room_key(&self, room_id: &str) { + let room_id = RoomId::try_from(room_id).unwrap(); + + self.inner.invalidate_group_session(&room_id); + } + pub fn start_verification(&self, device: &Device) -> Result { let user_id = UserId::try_from(device.user_id.clone()).unwrap(); let device_id = device.device_id.as_str().into(); diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 1d32503e15..66ebb09f80 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -127,4 +127,5 @@ interface OlmMachine { [ByRef] string passphrase, ProgressListener progress_listener ); + void discard_room_key([ByRef] string room_id); }; From 74a1c226a4bda4f30dba53c2450b3d1e29bac45f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 9 Apr 2021 12:42:22 +0200 Subject: [PATCH 070/252] crypto: Introduce some locks for some of our e2ee operations --- .../internal/crypto/DefaultCryptoService.kt | 66 +++++++++++-------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 8e0620507f..6740bac642 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -24,6 +24,7 @@ import com.squareup.moshi.Types import dagger.Lazy import java.io.File import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.ConcurrentHashMap import javax.inject.Inject import kotlin.jvm.Throws import kotlin.math.max @@ -32,6 +33,8 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback @@ -152,6 +155,11 @@ internal class DefaultCryptoService @Inject constructor( private var olmMachine: OlmMachine? = null private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() + // Locks for some of our operations + private val keyClaimLock: Mutex = Mutex() + private val outgointRequestsLock: Mutex = Mutex() + private val roomKeyShareLocks: ConcurrentHashMap = ConcurrentHashMap() + suspend fun onStateEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) @@ -650,23 +658,28 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun preshareGroupSession(roomId: String, roomMembers: List) { - // TODO this needs to be locked per room - val request = olmMachine!!.getMissingSessions(roomMembers) - - if (request != null) { - // This request can only be a keys claim request. - when (request) { - is Request.KeysClaim -> { - claimKeys(request) + keyClaimLock.withLock { + val request = olmMachine!!.getMissingSessions(roomMembers) + if (request != null) { + // This request can only be a keys claim request. + when (request) { + is Request.KeysClaim -> { + claimKeys(request) + } } } } - for (toDeviceRequest in olmMachine!!.shareGroupSession(roomId, roomMembers)) { - // This request can only be a to-device request. - when (toDeviceRequest) { - is Request.ToDevice -> { - sendToDevice(toDeviceRequest) + val keyShareLock = roomKeyShareLocks.getOrDefault(roomId, Mutex()) + + keyShareLock.withLock { + for (toDeviceRequest in olmMachine!!.shareGroupSession(roomId, roomMembers)) { + // TODO these requests should be sent out in parallel + // This request can only be a to-device request. + when (toDeviceRequest) { + is Request.ToDevice -> { + sendToDevice(toDeviceRequest) + } } } } @@ -699,7 +712,6 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun queryKeys(outgoingRequest: Request.KeysQuery) { - Timber.v("HELLO KEYS QUERY REQUEST ${outgoingRequest.users}") val params = DownloadKeysForUsersTask.Params(outgoingRequest.users, null) try { @@ -729,7 +741,6 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun claimKeys(request: Request.KeysClaim) { - // TODO this needs to be locked per call val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) val adapter = MoshiProvider @@ -741,18 +752,19 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun sendOutgoingRequests() { - // TODO this needs to be locked per call - // TODO these requests should be sent out in parallel - for (outgoingRequest in olmMachine!!.outgoingRequests()) { - when (outgoingRequest) { - is Request.KeysUpload -> { - uploadKeys(outgoingRequest) - } - is Request.KeysQuery -> { - queryKeys(outgoingRequest) - } - is Request.ToDevice -> { - // Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") + outgointRequestsLock.withLock { + // TODO these requests should be sent out in parallel + for (outgoingRequest in olmMachine!!.outgoingRequests()) { + when (outgoingRequest) { + is Request.KeysUpload -> { + uploadKeys(outgoingRequest) + } + is Request.KeysQuery -> { + queryKeys(outgoingRequest) + } + is Request.ToDevice -> { + // Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") + } } } } From 188d2d57c00bde1d237440b9e25fb0a6c18d95da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 9 Apr 2021 13:53:31 +0200 Subject: [PATCH 071/252] crypto: Use a concurrent hashmap for the live devices update logic --- .../java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 49773428c6..6c6b5abbe7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.crypto import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import java.io.File +import java.util.concurrent.ConcurrentHashMap import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.listeners.ProgressListener @@ -125,7 +126,7 @@ class Device(inner: InnerDevice, machine: InnerMachine) { } internal class DeviceUpdateObserver() { - internal val listeners = HashMap>() + internal val listeners = ConcurrentHashMap>() fun addDeviceUpdateListener(device: LiveDevice) { listeners.set(device, device.userIds) From 9296cab4fcc6f64e1318a306eac4f5b97c349303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 9 Apr 2021 13:53:55 +0200 Subject: [PATCH 072/252] crypto: Expose more device data from the rust side --- .../matrix/android/sdk/internal/crypto/OlmMachine.kt | 11 ++++------- rust-sdk/src/device.rs | 6 ++++++ rust-sdk/src/olm.udl | 3 +++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 6c6b5abbe7..b4d929724d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -108,17 +108,14 @@ class Device(inner: InnerDevice, machine: InnerMachine) { return CryptoDeviceInfo( this.deviceId(), this.userId(), - // TODO pass the algorithms here. - listOf(), + this.inner.algorithms, this.keys(), - // TODO pass the signatures here. + // TODO pass the signatures here, do we need this? mapOf(), - // TODO pass the display name here. - UnsignedDeviceInfo(), + UnsignedDeviceInfo(this.inner.displayName), // TODO pass trust levels here DeviceTrustLevel(false, false), - // TODO is the device blacklisted - false, + this.inner.isBlocked, // TODO null ) diff --git a/rust-sdk/src/device.rs b/rust-sdk/src/device.rs index 2e3a0a78e1..c8557c5de9 100644 --- a/rust-sdk/src/device.rs +++ b/rust-sdk/src/device.rs @@ -6,6 +6,9 @@ pub struct Device { pub user_id: String, pub device_id: String, pub keys: HashMap, + pub algorithms: Vec, + pub display_name: Option, + pub is_blocked: bool, } impl From for Device { @@ -18,6 +21,9 @@ impl From for Device { .iter() .map(|(k, v)| (k.to_string(), v.to_string())) .collect(), + algorithms: d.algorithms().iter().map(|a| a.to_string()).collect(), + display_name: d.display_name().clone(), + is_blocked: d.is_blacklisted(), } } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 66ebb09f80..9dc626667c 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -57,6 +57,9 @@ dictionary Device { string user_id; string device_id; record keys; + sequence algorithms; + string? display_name; + boolean is_blocked; }; dictionary Sas { From 99477914df335245ed7c687a06a256d54d730ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 9 Apr 2021 14:47:59 +0200 Subject: [PATCH 073/252] crypto: Remove the higher level Device since it's unlikely we'll be using it --- .../internal/crypto/DefaultCryptoService.kt | 4 +- .../android/sdk/internal/crypto/OlmMachine.kt | 55 +++++++------------ 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 6740bac642..c6f2bd7707 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -57,7 +57,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.crypto.OlmMachine import org.matrix.android.sdk.internal.crypto.setRustLogger -import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService @@ -132,7 +131,6 @@ internal class DefaultCryptoService @Inject constructor( private val crossSigningService: DefaultCrossSigningService, // Actions - private val megolmSessionDataImporter: MegolmSessionDataImporter, private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository, // Tasks private val deleteDeviceTask: DeleteDeviceTask, @@ -403,7 +401,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) { runBlocking { - olmMachine?.getDevice(userId, deviceId)?.toCryptoDeviceInfo() + olmMachine?.getDevice(userId, deviceId) } } else { null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index b4d929724d..c880ee8997 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -38,7 +38,7 @@ import org.matrix.android.sdk.internal.session.sync.model.DeviceOneTimeKeysCount import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse import timber.log.Timber import uniffi.olm.CryptoStoreErrorException -import uniffi.olm.Device as InnerDevice +import uniffi.olm.Device import uniffi.olm.DeviceLists import uniffi.olm.Logger import uniffi.olm.OlmMachine as InnerMachine @@ -68,7 +68,7 @@ internal class LiveDevice( userIds: List, observer: DeviceUpdateObserver ) : MutableLiveData>() { - var userIds: List = userIds + internal var userIds: List = userIds private var observer: DeviceUpdateObserver = observer override fun onActive() { @@ -84,42 +84,25 @@ fun setRustLogger() { setLogger(CryptoLogger() as Logger) } -class Device(inner: InnerDevice, machine: InnerMachine) { - private val machine: InnerMachine = machine - private val inner: InnerDevice = inner - - fun userId(): String { - return this.inner.userId - } - - fun deviceId(): String { - return this.inner.deviceId - } - - fun keys(): Map { - return this.inner.keys - } - - fun startVerification(): InnerSas { - return this.machine.startVerification(this.inner) - } - - fun toCryptoDeviceInfo(): CryptoDeviceInfo { - return CryptoDeviceInfo( - this.deviceId(), - this.userId(), - this.inner.algorithms, - this.keys(), - // TODO pass the signatures here, do we need this? +/** + * Convert a Rust Device into a Kotlin CryptoDeviceInfo + */ +private fun toCryptoDeviceInfo(device: Device): CryptoDeviceInfo { + return CryptoDeviceInfo( + device.deviceId, + device.userId, + device.algorithms, + device.keys, + // TODO pass the signatures here, do we need this, why should the + // Kotlin side care about signatures? mapOf(), - UnsignedDeviceInfo(this.inner.displayName), + UnsignedDeviceInfo(device.displayName), // TODO pass trust levels here DeviceTrustLevel(false, false), - this.inner.isBlocked, + device.isBlocked, // TODO null ) - } } internal class DeviceUpdateObserver() { @@ -417,10 +400,10 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @return The Device if it found one. */ - suspend fun getDevice(userId: String, deviceId: String): Device? = withContext(Dispatchers.IO) { - when (val device: InnerDevice? = inner.getDevice(userId, deviceId)) { + suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? = withContext(Dispatchers.IO) { + when (val device: Device? = inner.getDevice(userId, deviceId)) { null -> null - else -> Device(device, inner) + else -> toCryptoDeviceInfo(device) } } @@ -432,7 +415,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * @return The list of Devices or an empty list if there aren't any. */ suspend fun getUserDevices(userId: String): List { - return inner.getUserDevices(userId).map { Device(it, inner).toCryptoDeviceInfo() } + return inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) } } suspend fun getUserDevicesMap(userIds: List): MXUsersDevicesMap { From e9e3d129ba8992fb3ab1826f8d3255e2e774004d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 9 Apr 2021 19:10:25 +0200 Subject: [PATCH 074/252] crypto: Send out some of our requests in parallel --- .../internal/crypto/DefaultCryptoService.kt | 60 +++++++++++++------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index c6f2bd7707..34e0aeb7a0 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -28,9 +28,12 @@ import java.util.concurrent.ConcurrentHashMap import javax.inject.Inject import kotlin.jvm.Throws import kotlin.math.max +import kotlinx.coroutines.async import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex @@ -671,14 +674,22 @@ internal class DefaultCryptoService @Inject constructor( val keyShareLock = roomKeyShareLocks.getOrDefault(roomId, Mutex()) keyShareLock.withLock { - for (toDeviceRequest in olmMachine!!.shareGroupSession(roomId, roomMembers)) { - // TODO these requests should be sent out in parallel - // This request can only be a to-device request. - when (toDeviceRequest) { - is Request.ToDevice -> { - sendToDevice(toDeviceRequest) + coroutineScope { + olmMachine!!.shareGroupSession(roomId, roomMembers).map { + when (it) { + is Request.ToDevice -> { + async { + sendToDevice(it) + } + } + else -> { + // This request can only be a to-device request but + // we need to handle all our cases and put this + // async block for our joinAll to work. + async {} + } } - } + }.joinAll() } } } @@ -751,19 +762,30 @@ internal class DefaultCryptoService @Inject constructor( private suspend fun sendOutgoingRequests() { outgointRequestsLock.withLock { - // TODO these requests should be sent out in parallel - for (outgoingRequest in olmMachine!!.outgoingRequests()) { - when (outgoingRequest) { - is Request.KeysUpload -> { - uploadKeys(outgoingRequest) + coroutineScope { + olmMachine!!.outgoingRequests().map { + when (it) { + is Request.KeysUpload -> { + async { + uploadKeys(it) + } + } + is Request.KeysQuery -> { + async { + queryKeys(it) + } + } + is Request.ToDevice -> { + // TODO this sends out mostly key requests, it's a + // bit spammy as of now so it's disabled, needs to + // be fixed on the Rust side. + async {} + } + else -> { + async {} + } } - is Request.KeysQuery -> { - queryKeys(outgoingRequest) - } - is Request.ToDevice -> { - // Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") - } - } + }.joinAll() } } } From 0d708bc35acaaffa2e0d20156a5f027e5940a3f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 12 Apr 2021 15:02:47 +0200 Subject: [PATCH 075/252] rust: Update our deps --- rust-sdk/Cargo.toml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index ee9a950ed0..4a443166b6 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -9,12 +9,13 @@ crate-type = ["cdylib", "lib"] name = "matrix_crypto" [dependencies] -serde_json = "1.0.62" -http = "0.2.3" +serde_json = "1.0.64" +http = "0.2.4" -thiserror = "1.0.23" -tracing = "0.1.23" -tracing-subscriber = "0.2.15" +thiserror = "1.0.24" +tracing = "0.1.25" +tracing-subscriber = "0.2.17" +uniffi = "0.8.0" [dependencies.js_int] version = "0.2.0" @@ -30,14 +31,9 @@ branch = "encryption-info" features = ["sled_cryptostore"] [dependencies.tokio] -version = "1.2.0" +version = "1.4.0" default_features = false features = ["rt-multi-thread"] -[dependencies.uniffi] -version = "0.7.0" -git = "https://github.com/mozilla/uniffi-rs" -rev = "f7c8ccda783494ee507ea0f8a61f35b39527394f" - [build-dependencies] -uniffi_build = "0.7.0" +uniffi_build = "0.8.0" From 543a638e87fff1b271e15266a99f5882d2698f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 12 Apr 2021 15:03:28 +0200 Subject: [PATCH 076/252] crypto: Forward some more errors from the rust side to the kotlin side --- .../android/sdk/internal/crypto/OlmMachine.kt | 17 +++- rust-sdk/src/error.rs | 2 + rust-sdk/src/machine.rs | 87 +++++++++++-------- rust-sdk/src/olm.udl | 40 +++++---- 4 files changed, 90 insertions(+), 56 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index c880ee8997..3e46dac83f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -22,6 +22,7 @@ import java.io.File import java.util.concurrent.ConcurrentHashMap import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import kotlinx.coroutines.runBlocking 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 @@ -179,6 +180,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @param responseBody The body of the response that was received. */ + @Throws(CryptoStoreErrorException::class) suspend fun markRequestAsSent( requestId: String, requestType: RequestType, @@ -206,11 +208,12 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @param keyCounts The map of uploaded one-time key types and counts. */ + @Throws(CryptoStoreErrorException::class) suspend fun receiveSyncChanges( toDevice: ToDeviceSyncResponse?, deviceChanges: DeviceListResponse?, keyCounts: DeviceOneTimeKeysCountSyncResponse? - ) = withContext(Dispatchers.IO) { + ): ToDeviceSyncResponse = withContext(Dispatchers.IO) { var counts: MutableMap = mutableMapOf() if (keyCounts?.signedCurve25519 != null) { @@ -221,7 +224,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device val adapter = MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! - inner.receiveSyncChanges(events, devices, counts) + adapter.fromJson(inner.receiveSyncChanges(events, devices, counts))!! } /** @@ -254,6 +257,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @return A keys claim request that needs to be sent out to the server. */ + @Throws(CryptoStoreErrorException::class) suspend fun getMissingSessions(users: List): Request? = withContext(Dispatchers.IO) { inner.getMissingSessions(users) } @@ -277,6 +281,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @return The list of requests that need to be sent out. */ + @Throws(CryptoStoreErrorException::class) suspend fun shareGroupSession(roomId: String, users: List): List = withContext(Dispatchers.IO) { inner.shareGroupSession(roomId, users) } @@ -315,6 +320,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @return The encrypted version of the content */ + @Throws(CryptoStoreErrorException::class) suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) val contentString = adapter.toJson(content) @@ -400,6 +406,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @return The Device if it found one. */ + @Throws(CryptoStoreErrorException::class) suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? = withContext(Dispatchers.IO) { when (val device: Device? = inner.getDevice(userId, deviceId)) { null -> null @@ -414,6 +421,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @return The list of Devices or an empty list if there aren't any. */ + @Throws(CryptoStoreErrorException::class) suspend fun getUserDevices(userId: String): List { return inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) } } @@ -481,7 +489,10 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device /** * Discard the currently active room key for the given room if there is one. */ + @Throws(CryptoStoreErrorException::class) fun discardRoomKey(roomId: String) { - this.inner.discardRoomKey(roomId) + runBlocking { + inner.discardRoomKey(roomId) + } } } diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index 8e66539131..4a17011208 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -27,6 +27,8 @@ pub enum CryptoStoreError { OlmError(#[from] OlmError), #[error(transparent)] Serialization(#[from] serde_json::Error), + #[error(transparent)] + Identifier(#[from] RumaIdentifierError), } #[derive(Debug, thiserror::Error)] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 4462707b2f..1b01bcb864 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -87,13 +87,17 @@ impl OlmMachine { /// * `user_id` - The id of the device owner. /// /// * `device_id` - The id of the device itself. - pub fn get_device(&self, user_id: &str, device_id: &str) -> Option { - let user_id = UserId::try_from(user_id).unwrap(); + pub fn get_device( + &self, + user_id: &str, + device_id: &str, + ) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; - self.runtime - .block_on(self.inner.get_device(&user_id, device_id.into())) - .unwrap() - .map(|d| d.into()) + Ok(self + .runtime + .block_on(self.inner.get_device(&user_id, device_id.into()))? + .map(|d| d.into())) } /// Get all devices of an user. @@ -101,14 +105,15 @@ impl OlmMachine { /// # Arguments /// /// * `user_id` - The id of the device owner. - pub fn get_user_devices(&self, user_id: &str) -> Vec { - let user_id = UserId::try_from(user_id).unwrap(); - self.runtime - .block_on(self.inner.get_user_devices(&user_id)) - .unwrap() + pub fn get_user_devices(&self, user_id: &str) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + + Ok(self + .runtime + .block_on(self.inner.get_user_devices(&user_id))? .devices() .map(|d| d.into()) - .collect() + .collect()) } /// Get our own identity keys. @@ -190,8 +195,8 @@ impl OlmMachine { events: &str, device_changes: DeviceLists, key_counts: HashMap, - ) { - let events: ToDevice = serde_json::from_str(events).unwrap(); + ) -> Result { + let events: ToDevice = serde_json::from_str(events)?; let device_changes: RumaDeviceLists = device_changes.into(); let key_counts: BTreeMap = key_counts .into_iter() @@ -205,12 +210,15 @@ impl OlmMachine { }) .collect(); - self.runtime + let events = self + .runtime .block_on( self.inner .receive_sync_changes(&events, &device_changes, &key_counts), ) .unwrap(); + + Ok(serde_json::to_string(&events)?) } /// Add the given list of users to be tracked, triggering a key query request @@ -293,23 +301,24 @@ impl OlmMachine { /// /// * `users` - The list of users which are considered to be members of the /// room and should receive the room key. - pub fn share_group_session(&self, room_id: &str, users: Vec) -> Vec { + pub fn share_group_session( + &self, + room_id: &str, + users: Vec, + ) -> Result, CryptoStoreError> { let users: Vec = users .into_iter() .filter_map(|u| UserId::try_from(u).ok()) .collect(); - let room_id = RoomId::try_from(room_id).unwrap(); - let requests = self - .runtime - .block_on(self.inner.share_group_session( - &room_id, - users.iter(), - EncryptionSettings::default(), - )) - .unwrap(); + let room_id = RoomId::try_from(room_id)?; + let requests = self.runtime.block_on(self.inner.share_group_session( + &room_id, + users.iter(), + EncryptionSettings::default(), + ))?; - requests.into_iter().map(|r| (&*r).into()).collect() + Ok(requests.into_iter().map(|r| (&*r).into()).collect()) } /// Encrypt the given event with the given type and content for the given @@ -345,17 +354,22 @@ impl OlmMachine { /// * `even_type` - The type of the event. /// /// * `content` - The serialized content of the event. - pub fn encrypt(&self, room_id: &str, event_type: &str, content: &str) -> String { - let room_id = RoomId::try_from(room_id).unwrap(); - let content: Box = serde_json::from_str(content).unwrap(); + pub fn encrypt( + &self, + room_id: &str, + event_type: &str, + content: &str, + ) -> Result { + let room_id = RoomId::try_from(room_id)?; + let content: Box = serde_json::from_str(content)?; - let content = AnyMessageEventContent::from_parts(event_type, content).unwrap(); + let content = AnyMessageEventContent::from_parts(event_type, content)?; let encrypted_content = self .runtime .block_on(self.inner.encrypt(&room_id, content)) .unwrap(); - serde_json::to_string(&encrypted_content).unwrap() + Ok(serde_json::to_string(&encrypted_content)?) } /// Decrypt the given event that was sent in the given room. @@ -452,14 +466,17 @@ impl OlmMachine { /// Discard the currently active room key for the given room if there is /// one. - pub fn discard_room_key(&self, room_id: &str) { - let room_id = RoomId::try_from(room_id).unwrap(); + pub fn discard_room_key(&self, room_id: &str) -> Result<(), CryptoStoreError> { + let room_id = RoomId::try_from(room_id)?; - self.inner.invalidate_group_session(&room_id); + self.runtime + .block_on(self.inner.invalidate_group_session(&room_id))?; + + Ok(()) } pub fn start_verification(&self, device: &Device) -> Result { - let user_id = UserId::try_from(device.user_id.clone()).unwrap(); + let user_id = UserId::try_from(device.user_id.clone())?; let device_id = device.device_id.as_str().into(); let device = self .runtime diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 9dc626667c..6a711dfb21 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -27,6 +27,7 @@ enum CryptoStoreError { "CryptoStore", "OlmError", "Serialization", + "Identifier", }; [Error] @@ -89,29 +90,15 @@ interface OlmMachine { [Throws=MachineCreationError] constructor([ByRef] string user_id, [ByRef] string device_id, [ByRef] string path); - void receive_sync_changes([ByRef] string events, - DeviceLists device_changes, - record key_counts); - - [Throws=DecryptionError] - DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id); - string encrypt([ByRef] string room_id, [ByRef] string event_type, [ByRef] string content); - record identity_keys(); - string user_id(); string device_id(); - Device? get_device([ByRef] string user_id, [ByRef] string device_id); - sequence get_user_devices([ByRef] string user_id); - - sequence outgoing_requests(); - - void update_tracked_users(sequence users); [Throws=CryptoStoreError] - Request? get_missing_sessions(sequence users); - sequence share_group_session([ByRef] string room_id, sequence users); - + string receive_sync_changes([ByRef] string events, + DeviceLists device_changes, + record key_counts); + sequence outgoing_requests(); [Throws=CryptoStoreError] void mark_request_as_sent( [ByRef] string request_id, @@ -119,6 +106,22 @@ interface OlmMachine { [ByRef] string response ); + [Throws=DecryptionError] + DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id); + [Throws=CryptoStoreError] + string encrypt([ByRef] string room_id, [ByRef] string event_type, [ByRef] string content); + + [Throws=CryptoStoreError] + Device? get_device([ByRef] string user_id, [ByRef] string device_id); + [Throws=CryptoStoreError] + sequence get_user_devices([ByRef] string user_id); + + void update_tracked_users(sequence users); + [Throws=CryptoStoreError] + Request? get_missing_sessions(sequence users); + [Throws=CryptoStoreError] + sequence share_group_session([ByRef] string room_id, sequence users); + [Throws=CryptoStoreError] Sas start_verification([ByRef] Device device); @@ -130,5 +133,6 @@ interface OlmMachine { [ByRef] string passphrase, ProgressListener progress_listener ); + [Throws=CryptoStoreError] void discard_room_key([ByRef] string room_id); }; From 7d67c79d2975dba346e734d3bba79bb1ce9e4e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Apr 2021 12:14:52 +0200 Subject: [PATCH 077/252] crypto: Use the key import progress listener on the rust side --- rust-sdk/src/machine.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 1b01bcb864..1344f1a0f8 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -450,13 +450,18 @@ impl OlmMachine { &self, keys: &str, passphrase: &str, - _progress_listener: Box, + progress_listener: Box, ) -> Result { let keys = Cursor::new(keys); let keys = decrypt_key_export(keys, passphrase)?; - // TODO use the progress listener - let result = self.runtime.block_on(self.inner.import_keys(keys))?; + let listener = |progress: usize, total: usize| { + progress_listener.on_progress(progress as i32, total as i32) + }; + + let result = self + .runtime + .block_on(self.inner.import_keys(keys, listener))?; Ok(KeysImportResult { total: result.1 as i32, From aebfef8fa9894c584567387e00d67c1c2638a78b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Apr 2021 12:15:30 +0200 Subject: [PATCH 078/252] crypto: Remove a unused method --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 34e0aeb7a0..c5821081b1 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -313,14 +313,6 @@ internal class DefaultCryptoService @Inject constructor( } } - fun onSyncWillProcess(isInitialSync: Boolean) { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - if (isInitialSync) { - // TODO - } - } - } - private suspend fun internalStart() { if (isStarted.get() || isStarting.get()) { return From 5b761ef7d1d86d3700b125e22d13952a8f7392e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Apr 2021 12:15:47 +0200 Subject: [PATCH 079/252] crypto: Document the rust Device struct --- rust-sdk/src/device.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rust-sdk/src/device.rs b/rust-sdk/src/device.rs index c8557c5de9..606db76d61 100644 --- a/rust-sdk/src/device.rs +++ b/rust-sdk/src/device.rs @@ -2,12 +2,22 @@ use std::collections::HashMap; use matrix_sdk_crypto::Device as InnerDevice; +/// An E2EE capable Matrix device. pub struct Device { + /// The device owner. pub user_id: String, + /// The unique ID of the device. pub device_id: String, + /// The published public identity keys of the devices + /// + /// A map from the key type (e.g. curve25519) to the base64 encoded key. pub keys: HashMap, + /// The supported algorithms of the device. pub algorithms: Vec, + /// The human readable name of the device. pub display_name: Option, + /// A flag indicating if the device has been blocked, blocked devices don't + /// receive any room keys from us. pub is_blocked: bool, } From 3ba29b4ea9c90be766165c61d8236cbbe21439e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Apr 2021 12:16:09 +0200 Subject: [PATCH 080/252] crypto: Prepare outgoing to-device requests to be sent out --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index c5821081b1..ffb01a1cf1 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -771,7 +771,9 @@ internal class DefaultCryptoService @Inject constructor( // TODO this sends out mostly key requests, it's a // bit spammy as of now so it's disabled, needs to // be fixed on the Rust side. - async {} + async { + // sendToDevice(it) + } } else -> { async {} From 2805772d0ac2d9232bfe499081e758b3b88461a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Apr 2021 12:16:46 +0200 Subject: [PATCH 081/252] crypto: Notify the rest of the code about received room keys --- .../internal/crypto/DefaultCryptoService.kt | 51 +++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index ffb01a1cf1..91783e1dff 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -68,9 +68,11 @@ import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse +import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse @@ -161,6 +163,9 @@ internal class DefaultCryptoService @Inject constructor( private val outgointRequestsLock: Mutex = Mutex() private val roomKeyShareLocks: ConcurrentHashMap = ConcurrentHashMap() + // TODO does this need to be concurrent? + private val newSessionListeners = ArrayList() + suspend fun onStateEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) @@ -643,11 +648,50 @@ internal class DefaultCryptoService @Inject constructor( } } + private fun notifyRoomKeyReceival( + roomId: String, + sessionId: String, + ) { + // The sender key is actually unused since it's unimportant for megolm + // Our events don't contain the info so pass an empty string until we + // change the listener definition + val senderKey = "" + + newSessionListeners.forEach { + try { + it.onNewSession(roomId, senderKey, sessionId) + } catch (e: Throwable) { + } + } + } + suspend fun receiveSyncChanges( toDevice: ToDeviceSyncResponse?, deviceChanges: DeviceListResponse?, keyCounts: DeviceOneTimeKeysCountSyncResponse?) { - olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) + // Decrypt and handle our to-device events + val toDeviceEvents = olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) + + // Notify the our listeners about room keys so decryption is retried. + if (toDeviceEvents.events != null) { + for (event in toDeviceEvents.events) { + if (event.type == "m.room_key") { + val content = event.getClearContent().toModel() ?: continue + + val roomId = content.sessionId ?: continue + val sessionId = content.sessionId + + notifyRoomKeyReceival(roomId, sessionId) + } else if (event.type == "m.forwarded_room_key") { + val content = event.getClearContent().toModel() ?: continue + + val roomId = content.sessionId ?: continue + val sessionId = content.sessionId + + notifyRoomKeyReceival(roomId, sessionId) + } + } + } } private suspend fun preshareGroupSession(roomId: String, roomMembers: List) { @@ -946,12 +990,11 @@ internal class DefaultCryptoService @Inject constructor( } override fun addNewSessionListener(newSessionListener: NewSessionListener) { - // TODO we need to notify the listener when we receive a new inbound - // group session + if (!newSessionListeners.contains(newSessionListener)) newSessionListeners.add(newSessionListener) } override fun removeSessionListener(listener: NewSessionListener) { - // TODO + newSessionListeners.remove(listener) } /* ========================================================================================== * DEBUG INFO From 0afdcb35f1224dec2bbb3b74d80a9f2338391aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 14 Apr 2021 12:46:29 +0200 Subject: [PATCH 082/252] crypto: Clean up some log lines --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 91783e1dff..61c2dcf501 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -323,15 +323,13 @@ internal class DefaultCryptoService @Inject constructor( return } isStarting.set(true) - Timber.v("HELLLO WORLD STARTING CRYPTO") try { setRustLogger() olmMachine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) - - Timber.v("HELLLO WORLD STARTING $dataDir CRYPTO ${olmMachine?.identityKeys()}") + Timber.v("Successfully started up an Olm machine, identity keys: ${olmMachine?.identityKeys()}") } catch (throwable: Throwable) { - Timber.v("HELLLO WORLD FAILED CRYPTO $throwable") + Timber.v("Failed create an Olm machine: $throwable") } // Open the store From 91d28658fcce4d22f880376170279e80181e981f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 19 Apr 2021 18:03:52 +0200 Subject: [PATCH 083/252] crypto: Correctly decode the byte array when importing keys --- .../java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 3e46dac83f..9e9f3bdf94 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.crypto import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import java.io.File +import java.nio.charset.Charset import java.util.concurrent.ConcurrentHashMap import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -388,7 +389,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device */ @Throws(CryptoStoreErrorException::class) suspend fun importKeys(keys: ByteArray, passphrase: String, listener: ProgressListener?): ImportRoomKeysResult = withContext(Dispatchers.IO) { - var decodedKeys = keys.toString() + val decodedKeys = String(keys, Charset.defaultCharset()) var rustListener = CryptoProgressListener(listener) From 0db07011b176f6075f50690f28b628c6b9545eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 19 Apr 2021 19:25:56 +0200 Subject: [PATCH 084/252] crypto: Return our own device from the store as well The Kotlin side doesn't differentiate between our own device and other devices of our own user while the Rust side does, create and return our own device when it's requested from the store using trusted data. --- .../android/sdk/internal/crypto/OlmMachine.kt | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 9e9f3bdf94..bbe10ce068 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -22,8 +22,8 @@ import java.io.File import java.nio.charset.Charset import java.util.concurrent.ConcurrentHashMap import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext 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 @@ -47,7 +47,6 @@ import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType -import uniffi.olm.Sas as InnerSas import uniffi.olm.setLogger class CryptoLogger() : Logger { @@ -90,11 +89,15 @@ fun setRustLogger() { * Convert a Rust Device into a Kotlin CryptoDeviceInfo */ private fun toCryptoDeviceInfo(device: Device): CryptoDeviceInfo { + val keys = device.keys.map { (keyId, key) -> + "$keyId:$device.deviceId" to key + }.toMap() + return CryptoDeviceInfo( device.deviceId, device.userId, device.algorithms, - device.keys, + keys, // TODO pass the signatures here, do we need this, why should the // Kotlin side care about signatures? mapOf(), @@ -145,12 +148,18 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device } fun ownDevice(): CryptoDeviceInfo { + val deviceId = this.deviceId() + + val keys = this.identityKeys().map { (keyId, key) -> + "$keyId:$deviceId" to key + }.toMap() + return CryptoDeviceInfo( this.deviceId(), this.userId(), // TODO pass the algorithms here. listOf(), - this.identityKeys(), + keys, mapOf(), UnsignedDeviceInfo(), DeviceTrustLevel(false, true), @@ -409,9 +418,13 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device */ @Throws(CryptoStoreErrorException::class) suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? = withContext(Dispatchers.IO) { - when (val device: Device? = inner.getDevice(userId, deviceId)) { - null -> null - else -> toCryptoDeviceInfo(device) + // Our own device isn't part of our store on the rust side, return it + // using our ownDevice method + if (userId == userId() && deviceId == deviceId()) { + ownDevice() + } else { + val device = inner.getDevice(userId, deviceId) + if (device != null) toCryptoDeviceInfo(device) else null } } @@ -424,7 +437,14 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device */ @Throws(CryptoStoreErrorException::class) suspend fun getUserDevices(userId: String): List { - return inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) } + val ownDevice = ownDevice() + var devices = inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) }.toMutableList() + + // EA doesn't differentiate much between our own and other devices of + // while the rust-sdk does, append our own device here. + devices.add(ownDevice) + + return devices } suspend fun getUserDevicesMap(userIds: List): MXUsersDevicesMap { From 8bfb7a6e0c4f5d1deb9f7b414929faf3a986984b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Apr 2021 13:29:52 +0200 Subject: [PATCH 085/252] crypto: Connect the room key requesting to the rust side --- .../internal/crypto/DefaultCryptoService.kt | 18 +++++++++- .../android/sdk/internal/crypto/OlmMachine.kt | 10 ++++++ rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 35 ++++++++++++++++--- rust-sdk/src/olm.udl | 9 +++++ 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 61c2dcf501..9bae0f9a48 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -952,7 +952,23 @@ internal class DefaultCryptoService @Inject constructor( * @param event the event to decrypt again. */ override fun reRequestRoomKeyForEvent(event: Event) { - // TODO + cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { + val requestPair = olmMachine!!.requestRoomKey(event) + + if (requestPair.cancellation != null) { + when (requestPair.cancellation) { + is Request.ToDevice -> { + sendToDevice(requestPair.cancellation) + } + } + } + + when(requestPair.keyRequest) { + is Request.ToDevice -> { + sendToDevice(requestPair.keyRequest) + } + } + } } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index bbe10ce068..0a96122eee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -40,8 +40,10 @@ import org.matrix.android.sdk.internal.session.sync.model.DeviceOneTimeKeysCount 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.Device import uniffi.olm.DeviceLists +import uniffi.olm.KeyRequestPair import uniffi.olm.Logger import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener @@ -370,6 +372,14 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device } } + @Throws(DecryptionErrorException::class) + suspend fun requestRoomKey(event: Event): KeyRequestPair = withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val serializedEvent = adapter.toJson(event) + + inner.requestRoomKey(serializedEvent, event.roomId!!) + } + /** * Export all of our room keys. * diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 998182d793..99f01ad7f3 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -7,7 +7,7 @@ mod responses; pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{OlmMachine, Sas}; +pub use machine::{OlmMachine, Sas, KeyRequestPair}; pub use responses::{DeviceLists, KeysImportResult, Request, RequestType}; pub trait ProgressListener { diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 1344f1a0f8..7478000f44 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -47,6 +47,11 @@ pub struct Sas { pub request: Request, } +pub struct KeyRequestPair { + pub cancellation: Option, + pub key_request: Request, +} + impl OlmMachine { /// Create a new `OlmMachine` /// @@ -133,12 +138,13 @@ impl OlmMachine { /// [mark_request_as_sent()](#method.mark_request_as_sent) method. /// /// **Note**: This method call should be locked per call. - pub fn outgoing_requests(&self) -> Vec { - self.runtime - .block_on(self.inner.outgoing_requests()) + pub fn outgoing_requests(&self) -> Result, CryptoStoreError> { + Ok(self + .runtime + .block_on(self.inner.outgoing_requests())? .into_iter() .map(|r| r.into()) - .collect() + .collect()) } /// Mark a request that was sent to the server as sent. @@ -418,6 +424,27 @@ impl OlmMachine { }) } + pub fn request_room_key( + &self, + event: &str, + room_id: &str, + ) -> Result { + let event: SyncMessageEvent = serde_json::from_str(event)?; + let room_id = RoomId::try_from(room_id)?; + + let (cancel, request) = self + .runtime + .block_on(self.inner.request_room_key(&event, &room_id))?; + + let cancellation = cancel.map(|r| r.into()); + let key_request = request.into(); + + Ok(KeyRequestPair { + cancellation, + key_request, + }) + } + /// Export all of our room keys. /// /// # Arguments diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 6a711dfb21..615ad8c8e7 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -70,6 +70,11 @@ dictionary Sas { Request request; }; +dictionary KeyRequestPair { + Request? cancellation; + Request key_request; +}; + [Enum] interface Request { ToDevice(string request_id, string event_type, string body); @@ -98,6 +103,7 @@ interface OlmMachine { string receive_sync_changes([ByRef] string events, DeviceLists device_changes, record key_counts); + [Throws=CryptoStoreError] sequence outgoing_requests(); [Throws=CryptoStoreError] void mark_request_as_sent( @@ -125,6 +131,9 @@ interface OlmMachine { [Throws=CryptoStoreError] Sas start_verification([ByRef] Device device); + [Throws=DecryptionError] + KeyRequestPair request_room_key([ByRef] string event, [ByRef] string room_id); + [Throws=CryptoStoreError] string export_keys([ByRef] string passphrase, i32 rounds); [Throws=KeyImportError] From c5173dde71e15d87a4821eaff67a0b3df4d5001b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Apr 2021 14:32:43 +0200 Subject: [PATCH 086/252] crypto: Update the rust-sdk branch we're using --- rust-sdk/Cargo.toml | 4 ++-- rust-sdk/src/machine.rs | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 4a443166b6..7f0ab29e30 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -23,11 +23,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -branch = "encryption-info" +branch = "corroded-android" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -branch = "encryption-info" +branch = "corroded-android" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 7478000f44..a6e16e60c5 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -20,7 +20,7 @@ use matrix_sdk_common::{ events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent}, identifiers::{DeviceKeyAlgorithm, RoomId, UserId}, uuid::Uuid, - UInt, + IncomingResponse, UInt, }; use matrix_sdk_crypto::{ @@ -168,10 +168,18 @@ impl OlmMachine { let response = response_from_string(&response_body); let response: OwnedResponse = match request_type { - RequestType::KeysUpload => KeysUploadResponse::try_from(response).map(Into::into), - RequestType::KeysQuery => KeysQueryResponse::try_from(response).map(Into::into), - RequestType::ToDevice => ToDeviceResponse::try_from(response).map(Into::into), - RequestType::KeysClaim => KeysClaimResponse::try_from(response).map(Into::into), + RequestType::KeysUpload => { + KeysUploadResponse::try_from_http_response(response).map(Into::into) + } + RequestType::KeysQuery => { + KeysQueryResponse::try_from_http_response(response).map(Into::into) + } + RequestType::ToDevice => { + ToDeviceResponse::try_from_http_response(response).map(Into::into) + } + RequestType::KeysClaim => { + KeysClaimResponse::try_from_http_response(response).map(Into::into) + } } .expect("Can't convert json string to response"); From ed902fc42a259b4a61cb1a92e29d2c460658ec58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Apr 2021 14:33:01 +0200 Subject: [PATCH 087/252] crypto: Improve the startup log line --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 9bae0f9a48..b5b38ce63e 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -327,7 +327,9 @@ internal class DefaultCryptoService @Inject constructor( try { setRustLogger() olmMachine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) - Timber.v("Successfully started up an Olm machine, identity keys: ${olmMachine?.identityKeys()}") + Timber.v( + "## CRYPTO | Successfully started up an Olm machine for " + + "${userId}, ${deviceId}, identity keys: ${olmMachine?.identityKeys()}") } catch (throwable: Throwable) { Timber.v("Failed create an Olm machine: $throwable") } From 09c0ca10e553b403499b8ca12b66eeec3163f568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Apr 2021 14:33:43 +0200 Subject: [PATCH 088/252] crypto: Enable the sending of outgoing to-device requests --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index b5b38ce63e..61ca4fcf41 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -812,11 +812,8 @@ internal class DefaultCryptoService @Inject constructor( } } is Request.ToDevice -> { - // TODO this sends out mostly key requests, it's a - // bit spammy as of now so it's disabled, needs to - // be fixed on the Rust side. async { - // sendToDevice(it) + sendToDevice(it) } } else -> { From 389273d56a45284023eb4ef90872f628580bf7fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Apr 2021 14:34:32 +0200 Subject: [PATCH 089/252] crypto: Rename the share_group_session method --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 8 ++++---- .../org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 8 ++++---- rust-sdk/src/machine.rs | 2 +- rust-sdk/src/olm.udl | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 61ca4fcf41..390b3273b3 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -535,7 +535,7 @@ internal class DefaultCryptoService @Inject constructor( val t0 = System.currentTimeMillis() Timber.v("## CRYPTO | encryptEventContent() starts") runCatching { - preshareGroupSession(roomId, userIds) + preshareRoomKey(roomId, userIds) val content = encrypt(roomId, eventType, eventContent) Timber.v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms") MXEncryptEventContentResult(content, EventType.ENCRYPTED) @@ -694,7 +694,7 @@ internal class DefaultCryptoService @Inject constructor( } } - private suspend fun preshareGroupSession(roomId: String, roomMembers: List) { + private suspend fun preshareRoomKey(roomId: String, roomMembers: List) { keyClaimLock.withLock { val request = olmMachine!!.getMissingSessions(roomMembers) if (request != null) { @@ -711,7 +711,7 @@ internal class DefaultCryptoService @Inject constructor( keyShareLock.withLock { coroutineScope { - olmMachine!!.shareGroupSession(roomId, roomMembers).map { + olmMachine!!.shareRoomKey(roomId, roomMembers).map { when (it) { is Request.ToDevice -> { async { @@ -1077,7 +1077,7 @@ internal class DefaultCryptoService @Inject constructor( } runCatching { - preshareGroupSession(roomId, userIds) + preshareRoomKey(roomId, userIds) }.fold( { callback.onSuccess(Unit) }, { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 0a96122eee..8be469e481 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -262,7 +262,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * mark_request_as_sent() method. * * This method should be called every time before a call to - * share_group_session() is made. + * shareRoomKey() is made. * * @param users The list of users for which we would like to establish 1:1 * Olm sessions for. @@ -294,8 +294,8 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * @return The list of requests that need to be sent out. */ @Throws(CryptoStoreErrorException::class) - suspend fun shareGroupSession(roomId: String, users: List): List = withContext(Dispatchers.IO) { - inner.shareGroupSession(roomId, users) + suspend fun shareRoomKey(roomId: String, users: List): List = withContext(Dispatchers.IO) { + inner.shareRoomKey(roomId, users) } /** @@ -313,7 +313,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * using the [`get_missing_sessions()`](#method.get_missing_sessions) * method. This method call should be locked per call. * - * 2. Share a room key with all the room members using the share_group_session(). + * 2. Share a room key with all the room members using the shareRoomKey(). * This method call should be locked per room. * * 3. Encrypt the event using this method. diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index a6e16e60c5..7abc7615cc 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -315,7 +315,7 @@ impl OlmMachine { /// /// * `users` - The list of users which are considered to be members of the /// room and should receive the room key. - pub fn share_group_session( + pub fn share_room_key( &self, room_id: &str, users: Vec, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 615ad8c8e7..d7fb9b728e 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -126,7 +126,7 @@ interface OlmMachine { [Throws=CryptoStoreError] Request? get_missing_sessions(sequence users); [Throws=CryptoStoreError] - sequence share_group_session([ByRef] string room_id, sequence users); + sequence share_room_key([ByRef] string room_id, sequence users); [Throws=CryptoStoreError] Sas start_verification([ByRef] Device device); From 711e607fca0f752267c683b93341fd545c25272c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Apr 2021 14:34:54 +0200 Subject: [PATCH 090/252] crypto: Improve the docs a bit --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 1 + .../org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 6 +++--- rust-sdk/src/machine.rs | 9 +++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 390b3273b3..e957618127 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -867,6 +867,7 @@ internal class DefaultCryptoService @Inject constructor( * @param warn true to warn when some unknown devices are detected. */ override fun setWarnOnUnknownDevices(warn: Boolean) { + // TODO this doesn't seem to be used anymore? warnOnUnknownDevicesRepository.setWarnOnUnknownDevices(warn) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 8be469e481..ac5a027daa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -175,7 +175,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * After the request was sent out and a successful response was received * the response body should be passed back to the state machine using the - * mark_request_as_sent method. + * markRequestAsSent() method. * * @return the list of requests that needs to be sent to the homeserver */ @@ -259,7 +259,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * After the request was sent out and a successful response was received * the response body should be passed back to the state machine using the - * mark_request_as_sent() method. + * markRequestAsSent() method. * * This method should be called every time before a call to * shareRoomKey() is made. @@ -279,7 +279,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * After the request was sent out and a successful response was received * the response body should be passed back to the state machine using the - * mark_request_as_sent() method. + * markRequestAsSent() method. * * This method should be called every time before a call to * `encrypt()` with the given `room_id` is made. diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 7abc7615cc..4edf15d79d 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -432,6 +432,15 @@ impl OlmMachine { }) } + /// Request or re-request a room key that was used to encrypt the given + /// event. + /// + /// # Arguments + /// + /// * `event` - The undecryptable event that we would wish to request a room + /// key for. + /// + /// * `room_id` - The id of the room the event was sent to. pub fn request_room_key( &self, event: &str, From 326641a7e51f927eac1a6cfb20fce807cc9f50a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Apr 2021 14:40:58 +0200 Subject: [PATCH 091/252] crypto: Document the requestRoomKey method --- .../matrix/android/sdk/internal/crypto/OlmMachine.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index ac5a027daa..ecb632be8b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -372,6 +372,17 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device } } + /** + * Request the room key that was used to encrypt the given undecrypted + * event. + * + * @param event The that we're not able to decrypt and want to request a + * room key for. + * + * @return a key request pair, consisting of an optional key request + * cancellation and the key request itself. The cancellation *must* be sent + * out before the request, otherwise devices will ignore the key request. + */ @Throws(DecryptionErrorException::class) suspend fun requestRoomKey(event: Event): KeyRequestPair = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) From fe4abbbeefbb11175aab77dd8125c7332a9c08dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 27 Apr 2021 16:33:13 +0200 Subject: [PATCH 092/252] crypto: Fix a bunch of linter warnings --- .../internal/crypto/DefaultCryptoService.kt | 77 ++++++++----------- .../android/sdk/internal/crypto/OlmMachine.kt | 42 +++++----- 2 files changed, 52 insertions(+), 67 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index e957618127..fafd1c465b 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -160,7 +160,7 @@ internal class DefaultCryptoService @Inject constructor( // Locks for some of our operations private val keyClaimLock: Mutex = Mutex() - private val outgointRequestsLock: Mutex = Mutex() + private val outgoingRequestsLock: Mutex = Mutex() private val roomKeyShareLocks: ConcurrentHashMap = ConcurrentHashMap() // TODO does this need to be concurrent? @@ -182,7 +182,7 @@ internal class DefaultCryptoService @Inject constructor( } } - val gossipingBuffer = mutableListOf() + private val gossipingBuffer = mutableListOf() override fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback) { setDeviceNameTask @@ -217,9 +217,7 @@ internal class DefaultCryptoService @Inject constructor( return if (longFormat) "Rust SDK 0.3" else "0.3" } - override fun getMyDevice(): CryptoDeviceInfo { - return olmMachine!!.ownDevice() - } + override fun getMyDevice(): CryptoDeviceInfo = this.olmMachine!!.ownDevice() override fun fetchDevicesList(callback: MatrixCallback) { getDevicesTask @@ -280,15 +278,6 @@ internal class DefaultCryptoService @Inject constructor( return isStarted.get() } - /** - * Tells if the MXCrypto is starting. - * - * @return true if the crypto is starting - */ - fun isStarting(): Boolean { - return isStarting.get() - } - /** * Start the crypto module. * Device keys will be uploaded, then one time keys if there are not enough on the homeserver @@ -326,10 +315,10 @@ internal class DefaultCryptoService @Inject constructor( try { setRustLogger() - olmMachine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) + this.olmMachine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + - "${userId}, ${deviceId}, identity keys: ${olmMachine?.identityKeys()}") + "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") } catch (throwable: Throwable) { Timber.v("Failed create an Olm machine: $throwable") } @@ -401,7 +390,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) { runBlocking { - olmMachine?.getDevice(userId, deviceId) + this@DefaultCryptoService.olmMachine?.getDevice(userId, deviceId) } } else { null @@ -410,7 +399,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getCryptoDeviceInfo(userId: String): List { return runBlocking { - olmMachine?.getUserDevices(userId) ?: listOf() + this@DefaultCryptoService.olmMachine?.getUserDevices(userId) ?: listOf() } } @@ -420,7 +409,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getLiveCryptoDeviceInfo(userIds: List): LiveData> { return runBlocking { - olmMachine?.getLiveDevices(userIds) ?: LiveDevice(userIds, deviceObserver) + this@DefaultCryptoService.olmMachine?.getLiveDevices(userIds) ?: LiveDevice(userIds, deviceObserver) } } @@ -561,11 +550,10 @@ internal class DefaultCryptoService @Inject constructor( */ @Throws(MXCryptoError::class) override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { - val decrypted = runBlocking { + + return runBlocking { olmMachine!!.decryptRoomEvent(event) } - - return decrypted } /** @@ -670,22 +658,22 @@ internal class DefaultCryptoService @Inject constructor( deviceChanges: DeviceListResponse?, keyCounts: DeviceOneTimeKeysCountSyncResponse?) { // Decrypt and handle our to-device events - val toDeviceEvents = olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) + val toDeviceEvents = this.olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) // Notify the our listeners about room keys so decryption is retried. if (toDeviceEvents.events != null) { - for (event in toDeviceEvents.events) { + toDeviceEvents.events.forEach { event -> if (event.type == "m.room_key") { - val content = event.getClearContent().toModel() ?: continue + val content = event.getClearContent().toModel() ?: return@forEach - val roomId = content.sessionId ?: continue + val roomId = content.sessionId ?: return@forEach val sessionId = content.sessionId notifyRoomKeyReceival(roomId, sessionId) } else if (event.type == "m.forwarded_room_key") { - val content = event.getClearContent().toModel() ?: continue + val content = event.getClearContent().toModel() ?: return@forEach - val roomId = content.sessionId ?: continue + val roomId = content.sessionId ?: return@forEach val sessionId = content.sessionId notifyRoomKeyReceival(roomId, sessionId) @@ -696,13 +684,14 @@ internal class DefaultCryptoService @Inject constructor( private suspend fun preshareRoomKey(roomId: String, roomMembers: List) { keyClaimLock.withLock { - val request = olmMachine!!.getMissingSessions(roomMembers) + val request = this.olmMachine!!.getMissingSessions(roomMembers) + // This request can only be a keys claim request. if (request != null) { - // This request can only be a keys claim request. when (request) { is Request.KeysClaim -> { claimKeys(request) } + else -> {} } } } @@ -711,7 +700,7 @@ internal class DefaultCryptoService @Inject constructor( keyShareLock.withLock { coroutineScope { - olmMachine!!.shareRoomKey(roomId, roomMembers).map { + this@DefaultCryptoService.olmMachine!!.shareRoomKey(roomId, roomMembers).map { when (it) { is Request.ToDevice -> { async { @@ -745,14 +734,14 @@ internal class DefaultCryptoService @Inject constructor( val response = uploadKeysTask.execute(request) val adapter = MoshiProvider .providesMoshi() - .adapter(KeysUploadResponse::class.java) + .adapter(KeysUploadResponse::class.java) - val json_response = adapter.toJson(response)!! + val jsonResponse = adapter.toJson(response)!! - olmMachine!!.markRequestAsSent( + this.olmMachine!!.markRequestAsSent( outgoingRequest.requestId, RequestType.KEYS_UPLOAD, - json_response + jsonResponse ) } @@ -761,9 +750,9 @@ internal class DefaultCryptoService @Inject constructor( try { val response = downloadKeysForUsersTask.execute(params) - val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) - val json_response = adapter.toJson(response)!! - olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_QUERY, json_response) + val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) + val jsonResponse = adapter.toJson(response)!! + this.olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_QUERY, jsonResponse) } catch (throwable: Throwable) { Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") } @@ -790,14 +779,14 @@ internal class DefaultCryptoService @Inject constructor( val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) val adapter = MoshiProvider .providesMoshi() - .adapter(KeysClaimResponse::class.java) - val json_response = adapter.toJson(response)!! + .adapter(KeysClaimResponse::class.java) + val jsonResponse = adapter.toJson(response)!! - olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, json_response) + olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, jsonResponse) } private suspend fun sendOutgoingRequests() { - outgointRequestsLock.withLock { + outgoingRequestsLock.withLock { coroutineScope { olmMachine!!.outgoingRequests().map { when (it) { @@ -995,9 +984,9 @@ internal class DefaultCryptoService @Inject constructor( if (forceDownload) { // TODO replicate the logic from the device list manager // where we would download the fresh info from the server. - olmMachine?.getUserDevicesMap(userIds) ?: MXUsersDevicesMap() + this@DefaultCryptoService.olmMachine?.getUserDevicesMap(userIds) ?: MXUsersDevicesMap() } else { - olmMachine?.getUserDevicesMap(userIds) ?: MXUsersDevicesMap() + this@DefaultCryptoService.olmMachine?.getUserDevicesMap(userIds) ?: MXUsersDevicesMap() } }.foldToCallback(callback) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index ecb632be8b..e234c3cd0a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -51,7 +51,7 @@ import uniffi.olm.Request import uniffi.olm.RequestType import uniffi.olm.setLogger -class CryptoLogger() : Logger { +class CryptoLogger : Logger { override fun log(logLine: String) { Timber.d(logLine) } @@ -68,11 +68,9 @@ private class CryptoProgressListener(listener: ProgressListener?) : RustProgress } internal class LiveDevice( - userIds: List, - observer: DeviceUpdateObserver + internal var userIds: List, + private var observer: DeviceUpdateObserver ) : MutableLiveData>() { - internal var userIds: List = userIds - private var observer: DeviceUpdateObserver = observer override fun onActive() { observer.addDeviceUpdateListener(this) @@ -105,18 +103,18 @@ private fun toCryptoDeviceInfo(device: Device): CryptoDeviceInfo { mapOf(), UnsignedDeviceInfo(device.displayName), // TODO pass trust levels here - DeviceTrustLevel(false, false), + DeviceTrustLevel(crossSigningVerified = false, locallyVerified = false), device.isBlocked, // TODO null ) } -internal class DeviceUpdateObserver() { +internal class DeviceUpdateObserver { internal val listeners = ConcurrentHashMap>() fun addDeviceUpdateListener(device: LiveDevice) { - listeners.set(device, device.userIds) + listeners[device] = device.userIds } fun removeDeviceUpdateListener(device: LiveDevice) { @@ -164,7 +162,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device keys, mapOf(), UnsignedDeviceInfo(), - DeviceTrustLevel(false, true), + DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), false, null ) @@ -226,14 +224,14 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device deviceChanges: DeviceListResponse?, keyCounts: DeviceOneTimeKeysCountSyncResponse? ): ToDeviceSyncResponse = withContext(Dispatchers.IO) { - var counts: MutableMap = mutableMapOf() + val counts: MutableMap = mutableMapOf() if (keyCounts?.signedCurve25519 != null) { - counts.put("signed_curve25519", keyCounts.signedCurve25519) + counts["signed_curve25519"] = keyCounts.signedCurve25519 } val devices = DeviceLists(deviceChanges?.changed ?: listOf(), deviceChanges?.left ?: listOf()) - val adapter = MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) + val adapter = MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! adapter.fromJson(inner.receiveSyncChanges(events, devices, counts))!! @@ -351,7 +349,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device */ @Throws(MXCryptoError::class) suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(Dispatchers.IO) { - val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) val serializedEvent = adapter.toJson(event) try { @@ -385,7 +383,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device */ @Throws(DecryptionErrorException::class) suspend fun requestRoomKey(event: Event): KeyRequestPair = withContext(Dispatchers.IO) { - val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) val serializedEvent = adapter.toJson(event) inner.requestRoomKey(serializedEvent, event.roomId!!) @@ -421,9 +419,9 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device suspend fun importKeys(keys: ByteArray, passphrase: String, listener: ProgressListener?): ImportRoomKeysResult = withContext(Dispatchers.IO) { val decodedKeys = String(keys, Charset.defaultCharset()) - var rustListener = CryptoProgressListener(listener) + val rustListener = CryptoProgressListener(listener) - var result = inner.importKeys(decodedKeys, passphrase, rustListener) + val result = inner.importKeys(decodedKeys, passphrase, rustListener) ImportRoomKeysResult(result.total, result.imported) } @@ -459,7 +457,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device @Throws(CryptoStoreErrorException::class) suspend fun getUserDevices(userId: String): List { val ownDevice = ownDevice() - var devices = inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) }.toMutableList() + val devices = inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) }.toMutableList() // EA doesn't differentiate much between our own and other devices of // while the rust-sdk does, append our own device here. @@ -485,7 +483,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device /** * Get all the devices of multiple users. * - * @param userId The ids of the device owners. + * @param userIds The ids of the device owners. * * @return The list of Devices or an empty list if there aren't any. */ @@ -516,14 +514,14 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * The live version will update the list of devices if some of the data * changes, or if new devices arrive for a certain user. * - * @param userId The ids of the device owners. + * @param userIds The ids of the device owners. * * @return The list of Devices or an empty list if there aren't any. */ suspend fun getLiveDevices(userIds: List): LiveData> { val plainDevices = getUserDevices(userIds) val devices = LiveDevice(userIds, deviceUpdateObserver) - devices.setValue(plainDevices) + devices.value = plainDevices return devices } @@ -533,8 +531,6 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device */ @Throws(CryptoStoreErrorException::class) fun discardRoomKey(roomId: String) { - runBlocking { - inner.discardRoomKey(roomId) - } + runBlocking { inner.discardRoomKey(roomId) } } } From 49fa34e997771fe74170fa03153d5663ab011363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 29 Apr 2021 13:05:08 +0200 Subject: [PATCH 093/252] rust: Switch to the new encryption info branch of the rust-sdk --- rust-sdk/Cargo.toml | 5 +++-- rust-sdk/src/machine.rs | 39 +++++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 7f0ab29e30..c1c1d6b6a5 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -9,6 +9,7 @@ crate-type = ["cdylib", "lib"] name = "matrix_crypto" [dependencies] +serde = "1.0.64" serde_json = "1.0.64" http = "0.2.4" @@ -23,11 +24,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -branch = "corroded-android" +branch = "encryption-info-v2" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -branch = "corroded-android" +branch = "encryption-info-v2" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 4edf15d79d..7e67befe05 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -4,7 +4,8 @@ use std::{ io::Cursor, }; -use serde_json::{json, value::RawValue}; +use serde::{Deserialize, Serialize}; +use serde_json::value::RawValue; use tokio::runtime::Runtime; use matrix_sdk_common::{ @@ -16,8 +17,11 @@ use matrix_sdk_common::{ sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, to_device::send_event_to_device::Response as ToDeviceResponse, }, - deserialized_responses::events::{AlgorithmInfo, SyncMessageEvent}, - events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent}, + deserialized_responses::AlgorithmInfo, + events::{ + room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent, + SyncMessageEvent, + }, identifiers::{DeviceKeyAlgorithm, RoomId, UserId}, uuid::Uuid, IncomingResponse, UInt, @@ -47,8 +51,13 @@ pub struct Sas { pub request: Request, } +/// A pair of outgoing room key requests, both of those are sendToDevice +/// requests. pub struct KeyRequestPair { + /// The optional cancellation, this is None if no previous key request was + /// sent out for this key, thus it doesn't need to be cancelled. pub cancellation: Option, + /// The actual key request. pub key_request: Request, } @@ -228,7 +237,7 @@ impl OlmMachine { .runtime .block_on( self.inner - .receive_sync_changes(&events, &device_changes, &key_counts), + .receive_sync_changes(events, &device_changes, &key_counts), ) .unwrap(); @@ -398,6 +407,17 @@ impl OlmMachine { event: &str, room_id: &str, ) -> Result { + // Element Android wants only the content and the type and will create a + // decrypted event with those two itself, this struct makes sure we + // throw away all the other fields. + #[derive(Deserialize, Serialize)] + struct Event<'a> { + #[serde(rename = "type")] + event_type: String, + #[serde(borrow)] + content: &'a RawValue, + } + let event: SyncMessageEvent = serde_json::from_str(event)?; let room_id = RoomId::try_from(room_id)?; @@ -406,15 +426,10 @@ impl OlmMachine { .block_on(self.inner.decrypt_room_event(&event, &room_id))?; let encryption_info = decrypted - .encryption_info() + .encryption_info .expect("Decrypted event didn't contain any encryption info"); - let content = decrypted.content(); - - let clear_event = json!({ - "type": content.event_type(), - "content": content, - }); + let event_json: Event = serde_json::from_str(decrypted.event.json().get())?; Ok(match &encryption_info.algorithm_info { AlgorithmInfo::MegolmV1AesSha2 { @@ -422,7 +437,7 @@ impl OlmMachine { sender_claimed_keys, forwarding_curve25519_key_chain, } => DecryptedEvent { - clear_event: serde_json::to_string(&clear_event)?, + clear_event: serde_json::to_string(&event_json)?, sender_curve25519_key: curve25519_key.to_owned(), claimed_ed25519_key: sender_claimed_keys .get(&DeviceKeyAlgorithm::Ed25519) From 688c1671660c703f715f65aa8a293c1de546bf64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 25 May 2021 16:13:12 +0200 Subject: [PATCH 094/252] rust: Upgrade our deps --- rust-sdk/Cargo.toml | 18 +++++++++--------- rust-sdk/src/machine.rs | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index c1c1d6b6a5..b0702e9955 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -9,14 +9,14 @@ crate-type = ["cdylib", "lib"] name = "matrix_crypto" [dependencies] -serde = "1.0.64" +serde = "1.0.126" serde_json = "1.0.64" http = "0.2.4" -thiserror = "1.0.24" -tracing = "0.1.25" -tracing-subscriber = "0.2.17" -uniffi = "0.8.0" +thiserror = "1.0.25" +tracing = "0.1.26" +tracing-subscriber = "0.2.18" +uniffi = "0.9.0" [dependencies.js_int] version = "0.2.0" @@ -24,17 +24,17 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -branch = "encryption-info-v2" +rev = "e058191b992f261a1a848b7ec521badf173881d6" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -branch = "encryption-info-v2" +rev = "e058191b992f261a1a848b7ec521badf173881d6" features = ["sled_cryptostore"] [dependencies.tokio] -version = "1.4.0" +version = "1.6.0" default_features = false features = ["rt-multi-thread"] [build-dependencies] -uniffi_build = "0.8.0" +uniffi_build = "0.9.0" diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 7e67befe05..e9ac6d3614 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -386,7 +386,7 @@ impl OlmMachine { let room_id = RoomId::try_from(room_id)?; let content: Box = serde_json::from_str(content)?; - let content = AnyMessageEventContent::from_parts(event_type, content)?; + let content = AnyMessageEventContent::from_parts(event_type, &content)?; let encrypted_content = self .runtime .block_on(self.inner.encrypt(&room_id, content)) From a144b1f7b5b1dc4af18382760368781aa755ef36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 15 Jun 2021 13:16:30 +0200 Subject: [PATCH 095/252] rust: Fix the build and update our deps --- .../internal/crypto/DefaultCryptoService.kt | 13 +- rust-sdk/Cargo.toml | 12 +- rust-sdk/src/error.rs | 2 +- rust-sdk/src/machine.rs | 119 ++++++++++++++---- rust-sdk/src/olm.udl | 6 +- rust-sdk/src/responses.rs | 4 +- 6 files changed, 117 insertions(+), 39 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index c3971058d3..aa307d7c8e 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -933,17 +933,20 @@ internal class DefaultCryptoService @Inject constructor( cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { val requestPair = olmMachine!!.requestRoomKey(event) - if (requestPair.cancellation != null) { - when (requestPair.cancellation) { + val cancellation = requestPair.cancellation + val request = requestPair.keyRequest + + if (cancellation != null) { + when (cancellation) { is Request.ToDevice -> { - sendToDevice(requestPair.cancellation) + sendToDevice(cancellation) } } } - when(requestPair.keyRequest) { + when(request) { is Request.ToDevice -> { - sendToDevice(requestPair.keyRequest) + sendToDevice(request) } } } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index b0702e9955..138c937c0c 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -16,7 +16,7 @@ http = "0.2.4" thiserror = "1.0.25" tracing = "0.1.26" tracing-subscriber = "0.2.18" -uniffi = "0.9.0" +uniffi = "0.12.0" [dependencies.js_int] version = "0.2.0" @@ -24,11 +24,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "e058191b992f261a1a848b7ec521badf173881d6" +branch = "verification-qr" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "e058191b992f261a1a848b7ec521badf173881d6" +branch = "verification-qr" features = ["sled_cryptostore"] [dependencies.tokio] @@ -36,5 +36,9 @@ version = "1.6.0" default_features = false features = ["rt-multi-thread"] +[dependencies.ruma] +version = "*" +features = ["client-api"] + [build-dependencies] -uniffi_build = "0.9.0" +uniffi_build = "0.12.0" diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index 4a17011208..aa24c303b2 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -1,4 +1,4 @@ -use matrix_sdk_common::identifiers::Error as RumaIdentifierError; +use ruma::identifiers::Error as RumaIdentifierError; use matrix_sdk_crypto::{ store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError, }; diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index e9ac6d3614..4c6e42d02f 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -4,31 +4,33 @@ use std::{ io::Cursor, }; -use serde::{Deserialize, Serialize}; -use serde_json::value::RawValue; -use tokio::runtime::Runtime; - -use matrix_sdk_common::{ - api::r0::{ - keys::{ - claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, - upload_keys::Response as KeysUploadResponse, +use js_int::UInt; +use ruma::{ + api::{ + client::r0::{ + keys::{ + claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, + upload_keys::Response as KeysUploadResponse, + }, + sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, + to_device::send_event_to_device::Response as ToDeviceResponse, }, - sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, - to_device::send_event_to_device::Response as ToDeviceResponse, + IncomingResponse, }, - deserialized_responses::AlgorithmInfo, events::{ room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent, SyncMessageEvent, }, - identifiers::{DeviceKeyAlgorithm, RoomId, UserId}, - uuid::Uuid, - IncomingResponse, UInt, + DeviceKeyAlgorithm, RoomId, UserId, }; +use serde::{Deserialize, Serialize}; +use serde_json::value::RawValue; +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, }; use crate::{ @@ -48,7 +50,24 @@ pub struct Sas { pub other_user_id: String, pub other_device_id: String, pub flow_id: String, - pub request: Request, + pub is_cancelled: bool, + pub is_done: bool, + pub can_be_presented: bool, + pub timed_out: bool, +} + +impl From for Sas { + fn from(sas: InnerSas) -> Self { + Self { + other_user_id: sas.other_user_id().to_string(), + other_device_id: sas.other_device_id().to_string(), + flow_id: sas.flow_id().as_str().to_owned(), + is_cancelled: sas.is_cancelled(), + is_done: sas.is_done(), + can_be_presented: sas.can_be_presented(), + timed_out: sas.timed_out(), + } + } } /// A pair of outgoing room key requests, both of those are sendToDevice @@ -207,7 +226,7 @@ impl OlmMachine { /// # Arguments /// /// * `events` - A serialized array of to-device events we received in the - /// current sync resposne. + /// current sync response. /// /// * `device_changes` - The list of devices that have changed in some way /// since the previous sync. @@ -350,7 +369,7 @@ impl OlmMachine { /// **Note**: A room key needs to be shared with the group of users that are /// members in the given room. If this is not done this method will panic. /// - /// The usual flow to encrypt an evnet using this state machine is as + /// The usual flow to encrypt an event using this state machine is as /// follows: /// /// 1. Get the one-time key claim request to establish 1:1 Olm sessions for @@ -539,6 +558,15 @@ impl OlmMachine { Ok(()) } + pub fn get_verification(&self, flow_id: &str) -> Option { + todo!() + // self.inner.get_verification(flow_id).map(|s| s.into()) + } + + pub fn request_verification(&self) { + todo!() + } + pub fn start_verification(&self, device: &Device) -> Result { let user_id = UserId::try_from(device.user_id.clone())?; let device_id = device.device_id.as_str().into(); @@ -547,13 +575,54 @@ impl OlmMachine { .block_on(self.inner.get_device(&user_id, device_id))? .unwrap(); - let (sas, request) = self.runtime.block_on(device.start_verification())?; + // TODO we need to return the request as well. + let (sas, _) = self.runtime.block_on(device.start_verification())?; - Ok(Sas { - other_user_id: sas.other_user_id().to_string(), - other_device_id: sas.other_device_id().to_string(), - flow_id: sas.flow_id().as_str().to_owned(), - request: request.into(), - }) + Ok(sas.into()) + } + + pub fn accept_verification(&self, flow_id: &str) -> Option { + todo!() + // self.inner + // .get_verification(flow_id) + // .and_then(|s| s.accept().map(|r| r.into())) + } + + pub fn cancel_verification(&self, flow_id: &str) -> Option { + todo!() + // self.inner + // .get_verification(flow_id) + // .and_then(|s| s.cancel().map(|r| r.into())) + } + + pub fn confirm_verification( + &self, + flow_id: &str, + ) -> Result, CryptoStoreError> { + todo!() + // let sas = self.inner.get_verification(flow_id); + + // if let Some(sas) = sas { + // let (request, _) = self.runtime.block_on(sas.confirm())?; + // Ok(request.map(|r| r.into())) + // } else { + // Ok(None) + // } + } + + pub fn get_emoji_index(&self, flow_id: &str) -> Option> { + todo!() + // self.inner.get_verification(flow_id).and_then(|s| { + // s.emoji_index() + // .map(|v| v.iter().map(|i| (*i).into()).collect()) + // }) + } + + pub fn get_decimals(&self, flow_id: &str) -> Option> { + todo!() + // self.inner.get_verification(flow_id).and_then(|s| { + // s.decimals() + // .map(|v| [v.0.into(), v.1.into(), v.2.into()].to_vec()) + // }) } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index d7fb9b728e..6f2b42e626 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -67,7 +67,10 @@ dictionary Sas { string other_user_id; string other_device_id; string flow_id; - Request request; + boolean is_done; + boolean is_cancelled; + boolean can_be_presented; + boolean timed_out; }; dictionary KeyRequestPair { @@ -90,7 +93,6 @@ enum RequestType { "ToDevice", }; -[Threadsafe] interface OlmMachine { [Throws=MachineCreationError] constructor([ByRef] string user_id, [ByRef] string device_id, [ByRef] string path); diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index d7d52fef98..bda045debf 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -3,8 +3,8 @@ use std::{collections::HashMap, convert::TryFrom}; use http::Response; use serde_json::json; -use matrix_sdk_common::{ - api::r0::{ +use ruma::{ + api::client::r0::{ keys::{ claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, upload_keys::Response as KeysUploadResponse, From 5ad596c3bc714bcb681268726a0bc49991b768c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 7 May 2021 19:36:37 +0200 Subject: [PATCH 096/252] crypto: Bind more verification methods and types --- .../android/sdk/internal/crypto/OlmMachine.kt | 76 +++++++++++++++++++ rust-sdk/src/error.rs | 2 +- rust-sdk/src/lib.rs | 6 +- rust-sdk/src/machine.rs | 17 ++--- rust-sdk/src/olm.udl | 15 ++++ rust-sdk/src/responses.rs | 43 ++++++++++- 6 files changed, 144 insertions(+), 15 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index e234c3cd0a..d62d880676 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -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 { + val emojiIndex = this.machine.getEmojiIndex(this.inner.flowId) + + return if (emojiIndex != null) { + emojiIndex.map { getEmojiForCode(it) } + } else { + listOf() + } + } + + fun decimals(): List? { + 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) + } + } } diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index aa24c303b2..1d0128a809 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -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 { diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 99f01ad7f3..e7ac395fd9 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -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); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 4c6e42d02f..028169bff1 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -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 { 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))? diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 6f2b42e626..cdf5c2d7c4 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -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 share_room_key([ByRef] string room_id, sequence 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? get_emoji_index([ByRef] string flow_id); + sequence? get_decimals([ByRef] string flow_id); [Throws=DecryptionError] KeyRequestPair request_room_key([ByRef] string event, [ByRef] string room_id); diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index bda045debf..4cecd4981b 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -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 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 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"), } } } From c0bac697339558cbef1a3161a41fd21fdbf5ae03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 16 Jun 2021 13:21:37 +0200 Subject: [PATCH 097/252] crypto-service: Use constants when we check the event type --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index aa307d7c8e..cf31327e18 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -663,14 +663,14 @@ internal class DefaultCryptoService @Inject constructor( // Notify the our listeners about room keys so decryption is retried. if (toDeviceEvents.events != null) { toDeviceEvents.events.forEach { event -> - if (event.type == "m.room_key") { + if (event.type == EventType.ROOM_KEY) { val content = event.getClearContent().toModel() ?: return@forEach val roomId = content.sessionId ?: return@forEach val sessionId = content.sessionId notifyRoomKeyReceival(roomId, sessionId) - } else if (event.type == "m.forwarded_room_key") { + } else if (event.type == EventType.FORWARDED_ROOM_KEY) { val content = event.getClearContent().toModel() ?: return@forEach val roomId = content.sessionId ?: return@forEach From e46578a087f22f6ef9191ef723609428c0120c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 17 Jun 2021 13:36:44 +0200 Subject: [PATCH 098/252] rust: Bind the initial verification request type and methods --- rust-sdk/Cargo.toml | 4 +- rust-sdk/src/lib.rs | 33 ++++++++++++++- rust-sdk/src/machine.rs | 93 ++++++++++++++++++++++++++++++++++++++--- rust-sdk/src/olm.udl | 36 ++++++++++++++++ 4 files changed, 158 insertions(+), 8 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 138c937c0c..d70e7e4418 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -24,11 +24,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -branch = "verification-qr" +rev = "0fb3dedd1cd3b0766fa7378754480d52d38e8ef2" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -branch = "verification-qr" +rev = "0fb3dedd1cd3b0766fa7378754480d52d38e8ef2" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index e7ac395fd9..c1c37f3455 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -7,7 +7,7 @@ mod responses; pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{KeyRequestPair, OlmMachine, Sas}; +pub use machine::{KeyRequestPair, OlmMachine, Sas, VerificationRequest}; pub use responses::{ DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, }; @@ -30,4 +30,35 @@ pub struct DecryptedEvent { pub forwarding_curve25519_chain: Vec, } +pub enum CancelCode { + User, + Timeout, + UnknownTransaction, + UnknownMethod, + UnexpectedMessage, + KeyMismatch, + UserMismatch, + InvalidMessage, + Accepted, +} + +impl From for CancelCode { + fn from(c: ruma::events::key::verification::cancel::CancelCode) -> Self { + use ruma::events::key::verification::cancel::CancelCode as RumaCancelCode; + + match c { + RumaCancelCode::User => Self::User, + RumaCancelCode::Timeout => Self::Timeout, + RumaCancelCode::UnknownTransaction => Self::UnknownTransaction, + RumaCancelCode::UnknownMethod => Self::UnknownMethod, + RumaCancelCode::UnexpectedMessage => Self::UnexpectedMessage, + RumaCancelCode::KeyMismatch => Self::KeyMismatch, + RumaCancelCode::UserMismatch => Self::UserMismatch, + RumaCancelCode::InvalidMessage => Self::InvalidMessage, + RumaCancelCode::Accepted => Self::Accepted, + RumaCancelCode::_Custom(_) => Self::User, + } + } +} + include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 028169bff1..4cd216977a 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -18,8 +18,8 @@ use ruma::{ IncomingResponse, }, events::{ - room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent, - SyncMessageEvent, + key::verification::VerificationMethod, room::encrypted::EncryptedEventContent, + AnyMessageEventContent, EventContent, SyncMessageEvent, }, DeviceKeyAlgorithm, RoomId, UserId, }; @@ -30,14 +30,14 @@ 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, - Sas as InnerSas, + Sas as InnerSas, VerificationRequest as InnerVerificationRequest, }; use crate::{ error::{CryptoStoreError, DecryptionError, MachineCreationError}, responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, - DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, - Request, RequestType, + CancelCode, DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, + ProgressListener, Request, RequestType, }; /// A high level state machine that handles E2EE for Matrix. @@ -70,6 +70,44 @@ impl From for Sas { } } +pub struct VerificationRequest { + pub other_user_id: String, + pub other_device_id: Option, + pub flow_id: String, + pub is_cancelled: bool, + pub is_done: bool, + pub is_ready: bool, + pub room_id: Option, + pub cancel_code: Option, + pub we_started: bool, + pub is_passive: bool, + pub their_methods: Option>, + pub our_methods: Option>, +} + +impl From for VerificationRequest { + fn from(v: InnerVerificationRequest) -> Self { + Self { + other_user_id: v.other_user().to_string(), + other_device_id: v.other_device_id().map(|d| d.to_string()), + flow_id: v.flow_id().as_str().to_owned(), + is_cancelled: v.is_cancelled(), + is_done: v.is_done(), + is_ready: v.is_ready(), + room_id: v.room_id().map(|r| r.to_string()), + cancel_code: v.cancel_code().map(|c| c.clone().into()), + we_started: v.we_started(), + is_passive: v.is_passive(), + their_methods: v + .their_supported_methods() + .map(|v| v.into_iter().map(|m| m.to_string()).collect()), + our_methods: v + .our_supported_methods() + .map(|v| v.into_iter().map(|m| m.to_string()).collect()), + } + } +} + /// A pair of outgoing room key requests, both of those are sendToDevice /// requests. pub struct KeyRequestPair { @@ -556,6 +594,51 @@ impl OlmMachine { Ok(()) } + pub fn get_verification_requests(&self, user_id: &str) -> Vec { + let user_id = if let Ok(user_id) = UserId::try_from(user_id) { + user_id + } else { + return vec![]; + }; + + self.inner + .get_verification_requests(&user_id) + .into_iter() + .map(|v| v.into()) + .collect() + } + + pub fn get_verification_request( + &self, + user_id: &str, + flow_id: &str, + ) -> Option { + let user_id = UserId::try_from(user_id).ok()?; + + self.inner + .get_verification_request(&user_id, flow_id) + .map(|v| v.into()) + } + + pub fn accept_verification_request( + &self, + user_id: &str, + flow_id: &str, + methods: Vec, + ) -> Option { + let user_id = UserId::try_from(user_id).ok()?; + let methods = methods + .into_iter() + .map(|m| VerificationMethod::from(m)) + .collect(); + + if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { + verification.accept_with_methods(methods).map(|r| r.into()) + } else { + None + } + } + pub fn get_verification(&self, flow_id: &str) -> Option { todo!() // self.inner.get_verification(flow_id).map(|s| s.into()) diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index cdf5c2d7c4..01b0b84135 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -73,6 +73,34 @@ dictionary Sas { boolean timed_out; }; +dictionary VerificationRequest { + string other_user_id; + string? other_device_id; + string flow_id; + boolean is_cancelled; + boolean is_done; + boolean is_ready; + boolean we_started; + boolean is_passive; + string? room_id; + CancelCode? cancel_code; + sequence? their_methods; + sequence? our_methods; + +}; + +enum CancelCode { + "User", + "Timeout", + "UnknownTransaction", + "UnknownMethod", + "UnexpectedMessage", + "KeyMismatch", + "UserMismatch", + "InvalidMessage", + "Accepted", +}; + dictionary KeyRequestPair { Request? cancellation; Request key_request; @@ -136,8 +164,16 @@ interface OlmMachine { [Throws=CryptoStoreError] sequence share_room_key([ByRef] string room_id, sequence users); + sequence get_verification_requests([ByRef] string user_id); + VerificationRequest? get_verification_request([ByRef] string user_id, [ByRef] string flow_id); Sas? get_verification([ByRef] string flow_id); + OutgoingVerificationRequest? accept_verification_request( + [ByRef] string user_id, + [ByRef] string flow_id, + sequence methods + ); + [Throws=CryptoStoreError] Sas start_verification([ByRef] Device device); [Throws=CryptoStoreError] From a4e1a5bbcb12730421954697366e488bf7dac448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 17 Jun 2021 13:38:30 +0200 Subject: [PATCH 099/252] crypto: Initial support to answer to-device verification requests --- .../internal/crypto/DefaultCryptoService.kt | 44 +- .../android/sdk/internal/crypto/OlmMachine.kt | 567 +++++++++++------- .../verification/RustVerificationService.kt | 326 ++++++++++ 3 files changed, 724 insertions(+), 213 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index cf31327e18..37e1288525 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -49,6 +49,7 @@ import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService 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.EventType @@ -86,7 +87,7 @@ import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask -import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService +import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.di.SessionFilesDirectory @@ -131,9 +132,6 @@ internal class DefaultCryptoService @Inject constructor( private val mxCryptoConfig: MXCryptoConfig, // The key backup service. private val keysBackupService: DefaultKeysBackupService, - // The verification service. - private val verificationService: DefaultVerificationService, - private val crossSigningService: DefaultCrossSigningService, // Actions private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository, @@ -156,6 +154,9 @@ internal class DefaultCryptoService @Inject constructor( private val isStarting = AtomicBoolean(false) private val isStarted = AtomicBoolean(false) private var olmMachine: OlmMachine? = null + // The verification service. + private var verificationService: RustVerificationService? = null + private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() // Locks for some of our operations @@ -179,6 +180,7 @@ internal class DefaultCryptoService @Inject constructor( EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) + else -> this.verificationService?.onEvent(event) } } @@ -315,7 +317,10 @@ internal class DefaultCryptoService @Inject constructor( try { setRustLogger() - this.olmMachine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) + val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) + this.olmMachine = machine + this.verificationService = + RustVerificationService(this.taskExecutor, machine, this.sendToDeviceTask) Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") @@ -359,7 +364,32 @@ internal class DefaultCryptoService @Inject constructor( /** * @return the VerificationService */ - override fun verificationService() = verificationService + override fun verificationService(): VerificationService { + // TODO yet another problem because the CryptoService is started in the + // sync loop + // + // The `KeyRequestHandler` and `IncomingVerificationHandler` want to add + // listeners to the verification service, they are initialized in the + // `ActiveSessionHolder` class in the `setActiveSession()` method. In + // the `setActiveSession()` method we call the `start()` method of the + // handlers without first calling the `start()` method of the + // `DefaultCrytpoService`. + // + // The start method of the crypto service isn't part of the + // `CryptoService` interface so it currently can't be called there. I'm + // inclined to believe that it should be, and that it should be + // initialized before anything else tries to do something with it. + // + // Let's initialize here as a workaround until we figure out if the + // above conclusion is correct. + if (verificationService == null) { + runBlocking { + internalStart() + } + } + + return verificationService!! + } override fun crossSigningService() = crossSigningService @@ -677,6 +707,8 @@ internal class DefaultCryptoService @Inject constructor( val sessionId = content.sessionId notifyRoomKeyReceival(roomId, sessionId) + } else { + this.verificationService?.onEvent(event) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index d62d880676..f1e21e0b43 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -26,33 +26,44 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext 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.verification.CancelCode +import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation +import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest +import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady +import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest +import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod 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.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS 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 import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse import timber.log.Timber +import uniffi.olm.CancelCode as RustCancelCode 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 import uniffi.olm.Logger import uniffi.olm.OlmMachine as InnerMachine +import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType +import uniffi.olm.Sas as InnerSas +import uniffi.olm.VerificationRequest as InnerRequest import uniffi.olm.setLogger class CryptoLogger : Logger { @@ -89,13 +100,9 @@ fun setRustLogger() { setLogger(CryptoLogger() as Logger) } -/** - * Convert a Rust Device into a Kotlin CryptoDeviceInfo - */ +/** Convert a Rust Device into a Kotlin CryptoDeviceInfo */ private fun toCryptoDeviceInfo(device: Device): CryptoDeviceInfo { - val keys = device.keys.map { (keyId, key) -> - "$keyId:$device.deviceId" to key - }.toMap() + val keys = device.keys.map { (keyId, key) -> "$keyId:$device.deviceId" to key }.toMap() return CryptoDeviceInfo( device.deviceId, @@ -110,8 +117,7 @@ private fun toCryptoDeviceInfo(device: Device): CryptoDeviceInfo { DeviceTrustLevel(crossSigningVerified = false, locallyVerified = false), device.isBlocked, // TODO - null - ) + null) } internal class DeviceUpdateObserver { @@ -126,27 +132,171 @@ internal class DeviceUpdateObserver { } } -internal class Sas(private val machine: InnerMachine, private var inner: InnerSas) { +internal class VerificationRequest( + private val machine: InnerMachine, + private var inner: InnerRequest +) { private fun refreshData() { - val sas = this.machine.getVerification(this.inner.flowId) + val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) - if (sas != null) { - this.inner = sas - } + if (request != null) { + this.inner = request + } - return + return + } + + fun accept_with_methods(methods: List): OutgoingVerificationRequest? { + val stringMethods: MutableList = + methods.map { + when (it) { + VerificationMethod.QR_CODE_SCAN -> VERIFICATION_METHOD_QR_CODE_SCAN + VerificationMethod.QR_CODE_SHOW -> VERIFICATION_METHOD_QR_CODE_SHOW + VerificationMethod.SAS -> VERIFICATION_METHOD_SAS + } + }.toMutableList() + + if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || + stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { + stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) + } + + return this.machine.acceptVerificationRequest( + this.inner.otherUserId, this.inner.flowId, stringMethods) } fun isCanceled(): Boolean { refreshData() - return this.inner.isCanceled + return this.inner.isCancelled } fun isDone(): Boolean { refreshData() return this.inner.isDone } - + + fun isReady(): Boolean { + refreshData() + return this.inner.isReady + } + + fun toPendingVerificationRequest(): PendingVerificationRequest { + refreshData() + val code = this.inner.cancelCode + + val cancelCode = + if (code != null) { + toCancelCode(code) + } else { + null + } + + val ourMethods = this.inner.ourMethods + val theirMethods = this.inner.theirMethods + val otherDeviceId = this.inner.otherDeviceId + + var requestInfo: ValidVerificationInfoRequest? = null + var readyInfo: ValidVerificationInfoReady? = null + + if (this.inner.weStarted && ourMethods != null) { + requestInfo = + ValidVerificationInfoRequest( + this.inner.flowId, + this.machine.deviceId(), + ourMethods, + null, + ) + } else if (!this.inner.weStarted && ourMethods != null) { + readyInfo = + ValidVerificationInfoReady( + this.inner.flowId, + this.machine.deviceId(), + ourMethods, + ) + } + + if (this.inner.weStarted && theirMethods != null && otherDeviceId != null) { + readyInfo = + ValidVerificationInfoReady( + this.inner.flowId, + otherDeviceId, + theirMethods, + ) + } else if (!this.inner.weStarted && theirMethods != null && otherDeviceId != null) { + requestInfo = + ValidVerificationInfoRequest( + this.inner.flowId, + otherDeviceId, + theirMethods, + System.currentTimeMillis(), + ) + } + + return PendingVerificationRequest( + // Creation time + System.currentTimeMillis(), + // Who initiated the request + !this.inner.weStarted, + // Local echo id, what to do here? + this.inner.flowId, + // other user + this.inner.otherUserId, + // room id + this.inner.roomId, + // transaction id + this.inner.flowId, + // val requestInfo: ValidVerificationInfoRequest? = null, + requestInfo, + // val readyInfo: ValidVerificationInfoReady? = null, + readyInfo, + // cancel code if there is one + cancelCode, + // are we done/successful + this.inner.isDone, + // did another device answer the request + this.inner.isPassive, + // devices that should receive the events we send out + null, + ) + } +} + +private fun toCancelCode(cancelCode: RustCancelCode): CancelCode { + return when (cancelCode) { + RustCancelCode.USER -> CancelCode.User + RustCancelCode.TIMEOUT -> CancelCode.Timeout + RustCancelCode.UNKNOWN_TRANSACTION -> CancelCode.UnknownTransaction + RustCancelCode.UNKNOWN_METHOD -> CancelCode.UnknownMethod + RustCancelCode.UNEXPECTED_MESSAGE -> CancelCode.UnexpectedMessage + RustCancelCode.KEY_MISMATCH -> CancelCode.MismatchedKeys + RustCancelCode.USER_MISMATCH -> CancelCode.MismatchedKeys + RustCancelCode.INVALID_MESSAGE -> CancelCode.InvalidMessage + // TODO why don't the ruma codes match what's in EA? + RustCancelCode.ACCEPTED -> CancelCode.User + } +} + +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.isCancelled + } + + fun isDone(): Boolean { + refreshData() + return this.inner.isDone + } + fun timedOut(): Boolean { refreshData() return this.inner.timedOut @@ -162,9 +312,8 @@ internal class Sas(private val machine: InnerMachine, private var inner: InnerSa } @Throws(CryptoStoreErrorException::class) - suspend fun confirm(): OutgoingVerificationRequest? = withContext(Dispatchers.IO) { - machine.confirmVerification(inner.flowId) - } + suspend fun confirm(): OutgoingVerificationRequest? = + withContext(Dispatchers.IO) { machine.confirmVerification(inner.flowId) } fun cancel(): OutgoingVerificationRequest? { return this.machine.cancelVerification(inner.flowId) @@ -185,27 +334,26 @@ internal class Sas(private val machine: InnerMachine, private var inner: InnerSa } } -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 deviceUpdateObserver = deviceObserver - /** - * Get our own user ID. - */ + /** Get our own user ID. */ fun userId(): String { return this.inner.userId() } - /** - * Get our own device ID. - */ + /** Get our own device ID. */ fun deviceId(): String { return this.inner.deviceId() } - /** - * Get our own public identity keys ID. - */ + /** Get our own public identity keys ID. */ fun identityKeys(): Map { return this.inner.identityKeys() } @@ -213,36 +361,31 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device fun ownDevice(): CryptoDeviceInfo { val deviceId = this.deviceId() - val keys = this.identityKeys().map { (keyId, key) -> - "$keyId:$deviceId" to key - }.toMap() + val keys = this.identityKeys().map { (keyId, key) -> "$keyId:$deviceId" to key }.toMap() return CryptoDeviceInfo( - this.deviceId(), - this.userId(), - // TODO pass the algorithms here. - listOf(), - keys, - mapOf(), - UnsignedDeviceInfo(), - DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), - false, - null - ) + this.deviceId(), + this.userId(), + // TODO pass the algorithms here. + listOf(), + keys, + mapOf(), + UnsignedDeviceInfo(), + DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), + false, + null) } /** * Get the list of outgoing requests that need to be sent to the homeserver. * - * After the request was sent out and a successful response was received - * the response body should be passed back to the state machine using the - * markRequestAsSent() method. + * After the request was sent out and a successful response was received the response body + * should be passed back to the state machine using the markRequestAsSent() method. * * @return the list of requests that needs to be sent to the homeserver */ - suspend fun outgoingRequests(): List = withContext(Dispatchers.IO) { - inner.outgoingRequests() - } + suspend fun outgoingRequests(): List = + withContext(Dispatchers.IO) { inner.outgoingRequests() } /** * Mark a request that was sent to the server as sent. @@ -255,135 +398,127 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device */ @Throws(CryptoStoreErrorException::class) suspend fun markRequestAsSent( - requestId: String, - requestType: RequestType, - responseBody: String - ) = withContext(Dispatchers.IO) { - inner.markRequestAsSent(requestId, requestType, responseBody) + requestId: String, + requestType: RequestType, + responseBody: String + ) = + withContext(Dispatchers.IO) { + inner.markRequestAsSent(requestId, requestType, responseBody) - if (requestType == RequestType.KEYS_QUERY) { - updateLiveDevices() - } - } + if (requestType == RequestType.KEYS_QUERY) { + updateLiveDevices() + } + } /** - * Let the state machine know about E2EE related sync changes that we - * received from the server. + * Let the state machine know about E2EE related sync changes that we received from the server. * - * This needs to be called after every sync, ideally before processing - * any other sync changes. + * This needs to be called after every sync, ideally before processing any other sync changes. * - * @param toDevice A serialized array of to-device events we received in the - * current sync resposne. + * @param toDevice A serialized array of to-device events we received in the current sync + * resposne. * - * @param deviceChanges The list of devices that have changed in some way - * since the previous sync. + * @param deviceChanges The list of devices that have changed in some way since the previous + * sync. * * @param keyCounts The map of uploaded one-time key types and counts. */ @Throws(CryptoStoreErrorException::class) suspend fun receiveSyncChanges( - toDevice: ToDeviceSyncResponse?, - deviceChanges: DeviceListResponse?, - keyCounts: DeviceOneTimeKeysCountSyncResponse? - ): ToDeviceSyncResponse = withContext(Dispatchers.IO) { - val counts: MutableMap = mutableMapOf() + toDevice: ToDeviceSyncResponse?, + deviceChanges: DeviceListResponse?, + keyCounts: DeviceOneTimeKeysCountSyncResponse? + ): ToDeviceSyncResponse = + withContext(Dispatchers.IO) { + val counts: MutableMap = mutableMapOf() - if (keyCounts?.signedCurve25519 != null) { - counts["signed_curve25519"] = keyCounts.signedCurve25519 + if (keyCounts?.signedCurve25519 != null) { + counts["signed_curve25519"] = keyCounts.signedCurve25519 + } + + val devices = + DeviceLists( + deviceChanges?.changed ?: listOf(), deviceChanges?.left ?: listOf()) + val adapter = + MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) + val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! + + adapter.fromJson(inner.receiveSyncChanges(events, devices, counts))!! } - val devices = DeviceLists(deviceChanges?.changed ?: listOf(), deviceChanges?.left ?: listOf()) - val adapter = MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) - val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! - - adapter.fromJson(inner.receiveSyncChanges(events, devices, counts))!! - } - /** - * Mark the given list of users to be tracked, triggering a key query request - * for them. + * Mark the given list of users to be tracked, triggering a key query request for them. * - * *Note*: Only users that aren't already tracked will be considered for an - * update. It's safe to call this with already tracked users, it won't - * result in excessive keys query requests. + * *Note*: Only users that aren't already tracked will be considered for an update. It's safe to + * call this with already tracked users, it won't result in excessive keys query requests. * * @param users The users that should be queued up for a key query. */ - suspend fun updateTrackedUsers(users: List) = withContext(Dispatchers.IO) { - inner.updateTrackedUsers(users) - } + suspend fun updateTrackedUsers(users: List) = + withContext(Dispatchers.IO) { inner.updateTrackedUsers(users) } /** - * Generate one-time key claiming requests for all the users we are missing - * sessions for. + * Generate one-time key claiming requests for all the users we are missing sessions for. * - * After the request was sent out and a successful response was received - * the response body should be passed back to the state machine using the - * markRequestAsSent() method. + * After the request was sent out and a successful response was received the response body + * should be passed back to the state machine using the markRequestAsSent() method. * - * This method should be called every time before a call to - * shareRoomKey() is made. + * This method should be called every time before a call to shareRoomKey() is made. * - * @param users The list of users for which we would like to establish 1:1 - * Olm sessions for. + * @param users The list of users for which we would like to establish 1:1 Olm sessions for. * * @return A keys claim request that needs to be sent out to the server. */ @Throws(CryptoStoreErrorException::class) - suspend fun getMissingSessions(users: List): Request? = withContext(Dispatchers.IO) { - inner.getMissingSessions(users) - } + suspend fun getMissingSessions(users: List): Request? = + withContext(Dispatchers.IO) { inner.getMissingSessions(users) } /** * Share a room key with the given list of users for the given room. * - * After the request was sent out and a successful response was received - * the response body should be passed back to the state machine using the - * markRequestAsSent() method. + * After the request was sent out and a successful response was received the response body + * should be passed back to the state machine using the markRequestAsSent() method. * - * This method should be called every time before a call to - * `encrypt()` with the given `room_id` is made. + * This method should be called every time before a call to `encrypt()` with the given `room_id` + * is made. * - * @param roomId The unique id of the room, note that this doesn't strictly - * need to be a Matrix room, it just needs to be an unique identifier for - * the group that will participate in the conversation. + * @param roomId The unique id of the room, note that this doesn't strictly need to be a Matrix + * room, it just needs to be an unique identifier for the group that will participate in the + * conversation. * - * @param users The list of users which are considered to be members of the - * room and should receive the room key. + * @param users The list of users which are considered to be members of the room and should + * receive the room key. * * @return The list of requests that need to be sent out. */ @Throws(CryptoStoreErrorException::class) - suspend fun shareRoomKey(roomId: String, users: List): List = withContext(Dispatchers.IO) { - inner.shareRoomKey(roomId, users) - } + suspend fun shareRoomKey(roomId: String, users: List): List = + withContext(Dispatchers.IO) { inner.shareRoomKey(roomId, users) } /** - * Encrypt the given event with the given type and content for the given - * room. + * Encrypt the given event with the given type and content for the given room. * - * **Note**: A room key needs to be shared with the group of users that are - * members in the given room. If this is not done this method will panic. + * **Note**: A room key needs to be shared with the group of users that are members in the given + * room. If this is not done this method will panic. * - * The usual flow to encrypt an evnet using this state machine is as - * follows: + * The usual flow to encrypt an evnet using this state machine is as follows: * * 1. Get the one-time key claim request to establish 1:1 Olm sessions for + * ``` * the room members of the room we wish to participate in. This is done * using the [`get_missing_sessions()`](#method.get_missing_sessions) * method. This method call should be locked per call. - * + * ``` * 2. Share a room key with all the room members using the shareRoomKey(). + * ``` * This method call should be locked per room. - * + * ``` * 3. Encrypt the event using this method. * * 4. Send the encrypted event to the server. * - * After the room key is shared steps 1 and 2 will become noops, unless - * there's some changes in the room membership or in the list of devices a - * member has. + * After the room key is shared steps 1 and 2 will become noops, unless there's some changes in + * the room membership or in the list of devices a member has. * * @param roomId the ID of the room where the encrypted event will be sent to * @@ -394,12 +529,13 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * @return The encrypted version of the content */ @Throws(CryptoStoreErrorException::class) - suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = withContext(Dispatchers.IO) { - val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) - val contentString = adapter.toJson(content) - val encrypted = inner.encrypt(roomId, eventType, contentString) - adapter.fromJson(encrypted)!! - } + suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = + withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val contentString = adapter.toJson(content) + val encrypted = inner.encrypt(roomId, eventType, contentString) + adapter.fromJson(encrypted)!! + } /** * Decrypt the given event that was sent in the given room. @@ -411,62 +547,64 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * @return the decrypted version of the event. */ @Throws(MXCryptoError::class) - suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(Dispatchers.IO) { - val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) - val serializedEvent = adapter.toJson(event) + suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = + withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val serializedEvent = adapter.toJson(event) - try { - val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId!!) + try { + val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId!!) - val deserializationAdapter = MoshiProvider.providesMoshi().adapter(Map::class.java) - val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent)!! + val deserializationAdapter = + MoshiProvider.providesMoshi().adapter(Map::class.java) + val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent)!! - MXEventDecryptionResult( - clearEvent, - decrypted.senderCurve25519Key, - decrypted.claimedEd25519Key, - decrypted.forwardingCurve25519Chain - ) - } catch (throwable: Throwable) { - val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, throwable.message, "m.megolm.v1.aes-sha2") - throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason) - } - } + MXEventDecryptionResult( + clearEvent, + decrypted.senderCurve25519Key, + decrypted.claimedEd25519Key, + decrypted.forwardingCurve25519Chain) + } catch (throwable: Throwable) { + val reason = + String.format( + MXCryptoError.UNABLE_TO_DECRYPT_REASON, + throwable.message, + "m.megolm.v1.aes-sha2") + throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason) + } + } /** - * Request the room key that was used to encrypt the given undecrypted - * event. + * Request the room key that was used to encrypt the given undecrypted event. * - * @param event The that we're not able to decrypt and want to request a - * room key for. + * @param event The that we're not able to decrypt and want to request a room key for. * - * @return a key request pair, consisting of an optional key request - * cancellation and the key request itself. The cancellation *must* be sent - * out before the request, otherwise devices will ignore the key request. + * @return a key request pair, consisting of an optional key request cancellation and the key + * request itself. The cancellation *must* be sent out before the request, otherwise devices + * will ignore the key request. */ @Throws(DecryptionErrorException::class) - suspend fun requestRoomKey(event: Event): KeyRequestPair = withContext(Dispatchers.IO) { - val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) - val serializedEvent = adapter.toJson(event) + suspend fun requestRoomKey(event: Event): KeyRequestPair = + withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val serializedEvent = adapter.toJson(event) - inner.requestRoomKey(serializedEvent, event.roomId!!) - } + inner.requestRoomKey(serializedEvent, event.roomId!!) + } /** * Export all of our room keys. * - * @param passphrase The passphrase that should be used to encrypt the key - * export. + * @param passphrase The passphrase that should be used to encrypt the key export. * - * @param rounds The number of rounds that should be used when expanding the - * passphrase into an key. + * @param rounds The number of rounds that should be used when expanding the passphrase into an + * key. * * @return the encrypted key export as a bytearray. */ @Throws(CryptoStoreErrorException::class) - suspend fun exportKeys(passphrase: String, rounds: Int): ByteArray = withContext(Dispatchers.IO) { - inner.exportKeys(passphrase, rounds).toByteArray() - } + suspend fun exportKeys(passphrase: String, rounds: Int): ByteArray = + withContext(Dispatchers.IO) { inner.exportKeys(passphrase, rounds).toByteArray() } /** * Import room keys from the given serialized key export. @@ -475,19 +613,23 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * * @param passphrase The passphrase that was used to encrypt the key export. * - * @param listener A callback that can be used to introspect the - * progress of the key import. + * @param listener A callback that can be used to introspect the progress of the key import. */ @Throws(CryptoStoreErrorException::class) - suspend fun importKeys(keys: ByteArray, passphrase: String, listener: ProgressListener?): ImportRoomKeysResult = withContext(Dispatchers.IO) { - val decodedKeys = String(keys, Charset.defaultCharset()) + suspend fun importKeys( + keys: ByteArray, + passphrase: String, + listener: ProgressListener? + ): ImportRoomKeysResult = + withContext(Dispatchers.IO) { + val decodedKeys = String(keys, Charset.defaultCharset()) - val rustListener = CryptoProgressListener(listener) + val rustListener = CryptoProgressListener(listener) - val result = inner.importKeys(decodedKeys, passphrase, rustListener) + val result = inner.importKeys(decodedKeys, passphrase, rustListener) - ImportRoomKeysResult(result.total, result.imported) - } + ImportRoomKeysResult(result.total, result.imported) + } /** * Get a `Device` from the store. @@ -499,16 +641,17 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device * @return The Device if it found one. */ @Throws(CryptoStoreErrorException::class) - suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? = withContext(Dispatchers.IO) { - // Our own device isn't part of our store on the rust side, return it - // using our ownDevice method - if (userId == userId() && deviceId == deviceId()) { - ownDevice() - } else { - val device = inner.getDevice(userId, deviceId) - if (device != null) toCryptoDeviceInfo(device) else null - } - } + suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? = + withContext(Dispatchers.IO) { + // Our own device isn't part of our store on the rust side, return it + // using our ownDevice method + if (userId == userId() && deviceId == deviceId()) { + ownDevice() + } else { + val device = inner.getDevice(userId, deviceId) + if (device != null) toCryptoDeviceInfo(device) else null + } + } /** * Get all devices of an user. @@ -561,9 +704,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device return plainDevices } - /** - * Update all of our live device listeners. - */ + /** Update all of our live device listeners. */ private suspend fun updateLiveDevices() { for ((liveDevice, users) in deviceUpdateObserver.listeners) { val devices = getUserDevices(users) @@ -574,8 +715,8 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device /** * Get all the devices of multiple users as a live version. * - * The live version will update the list of devices if some of the data - * changes, or if new devices arrive for a certain user. + * The live version will update the list of devices if some of the data changes, or if new + * devices arrive for a certain user. * * @param userIds The ids of the device owners. * @@ -589,24 +730,36 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device return devices } - /** - * Discard the currently active room key for the given room if there is one. - */ + /** Discard the currently active room key for the given room if there is one. */ @Throws(CryptoStoreErrorException::class) fun discardRoomKey(roomId: String) { runBlocking { inner.discardRoomKey(roomId) } } - /** - * Get an active verification - */ - fun getVerification(flowId: String): Sas? { - val sas = this.inner.getVerification(flowId) + fun getVerificationRequests(userId: String): List { + return this.inner.getVerificationRequests(userId).map { + VerificationRequest(this.inner, it) + } + } - return if (sas == null) { - null - } else { - Sas(this.inner, sas) - } - } + fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? { + val request = this.inner.getVerificationRequest(userId, flowId) + + return if (request == null) { + null + } else { + VerificationRequest(this.inner, request) + } + } + + /** 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) + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt new file mode 100644 index 0000000000..2acad69ebf --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -0,0 +1,326 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.verification + +import android.os.Handler +import android.os.Looper +import javax.inject.Inject +import kotlin.collections.set +import kotlinx.coroutines.runBlocking +import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest +import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType +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.KeyVerificationRequest +import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.session.SessionScope +import org.matrix.android.sdk.internal.task.TaskExecutor +import timber.log.Timber +import uniffi.olm.OutgoingVerificationRequest + +@SessionScope +internal class RustVerificationService +@Inject +constructor( + private val taskExecutor: TaskExecutor, + private val olmMachine: OlmMachine, + private val sendToDeviceTask: SendToDeviceTask, +) : DefaultVerificationTransaction.Listener, VerificationService { + + private val uiHandler = Handler(Looper.getMainLooper()) + private var listeners = ArrayList() + + override fun addListener(listener: VerificationService.Listener) { + uiHandler.post { + if (!listeners.contains(listener)) { + listeners.add(listener) + } + } + } + + override fun removeListener(listener: VerificationService.Listener) { + uiHandler.post { listeners.remove(listener) } + } + + private fun dispatchTxAdded(tx: VerificationTransaction) { + uiHandler.post { + listeners.forEach { + try { + it.transactionCreated(tx) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + private fun dispatchTxUpdated(tx: VerificationTransaction) { + uiHandler.post { + listeners.forEach { + try { + it.transactionUpdated(tx) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + private fun dispatchRequestAdded(tx: PendingVerificationRequest) { + Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} ${tx}") + uiHandler.post { + listeners.forEach { + try { + it.verificationRequestCreated(tx) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + private fun dispatchRequestUpdated(tx: PendingVerificationRequest) { + uiHandler.post { + listeners.forEach { + try { + it.verificationRequestUpdated(tx) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { + TODO() + // setDeviceVerificationAction.handle(DeviceTrustLevel(false, true), + // userId, + // deviceID) + + // listeners.forEach { + // try { + // it.markedAsManuallyVerified(userId, deviceID) + // } catch (e: Throwable) { + // Timber.e(e, "## Error while notifying listeners") + // } + // } + } + + suspend fun onEvent(event: Event) { + when (event.getClearType()) { + EventType.KEY_VERIFICATION_START -> {} + EventType.KEY_VERIFICATION_CANCEL -> {} + EventType.KEY_VERIFICATION_ACCEPT -> {} + EventType.KEY_VERIFICATION_KEY -> {} + EventType.KEY_VERIFICATION_MAC -> {} + EventType.KEY_VERIFICATION_READY -> {} + EventType.KEY_VERIFICATION_DONE -> {} + MessageType.MSGTYPE_VERIFICATION_REQUEST -> { + onRequestReceived(event) + } + else -> { + // 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 onRequestReceived(event: Event) { + val content = event.getClearContent().toModel() ?: return + val flowId = content.transactionId + val sender = event.senderId ?: return + + val request = this.getExistingVerificationRequest(sender, flowId) ?: return + + dispatchRequestAdded(request) + } + + override fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event) { + // TODO This should be handled inside the rust-sdk decryption method + } + + // TODO All this methods should be delegated to a TransactionStore + override fun getExistingTransaction( + otherUserId: String, + tid: String + ): VerificationTransaction? { + return null + } + + override fun getExistingVerificationRequests( + otherUserId: String + ): List { + return this.olmMachine.getVerificationRequests(otherUserId).map { + it.toPendingVerificationRequest() + } + } + + override fun getExistingVerificationRequest( + otherUserId: String, + tid: String? + ): PendingVerificationRequest? { + return if (tid != null) { + val request = this.olmMachine.getVerificationRequest(otherUserId, tid) + + if (request != null) { + request.toPendingVerificationRequest() + } else { + null + } + } else { + null + } + } + + override fun getExistingVerificationRequestInRoom( + roomId: String, + tid: String? + ): PendingVerificationRequest? { + TODO() + } + + override fun beginKeyVerification( + method: VerificationMethod, + otherUserId: String, + otherDeviceId: String, + 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() + } else { + throw IllegalArgumentException("Unknown verification method") + } + } + + override fun requestKeyVerificationInDMs( + methods: List, + otherUserId: String, + roomId: String, + localId: String? + ): PendingVerificationRequest { + Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") + + // TODO cancel other active requests, create a new request here and + // dispatch it + TODO() + } + + override fun requestKeyVerification( + methods: List, + otherUserId: String, + otherDevices: List? + ): PendingVerificationRequest { + // This was mostly a copy paste of the InDMs method, do the same here + TODO() + } + + override fun cancelVerificationRequest(request: PendingVerificationRequest) { + // TODO get the request out of the olm machine and cancel here + TODO() + } + + override fun declineVerificationRequestInDMs( + otherUserId: String, + transactionId: String, + roomId: String + ) { + // TODO get an existing verification request out of the olm machine and + // cancel it. update the pending request afterwards + } + + override fun beginKeyVerificationInDMs( + method: VerificationMethod, + transactionId: String, + roomId: String, + otherUserId: String, + otherDeviceId: String + ): String { + // TODO fetch out the verification request nad start SAS, return the + // flow id + return "" + } + + override fun readyPendingVerificationInDMs( + methods: List, + otherUserId: String, + roomId: String, + transactionId: String + ): Boolean { + Timber.e("## TRYING TO READY PENDING ROOM VERIFICATION") + // TODO do the same as readyPendingVerification + return true + } + + override fun readyPendingVerification( + methods: List, + otherUserId: String, + transactionId: String + ): Boolean { + val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) + + return if (request != null) { + val outgoingRequest = request.accept_with_methods(methods) + + if (outgoingRequest != null) { + runBlocking { sendRequest(outgoingRequest) } + dispatchRequestUpdated(request.toPendingVerificationRequest()) + true + } else { + false + } + } else { + false + } + } + + suspend fun sendRequest(request: OutgoingVerificationRequest) { + when (request) { + is OutgoingVerificationRequest.ToDevice -> { + val adapter = + MoshiProvider.providesMoshi() + .adapter>>(Map::class.java) + val body = adapter.fromJson(request.body)!! + + val userMap = MXUsersDevicesMap() + userMap.join(body) + + val sendToDeviceParams = SendToDeviceTask.Params(request.eventType, userMap) + sendToDeviceTask.execute(sendToDeviceParams) + } + else -> {} + } + + // TODO move this into the VerificationRequest and Verification classes? + } + + override fun transactionUpdated(tx: VerificationTransaction) { + dispatchTxUpdated(tx) + } +} From 0cb9f6be10bf69d332ee29b49fba1a8c8fec8689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 18 Jun 2021 12:16:38 +0200 Subject: [PATCH 100/252] rust: Rework the rest of the sas verification methods --- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 143 ++++++++++++++++++++++++++-------------- rust-sdk/src/olm.udl | 19 ++++-- 3 files changed, 106 insertions(+), 58 deletions(-) diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index c1c37f3455..fea61ce7b5 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -7,7 +7,7 @@ mod responses; pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{KeyRequestPair, OlmMachine, Sas, VerificationRequest}; +pub use machine::{KeyRequestPair, OlmMachine, Sas, VerificationRequest, StartSasResult}; pub use responses::{ DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, }; diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 4cd216977a..ff657953ef 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -30,7 +30,7 @@ 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, - Sas as InnerSas, VerificationRequest as InnerVerificationRequest, + Sas as InnerSas, Verification, VerificationRequest as InnerVerificationRequest, }; use crate::{ @@ -56,6 +56,11 @@ pub struct Sas { pub timed_out: bool, } +pub struct StartSasResult { + pub sas: Sas, + pub request: OutgoingVerificationRequest, +} + impl From for Sas { fn from(sas: InnerSas) -> Self { Self { @@ -639,72 +644,110 @@ impl OlmMachine { } } - pub fn get_verification(&self, flow_id: &str) -> Option { - todo!() - // self.inner.get_verification(flow_id).map(|s| s.into()) - } - - pub fn request_verification(&self) { + pub fn request_verification(&self, user_id: &str) { + let _user_id = UserId::try_from(user_id).unwrap(); todo!() } - pub fn start_verification(&self, device: &Device) -> Result { - 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))? - .unwrap(); - - // TODO we need to return the request as well. - let (sas, _) = self.runtime.block_on(device.start_verification())?; - - Ok(sas.into()) + pub fn get_verification(&self, user_id: &str, _flow_id: &str) -> Option { + let _user_id = UserId::try_from(user_id).ok()?; + todo!() } - pub fn accept_verification(&self, flow_id: &str) -> Option { - todo!() - // self.inner - // .get_verification(flow_id) - // .and_then(|s| s.accept().map(|r| r.into())) + pub fn start_sas_verification( + &self, + user_id: &str, + flow_id: &str, + ) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + + Ok( + if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { + self.runtime + .block_on(verification.start_sas())? + .map(|(sas, r)| StartSasResult { + sas: sas.into(), + request: r.into(), + }) + } else { + None + }, + ) } - pub fn cancel_verification(&self, flow_id: &str) -> Option { - todo!() - // self.inner - // .get_verification(flow_id) - // .and_then(|s| s.cancel().map(|r| r.into())) + pub fn accept_sas_verification( + &self, + user_id: &str, + flow_id: &str, + ) -> Option { + let user_id = UserId::try_from(user_id).ok()?; + self.inner + .get_verification(&user_id, flow_id) + .and_then(|s| s.sas_v1()) + .and_then(|s| s.accept().map(|r| r.into())) + } + + pub fn cancel_verification( + &self, + user_id: &str, + flow_id: &str, + ) -> Option { + let user_id = UserId::try_from(user_id).ok()?; + + if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { + match verification { + Verification::SasV1(v) => v.cancel().map(|r| r.into()), + Verification::QrV1(v) => v.cancel().map(|r| r.into()), + } + } else { + None + } } pub fn confirm_verification( &self, + user_id: &str, flow_id: &str, ) -> Result, CryptoStoreError> { - todo!() - // let sas = self.inner.get_verification(flow_id); + let user_id = UserId::try_from(user_id)?; - // if let Some(sas) = sas { - // let (request, _) = self.runtime.block_on(sas.confirm())?; - // Ok(request.map(|r| r.into())) - // } else { - // Ok(None) - // } + Ok( + if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { + match verification { + Verification::SasV1(v) => { + self.runtime.block_on(v.confirm())?.0.map(|r| r.into()) + } + Verification::QrV1(v) => v.confirm_scanning().map(|r| r.into()), + } + } else { + None + }, + ) } - pub fn get_emoji_index(&self, flow_id: &str) -> Option> { - todo!() - // self.inner.get_verification(flow_id).and_then(|s| { - // s.emoji_index() - // .map(|v| v.iter().map(|i| (*i).into()).collect()) - // }) + pub fn get_emoji_index(&self, user_id: &str, flow_id: &str) -> Option> { + let user_id = UserId::try_from(user_id).ok()?; + + self.inner + .get_verification(&user_id, flow_id) + .and_then(|s| { + s.sas_v1().and_then(|s| { + s.emoji_index() + .map(|v| v.iter().map(|i| (*i).into()).collect()) + }) + }) } - pub fn get_decimals(&self, flow_id: &str) -> Option> { - todo!() - // self.inner.get_verification(flow_id).and_then(|s| { - // s.decimals() - // .map(|v| [v.0.into(), v.1.into(), v.2.into()].to_vec()) - // }) + pub fn get_decimals(&self, user_id: &str, flow_id: &str) -> Option> { + let user_id = UserId::try_from(user_id).ok()?; + + self.inner + .get_verification(&user_id, flow_id) + .and_then(|s| { + s.sas_v1().and_then(|s| { + s.decimals() + .map(|v| [v.0.into(), v.1.into(), v.2.into()].to_vec()) + }) + }) } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 01b0b84135..be552c6643 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -63,6 +63,11 @@ dictionary Device { boolean is_blocked; }; +dictionary StartSasResult { + Sas sas; + OutgoingVerificationRequest request; +}; + dictionary Sas { string other_user_id; string other_device_id; @@ -166,7 +171,7 @@ interface OlmMachine { sequence get_verification_requests([ByRef] string user_id); VerificationRequest? get_verification_request([ByRef] string user_id, [ByRef] string flow_id); - Sas? get_verification([ByRef] string flow_id); + Sas? get_verification([ByRef] string user_id, [ByRef] string flow_id); OutgoingVerificationRequest? accept_verification_request( [ByRef] string user_id, @@ -175,14 +180,14 @@ interface OlmMachine { ); [Throws=CryptoStoreError] - Sas start_verification([ByRef] Device device); + StartSasResult? start_sas_verification([ByRef] string user_id, [ByRef] string flow_id); [Throws=CryptoStoreError] - OutgoingVerificationRequest? confirm_verification([ByRef] string flow_id); - OutgoingVerificationRequest? cancel_verification([ByRef] string flow_id); - OutgoingVerificationRequest? accept_verification([ByRef] string flow_id); + OutgoingVerificationRequest? confirm_verification([ByRef] string user_id, [ByRef] string flow_id); + OutgoingVerificationRequest? cancel_verification([ByRef] string user_id, [ByRef] string flow_id); + OutgoingVerificationRequest? accept_sas_verification([ByRef] string user_id, [ByRef] string flow_id); - sequence? get_emoji_index([ByRef] string flow_id); - sequence? get_decimals([ByRef] string flow_id); + sequence? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); + sequence? get_decimals([ByRef] string user_id, [ByRef] string flow_id); [Throws=DecryptionError] KeyRequestPair request_room_key([ByRef] string event, [ByRef] string room_id); From d00b54929faeb7a09230b874c85ea802103bdc34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Sun, 20 Jun 2021 22:34:54 +0200 Subject: [PATCH 101/252] crypto: Add the scaffolding to connect the SAS verification to the rust side --- .../android/sdk/internal/crypto/OlmMachine.kt | 126 +++++++++++++++--- .../verification/RustVerificationService.kt | 3 + 2 files changed, 109 insertions(+), 20 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index f1e21e0b43..19d8233462 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -29,9 +29,11 @@ import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest +import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod +import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState 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.util.JsonDict @@ -63,6 +65,7 @@ import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType import uniffi.olm.Sas as InnerSas +import uniffi.olm.StartSasResult import uniffi.olm.VerificationRequest as InnerRequest import uniffi.olm.setLogger @@ -148,13 +151,15 @@ internal class VerificationRequest( fun accept_with_methods(methods: List): OutgoingVerificationRequest? { val stringMethods: MutableList = - methods.map { - when (it) { - VerificationMethod.QR_CODE_SCAN -> VERIFICATION_METHOD_QR_CODE_SCAN - VerificationMethod.QR_CODE_SHOW -> VERIFICATION_METHOD_QR_CODE_SHOW - VerificationMethod.SAS -> VERIFICATION_METHOD_SAS - } - }.toMutableList() + methods + .map { + when (it) { + VerificationMethod.QR_CODE_SCAN -> VERIFICATION_METHOD_QR_CODE_SCAN + VerificationMethod.QR_CODE_SHOW -> VERIFICATION_METHOD_QR_CODE_SHOW + VerificationMethod.SAS -> VERIFICATION_METHOD_SAS + } + } + .toMutableList() if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { @@ -180,6 +185,14 @@ internal class VerificationRequest( return this.inner.isReady } + suspend fun startSasVerification(): StartSasResult? { + refreshData() + + return withContext(Dispatchers.IO) { + machine.startSasVerification(inner.otherUserId, inner.flowId) + } + } + fun toPendingVerificationRequest(): PendingVerificationRequest { refreshData() val code = this.inner.cancelCode @@ -276,9 +289,12 @@ private fun toCancelCode(cancelCode: RustCancelCode): CancelCode { } } -internal class Sas(private val machine: InnerMachine, private var inner: InnerSas) { +public class SasVerification(private val machine: InnerMachine, private var inner: InnerSas) : + SasVerificationTransaction { + private var stateField: VerificationTxState = VerificationTxState.OnStarted + private fun refreshData() { - val sas = this.machine.getVerification(this.inner.flowId) + val sas = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId) if (sas != null) { this.inner = sas @@ -287,6 +303,68 @@ internal class Sas(private val machine: InnerMachine, private var inner: InnerSa return } + override val isIncoming: Boolean + get() { + return false + } + + override var otherDeviceId: String? + get() { + return this.inner.otherDeviceId + } + set(value) { + if (value != null) { + this.inner.otherDeviceId = value + } + } + + override val otherUserId: String + get() { + return this.inner.otherUserId + } + + override var state: VerificationTxState + get() { + TODO() + } + set(v) { + this.stateField = v + } + + override val transactionId: String + get() { + return this.inner.flowId + } + + override fun cancel() { + TODO() + } + + override fun cancel(code: CancelCode) { + TODO() + } + + override fun shortCodeDoesNotMatch() { + TODO() + } + + override fun isToDeviceTransport(): Boolean { + return false + } + + override fun supportsDecimal(): Boolean { + return false + } + + override fun supportsEmoji(): Boolean { + return false + } + + override fun userHasVerifiedShortCode() { + // This is confirm + TODO() + } + fun isCanceled(): Boolean { refreshData() return this.inner.isCancelled @@ -308,19 +386,21 @@ internal class Sas(private val machine: InnerMachine, private var inner: InnerSa } fun accept(): OutgoingVerificationRequest? { - return this.machine.acceptVerification(inner.flowId) + return this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId) } @Throws(CryptoStoreErrorException::class) suspend fun confirm(): OutgoingVerificationRequest? = - withContext(Dispatchers.IO) { machine.confirmVerification(inner.flowId) } + withContext(Dispatchers.IO) { + machine.confirmVerification(inner.otherUserId, inner.flowId) + } - fun cancel(): OutgoingVerificationRequest? { - return this.machine.cancelVerification(inner.flowId) + fun cancelHelper(): OutgoingVerificationRequest? { + return this.machine.cancelVerification(this.inner.otherUserId, inner.flowId) } - fun emoji(): List { - val emojiIndex = this.machine.getEmojiIndex(this.inner.flowId) + override fun getEmojiCodeRepresentation(): List { + val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId) return if (emojiIndex != null) { emojiIndex.map { getEmojiForCode(it) } @@ -329,8 +409,14 @@ internal class Sas(private val machine: InnerMachine, private var inner: InnerSa } } - fun decimals(): List? { - return this.machine.getDecimals(this.inner.flowId) + override fun getDecimalCodeRepresentation(): String { + val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId) + + return if (decimals != null) { + decimals.joinToString(" ") + } else { + "" + } } } @@ -753,13 +839,13 @@ internal class OlmMachine( } /** Get an active verification */ - fun getVerification(flowId: String): Sas? { - val sas = this.inner.getVerification(flowId) + fun getVerification(userId: String, flowId: String): SasVerification? { + val sas = this.inner.getVerification(userId, flowId) return if (sas == null) { null } else { - Sas(this.inner, sas) + SasVerification(this.inner, sas) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 2acad69ebf..b561e90d5f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -300,6 +300,9 @@ constructor( } } + // TODO create a class that handles this, the DefaultCryptoService has + // similar needs so we could share code there, beware that local echo seems + // to be handled here suspend fun sendRequest(request: OutgoingVerificationRequest) { when (request) { is OutgoingVerificationRequest.ToDevice -> { From 6649aaca2eddc984e229583892dafa13946a6f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 11:37:14 +0200 Subject: [PATCH 102/252] crypto: Support SAS verification up to showing emojis --- .../android/sdk/internal/crypto/OlmMachine.kt | 36 +++++++++++-- .../verification/RustVerificationService.kt | 53 ++++++++++++++----- rust-sdk/Cargo.toml | 8 ++- rust-sdk/src/machine.rs | 10 ++-- rust-sdk/src/olm.udl | 1 + 5 files changed, 83 insertions(+), 25 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 19d8233462..196eced925 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -185,11 +185,17 @@ internal class VerificationRequest( return this.inner.isReady } - suspend fun startSasVerification(): StartSasResult? { + suspend fun startSasVerification(): Pair? { 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() { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index b561e90d5f..91c68e18cf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -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() ?: 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() ?: 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") } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index d70e7e4418..a311211950 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -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] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index ff657953ef..47dd74c95b 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -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 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 { - let _user_id = UserId::try_from(user_id).ok()?; - todo!() + pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { + 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( diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index be552c6643..0986c87450 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -76,6 +76,7 @@ dictionary Sas { boolean is_cancelled; boolean can_be_presented; boolean timed_out; + boolean supports_emoji; }; dictionary VerificationRequest { From 6a79d022c35723a6869129d4ccd74a9f35820d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 24 Jun 2021 13:57:13 +0200 Subject: [PATCH 103/252] crypto: Expose the trust state of our devices --- .../android/sdk/internal/crypto/RustSasVerification.kt | 2 ++ rust-sdk/Cargo.toml | 6 ++++-- rust-sdk/src/device.rs | 7 +++++++ rust-sdk/src/machine.rs | 6 +++++- rust-sdk/src/olm.udl | 4 ++++ 5 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt new file mode 100644 index 0000000000..4ae9ccbcc0 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -0,0 +1,2 @@ +package org.matrix.android.sdk.internal.crypto + diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index a311211950..86e3645dab 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -23,10 +23,12 @@ version = "0.2.0" features = ["lax_deserialize"] [dependencies.matrix-sdk-common] -version = "0.3.0" +git = "https://github.com/matrix-org/matrix-rust-sdk/" +rev = "43583c292644e0e9bdaa6c83b2af35721416a263" [dependencies.matrix-sdk-crypto] -version = "0.3.0" +git = "https://github.com/matrix-org/matrix-rust-sdk/" +rev = "43583c292644e0e9bdaa6c83b2af35721416a263" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/device.rs b/rust-sdk/src/device.rs index 606db76d61..5aa36bd5bb 100644 --- a/rust-sdk/src/device.rs +++ b/rust-sdk/src/device.rs @@ -19,6 +19,11 @@ pub struct Device { /// A flag indicating if the device has been blocked, blocked devices don't /// receive any room keys from us. pub is_blocked: bool, + /// Is the device locally trusted + pub locally_trusted: bool, + /// Is our cross signing identity trusted and does the identity trust the + /// device. + pub cross_signing_trusted: bool, } impl From for Device { @@ -34,6 +39,8 @@ impl From for Device { algorithms: d.algorithms().iter().map(|a| a.to_string()).collect(), display_name: d.display_name().clone(), is_blocked: d.is_blacklisted(), + locally_trusted: d.is_locally_trusted(), + cross_signing_trusted: d.is_cross_signing_trusted(), } } } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 47dd74c95b..a730884d28 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -50,8 +50,10 @@ pub struct Sas { pub other_user_id: String, pub other_device_id: String, pub flow_id: String, + pub have_we_confirmed: bool, pub is_cancelled: bool, pub is_done: bool, + pub cancel_code: Option, pub can_be_presented: bool, pub supports_emoji: bool, pub timed_out: bool, @@ -73,6 +75,8 @@ impl From for Sas { can_be_presented: sas.can_be_presented(), timed_out: sas.timed_out(), supports_emoji: sas.supports_emoji(), + have_we_confirmed: sas.have_we_confirmed(), + cancel_code: sas.cancel_code().map(|c| c.into()), } } } @@ -102,7 +106,7 @@ impl From for VerificationRequest { is_done: v.is_done(), is_ready: v.is_ready(), room_id: v.room_id().map(|r| r.to_string()), - cancel_code: v.cancel_code().map(|c| c.clone().into()), + cancel_code: v.cancel_code().map(|c| c.into()), we_started: v.we_started(), is_passive: v.is_passive(), their_methods: v diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 0986c87450..fb17755e8d 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -61,6 +61,8 @@ dictionary Device { sequence algorithms; string? display_name; boolean is_blocked; + boolean locally_trusted; + boolean cross_signing_trusted; }; dictionary StartSasResult { @@ -72,6 +74,8 @@ dictionary Sas { string other_user_id; string other_device_id; string flow_id; + CancelCode? cancel_code; + boolean have_we_confirmed; boolean is_done; boolean is_cancelled; boolean can_be_presented; From aad18ebec75c062607574c4b75d9e796c4118eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 24 Jun 2021 13:58:59 +0200 Subject: [PATCH 104/252] crypto: Move the sendToDevice logic to a common class and use it for verifications --- .../internal/crypto/DefaultCryptoService.kt | 70 +++--- .../android/sdk/internal/crypto/OlmMachine.kt | 193 ++-------------- .../internal/crypto/RustSasVerification.kt | 208 +++++++++++++++++- .../verification/RustVerificationService.kt | 45 ++-- 4 files changed, 272 insertions(+), 244 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 37e1288525..c21aaed6a1 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -20,25 +20,16 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.lifecycle.LiveData import androidx.paging.PagedList -import com.squareup.moshi.Types -import dagger.Lazy -import java.io.File -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.ConcurrentHashMap -import javax.inject.Inject -import kotlin.jvm.Throws -import kotlin.math.max -import kotlinx.coroutines.async import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.async import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor @@ -59,14 +50,11 @@ import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.OlmMachine -import org.matrix.android.sdk.internal.crypto.setRustLogger import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService 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.MXDeviceInfo import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent @@ -74,19 +62,19 @@ import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent -import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse +import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask -import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask -import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask -import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask +import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask +import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.MoshiProvider @@ -95,7 +83,6 @@ import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask -import org.matrix.android.sdk.internal.session.sync.model.SyncResponse 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.ToDeviceSyncResponse @@ -107,6 +94,30 @@ import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import timber.log.Timber import uniffi.olm.Request import uniffi.olm.RequestType +import java.io.File +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean +import javax.inject.Inject +import kotlin.math.max + +internal class RequestSender( + private val sendToDeviceTask: SendToDeviceTask, +) { + suspend fun sendToDevice(eventType: String, body: String) { + // TODO this produces floats for the Olm type fields, which + // are integers originally. + val adapter = MoshiProvider + .providesMoshi() + .adapter>>(Map::class.java) + val jsonBody = adapter.fromJson(body)!! + + val userMap = MXUsersDevicesMap() + userMap.join(jsonBody) + + val sendToDeviceParams = SendToDeviceTask.Params(eventType, userMap) + sendToDeviceTask.execute(sendToDeviceParams) + } +} /** * A `CryptoService` class instance manages the end-to-end crypto for a session. @@ -153,6 +164,8 @@ internal class DefaultCryptoService @Inject constructor( private val isStarting = AtomicBoolean(false) private val isStarted = AtomicBoolean(false) + private val sender = RequestSender(this.sendToDeviceTask) + private var olmMachine: OlmMachine? = null // The verification service. private var verificationService: RustVerificationService? = null @@ -320,7 +333,7 @@ internal class DefaultCryptoService @Inject constructor( val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) this.olmMachine = machine this.verificationService = - RustVerificationService(this.taskExecutor, machine, this.sendToDeviceTask) + RustVerificationService(machine, this.sender) Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") @@ -373,7 +386,7 @@ internal class DefaultCryptoService @Inject constructor( // `ActiveSessionHolder` class in the `setActiveSession()` method. In // the `setActiveSession()` method we call the `start()` method of the // handlers without first calling the `start()` method of the - // `DefaultCrytpoService`. + // `DefaultCryptoService`. // // The start method of the crypto service isn't part of the // `CryptoService` interface so it currently can't be called there. I'm @@ -666,7 +679,7 @@ internal class DefaultCryptoService @Inject constructor( } } - private fun notifyRoomKeyReceival( + private fun notifyRoomKeyReceived( roomId: String, sessionId: String, ) { @@ -791,18 +804,7 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun sendToDevice(request: Request.ToDevice) { - // TODO this produces floats for the Olm type fields, which - // are integers originally. - val adapter = MoshiProvider - .providesMoshi() - .adapter>>(Map::class.java) - val body = adapter.fromJson(request.body)!! - - val userMap = MXUsersDevicesMap() - userMap.join(body) - - val sendToDeviceParams = SendToDeviceTask.Params(request.eventType, userMap) - sendToDeviceTask.execute(sendToDeviceParams) + this.sender.sendToDevice(request.eventType, request.body) olmMachine!!.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}") } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 196eced925..4622960c3f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -27,13 +27,10 @@ import kotlinx.coroutines.withContext 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.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest -import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState 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.util.JsonDict @@ -46,7 +43,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS -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 @@ -64,7 +60,7 @@ import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType -import uniffi.olm.Sas as InnerSas +import uniffi.olm.Sas import uniffi.olm.StartSasResult import uniffi.olm.VerificationRequest as InnerRequest import uniffi.olm.setLogger @@ -149,7 +145,7 @@ internal class VerificationRequest( return } - fun accept_with_methods(methods: List): OutgoingVerificationRequest? { + fun acceptWithMethods(methods: List): OutgoingVerificationRequest? { val stringMethods: MutableList = methods .map { @@ -185,17 +181,11 @@ internal class VerificationRequest( return this.inner.isReady } - suspend fun startSasVerification(): Pair? { + suspend fun startSasVerification(): StartSasResult? { refreshData() return withContext(Dispatchers.IO) { - val response = machine.startSasVerification(inner.otherUserId, inner.flowId) - - if (response != null) { - Pair(response.request, SasVerification(machine, response.sas)) - } else { - null - } + machine.startSasVerification(inner.otherUserId, inner.flowId) } } @@ -280,7 +270,7 @@ internal class VerificationRequest( } } -private fun toCancelCode(cancelCode: RustCancelCode): CancelCode { +internal fun toCancelCode(cancelCode: RustCancelCode): CancelCode { return when (cancelCode) { RustCancelCode.USER -> CancelCode.User RustCancelCode.TIMEOUT -> CancelCode.Timeout @@ -290,162 +280,11 @@ private fun toCancelCode(cancelCode: RustCancelCode): CancelCode { RustCancelCode.KEY_MISMATCH -> CancelCode.MismatchedKeys RustCancelCode.USER_MISMATCH -> CancelCode.MismatchedKeys RustCancelCode.INVALID_MESSAGE -> CancelCode.InvalidMessage - // TODO why don't the ruma codes match what's in EA? + // TODO why don't the Ruma codes match what's in EA? RustCancelCode.ACCEPTED -> CancelCode.User } } -public class SasVerification(private val machine: InnerMachine, private var inner: InnerSas) : - SasVerificationTransaction { - private var stateField: VerificationTxState = VerificationTxState.OnStarted - - private fun refreshData() { - val sas = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId) - - if (sas != null) { - this.inner = sas - } - - return - } - - override val isIncoming: Boolean - get() { - return false - } - - override var otherDeviceId: String? - get() { - return this.inner.otherDeviceId - } - set(value) { - if (value != null) { - this.inner.otherDeviceId = value - } - } - - override val otherUserId: String - get() { - return this.inner.otherUserId - } - - override var state: VerificationTxState - get() { - 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 - } - - override val transactionId: String - get() { - return this.inner.flowId - } - - override fun cancel() { - TODO() - } - - override fun cancel(code: CancelCode) { - TODO() - } - - override fun shortCodeDoesNotMatch() { - TODO() - } - - override fun isToDeviceTransport(): Boolean { - return false - } - - override fun supportsDecimal(): Boolean { - // 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 { - refreshData() - return this.inner.supportsEmoji - } - - override fun userHasVerifiedShortCode() { - // This is confirm - TODO() - } - - fun isCanceled(): Boolean { - refreshData() - return this.inner.isCancelled - } - - 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.acceptSasVerification(this.inner.otherUserId, inner.flowId) - } - - @Throws(CryptoStoreErrorException::class) - suspend fun confirm(): OutgoingVerificationRequest? = - withContext(Dispatchers.IO) { - machine.confirmVerification(inner.otherUserId, inner.flowId) - } - - fun cancelHelper(): OutgoingVerificationRequest? { - return this.machine.cancelVerification(this.inner.otherUserId, inner.flowId) - } - - override fun getEmojiCodeRepresentation(): List { - val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId) - - return if (emojiIndex != null) { - emojiIndex.map { getEmojiForCode(it) } - } else { - listOf() - } - } - - override fun getDecimalCodeRepresentation(): String { - val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId) - - return if (decimals != null) { - decimals.joinToString(" ") - } else { - "" - } - } -} - internal class OlmMachine( user_id: String, device_id: String, @@ -470,6 +309,10 @@ internal class OlmMachine( return this.inner.identityKeys() } + fun inner(): InnerMachine { + return this.inner + } + fun ownDevice(): CryptoDeviceInfo { val deviceId = this.deviceId() @@ -528,7 +371,7 @@ internal class OlmMachine( * This needs to be called after every sync, ideally before processing any other sync changes. * * @param toDevice A serialized array of to-device events we received in the current sync - * resposne. + * response. * * @param deviceChanges The list of devices that have changed in some way since the previous * sync. @@ -613,7 +456,7 @@ internal class OlmMachine( * **Note**: A room key needs to be shared with the group of users that are members in the given * room. If this is not done this method will panic. * - * The usual flow to encrypt an evnet using this state machine is as follows: + * The usual flow to encrypt an event using this state machine is as follows: * * 1. Get the one-time key claim request to establish 1:1 Olm sessions for * ``` @@ -629,7 +472,7 @@ internal class OlmMachine( * * 4. Send the encrypted event to the server. * - * After the room key is shared steps 1 and 2 will become noops, unless there's some changes in + * After the room key is shared steps 1 and 2 will become no-ops, unless there's some changes in * the room membership or in the list of devices a member has. * * @param roomId the ID of the room where the encrypted event will be sent to @@ -865,13 +708,7 @@ internal class OlmMachine( } /** Get an active verification */ - fun getVerification(userId: String, flowId: String): SasVerification? { - val sas = this.inner.getVerification(userId, flowId) - - return if (sas == null) { - null - } else { - SasVerification(this.inner, sas) - } + fun getVerification(userId: String, flowId: String): Sas? { + return this.inner.getVerification(userId, flowId) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index 4ae9ccbcc0..a4cb81150e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -1,2 +1,208 @@ -package org.matrix.android.sdk.internal.crypto +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.matrix.android.sdk.internal.crypto + +import android.os.Handler +import android.os.Looper +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.verification.CancelCode +import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation +import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState +import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode +import timber.log.Timber +import uniffi.olm.CryptoStoreErrorException +import uniffi.olm.OlmMachine +import uniffi.olm.OutgoingVerificationRequest +import uniffi.olm.Sas + +internal class SasVerification( + private val machine: OlmMachine, + private var inner: Sas, + private val sender: RequestSender, + private val listeners: ArrayList, + ) : + SasVerificationTransaction { + private val uiHandler = Handler(Looper.getMainLooper()) + private var stateField: VerificationTxState = VerificationTxState.OnStarted + + private fun dispatchTxUpdated() { + uiHandler.post { + listeners.forEach { + try { + it.transactionUpdated(this) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + private fun refreshData() { + val sas = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId) + + if (sas != null) { + this.inner = sas + } + + return + } + + override val isIncoming: Boolean + get() { + return false + } + + override var otherDeviceId: String? + get() { + return this.inner.otherDeviceId + } + set(value) { + if (value != null) { + this.inner.otherDeviceId = value + } + } + + override val otherUserId: String + get() { + return this.inner.otherUserId + } + + override var state: VerificationTxState + get() { + refreshData() + return when { + this.inner.isDone -> VerificationTxState.Verified + this.inner.haveWeConfirmed -> VerificationTxState.ShortCodeAccepted + this.inner.canBePresented -> VerificationTxState.ShortCodeReady + this.inner.isCancelled -> { + val rustCancelCode = this.inner.cancelCode + val cancelCode = + if (rustCancelCode != null) { + toCancelCode(rustCancelCode) + } else { + CancelCode.UnexpectedMessage + } + // TODO get byMe from the rust side + VerificationTxState.Cancelled(cancelCode, false) + } + else -> { + VerificationTxState.Started + } + } + } + set(v) { + this.stateField = v + } + + override val transactionId: String + get() { + return this.inner.flowId + } + + override fun cancel() { + TODO() + } + + override fun cancel(code: CancelCode) { + TODO() + } + + override fun shortCodeDoesNotMatch() { + TODO() + } + + override fun isToDeviceTransport(): Boolean { + return false + } + + override fun supportsDecimal(): Boolean { + // 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 { + refreshData() + return this.inner.supportsEmoji + } + + override fun userHasVerifiedShortCode() { + runBlocking { + when (val request = confirm()) { + is OutgoingVerificationRequest.ToDevice -> { + sender.sendToDevice(request.eventType, request.body) + } + + else -> {} + } + } + refreshData() + dispatchTxUpdated() + } + + fun isCanceled(): Boolean { + refreshData() + return this.inner.isCancelled + } + + 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.acceptSasVerification(this.inner.otherUserId, inner.flowId) + } + + @Throws(CryptoStoreErrorException::class) + suspend fun confirm(): OutgoingVerificationRequest? = + withContext(Dispatchers.IO) { + machine.confirmVerification(inner.otherUserId, inner.flowId) + } + + fun cancelHelper(): OutgoingVerificationRequest? { + return this.machine.cancelVerification(this.inner.otherUserId, inner.flowId) + } + + override fun getEmojiCodeRepresentation(): List { + val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId) + + return emojiIndex?.map { getEmojiForCode(it) } ?: listOf() + } + + override fun getDecimalCodeRepresentation(): String { + val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId) + + return decimals?.joinToString(" ") ?: "" + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 91c68e18cf..0630830ce0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -18,9 +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 import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod @@ -31,14 +29,12 @@ import org.matrix.android.sdk.api.session.events.model.EventType 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.RequestSender +import org.matrix.android.sdk.internal.crypto.SasVerification 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 import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.task.TaskExecutor import timber.log.Timber import uniffi.olm.OutgoingVerificationRequest @@ -46,9 +42,8 @@ import uniffi.olm.OutgoingVerificationRequest internal class RustVerificationService @Inject constructor( - private val taskExecutor: TaskExecutor, private val olmMachine: OlmMachine, - private val sendToDeviceTask: SendToDeviceTask, + private val requestSender: RequestSender, ) : DefaultVerificationTransaction.Listener, VerificationService { private val uiHandler = Handler(Looper.getMainLooper()) @@ -91,7 +86,7 @@ constructor( } private fun dispatchRequestAdded(tx: PendingVerificationRequest) { - Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} ${tx}") + Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx") uiHandler.post { listeners.forEach { try { @@ -188,7 +183,9 @@ constructor( otherUserId: String, tid: String, ): VerificationTransaction? { - return this.olmMachine.getVerification(otherUserId, tid) + val verification = this.olmMachine.getVerification(otherUserId, tid) ?: return null + + return SasVerification(this.olmMachine.inner(), verification, this.requestSender, this.listeners) } override fun getExistingVerificationRequests( @@ -204,13 +201,7 @@ constructor( tid: String? ): PendingVerificationRequest? { return if (tid != null) { - val request = this.olmMachine.getVerificationRequest(otherUserId, tid) - - if (request != null) { - request.toPendingVerificationRequest() - } else { - null - } + olmMachine.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest() } else { null } @@ -236,9 +227,10 @@ constructor( runBlocking { val response = request?.startSasVerification() if (response != null) { - sendRequest(response.first) - dispatchTxAdded(response.second) - response.second.transactionId + sendRequest(response.request) + val sas = SasVerification(olmMachine.inner(), response.sas, requestSender, listeners) + dispatchTxAdded(sas) + sas.transactionId } else { null } @@ -315,7 +307,7 @@ constructor( val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) return if (request != null) { - val outgoingRequest = request.accept_with_methods(methods) + val outgoingRequest = request.acceptWithMethods(methods) if (outgoingRequest != null) { runBlocking { sendRequest(outgoingRequest) } @@ -335,16 +327,7 @@ constructor( suspend fun sendRequest(request: OutgoingVerificationRequest) { when (request) { is OutgoingVerificationRequest.ToDevice -> { - val adapter = - MoshiProvider.providesMoshi() - .adapter>>(Map::class.java) - val body = adapter.fromJson(request.body)!! - - val userMap = MXUsersDevicesMap() - userMap.join(body) - - val sendToDeviceParams = SendToDeviceTask.Params(request.eventType, userMap) - sendToDeviceTask.execute(sendToDeviceParams) + this.requestSender.sendToDevice(request.eventType, request.body) } else -> {} } From 948aa1a1411ba11903a4214d83086afb66fc335e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 24 Jun 2021 13:59:44 +0200 Subject: [PATCH 105/252] crypto: Correctly pick up our device verification state --- .../java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 4622960c3f..db501a1f20 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -112,8 +112,7 @@ private fun toCryptoDeviceInfo(device: Device): CryptoDeviceInfo { // Kotlin side care about signatures? mapOf(), UnsignedDeviceInfo(device.displayName), - // TODO pass trust levels here - DeviceTrustLevel(crossSigningVerified = false, locallyVerified = false), + DeviceTrustLevel(crossSigningVerified = device.verified, locallyVerified = device.locallyVerified), device.isBlocked, // TODO null) From b53b0a00930f35fef141b03b189d9f7e1783d4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 25 Jun 2021 08:13:19 +0200 Subject: [PATCH 106/252] crypto: Use a when instead of a big if/else statement --- .../internal/crypto/DefaultCryptoService.kt | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index c21aaed6a1..bacc9e1456 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -706,22 +706,26 @@ internal class DefaultCryptoService @Inject constructor( // Notify the our listeners about room keys so decryption is retried. if (toDeviceEvents.events != null) { toDeviceEvents.events.forEach { event -> - if (event.type == EventType.ROOM_KEY) { - val content = event.getClearContent().toModel() ?: return@forEach + when (event.type) { + EventType.ROOM_KEY -> { + val content = event.getClearContent().toModel() ?: return@forEach - val roomId = content.sessionId ?: return@forEach - val sessionId = content.sessionId + val roomId = content.sessionId ?: return@forEach + val sessionId = content.sessionId - notifyRoomKeyReceival(roomId, sessionId) - } else if (event.type == EventType.FORWARDED_ROOM_KEY) { - val content = event.getClearContent().toModel() ?: return@forEach + notifyRoomKeyReceived(roomId, sessionId) + } + EventType.FORWARDED_ROOM_KEY -> { + val content = event.getClearContent().toModel() ?: return@forEach - val roomId = content.sessionId ?: return@forEach - val sessionId = content.sessionId + val roomId = content.sessionId ?: return@forEach + val sessionId = content.sessionId - notifyRoomKeyReceival(roomId, sessionId) - } else { - this.verificationService?.onEvent(event) + notifyRoomKeyReceived(roomId, sessionId) + } + else -> { + this.verificationService?.onEvent(event) + } } } } From f854e9cf1c77c3606c1702855e27f1f91ad09695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 25 Jun 2021 13:38:49 +0200 Subject: [PATCH 107/252] crypto: Remove the intermediately CancelCode and use strings to map over FFI --- .../android/sdk/internal/crypto/OlmMachine.kt | 19 ++--------- .../internal/crypto/RustSasVerification.kt | 13 +++----- rust-sdk/Cargo.toml | 4 +-- rust-sdk/src/lib.rs | 33 +------------------ rust-sdk/src/machine.rs | 21 ++++++++---- rust-sdk/src/olm.udl | 25 ++++++-------- 6 files changed, 33 insertions(+), 82 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index db501a1f20..e05287052a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -31,6 +31,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificatio import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod +import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf 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.util.JsonDict @@ -48,7 +49,6 @@ 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.ToDeviceSyncResponse import timber.log.Timber -import uniffi.olm.CancelCode as RustCancelCode import uniffi.olm.CryptoStoreErrorException import uniffi.olm.DecryptionErrorException import uniffi.olm.Device @@ -194,7 +194,7 @@ internal class VerificationRequest( val cancelCode = if (code != null) { - toCancelCode(code) + safeValueOf(code) } else { null } @@ -269,21 +269,6 @@ internal class VerificationRequest( } } -internal fun toCancelCode(cancelCode: RustCancelCode): CancelCode { - return when (cancelCode) { - RustCancelCode.USER -> CancelCode.User - RustCancelCode.TIMEOUT -> CancelCode.Timeout - RustCancelCode.UNKNOWN_TRANSACTION -> CancelCode.UnknownTransaction - RustCancelCode.UNKNOWN_METHOD -> CancelCode.UnknownMethod - RustCancelCode.UNEXPECTED_MESSAGE -> CancelCode.UnexpectedMessage - RustCancelCode.KEY_MISMATCH -> CancelCode.MismatchedKeys - RustCancelCode.USER_MISMATCH -> CancelCode.MismatchedKeys - RustCancelCode.INVALID_MESSAGE -> CancelCode.InvalidMessage - // TODO why don't the Ruma codes match what's in EA? - RustCancelCode.ACCEPTED -> CancelCode.User - } -} - internal class OlmMachine( user_id: String, device_id: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index a4cb81150e..6a8ab11d82 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -26,6 +26,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentatio import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState +import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode import timber.log.Timber import uniffi.olm.CryptoStoreErrorException @@ -93,15 +94,9 @@ internal class SasVerification( this.inner.haveWeConfirmed -> VerificationTxState.ShortCodeAccepted this.inner.canBePresented -> VerificationTxState.ShortCodeReady this.inner.isCancelled -> { - val rustCancelCode = this.inner.cancelCode - val cancelCode = - if (rustCancelCode != null) { - toCancelCode(rustCancelCode) - } else { - CancelCode.UnexpectedMessage - } - // TODO get byMe from the rust side - VerificationTxState.Cancelled(cancelCode, false) + val cancelCode = safeValueOf(this.inner.cancelCode) + val byMe = this.inner.cancelledByUs ?: false + VerificationTxState.Cancelled(cancelCode, byMe) } else -> { VerificationTxState.Started diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 86e3645dab..fdf306d537 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -24,11 +24,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "43583c292644e0e9bdaa6c83b2af35721416a263" +rev = "710b519c110278a0857f26a86a0f8329609c1a5f" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "43583c292644e0e9bdaa6c83b2af35721416a263" +rev = "710b519c110278a0857f26a86a0f8329609c1a5f" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index fea61ce7b5..fe2d973033 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -7,7 +7,7 @@ mod responses; pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{KeyRequestPair, OlmMachine, Sas, VerificationRequest, StartSasResult}; +pub use machine::{KeyRequestPair, OlmMachine, Sas, StartSasResult, VerificationRequest}; pub use responses::{ DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, }; @@ -30,35 +30,4 @@ pub struct DecryptedEvent { pub forwarding_curve25519_chain: Vec, } -pub enum CancelCode { - User, - Timeout, - UnknownTransaction, - UnknownMethod, - UnexpectedMessage, - KeyMismatch, - UserMismatch, - InvalidMessage, - Accepted, -} - -impl From for CancelCode { - fn from(c: ruma::events::key::verification::cancel::CancelCode) -> Self { - use ruma::events::key::verification::cancel::CancelCode as RumaCancelCode; - - match c { - RumaCancelCode::User => Self::User, - RumaCancelCode::Timeout => Self::Timeout, - RumaCancelCode::UnknownTransaction => Self::UnknownTransaction, - RumaCancelCode::UnknownMethod => Self::UnknownMethod, - RumaCancelCode::UnexpectedMessage => Self::UnexpectedMessage, - RumaCancelCode::KeyMismatch => Self::KeyMismatch, - RumaCancelCode::UserMismatch => Self::UserMismatch, - RumaCancelCode::InvalidMessage => Self::InvalidMessage, - RumaCancelCode::Accepted => Self::Accepted, - RumaCancelCode::_Custom(_) => Self::User, - } - } -} - include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index a730884d28..8cdfd40e57 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -36,8 +36,8 @@ use matrix_sdk_crypto::{ use crate::{ error::{CryptoStoreError, DecryptionError, MachineCreationError}, responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, - CancelCode, DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, - ProgressListener, Request, RequestType, + DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, + Request, RequestType, }; /// A high level state machine that handles E2EE for Matrix. @@ -50,10 +50,13 @@ pub struct Sas { pub other_user_id: String, pub other_device_id: String, pub flow_id: String, + pub room_id: Option, pub have_we_confirmed: bool, pub is_cancelled: bool, pub is_done: bool, - pub cancel_code: Option, + pub cancel_code: Option, + pub cancelled_by_us: Option, + pub we_started: bool, pub can_be_presented: bool, pub supports_emoji: bool, pub timed_out: bool, @@ -76,7 +79,10 @@ impl From for Sas { timed_out: sas.timed_out(), supports_emoji: sas.supports_emoji(), have_we_confirmed: sas.have_we_confirmed(), - cancel_code: sas.cancel_code().map(|c| c.into()), + cancel_code: sas.cancel_code().map(|c| c.as_str().to_owned()), + we_started: sas.we_started(), + room_id: sas.room_id().map(|r| r.to_string()), + cancelled_by_us: sas.cancelled_by_us(), } } } @@ -89,7 +95,7 @@ pub struct VerificationRequest { pub is_done: bool, pub is_ready: bool, pub room_id: Option, - pub cancel_code: Option, + pub cancel_code: Option, pub we_started: bool, pub is_passive: bool, pub their_methods: Option>, @@ -106,7 +112,7 @@ impl From for VerificationRequest { is_done: v.is_done(), is_ready: v.is_ready(), room_id: v.room_id().map(|r| r.to_string()), - cancel_code: v.cancel_code().map(|c| c.into()), + cancel_code: v.cancel_code().map(|c| c.as_str().to_owned()), we_started: v.we_started(), is_passive: v.is_passive(), their_methods: v @@ -699,12 +705,13 @@ impl OlmMachine { &self, user_id: &str, flow_id: &str, + cancel_code: &str, ) -> Option { let user_id = UserId::try_from(user_id).ok()?; if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { match verification { - Verification::SasV1(v) => v.cancel().map(|r| r.into()), + Verification::SasV1(v) => v.cancel_with_code(cancel_code.into()).map(|r| r.into()), Verification::QrV1(v) => v.cancel().map(|r| r.into()), } } else { diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index fb17755e8d..41baa128a3 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -74,7 +74,10 @@ dictionary Sas { string other_user_id; string other_device_id; string flow_id; - CancelCode? cancel_code; + string? cancel_code; + string? room_id; + boolean we_started; + boolean? cancelled_by_us; boolean have_we_confirmed; boolean is_done; boolean is_cancelled; @@ -93,24 +96,12 @@ dictionary VerificationRequest { boolean we_started; boolean is_passive; string? room_id; - CancelCode? cancel_code; + string? cancel_code; sequence? their_methods; sequence? our_methods; }; -enum CancelCode { - "User", - "Timeout", - "UnknownTransaction", - "UnknownMethod", - "UnexpectedMessage", - "KeyMismatch", - "UserMismatch", - "InvalidMessage", - "Accepted", -}; - dictionary KeyRequestPair { Request? cancellation; Request key_request; @@ -188,7 +179,11 @@ interface OlmMachine { StartSasResult? start_sas_verification([ByRef] string user_id, [ByRef] string flow_id); [Throws=CryptoStoreError] OutgoingVerificationRequest? confirm_verification([ByRef] string user_id, [ByRef] string flow_id); - OutgoingVerificationRequest? cancel_verification([ByRef] string user_id, [ByRef] string flow_id); + OutgoingVerificationRequest? cancel_verification( + [ByRef] string user_id, + [ByRef] string flow_id, + [ByRef] string cancel_code + ); OutgoingVerificationRequest? accept_sas_verification([ByRef] string user_id, [ByRef] string flow_id); sequence? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); From f95c4ae08836ae4666f0ac21204b0781c70c1398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 25 Jun 2021 13:40:11 +0200 Subject: [PATCH 108/252] crypto: Allow cancelling of SAS transactions --- .../android/sdk/internal/crypto/OlmMachine.kt | 2 +- .../internal/crypto/RustSasVerification.kt | 76 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index e05287052a..7d93ee715e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -112,7 +112,7 @@ private fun toCryptoDeviceInfo(device: Device): CryptoDeviceInfo { // Kotlin side care about signatures? mapOf(), UnsignedDeviceInfo(device.displayName), - DeviceTrustLevel(crossSigningVerified = device.verified, locallyVerified = device.locallyVerified), + DeviceTrustLevel(crossSigningVerified = device.crossSigningTrusted, locallyVerified = device.locallyTrusted), device.isBlocked, // TODO null) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index 6a8ab11d82..86be1b9cc6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -68,7 +68,7 @@ internal class SasVerification( override val isIncoming: Boolean get() { - return false + return !this.inner.weStarted } override var otherDeviceId: String? @@ -113,19 +113,19 @@ internal class SasVerification( } override fun cancel() { - TODO() + this.cancelHelper(CancelCode.User) } override fun cancel(code: CancelCode) { - TODO() + this.cancelHelper(code) } override fun shortCodeDoesNotMatch() { - TODO() + this.cancelHelper(CancelCode.MismatchedSas) } override fun isToDeviceTransport(): Boolean { - return false + return this.inner.roomId == null } override fun supportsDecimal(): Boolean { @@ -142,41 +142,23 @@ internal class SasVerification( } override fun userHasVerifiedShortCode() { - runBlocking { - when (val request = confirm()) { + val request = runBlocking { confirm() } ?: return + sendRequest(request) + } + + suspend fun accept() { + val request = this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId) + + if (request != null) { + when (request) { is OutgoingVerificationRequest.ToDevice -> { sender.sendToDevice(request.eventType, request.body) + } + is OutgoingVerificationRequest.InRoom -> TODO() } - - else -> {} - } + refreshData() + dispatchTxUpdated() } - refreshData() - dispatchTxUpdated() - } - - fun isCanceled(): Boolean { - refreshData() - return this.inner.isCancelled - } - - 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.acceptSasVerification(this.inner.otherUserId, inner.flowId) } @Throws(CryptoStoreErrorException::class) @@ -185,8 +167,12 @@ internal class SasVerification( machine.confirmVerification(inner.otherUserId, inner.flowId) } - fun cancelHelper(): OutgoingVerificationRequest? { - return this.machine.cancelVerification(this.inner.otherUserId, inner.flowId) + fun cancelHelper(code: CancelCode) { + val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value) + + if (request != null) { + sendRequest(request) + } } override fun getEmojiCodeRepresentation(): List { @@ -200,4 +186,18 @@ internal class SasVerification( return decimals?.joinToString(" ") ?: "" } + + fun sendRequest(request: OutgoingVerificationRequest) { + runBlocking { + when (request) { + is OutgoingVerificationRequest.ToDevice -> { + sender.sendToDevice(request.eventType, request.body) + } + is OutgoingVerificationRequest.InRoom -> TODO() + } + } + + refreshData() + dispatchTxUpdated() + } } From 846242217b9d441cb8f44379f0018d792241e71e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 25 Jun 2021 14:06:48 +0200 Subject: [PATCH 109/252] crypto: Move the VerificationRequest into a separate file --- .../android/sdk/internal/crypto/OlmMachine.kt | 152 ---------------- .../internal/crypto/VerificationRequest.kt | 172 ++++++++++++++++++ .../verification/RustVerificationService.kt | 2 - 3 files changed, 172 insertions(+), 154 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 7d93ee715e..3bbd7b4524 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -26,12 +26,6 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext 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.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest -import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady -import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest -import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod -import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf 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.util.JsonDict @@ -40,10 +34,6 @@ 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.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS 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 @@ -56,13 +46,10 @@ import uniffi.olm.DeviceLists import uniffi.olm.KeyRequestPair import uniffi.olm.Logger import uniffi.olm.OlmMachine as InnerMachine -import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType import uniffi.olm.Sas -import uniffi.olm.StartSasResult -import uniffi.olm.VerificationRequest as InnerRequest import uniffi.olm.setLogger class CryptoLogger : Logger { @@ -130,145 +117,6 @@ internal class DeviceUpdateObserver { } } -internal class VerificationRequest( - private val machine: InnerMachine, - private var inner: InnerRequest -) { - private fun refreshData() { - val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) - - if (request != null) { - this.inner = request - } - - return - } - - fun acceptWithMethods(methods: List): OutgoingVerificationRequest? { - val stringMethods: MutableList = - methods - .map { - when (it) { - VerificationMethod.QR_CODE_SCAN -> VERIFICATION_METHOD_QR_CODE_SCAN - VerificationMethod.QR_CODE_SHOW -> VERIFICATION_METHOD_QR_CODE_SHOW - VerificationMethod.SAS -> VERIFICATION_METHOD_SAS - } - } - .toMutableList() - - if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || - stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { - stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) - } - - return this.machine.acceptVerificationRequest( - this.inner.otherUserId, this.inner.flowId, stringMethods) - } - - fun isCanceled(): Boolean { - refreshData() - return this.inner.isCancelled - } - - fun isDone(): Boolean { - refreshData() - return this.inner.isDone - } - - fun isReady(): Boolean { - refreshData() - return this.inner.isReady - } - - suspend fun startSasVerification(): StartSasResult? { - refreshData() - - return withContext(Dispatchers.IO) { - machine.startSasVerification(inner.otherUserId, inner.flowId) - } - } - - fun toPendingVerificationRequest(): PendingVerificationRequest { - refreshData() - val code = this.inner.cancelCode - - val cancelCode = - if (code != null) { - safeValueOf(code) - } else { - null - } - - val ourMethods = this.inner.ourMethods - val theirMethods = this.inner.theirMethods - val otherDeviceId = this.inner.otherDeviceId - - var requestInfo: ValidVerificationInfoRequest? = null - var readyInfo: ValidVerificationInfoReady? = null - - if (this.inner.weStarted && ourMethods != null) { - requestInfo = - ValidVerificationInfoRequest( - this.inner.flowId, - this.machine.deviceId(), - ourMethods, - null, - ) - } else if (!this.inner.weStarted && ourMethods != null) { - readyInfo = - ValidVerificationInfoReady( - this.inner.flowId, - this.machine.deviceId(), - ourMethods, - ) - } - - if (this.inner.weStarted && theirMethods != null && otherDeviceId != null) { - readyInfo = - ValidVerificationInfoReady( - this.inner.flowId, - otherDeviceId, - theirMethods, - ) - } else if (!this.inner.weStarted && theirMethods != null && otherDeviceId != null) { - requestInfo = - ValidVerificationInfoRequest( - this.inner.flowId, - otherDeviceId, - theirMethods, - System.currentTimeMillis(), - ) - } - - return PendingVerificationRequest( - // Creation time - System.currentTimeMillis(), - // Who initiated the request - !this.inner.weStarted, - // Local echo id, what to do here? - this.inner.flowId, - // other user - this.inner.otherUserId, - // room id - this.inner.roomId, - // transaction id - this.inner.flowId, - // val requestInfo: ValidVerificationInfoRequest? = null, - requestInfo, - // val readyInfo: ValidVerificationInfoReady? = null, - readyInfo, - // cancel code if there is one - cancelCode, - // are we done/successful - this.inner.isDone, - // did another device answer the request - this.inner.isPassive, - // devices that should receive the events we send out - null, - ) - } -} - internal class OlmMachine( user_id: String, device_id: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt new file mode 100644 index 0000000000..10b23ff0ad --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest +import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady +import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest +import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod +import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS +import uniffi.olm.OlmMachine +import uniffi.olm.OutgoingVerificationRequest +import uniffi.olm.StartSasResult +import uniffi.olm.VerificationRequest + +internal class VerificationRequest( + private val machine: OlmMachine, + private var inner: VerificationRequest +) { + private fun refreshData() { + val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) + + if (request != null) { + this.inner = request + } + + return + } + + fun acceptWithMethods(methods: List): OutgoingVerificationRequest? { + val stringMethods: MutableList = + methods + .map { + when (it) { + VerificationMethod.QR_CODE_SCAN -> VERIFICATION_METHOD_QR_CODE_SCAN + VerificationMethod.QR_CODE_SHOW -> VERIFICATION_METHOD_QR_CODE_SHOW + VerificationMethod.SAS -> VERIFICATION_METHOD_SAS + } + } + .toMutableList() + + if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || + stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { + stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) + } + + return this.machine.acceptVerificationRequest( + this.inner.otherUserId, this.inner.flowId, stringMethods) + } + + fun isCanceled(): Boolean { + refreshData() + return this.inner.isCancelled + } + + fun isDone(): Boolean { + refreshData() + return this.inner.isDone + } + + fun isReady(): Boolean { + refreshData() + return this.inner.isReady + } + + suspend fun startSasVerification(): StartSasResult? { + refreshData() + + return withContext(Dispatchers.IO) { + machine.startSasVerification(inner.otherUserId, inner.flowId) + } + } + + fun toPendingVerificationRequest(): PendingVerificationRequest { + refreshData() + val code = this.inner.cancelCode + + val cancelCode = + if (code != null) { + safeValueOf(code) + } else { + null + } + + val ourMethods = this.inner.ourMethods + val theirMethods = this.inner.theirMethods + val otherDeviceId = this.inner.otherDeviceId + + var requestInfo: ValidVerificationInfoRequest? = null + var readyInfo: ValidVerificationInfoReady? = null + + if (this.inner.weStarted && ourMethods != null) { + requestInfo = + ValidVerificationInfoRequest( + this.inner.flowId, + this.machine.deviceId(), + ourMethods, + null, + ) + } else if (!this.inner.weStarted && ourMethods != null) { + readyInfo = + ValidVerificationInfoReady( + this.inner.flowId, + this.machine.deviceId(), + ourMethods, + ) + } + + if (this.inner.weStarted && theirMethods != null && otherDeviceId != null) { + readyInfo = + ValidVerificationInfoReady( + this.inner.flowId, + otherDeviceId, + theirMethods, + ) + } else if (!this.inner.weStarted && theirMethods != null && otherDeviceId != null) { + requestInfo = + ValidVerificationInfoRequest( + this.inner.flowId, + otherDeviceId, + theirMethods, + System.currentTimeMillis(), + ) + } + + return PendingVerificationRequest( + // Creation time + System.currentTimeMillis(), + // Who initiated the request + !this.inner.weStarted, + // Local echo id, what to do here? + this.inner.flowId, + // other user + this.inner.otherUserId, + // room id + this.inner.roomId, + // transaction id + this.inner.flowId, + // val requestInfo: ValidVerificationInfoRequest? = null, + requestInfo, + // val readyInfo: ValidVerificationInfoReady? = null, + readyInfo, + // cancel code if there is one + cancelCode, + // are we done/successful + this.inner.isDone, + // did another device answer the request + this.inner.isPassive, + // devices that should receive the events we send out + null, + ) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 0630830ce0..b103607c78 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -178,13 +178,11 @@ constructor( // TODO This should be handled inside the rust-sdk decryption method } - // TODO All this methods should be delegated to a TransactionStore override fun getExistingTransaction( otherUserId: String, tid: String, ): VerificationTransaction? { val verification = this.olmMachine.getVerification(otherUserId, tid) ?: return null - return SasVerification(this.olmMachine.inner(), verification, this.requestSender, this.listeners) } From d15269a4bd54e6bb7e1004c75d8baf823adc3a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 25 Jun 2021 18:01:44 +0200 Subject: [PATCH 110/252] rust: Add methods for the QR code verification --- rust-sdk/Cargo.toml | 9 ++--- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 80 +++++++++++++++++++++++++++++++++++++---- rust-sdk/src/olm.udl | 24 ++++++++++++- 4 files changed, 102 insertions(+), 13 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index fdf306d537..30556a48b4 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -12,6 +12,7 @@ name = "matrix_crypto" serde = "1.0.126" serde_json = "1.0.64" http = "0.2.4" +base64 = "0.13.0" thiserror = "1.0.25" tracing = "0.1.26" @@ -19,20 +20,20 @@ tracing-subscriber = "0.2.18" uniffi = "0.12.0" [dependencies.js_int] -version = "0.2.0" +version = "0.2.1" features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "710b519c110278a0857f26a86a0f8329609c1a5f" +rev = "b62f725bead1f44b2038784e5321909f71a4af4a" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "710b519c110278a0857f26a86a0f8329609c1a5f" +rev = "b62f725bead1f44b2038784e5321909f71a4af4a" features = ["sled_cryptostore"] [dependencies.tokio] -version = "1.6.0" +version = "1.7.1" default_features = false features = ["rt-multi-thread"] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index fe2d973033..e21591d976 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -7,7 +7,7 @@ mod responses; pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; 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::{ DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, }; diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 8cdfd40e57..417cf54c83 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -5,6 +5,7 @@ use std::{ }; use js_int::UInt; +use base64::encode; use ruma::{ api::{ client::r0::{ @@ -30,7 +31,8 @@ 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, - Sas as InnerSas, Verification, VerificationRequest as InnerVerificationRequest, + QrVerification as InnerQr, Sas as InnerSas, Verification as RustVerification, + VerificationRequest as InnerVerificationRequest, }; use crate::{ @@ -46,6 +48,11 @@ pub struct OlmMachine { runtime: Runtime, } +pub enum Verification { + SasV1 { sas: Sas }, + QrCodeV1 { qrcode: QrCode }, +} + pub struct Sas { pub other_user_id: String, pub other_device_id: String, @@ -62,6 +69,36 @@ pub struct Sas { 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, + pub is_cancelled: bool, + pub is_done: bool, + pub we_started: bool, + pub other_side_scanned: bool, + pub cancel_code: Option, + pub cancelled_by_us: Option, +} + +impl From 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 sas: Sas, pub request: OutgoingVerificationRequest, @@ -661,11 +698,38 @@ impl OlmMachine { todo!() } - pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { + pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { 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())) + .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, 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 { + 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( @@ -711,8 +775,10 @@ impl OlmMachine { if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { match verification { - Verification::SasV1(v) => v.cancel_with_code(cancel_code.into()).map(|r| r.into()), - Verification::QrV1(v) => v.cancel().map(|r| r.into()), + RustVerification::SasV1(v) => { + v.cancel_with_code(cancel_code.into()).map(|r| r.into()) + } + RustVerification::QrV1(v) => v.cancel().map(|r| r.into()), } } else { None @@ -729,10 +795,10 @@ impl OlmMachine { Ok( if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { match verification { - Verification::SasV1(v) => { + RustVerification::SasV1(v) => { 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 { None diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 41baa128a3..47cb8a6c08 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -86,6 +86,19 @@ dictionary Sas { 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 { string other_user_id; string? other_device_id; @@ -102,6 +115,12 @@ dictionary VerificationRequest { }; +[Enum] +interface Verification { + SasV1(Sas sas); + QrCodeV1(QrCode qrcode); +}; + dictionary KeyRequestPair { Request? cancellation; Request key_request; @@ -167,7 +186,7 @@ interface OlmMachine { sequence get_verification_requests([ByRef] string user_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( [ByRef] string user_id, @@ -185,6 +204,9 @@ interface OlmMachine { [ByRef] string cancel_code ); 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? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); sequence? get_decimals([ByRef] string user_id, [ByRef] string flow_id); From 6523ca5afec05ed3989a18fbf3a47896747a49bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 25 Jun 2021 20:24:56 +0200 Subject: [PATCH 111/252] crypto: Allow the displaying of QR codes --- .../android/sdk/internal/crypto/OlmMachine.kt | 159 ++++++++++++++++-- .../internal/crypto/RustSasVerification.kt | 10 +- .../internal/crypto/VerificationRequest.kt | 20 ++- .../verification/RustVerificationService.kt | 46 ++++- 4 files changed, 212 insertions(+), 23 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 3bbd7b4524..6868d5b997 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal.crypto +import android.os.Handler +import android.os.Looper import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import java.io.File @@ -26,10 +28,16 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext 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.verification.CancelCode +import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState +import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf 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.util.JsonDict import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 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 @@ -45,11 +53,14 @@ import uniffi.olm.Device import uniffi.olm.DeviceLists import uniffi.olm.KeyRequestPair import uniffi.olm.Logger +import uniffi.olm.OutgoingVerificationRequest +import uniffi.olm.QrCode import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType -import uniffi.olm.Sas +import uniffi.olm.Verification +import uniffi.olm.VerificationRequest import uniffi.olm.setLogger class CryptoLogger : Logger { @@ -117,6 +128,136 @@ internal class DeviceUpdateObserver { } } +internal class QrCodeVerification( + private val machine: uniffi.olm.OlmMachine, + private var inner: QrCode, + private val sender: RequestSender, + private val listeners: ArrayList, +) : QrCodeVerificationTransaction { + private val uiHandler = Handler(Looper.getMainLooper()) + private var stateField: VerificationTxState = VerificationTxState.OnStarted + + private fun dispatchTxUpdated() { + uiHandler.post { + listeners.forEach { + try { + it.transactionUpdated(this) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + override val qrCodeText: String? + get() { + val data = this.machine.generateQrCode(this.inner.otherUserId, this.inner.flowId) + + // TODO Why are we encoding this to ISO_8859_1? If we're going to encode, why not base64? + return data?.fromBase64()?.toString(Charsets.ISO_8859_1) + } + + override fun userHasScannedOtherQrCode(otherQrCodeText: String) { + TODO("Not yet implemented") + } + + override fun otherUserScannedMyQrCode() { + val request = runBlocking { confirm() } ?: return + sendRequest(request) + } + + override fun otherUserDidNotScannedMyQrCode() { + // TODO Is this code correct here? The old code seems to do this + cancelHelper(CancelCode.MismatchedKeys) + } + + override var state: VerificationTxState + get() { + refreshData() + val state = when { + this.inner.isDone -> VerificationTxState.Verified + this.inner.otherSideScanned -> VerificationTxState.QrScannedByOther + this.inner.isCancelled -> { + val cancelCode = safeValueOf(this.inner.cancelCode) + val byMe = this.inner.cancelledByUs ?: false + VerificationTxState.Cancelled(cancelCode, byMe) + } + else -> { + VerificationTxState.None + } + } + + return state + } + @Suppress("UNUSED_PARAMETER") + set(value) {} + + override val transactionId: String + get() = this.inner.flowId + + override val otherUserId: String + get() = this.inner.otherUserId + + override var otherDeviceId: String? + get() = this.inner.otherDeviceId + @Suppress("UNUSED_PARAMETER") + set(value) {} + + override val isIncoming: Boolean + get() = !this.inner.weStarted + + override fun cancel() { + cancelHelper(CancelCode.User) + } + + override fun cancel(code: CancelCode) { + cancelHelper(code) + } + + override fun isToDeviceTransport(): Boolean { + return this.inner.roomId == null + } + + @Throws(CryptoStoreErrorException::class) + suspend fun confirm(): OutgoingVerificationRequest? = + withContext(Dispatchers.IO) { + machine.confirmVerification(inner.otherUserId, inner.flowId) + } + + private fun sendRequest(request: OutgoingVerificationRequest) { + runBlocking { + when (request) { + is OutgoingVerificationRequest.ToDevice -> { + sender.sendToDevice(request.eventType, request.body) + } + is OutgoingVerificationRequest.InRoom -> TODO() + } + } + + refreshData() + dispatchTxUpdated() + } + + private fun cancelHelper(code: CancelCode) { + val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value) + + if (request != null) { + sendRequest(request) + } + } + + private fun refreshData() { + when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { + is Verification.QrCodeV1 -> { + this.inner = verification.qrcode + } + else -> {} + } + + return + } +} + internal class OlmMachine( user_id: String, device_id: String, @@ -523,24 +664,16 @@ internal class OlmMachine( runBlocking { inner.discardRoomKey(roomId) } } - fun getVerificationRequests(userId: String): List { - return this.inner.getVerificationRequests(userId).map { - VerificationRequest(this.inner, it) - } + fun getVerificationRequests(userId: String): List { + return this.inner.getVerificationRequests(userId) } fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? { - val request = this.inner.getVerificationRequest(userId, flowId) - - return if (request == null) { - null - } else { - VerificationRequest(this.inner, request) - } + return this.inner.getVerificationRequest(userId, flowId) } /** Get an active verification */ - fun getVerification(userId: String, flowId: String): Sas? { + fun getVerification(userId: String, flowId: String): Verification? { return this.inner.getVerification(userId, flowId) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index 86be1b9cc6..9c4ca62e9f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -33,6 +33,7 @@ import uniffi.olm.CryptoStoreErrorException import uniffi.olm.OlmMachine import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.Sas +import uniffi.olm.Verification internal class SasVerification( private val machine: OlmMachine, @@ -57,10 +58,11 @@ internal class SasVerification( } private fun refreshData() { - val sas = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId) - - if (sas != null) { - this.inner = sas + when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { + is Verification.SasV1 -> { + this.inner = verification.sas + } + else -> {} } return diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 10b23ff0ad..78df72a928 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -22,6 +22,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificatio import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW @@ -34,7 +35,9 @@ import uniffi.olm.VerificationRequest internal class VerificationRequest( private val machine: OlmMachine, - private var inner: VerificationRequest + private var inner: VerificationRequest, + private val sender: RequestSender, + private val listeners: ArrayList, ) { private fun refreshData() { val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) @@ -46,6 +49,21 @@ internal class VerificationRequest( return } + internal fun startQrVerification(): QrCodeVerification? { + val qrcode = this.machine.startQrVerification(this.inner.otherUserId, this.inner.flowId) + + return if (qrcode != null) { + QrCodeVerification( + this.machine, + qrcode, + this.sender, + this.listeners, + ) + } else { + null + } + } + fun acceptWithMethods(methods: List): OutgoingVerificationRequest? { val stringMethods: MutableList = methods diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index b103607c78..cbf8ca32ca 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -29,14 +29,17 @@ import org.matrix.android.sdk.api.session.events.model.EventType 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.QrCodeVerification import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.SasVerification +import org.matrix.android.sdk.internal.crypto.VerificationRequest 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.session.SessionScope import timber.log.Timber import uniffi.olm.OutgoingVerificationRequest +import uniffi.olm.Verification @SessionScope internal class RustVerificationService @@ -183,13 +186,16 @@ constructor( tid: String, ): VerificationTransaction? { val verification = this.olmMachine.getVerification(otherUserId, tid) ?: return null - return SasVerification(this.olmMachine.inner(), verification, this.requestSender, this.listeners) + return when (verification) { + is Verification.QrCodeV1 -> QrCodeVerification(this.olmMachine.inner(), verification.qrcode, this.requestSender, this.listeners) + is Verification.SasV1 -> SasVerification(this.olmMachine.inner(), verification.sas, this.requestSender, this.listeners) + } } override fun getExistingVerificationRequests( otherUserId: String ): List { - return this.olmMachine.getVerificationRequests(otherUserId).map { + return this.getVerificationRequests(otherUserId).map { it.toPendingVerificationRequest() } } @@ -199,7 +205,7 @@ constructor( tid: String? ): PendingVerificationRequest? { return if (tid != null) { - olmMachine.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest() + this.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest() } else { null } @@ -221,7 +227,7 @@ constructor( // should check if already one (and cancel it) return if (method == VerificationMethod.SAS) { val flowId = transactionId ?: return null - val request = this.olmMachine.getVerificationRequest(otherUserId, flowId) + val request = this.getVerificationRequest(otherUserId, flowId) runBlocking { val response = request?.startSasVerification() if (response != null) { @@ -297,12 +303,38 @@ constructor( return true } + private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? { + val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) + + return if (request != null) { + VerificationRequest( + this.olmMachine.inner(), + request, + requestSender, + listeners, + ) + } else { + null + } + } + + private fun getVerificationRequests(userId: String): List { + return this.olmMachine.getVerificationRequests(userId).map { + VerificationRequest( + this.olmMachine.inner(), + it, + this.requestSender, + this.listeners, + ) + } + } + override fun readyPendingVerification( methods: List, otherUserId: String, transactionId: String ): Boolean { - val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) + val request = this.getVerificationRequest(otherUserId, transactionId) return if (request != null) { val outgoingRequest = request.acceptWithMethods(methods) @@ -310,6 +342,10 @@ constructor( if (outgoingRequest != null) { runBlocking { sendRequest(outgoingRequest) } dispatchRequestUpdated(request.toPendingVerificationRequest()) + val qrcode = request.startQrVerification() + if (qrcode != null) { + dispatchTxAdded(qrcode) + } true } else { false From 4473af85b1b1d7a8bb0d1da00962107ec96329c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 09:50:59 +0200 Subject: [PATCH 112/252] crypto: Move more of the request sending logic into the sender class --- .../internal/crypto/DefaultCryptoService.kt | 18 ++++++- .../android/sdk/internal/crypto/OlmMachine.kt | 1 - .../internal/crypto/RustSasVerification.kt | 14 +---- .../internal/crypto/VerificationRequest.kt | 37 +++++++++++-- .../verification/RustVerificationService.kt | 52 +++++-------------- 5 files changed, 66 insertions(+), 56 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index bacc9e1456..5764f078f7 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -92,6 +92,7 @@ import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.task.launchToCallback import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import timber.log.Timber +import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.Request import uniffi.olm.RequestType import java.io.File @@ -103,6 +104,21 @@ import kotlin.math.max internal class RequestSender( private val sendToDeviceTask: SendToDeviceTask, ) { + suspend fun sendVerificationRequest(request: OutgoingVerificationRequest) { + when (request) { + is OutgoingVerificationRequest.InRoom -> TODO() + is OutgoingVerificationRequest.ToDevice -> sendToDevice(request) + } + } + + suspend fun sendToDevice(request: Request.ToDevice) { + sendToDevice(request.eventType, request.body) + } + + suspend fun sendToDevice(request: OutgoingVerificationRequest.ToDevice) { + sendToDevice(request.eventType, request.body) + } + suspend fun sendToDevice(eventType: String, body: String) { // TODO this produces floats for the Olm type fields, which // are integers originally. @@ -808,7 +824,7 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun sendToDevice(request: Request.ToDevice) { - this.sender.sendToDevice(request.eventType, request.body) + this.sender.sendToDevice(request) olmMachine!!.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}") } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 6868d5b997..59e122d518 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -135,7 +135,6 @@ internal class QrCodeVerification( private val listeners: ArrayList, ) : QrCodeVerificationTransaction { private val uiHandler = Handler(Looper.getMainLooper()) - private var stateField: VerificationTxState = VerificationTxState.OnStarted private fun dispatchTxUpdated() { uiHandler.post { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index 9c4ca62e9f..d38662abec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -152,12 +152,7 @@ internal class SasVerification( val request = this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId) if (request != null) { - when (request) { - is OutgoingVerificationRequest.ToDevice -> { - sender.sendToDevice(request.eventType, request.body) - } - is OutgoingVerificationRequest.InRoom -> TODO() - } + this.sender.sendVerificationRequest(request) refreshData() dispatchTxUpdated() } @@ -191,12 +186,7 @@ internal class SasVerification( fun sendRequest(request: OutgoingVerificationRequest) { runBlocking { - when (request) { - is OutgoingVerificationRequest.ToDevice -> { - sender.sendToDevice(request.eventType, request.body) - } - is OutgoingVerificationRequest.InRoom -> TODO() - } + sender.sendVerificationRequest(request) } refreshData() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 78df72a928..24edebc085 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal.crypto +import android.os.Handler +import android.os.Looper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest @@ -28,8 +30,10 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS +import timber.log.Timber import uniffi.olm.OlmMachine import uniffi.olm.OutgoingVerificationRequest +import uniffi.olm.Sas import uniffi.olm.StartSasResult import uniffi.olm.VerificationRequest @@ -39,6 +43,8 @@ internal class VerificationRequest( private val sender: RequestSender, private val listeners: ArrayList, ) { + private val uiHandler = Handler(Looper.getMainLooper()) + private fun refreshData() { val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) @@ -49,6 +55,18 @@ internal class VerificationRequest( return } + private fun dispatchRequestUpdated() { + uiHandler.post { + listeners.forEach { + try { + it.verificationRequestUpdated(this.toPendingVerificationRequest()) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + internal fun startQrVerification(): QrCodeVerification? { val qrcode = this.machine.startQrVerification(this.inner.otherUserId, this.inner.flowId) @@ -64,7 +82,7 @@ internal class VerificationRequest( } } - fun acceptWithMethods(methods: List): OutgoingVerificationRequest? { + suspend fun acceptWithMethods(methods: List) { val stringMethods: MutableList = methods .map { @@ -81,8 +99,13 @@ internal class VerificationRequest( stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) } - return this.machine.acceptVerificationRequest( + val request = this.machine.acceptVerificationRequest( this.inner.otherUserId, this.inner.flowId, stringMethods) + + if (request != null) { + this.sender.sendVerificationRequest(request) + this.dispatchRequestUpdated() + } } fun isCanceled(): Boolean { @@ -100,11 +123,17 @@ internal class VerificationRequest( return this.inner.isReady } - suspend fun startSasVerification(): StartSasResult? { + suspend fun startSasVerification(): Sas? { refreshData() return withContext(Dispatchers.IO) { - machine.startSasVerification(inner.otherUserId, inner.flowId) + val result = machine.startSasVerification(inner.otherUserId, inner.flowId) + if (result != null) { + sender.sendVerificationRequest(result.request) + result.sas + } else { + null + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index cbf8ca32ca..d9af61029c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -36,9 +36,9 @@ import org.matrix.android.sdk.internal.crypto.VerificationRequest 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.model.rest.KeyVerificationStart import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber -import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.Verification @SessionScope @@ -101,18 +101,6 @@ constructor( } } - private fun dispatchRequestUpdated(tx: PendingVerificationRequest) { - uiHandler.post { - listeners.forEach { - try { - it.verificationRequestUpdated(tx) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } - override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { TODO() // setDeviceVerificationAction.handle(DeviceTrustLevel(false, true), @@ -224,17 +212,19 @@ constructor( otherDeviceId: String, transactionId: String? ): String? { + val flowId = transactionId ?: return null + // should check if already one (and cancel it) return if (method == VerificationMethod.SAS) { - val flowId = transactionId ?: return null val request = this.getVerificationRequest(otherUserId, flowId) + runBlocking { - val response = request?.startSasVerification() - if (response != null) { - sendRequest(response.request) - val sas = SasVerification(olmMachine.inner(), response.sas, requestSender, listeners) - dispatchTxAdded(sas) - sas.transactionId + val sas = request?.startSasVerification() + + if (sas != null) { + val sasTransaction = SasVerification(olmMachine.inner(), sas, requestSender, listeners) + dispatchTxAdded(sasTransaction) + sasTransaction.transactionId } else { null } @@ -337,15 +327,15 @@ constructor( val request = this.getVerificationRequest(otherUserId, transactionId) return if (request != null) { - val outgoingRequest = request.acceptWithMethods(methods) + runBlocking { request.acceptWithMethods(methods) } - if (outgoingRequest != null) { - runBlocking { sendRequest(outgoingRequest) } - dispatchRequestUpdated(request.toPendingVerificationRequest()) + if (request.isReady()) { val qrcode = request.startQrVerification() + if (qrcode != null) { dispatchTxAdded(qrcode) } + true } else { false @@ -355,20 +345,6 @@ constructor( } } - // TODO create a class that handles this, the DefaultCryptoService has - // similar needs so we could share code there, beware that local echo seems - // to be handled here - suspend fun sendRequest(request: OutgoingVerificationRequest) { - when (request) { - is OutgoingVerificationRequest.ToDevice -> { - this.requestSender.sendToDevice(request.eventType, request.body) - } - else -> {} - } - - // TODO move this into the VerificationRequest and Verification classes? - } - override fun transactionUpdated(tx: VerificationTransaction) { dispatchTxUpdated(tx) } From d21137d910b70562abc9ee331869dcba6eb2c6e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 09:57:32 +0200 Subject: [PATCH 113/252] crypto: Add a state for when we confirmed the QR code --- .../android/sdk/internal/crypto/OlmMachine.kt | 7 +-- .../verification/RustVerificationService.kt | 44 +++++++++---------- rust-sdk/Cargo.toml | 4 +- rust-sdk/src/machine.rs | 4 +- rust-sdk/src/olm.udl | 1 + 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 59e122d518..04a51c723c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -174,14 +174,15 @@ internal class QrCodeVerification( get() { refreshData() val state = when { - this.inner.isDone -> VerificationTxState.Verified + this.inner.isDone -> VerificationTxState.Verified + this.inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm this.inner.otherSideScanned -> VerificationTxState.QrScannedByOther - this.inner.isCancelled -> { + this.inner.isCancelled -> { val cancelCode = safeValueOf(this.inner.cancelCode) val byMe = this.inner.cancelledByUs ?: false VerificationTxState.Cancelled(cancelCode, byMe) } - else -> { + else -> { VerificationTxState.None } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index d9af61029c..b326639de7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -116,26 +116,25 @@ constructor( // } } - suspend fun onEvent(event: Event) { - when (event.getClearType()) { - EventType.KEY_VERIFICATION_START -> {} - EventType.KEY_VERIFICATION_CANCEL -> {} - EventType.KEY_VERIFICATION_ACCEPT -> {} - EventType.KEY_VERIFICATION_KEY -> { - onKeyReceived(event) - } - EventType.KEY_VERIFICATION_MAC -> {} - EventType.KEY_VERIFICATION_READY -> {} - EventType.KEY_VERIFICATION_DONE -> { - onDone(event) - } - MessageType.MSGTYPE_VERIFICATION_REQUEST -> { - onRequestReceived(event) - } - else -> { - // ignore - } - } + fun onEvent(event: Event) = when (event.getClearType()) { + EventType.KEY_VERIFICATION_START -> onStart(event) + EventType.KEY_VERIFICATION_CANCEL -> {} + EventType.KEY_VERIFICATION_ACCEPT -> {} + EventType.KEY_VERIFICATION_KEY -> onKey(event) + EventType.KEY_VERIFICATION_MAC -> {} + EventType.KEY_VERIFICATION_READY -> {} + EventType.KEY_VERIFICATION_DONE -> onDone(event) + MessageType.MSGTYPE_VERIFICATION_REQUEST -> onRequest(event) + else -> {} + } + + private fun onStart(event: Event) { + val content = event.getClearContent().toModel() ?: return + val flowId = content.transactionId ?: return + val sender = event.senderId ?: return + + val verification = this.getExistingTransaction(sender, flowId) ?: return + dispatchTxUpdated(verification) } private fun onDone(event: Event) { @@ -146,7 +145,8 @@ constructor( val verification = this.getExistingTransaction(sender, flowId) ?: return dispatchTxUpdated(verification) } - private fun onKeyReceived(event: Event) { + + private fun onKey(event: Event) { val content = event.getClearContent().toModel() ?: return val flowId = content.transactionId ?: return val sender = event.senderId ?: return @@ -155,7 +155,7 @@ constructor( dispatchTxUpdated(verification) } - private fun onRequestReceived(event: Event) { + private fun onRequest(event: Event) { val content = event.getClearContent().toModel() ?: return val flowId = content.transactionId val sender = event.senderId ?: return diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 30556a48b4..7d1b6e73c2 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -25,11 +25,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "b62f725bead1f44b2038784e5321909f71a4af4a" +rev = "3bd43a16086415c17faa969432f18d9ed9e9c272" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "b62f725bead1f44b2038784e5321909f71a4af4a" +rev = "3bd43a16086415c17faa969432f18d9ed9e9c272" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 417cf54c83..aa2b581e07 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -78,6 +78,7 @@ pub struct QrCode { pub is_done: bool, pub we_started: bool, pub other_side_scanned: bool, + pub has_been_confirmed: bool, pub cancel_code: Option, pub cancelled_by_us: Option, } @@ -92,7 +93,8 @@ impl From for QrCode { 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_side_scanned: qr.has_been_scanned(), + has_been_confirmed: qr.has_been_confirmed(), other_device_id: qr.other_device_id().to_string(), room_id: qr.room_id().map(|r| r.to_string()), } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 47cb8a6c08..9b488d6962 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -93,6 +93,7 @@ dictionary QrCode { string? cancel_code; string? room_id; boolean we_started; + boolean has_been_confirmed; boolean? cancelled_by_us; boolean is_done; boolean is_cancelled; From 02b8b1f5b1b35de586588fe1615e68b4872843bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 10:16:31 +0200 Subject: [PATCH 114/252] crypto: Clean up the SAS verification transaction a bit --- .../internal/crypto/RustSasVerification.kt | 34 +++++-------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index d38662abec..df6cb2de52 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -43,7 +43,6 @@ internal class SasVerification( ) : SasVerificationTransaction { private val uiHandler = Handler(Looper.getMainLooper()) - private var stateField: VerificationTxState = VerificationTxState.OnStarted private fun dispatchTxUpdated() { uiHandler.post { @@ -69,24 +68,14 @@ internal class SasVerification( } override val isIncoming: Boolean - get() { - return !this.inner.weStarted - } + get() = !this.inner.weStarted override var otherDeviceId: String? - get() { - return this.inner.otherDeviceId - } - set(value) { - if (value != null) { - this.inner.otherDeviceId = value - } - } + get() = this.inner.otherDeviceId + @Suppress("UNUSED_PARAMETER") + set(value) {} - override val otherUserId: String - get() { - return this.inner.otherUserId - } + override val otherUserId: String = this.inner.otherUserId override var state: VerificationTxState get() { @@ -105,14 +94,11 @@ internal class SasVerification( } } } - set(v) { - this.stateField = v - } + @Suppress("UNUSED_PARAMETER") + set(v) {} override val transactionId: String - get() { - return this.inner.flowId - } + get() = this.inner.flowId override fun cancel() { this.cancelHelper(CancelCode.User) @@ -126,9 +112,7 @@ internal class SasVerification( this.cancelHelper(CancelCode.MismatchedSas) } - override fun isToDeviceTransport(): Boolean { - return this.inner.roomId == null - } + override fun isToDeviceTransport(): Boolean = this.inner.roomId == null override fun supportsDecimal(): Boolean { // This is ignored anyways, throw it away? From 05119bcf90de217b6302e2c51f3ce424317687e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 14:08:08 +0200 Subject: [PATCH 115/252] crypto: Allow devices to be marked manually as verified --- .../android/sdk/internal/crypto/OlmMachine.kt | 6 ++++ .../verification/RustVerificationService.kt | 13 +------- rust-sdk/src/lib.rs | 4 ++- rust-sdk/src/machine.rs | 32 ++++++++++++++++--- rust-sdk/src/olm.udl | 2 ++ 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 04a51c723c..ddd7cc4134 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -632,6 +632,12 @@ internal class OlmMachine( return plainDevices } + @Throws(CryptoStoreErrorException::class) + internal suspend fun markDeviceAsTrusted(userId: String, deviceId: String) = + withContext(Dispatchers.IO) { + inner.markDeviceAsTrusted(userId, deviceId) + } + /** Update all of our live device listeners. */ private suspend fun updateLiveDevices() { for ((liveDevice, users) in deviceUpdateObserver.listeners) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index b326639de7..26d9fd1ef6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -102,18 +102,7 @@ constructor( } override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { - TODO() - // setDeviceVerificationAction.handle(DeviceTrustLevel(false, true), - // userId, - // deviceID) - - // listeners.forEach { - // try { - // it.markedAsManuallyVerified(userId, deviceID) - // } catch (e: Throwable) { - // Timber.e(e, "## Error while notifying listeners") - // } - // } + runBlocking { olmMachine.markDeviceAsTrusted(userId, deviceID) } } fun onEvent(event: Event) = when (event.getClearType()) { diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index e21591d976..331c6336b2 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -7,7 +7,9 @@ mod responses; pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{KeyRequestPair, OlmMachine, Sas, StartSasResult, VerificationRequest, QrCode, Verification}; +pub use machine::{ + KeyRequestPair, OlmMachine, QrCode, Sas, StartSasResult, Verification, VerificationRequest, +}; pub use responses::{ DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, }; diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index aa2b581e07..bbce67d9a7 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -4,8 +4,8 @@ use std::{ io::Cursor, }; -use js_int::UInt; use base64::encode; +use js_int::UInt; use ruma::{ api::{ client::r0::{ @@ -30,9 +30,9 @@ 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, - QrVerification as InnerQr, Sas as InnerSas, Verification as RustVerification, - VerificationRequest as InnerVerificationRequest, + decrypt_key_export, encrypt_key_export, EncryptionSettings, LocalTrust, + OlmMachine as InnerMachine, QrVerification as InnerQr, Sas as InnerSas, + Verification as RustVerification, VerificationRequest as InnerVerificationRequest, }; use crate::{ @@ -227,6 +227,25 @@ impl OlmMachine { .map(|d| d.into())) } + pub fn mark_device_as_trusted( + &self, + user_id: &str, + device_id: &str, + ) -> Result<(), CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + + let device = self + .runtime + .block_on(self.inner.get_device(&user_id, device_id.into()))?; + + if let Some(device) = device { + self.runtime + .block_on(device.set_local_trust(LocalTrust::Verified))?; + } + + Ok(()) + } + /// Get all devices of an user. /// /// # Arguments @@ -731,7 +750,10 @@ impl OlmMachine { 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())) + .and_then(|v| { + v.qr_v1() + .and_then(|qr| qr.to_bytes().map(|b| encode(b)).ok()) + }) } pub fn start_sas_verification( diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 9b488d6962..2acb35bb23 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -177,6 +177,8 @@ interface OlmMachine { [Throws=CryptoStoreError] Device? get_device([ByRef] string user_id, [ByRef] string device_id); [Throws=CryptoStoreError] + void mark_device_as_trusted([ByRef] string user_id, [ByRef] string device_id); + [Throws=CryptoStoreError] sequence get_user_devices([ByRef] string user_id); void update_tracked_users(sequence users); From 1f7311a42802a603db62bf63cdcfccad6eda8711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 14:08:49 +0200 Subject: [PATCH 116/252] crypto: Allow verification requests to be canelled --- .../internal/crypto/VerificationRequest.kt | 10 +++++++ .../verification/RustVerificationService.kt | 30 +++++++++++++------ rust-sdk/src/machine.rs | 4 ++- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 24edebc085..79feb795f7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -20,6 +20,7 @@ import android.os.Handler import android.os.Looper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest @@ -108,6 +109,15 @@ internal class VerificationRequest( } } + suspend fun cancel() { + val request = this.machine.cancelVerification(this.inner.otherUserId, this.inner.flowId, CancelCode.User.value) + + if (request != null) { + this.sender.sendVerificationRequest(request) + this.dispatchRequestUpdated() + } + } + fun isCanceled(): Boolean { refreshData() return this.inner.isCancelled diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 26d9fd1ef6..4ccafd3a99 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -33,6 +33,7 @@ import org.matrix.android.sdk.internal.crypto.QrCodeVerification import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.SasVerification import org.matrix.android.sdk.internal.crypto.VerificationRequest +import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel 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 @@ -106,8 +107,10 @@ constructor( } fun onEvent(event: Event) = when (event.getClearType()) { + // TODO most of those methods do the same, we just need to get the + // flow id and the sender from the event, can we add a generic method for this? EventType.KEY_VERIFICATION_START -> onStart(event) - EventType.KEY_VERIFICATION_CANCEL -> {} + EventType.KEY_VERIFICATION_CANCEL -> onCancel(event) EventType.KEY_VERIFICATION_ACCEPT -> {} EventType.KEY_VERIFICATION_KEY -> onKey(event) EventType.KEY_VERIFICATION_MAC -> {} @@ -117,13 +120,24 @@ constructor( else -> {} } + private fun getAndDispatch(sender: String, flowId: String) { + val verification = this.getExistingTransaction(sender, flowId) ?: return + dispatchTxUpdated(verification) + } + + private fun onCancel(event: Event) { + val content = event.getClearContent().toModel() ?: return + val flowId = content.transactionId ?: return + val sender = event.senderId ?: return + + getAndDispatch(sender, flowId) + } private fun onStart(event: Event) { val content = event.getClearContent().toModel() ?: return val flowId = content.transactionId ?: return val sender = event.senderId ?: return - val verification = this.getExistingTransaction(sender, flowId) ?: return - dispatchTxUpdated(verification) + getAndDispatch(sender, flowId) } private fun onDone(event: Event) { @@ -131,8 +145,7 @@ constructor( val flowId = content.transactionId ?: return val sender = event.senderId ?: return - val verification = this.getExistingTransaction(sender, flowId) ?: return - dispatchTxUpdated(verification) + getAndDispatch(sender, flowId) } private fun onKey(event: Event) { @@ -140,8 +153,7 @@ constructor( val flowId = content.transactionId ?: return val sender = event.senderId ?: return - val verification = this.getExistingTransaction(sender, flowId) ?: return - dispatchTxUpdated(verification) + getAndDispatch(sender, flowId) } private fun onRequest(event: Event) { @@ -246,8 +258,8 @@ constructor( } override fun cancelVerificationRequest(request: PendingVerificationRequest) { - // TODO get the request out of the olm machine and cancel here - TODO() + val verificationRequest = request.transactionId?.let { this.getVerificationRequest(request.otherUserId, it) } + runBlocking { verificationRequest?.cancel() } } override fun declineVerificationRequestInDMs( diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index bbce67d9a7..8affeeca3f 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -797,7 +797,9 @@ impl OlmMachine { ) -> Option { let user_id = UserId::try_from(user_id).ok()?; - if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { + if let Some(request) = self.inner.get_verification_request(&user_id, flow_id) { + request.cancel().map(|r| r.into()) + } else if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { match verification { RustVerification::SasV1(v) => { v.cancel_with_code(cancel_code.into()).map(|r| r.into()) From 6bb7d5faaa24cdf301615ef67c995298f6c0106c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 15:25:31 +0200 Subject: [PATCH 117/252] crypto: Dispatch verification request cancellations as well --- .../matrix/android/sdk/internal/crypto/VerificationRequest.kt | 2 +- .../sdk/internal/crypto/verification/RustVerificationService.kt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 79feb795f7..c5d3a19cc7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -56,7 +56,7 @@ internal class VerificationRequest( return } - private fun dispatchRequestUpdated() { + internal fun dispatchRequestUpdated() { uiHandler.post { listeners.forEach { try { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 4ccafd3a99..41a0972b7a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -130,6 +130,7 @@ constructor( val flowId = content.transactionId ?: return val sender = event.senderId ?: return + this.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() getAndDispatch(sender, flowId) } private fun onStart(event: Event) { From 03499b5309fb1f1f696bb4b2d28671bccfc0ad83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 15:30:35 +0200 Subject: [PATCH 118/252] rust: Update the rust-sdk revision. --- rust-sdk/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 7d1b6e73c2..0a910616cb 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -25,11 +25,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "3bd43a16086415c17faa969432f18d9ed9e9c272" +rev = "59a07da99e76a162b71b026ed244fb0cbc39f0c9" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "3bd43a16086415c17faa969432f18d9ed9e9c272" +rev = "59a07da99e76a162b71b026ed244fb0cbc39f0c9" features = ["sled_cryptostore"] [dependencies.tokio] From 53b3f54808ca5b6010b3f1ab0d64eaa0c9fabfd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 29 Jun 2021 09:21:32 +0200 Subject: [PATCH 119/252] crypto: Add support to accept the short SAS verification flow --- .../SasVerificationTransaction.kt | 2 ++ .../internal/crypto/RustSasVerification.kt | 30 ++++++++++------- .../internal/crypto/VerificationRequest.kt | 2 -- ...comingSASDefaultVerificationTransaction.kt | 4 +++ ...tgoingSASDefaultVerificationTransaction.kt | 4 +++ .../verification/RustVerificationService.kt | 33 ++++++++++++++++--- rust-sdk/Cargo.toml | 4 +-- rust-sdk/src/machine.rs | 2 ++ rust-sdk/src/olm.udl | 1 + .../VerificationBottomSheetViewModel.kt | 8 ++++- .../features/navigation/DefaultNavigator.kt | 7 ++-- 11 files changed, 74 insertions(+), 23 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/SasVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/SasVerificationTransaction.kt index da546be68f..2922d98a62 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/SasVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/SasVerificationTransaction.kt @@ -32,5 +32,7 @@ interface SasVerificationTransaction : VerificationTransaction { */ fun userHasVerifiedShortCode() + fun acceptVerification() + fun shortCodeDoesNotMatch() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index df6cb2de52..63e2e0f3a4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -40,7 +40,7 @@ internal class SasVerification( private var inner: Sas, private val sender: RequestSender, private val listeners: ArrayList, - ) : +) : SasVerificationTransaction { private val uiHandler = Handler(Looper.getMainLooper()) @@ -58,10 +58,11 @@ internal class SasVerification( private fun refreshData() { when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { - is Verification.SasV1 -> { + is Verification.SasV1 -> { this.inner = verification.sas } - else -> {} + else -> { + } } return @@ -73,7 +74,8 @@ internal class SasVerification( override var otherDeviceId: String? get() = this.inner.otherDeviceId @Suppress("UNUSED_PARAMETER") - set(value) {} + set(value) { + } override val otherUserId: String = this.inner.otherUserId @@ -81,21 +83,21 @@ internal class SasVerification( get() { refreshData() return when { - this.inner.isDone -> VerificationTxState.Verified - this.inner.haveWeConfirmed -> VerificationTxState.ShortCodeAccepted - this.inner.canBePresented -> VerificationTxState.ShortCodeReady - this.inner.isCancelled -> { + this.inner.isCancelled -> { val cancelCode = safeValueOf(this.inner.cancelCode) val byMe = this.inner.cancelledByUs ?: false VerificationTxState.Cancelled(cancelCode, byMe) } - else -> { - VerificationTxState.Started - } + this.inner.isDone -> VerificationTxState.Verified + this.inner.haveWeConfirmed -> VerificationTxState.ShortCodeAccepted + this.inner.canBePresented -> VerificationTxState.ShortCodeReady + this.inner.hasBeenAccepted -> VerificationTxState.Accepted + else -> VerificationTxState.OnStarted } } @Suppress("UNUSED_PARAMETER") - set(v) {} + set(v) { + } override val transactionId: String get() = this.inner.flowId @@ -132,6 +134,10 @@ internal class SasVerification( sendRequest(request) } + override fun acceptVerification() { + runBlocking { accept() } + } + suspend fun accept() { val request = this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index c5d3a19cc7..ac3058b592 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -33,9 +33,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_REC import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS import timber.log.Timber import uniffi.olm.OlmMachine -import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.Sas -import uniffi.olm.StartSasResult import uniffi.olm.VerificationRequest internal class VerificationRequest( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt index fde9f70e7b..e061976618 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt @@ -82,6 +82,10 @@ internal class DefaultIncomingSASDefaultVerificationTransaction( } } + override fun acceptVerification() { + this.performAccept() + } + override fun onVerificationStart(startReq: ValidVerificationInfoStart.SasVerificationInfoStart) { Timber.v("## SAS I: received verification request from state $state") if (state != VerificationTxState.None) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt index 1a41f89006..d8568b0a96 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt @@ -85,6 +85,10 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction( cancel(CancelCode.UnexpectedMessage) } + override fun acceptVerification() { + return + } + fun start() { if (state != VerificationTxState.None) { Timber.e("## SAS O: start verification from invalid state") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 41a0972b7a..b39022589c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -103,10 +103,11 @@ constructor( } override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { + // TODO this doesn't seem to be used anymore? runBlocking { olmMachine.markDeviceAsTrusted(userId, deviceID) } } - fun onEvent(event: Event) = when (event.getClearType()) { + suspend fun onEvent(event: Event) = when (event.getClearType()) { // TODO most of those methods do the same, we just need to get the // flow id and the sender from the event, can we add a generic method for this? EventType.KEY_VERIFICATION_START -> onStart(event) @@ -133,12 +134,36 @@ constructor( this.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() getAndDispatch(sender, flowId) } - private fun onStart(event: Event) { + + private suspend fun onStart(event: Event) { val content = event.getClearContent().toModel() ?: return val flowId = content.transactionId ?: return val sender = event.senderId ?: return - getAndDispatch(sender, flowId) + val verification = this.getExistingTransaction(sender, flowId) ?: return + val request = this.getVerificationRequest(sender, flowId) + + if (request != null && request.isReady()) { + // If this is a SAS verification originating from a `m.key.verification.request` + // event we auto-accept here considering that we either initiated the request or + // accepted the request, otherwise it's a QR code verification, just dispatch an update. + if (verification is SasVerification) { + // Accept dispatches an update, no need to do it twice. + verification.accept() + } else { + dispatchTxUpdated(verification) + } + } else { + Timber.d("HELLOOOOO DISPATCHING NEW VERIFICATIONO $verification") + // This didn't originate from a request, so tell our listeners that + // this is a new verification. + dispatchTxAdded(verification) + // The IncomingVerificationRequestHandler seems to only listen to updates + // so let's trigger an update after the addition as well. + dispatchTxUpdated(verification) + } + + } private fun onDone(event: Event) { @@ -292,7 +317,7 @@ constructor( ): Boolean { Timber.e("## TRYING TO READY PENDING ROOM VERIFICATION") // TODO do the same as readyPendingVerification - return true + TODO() } private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? { diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 0a910616cb..963eec3424 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -25,11 +25,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "59a07da99e76a162b71b026ed244fb0cbc39f0c9" +rev = "d2e4b3f3bbcdc139560cdacbdf62dedab6f156b9" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "59a07da99e76a162b71b026ed244fb0cbc39f0c9" +rev = "d2e4b3f3bbcdc139560cdacbdf62dedab6f156b9" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 8affeeca3f..7deb409c45 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -63,6 +63,7 @@ pub struct Sas { pub is_done: bool, pub cancel_code: Option, pub cancelled_by_us: Option, + pub has_been_accepted: bool, pub we_started: bool, pub can_be_presented: bool, pub supports_emoji: bool, @@ -122,6 +123,7 @@ impl From for Sas { we_started: sas.we_started(), room_id: sas.room_id().map(|r| r.to_string()), cancelled_by_us: sas.cancelled_by_us(), + has_been_accepted: sas.has_been_accepted(), } } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 2acb35bb23..d3297b84c5 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -78,6 +78,7 @@ dictionary Sas { string? room_id; boolean we_started; boolean? cancelled_by_us; + boolean has_been_accepted; boolean have_we_confirmed; boolean is_done; boolean is_cancelled; diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 8e21412715..f38dcb6a4e 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -41,7 +41,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.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction @@ -466,11 +465,18 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( // is this an incoming with that user if (tx.isIncoming && tx.otherUserId == state.otherUserMxItem?.id) { // Also auto accept incoming if needed! + // TODO is state.transactionId ever null for self verifications, doesn't seem + // like this will ever trigger + if (tx is SasVerificationTransaction && tx.state == VerificationTxState.OnStarted) { + tx.acceptVerification() + } + /* if (tx is IncomingSasVerificationTransaction) { if (tx.uxState == IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { tx.performAccept() } } + */ // Use this one! setState { copy( diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 01290a57ea..2b2128d67e 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -85,7 +85,7 @@ import im.vector.app.features.terms.ReviewTermsActivity import im.vector.app.features.widgets.WidgetActivity import im.vector.app.features.widgets.WidgetArgsBuilder import im.vector.app.space -import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction +import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.widgets.model.Widget @@ -159,7 +159,10 @@ class DefaultNavigator @Inject constructor( val session = sessionHolder.getSafeActiveSession() ?: return val tx = session.cryptoService().verificationService().getExistingTransaction(otherUserId, sasTransactionId) ?: return - (tx as? IncomingSasVerificationTransaction)?.performAccept() + if (tx is SasVerificationTransaction && tx.isIncoming) { + tx.acceptVerification() + } + if (context is AppCompatActivity) { VerificationBottomSheet.withArgs( roomId = null, From 304c89a56d2ae07d14cf1dde3c05b20a2c73fbe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 29 Jun 2021 10:03:53 +0200 Subject: [PATCH 120/252] crypto: Dispatch updates when we receive MAC events --- .../crypto/verification/RustVerificationService.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index b39022589c..c3ff64d01d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -36,6 +36,7 @@ import org.matrix.android.sdk.internal.crypto.VerificationRequest import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel 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.KeyVerificationMac import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart import org.matrix.android.sdk.internal.session.SessionScope @@ -114,7 +115,7 @@ constructor( EventType.KEY_VERIFICATION_CANCEL -> onCancel(event) EventType.KEY_VERIFICATION_ACCEPT -> {} EventType.KEY_VERIFICATION_KEY -> onKey(event) - EventType.KEY_VERIFICATION_MAC -> {} + EventType.KEY_VERIFICATION_MAC -> onMac(event) EventType.KEY_VERIFICATION_READY -> {} EventType.KEY_VERIFICATION_DONE -> onDone(event) MessageType.MSGTYPE_VERIFICATION_REQUEST -> onRequest(event) @@ -182,6 +183,14 @@ constructor( getAndDispatch(sender, flowId) } + private fun onMac(event: Event) { + val content = event.getClearContent().toModel() ?: return + val flowId = content.transactionId ?: return + val sender = event.senderId ?: return + + getAndDispatch(sender, flowId) + } + private fun onRequest(event: Event) { val content = event.getClearContent().toModel() ?: return val flowId = content.transactionId From bcfb121215d649ffb87e480a74cf9b6a28f5b259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 29 Jun 2021 11:12:41 +0200 Subject: [PATCH 121/252] crypto: Prepare the verification service to allow starting short SAS flows --- .../verification/RustVerificationService.kt | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index c3ff64d01d..4ba58ab9fc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -248,22 +248,29 @@ constructor( otherDeviceId: String, transactionId: String? ): String? { - val flowId = transactionId ?: return null - // should check if already one (and cancel it) return if (method == VerificationMethod.SAS) { - val request = this.getVerificationRequest(otherUserId, flowId) + val request = transactionId?.let { this.getVerificationRequest(otherUserId, it) } - runBlocking { - val sas = request?.startSasVerification() + if (request != null) { + runBlocking { + val sas = request.startSasVerification() - if (sas != null) { - val sasTransaction = SasVerification(olmMachine.inner(), sas, requestSender, listeners) - dispatchTxAdded(sasTransaction) - sasTransaction.transactionId - } else { - null + if (sas != null) { + val sasTransaction = SasVerification(olmMachine.inner(), sas, requestSender, listeners) + dispatchTxAdded(sasTransaction) + sasTransaction.transactionId + } else { + null + } } + } else { + // This should start the short SAS flow, the one that doesn't start with + // a `m.key.verification.request`, Element web stopped doing this, might + // be wise do do so as well + // DeviceListBottomSheetViewModel triggers this, interestingly the method that + // triggers this is called `manuallyVerify()` + TODO() } } else { throw IllegalArgumentException("Unknown verification method") From 2c1dc053edc2e07c9fa32b465b7d46c07535f93b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 30 Jun 2021 15:48:24 +0200 Subject: [PATCH 122/252] crypto: Support answering in-room verifications --- .../internal/crypto/DefaultCryptoService.kt | 44 ++- .../android/sdk/internal/crypto/OlmMachine.kt | 2 +- .../verification/RustVerificationService.kt | 300 ++++++++---------- rust-sdk/Cargo.toml | 10 +- rust-sdk/src/machine.rs | 2 +- rust-sdk/src/olm.udl | 1 + rust-sdk/src/responses.rs | 24 +- 7 files changed, 201 insertions(+), 182 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 5764f078f7..a8d382df25 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -20,6 +20,7 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.lifecycle.LiveData import androidx.paging.PagedList +import dagger.Lazy import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async @@ -44,6 +45,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic 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.EventType +import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility @@ -68,11 +70,13 @@ import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask +import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask +import org.matrix.android.sdk.internal.crypto.tasks.SendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService @@ -101,16 +105,34 @@ import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import kotlin.math.max -internal class RequestSender( +internal class RequestSender @Inject constructor( private val sendToDeviceTask: SendToDeviceTask, -) { + private val sendVerificationMessageTask: Lazy, + ) { + suspend fun sendVerificationRequest(request: OutgoingVerificationRequest) { when (request) { - is OutgoingVerificationRequest.InRoom -> TODO() + is OutgoingVerificationRequest.InRoom -> sendRoomMessage(request) is OutgoingVerificationRequest.ToDevice -> sendToDevice(request) } } + suspend fun sendRoomMessage(request: OutgoingVerificationRequest.InRoom) { + sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) + } + + suspend fun sendRoomMessage(request: Request.RoomMessage) { + sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) + } + + suspend fun sendRoomMessage(eventType: String, roomId: String, content: String, transactionId: String) { + val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val jsonContent = adapter.fromJson(content) + val event = Event(eventType, transactionId, jsonContent, roomId = roomId) + val params = SendVerificationMessageTask.Params(event) + this.sendVerificationMessageTask.get().execute(params) + } + suspend fun sendToDevice(request: Request.ToDevice) { sendToDevice(request.eventType, request.body) } @@ -176,11 +198,11 @@ internal class DefaultCryptoService @Inject constructor( private val coroutineDispatchers: MatrixCoroutineDispatchers, private val taskExecutor: TaskExecutor, private val cryptoCoroutineScope: CoroutineScope, + private val sender: RequestSender, ) : CryptoService { private val isStarting = AtomicBoolean(false) private val isStarted = AtomicBoolean(false) - private val sender = RequestSender(this.sendToDeviceTask) private var olmMachine: OlmMachine? = null // The verification service. @@ -348,8 +370,7 @@ internal class DefaultCryptoService @Inject constructor( setRustLogger() val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) this.olmMachine = machine - this.verificationService = - RustVerificationService(machine, this.sender) + this.verificationService = RustVerificationService(machine, this.sender) Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") @@ -859,8 +880,15 @@ internal class DefaultCryptoService @Inject constructor( sendToDevice(it) } } - else -> { - async {} + is Request.KeysClaim -> { + async { + claimKeys(it) + } + } + is Request.RoomMessage -> { + async { + sender.sendRoomMessage(it) + } } } }.joinAll() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index ddd7cc4134..2b9de6004e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -228,7 +228,7 @@ internal class QrCodeVerification( runBlocking { when (request) { is OutgoingVerificationRequest.ToDevice -> { - sender.sendToDevice(request.eventType, request.body) + sender.sendToDevice(request) } is OutgoingVerificationRequest.InRoom -> TODO() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 4ba58ab9fc..673f91c176 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,8 @@ package org.matrix.android.sdk.internal.crypto.verification import android.os.Handler import android.os.Looper -import javax.inject.Inject +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod @@ -27,30 +28,38 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransa import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent 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.QrCodeVerification import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.SasVerification import org.matrix.android.sdk.internal.crypto.VerificationRequest -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel -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.KeyVerificationMac -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber import uniffi.olm.Verification +private fun getFlowId(event: Event): String? { + @JsonClass(generateAdapter = true) + data class ToDeviceVerificationEvent( + @Json(name = "sender") val sender: String?, + @Json(name = "transaction_id") val transactionId: String, + ) + + return if (event.eventId != null) { + val relatesTo = event.content.toModel()?.relatesTo + relatesTo?.eventId + } else { + val content = event.getClearContent().toModel() ?: return null + content.transactionId + } +} + @SessionScope -internal class RustVerificationService -@Inject -constructor( +internal class RustVerificationService( private val olmMachine: OlmMachine, private val requestSender: RequestSender, ) : DefaultVerificationTransaction.Listener, VerificationService { - private val uiHandler = Handler(Looper.getMainLooper()) private var listeners = ArrayList() @@ -103,43 +112,31 @@ constructor( } } - override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { - // TODO this doesn't seem to be used anymore? - runBlocking { olmMachine.markDeviceAsTrusted(userId, deviceID) } - } - suspend fun onEvent(event: Event) = when (event.getClearType()) { - // TODO most of those methods do the same, we just need to get the - // flow id and the sender from the event, can we add a generic method for this? - EventType.KEY_VERIFICATION_START -> onStart(event) - EventType.KEY_VERIFICATION_CANCEL -> onCancel(event) - EventType.KEY_VERIFICATION_ACCEPT -> {} - EventType.KEY_VERIFICATION_KEY -> onKey(event) - EventType.KEY_VERIFICATION_MAC -> onMac(event) - EventType.KEY_VERIFICATION_READY -> {} - EventType.KEY_VERIFICATION_DONE -> onDone(event) MessageType.MSGTYPE_VERIFICATION_REQUEST -> onRequest(event) - else -> {} + EventType.KEY_VERIFICATION_START -> onStart(event) + EventType.KEY_VERIFICATION_READY, + EventType.KEY_VERIFICATION_ACCEPT, + EventType.KEY_VERIFICATION_KEY, + EventType.KEY_VERIFICATION_MAC, + EventType.KEY_VERIFICATION_CANCEL, + EventType.KEY_VERIFICATION_DONE -> onUpdate(event) + else -> { + } } - private fun getAndDispatch(sender: String, flowId: String) { + private fun onUpdate(event: Event) { + val sender = event.senderId ?: return + val flowId = getFlowId(event) ?: return + + this.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() val verification = this.getExistingTransaction(sender, flowId) ?: return dispatchTxUpdated(verification) } - private fun onCancel(event: Event) { - val content = event.getClearContent().toModel() ?: return - val flowId = content.transactionId ?: return - val sender = event.senderId ?: return - - this.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() - getAndDispatch(sender, flowId) - } - private suspend fun onStart(event: Event) { - val content = event.getClearContent().toModel() ?: return - val flowId = content.transactionId ?: return val sender = event.senderId ?: return + val flowId = getFlowId(event) ?: return val verification = this.getExistingTransaction(sender, flowId) ?: return val request = this.getVerificationRequest(sender, flowId) @@ -150,12 +147,12 @@ constructor( // accepted the request, otherwise it's a QR code verification, just dispatch an update. if (verification is SasVerification) { // Accept dispatches an update, no need to do it twice. + Timber.d("## Verification: Auto accepting SAS verification with $sender") verification.accept() } else { dispatchTxUpdated(verification) } } else { - Timber.d("HELLOOOOO DISPATCHING NEW VERIFICATIONO $verification") // This didn't originate from a request, so tell our listeners that // this is a new verification. dispatchTxAdded(verification) @@ -163,37 +160,10 @@ constructor( // so let's trigger an update after the addition as well. dispatchTxUpdated(verification) } - - - } - - private fun onDone(event: Event) { - val content = event.getClearContent().toModel() ?: return - val flowId = content.transactionId ?: return - val sender = event.senderId ?: return - - getAndDispatch(sender, flowId) - } - - private fun onKey(event: Event) { - val content = event.getClearContent().toModel() ?: return - val flowId = content.transactionId ?: return - val sender = event.senderId ?: return - - getAndDispatch(sender, flowId) - } - - private fun onMac(event: Event) { - val content = event.getClearContent().toModel() ?: return - val flowId = content.transactionId ?: return - val sender = event.senderId ?: return - - getAndDispatch(sender, flowId) } private fun onRequest(event: Event) { - val content = event.getClearContent().toModel() ?: return - val flowId = content.transactionId + val flowId = getFlowId(event) ?: return val sender = event.senderId ?: return val request = this.getExistingVerificationRequest(sender, flowId) ?: return @@ -201,6 +171,26 @@ constructor( dispatchRequestAdded(request) } + private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? { + val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) + + return if (request != null) { + VerificationRequest( + this.olmMachine.inner(), + request, + requestSender, + listeners, + ) + } else { + null + } + } + + override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { + // TODO this doesn't seem to be used anymore? + runBlocking { olmMachine.markDeviceAsTrusted(userId, deviceID) } + } + override fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event) { // TODO This should be handled inside the rust-sdk decryption method } @@ -219,8 +209,13 @@ constructor( override fun getExistingVerificationRequests( otherUserId: String ): List { - return this.getVerificationRequests(otherUserId).map { - it.toPendingVerificationRequest() + return this.olmMachine.getVerificationRequests(otherUserId).map { + VerificationRequest( + this.olmMachine.inner(), + it, + this.requestSender, + this.listeners, + ).toPendingVerificationRequest() } } @@ -239,9 +234,67 @@ constructor( roomId: String, tid: String? ): PendingVerificationRequest? { + // This is only used in `RoomDetailViewModel` to resume the verification. TODO() } + override fun requestKeyVerification( + methods: List, + otherUserId: String, + otherDevices: List? + ): PendingVerificationRequest { + // This was mostly a copy paste of the InDMs method, do the same here + TODO() + } + + override fun requestKeyVerificationInDMs( + methods: List, + otherUserId: String, + roomId: String, + localId: String? + ): PendingVerificationRequest { + Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") + + // TODO cancel other active requests, create a new request here and + // dispatch it + TODO() + } + + override fun readyPendingVerification( + methods: List, + otherUserId: String, + transactionId: String + ): Boolean { + val request = this.getVerificationRequest(otherUserId, transactionId) + + return if (request != null) { + runBlocking { request.acceptWithMethods(methods) } + + if (request.isReady()) { + val qrcode = request.startQrVerification() + + if (qrcode != null) { + dispatchTxAdded(qrcode) + } + + true + } else { + false + } + } else { + false + } + } + + override fun readyPendingVerificationInDMs( + methods: List, + otherUserId: String, + roomId: String, + transactionId: String + ): Boolean { + return readyPendingVerification(methods, otherUserId, transactionId) + } + override fun beginKeyVerification( method: VerificationMethod, otherUserId: String, @@ -277,26 +330,17 @@ constructor( } } - override fun requestKeyVerificationInDMs( - methods: List, - otherUserId: String, + override fun beginKeyVerificationInDMs( + method: VerificationMethod, + transactionId: String, roomId: String, - localId: String? - ): PendingVerificationRequest { - Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") - - // TODO cancel other active requests, create a new request here and - // dispatch it - TODO() - } - - override fun requestKeyVerification( - methods: List, otherUserId: String, - otherDevices: List? - ): PendingVerificationRequest { - // This was mostly a copy paste of the InDMs method, do the same here - TODO() + otherDeviceId: String + ): String { + beginKeyVerification(method, otherUserId, otherDeviceId, transactionId) + // TODO what's the point of returning the same ID we got as an argument? + // We do this because the old verification service did so + return transactionId } override fun cancelVerificationRequest(request: PendingVerificationRequest) { @@ -309,86 +353,12 @@ constructor( transactionId: String, roomId: String ) { - // TODO get an existing verification request out of the olm machine and - // cancel it. update the pending request afterwards - } - - override fun beginKeyVerificationInDMs( - method: VerificationMethod, - transactionId: String, - roomId: String, - otherUserId: String, - otherDeviceId: String - ): String { - // TODO fetch out the verification request nad start SAS, return the - // flow id - return "" - } - - override fun readyPendingVerificationInDMs( - methods: List, - otherUserId: String, - roomId: String, - transactionId: String - ): Boolean { - Timber.e("## TRYING TO READY PENDING ROOM VERIFICATION") - // TODO do the same as readyPendingVerification - TODO() - } - - private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? { - val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) - - return if (request != null) { - VerificationRequest( - this.olmMachine.inner(), - request, - requestSender, - listeners, - ) - } else { - null - } - } - - private fun getVerificationRequests(userId: String): List { - return this.olmMachine.getVerificationRequests(userId).map { - VerificationRequest( - this.olmMachine.inner(), - it, - this.requestSender, - this.listeners, - ) - } - } - - override fun readyPendingVerification( - methods: List, - otherUserId: String, - transactionId: String - ): Boolean { - val request = this.getVerificationRequest(otherUserId, transactionId) - - return if (request != null) { - runBlocking { request.acceptWithMethods(methods) } - - if (request.isReady()) { - val qrcode = request.startQrVerification() - - if (qrcode != null) { - dispatchTxAdded(qrcode) - } - - true - } else { - false - } - } else { - false - } + val verificationRequest = this.getVerificationRequest(otherUserId, transactionId) + runBlocking { verificationRequest?.cancel() } } override fun transactionUpdated(tx: VerificationTransaction) { + // TODO this isn't really used anymore dispatchTxUpdated(tx) } } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 963eec3424..1266b97814 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -24,12 +24,14 @@ version = "0.2.1" features = ["lax_deserialize"] [dependencies.matrix-sdk-common] -git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "d2e4b3f3bbcdc139560cdacbdf62dedab6f156b9" +path = "/home/poljar/werk/matrix/nio-rust/matrix_sdk_common" +# git = "https://github.com/matrix-org/matrix-rust-sdk/" +# rev = "d2e4b3f3bbcdc139560cdacbdf62dedab6f156b9" [dependencies.matrix-sdk-crypto] -git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "d2e4b3f3bbcdc139560cdacbdf62dedab6f156b9" +path = "/home/poljar/werk/matrix/nio-rust/matrix_sdk_crypto" +# git = "https://github.com/matrix-org/matrix-rust-sdk/" +# rev = "d2e4b3f3bbcdc139560cdacbdf62dedab6f156b9" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 7deb409c45..44dd783e4d 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -718,7 +718,7 @@ impl OlmMachine { pub fn request_verification(&self, user_id: &str) { let _user_id = UserId::try_from(user_id).unwrap(); - todo!() + todo!("Requesting key verification isn't yet supported") } pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index d3297b84c5..452a02279d 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -140,6 +140,7 @@ interface Request { KeysUpload(string request_id, string body); KeysQuery(string request_id, sequence users); KeysClaim(string request_id, record> one_time_keys); + RoomMessage(string request_id, string room_id, string event_type, string content); }; enum RequestType { diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index 4cecd4981b..f1204900db 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -19,7 +19,7 @@ use ruma::{ use matrix_sdk_crypto::{ IncomingResponse, OutgoingRequest, OutgoingVerificationRequest as SdkVerificationRequest, - ToDeviceRequest, + ToDeviceRequest, RoomMessageRequest, }; pub enum OutgoingVerificationRequest { @@ -73,6 +73,12 @@ pub enum Request { request_id: String, one_time_keys: HashMap>, }, + RoomMessage { + request_id: String, + room_id: String, + event_type: String, + content: String, + }, } impl From for Request { @@ -100,8 +106,8 @@ impl From for Request { } } ToDeviceRequest(t) => Request::from(t), - SignatureUpload(_) => todo!(), - RoomMessage(_) => todo!(), + SignatureUpload(_) => todo!("Uploading signatures isn't yet supported"), + RoomMessage(r) => Request::from(r), } } } @@ -126,6 +132,18 @@ impl From<&ToDeviceRequest> for Request { } } +impl From<&RoomMessageRequest> for Request { + fn from(r: &RoomMessageRequest) -> Self { + Self::RoomMessage { + request_id: r.txn_id.to_string(), + room_id: r.room_id.to_string(), + event_type: r.content.event_type().to_string(), + content: serde_json::to_string(&r.content) + .expect("Can't serialize message content"), + } + } +} + pub(crate) fn response_from_string(body: &str) -> Response> { Response::builder() .status(200) From cd5aad9a3133368a7cda9d0841e1b7a76d765f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 30 Jun 2021 16:22:17 +0200 Subject: [PATCH 123/252] crypto: Move the request sending logic into the sender --- .../internal/crypto/DefaultCryptoService.kt | 82 +++++++++---------- 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index a8d382df25..313855c76c 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -45,7 +45,6 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic 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.EventType -import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility @@ -107,8 +106,37 @@ import kotlin.math.max internal class RequestSender @Inject constructor( private val sendToDeviceTask: SendToDeviceTask, + private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, + private val uploadKeysTask: UploadKeysTask, + private val downloadKeysForUsersTask: DownloadKeysForUsersTask, private val sendVerificationMessageTask: Lazy, - ) { +) { + + suspend fun claimKeys(request: Request.KeysClaim): String { + val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) + val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) + val adapter = MoshiProvider + .providesMoshi() + .adapter(KeysClaimResponse::class.java) + return adapter.toJson(response)!! + } + + suspend fun queryKeys(request: Request.KeysQuery): String { + val params = DownloadKeysForUsersTask.Params(request.users, null) + val response = downloadKeysForUsersTask.execute(params) + val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) + return adapter.toJson(response)!! + } + + suspend fun uploadKeys(request: Request.KeysUpload): String { + val body = MoshiProvider.providesMoshi().adapter(Map::class.java).fromJson(request.body)!! + val params = UploadKeysTask.Params(body) + + val response = uploadKeysTask.execute(params) + val adapter = MoshiProvider.providesMoshi().adapter(KeysUploadResponse::class.java) + + return adapter.toJson(response)!! + } suspend fun sendVerificationRequest(request: OutgoingVerificationRequest) { when (request) { @@ -142,8 +170,7 @@ internal class RequestSender @Inject constructor( } suspend fun sendToDevice(eventType: String, body: String) { - // TODO this produces floats for the Olm type fields, which - // are integers originally. + // TODO this produces floats for the Olm type fields, which are integers originally. val adapter = MoshiProvider .providesMoshi() .adapter>>(Map::class.java) @@ -187,12 +214,8 @@ internal class DefaultCryptoService @Inject constructor( // Tasks private val deleteDeviceTask: DeleteDeviceTask, private val getDevicesTask: GetDevicesTask, - private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, - private val sendToDeviceTask: SendToDeviceTask, - private val downloadKeysForUsersTask: DownloadKeysForUsersTask, private val getDeviceInfoTask: GetDeviceInfoTask, private val setDeviceNameTask: SetDeviceNameTask, - private val uploadKeysTask: UploadKeysTask, private val loadRoomMembersTask: LoadRoomMembersTask, private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, private val coroutineDispatchers: MatrixCoroutineDispatchers, @@ -809,36 +832,15 @@ internal class DefaultCryptoService @Inject constructor( return olmMachine!!.encrypt(roomId, eventType, content) } - private suspend fun uploadKeys(outgoingRequest: Request.KeysUpload) { - val body = MoshiProvider - .providesMoshi() - .adapter(Map::class.java) - .fromJson(outgoingRequest.body)!! - - val request = UploadKeysTask.Params(body) - - val response = uploadKeysTask.execute(request) - val adapter = MoshiProvider - .providesMoshi() - .adapter(KeysUploadResponse::class.java) - - val jsonResponse = adapter.toJson(response)!! - - this.olmMachine!!.markRequestAsSent( - outgoingRequest.requestId, - RequestType.KEYS_UPLOAD, - jsonResponse - ) + private suspend fun uploadKeys(request: Request.KeysUpload) { + val response = this.sender.uploadKeys(request) + this.olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_UPLOAD, response) } - private suspend fun queryKeys(outgoingRequest: Request.KeysQuery) { - val params = DownloadKeysForUsersTask.Params(outgoingRequest.users, null) - + private suspend fun queryKeys(request: Request.KeysQuery) { try { - val response = downloadKeysForUsersTask.execute(params) - val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) - val jsonResponse = adapter.toJson(response)!! - this.olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_QUERY, jsonResponse) + val response = this.sender.queryKeys(request) + this.olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_QUERY, response) } catch (throwable: Throwable) { Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") } @@ -850,14 +852,8 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun claimKeys(request: Request.KeysClaim) { - val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) - val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) - val adapter = MoshiProvider - .providesMoshi() - .adapter(KeysClaimResponse::class.java) - val jsonResponse = adapter.toJson(response)!! - - olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, jsonResponse) + val response = this.sender.claimKeys(request) + olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, response) } private suspend fun sendOutgoingRequests() { From 7e49760da0439dd67fe0f9c3a5f99e7bbb4e15e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 30 Jun 2021 17:39:36 +0200 Subject: [PATCH 124/252] rust: Don't depend on a local rust-sdk --- rust-sdk/Cargo.toml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 1266b97814..2c3399656e 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -24,14 +24,12 @@ version = "0.2.1" features = ["lax_deserialize"] [dependencies.matrix-sdk-common] -path = "/home/poljar/werk/matrix/nio-rust/matrix_sdk_common" -# git = "https://github.com/matrix-org/matrix-rust-sdk/" -# rev = "d2e4b3f3bbcdc139560cdacbdf62dedab6f156b9" +git = "https://github.com/matrix-org/matrix-rust-sdk/" +rev = "9052843acbc762388f4ae59e6dad0d580914cf59" [dependencies.matrix-sdk-crypto] -path = "/home/poljar/werk/matrix/nio-rust/matrix_sdk_crypto" -# git = "https://github.com/matrix-org/matrix-rust-sdk/" -# rev = "d2e4b3f3bbcdc139560cdacbdf62dedab6f156b9" +git = "https://github.com/matrix-org/matrix-rust-sdk/" +rev = "9052843acbc762388f4ae59e6dad0d580914cf59" features = ["sled_cryptostore"] [dependencies.tokio] From d24c94d0f9bffaa92e32d304a6201fcd43e9c5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 1 Jul 2021 13:15:26 +0200 Subject: [PATCH 125/252] crypto: Allow the direct start of the short SAS flow --- .../android/sdk/internal/crypto/OlmMachine.kt | 36 +++++++++- .../internal/crypto/VerificationRequest.kt | 40 +++++------ .../verification/RustVerificationService.kt | 67 ++++++++++++++----- rust-sdk/src/machine.rs | 24 +++++++ rust-sdk/src/olm.udl | 2 + rust-sdk/src/responses.rs | 21 +++--- 6 files changed, 142 insertions(+), 48 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 2b9de6004e..5a099c12db 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -49,7 +49,7 @@ 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.Device +import uniffi.olm.Device as InnerDevice import uniffi.olm.DeviceLists import uniffi.olm.KeyRequestPair import uniffi.olm.Logger @@ -98,7 +98,7 @@ fun setRustLogger() { } /** Convert a Rust Device into a Kotlin CryptoDeviceInfo */ -private fun toCryptoDeviceInfo(device: Device): CryptoDeviceInfo { +private fun toCryptoDeviceInfo(device: InnerDevice): CryptoDeviceInfo { val keys = device.keys.map { (keyId, key) -> "$keyId:$device.deviceId" to key }.toMap() return CryptoDeviceInfo( @@ -128,6 +128,36 @@ internal class DeviceUpdateObserver { } } +internal class Device( + private val machine: uniffi.olm.OlmMachine, + private var inner: InnerDevice, + private val sender: RequestSender, + private val listeners: ArrayList, +) { + @Throws(CryptoStoreErrorException::class) + suspend fun startVerification(): SasVerification? { + val result = withContext(Dispatchers.IO) { + machine.startSasWithDevice(inner.userId, inner.deviceId) + } + + return if (result != null) { + this.sender.sendVerificationRequest(result.request) + SasVerification( + this.machine, result.sas, this.sender, this.listeners, + ) + } else { + null + } + } + + @Throws(CryptoStoreErrorException::class) + suspend fun markAsTrusted() { + withContext(Dispatchers.IO) { + machine.markDeviceAsTrusted(inner.userId, inner.deviceId) + } + } +} + internal class QrCodeVerification( private val machine: uniffi.olm.OlmMachine, private var inner: QrCode, @@ -670,7 +700,7 @@ internal class OlmMachine( runBlocking { inner.discardRoomKey(roomId) } } - fun getVerificationRequests(userId: String): List { + fun getVerificationRequests(userId: String): List { return this.inner.getVerificationRequests(userId) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index ac3058b592..f15ee7b405 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -33,7 +33,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_REC import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS import timber.log.Timber import uniffi.olm.OlmMachine -import uniffi.olm.Sas import uniffi.olm.VerificationRequest internal class VerificationRequest( @@ -66,6 +65,21 @@ internal class VerificationRequest( } } + fun isCanceled(): Boolean { + refreshData() + return this.inner.isCancelled + } + + fun isDone(): Boolean { + refreshData() + return this.inner.isDone + } + + fun isReady(): Boolean { + refreshData() + return this.inner.isReady + } + internal fun startQrVerification(): QrCodeVerification? { val qrcode = this.machine.startQrVerification(this.inner.otherUserId, this.inner.flowId) @@ -99,7 +113,10 @@ internal class VerificationRequest( } val request = this.machine.acceptVerificationRequest( - this.inner.otherUserId, this.inner.flowId, stringMethods) + this.inner.otherUserId, + this.inner.flowId, + stringMethods + ) if (request != null) { this.sender.sendVerificationRequest(request) @@ -116,29 +133,14 @@ internal class VerificationRequest( } } - fun isCanceled(): Boolean { - refreshData() - return this.inner.isCancelled - } - - fun isDone(): Boolean { - refreshData() - return this.inner.isDone - } - - fun isReady(): Boolean { - refreshData() - return this.inner.isReady - } - - suspend fun startSasVerification(): Sas? { + suspend fun startSasVerification(): SasVerification? { refreshData() return withContext(Dispatchers.IO) { val result = machine.startSasVerification(inner.otherUserId, inner.flowId) if (result != null) { sender.sendVerificationRequest(result.request) - result.sas + SasVerification(machine, result.sas, sender, listeners) } else { null } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 673f91c176..9a9078de65 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -20,7 +20,9 @@ import android.os.Handler import android.os.Looper import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService @@ -30,6 +32,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent import org.matrix.android.sdk.api.session.room.model.message.MessageType +import org.matrix.android.sdk.internal.crypto.Device import org.matrix.android.sdk.internal.crypto.OlmMachine import org.matrix.android.sdk.internal.crypto.QrCodeVerification import org.matrix.android.sdk.internal.crypto.RequestSender @@ -39,13 +42,13 @@ import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber import uniffi.olm.Verification -private fun getFlowId(event: Event): String? { - @JsonClass(generateAdapter = true) - data class ToDeviceVerificationEvent( - @Json(name = "sender") val sender: String?, - @Json(name = "transaction_id") val transactionId: String, - ) +@JsonClass(generateAdapter = true) +data class ToDeviceVerificationEvent( + @Json(name = "sender") val sender: String?, + @Json(name = "transaction_id") val transactionId: String, +) +private fun getFlowId(event: Event): String? { return if (event.eventId != null) { val relatesTo = event.content.toModel()?.relatesTo relatesTo?.eventId @@ -186,9 +189,24 @@ internal class RustVerificationService( } } + private suspend fun getDevice(userId: String, deviceID: String): Device? { + val device = withContext(Dispatchers.IO) { + olmMachine.inner().getDevice(userId, deviceID) + } + + return if (device != null) { + Device(this.olmMachine.inner(), device, this.requestSender, this.listeners) + } else { + null + } + } + override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { // TODO this doesn't seem to be used anymore? - runBlocking { olmMachine.markDeviceAsTrusted(userId, deviceID) } + runBlocking { + val device = getDevice(userId, deviceID) + device?.markAsTrusted() + } } override fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event) { @@ -200,9 +218,14 @@ internal class RustVerificationService( tid: String, ): VerificationTransaction? { val verification = this.olmMachine.getVerification(otherUserId, tid) ?: return null + return when (verification) { - is Verification.QrCodeV1 -> QrCodeVerification(this.olmMachine.inner(), verification.qrcode, this.requestSender, this.listeners) - is Verification.SasV1 -> SasVerification(this.olmMachine.inner(), verification.sas, this.requestSender, this.listeners) + is Verification.QrCodeV1 -> { + QrCodeVerification(this.olmMachine.inner(), verification.qrcode, this.requestSender, this.listeners) + } + is Verification.SasV1 -> { + SasVerification(this.olmMachine.inner(), verification.sas, this.requestSender, this.listeners) + } } } @@ -235,7 +258,8 @@ internal class RustVerificationService( tid: String? ): PendingVerificationRequest? { // This is only used in `RoomDetailViewModel` to resume the verification. - TODO() + // We don't support resuming in the rust-sdk, at least for now, so let's return null here. + return null } override fun requestKeyVerification( @@ -303,27 +327,34 @@ internal class RustVerificationService( ): String? { // should check if already one (and cancel it) return if (method == VerificationMethod.SAS) { - val request = transactionId?.let { this.getVerificationRequest(otherUserId, it) } + if (transactionId != null) { + val request = this.getVerificationRequest(otherUserId, transactionId) - if (request != null) { runBlocking { - val sas = request.startSasVerification() + val sas = request?.startSasVerification() if (sas != null) { - val sasTransaction = SasVerification(olmMachine.inner(), sas, requestSender, listeners) - dispatchTxAdded(sasTransaction) - sasTransaction.transactionId + dispatchTxAdded(sas) + sas.transactionId } else { null } } } else { - // This should start the short SAS flow, the one that doesn't start with + // This starts the short SAS flow, the one that doesn't start with // a `m.key.verification.request`, Element web stopped doing this, might // be wise do do so as well // DeviceListBottomSheetViewModel triggers this, interestingly the method that // triggers this is called `manuallyVerify()` - TODO() + runBlocking { + val sas = getDevice(otherUserId, otherDeviceId)?.startVerification() + if (sas != null) { + dispatchTxAdded(sas) + sas.transactionId + } else { + null + } + } } } else { throw IllegalArgumentException("Unknown verification method") diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 44dd783e4d..83016e6c1e 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -758,6 +758,30 @@ impl OlmMachine { }) } + pub fn start_sas_with_device( + &self, + user_id: &str, + device_id: &str, + ) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + + Ok( + if let Some(device) = self + .runtime + .block_on(self.inner.get_device(&user_id, device_id.into()))? + { + let (sas, request) = self.runtime.block_on(device.start_verification())?; + + Some(StartSasResult { + sas: sas.into(), + request: request.into(), + }) + } else { + None + }, + ) + } + pub fn start_sas_verification( &self, user_id: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 452a02279d..a924dc9f64 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -199,6 +199,8 @@ interface OlmMachine { sequence methods ); + [Throws=CryptoStoreError] + StartSasResult? start_sas_with_device([ByRef] string user_id, [ByRef] string device_id); [Throws=CryptoStoreError] StartSasResult? start_sas_verification([ByRef] string user_id, [ByRef] string flow_id); [Throws=CryptoStoreError] diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index f1204900db..b2af4b162a 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -19,7 +19,7 @@ use ruma::{ use matrix_sdk_crypto::{ IncomingResponse, OutgoingRequest, OutgoingVerificationRequest as SdkVerificationRequest, - ToDeviceRequest, RoomMessageRequest, + RoomMessageRequest, ToDeviceRequest, }; pub enum OutgoingVerificationRequest { @@ -39,11 +39,7 @@ pub enum OutgoingVerificationRequest { impl From 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::ToDevice(r) => r.into(), SdkVerificationRequest::InRoom(r) => Self::InRoom { request_id: r.txn_id.to_string(), room_id: r.room_id.to_string(), @@ -55,6 +51,16 @@ impl From for OutgoingVerificationRequest { } } +impl From for OutgoingVerificationRequest { + fn from(r: ToDeviceRequest) -> Self { + 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"), + } + } +} + pub enum Request { ToDevice { request_id: String, @@ -138,8 +144,7 @@ impl From<&RoomMessageRequest> for Request { request_id: r.txn_id.to_string(), room_id: r.room_id.to_string(), event_type: r.content.event_type().to_string(), - content: serde_json::to_string(&r.content) - .expect("Can't serialize message content"), + content: serde_json::to_string(&r.content).expect("Can't serialize message content"), } } } From 33c2184c528bd9e0f68af05c6c60635f0816fc22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 8 Jul 2021 12:49:44 +0200 Subject: [PATCH 126/252] crypto: Allow verifications to be requested --- .../internal/crypto/DefaultCryptoService.kt | 20 ++-- .../android/sdk/internal/crypto/OlmMachine.kt | 19 ++-- .../internal/crypto/VerificationRequest.kt | 12 +-- .../verification/RustVerificationService.kt | 61 ++++++++++-- rust-sdk/Cargo.toml | 4 +- rust-sdk/src/lib.rs | 3 +- rust-sdk/src/machine.rs | 93 +++++++++++++++++-- rust-sdk/src/olm.udl | 19 ++++ 8 files changed, 182 insertions(+), 49 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 313855c76c..338229e720 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -145,31 +145,31 @@ internal class RequestSender @Inject constructor( } } - suspend fun sendRoomMessage(request: OutgoingVerificationRequest.InRoom) { - sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) + suspend fun sendRoomMessage(request: OutgoingVerificationRequest.InRoom): String { + return sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) } - suspend fun sendRoomMessage(request: Request.RoomMessage) { - sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) + suspend fun sendRoomMessage(request: Request.RoomMessage): String { + return sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) } - suspend fun sendRoomMessage(eventType: String, roomId: String, content: String, transactionId: String) { + suspend fun sendRoomMessage(eventType: String, roomId: String, content: String, transactionId: String): String { val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) val jsonContent = adapter.fromJson(content) val event = Event(eventType, transactionId, jsonContent, roomId = roomId) val params = SendVerificationMessageTask.Params(event) - this.sendVerificationMessageTask.get().execute(params) + return this.sendVerificationMessageTask.get().execute(params) } suspend fun sendToDevice(request: Request.ToDevice) { - sendToDevice(request.eventType, request.body) + sendToDevice(request.eventType, request.body, request.requestId) } suspend fun sendToDevice(request: OutgoingVerificationRequest.ToDevice) { - sendToDevice(request.eventType, request.body) + sendToDevice(request.eventType, request.body, request.requestId) } - suspend fun sendToDevice(eventType: String, body: String) { + suspend fun sendToDevice(eventType: String, body: String, transactionId: String) { // TODO this produces floats for the Olm type fields, which are integers originally. val adapter = MoshiProvider .providesMoshi() @@ -179,7 +179,7 @@ internal class RequestSender @Inject constructor( val userMap = MXUsersDevicesMap() userMap.join(jsonBody) - val sendToDeviceParams = SendToDeviceTask.Params(eventType, userMap) + val sendToDeviceParams = SendToDeviceTask.Params(eventType, userMap, transactionId) sendToDeviceTask.execute(sendToDeviceParams) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 5a099c12db..96eda6a465 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -203,21 +203,20 @@ internal class QrCodeVerification( override var state: VerificationTxState get() { refreshData() - val state = when { - this.inner.isDone -> VerificationTxState.Verified - this.inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm - this.inner.otherSideScanned -> VerificationTxState.QrScannedByOther - this.inner.isCancelled -> { - val cancelCode = safeValueOf(this.inner.cancelCode) - val byMe = this.inner.cancelledByUs ?: false + + return when { + inner.isDone -> VerificationTxState.Verified + inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm + inner.otherSideScanned -> VerificationTxState.QrScannedByOther + inner.isCancelled -> { + val cancelCode = safeValueOf(inner.cancelCode) + val byMe = inner.cancelledByUs ?: false VerificationTxState.Cancelled(cancelCode, byMe) } - else -> { + else -> { VerificationTxState.None } } - - return state } @Suppress("UNUSED_PARAMETER") set(value) {} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index f15ee7b405..2dd9e6f6fa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -31,6 +31,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS +import org.matrix.android.sdk.internal.crypto.model.rest.toValue import timber.log.Timber import uniffi.olm.OlmMachine import uniffi.olm.VerificationRequest @@ -96,16 +97,7 @@ internal class VerificationRequest( } suspend fun acceptWithMethods(methods: List) { - val stringMethods: MutableList = - methods - .map { - when (it) { - VerificationMethod.QR_CODE_SCAN -> VERIFICATION_METHOD_QR_CODE_SCAN - VerificationMethod.QR_CODE_SHOW -> VERIFICATION_METHOD_QR_CODE_SHOW - VerificationMethod.SAS -> VERIFICATION_METHOD_SAS - } - } - .toMutableList() + val stringMethods: MutableList = methods.map { it.toValue() }.toMutableList() if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 9a9078de65..b3fb53dfb2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -38,6 +38,10 @@ import org.matrix.android.sdk.internal.crypto.QrCodeVerification import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.SasVerification import org.matrix.android.sdk.internal.crypto.VerificationRequest +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW +import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE +import org.matrix.android.sdk.internal.crypto.model.rest.toValue import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber import uniffi.olm.Verification @@ -258,7 +262,22 @@ internal class RustVerificationService( tid: String? ): PendingVerificationRequest? { // This is only used in `RoomDetailViewModel` to resume the verification. - // We don't support resuming in the rust-sdk, at least for now, so let's return null here. + // + // Is this actually useful? SAS and QR code verifications ephemeral nature + // due to the usage of ephemeral secrets. In the case of SAS verification, the + // ephemeral key can't be stored due to libolm missing support for it, I would + // argue that the ephemeral secret for QR verifications shouldn't be persisted either. + // + // This means that once we transition from a verification request into an actual + // verification flow (SAS/QR) we won't be able to resume. In other words resumption + // is only supported before both sides agree to verify. + // + // We would either need to remember if the request transitioned into a flow and only + // support resumption if we didn't, otherwise we would risk getting different emojis + // or secrets in the QR code, not to mention that the flows could be interrupted in + // any non-starting state. + // + // In any case, we don't support resuming in the rust-sdk, so let's return null here. return null } @@ -267,8 +286,19 @@ internal class RustVerificationService( otherUserId: String, otherDevices: List? ): PendingVerificationRequest { - // This was mostly a copy paste of the InDMs method, do the same here - TODO() + + val stringMethods: MutableList = methods.map { it.toValue() }.toMutableList() + if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || + stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { + stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) + } + + val result = this.olmMachine.inner().requestSelfVerification(stringMethods) + runBlocking { + requestSender.sendVerificationRequest(result!!.request) + } + + return VerificationRequest(this.olmMachine.inner(), result!!.verification, this.requestSender, this.listeners).toPendingVerificationRequest() } override fun requestKeyVerificationInDMs( @@ -278,10 +308,21 @@ internal class RustVerificationService( localId: String? ): PendingVerificationRequest { Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") + val stringMethods: MutableList = methods.map { it.toValue() }.toMutableList() - // TODO cancel other active requests, create a new request here and - // dispatch it - TODO() + if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || + stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { + stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) + } + + val content = this.olmMachine.inner().verificationRequestContent(otherUserId, stringMethods)!! + + val eventID = runBlocking { + requestSender.sendRoomMessage(EventType.MESSAGE, roomId, content, localId!!) + } + + val innerRequest = this.olmMachine.inner().requestVerification(otherUserId, roomId, eventID, stringMethods)!! + return VerificationRequest(this.olmMachine.inner(), innerRequest, this.requestSender, this.listeners).toPendingVerificationRequest() } override fun readyPendingVerification( @@ -347,10 +388,10 @@ internal class RustVerificationService( // DeviceListBottomSheetViewModel triggers this, interestingly the method that // triggers this is called `manuallyVerify()` runBlocking { - val sas = getDevice(otherUserId, otherDeviceId)?.startVerification() - if (sas != null) { - dispatchTxAdded(sas) - sas.transactionId + val verification = getDevice(otherUserId, otherDeviceId)?.startVerification() + if (verification != null) { + dispatchTxAdded(verification) + verification.transactionId } else { null } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 2c3399656e..29d19c41a6 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -25,11 +25,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "9052843acbc762388f4ae59e6dad0d580914cf59" +rev = "c5df7c5356c2540ede95f41e3565e91ca7de5777" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "9052843acbc762388f4ae59e6dad0d580914cf59" +rev = "c5df7c5356c2540ede95f41e3565e91ca7de5777" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 331c6336b2..fe02dc3ab7 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -8,7 +8,8 @@ pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; pub use machine::{ - KeyRequestPair, OlmMachine, QrCode, Sas, StartSasResult, Verification, VerificationRequest, + KeyRequestPair, OlmMachine, QrCode, RequestVerificationResult, Sas, StartSasResult, + Verification, VerificationRequest, }; pub use responses::{ DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 83016e6c1e..7b7a204357 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -22,7 +22,7 @@ use ruma::{ key::verification::VerificationMethod, room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent, SyncMessageEvent, }, - DeviceKeyAlgorithm, RoomId, UserId, + DeviceKeyAlgorithm, EventId, RoomId, UserId, }; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue; @@ -128,6 +128,11 @@ impl From for Sas { } } +pub struct RequestVerificationResult { + pub verification: VerificationRequest, + pub request: OutgoingVerificationRequest, +} + pub struct VerificationRequest { pub other_user_id: String, pub other_device_id: Option, @@ -716,11 +721,6 @@ impl OlmMachine { } } - pub fn request_verification(&self, user_id: &str) { - let _user_id = UserId::try_from(user_id).unwrap(); - todo!("Requesting key verification isn't yet supported") - } - pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { let user_id = UserId::try_from(user_id).ok()?; self.inner @@ -758,6 +758,87 @@ impl OlmMachine { }) } + pub fn request_verification( + &self, + user_id: &str, + room_id: &str, + event_id: &str, + methods: Vec, + ) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + let event_id = EventId::try_from(event_id)?; + let room_id = RoomId::try_from(room_id)?; + + let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; + + let methods = methods + .into_iter() + .map(|m| VerificationMethod::from(m)) + .collect(); + + Ok(if let Some(identity) = identity.and_then(|i| i.other()) { + let request = self.runtime.block_on(identity.request_verification( + &room_id, + &event_id, + Some(methods), + )); + + Some(request.into()) + } else { + None + }) + } + + pub fn verification_request_content( + &self, + user_id: &str, + methods: Vec, + ) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + + let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; + + let methods = methods + .into_iter() + .map(|m| VerificationMethod::from(m)) + .collect(); + + Ok(if let Some(identity) = identity.and_then(|i| i.other()) { + let content = self + .runtime + .block_on(identity.verification_request_content(Some(methods))); + Some(serde_json::to_string(&content)?) + } else { + None + }) + } + + pub fn request_self_verification( + &self, + methods: Vec, + ) -> Result, CryptoStoreError> { + let identity = self + .runtime + .block_on(self.inner.get_identity(self.inner.user_id()))?; + + let methods = methods + .into_iter() + .map(|m| VerificationMethod::from(m)) + .collect(); + + Ok(if let Some(identity) = identity.and_then(|i| i.own()) { + let (verification, request) = self + .runtime + .block_on(identity.request_verification_with_methods(methods))?; + Some(RequestVerificationResult { + verification: verification.into(), + request: request.into(), + }) + } else { + None + }) + } + pub fn start_sas_with_device( &self, user_id: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index a924dc9f64..62c36f9a9a 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -117,6 +117,11 @@ dictionary VerificationRequest { }; +dictionary RequestVerificationResult { + VerificationRequest verification; + OutgoingVerificationRequest request; +}; + [Enum] interface Verification { SasV1(Sas sas); @@ -199,6 +204,20 @@ interface OlmMachine { sequence methods ); + [Throws=CryptoStoreError] + VerificationRequest? request_verification( + [ByRef] string user_id, + [ByRef] string room_id, + [ByRef] string event_id, + sequence methods + ); + [Throws=CryptoStoreError] + string? verification_request_content( + [ByRef] string user_id, + sequence methods + ); + [Throws=CryptoStoreError] + RequestVerificationResult? request_self_verification(sequence methods); [Throws=CryptoStoreError] StartSasResult? start_sas_with_device([ByRef] string user_id, [ByRef] string device_id); [Throws=CryptoStoreError] From 80e80e07b3a500881273fd7bce2d2cb7eb90f456 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jul 2021 16:18:29 +0200 Subject: [PATCH 127/252] To be reverted: temporarily change appId to 'im.vector.app.corroded' and app name --- vector/build.gradle | 6 +++--- vector/src/gplay/debug/google-services.json | 2 +- vector/src/gplay/release/google-services.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index 7c01cb550e..6854c3312f 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -109,7 +109,7 @@ android { ndkVersion "21.3.6528147" defaultConfig { - applicationId "im.vector.app" + applicationId "im.vector.app.corroded" // Set to API 21: see #405 minSdkVersion 21 targetSdkVersion 30 @@ -214,7 +214,7 @@ android { buildTypes { debug { applicationIdSuffix ".debug" - resValue "string", "app_name", "Element dbg" + resValue "string", "app_name", "Corroded Element dbg" resValue "bool", "debug_mode", "true" buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false" @@ -225,7 +225,7 @@ android { } release { - resValue "string", "app_name", "Element" + resValue "string", "app_name", "Corroded Element" resValue "bool", "debug_mode", "false" buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false" diff --git a/vector/src/gplay/debug/google-services.json b/vector/src/gplay/debug/google-services.json index 713c1d4e03..cfebf416bb 100644 --- a/vector/src/gplay/debug/google-services.json +++ b/vector/src/gplay/debug/google-services.json @@ -10,7 +10,7 @@ "client_info": { "mobilesdk_app_id": "1:912726360885:android:4ef8f3a0021e774d", "android_client_info": { - "package_name": "im.vector.app.debug" + "package_name": "im.vector.app.corroded.debug" } }, "oauth_client": [ diff --git a/vector/src/gplay/release/google-services.json b/vector/src/gplay/release/google-services.json index fb8f769f45..66da911c11 100644 --- a/vector/src/gplay/release/google-services.json +++ b/vector/src/gplay/release/google-services.json @@ -10,7 +10,7 @@ "client_info": { "mobilesdk_app_id": "1:912726360885:android:4ef8f3a0021e774d", "android_client_info": { - "package_name": "im.vector.app" + "package_name": "im.vector.app.corroded" } }, "oauth_client": [ From d4090c4b0a0cb93d14481898e0350fe797b483e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 8 Jul 2021 16:51:57 +0200 Subject: [PATCH 128/252] crypto: Only add our own devices if we're requesting devices for our own user --- .../org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 96eda6a465..3d555cc8e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -619,12 +619,15 @@ internal class OlmMachine( */ @Throws(CryptoStoreErrorException::class) suspend fun getUserDevices(userId: String): List { - val ownDevice = ownDevice() val devices = inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) }.toMutableList() // EA doesn't differentiate much between our own and other devices of // while the rust-sdk does, append our own device here. - devices.add(ownDevice) + val ownDevice = this.ownDevice() + + if (userId == ownDevice.userId) { + devices.add(ownDevice) + } return devices } From 54c3b4192e69883bb66ca1e3c801b2a6b62df350 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jul 2021 17:14:45 +0200 Subject: [PATCH 129/252] Small cleanup and format --- .../internal/crypto/DefaultCryptoService.kt | 104 ++++++++---------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 338229e720..548b0bb583 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -228,6 +228,7 @@ internal class DefaultCryptoService @Inject constructor( private val isStarted = AtomicBoolean(false) private var olmMachine: OlmMachine? = null + // The verification service. private var verificationService: RustVerificationService? = null @@ -254,7 +255,7 @@ internal class DefaultCryptoService @Inject constructor( EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) - else -> this.verificationService?.onEvent(event) + else -> this.verificationService?.onEvent(event) } } @@ -361,7 +362,7 @@ internal class DefaultCryptoService @Inject constructor( * devices. * */ - suspend fun start() { + fun start() { internalStart() // Just update fetchDevicesList(NoOpMatrixCallback()) @@ -383,7 +384,7 @@ internal class DefaultCryptoService @Inject constructor( } } - private suspend fun internalStart() { + private fun internalStart() { if (isStarted.get() || isStarting.get()) { return } @@ -392,11 +393,11 @@ internal class DefaultCryptoService @Inject constructor( try { setRustLogger() val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) - this.olmMachine = machine - this.verificationService = RustVerificationService(machine, this.sender) + olmMachine = machine + verificationService = RustVerificationService(machine, this.sender) Timber.v( - "## CRYPTO | Successfully started up an Olm machine for " + - "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") + "## CRYPTO | Successfully started up an Olm machine for " + + "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") } catch (throwable: Throwable) { Timber.v("Failed create an Olm machine: $throwable") } @@ -404,18 +405,8 @@ internal class DefaultCryptoService @Inject constructor( // Open the store cryptoStore.open() - runCatching { - }.fold( - { - isStarting.set(false) - isStarted.set(true) - }, - { - isStarting.set(false) - isStarted.set(false) - Timber.e(it, "Start failed") - } - ) + isStarting.set(false) + isStarted.set(true) } /** @@ -456,9 +447,7 @@ internal class DefaultCryptoService @Inject constructor( // Let's initialize here as a workaround until we figure out if the // above conclusion is correct. if (verificationService == null) { - runBlocking { - internalStart() - } + internalStart() } return verificationService!! @@ -740,8 +729,8 @@ internal class DefaultCryptoService @Inject constructor( } private fun notifyRoomKeyReceived( - roomId: String, - sessionId: String, + roomId: String, + sessionId: String, ) { // The sender key is actually unused since it's unimportant for megolm // Our events don't contain the info so pass an empty string until we @@ -757,38 +746,38 @@ internal class DefaultCryptoService @Inject constructor( } suspend fun receiveSyncChanges( - toDevice: ToDeviceSyncResponse?, - deviceChanges: DeviceListResponse?, - keyCounts: DeviceOneTimeKeysCountSyncResponse?) { - // Decrypt and handle our to-device events - val toDeviceEvents = this.olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) + toDevice: ToDeviceSyncResponse?, + deviceChanges: DeviceListResponse?, + keyCounts: DeviceOneTimeKeysCountSyncResponse?) { + // Decrypt and handle our to-device events + val toDeviceEvents = this.olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) - // Notify the our listeners about room keys so decryption is retried. - if (toDeviceEvents.events != null) { - toDeviceEvents.events.forEach { event -> - when (event.type) { - EventType.ROOM_KEY -> { - val content = event.getClearContent().toModel() ?: return@forEach + // Notify the our listeners about room keys so decryption is retried. + if (toDeviceEvents.events != null) { + toDeviceEvents.events.forEach { event -> + when (event.type) { + EventType.ROOM_KEY -> { + val content = event.getClearContent().toModel() ?: return@forEach - val roomId = content.sessionId ?: return@forEach - val sessionId = content.sessionId + val roomId = content.sessionId ?: return@forEach + val sessionId = content.sessionId - notifyRoomKeyReceived(roomId, sessionId) - } - EventType.FORWARDED_ROOM_KEY -> { - val content = event.getClearContent().toModel() ?: return@forEach + notifyRoomKeyReceived(roomId, sessionId) + } + EventType.FORWARDED_ROOM_KEY -> { + val content = event.getClearContent().toModel() ?: return@forEach - val roomId = content.sessionId ?: return@forEach - val sessionId = content.sessionId + val roomId = content.sessionId ?: return@forEach + val sessionId = content.sessionId - notifyRoomKeyReceived(roomId, sessionId) - } - else -> { - this.verificationService?.onEvent(event) - } + notifyRoomKeyReceived(roomId, sessionId) + } + else -> { + this.verificationService?.onEvent(event) } } } + } } private suspend fun preshareRoomKey(roomId: String, roomMembers: List) { @@ -800,7 +789,8 @@ internal class DefaultCryptoService @Inject constructor( is Request.KeysClaim -> { claimKeys(request) } - else -> {} + else -> { + } } } } @@ -816,7 +806,7 @@ internal class DefaultCryptoService @Inject constructor( sendToDevice(it) } } - else -> { + else -> { // This request can only be a to-device request but // we need to handle all our cases and put this // async block for our joinAll to work. @@ -861,22 +851,22 @@ internal class DefaultCryptoService @Inject constructor( coroutineScope { olmMachine!!.outgoingRequests().map { when (it) { - is Request.KeysUpload -> { + is Request.KeysUpload -> { async { uploadKeys(it) } } - is Request.KeysQuery -> { + is Request.KeysQuery -> { async { queryKeys(it) } } - is Request.ToDevice -> { + is Request.ToDevice -> { async { sendToDevice(it) } } - is Request.KeysClaim -> { + is Request.KeysClaim -> { async { claimKeys(it) } @@ -912,8 +902,8 @@ internal class DefaultCryptoService @Inject constructor( * @return the result ImportRoomKeysResult */ override suspend fun importRoomKeys(roomKeysAsArray: ByteArray, - password: String, - progressListener: ProgressListener?): ImportRoomKeysResult { + password: String, + progressListener: ProgressListener?): ImportRoomKeysResult { return olmMachine!!.importKeys(roomKeysAsArray, password, progressListener) } @@ -1022,7 +1012,7 @@ internal class DefaultCryptoService @Inject constructor( } } - when(request) { + when (request) { is Request.ToDevice -> { sendToDevice(request) } From f8ad024f1bddcc66b5fec05c0047446d29055f32 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jul 2021 18:36:37 +0200 Subject: [PATCH 130/252] Remove some dead code. --- .../internal/crypto/verification/SASTest.kt | 627 ------- .../actions/SetDeviceVerificationAction.kt | 54 - ...comingSASDefaultVerificationTransaction.kt | 268 --- ...tgoingSASDefaultVerificationTransaction.kt | 260 --- .../DefaultVerificationService.kt | 1478 ----------------- .../DefaultVerificationTransaction.kt | 112 -- .../verification/RustVerificationService.kt | 7 +- .../SASDefaultVerificationTransaction.kt | 423 ----- .../SendVerificationMessageWorker.kt | 88 - .../verification/VerificationInfoStart.kt | 9 +- .../VerificationMessageProcessor.kt | 168 -- .../verification/VerificationTransport.kt | 96 -- .../VerificationTransportRoomMessage.kt | 382 ----- ...VerificationTransportRoomMessageFactory.kt | 49 - .../VerificationTransportToDevice.kt | 248 --- .../VerificationTransportToDeviceFactory.kt | 32 - .../DefaultQrCodeVerificationTransaction.kt | 283 ---- .../sdk/internal/session/SessionComponent.kt | 3 - .../sdk/internal/session/SessionModule.kt | 5 - 19 files changed, 8 insertions(+), 4584 deletions(-) delete mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/SetDeviceVerificationAction.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SendVerificationMessageWorker.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransport.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessageFactory.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDeviceFactory.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt deleted file mode 100644 index 4ea8cdc074..0000000000 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.verification - -import android.util.Log -import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.SasMode -import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod -import org.matrix.android.sdk.api.session.crypto.verification.VerificationService -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.common.CommonTestHelper -import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart -import org.matrix.android.sdk.internal.crypto.model.rest.toValue -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertNull -import org.junit.Assert.assertTrue -import org.junit.Assert.fail -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import java.util.concurrent.CountDownLatch - -@RunWith(AndroidJUnit4::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class SASTest : InstrumentedTest { - private val mTestHelper = CommonTestHelper(context()) - private val mCryptoTestHelper = CryptoTestHelper(mTestHelper) - - @Test - fun test_aliceStartThenAliceCancel() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val aliceSession = cryptoTestData.firstSession - val bobSession = cryptoTestData.secondSession - - val aliceVerificationService = aliceSession.cryptoService().verificationService() - val bobVerificationService = bobSession!!.cryptoService().verificationService() - - val bobTxCreatedLatch = CountDownLatch(1) - val bobListener = object : VerificationService.Listener { - override fun transactionUpdated(tx: VerificationTransaction) { - bobTxCreatedLatch.countDown() - } - } - bobVerificationService.addListener(bobListener) - - val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, - bobSession.myUserId, - bobSession.cryptoService().getMyDevice().deviceId, - null) - assertNotNull("Alice should have a started transaction", txID) - - val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!) - assertNotNull("Alice should have a started transaction", aliceKeyTx) - - mTestHelper.await(bobTxCreatedLatch) - bobVerificationService.removeListener(bobListener) - - val bobKeyTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, txID) - - assertNotNull("Bob should have started verif transaction", bobKeyTx) - assertTrue(bobKeyTx is SASDefaultVerificationTransaction) - assertNotNull("Bob should have starting a SAS transaction", bobKeyTx) - assertTrue(aliceKeyTx is SASDefaultVerificationTransaction) - assertEquals("Alice and Bob have same transaction id", aliceKeyTx!!.transactionId, bobKeyTx!!.transactionId) - - val aliceSasTx = aliceKeyTx as SASDefaultVerificationTransaction? - val bobSasTx = bobKeyTx as SASDefaultVerificationTransaction? - - assertEquals("Alice state should be started", VerificationTxState.Started, aliceSasTx!!.state) - assertEquals("Bob state should be started by alice", VerificationTxState.OnStarted, bobSasTx!!.state) - - // Let's cancel from alice side - val cancelLatch = CountDownLatch(1) - - val bobListener2 = object : VerificationService.Listener { - override fun transactionUpdated(tx: VerificationTransaction) { - if (tx.transactionId == txID) { - val immutableState = (tx as SASDefaultVerificationTransaction).state - if (immutableState is VerificationTxState.Cancelled && !immutableState.byMe) { - cancelLatch.countDown() - } - } - } - } - bobVerificationService.addListener(bobListener2) - - aliceSasTx.cancel(CancelCode.User) - mTestHelper.await(cancelLatch) - - assertTrue("Should be cancelled on alice side", aliceSasTx.state is VerificationTxState.Cancelled) - assertTrue("Should be cancelled on bob side", bobSasTx.state is VerificationTxState.Cancelled) - - val aliceCancelState = aliceSasTx.state as VerificationTxState.Cancelled - val bobCancelState = bobSasTx.state as VerificationTxState.Cancelled - - assertTrue("Should be cancelled by me on alice side", aliceCancelState.byMe) - assertFalse("Should be cancelled by other on bob side", bobCancelState.byMe) - - assertEquals("Should be User cancelled on alice side", CancelCode.User, aliceCancelState.cancelCode) - assertEquals("Should be User cancelled on bob side", CancelCode.User, bobCancelState.cancelCode) - - assertNull(bobVerificationService.getExistingTransaction(aliceSession.myUserId, txID)) - assertNull(aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID)) - - cryptoTestData.cleanUp(mTestHelper) - } - - @Test - fun test_key_agreement_protocols_must_include_curve25519() { - fail("Not passing for the moment") - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val bobSession = cryptoTestData.secondSession!! - - val protocols = listOf("meh_dont_know") - val tid = "00000000" - - // Bob should receive a cancel - var cancelReason: CancelCode? = null - val cancelLatch = CountDownLatch(1) - - val bobListener = object : VerificationService.Listener { - override fun transactionUpdated(tx: VerificationTransaction) { - if (tx.transactionId == tid && tx.state is VerificationTxState.Cancelled) { - cancelReason = (tx.state as VerificationTxState.Cancelled).cancelCode - cancelLatch.countDown() - } - } - } - bobSession.cryptoService().verificationService().addListener(bobListener) - - // TODO bobSession!!.dataHandler.addListener(object : MXEventListener() { - // TODO override fun onToDeviceEvent(event: Event?) { - // TODO if (event!!.getType() == CryptoEvent.EVENT_TYPE_KEY_VERIFICATION_CANCEL) { - // TODO if (event.contentAsJsonObject?.get("transaction_id")?.asString == tid) { - // TODO canceledToDeviceEvent = event - // TODO cancelLatch.countDown() - // TODO } - // TODO } - // TODO } - // TODO }) - - val aliceSession = cryptoTestData.firstSession - val aliceUserID = aliceSession.myUserId - val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId - - val aliceListener = object : VerificationService.Listener { - override fun transactionUpdated(tx: VerificationTransaction) { - if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { - (tx as IncomingSasVerificationTransaction).performAccept() - } - } - } - aliceSession.cryptoService().verificationService().addListener(aliceListener) - - fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, protocols = protocols) - - mTestHelper.await(cancelLatch) - - assertEquals("Request should be cancelled with m.unknown_method", CancelCode.UnknownMethod, cancelReason) - - cryptoTestData.cleanUp(mTestHelper) - } - - @Test - fun test_key_agreement_macs_Must_include_hmac_sha256() { - fail("Not passing for the moment") - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val bobSession = cryptoTestData.secondSession!! - - val mac = listOf("shaBit") - val tid = "00000000" - - // Bob should receive a cancel - var canceledToDeviceEvent: Event? = null - val cancelLatch = CountDownLatch(1) - // TODO bobSession!!.dataHandler.addListener(object : MXEventListener() { - // TODO override fun onToDeviceEvent(event: Event?) { - // TODO if (event!!.getType() == CryptoEvent.EVENT_TYPE_KEY_VERIFICATION_CANCEL) { - // TODO if (event.contentAsJsonObject?.get("transaction_id")?.asString == tid) { - // TODO canceledToDeviceEvent = event - // TODO cancelLatch.countDown() - // TODO } - // TODO } - // TODO } - // TODO }) - - val aliceSession = cryptoTestData.firstSession - val aliceUserID = aliceSession.myUserId - val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId - - fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, mac = mac) - - mTestHelper.await(cancelLatch) - - val cancelReq = canceledToDeviceEvent!!.content.toModel()!! - assertEquals("Request should be cancelled with m.unknown_method", CancelCode.UnknownMethod.value, cancelReq.code) - - cryptoTestData.cleanUp(mTestHelper) - } - - @Test - fun test_key_agreement_short_code_include_decimal() { - fail("Not passing for the moment") - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val bobSession = cryptoTestData.secondSession!! - - val codes = listOf("bin", "foo", "bar") - val tid = "00000000" - - // Bob should receive a cancel - var canceledToDeviceEvent: Event? = null - val cancelLatch = CountDownLatch(1) - // TODO bobSession!!.dataHandler.addListener(object : MXEventListener() { - // TODO override fun onToDeviceEvent(event: Event?) { - // TODO if (event!!.getType() == CryptoEvent.EVENT_TYPE_KEY_VERIFICATION_CANCEL) { - // TODO if (event.contentAsJsonObject?.get("transaction_id")?.asString == tid) { - // TODO canceledToDeviceEvent = event - // TODO cancelLatch.countDown() - // TODO } - // TODO } - // TODO } - // TODO }) - - val aliceSession = cryptoTestData.firstSession - val aliceUserID = aliceSession.myUserId - val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId - - fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, codes = codes) - - mTestHelper.await(cancelLatch) - - val cancelReq = canceledToDeviceEvent!!.content.toModel()!! - assertEquals("Request should be cancelled with m.unknown_method", CancelCode.UnknownMethod.value, cancelReq.code) - - cryptoTestData.cleanUp(mTestHelper) - } - - private fun fakeBobStart(bobSession: Session, - aliceUserID: String?, - aliceDevice: String?, - tid: String, - protocols: List = SASDefaultVerificationTransaction.KNOWN_AGREEMENT_PROTOCOLS, - hashes: List = SASDefaultVerificationTransaction.KNOWN_HASHES, - mac: List = SASDefaultVerificationTransaction.KNOWN_MACS, - codes: List = SASDefaultVerificationTransaction.KNOWN_SHORT_CODES) { - val startMessage = KeyVerificationStart( - fromDevice = bobSession.cryptoService().getMyDevice().deviceId, - method = VerificationMethod.SAS.toValue(), - transactionId = tid, - keyAgreementProtocols = protocols, - hashes = hashes, - messageAuthenticationCodes = mac, - shortAuthenticationStrings = codes - ) - - val contentMap = MXUsersDevicesMap() - contentMap.setObject(aliceUserID, aliceDevice, startMessage) - - // TODO val sendLatch = CountDownLatch(1) - // TODO bobSession.cryptoRestClient.sendToDevice( - // TODO EventType.KEY_VERIFICATION_START, - // TODO contentMap, - // TODO tid, - // TODO TestMatrixCallback(sendLatch) - // TODO ) - } - - // any two devices may only have at most one key verification in flight at a time. - // If a device has two verifications in progress with the same device, then it should cancel both verifications. - @Test - fun test_aliceStartTwoRequests() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val aliceSession = cryptoTestData.firstSession - val bobSession = cryptoTestData.secondSession - - val aliceVerificationService = aliceSession.cryptoService().verificationService() - - val aliceCreatedLatch = CountDownLatch(2) - val aliceCancelledLatch = CountDownLatch(2) - val createdTx = mutableListOf() - val aliceListener = object : VerificationService.Listener { - override fun transactionCreated(tx: VerificationTransaction) { - createdTx.add(tx as SASDefaultVerificationTransaction) - aliceCreatedLatch.countDown() - } - - override fun transactionUpdated(tx: VerificationTransaction) { - if ((tx as SASDefaultVerificationTransaction).state is VerificationTxState.Cancelled && !(tx.state as VerificationTxState.Cancelled).byMe) { - aliceCancelledLatch.countDown() - } - } - } - aliceVerificationService.addListener(aliceListener) - - val bobUserId = bobSession!!.myUserId - val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId - aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) - aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) - - mTestHelper.await(aliceCreatedLatch) - mTestHelper.await(aliceCancelledLatch) - - cryptoTestData.cleanUp(mTestHelper) - } - - /** - * Test that when alice starts a 'correct' request, bob agrees. - */ - @Test - fun test_aliceAndBobAgreement() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val aliceSession = cryptoTestData.firstSession - val bobSession = cryptoTestData.secondSession - - val aliceVerificationService = aliceSession.cryptoService().verificationService() - val bobVerificationService = bobSession!!.cryptoService().verificationService() - - var accepted: ValidVerificationInfoAccept? = null - var startReq: ValidVerificationInfoStart.SasVerificationInfoStart? = null - - val aliceAcceptedLatch = CountDownLatch(1) - val aliceListener = object : VerificationService.Listener { - override fun transactionUpdated(tx: VerificationTransaction) { - Log.v("TEST", "== aliceTx state ${tx.state} => ${(tx as? OutgoingSasVerificationTransaction)?.uxState}") - if ((tx as SASDefaultVerificationTransaction).state === VerificationTxState.OnAccepted) { - val at = tx as SASDefaultVerificationTransaction - accepted = at.accepted - startReq = at.startReq - aliceAcceptedLatch.countDown() - } - } - } - aliceVerificationService.addListener(aliceListener) - - val bobListener = object : VerificationService.Listener { - override fun transactionUpdated(tx: VerificationTransaction) { - Log.v("TEST", "== bobTx state ${tx.state} => ${(tx as? IncomingSasVerificationTransaction)?.uxState}") - if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { - bobVerificationService.removeListener(this) - val at = tx as IncomingSasVerificationTransaction - at.performAccept() - } - } - } - bobVerificationService.addListener(bobListener) - - val bobUserId = bobSession.myUserId - val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId - aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) - mTestHelper.await(aliceAcceptedLatch) - - assertTrue("Should have receive a commitment", accepted!!.commitment?.trim()?.isEmpty() == false) - - // check that agreement is valid - assertTrue("Agreed Protocol should be Valid", accepted != null) - assertTrue("Agreed Protocol should be known by alice", startReq!!.keyAgreementProtocols.contains(accepted!!.keyAgreementProtocol)) - assertTrue("Hash should be known by alice", startReq!!.hashes.contains(accepted!!.hash)) - assertTrue("Hash should be known by alice", startReq!!.messageAuthenticationCodes.contains(accepted!!.messageAuthenticationCode)) - - accepted!!.shortAuthenticationStrings.forEach { - assertTrue("all agreed Short Code should be known by alice", startReq!!.shortAuthenticationStrings.contains(it)) - } - - cryptoTestData.cleanUp(mTestHelper) - } - - @Test - fun test_aliceAndBobSASCode() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val aliceSession = cryptoTestData.firstSession - val bobSession = cryptoTestData.secondSession - - val aliceVerificationService = aliceSession.cryptoService().verificationService() - val bobVerificationService = bobSession!!.cryptoService().verificationService() - - val aliceSASLatch = CountDownLatch(1) - val aliceListener = object : VerificationService.Listener { - override fun transactionUpdated(tx: VerificationTransaction) { - val uxState = (tx as OutgoingSasVerificationTransaction).uxState - when (uxState) { - OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> { - aliceSASLatch.countDown() - } - else -> Unit - } - } - } - aliceVerificationService.addListener(aliceListener) - - val bobSASLatch = CountDownLatch(1) - val bobListener = object : VerificationService.Listener { - override fun transactionUpdated(tx: VerificationTransaction) { - val uxState = (tx as IncomingSasVerificationTransaction).uxState - when (uxState) { - IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> { - tx.performAccept() - } - else -> Unit - } - if (uxState === IncomingSasVerificationTransaction.UxState.SHOW_SAS) { - bobSASLatch.countDown() - } - } - } - bobVerificationService.addListener(bobListener) - - val bobUserId = bobSession.myUserId - val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId - val verificationSAS = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) - mTestHelper.await(aliceSASLatch) - mTestHelper.await(bobSASLatch) - - val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SASDefaultVerificationTransaction - val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SASDefaultVerificationTransaction - - assertEquals("Should have same SAS", aliceTx.getShortCodeRepresentation(SasMode.DECIMAL), - bobTx.getShortCodeRepresentation(SasMode.DECIMAL)) - - cryptoTestData.cleanUp(mTestHelper) - } - - @Test - fun test_happyPath() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val aliceSession = cryptoTestData.firstSession - val bobSession = cryptoTestData.secondSession - - val aliceVerificationService = aliceSession.cryptoService().verificationService() - val bobVerificationService = bobSession!!.cryptoService().verificationService() - - val aliceSASLatch = CountDownLatch(1) - val aliceListener = object : VerificationService.Listener { - var matchOnce = true - override fun transactionUpdated(tx: VerificationTransaction) { - val uxState = (tx as OutgoingSasVerificationTransaction).uxState - Log.v("TEST", "== aliceState ${uxState.name}") - when (uxState) { - OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> { - tx.userHasVerifiedShortCode() - } - OutgoingSasVerificationTransaction.UxState.VERIFIED -> { - if (matchOnce) { - matchOnce = false - aliceSASLatch.countDown() - } - } - else -> Unit - } - } - } - aliceVerificationService.addListener(aliceListener) - - val bobSASLatch = CountDownLatch(1) - val bobListener = object : VerificationService.Listener { - var acceptOnce = true - var matchOnce = true - override fun transactionUpdated(tx: VerificationTransaction) { - val uxState = (tx as IncomingSasVerificationTransaction).uxState - Log.v("TEST", "== bobState ${uxState.name}") - when (uxState) { - IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> { - if (acceptOnce) { - acceptOnce = false - tx.performAccept() - } - } - IncomingSasVerificationTransaction.UxState.SHOW_SAS -> { - if (matchOnce) { - matchOnce = false - tx.userHasVerifiedShortCode() - } - } - IncomingSasVerificationTransaction.UxState.VERIFIED -> { - bobSASLatch.countDown() - } - else -> Unit - } - } - } - bobVerificationService.addListener(bobListener) - - val bobUserId = bobSession.myUserId - val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId - aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) - mTestHelper.await(aliceSASLatch) - mTestHelper.await(bobSASLatch) - - // Assert that devices are verified - val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId) - val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId) - - // latch wait a bit again - Thread.sleep(1000) - - assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified) - assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified) - cryptoTestData.cleanUp(mTestHelper) - } - - @Test - fun test_ConcurrentStart() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() - - val aliceSession = cryptoTestData.firstSession - val bobSession = cryptoTestData.secondSession - - val aliceVerificationService = aliceSession.cryptoService().verificationService() - val bobVerificationService = bobSession!!.cryptoService().verificationService() - - val req = aliceVerificationService.requestKeyVerificationInDMs( - listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW), - bobSession.myUserId, - cryptoTestData.roomId - ) - - var requestID : String? = null - - mTestHelper.waitWithLatch { - mTestHelper.retryPeriodicallyWithLatch(it) { - val prAlicePOV = aliceVerificationService.getExistingVerificationRequests(bobSession.myUserId).firstOrNull() - requestID = prAlicePOV?.transactionId - Log.v("TEST", "== alicePOV is $prAlicePOV") - prAlicePOV?.transactionId != null && prAlicePOV.localId == req.localId - } - } - - Log.v("TEST", "== requestID is $requestID") - - mTestHelper.waitWithLatch { - mTestHelper.retryPeriodicallyWithLatch(it) { - val prBobPOV = bobVerificationService.getExistingVerificationRequests(aliceSession.myUserId).firstOrNull() - Log.v("TEST", "== prBobPOV is $prBobPOV") - prBobPOV?.transactionId == requestID - } - } - - bobVerificationService.readyPendingVerification( - listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW), - aliceSession.myUserId, - requestID!! - ) - - // wait for alice to get the ready - mTestHelper.waitWithLatch { - mTestHelper.retryPeriodicallyWithLatch(it) { - val prAlicePOV = aliceVerificationService.getExistingVerificationRequests(bobSession.myUserId).firstOrNull() - Log.v("TEST", "== prAlicePOV is $prAlicePOV") - prAlicePOV?.transactionId == requestID && prAlicePOV?.isReady != null - } - } - - // Start concurrent! - aliceVerificationService.beginKeyVerificationInDMs( - VerificationMethod.SAS, - requestID!!, - cryptoTestData.roomId, - bobSession.myUserId, - bobSession.sessionParams.deviceId!!) - - bobVerificationService.beginKeyVerificationInDMs( - VerificationMethod.SAS, - requestID!!, - cryptoTestData.roomId, - aliceSession.myUserId, - aliceSession.sessionParams.deviceId!!) - - // we should reach SHOW SAS on both - var alicePovTx: SasVerificationTransaction? - var bobPovTx: SasVerificationTransaction? - - mTestHelper.waitWithLatch { - mTestHelper.retryPeriodicallyWithLatch(it) { - alicePovTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, requestID!!) as? SasVerificationTransaction - Log.v("TEST", "== alicePovTx is $alicePovTx") - alicePovTx?.state == VerificationTxState.ShortCodeReady - } - } - // wait for alice to get the ready - mTestHelper.waitWithLatch { - mTestHelper.retryPeriodicallyWithLatch(it) { - bobPovTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, requestID!!) as? SasVerificationTransaction - Log.v("TEST", "== bobPovTx is $bobPovTx") - bobPovTx?.state == VerificationTxState.ShortCodeReady - } - } - - cryptoTestData.cleanUp(mTestHelper) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/SetDeviceVerificationAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/SetDeviceVerificationAction.kt deleted file mode 100644 index 40eddc82bd..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/SetDeviceVerificationAction.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.actions - -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.di.UserId -import timber.log.Timber -import javax.inject.Inject - -internal class SetDeviceVerificationAction @Inject constructor( - private val cryptoStore: IMXCryptoStore, - @UserId private val userId: String, - private val defaultKeysBackupService: DefaultKeysBackupService) { - - fun handle(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) { - val device = cryptoStore.getUserDevice(userId, deviceId) - - // Sanity check - if (null == device) { - Timber.w("## setDeviceVerification() : Unknown device $userId:$deviceId") - return - } - - if (device.isVerified != trustLevel.isVerified()) { - if (userId == this.userId) { - // If one of the user's own devices is being marked as verified / unverified, - // check the key backup status, since whether or not we use this depends on - // whether it has a signature from a verified device - defaultKeysBackupService.checkAndStartKeysBackup() - } - } - - if (device.trustLevel != trustLevel) { - device.trustLevel = trustLevel - cryptoStore.setDeviceTrust(userId, deviceId, trustLevel.crossSigningVerified, trustLevel.locallyVerified) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt deleted file mode 100644 index e061976618..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultIncomingSASDefaultVerificationTransaction.kt +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import android.util.Base64 -import org.matrix.android.sdk.BuildConfig -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.SasMode -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import timber.log.Timber - -internal class DefaultIncomingSASDefaultVerificationTransaction( - setDeviceVerificationAction: SetDeviceVerificationAction, - override val userId: String, - override val deviceId: String?, - private val cryptoStore: IMXCryptoStore, - crossSigningService: CrossSigningService, - outgoingGossipingRequestManager: OutgoingGossipingRequestManager, - incomingGossipingRequestManager: IncomingGossipingRequestManager, - deviceFingerprint: String, - transactionId: String, - otherUserID: String, - private val autoAccept: Boolean = false -) : SASDefaultVerificationTransaction( - setDeviceVerificationAction, - userId, - deviceId, - cryptoStore, - crossSigningService, - outgoingGossipingRequestManager, - incomingGossipingRequestManager, - deviceFingerprint, - transactionId, - otherUserID, - null, - isIncoming = true), - IncomingSasVerificationTransaction { - - override val uxState: IncomingSasVerificationTransaction.UxState - get() { - return when (val immutableState = state) { - is VerificationTxState.OnStarted -> IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT - is VerificationTxState.SendingAccept, - is VerificationTxState.Accepted, - is VerificationTxState.OnKeyReceived, - is VerificationTxState.SendingKey, - is VerificationTxState.KeySent -> IncomingSasVerificationTransaction.UxState.WAIT_FOR_KEY_AGREEMENT - is VerificationTxState.ShortCodeReady -> IncomingSasVerificationTransaction.UxState.SHOW_SAS - is VerificationTxState.ShortCodeAccepted, - is VerificationTxState.SendingMac, - is VerificationTxState.MacSent, - is VerificationTxState.Verifying -> IncomingSasVerificationTransaction.UxState.WAIT_FOR_VERIFICATION - is VerificationTxState.Verified -> IncomingSasVerificationTransaction.UxState.VERIFIED - is VerificationTxState.Cancelled -> { - if (immutableState.byMe) { - IncomingSasVerificationTransaction.UxState.CANCELLED_BY_ME - } else { - IncomingSasVerificationTransaction.UxState.CANCELLED_BY_OTHER - } - } - else -> IncomingSasVerificationTransaction.UxState.UNKNOWN - } - } - - override fun acceptVerification() { - this.performAccept() - } - - override fun onVerificationStart(startReq: ValidVerificationInfoStart.SasVerificationInfoStart) { - Timber.v("## SAS I: received verification request from state $state") - if (state != VerificationTxState.None) { - Timber.e("## SAS I: received verification request from invalid state") - // should I cancel?? - throw IllegalStateException("Interactive Key verification already started") - } - this.startReq = startReq - state = VerificationTxState.OnStarted - this.otherDeviceId = startReq.fromDevice - - if (autoAccept) { - performAccept() - } - } - - override fun performAccept() { - if (state != VerificationTxState.OnStarted) { - Timber.e("## SAS Cannot perform accept from state $state") - return - } - - // Select a key agreement protocol, a hash algorithm, a message authentication code, - // and short authentication string methods out of the lists given in requester's message. - val agreedProtocol = startReq!!.keyAgreementProtocols.firstOrNull { KNOWN_AGREEMENT_PROTOCOLS.contains(it) } - val agreedHash = startReq!!.hashes.firstOrNull { KNOWN_HASHES.contains(it) } - val agreedMac = startReq!!.messageAuthenticationCodes.firstOrNull { KNOWN_MACS.contains(it) } - val agreedShortCode = startReq!!.shortAuthenticationStrings.filter { KNOWN_SHORT_CODES.contains(it) } - - // No common key sharing/hashing/hmac/SAS methods. - // If a device is unable to complete the verification because the devices are unable to find a common key sharing, - // hashing, hmac, or SAS method, then it should send a m.key.verification.cancel message - if (listOf(agreedProtocol, agreedHash, agreedMac).any { it.isNullOrBlank() } - || agreedShortCode.isNullOrEmpty()) { - // Failed to find agreement - Timber.e("## SAS Failed to find agreement ") - cancel(CancelCode.UnknownMethod) - return - } - - // Bob’s device ensures that it has a copy of Alice’s device key. - val mxDeviceInfo = cryptoStore.getUserDevice(userId = otherUserId, deviceId = otherDeviceId!!) - - if (mxDeviceInfo?.fingerprint() == null) { - Timber.e("## SAS Failed to find device key ") - // TODO force download keys!! - // would be probably better to download the keys - // for now I cancel - cancel(CancelCode.User) - } else { - // val otherKey = info.identityKey() - // need to jump back to correct thread - val accept = transport.createAccept( - tid = transactionId, - keyAgreementProtocol = agreedProtocol!!, - hash = agreedHash!!, - messageAuthenticationCode = agreedMac!!, - shortAuthenticationStrings = agreedShortCode, - commitment = Base64.encodeToString("temporary commitment".toByteArray(), Base64.DEFAULT) - ) - doAccept(accept) - } - } - - private fun doAccept(accept: VerificationInfoAccept) { - this.accepted = accept.asValidObject() - Timber.v("## SAS incoming accept request id:$transactionId") - - // The hash commitment is the hash (using the selected hash algorithm) of the unpadded base64 representation of QB, - // concatenated with the canonical JSON representation of the content of the m.key.verification.start message - val concat = getSAS().publicKey + startReq!!.canonicalJson - accept.commitment = hashUsingAgreedHashMethod(concat) ?: "" - // we need to send this to other device now - state = VerificationTxState.SendingAccept - sendToOther(EventType.KEY_VERIFICATION_ACCEPT, accept, VerificationTxState.Accepted, CancelCode.User) { - if (state == VerificationTxState.SendingAccept) { - // It is possible that we receive the next event before this one :/, in this case we should keep state - state = VerificationTxState.Accepted - } - } - } - - override fun onVerificationAccept(accept: ValidVerificationInfoAccept) { - Timber.v("## SAS invalid message for incoming request id:$transactionId") - cancel(CancelCode.UnexpectedMessage) - } - - override fun onKeyVerificationKey(vKey: ValidVerificationInfoKey) { - Timber.v("## SAS received key for request id:$transactionId") - if (state != VerificationTxState.SendingAccept && state != VerificationTxState.Accepted) { - Timber.e("## SAS received key from invalid state $state") - cancel(CancelCode.UnexpectedMessage) - return - } - - otherKey = vKey.key - // Upon receipt of the m.key.verification.key message from Alice’s device, - // Bob’s device replies with a to_device message with type set to m.key.verification.key, - // sending Bob’s public key QB - val pubKey = getSAS().publicKey - - val keyToDevice = transport.createKey(transactionId, pubKey) - // we need to send this to other device now - state = VerificationTxState.SendingKey - this.sendToOther(EventType.KEY_VERIFICATION_KEY, keyToDevice, VerificationTxState.KeySent, CancelCode.User) { - if (state == VerificationTxState.SendingKey) { - // It is possible that we receive the next event before this one :/, in this case we should keep state - state = VerificationTxState.KeySent - } - } - - // Alice’s and Bob’s devices perform an Elliptic-curve Diffie-Hellman - // (calculate the point (x,y)=dAQB=dBQA and use x as the result of the ECDH), - // using the result as the shared secret. - - getSAS().setTheirPublicKey(otherKey) - - shortCodeBytes = calculateSASBytes() - - if (BuildConfig.LOG_PRIVATE_DATA) { - Timber.v("************ BOB CODE ${getDecimalCodeRepresentation(shortCodeBytes!!)}") - Timber.v("************ BOB EMOJI CODE ${getShortCodeRepresentation(SasMode.EMOJI)}") - } - - state = VerificationTxState.ShortCodeReady - } - - private fun calculateSASBytes(): ByteArray { - when (accepted?.keyAgreementProtocol) { - KEY_AGREEMENT_V1 -> { - // (Note: In all of the following HKDF is as defined in RFC 5869, and uses the previously agreed-on hash function as the hash function, - // the shared secret as the input keying material, no salt, and with the input parameter set to the concatenation of: - // - the string “MATRIX_KEY_VERIFICATION_SAS”, - // - the Matrix ID of the user who sent the m.key.verification.start message, - // - the device ID of the device that sent the m.key.verification.start message, - // - the Matrix ID of the user who sent the m.key.verification.accept message, - // - he device ID of the device that sent the m.key.verification.accept message - // - the transaction ID. - val sasInfo = "MATRIX_KEY_VERIFICATION_SAS$otherUserId$otherDeviceId$userId$deviceId$transactionId" - - // decimal: generate five bytes by using HKDF. - // emoji: generate six bytes by using HKDF. - return getSAS().generateShortCode(sasInfo, 6) - } - KEY_AGREEMENT_V2 -> { - // Adds the SAS public key, and separate by | - val sasInfo = "MATRIX_KEY_VERIFICATION_SAS|$otherUserId|$otherDeviceId|$otherKey|$userId|$deviceId|${getSAS().publicKey}|$transactionId" - return getSAS().generateShortCode(sasInfo, 6) - } - else -> { - // Protocol has been checked earlier - throw IllegalArgumentException() - } - } - } - - override fun onKeyVerificationMac(vMac: ValidVerificationInfoMac) { - Timber.v("## SAS I: received mac for request id:$transactionId") - // Check for state? - if (state != VerificationTxState.SendingKey - && state != VerificationTxState.KeySent - && state != VerificationTxState.ShortCodeReady - && state != VerificationTxState.ShortCodeAccepted - && state != VerificationTxState.SendingMac - && state != VerificationTxState.MacSent) { - Timber.e("## SAS I: received key from invalid state $state") - cancel(CancelCode.UnexpectedMessage) - return - } - - theirMac = vMac - - // Do I have my Mac? - if (myMac != null) { - // I can check - verifyMacs(vMac) - } - // Wait for ShortCode Accepted - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt deleted file mode 100644 index d8568b0a96..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultOutgoingSASDefaultVerificationTransaction.kt +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import timber.log.Timber - -internal class DefaultOutgoingSASDefaultVerificationTransaction( - setDeviceVerificationAction: SetDeviceVerificationAction, - userId: String, - deviceId: String?, - cryptoStore: IMXCryptoStore, - crossSigningService: CrossSigningService, - outgoingGossipingRequestManager: OutgoingGossipingRequestManager, - incomingGossipingRequestManager: IncomingGossipingRequestManager, - deviceFingerprint: String, - transactionId: String, - otherUserId: String, - otherDeviceId: String -) : SASDefaultVerificationTransaction( - setDeviceVerificationAction, - userId, - deviceId, - cryptoStore, - crossSigningService, - outgoingGossipingRequestManager, - incomingGossipingRequestManager, - deviceFingerprint, - transactionId, - otherUserId, - otherDeviceId, - isIncoming = false), - OutgoingSasVerificationTransaction { - - override val uxState: OutgoingSasVerificationTransaction.UxState - get() { - return when (val immutableState = state) { - is VerificationTxState.None -> OutgoingSasVerificationTransaction.UxState.WAIT_FOR_START - is VerificationTxState.SendingStart, - is VerificationTxState.Started, - is VerificationTxState.OnAccepted, - is VerificationTxState.SendingKey, - is VerificationTxState.KeySent, - is VerificationTxState.OnKeyReceived -> OutgoingSasVerificationTransaction.UxState.WAIT_FOR_KEY_AGREEMENT - is VerificationTxState.ShortCodeReady -> OutgoingSasVerificationTransaction.UxState.SHOW_SAS - is VerificationTxState.ShortCodeAccepted, - is VerificationTxState.SendingMac, - is VerificationTxState.MacSent, - is VerificationTxState.Verifying -> OutgoingSasVerificationTransaction.UxState.WAIT_FOR_VERIFICATION - is VerificationTxState.Verified -> OutgoingSasVerificationTransaction.UxState.VERIFIED - is VerificationTxState.Cancelled -> { - if (immutableState.byMe) { - OutgoingSasVerificationTransaction.UxState.CANCELLED_BY_OTHER - } else { - OutgoingSasVerificationTransaction.UxState.CANCELLED_BY_ME - } - } - else -> OutgoingSasVerificationTransaction.UxState.UNKNOWN - } - } - - override fun onVerificationStart(startReq: ValidVerificationInfoStart.SasVerificationInfoStart) { - Timber.e("## SAS O: onVerificationStart - unexpected id:$transactionId") - cancel(CancelCode.UnexpectedMessage) - } - - override fun acceptVerification() { - return - } - - fun start() { - if (state != VerificationTxState.None) { - Timber.e("## SAS O: start verification from invalid state") - // should I cancel?? - throw IllegalStateException("Interactive Key verification already started") - } - - val startMessage = transport.createStartForSas( - deviceId ?: "", - transactionId, - KNOWN_AGREEMENT_PROTOCOLS, - KNOWN_HASHES, - KNOWN_MACS, - KNOWN_SHORT_CODES - ) - - startReq = startMessage.asValidObject() as? ValidVerificationInfoStart.SasVerificationInfoStart - state = VerificationTxState.SendingStart - - sendToOther( - EventType.KEY_VERIFICATION_START, - startMessage, - VerificationTxState.Started, - CancelCode.User, - null - ) - } - -// fun request() { -// if (state != VerificationTxState.None) { -// Timber.e("## start verification from invalid state") -// // should I cancel?? -// throw IllegalStateException("Interactive Key verification already started") -// } -// -// val requestMessage = KeyVerificationRequest( -// fromDevice = session.sessionParams.deviceId ?: "", -// methods = listOf(KeyVerificationStart.VERIF_METHOD_SAS), -// timestamp = System.currentTimeMillis().toInt(), -// transactionId = transactionId -// ) -// -// sendToOther( -// EventType.KEY_VERIFICATION_REQUEST, -// requestMessage, -// VerificationTxState.None, -// CancelCode.User, -// null -// ) -// } - - override fun onVerificationAccept(accept: ValidVerificationInfoAccept) { - Timber.v("## SAS O: onVerificationAccept id:$transactionId") - if (state != VerificationTxState.Started && state != VerificationTxState.SendingStart) { - Timber.e("## SAS O: received accept request from invalid state $state") - cancel(CancelCode.UnexpectedMessage) - return - } - // Check that the agreement is correct - if (!KNOWN_AGREEMENT_PROTOCOLS.contains(accept.keyAgreementProtocol) - || !KNOWN_HASHES.contains(accept.hash) - || !KNOWN_MACS.contains(accept.messageAuthenticationCode) - || accept.shortAuthenticationStrings.intersect(KNOWN_SHORT_CODES).isEmpty()) { - Timber.e("## SAS O: received invalid accept") - cancel(CancelCode.UnknownMethod) - return - } - - // Upon receipt of the m.key.verification.accept message from Bob’s device, - // Alice’s device stores the commitment value for later use. - accepted = accept - state = VerificationTxState.OnAccepted - - // Alice’s device creates an ephemeral Curve25519 key pair (dA,QA), - // and replies with a to_device message with type set to “m.key.verification.key”, sending Alice’s public key QA - val pubKey = getSAS().publicKey - - val keyToDevice = transport.createKey(transactionId, pubKey) - // we need to send this to other device now - state = VerificationTxState.SendingKey - sendToOther(EventType.KEY_VERIFICATION_KEY, keyToDevice, VerificationTxState.KeySent, CancelCode.User) { - // It is possible that we receive the next event before this one :/, in this case we should keep state - if (state == VerificationTxState.SendingKey) { - state = VerificationTxState.KeySent - } - } - } - - override fun onKeyVerificationKey(vKey: ValidVerificationInfoKey) { - Timber.v("## SAS O: onKeyVerificationKey id:$transactionId") - if (state != VerificationTxState.SendingKey && state != VerificationTxState.KeySent) { - Timber.e("## received key from invalid state $state") - cancel(CancelCode.UnexpectedMessage) - return - } - - otherKey = vKey.key - // Upon receipt of the m.key.verification.key message from Bob’s device, - // Alice’s device checks that the commitment property from the Bob’s m.key.verification.accept - // message is the same as the expected value based on the value of the key property received - // in Bob’s m.key.verification.key and the content of Alice’s m.key.verification.start message. - - // check commitment - val concat = vKey.key + startReq!!.canonicalJson - val otherCommitment = hashUsingAgreedHashMethod(concat) ?: "" - - if (accepted!!.commitment.equals(otherCommitment)) { - getSAS().setTheirPublicKey(otherKey) - shortCodeBytes = calculateSASBytes() - state = VerificationTxState.ShortCodeReady - } else { - // bad commitment - cancel(CancelCode.MismatchedCommitment) - } - } - - private fun calculateSASBytes(): ByteArray { - when (accepted?.keyAgreementProtocol) { - KEY_AGREEMENT_V1 -> { - // (Note: In all of the following HKDF is as defined in RFC 5869, and uses the previously agreed-on hash function as the hash function, - // the shared secret as the input keying material, no salt, and with the input parameter set to the concatenation of: - // - the string “MATRIX_KEY_VERIFICATION_SAS”, - // - the Matrix ID of the user who sent the m.key.verification.start message, - // - the device ID of the device that sent the m.key.verification.start message, - // - the Matrix ID of the user who sent the m.key.verification.accept message, - // - he device ID of the device that sent the m.key.verification.accept message - // - the transaction ID. - val sasInfo = "MATRIX_KEY_VERIFICATION_SAS$userId$deviceId$otherUserId$otherDeviceId$transactionId" - - // decimal: generate five bytes by using HKDF. - // emoji: generate six bytes by using HKDF. - return getSAS().generateShortCode(sasInfo, 6) - } - KEY_AGREEMENT_V2 -> { - // Adds the SAS public key, and separate by | - val sasInfo = "MATRIX_KEY_VERIFICATION_SAS|$userId|$deviceId|${getSAS().publicKey}|$otherUserId|$otherDeviceId|$otherKey|$transactionId" - return getSAS().generateShortCode(sasInfo, 6) - } - else -> { - // Protocol has been checked earlier - throw IllegalArgumentException() - } - } - } - - override fun onKeyVerificationMac(vMac: ValidVerificationInfoMac) { - Timber.v("## SAS O: onKeyVerificationMac id:$transactionId") - // There is starting to be a huge amount of state / race here :/ - if (state != VerificationTxState.OnKeyReceived - && state != VerificationTxState.ShortCodeReady - && state != VerificationTxState.ShortCodeAccepted - && state != VerificationTxState.KeySent - && state != VerificationTxState.SendingMac - && state != VerificationTxState.MacSent) { - Timber.e("## SAS O: received mac from invalid state $state") - cancel(CancelCode.UnexpectedMessage) - return - } - - theirMac = vMac - - // Do I have my Mac? - if (myMac != null) { - // I can check - verifyMacs(vMac) - } - // Wait for ShortCode Accepted - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt deleted file mode 100644 index d9da88770c..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt +++ /dev/null @@ -1,1478 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.verification - -import android.os.Handler -import android.os.Looper -import dagger.Lazy -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME -import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME -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.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest -import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady -import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod -import org.matrix.android.sdk.api.session.crypto.verification.VerificationService -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.LocalEcho -import org.matrix.android.sdk.api.session.events.model.RelationType -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.room.model.message.MessageContent -import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent -import org.matrix.android.sdk.api.session.room.model.message.MessageType -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationAcceptContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationCancelContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationDoneContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationKeyContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationMacContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationReadyContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationStartContent -import org.matrix.android.sdk.api.session.room.model.message.ValidVerificationDone -import org.matrix.android.sdk.internal.crypto.DeviceListManager -import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.MyDeviceInfoHolder -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -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.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationAccept -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel -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.KeyVerificationMac -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationReady -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS -import org.matrix.android.sdk.internal.crypto.model.rest.toValue -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.verification.qrcode.DefaultQrCodeVerificationTransaction -import org.matrix.android.sdk.internal.crypto.verification.qrcode.QrCodeData -import org.matrix.android.sdk.internal.crypto.verification.qrcode.generateSharedSecretV2 -import org.matrix.android.sdk.internal.di.DeviceId -import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.task.TaskExecutor -import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import timber.log.Timber -import java.util.UUID -import javax.inject.Inject -import kotlin.collections.set - -@SessionScope -internal class DefaultVerificationService @Inject constructor( - @UserId private val userId: String, - @DeviceId private val deviceId: String?, - private val cryptoStore: IMXCryptoStore, - private val outgoingGossipingRequestManager: OutgoingGossipingRequestManager, - private val incomingGossipingRequestManager: IncomingGossipingRequestManager, - private val myDeviceInfoHolder: Lazy, - private val deviceListManager: DeviceListManager, - private val setDeviceVerificationAction: SetDeviceVerificationAction, - private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val verificationTransportRoomMessageFactory: VerificationTransportRoomMessageFactory, - private val verificationTransportToDeviceFactory: VerificationTransportToDeviceFactory, - private val crossSigningService: CrossSigningService, - private val cryptoCoroutineScope: CoroutineScope, - private val taskExecutor: TaskExecutor -) : DefaultVerificationTransaction.Listener, VerificationService { - - private val uiHandler = Handler(Looper.getMainLooper()) - - // map [sender : [transaction]] - private val txMap = HashMap>() - - // we need to keep track of finished transaction - // It will be used for gossiping (to send request after request is completed and 'done' by other) - private val pastTransactions = HashMap>() - - /** - * Map [sender: [PendingVerificationRequest]] - * For now we keep all requests (even terminated ones) during the lifetime of the app. - */ - private val pendingRequests = HashMap>() - - // Event received from the sync - fun onToDeviceEvent(event: Event) { - Timber.d("## SAS onToDeviceEvent ${event.getClearType()}") - cryptoCoroutineScope.launch(coroutineDispatchers.dmVerif) { - when (event.getClearType()) { - EventType.KEY_VERIFICATION_START -> { - onStartRequestReceived(event) - } - EventType.KEY_VERIFICATION_CANCEL -> { - onCancelReceived(event) - } - EventType.KEY_VERIFICATION_ACCEPT -> { - onAcceptReceived(event) - } - EventType.KEY_VERIFICATION_KEY -> { - onKeyReceived(event) - } - EventType.KEY_VERIFICATION_MAC -> { - onMacReceived(event) - } - EventType.KEY_VERIFICATION_READY -> { - onReadyReceived(event) - } - EventType.KEY_VERIFICATION_DONE -> { - onDoneReceived(event) - } - MessageType.MSGTYPE_VERIFICATION_REQUEST -> { - onRequestReceived(event) - } - else -> { - // ignore - } - } - } - } - - fun onRoomEvent(event: Event) { - cryptoCoroutineScope.launch(coroutineDispatchers.dmVerif) { - when (event.getClearType()) { - EventType.KEY_VERIFICATION_START -> { - onRoomStartRequestReceived(event) - } - EventType.KEY_VERIFICATION_CANCEL -> { - // MultiSessions | ignore events if i didn't sent the start from this device, or accepted from this device - onRoomCancelReceived(event) - } - EventType.KEY_VERIFICATION_ACCEPT -> { - onRoomAcceptReceived(event) - } - EventType.KEY_VERIFICATION_KEY -> { - onRoomKeyRequestReceived(event) - } - EventType.KEY_VERIFICATION_MAC -> { - onRoomMacReceived(event) - } - EventType.KEY_VERIFICATION_READY -> { - onRoomReadyReceived(event) - } - EventType.KEY_VERIFICATION_DONE -> { - onRoomDoneReceived(event) - } - EventType.MESSAGE -> { - if (MessageType.MSGTYPE_VERIFICATION_REQUEST == event.getClearContent().toModel()?.msgType) { - onRoomRequestReceived(event) - } - } - else -> { - // ignore - } - } - } - } - - private var listeners = ArrayList() - - override fun addListener(listener: VerificationService.Listener) { - uiHandler.post { - if (!listeners.contains(listener)) { - listeners.add(listener) - } - } - } - - override fun removeListener(listener: VerificationService.Listener) { - uiHandler.post { - listeners.remove(listener) - } - } - - private fun dispatchTxAdded(tx: VerificationTransaction) { - uiHandler.post { - listeners.forEach { - try { - it.transactionCreated(tx) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } - - private fun dispatchTxUpdated(tx: VerificationTransaction) { - uiHandler.post { - listeners.forEach { - try { - it.transactionUpdated(tx) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } - - private fun dispatchRequestAdded(tx: PendingVerificationRequest) { - Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId}") - uiHandler.post { - listeners.forEach { - try { - it.verificationRequestCreated(tx) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } - - private fun dispatchRequestUpdated(tx: PendingVerificationRequest) { - uiHandler.post { - listeners.forEach { - try { - it.verificationRequestUpdated(tx) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } - - override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { - setDeviceVerificationAction.handle(DeviceTrustLevel(false, true), - userId, - deviceID) - - listeners.forEach { - try { - it.markedAsManuallyVerified(userId, deviceID) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - - fun onRoomRequestHandledByOtherDevice(event: Event) { - val requestInfo = event.content.toModel() - ?: return - val requestId = requestInfo.relatesTo?.eventId ?: return - getExistingVerificationRequestInRoom(event.roomId ?: "", requestId)?.let { - updatePendingRequest( - it.copy( - handledByOtherSession = true - ) - ) - } - } - - private fun onRequestReceived(event: Event) { - val validRequestInfo = event.getClearContent().toModel()?.asValidObject() - - if (validRequestInfo == null) { - // ignore - Timber.e("## SAS Received invalid key request") - return - } - val senderId = event.senderId ?: return - - // We don't want to block here - val otherDeviceId = validRequestInfo.fromDevice - - Timber.v("## SAS onRequestReceived from $senderId and device $otherDeviceId, txId:${validRequestInfo.transactionId}") - - cryptoCoroutineScope.launch { - if (checkKeysAreDownloaded(senderId, otherDeviceId) == null) { - Timber.e("## Verification device $otherDeviceId is not known") - } - } - Timber.v("## SAS onRequestReceived .. checkKeysAreDownloaded launched") - - // Remember this request - val requestsForUser = pendingRequests.getOrPut(senderId) { mutableListOf() } - - val pendingVerificationRequest = PendingVerificationRequest( - ageLocalTs = event.ageLocalTs ?: System.currentTimeMillis(), - isIncoming = true, - otherUserId = senderId, // requestInfo.toUserId, - roomId = null, - transactionId = validRequestInfo.transactionId, - localId = validRequestInfo.transactionId, - requestInfo = validRequestInfo - ) - requestsForUser.add(pendingVerificationRequest) - dispatchRequestAdded(pendingVerificationRequest) - } - - suspend fun onRoomRequestReceived(event: Event) { - Timber.v("## SAS Verification request from ${event.senderId} in room ${event.roomId}") - val requestInfo = event.getClearContent().toModel() ?: return - val validRequestInfo = requestInfo - // copy the EventId to the transactionId - .copy(transactionId = event.eventId) - .asValidObject() ?: return - - val senderId = event.senderId ?: return - - if (requestInfo.toUserId != userId) { - // I should ignore this, it's not for me - Timber.w("## SAS Verification ignoring request from ${event.senderId}, not sent to me") - return - } - - // We don't want to block here - taskExecutor.executorScope.launch { - if (checkKeysAreDownloaded(senderId, validRequestInfo.fromDevice) == null) { - Timber.e("## SAS Verification device ${validRequestInfo.fromDevice} is not known") - } - } - - // Remember this request - val requestsForUser = pendingRequests.getOrPut(senderId) { mutableListOf() } - - val pendingVerificationRequest = PendingVerificationRequest( - ageLocalTs = event.ageLocalTs ?: System.currentTimeMillis(), - isIncoming = true, - otherUserId = senderId, // requestInfo.toUserId, - roomId = event.roomId, - transactionId = event.eventId, - localId = event.eventId!!, - requestInfo = validRequestInfo - ) - requestsForUser.add(pendingVerificationRequest) - dispatchRequestAdded(pendingVerificationRequest) - - /* - * After the m.key.verification.ready event is sent, either party can send an m.key.verification.start event - * to begin the verification. - * If both parties send an m.key.verification.start event, and they both specify the same verification method, - * then the event sent by the user whose user ID is the smallest is used, and the other m.key.verification.start - * event is ignored. - * In the case of a single user verifying two of their devices, the device ID is compared instead. - * If both parties send an m.key.verification.start event, but they specify different verification methods, - * the verification should be cancelled with a code of m.unexpected_message. - */ - } - - override fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event) { - // When Should/Can we cancel?? - val relationContent = event.content.toModel()?.relatesTo - if (relationContent?.type == RelationType.REFERENCE) { - val relatedId = relationContent.eventId ?: return - // at least if request was sent by me, I can safely cancel without interfering - pendingRequests[event.senderId]?.firstOrNull { - it.transactionId == relatedId && !it.isIncoming - }?.let { pr -> - verificationTransportRoomMessageFactory.createTransport(event.roomId ?: "", null) - .cancelTransaction( - relatedId, - event.senderId ?: "", - event.getSenderKey() ?: "", - CancelCode.InvalidMessage - ) - updatePendingRequest(pr.copy(cancelConclusion = CancelCode.InvalidMessage)) - } - } - } - - private suspend fun onRoomStartRequestReceived(event: Event) { - val startReq = event.getClearContent().toModel() - ?.copy( - // relates_to is in clear in encrypted payload - relatesTo = event.content.toModel()?.relatesTo - ) - - val validStartReq = startReq?.asValidObject() - - val otherUserId = event.senderId - if (validStartReq == null) { - Timber.e("## received invalid verification request") - if (startReq?.transactionId != null) { - verificationTransportRoomMessageFactory.createTransport(event.roomId ?: "", null) - .cancelTransaction( - startReq.transactionId ?: "", - otherUserId!!, - startReq.fromDevice ?: event.getSenderKey()!!, - CancelCode.UnknownMethod - ) - } - return - } - - handleStart(otherUserId, validStartReq) { - it.transport = verificationTransportRoomMessageFactory.createTransport(event.roomId ?: "", it) - }?.let { - verificationTransportRoomMessageFactory.createTransport(event.roomId ?: "", null) - .cancelTransaction( - validStartReq.transactionId, - otherUserId!!, - validStartReq.fromDevice, - it - ) - } - } - - private suspend fun onStartRequestReceived(event: Event) { - Timber.e("## SAS received Start request ${event.eventId}") - val startReq = event.getClearContent().toModel() - val validStartReq = startReq?.asValidObject() - Timber.v("## SAS received Start request $startReq") - - val otherUserId = event.senderId!! - if (validStartReq == null) { - Timber.e("## SAS received invalid verification request") - if (startReq?.transactionId != null) { - verificationTransportToDeviceFactory.createTransport(null).cancelTransaction( - startReq.transactionId, - otherUserId, - startReq.fromDevice ?: event.getSenderKey()!!, - CancelCode.UnknownMethod - ) - } - return - } - // Download device keys prior to everything - handleStart(otherUserId, validStartReq) { - it.transport = verificationTransportToDeviceFactory.createTransport(it) - }?.let { - verificationTransportToDeviceFactory.createTransport(null).cancelTransaction( - validStartReq.transactionId, - otherUserId, - validStartReq.fromDevice, - it - ) - } - } - - /** - * Return a CancelCode to make the caller cancel the verification. Else return null - */ - private suspend fun handleStart(otherUserId: String?, - startReq: ValidVerificationInfoStart, - txConfigure: (DefaultVerificationTransaction) -> Unit): CancelCode? { - Timber.d("## SAS onStartRequestReceived $startReq") - if (otherUserId?.let { checkKeysAreDownloaded(it, startReq.fromDevice) } != null) { - val tid = startReq.transactionId - var existing = getExistingTransaction(otherUserId, tid) - - // After the m.key.verification.ready event is sent, either party can send an - // m.key.verification.start event to begin the verification. If both parties - // send an m.key.verification.start event, and they both specify the same - // verification method, then the event sent by the user whose user ID is the - // smallest is used, and the other m.key.verification.start event is ignored. - // In the case of a single user verifying two of their devices, the device ID is - // compared instead . - if (existing is DefaultOutgoingSASDefaultVerificationTransaction) { - val readyRequest = getExistingVerificationRequest(otherUserId, tid) - if (readyRequest?.isReady == true) { - if (isOtherPrioritary(otherUserId, existing.otherDeviceId ?: "")) { - Timber.d("## SAS concurrent start isOtherPrioritary, clear") - // The other is prioritary! - // I should replace my outgoing with an incoming - removeTransaction(otherUserId, tid) - existing = null - } else { - Timber.d("## SAS concurrent start i am prioritary, ignore") - // i am prioritary, ignore this start event! - return null - } - } - } - - when (startReq) { - is ValidVerificationInfoStart.SasVerificationInfoStart -> { - when (existing) { - is SasVerificationTransaction -> { - // should cancel both! - Timber.v("## SAS onStartRequestReceived - Request exist with same id ${startReq.transactionId}") - existing.cancel(CancelCode.UnexpectedMessage) - // Already cancelled, so return null - return null - } - is QrCodeVerificationTransaction -> { - // Nothing to do? - } - null -> { - getExistingTransactionsForUser(otherUserId) - ?.filterIsInstance(SasVerificationTransaction::class.java) - ?.takeIf { it.isNotEmpty() } - ?.also { - // Multiple keyshares between two devices: - // any two devices may only have at most one key verification in flight at a time. - Timber.v("## SAS onStartRequestReceived - Already a transaction with this user ${startReq.transactionId}") - } - ?.forEach { - it.cancel(CancelCode.UnexpectedMessage) - } - ?.also { - return CancelCode.UnexpectedMessage - } - } - } - - // Ok we can create a SAS transaction - Timber.v("## SAS onStartRequestReceived - request accepted ${startReq.transactionId}") - // If there is a corresponding request, we can auto accept - // as we are the one requesting in first place (or we accepted the request) - // I need to check if the pending request was related to this device also - val autoAccept = getExistingVerificationRequests(otherUserId).any { - it.transactionId == startReq.transactionId - && (it.requestInfo?.fromDevice == this.deviceId || it.readyInfo?.fromDevice == this.deviceId) - } - val tx = DefaultIncomingSASDefaultVerificationTransaction( -// this, - setDeviceVerificationAction, - userId, - deviceId, - cryptoStore, - crossSigningService, - outgoingGossipingRequestManager, - incomingGossipingRequestManager, - myDeviceInfoHolder.get().myDevice.fingerprint()!!, - startReq.transactionId, - otherUserId, - autoAccept).also { txConfigure(it) } - addTransaction(tx) - tx.onVerificationStart(startReq) - return null - } - is ValidVerificationInfoStart.ReciprocateVerificationInfoStart -> { - // Other user has scanned my QR code - if (existing is DefaultQrCodeVerificationTransaction) { - existing.onStartReceived(startReq) - return null - } else { - Timber.w("## SAS onStartRequestReceived - unexpected message ${startReq.transactionId} / $existing") - return CancelCode.UnexpectedMessage - } - } - } - } else { - return CancelCode.UnexpectedMessage - } - } - - private fun isOtherPrioritary(otherUserId: String, otherDeviceId: String): Boolean { - if (userId < otherUserId) { - return false - } else if (userId > otherUserId) { - return true - } else { - return otherDeviceId < deviceId ?: "" - } - } - - // TODO Refacto: It could just return a boolean - private suspend fun checkKeysAreDownloaded(otherUserId: String, - otherDeviceId: String): MXUsersDevicesMap? { - return try { - var keys = deviceListManager.downloadKeys(listOf(otherUserId), false) - if (keys.getUserDeviceIds(otherUserId)?.contains(otherDeviceId) == true) { - return keys - } else { - // force download - keys = deviceListManager.downloadKeys(listOf(otherUserId), true) - return keys.takeIf { keys.getUserDeviceIds(otherUserId)?.contains(otherDeviceId) == true } - } - } catch (e: Exception) { - null - } - } - - private fun onRoomCancelReceived(event: Event) { - val cancelReq = event.getClearContent().toModel() - ?.copy( - // relates_to is in clear in encrypted payload - relatesTo = event.content.toModel()?.relatesTo - ) - - val validCancelReq = cancelReq?.asValidObject() - - if (validCancelReq == null) { - // ignore - Timber.e("## SAS Received invalid cancel request") - // TODO should we cancel? - return - } - getExistingVerificationRequest(event.senderId ?: "", validCancelReq.transactionId)?.let { - updatePendingRequest(it.copy(cancelConclusion = safeValueOf(validCancelReq.code))) - // Should we remove it from the list? - } - handleOnCancel(event.senderId!!, validCancelReq) - } - - private fun onCancelReceived(event: Event) { - Timber.v("## SAS onCancelReceived") - val cancelReq = event.getClearContent().toModel()?.asValidObject() - - if (cancelReq == null) { - // ignore - Timber.e("## SAS Received invalid cancel request") - return - } - val otherUserId = event.senderId!! - - handleOnCancel(otherUserId, cancelReq) - } - - private fun handleOnCancel(otherUserId: String, cancelReq: ValidVerificationInfoCancel) { - Timber.v("## SAS onCancelReceived otherUser: $otherUserId reason: ${cancelReq.reason}") - - val existingTransaction = getExistingTransaction(otherUserId, cancelReq.transactionId) - val existingRequest = getExistingVerificationRequest(otherUserId, cancelReq.transactionId) - - if (existingRequest != null) { - // Mark this request as cancelled - updatePendingRequest(existingRequest.copy( - cancelConclusion = safeValueOf(cancelReq.code) - )) - } - - existingTransaction?.state = VerificationTxState.Cancelled(safeValueOf(cancelReq.code), false) - } - - private fun onRoomAcceptReceived(event: Event) { - Timber.d("## SAS Received Accept via DM $event") - val accept = event.getClearContent().toModel() - ?.copy( - // relates_to is in clear in encrypted payload - relatesTo = event.content.toModel()?.relatesTo - ) - ?: return - - val validAccept = accept.asValidObject() ?: return - - handleAccept(validAccept, event.senderId!!) - } - - private fun onAcceptReceived(event: Event) { - Timber.d("## SAS Received Accept $event") - val acceptReq = event.getClearContent().toModel()?.asValidObject() ?: return - handleAccept(acceptReq, event.senderId!!) - } - - private fun handleAccept(acceptReq: ValidVerificationInfoAccept, senderId: String) { - val otherUserId = senderId - val existing = getExistingTransaction(otherUserId, acceptReq.transactionId) - if (existing == null) { - Timber.e("## SAS Received invalid accept request") - return - } - - if (existing is SASDefaultVerificationTransaction) { - existing.onVerificationAccept(acceptReq) - } else { - // not other types now - } - } - - private fun onRoomKeyRequestReceived(event: Event) { - val keyReq = event.getClearContent().toModel() - ?.copy( - // relates_to is in clear in encrypted payload - relatesTo = event.content.toModel()?.relatesTo - ) - ?.asValidObject() - if (keyReq == null) { - // ignore - Timber.e("## SAS Received invalid key request") - // TODO should we cancel? - return - } - handleKeyReceived(event, keyReq) - } - - private fun onKeyReceived(event: Event) { - val keyReq = event.getClearContent().toModel()?.asValidObject() - - if (keyReq == null) { - // ignore - Timber.e("## SAS Received invalid key request") - return - } - handleKeyReceived(event, keyReq) - } - - private fun handleKeyReceived(event: Event, keyReq: ValidVerificationInfoKey) { - Timber.d("## SAS Received Key from ${event.senderId} with info $keyReq") - val otherUserId = event.senderId!! - val existing = getExistingTransaction(otherUserId, keyReq.transactionId) - if (existing == null) { - Timber.e("## SAS Received invalid key request") - return - } - if (existing is SASDefaultVerificationTransaction) { - existing.onKeyVerificationKey(keyReq) - } else { - // not other types now - } - } - - private fun onRoomMacReceived(event: Event) { - val macReq = event.getClearContent().toModel() - ?.copy( - // relates_to is in clear in encrypted payload - relatesTo = event.content.toModel()?.relatesTo - ) - ?.asValidObject() - if (macReq == null || event.senderId == null) { - // ignore - Timber.e("## SAS Received invalid mac request") - // TODO should we cancel? - return - } - handleMacReceived(event.senderId, macReq) - } - - private suspend fun onRoomReadyReceived(event: Event) { - val readyReq = event.getClearContent().toModel() - ?.copy( - // relates_to is in clear in encrypted payload - relatesTo = event.content.toModel()?.relatesTo - ) - ?.asValidObject() - if (readyReq == null || event.senderId == null) { - // ignore - Timber.e("## SAS Received invalid ready request") - // TODO should we cancel? - return - } - if (checkKeysAreDownloaded(event.senderId, readyReq.fromDevice) == null) { - Timber.e("## SAS Verification device ${readyReq.fromDevice} is not known") - // TODO cancel? - return - } - - handleReadyReceived(event.senderId, readyReq) { - verificationTransportRoomMessageFactory.createTransport(event.roomId!!, it) - } - } - - private suspend fun onReadyReceived(event: Event) { - val readyReq = event.getClearContent().toModel()?.asValidObject() - Timber.v("## SAS onReadyReceived $readyReq") - - if (readyReq == null || event.senderId == null) { - // ignore - Timber.e("## SAS Received invalid ready request") - // TODO should we cancel? - return - } - if (checkKeysAreDownloaded(event.senderId, readyReq.fromDevice) == null) { - Timber.e("## SAS Verification device ${readyReq.fromDevice} is not known") - // TODO cancel? - return - } - - handleReadyReceived(event.senderId, readyReq) { - verificationTransportToDeviceFactory.createTransport(it) - } - } - - private fun onDoneReceived(event: Event) { - Timber.v("## onDoneReceived") - val doneReq = event.getClearContent().toModel()?.asValidObject() - if (doneReq == null || event.senderId == null) { - // ignore - Timber.e("## SAS Received invalid done request") - return - } - - handleDoneReceived(event.senderId, doneReq) - - if (event.senderId == userId) { - // We only send gossiping request when the other sent us a done - // We can ask without checking too much thinks (like trust), because we will check validity of secret on reception - getExistingTransaction(userId, doneReq.transactionId) - ?: getOldTransaction(userId, doneReq.transactionId) - ?.let { vt -> - val otherDeviceId = vt.otherDeviceId - if (!crossSigningService.canCrossSign()) { - outgoingGossipingRequestManager.sendSecretShareRequest(MASTER_KEY_SSSS_NAME, mapOf(userId to listOf(otherDeviceId - ?: "*"))) - outgoingGossipingRequestManager.sendSecretShareRequest(SELF_SIGNING_KEY_SSSS_NAME, mapOf(userId to listOf(otherDeviceId - ?: "*"))) - outgoingGossipingRequestManager.sendSecretShareRequest(USER_SIGNING_KEY_SSSS_NAME, mapOf(userId to listOf(otherDeviceId - ?: "*"))) - } - outgoingGossipingRequestManager.sendSecretShareRequest(KEYBACKUP_SECRET_SSSS_NAME, mapOf(userId to listOf(otherDeviceId - ?: "*"))) - } - } - } - - private fun handleDoneReceived(senderId: String, doneReq: ValidVerificationDone) { - Timber.v("## SAS Done received $doneReq") - val existing = getExistingTransaction(senderId, doneReq.transactionId) - if (existing == null) { - Timber.e("## SAS Received invalid Done request") - return - } - if (existing is DefaultQrCodeVerificationTransaction) { - existing.onDoneReceived() - } else { - // SAS do not care for now? - } - - // Now transactions are updated, let's also update Requests - val existingRequest = getExistingVerificationRequests(senderId).find { it.transactionId == doneReq.transactionId } - if (existingRequest == null) { - Timber.e("## SAS Received Done for unknown request txId:${doneReq.transactionId}") - return - } - updatePendingRequest(existingRequest.copy(isSuccessful = true)) - } - - private fun onRoomDoneReceived(event: Event) { - val doneReq = event.getClearContent().toModel() - ?.copy( - // relates_to is in clear in encrypted payload - relatesTo = event.content.toModel()?.relatesTo - ) - ?.asValidObject() - - if (doneReq == null || event.senderId == null) { - // ignore - Timber.e("## SAS Received invalid Done request") - // TODO should we cancel? - return - } - - handleDoneReceived(event.senderId, doneReq) - } - - private fun onMacReceived(event: Event) { - val macReq = event.getClearContent().toModel()?.asValidObject() - - if (macReq == null || event.senderId == null) { - // ignore - Timber.e("## SAS Received invalid mac request") - return - } - handleMacReceived(event.senderId, macReq) - } - - private fun handleMacReceived(senderId: String, macReq: ValidVerificationInfoMac) { - Timber.v("## SAS Received $macReq") - val existing = getExistingTransaction(senderId, macReq.transactionId) - if (existing == null) { - Timber.e("## SAS Received invalid Mac request") - return - } - if (existing is SASDefaultVerificationTransaction) { - existing.onKeyVerificationMac(macReq) - } else { - // not other types known for now - } - } - - private fun handleReadyReceived(senderId: String, - readyReq: ValidVerificationInfoReady, - transportCreator: (DefaultVerificationTransaction) -> VerificationTransport) { - val existingRequest = getExistingVerificationRequests(senderId).find { it.transactionId == readyReq.transactionId } - if (existingRequest == null) { - Timber.e("## SAS Received Ready for unknown request txId:${readyReq.transactionId} fromDevice ${readyReq.fromDevice}") - return - } - - val qrCodeData = readyReq.methods - // Check if other user is able to scan QR code - .takeIf { it.contains(VERIFICATION_METHOD_QR_CODE_SCAN) } - ?.let { - createQrCodeData(existingRequest.transactionId, existingRequest.otherUserId, readyReq.fromDevice) - } - - if (readyReq.methods.contains(VERIFICATION_METHOD_RECIPROCATE)) { - // Create the pending transaction - val tx = DefaultQrCodeVerificationTransaction( - setDeviceVerificationAction = setDeviceVerificationAction, - transactionId = readyReq.transactionId, - otherUserId = senderId, - otherDeviceId = readyReq.fromDevice, - crossSigningService = crossSigningService, - outgoingGossipingRequestManager = outgoingGossipingRequestManager, - incomingGossipingRequestManager = incomingGossipingRequestManager, - cryptoStore = cryptoStore, - qrCodeData = qrCodeData, - userId = userId, - deviceId = deviceId ?: "", - isIncoming = false) - - tx.transport = transportCreator.invoke(tx) - - addTransaction(tx) - } - - updatePendingRequest(existingRequest.copy( - readyInfo = readyReq - )) - } - - private fun createQrCodeData(requestId: String?, otherUserId: String, otherDeviceId: String?): QrCodeData? { - requestId ?: run { - Timber.w("## Unknown requestId") - return null - } - - return when { - userId != otherUserId -> - createQrCodeDataForDistinctUser(requestId, otherUserId) - crossSigningService.isCrossSigningVerified() -> - // This is a self verification and I am the old device (Osborne2) - createQrCodeDataForVerifiedDevice(requestId, otherDeviceId) - else -> - // This is a self verification and I am the new device (Dynabook) - createQrCodeDataForUnVerifiedDevice(requestId) - } - } - - private fun createQrCodeDataForDistinctUser(requestId: String, otherUserId: String): QrCodeData.VerifyingAnotherUser? { - val myMasterKey = crossSigningService.getMyCrossSigningKeys() - ?.masterKey() - ?.unpaddedBase64PublicKey - ?: run { - Timber.w("## Unable to get my master key") - return null - } - - val otherUserMasterKey = crossSigningService.getUserCrossSigningKeys(otherUserId) - ?.masterKey() - ?.unpaddedBase64PublicKey - ?: run { - Timber.w("## Unable to get other user master key") - return null - } - - return QrCodeData.VerifyingAnotherUser( - transactionId = requestId, - userMasterCrossSigningPublicKey = myMasterKey, - otherUserMasterCrossSigningPublicKey = otherUserMasterKey, - sharedSecret = generateSharedSecretV2() - ) - } - - // Create a QR code to display on the old device (Osborne2) - private fun createQrCodeDataForVerifiedDevice(requestId: String, otherDeviceId: String?): QrCodeData.SelfVerifyingMasterKeyTrusted? { - val myMasterKey = crossSigningService.getMyCrossSigningKeys() - ?.masterKey() - ?.unpaddedBase64PublicKey - ?: run { - Timber.w("## Unable to get my master key") - return null - } - - val otherDeviceKey = otherDeviceId - ?.let { - cryptoStore.getUserDevice(userId, otherDeviceId)?.fingerprint() - } - ?: run { - Timber.w("## Unable to get other device data") - return null - } - - return QrCodeData.SelfVerifyingMasterKeyTrusted( - transactionId = requestId, - userMasterCrossSigningPublicKey = myMasterKey, - otherDeviceKey = otherDeviceKey, - sharedSecret = generateSharedSecretV2() - ) - } - - // Create a QR code to display on the new device (Dynabook) - private fun createQrCodeDataForUnVerifiedDevice(requestId: String): QrCodeData.SelfVerifyingMasterKeyNotTrusted? { - val myMasterKey = crossSigningService.getMyCrossSigningKeys() - ?.masterKey() - ?.unpaddedBase64PublicKey - ?: run { - Timber.w("## Unable to get my master key") - return null - } - - val myDeviceKey = myDeviceInfoHolder.get().myDevice.fingerprint() - ?: run { - Timber.w("## Unable to get my fingerprint") - return null - } - - return QrCodeData.SelfVerifyingMasterKeyNotTrusted( - transactionId = requestId, - deviceKey = myDeviceKey, - userMasterCrossSigningPublicKey = myMasterKey, - sharedSecret = generateSharedSecretV2() - ) - } - -// private fun handleDoneReceived(senderId: String, doneInfo: ValidVerificationDone) { -// val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == doneInfo.transactionId } -// if (existingRequest == null) { -// Timber.e("## SAS Received Done for unknown request txId:${doneInfo.transactionId}") -// return -// } -// updatePendingRequest(existingRequest.copy(isSuccessful = true)) -// } - - // TODO All this methods should be delegated to a TransactionStore - override fun getExistingTransaction(otherUserId: String, tid: String): VerificationTransaction? { - synchronized(lock = txMap) { - return txMap[otherUserId]?.get(tid) - } - } - - override fun getExistingVerificationRequests(otherUserId: String): List { - synchronized(lock = pendingRequests) { - return pendingRequests[otherUserId].orEmpty() - } - } - - override fun getExistingVerificationRequest(otherUserId: String, tid: String?): PendingVerificationRequest? { - synchronized(lock = pendingRequests) { - return tid?.let { tid -> pendingRequests[otherUserId]?.firstOrNull { it.transactionId == tid } } - } - } - - override fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest? { - synchronized(lock = pendingRequests) { - return tid?.let { tid -> - pendingRequests.flatMap { entry -> - entry.value.filter { it.roomId == roomId && it.transactionId == tid } - }.firstOrNull() - } - } - } - - private fun getExistingTransactionsForUser(otherUser: String): Collection? { - synchronized(txMap) { - return txMap[otherUser]?.values - } - } - - private fun removeTransaction(otherUser: String, tid: String) { - synchronized(txMap) { - txMap[otherUser]?.remove(tid)?.also { - it.removeListener(this) - } - }?.let { - rememberOldTransaction(it) - } - } - - private fun addTransaction(tx: DefaultVerificationTransaction) { - synchronized(txMap) { - val txInnerMap = txMap.getOrPut(tx.otherUserId) { HashMap() } - txInnerMap[tx.transactionId] = tx - dispatchTxAdded(tx) - tx.addListener(this) - } - } - - private fun rememberOldTransaction(tx: DefaultVerificationTransaction) { - synchronized(pastTransactions) { - pastTransactions.getOrPut(tx.otherUserId) { HashMap() }[tx.transactionId] = tx - } - } - - private fun getOldTransaction(userId: String, tid: String?): DefaultVerificationTransaction? { - return tid?.let { - synchronized(pastTransactions) { - pastTransactions[userId]?.get(it) - } - } - } - - override fun beginKeyVerification(method: VerificationMethod, otherUserId: String, otherDeviceId: String, transactionId: String?): String? { - val txID = transactionId?.takeIf { it.isNotEmpty() } ?: createUniqueIDForTransaction(otherUserId, otherDeviceId) - // should check if already one (and cancel it) - if (method == VerificationMethod.SAS) { - val tx = DefaultOutgoingSASDefaultVerificationTransaction( - setDeviceVerificationAction, - userId, - deviceId, - cryptoStore, - crossSigningService, - outgoingGossipingRequestManager, - incomingGossipingRequestManager, - myDeviceInfoHolder.get().myDevice.fingerprint()!!, - txID, - otherUserId, - otherDeviceId) - tx.transport = verificationTransportToDeviceFactory.createTransport(tx) - addTransaction(tx) - - tx.start() - return txID - } else { - throw IllegalArgumentException("Unknown verification method") - } - } - - override fun requestKeyVerificationInDMs(methods: List, otherUserId: String, roomId: String, localId: String?) - : PendingVerificationRequest { - Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") - - val requestsForUser = pendingRequests.getOrPut(otherUserId) { mutableListOf() } - - val transport = verificationTransportRoomMessageFactory.createTransport(roomId, null) - - // Cancel existing pending requests? - requestsForUser.toList().forEach { existingRequest -> - existingRequest.transactionId?.let { tid -> - if (!existingRequest.isFinished) { - Timber.d("## SAS, cancelling pending requests to start a new one") - updatePendingRequest(existingRequest.copy(cancelConclusion = CancelCode.User)) - transport.cancelTransaction(tid, existingRequest.otherUserId, "", CancelCode.User) - } - } - } - - val validLocalId = localId ?: LocalEcho.createLocalEchoId() - - val verificationRequest = PendingVerificationRequest( - ageLocalTs = System.currentTimeMillis(), - isIncoming = false, - roomId = roomId, - localId = validLocalId, - otherUserId = otherUserId - ) - - // We can SCAN or SHOW QR codes only if cross-signing is verified - val methodValues = if (crossSigningService.isCrossSigningVerified()) { - // Add reciprocate method if application declares it can scan or show QR codes - // Not sure if it ok to do that (?) - val reciprocateMethod = methods - .firstOrNull { it == VerificationMethod.QR_CODE_SCAN || it == VerificationMethod.QR_CODE_SHOW } - ?.let { listOf(VERIFICATION_METHOD_RECIPROCATE) }.orEmpty() - methods.map { it.toValue() } + reciprocateMethod - } else { - // Filter out SCAN and SHOW qr code method - methods - .filter { it != VerificationMethod.QR_CODE_SHOW && it != VerificationMethod.QR_CODE_SCAN } - .map { it.toValue() } - } - .distinct() - - transport.sendVerificationRequest(methodValues, validLocalId, otherUserId, roomId, null) { syncedId, info -> - // We need to update with the syncedID - updatePendingRequest(verificationRequest.copy( - transactionId = syncedId, - // localId stays different - requestInfo = info - )) - } - - requestsForUser.add(verificationRequest) - dispatchRequestAdded(verificationRequest) - - return verificationRequest - } - - override fun cancelVerificationRequest(request: PendingVerificationRequest) { - if (request.roomId != null) { - val transport = verificationTransportRoomMessageFactory.createTransport(request.roomId, null) - transport.cancelTransaction(request.transactionId ?: "", request.otherUserId, null, CancelCode.User) - } else { - val transport = verificationTransportToDeviceFactory.createTransport(null) - request.targetDevices?.forEach { deviceId -> - transport.cancelTransaction(request.transactionId ?: "", request.otherUserId, deviceId, CancelCode.User) - } - } - } - - override fun requestKeyVerification(methods: List, otherUserId: String, otherDevices: List?): PendingVerificationRequest { - // TODO refactor this with the DM one - Timber.i("## Requesting verification to user: $otherUserId with device list $otherDevices") - - val targetDevices = otherDevices ?: cryptoStore.getUserDevices(otherUserId) - ?.values?.map { it.deviceId }.orEmpty() - - val requestsForUser = pendingRequests.getOrPut(otherUserId) { mutableListOf() } - - val transport = verificationTransportToDeviceFactory.createTransport(null) - - // Cancel existing pending requests? - requestsForUser.toList().forEach { existingRequest -> - existingRequest.transactionId?.let { tid -> - if (!existingRequest.isFinished) { - Timber.d("## SAS, cancelling pending requests to start a new one") - updatePendingRequest(existingRequest.copy(cancelConclusion = CancelCode.User)) - existingRequest.targetDevices?.forEach { - transport.cancelTransaction(tid, existingRequest.otherUserId, it, CancelCode.User) - } - } - } - } - - val localId = LocalEcho.createLocalEchoId() - - val verificationRequest = PendingVerificationRequest( - transactionId = localId, - ageLocalTs = System.currentTimeMillis(), - isIncoming = false, - roomId = null, - localId = localId, - otherUserId = otherUserId, - targetDevices = targetDevices - ) - - // We can SCAN or SHOW QR codes only if cross-signing is enabled - val methodValues = if (crossSigningService.isCrossSigningInitialized()) { - // Add reciprocate method if application declares it can scan or show QR codes - // Not sure if it ok to do that (?) - val reciprocateMethod = methods - .firstOrNull { it == VerificationMethod.QR_CODE_SCAN || it == VerificationMethod.QR_CODE_SHOW } - ?.let { listOf(VERIFICATION_METHOD_RECIPROCATE) }.orEmpty() - methods.map { it.toValue() } + reciprocateMethod - } else { - // Filter out SCAN and SHOW qr code method - methods - .filter { it != VerificationMethod.QR_CODE_SHOW && it != VerificationMethod.QR_CODE_SCAN } - .map { it.toValue() } - } - .distinct() - - transport.sendVerificationRequest(methodValues, localId, otherUserId, null, targetDevices) { _, info -> - // Nothing special to do in to device mode - updatePendingRequest(verificationRequest.copy( - // localId stays different - requestInfo = info - )) - } - - requestsForUser.add(verificationRequest) - dispatchRequestAdded(verificationRequest) - - return verificationRequest - } - - override fun declineVerificationRequestInDMs(otherUserId: String, transactionId: String, roomId: String) { - verificationTransportRoomMessageFactory.createTransport(roomId, null) - .cancelTransaction(transactionId, otherUserId, null, CancelCode.User) - - getExistingVerificationRequest(otherUserId, transactionId)?.let { - updatePendingRequest(it.copy( - cancelConclusion = CancelCode.User - )) - } - } - - private fun updatePendingRequest(updated: PendingVerificationRequest) { - val requestsForUser = pendingRequests.getOrPut(updated.otherUserId) { mutableListOf() } - val index = requestsForUser.indexOfFirst { - it.transactionId == updated.transactionId - || it.transactionId == null && it.localId == updated.localId - } - if (index != -1) { - requestsForUser.removeAt(index) - } - requestsForUser.add(updated) - dispatchRequestUpdated(updated) - } - - override fun beginKeyVerificationInDMs(method: VerificationMethod, - transactionId: String, - roomId: String, - otherUserId: String, - otherDeviceId: String): String { - if (method == VerificationMethod.SAS) { - val tx = DefaultOutgoingSASDefaultVerificationTransaction( - setDeviceVerificationAction, - userId, - deviceId, - cryptoStore, - crossSigningService, - outgoingGossipingRequestManager, - incomingGossipingRequestManager, - myDeviceInfoHolder.get().myDevice.fingerprint()!!, - transactionId, - otherUserId, - otherDeviceId) - tx.transport = verificationTransportRoomMessageFactory.createTransport(roomId, tx) - addTransaction(tx) - - tx.start() - return transactionId - } else { - throw IllegalArgumentException("Unknown verification method") - } - } - - override fun readyPendingVerificationInDMs(methods: List, - otherUserId: String, - roomId: String, - transactionId: String): Boolean { - Timber.v("## SAS readyPendingVerificationInDMs $otherUserId room:$roomId tx:$transactionId") - // Let's find the related request - val existingRequest = getExistingVerificationRequest(otherUserId, transactionId) - if (existingRequest != null) { - // we need to send a ready event, with matching methods - val transport = verificationTransportRoomMessageFactory.createTransport(roomId, null) - val computedMethods = computeReadyMethods( - transactionId, - otherUserId, - existingRequest.requestInfo?.fromDevice ?: "", - existingRequest.requestInfo?.methods, - methods) { - verificationTransportRoomMessageFactory.createTransport(roomId, it) - } - if (methods.isNullOrEmpty()) { - Timber.i("Cannot ready this request, no common methods found txId:$transactionId") - // TODO buttons should not be shown in this case? - return false - } - // TODO this is not yet related to a transaction, maybe we should use another method like for cancel? - val readyMsg = transport.createReady(transactionId, deviceId ?: "", computedMethods) - transport.sendToOther(EventType.KEY_VERIFICATION_READY, - readyMsg, - VerificationTxState.None, - CancelCode.User, - null // TODO handle error? - ) - updatePendingRequest(existingRequest.copy(readyInfo = readyMsg.asValidObject())) - return true - } else { - Timber.e("## SAS readyPendingVerificationInDMs Verification not found") - // :/ should not be possible... unless live observer very slow - return false - } - } - - override fun readyPendingVerification(methods: List, - otherUserId: String, - transactionId: String): Boolean { - Timber.v("## SAS readyPendingVerification $otherUserId tx:$transactionId") - // Let's find the related request - val existingRequest = getExistingVerificationRequest(otherUserId, transactionId) - if (existingRequest != null) { - // we need to send a ready event, with matching methods - val transport = verificationTransportToDeviceFactory.createTransport(null) - val computedMethods = computeReadyMethods( - transactionId, - otherUserId, - existingRequest.requestInfo?.fromDevice ?: "", - existingRequest.requestInfo?.methods, - methods) { - verificationTransportToDeviceFactory.createTransport(it) - } - if (methods.isNullOrEmpty()) { - Timber.i("Cannot ready this request, no common methods found txId:$transactionId") - // TODO buttons should not be shown in this case? - return false - } - // TODO this is not yet related to a transaction, maybe we should use another method like for cancel? - val readyMsg = transport.createReady(transactionId, deviceId ?: "", computedMethods) - transport.sendVerificationReady( - readyMsg, - otherUserId, - existingRequest.requestInfo?.fromDevice ?: "", - null // TODO handle error? - ) - updatePendingRequest(existingRequest.copy(readyInfo = readyMsg.asValidObject())) - return true - } else { - Timber.e("## SAS readyPendingVerification Verification not found") - // :/ should not be possible... unless live observer very slow - return false - } - } - - private fun computeReadyMethods( - transactionId: String, - otherUserId: String, - otherDeviceId: String, - otherUserMethods: List?, - methods: List, - transportCreator: (DefaultVerificationTransaction) -> VerificationTransport): List { - if (otherUserMethods.isNullOrEmpty()) { - return emptyList() - } - - val result = mutableSetOf() - - if (VERIFICATION_METHOD_SAS in otherUserMethods && VerificationMethod.SAS in methods) { - // Other can do SAS and so do I - result.add(VERIFICATION_METHOD_SAS) - } - - if (VERIFICATION_METHOD_QR_CODE_SCAN in otherUserMethods || VERIFICATION_METHOD_QR_CODE_SHOW in otherUserMethods) { - // Other user wants to verify using QR code. Cross-signing has to be setup - val qrCodeData = createQrCodeData(transactionId, otherUserId, otherDeviceId) - - if (qrCodeData != null) { - if (VERIFICATION_METHOD_QR_CODE_SCAN in otherUserMethods && VerificationMethod.QR_CODE_SHOW in methods) { - // Other can Scan and I can show QR code - result.add(VERIFICATION_METHOD_QR_CODE_SHOW) - result.add(VERIFICATION_METHOD_RECIPROCATE) - } - if (VERIFICATION_METHOD_QR_CODE_SHOW in otherUserMethods && VerificationMethod.QR_CODE_SCAN in methods) { - // Other can show and I can scan QR code - result.add(VERIFICATION_METHOD_QR_CODE_SCAN) - result.add(VERIFICATION_METHOD_RECIPROCATE) - } - } - - if (VERIFICATION_METHOD_RECIPROCATE in result) { - // Create the pending transaction - val tx = DefaultQrCodeVerificationTransaction( - setDeviceVerificationAction = setDeviceVerificationAction, - transactionId = transactionId, - otherUserId = otherUserId, - otherDeviceId = otherDeviceId, - crossSigningService = crossSigningService, - outgoingGossipingRequestManager = outgoingGossipingRequestManager, - incomingGossipingRequestManager = incomingGossipingRequestManager, - cryptoStore = cryptoStore, - qrCodeData = qrCodeData, - userId = userId, - deviceId = deviceId ?: "", - isIncoming = false) - - tx.transport = transportCreator.invoke(tx) - - addTransaction(tx) - } - } - - return result.toList() - } - - /** - * This string must be unique for the pair of users performing verification for the duration that the transaction is valid - */ - private fun createUniqueIDForTransaction(otherUserId: String, otherDeviceID: String): String { - return buildString { - append(userId).append("|") - append(deviceId).append("|") - append(otherUserId).append("|") - append(otherDeviceID).append("|") - append(UUID.randomUUID().toString()) - } - } - - override fun transactionUpdated(tx: VerificationTransaction) { - dispatchTxUpdated(tx) - if (tx.state is VerificationTxState.TerminalTxState) { - // remove - this.removeTransaction(tx.otherUserId, tx.transactionId) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt deleted file mode 100644 index 6043c21b66..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import timber.log.Timber - -/** - * Generic interactive key verification transaction - */ -internal abstract class DefaultVerificationTransaction( - private val setDeviceVerificationAction: SetDeviceVerificationAction, - private val crossSigningService: CrossSigningService, - private val outgoingGossipingRequestManager: OutgoingGossipingRequestManager, - private val incomingGossipingRequestManager: IncomingGossipingRequestManager, - private val userId: String, - override val transactionId: String, - override val otherUserId: String, - override var otherDeviceId: String? = null, - override val isIncoming: Boolean) : VerificationTransaction { - - lateinit var transport: VerificationTransport - - interface Listener { - fun transactionUpdated(tx: VerificationTransaction) - } - - protected var listeners = ArrayList() - - fun addListener(listener: Listener) { - if (!listeners.contains(listener)) listeners.add(listener) - } - - fun removeListener(listener: Listener) { - listeners.remove(listener) - } - - protected fun trust(canTrustOtherUserMasterKey: Boolean, - toVerifyDeviceIds: List, - eventuallyMarkMyMasterKeyAsTrusted: Boolean, autoDone: Boolean = true) { - Timber.d("## Verification: trust ($otherUserId,$otherDeviceId) , verifiedDevices:$toVerifyDeviceIds") - Timber.d("## Verification: trust Mark myMSK trusted $eventuallyMarkMyMasterKeyAsTrusted") - - // TODO what if the otherDevice is not in this list? and should we - toVerifyDeviceIds.forEach { - setDeviceVerified(otherUserId, it) - } - - // If not me sign his MSK and upload the signature - if (canTrustOtherUserMasterKey) { - // we should trust this master key - // And check verification MSK -> SSK? - if (otherUserId != userId) { - crossSigningService.trustUser(otherUserId, object : MatrixCallback { - override fun onFailure(failure: Throwable) { - Timber.e(failure, "## Verification: Failed to trust User $otherUserId") - } - }) - } else { - // Notice other master key is mine because other is me - if (eventuallyMarkMyMasterKeyAsTrusted) { - // Mark my keys as trusted locally - crossSigningService.markMyMasterKeyAsTrusted() - } - } - } - - if (otherUserId == userId) { - incomingGossipingRequestManager.onVerificationCompleteForDevice(otherDeviceId!!) - - // If me it's reasonable to sign and upload the device signature - // Notice that i might not have the private keys, so may not be able to do it - crossSigningService.trustDevice(otherDeviceId!!, object : MatrixCallback { - override fun onFailure(failure: Throwable) { - Timber.w("## Verification: Failed to sign new device $otherDeviceId, ${failure.localizedMessage}") - } - }) - } - - if (autoDone) { - state = VerificationTxState.Verified - transport.done(transactionId) {} - } - } - - private fun setDeviceVerified(userId: String, deviceId: String) { - // TODO should not override cross sign status - setDeviceVerificationAction.handle(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), - userId, - deviceId) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index b3fb53dfb2..b77007aa28 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -66,7 +66,7 @@ private fun getFlowId(event: Event): String? { internal class RustVerificationService( private val olmMachine: OlmMachine, private val requestSender: RequestSender, -) : DefaultVerificationTransaction.Listener, VerificationService { +) : VerificationService { private val uiHandler = Handler(Looper.getMainLooper()) private var listeners = ArrayList() @@ -428,9 +428,4 @@ internal class RustVerificationService( val verificationRequest = this.getVerificationRequest(otherUserId, transactionId) runBlocking { verificationRequest?.cancel() } } - - override fun transactionUpdated(tx: VerificationTransaction) { - // TODO this isn't really used anymore - dispatchTxUpdated(tx) - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt deleted file mode 100644 index 4bf01a2809..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation -import org.matrix.android.sdk.api.session.crypto.verification.SasMode -import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.extensions.toUnsignedInt -import org.matrix.olm.OlmSAS -import org.matrix.olm.OlmUtility -import timber.log.Timber -import java.util.Locale - -/** - * Represents an ongoing short code interactive key verification between two devices. - */ -internal abstract class SASDefaultVerificationTransaction( - setDeviceVerificationAction: SetDeviceVerificationAction, - open val userId: String, - open val deviceId: String?, - private val cryptoStore: IMXCryptoStore, - crossSigningService: CrossSigningService, - outgoingGossipingRequestManager: OutgoingGossipingRequestManager, - incomingGossipingRequestManager: IncomingGossipingRequestManager, - private val deviceFingerprint: String, - transactionId: String, - otherUserId: String, - otherDeviceId: String?, - isIncoming: Boolean -) : DefaultVerificationTransaction( - setDeviceVerificationAction, - crossSigningService, - outgoingGossipingRequestManager, - incomingGossipingRequestManager, - userId, - transactionId, - otherUserId, - otherDeviceId, - isIncoming), - SasVerificationTransaction { - - companion object { - const val SAS_MAC_SHA256_LONGKDF = "hmac-sha256" - const val SAS_MAC_SHA256 = "hkdf-hmac-sha256" - - // Deprecated maybe removed later, use V2 - const val KEY_AGREEMENT_V1 = "curve25519" - const val KEY_AGREEMENT_V2 = "curve25519-hkdf-sha256" - - // ordered by preferred order - val KNOWN_AGREEMENT_PROTOCOLS = listOf(KEY_AGREEMENT_V2, KEY_AGREEMENT_V1) - - // ordered by preferred order - val KNOWN_HASHES = listOf("sha256") - - // ordered by preferred order - val KNOWN_MACS = listOf(SAS_MAC_SHA256, SAS_MAC_SHA256_LONGKDF) - - // older devices have limited support of emoji but SDK offers images for the 64 verification emojis - // so always send that we support EMOJI - val KNOWN_SHORT_CODES = listOf(SasMode.EMOJI, SasMode.DECIMAL) - } - - override var state: VerificationTxState = VerificationTxState.None - set(newState) { - field = newState - - listeners.forEach { - try { - it.transactionUpdated(this) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - - if (newState is VerificationTxState.TerminalTxState) { - releaseSAS() - } - } - - private var olmSas: OlmSAS? = null - - // Visible for test - var startReq: ValidVerificationInfoStart.SasVerificationInfoStart? = null - - // Visible for test - var accepted: ValidVerificationInfoAccept? = null - protected var otherKey: String? = null - protected var shortCodeBytes: ByteArray? = null - - protected var myMac: ValidVerificationInfoMac? = null - protected var theirMac: ValidVerificationInfoMac? = null - - protected fun getSAS(): OlmSAS { - if (olmSas == null) olmSas = OlmSAS() - return olmSas!! - } - - // To override finalize(), all you need to do is simply declare it, without using the override keyword: - protected fun finalize() { - releaseSAS() - } - - private fun releaseSAS() { - // finalization logic - olmSas?.releaseSas() - olmSas = null - } - - /** - * To be called by the client when the user has verified that - * both short codes do match - */ - override fun userHasVerifiedShortCode() { - Timber.v("## SAS short code verified by user for id:$transactionId") - if (state != VerificationTxState.ShortCodeReady) { - // ignore and cancel? - Timber.e("## Accepted short code from invalid state $state") - cancel(CancelCode.UnexpectedMessage) - return - } - - state = VerificationTxState.ShortCodeAccepted - // Alice and Bob’ devices calculate the HMAC of their own device keys and a comma-separated, - // sorted list of the key IDs that they wish the other user to verify, - // the shared secret as the input keying material, no salt, and with the input parameter set to the concatenation of: - // - the string “MATRIX_KEY_VERIFICATION_MAC”, - // - the Matrix ID of the user whose key is being MAC-ed, - // - the device ID of the device sending the MAC, - // - the Matrix ID of the other user, - // - the device ID of the device receiving the MAC, - // - the transaction ID, and - // - the key ID of the key being MAC-ed, or the string “KEY_IDS” if the item being MAC-ed is the list of key IDs. - val baseInfo = "MATRIX_KEY_VERIFICATION_MAC$userId$deviceId$otherUserId$otherDeviceId$transactionId" - - // Previously, with SAS verification, the m.key.verification.mac message only contained the user's device key. - // It should now contain both the device key and the MSK. - // So when Alice and Bob verify with SAS, the verification will verify the MSK. - - val keyMap = HashMap() - - val keyId = "ed25519:$deviceId" - val macString = macUsingAgreedMethod(deviceFingerprint, baseInfo + keyId) - - if (macString.isNullOrBlank()) { - // Should not happen - Timber.e("## SAS verification [$transactionId] failed to send KeyMac, empty key hashes.") - cancel(CancelCode.UnexpectedMessage) - return - } - - keyMap[keyId] = macString - - cryptoStore.getMyCrossSigningInfo()?.takeIf { it.isTrusted() } - ?.masterKey() - ?.unpaddedBase64PublicKey - ?.let { masterPublicKey -> - val crossSigningKeyId = "ed25519:$masterPublicKey" - macUsingAgreedMethod(masterPublicKey, baseInfo + crossSigningKeyId)?.let { mskMacString -> - keyMap[crossSigningKeyId] = mskMacString - } - } - - val keyStrings = macUsingAgreedMethod(keyMap.keys.sorted().joinToString(","), baseInfo + "KEY_IDS") - - if (macString.isNullOrBlank() || keyStrings.isNullOrBlank()) { - // Should not happen - Timber.e("## SAS verification [$transactionId] failed to send KeyMac, empty key hashes.") - cancel(CancelCode.UnexpectedMessage) - return - } - - val macMsg = transport.createMac(transactionId, keyMap, keyStrings) - myMac = macMsg.asValidObject() - state = VerificationTxState.SendingMac - sendToOther(EventType.KEY_VERIFICATION_MAC, macMsg, VerificationTxState.MacSent, CancelCode.User) { - if (state == VerificationTxState.SendingMac) { - // It is possible that we receive the next event before this one :/, in this case we should keep state - state = VerificationTxState.MacSent - } - } - - // Do I already have their Mac? - theirMac?.let { verifyMacs(it) } - // if not wait for it - } - - override fun shortCodeDoesNotMatch() { - Timber.v("## SAS short code do not match for id:$transactionId") - cancel(CancelCode.MismatchedSas) - } - - override fun isToDeviceTransport(): Boolean { - return transport is VerificationTransportToDevice - } - - abstract fun onVerificationStart(startReq: ValidVerificationInfoStart.SasVerificationInfoStart) - - abstract fun onVerificationAccept(accept: ValidVerificationInfoAccept) - - abstract fun onKeyVerificationKey(vKey: ValidVerificationInfoKey) - - abstract fun onKeyVerificationMac(vMac: ValidVerificationInfoMac) - - protected fun verifyMacs(theirMacSafe: ValidVerificationInfoMac) { - Timber.v("## SAS verifying macs for id:$transactionId") - state = VerificationTxState.Verifying - - // Keys have been downloaded earlier in process - val otherUserKnownDevices = cryptoStore.getUserDevices(otherUserId) - - // Bob’s device calculates the HMAC (as above) of its copies of Alice’s keys given in the message (as identified by their key ID), - // as well as the HMAC of the comma-separated, sorted list of the key IDs given in the message. - // Bob’s device compares these with the HMAC values given in the m.key.verification.mac message. - // If everything matches, then consider Alice’s device keys as verified. - val baseInfo = "MATRIX_KEY_VERIFICATION_MAC$otherUserId$otherDeviceId$userId$deviceId$transactionId" - - val commaSeparatedListOfKeyIds = theirMacSafe.mac.keys.sorted().joinToString(",") - - val keyStrings = macUsingAgreedMethod(commaSeparatedListOfKeyIds, baseInfo + "KEY_IDS") - if (theirMacSafe.keys != keyStrings) { - // WRONG! - cancel(CancelCode.MismatchedKeys) - return - } - - val verifiedDevices = ArrayList() - - // cannot be empty because it has been validated - theirMacSafe.mac.keys.forEach { - val keyIDNoPrefix = it.removePrefix("ed25519:") - val otherDeviceKey = otherUserKnownDevices?.get(keyIDNoPrefix)?.fingerprint() - if (otherDeviceKey == null) { - Timber.w("## SAS Verification: Could not find device $keyIDNoPrefix to verify") - // just ignore and continue - return@forEach - } - val mac = macUsingAgreedMethod(otherDeviceKey, baseInfo + it) - if (mac != theirMacSafe.mac[it]) { - // WRONG! - Timber.e("## SAS Verification: mac mismatch for $otherDeviceKey with id $keyIDNoPrefix") - cancel(CancelCode.MismatchedKeys) - return - } - verifiedDevices.add(keyIDNoPrefix) - } - - var otherMasterKeyIsVerified = false - val otherMasterKey = cryptoStore.getCrossSigningInfo(otherUserId)?.masterKey() - val otherCrossSigningMasterKeyPublic = otherMasterKey?.unpaddedBase64PublicKey - if (otherCrossSigningMasterKeyPublic != null) { - // Did the user signed his master key - theirMacSafe.mac.keys.forEach { - val keyIDNoPrefix = it.removePrefix("ed25519:") - if (keyIDNoPrefix == otherCrossSigningMasterKeyPublic) { - // Check the signature - val mac = macUsingAgreedMethod(otherCrossSigningMasterKeyPublic, baseInfo + it) - if (mac != theirMacSafe.mac[it]) { - // WRONG! - Timber.e("## SAS Verification: mac mismatch for MasterKey with id $keyIDNoPrefix") - cancel(CancelCode.MismatchedKeys) - return - } else { - otherMasterKeyIsVerified = true - } - } - } - } - - // if none of the keys could be verified, then error because the app - // should be informed about that - if (verifiedDevices.isEmpty() && !otherMasterKeyIsVerified) { - Timber.e("## SAS Verification: No devices verified") - cancel(CancelCode.MismatchedKeys) - return - } - - trust(otherMasterKeyIsVerified, - verifiedDevices, - eventuallyMarkMyMasterKeyAsTrusted = otherMasterKey?.trustLevel?.isVerified() == false) - } - - override fun cancel() { - cancel(CancelCode.User) - } - - override fun cancel(code: CancelCode) { - state = VerificationTxState.Cancelled(code, true) - transport.cancelTransaction(transactionId, otherUserId, otherDeviceId ?: "", code) - } - - protected fun sendToOther(type: String, - keyToDevice: VerificationInfo, - nextState: VerificationTxState, - onErrorReason: CancelCode, - onDone: (() -> Unit)?) { - transport.sendToOther(type, keyToDevice, nextState, onErrorReason, onDone) - } - - fun getShortCodeRepresentation(shortAuthenticationStringMode: String): String? { - if (shortCodeBytes == null) { - return null - } - when (shortAuthenticationStringMode) { - SasMode.DECIMAL -> { - if (shortCodeBytes!!.size < 5) return null - return getDecimalCodeRepresentation(shortCodeBytes!!) - } - SasMode.EMOJI -> { - if (shortCodeBytes!!.size < 6) return null - return getEmojiCodeRepresentation(shortCodeBytes!!).joinToString(" ") { it.emoji } - } - else -> return null - } - } - - override fun supportsEmoji(): Boolean { - return accepted?.shortAuthenticationStrings?.contains(SasMode.EMOJI).orFalse() - } - - override fun supportsDecimal(): Boolean { - return accepted?.shortAuthenticationStrings?.contains(SasMode.DECIMAL).orFalse() - } - - protected fun hashUsingAgreedHashMethod(toHash: String): String? { - if ("sha256" == accepted?.hash?.lowercase(Locale.ROOT)) { - val olmUtil = OlmUtility() - val hashBytes = olmUtil.sha256(toHash) - olmUtil.releaseUtility() - return hashBytes - } - return null - } - - private fun macUsingAgreedMethod(message: String, info: String): String? { - return when (accepted?.messageAuthenticationCode?.lowercase(Locale.ROOT)) { - SAS_MAC_SHA256_LONGKDF -> getSAS().calculateMacLongKdf(message, info) - SAS_MAC_SHA256 -> getSAS().calculateMac(message, info) - else -> null - } - } - - override fun getDecimalCodeRepresentation(): String { - return getDecimalCodeRepresentation(shortCodeBytes!!) - } - - /** - * decimal: generate five bytes by using HKDF. - * Take the first 13 bits and convert it to a decimal number (which will be a number between 0 and 8191 inclusive), - * and add 1000 (resulting in a number between 1000 and 9191 inclusive). - * Do the same with the second 13 bits, and the third 13 bits, giving three 4-digit numbers. - * In other words, if the five bytes are B0, B1, B2, B3, and B4, then the first number is (B0 << 5 | B1 >> 3) + 1000, - * the second number is ((B1 & 0x7) << 10 | B2 << 2 | B3 >> 6) + 1000, and the third number is ((B3 & 0x3f) << 7 | B4 >> 1) + 1000. - * (This method of converting 13 bits at a time is used to avoid requiring 32-bit clients to do big-number arithmetic, - * and adding 1000 to the number avoids having clients to worry about properly zero-padding the number when displaying to the user.) - * The three 4-digit numbers are displayed to the user either with dashes (or another appropriate separator) separating the three numbers, - * or with the three numbers on separate lines. - */ - fun getDecimalCodeRepresentation(byteArray: ByteArray): String { - val b0 = byteArray[0].toUnsignedInt() // need unsigned byte - val b1 = byteArray[1].toUnsignedInt() // need unsigned byte - val b2 = byteArray[2].toUnsignedInt() // need unsigned byte - val b3 = byteArray[3].toUnsignedInt() // need unsigned byte - val b4 = byteArray[4].toUnsignedInt() // need unsigned byte - // (B0 << 5 | B1 >> 3) + 1000 - val first = (b0.shl(5) or b1.shr(3)) + 1000 - // ((B1 & 0x7) << 10 | B2 << 2 | B3 >> 6) + 1000 - val second = ((b1 and 0x7).shl(10) or b2.shl(2) or b3.shr(6)) + 1000 - // ((B3 & 0x3f) << 7 | B4 >> 1) + 1000 - val third = ((b3 and 0x3f).shl(7) or b4.shr(1)) + 1000 - return "$first $second $third" - } - - override fun getEmojiCodeRepresentation(): List { - return getEmojiCodeRepresentation(shortCodeBytes!!) - } - - /** - * emoji: generate six bytes by using HKDF. - * Split the first 42 bits into 7 groups of 6 bits, as one would do when creating a base64 encoding. - * For each group of 6 bits, look up the emoji from Appendix A corresponding - * to that number 7 emoji are selected from a list of 64 emoji (see Appendix A) - */ - private fun getEmojiCodeRepresentation(byteArray: ByteArray): List { - val b0 = byteArray[0].toUnsignedInt() - val b1 = byteArray[1].toUnsignedInt() - val b2 = byteArray[2].toUnsignedInt() - val b3 = byteArray[3].toUnsignedInt() - val b4 = byteArray[4].toUnsignedInt() - val b5 = byteArray[5].toUnsignedInt() - return listOf( - getEmojiForCode((b0 and 0xFC).shr(2)), - getEmojiForCode((b0 and 0x3).shl(4) or (b1 and 0xF0).shr(4)), - getEmojiForCode((b1 and 0xF).shl(2) or (b2 and 0xC0).shr(6)), - getEmojiForCode((b2 and 0x3F)), - getEmojiForCode((b3 and 0xFC).shr(2)), - getEmojiForCode((b3 and 0x3).shl(4) or (b4 and 0xF0).shr(4)), - getEmojiForCode((b4 and 0xF).shl(2) or (b5 and 0xC0).shr(6)) - ) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SendVerificationMessageWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SendVerificationMessageWorker.kt deleted file mode 100644 index 538d7b56e9..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SendVerificationMessageWorker.kt +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import android.content.Context -import androidx.work.Data -import androidx.work.WorkerParameters -import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.api.failure.shouldBeRetried -import org.matrix.android.sdk.internal.crypto.tasks.SendVerificationMessageTask -import org.matrix.android.sdk.internal.session.SessionComponent -import org.matrix.android.sdk.internal.session.room.send.CancelSendTracker -import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository -import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker -import org.matrix.android.sdk.internal.worker.SessionWorkerParams -import timber.log.Timber -import javax.inject.Inject - -/** - * Possible previous worker: None - * Possible next worker : None - */ -internal class SendVerificationMessageWorker(context: Context, - params: WorkerParameters) - : SessionSafeCoroutineWorker(context, params, Params::class.java) { - - @JsonClass(generateAdapter = true) - internal data class Params( - override val sessionId: String, - val eventId: String, - override val lastFailureMessage: String? = null - ) : SessionWorkerParams - - @Inject lateinit var sendVerificationMessageTask: SendVerificationMessageTask - @Inject lateinit var localEchoRepository: LocalEchoRepository - @Inject lateinit var cancelSendTracker: CancelSendTracker - - override fun injectWith(injector: SessionComponent) { - injector.inject(this) - } - - override suspend fun doSafeWork(params: Params): Result { - val localEvent = localEchoRepository.getUpToDateEcho(params.eventId) ?: return buildErrorResult(params, "Event not found") - val localEventId = localEvent.eventId ?: "" - val roomId = localEvent.roomId ?: "" - - if (cancelSendTracker.isCancelRequestedFor(localEventId, roomId)) { - return Result.success() - .also { - cancelSendTracker.markCancelled(localEventId, roomId) - Timber.e("## SendEvent: Event sending has been cancelled $localEventId") - } - } - - return try { - val resultEventId = sendVerificationMessageTask.execute( - SendVerificationMessageTask.Params( - event = localEvent - ) - ) - - Result.success(Data.Builder().putString(localEventId, resultEventId).build()) - } catch (throwable: Throwable) { - if (throwable.shouldBeRetried()) { - Result.retry() - } else { - buildErrorResult(params, throwable.localizedMessage ?: "error") - } - } - } - - override fun buildErrorParams(params: Params, message: String): Params { - return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt index 21a6ba41b1..04699c1395 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt @@ -73,8 +73,8 @@ internal interface VerificationInfoStart : VerificationInfo null } } + + companion object { + const val SAS_MAC_SHA256_LONGKDF = "hmac-sha256" + const val SAS_MAC_SHA256 = "hkdf-hmac-sha256" + } } sealed class ValidVerificationInfoStart( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt deleted file mode 100644 index 74827eeb2a..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import org.matrix.android.sdk.api.session.crypto.MXCryptoError -import org.matrix.android.sdk.api.session.crypto.verification.VerificationService -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.LocalEcho -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.room.model.message.MessageContent -import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent -import org.matrix.android.sdk.api.session.room.model.message.MessageType -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationReadyContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationStartContent -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult -import org.matrix.android.sdk.internal.database.model.EventInsertType -import org.matrix.android.sdk.internal.di.DeviceId -import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor -import io.realm.Realm -import org.matrix.android.sdk.internal.crypto.EventDecryptor -import timber.log.Timber -import java.util.ArrayList -import javax.inject.Inject - -internal class VerificationMessageProcessor @Inject constructor( - private val eventDecryptor: EventDecryptor, - private val verificationService: DefaultVerificationService, - @UserId private val userId: String, - @DeviceId private val deviceId: String? -) : EventInsertLiveProcessor { - - private val transactionsHandledByOtherDevice = ArrayList() - - private val allowedTypes = listOf( - EventType.KEY_VERIFICATION_START, - EventType.KEY_VERIFICATION_ACCEPT, - EventType.KEY_VERIFICATION_KEY, - EventType.KEY_VERIFICATION_MAC, - EventType.KEY_VERIFICATION_CANCEL, - EventType.KEY_VERIFICATION_DONE, - EventType.KEY_VERIFICATION_READY, - EventType.MESSAGE, - EventType.ENCRYPTED - ) - - override fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean { - if (insertType != EventInsertType.INCREMENTAL_SYNC) { - return false - } - return allowedTypes.contains(eventType) && !LocalEcho.isLocalEchoId(eventId) - } - - override suspend fun process(realm: Realm, event: Event) { - Timber.v("## SAS Verification live observer: received msgId: ${event.eventId} msgtype: ${event.type} from ${event.senderId}") - - // If the request is in the future by more than 5 minutes or more than 10 minutes in the past, - // the message should be ignored by the receiver. - - if (!VerificationService.isValidRequest(event.ageLocalTs - ?: event.originServerTs)) return Unit.also { - Timber.d("## SAS Verification live observer: msgId: ${event.eventId} is outdated") - } - - // decrypt if needed? - if (event.isEncrypted() && event.mxDecryptionResult == null) { - // TODO use a global event decryptor? attache to session and that listen to new sessionId? - // for now decrypt sync - try { - val result = eventDecryptor.decryptEvent(event, "") - event.mxDecryptionResult = OlmDecryptionResult( - payload = result.clearEvent, - senderKey = result.senderCurve25519Key, - keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) }, - forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain - ) - } catch (e: MXCryptoError) { - Timber.e("## SAS Failed to decrypt event: ${event.eventId}") - verificationService.onPotentiallyInterestingEventRoomFailToDecrypt(event) - } - } - Timber.v("## SAS Verification live observer: received msgId: ${event.eventId} type: ${event.getClearType()}") - - // Relates to is not encrypted - val relatesToEventId = event.content.toModel()?.relatesTo?.eventId - - if (event.senderId == userId) { - // If it's send from me, we need to keep track of Requests or Start - // done from another device of mine - - if (EventType.MESSAGE == event.getClearType()) { - val msgType = event.getClearContent().toModel()?.msgType - if (MessageType.MSGTYPE_VERIFICATION_REQUEST == msgType) { - event.getClearContent().toModel()?.let { - if (it.fromDevice != deviceId) { - // The verification is requested from another device - Timber.v("## SAS Verification live observer: Transaction requested from other device tid:${event.eventId} ") - event.eventId?.let { txId -> transactionsHandledByOtherDevice.add(txId) } - } - } - } - } else if (EventType.KEY_VERIFICATION_START == event.getClearType()) { - event.getClearContent().toModel()?.let { - if (it.fromDevice != deviceId) { - // The verification is started from another device - Timber.v("## SAS Verification live observer: Transaction started by other device tid:$relatesToEventId ") - relatesToEventId?.let { txId -> transactionsHandledByOtherDevice.add(txId) } - verificationService.onRoomRequestHandledByOtherDevice(event) - } - } - } else if (EventType.KEY_VERIFICATION_READY == event.getClearType()) { - event.getClearContent().toModel()?.let { - if (it.fromDevice != deviceId) { - // The verification is started from another device - Timber.v("## SAS Verification live observer: Transaction started by other device tid:$relatesToEventId ") - relatesToEventId?.let { txId -> transactionsHandledByOtherDevice.add(txId) } - verificationService.onRoomRequestHandledByOtherDevice(event) - } - } - } else if (EventType.KEY_VERIFICATION_CANCEL == event.getClearType() || EventType.KEY_VERIFICATION_DONE == event.getClearType()) { - relatesToEventId?.let { - transactionsHandledByOtherDevice.remove(it) - verificationService.onRoomRequestHandledByOtherDevice(event) - } - } - - Timber.v("## SAS Verification ignoring message sent by me: ${event.eventId} type: ${event.getClearType()}") - return - } - - if (relatesToEventId != null && transactionsHandledByOtherDevice.contains(relatesToEventId)) { - // Ignore this event, it is directed to another of my devices - Timber.v("## SAS Verification live observer: Ignore Transaction handled by other device tid:$relatesToEventId ") - return - } - when (event.getClearType()) { - EventType.KEY_VERIFICATION_START, - EventType.KEY_VERIFICATION_ACCEPT, - EventType.KEY_VERIFICATION_KEY, - EventType.KEY_VERIFICATION_MAC, - EventType.KEY_VERIFICATION_CANCEL, - EventType.KEY_VERIFICATION_READY, - EventType.KEY_VERIFICATION_DONE -> { - verificationService.onRoomEvent(event) - } - EventType.MESSAGE -> { - if (MessageType.MSGTYPE_VERIFICATION_REQUEST == event.getClearContent().toModel()?.msgType) { - verificationService.onRoomRequestReceived(event) - } - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransport.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransport.kt deleted file mode 100644 index b0fab6213e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransport.kt +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest -import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState - -/** - * Verification can be performed using toDevice events or via DM. - * This class abstracts the concept of transport for verification - */ -internal interface VerificationTransport { - - /** - * Sends a message - */ - fun sendToOther(type: String, - verificationInfo: VerificationInfo, - nextState: VerificationTxState, - onErrorReason: CancelCode, - onDone: (() -> Unit)?) - - /** - * @param callback will be called with eventId and ValidVerificationInfoRequest in case of success - */ - fun sendVerificationRequest(supportedMethods: List, - localId: String, - otherUserId: String, - roomId: String?, - toDevices: List?, - callback: (String?, ValidVerificationInfoRequest?) -> Unit) - - fun cancelTransaction(transactionId: String, - otherUserId: String, - otherUserDeviceId: String?, - code: CancelCode) - - fun done(transactionId: String, - onDone: (() -> Unit)?) - - /** - * Creates an accept message suitable for this transport - */ - fun createAccept(tid: String, - keyAgreementProtocol: String, - hash: String, - commitment: String, - messageAuthenticationCode: String, - shortAuthenticationStrings: List): VerificationInfoAccept - - fun createKey(tid: String, - pubKey: String): VerificationInfoKey - - /** - * Create start for SAS verification - */ - fun createStartForSas(fromDevice: String, - transactionId: String, - keyAgreementProtocols: List, - hashes: List, - messageAuthenticationCodes: List, - shortAuthenticationStrings: List): VerificationInfoStart - - /** - * Create start for QR code verification - */ - fun createStartForQrCode(fromDevice: String, - transactionId: String, - sharedSecret: String): VerificationInfoStart - - fun createMac(tid: String, mac: Map, keys: String): VerificationInfoMac - - fun createReady(tid: String, - fromDevice: String, - methods: List): VerificationInfoReady - - // TODO Refactor - fun sendVerificationReady(keyReq: VerificationInfoReady, - otherUserId: String, - otherDeviceId: String?, - callback: (() -> Unit)?) -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt deleted file mode 100644 index bcf3250ed2..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessage.kt +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import androidx.lifecycle.Observer -import androidx.work.BackoffPolicy -import androidx.work.Data -import androidx.work.ExistingWorkPolicy -import androidx.work.Operation -import androidx.work.WorkInfo -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -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.EventType -import org.matrix.android.sdk.api.session.events.model.LocalEcho -import org.matrix.android.sdk.api.session.events.model.RelationType -import org.matrix.android.sdk.api.session.events.model.UnsignedData -import org.matrix.android.sdk.api.session.events.model.toContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationAcceptContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationCancelContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationDoneContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationKeyContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationMacContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationReadyContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent -import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationStartContent -import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS -import org.matrix.android.sdk.internal.di.WorkManagerProvider -import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory -import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker -import org.matrix.android.sdk.internal.worker.WorkerParamsFactory -import timber.log.Timber -import java.util.UUID -import java.util.concurrent.TimeUnit - -internal class VerificationTransportRoomMessage( - private val workManagerProvider: WorkManagerProvider, - private val sessionId: String, - private val userId: String, - private val userDeviceId: String?, - private val roomId: String, - private val localEchoEventFactory: LocalEchoEventFactory, - private val tx: DefaultVerificationTransaction?, - private val coroutineScope: CoroutineScope -) : VerificationTransport { - - override fun sendToOther(type: String, - verificationInfo: VerificationInfo, - nextState: VerificationTxState, - onErrorReason: CancelCode, - onDone: (() -> Unit)?) { - Timber.d("## SAS sending msg type $type") - Timber.v("## SAS sending msg info $verificationInfo") - val event = createEventAndLocalEcho( - type = type, - roomId = roomId, - content = verificationInfo.toEventContent()!! - ) - - val workerParams = WorkerParamsFactory.toData(SendVerificationMessageWorker.Params( - sessionId = sessionId, - eventId = event.eventId ?: "" - )) - val enqueueInfo = enqueueSendWork(workerParams) - - // I cannot just listen to the given work request, because when used in a uniqueWork, - // The callback is called while it is still Running ... - -// Futures.addCallback(enqueueInfo.first.result, object : FutureCallback { -// override fun onSuccess(result: Operation.State.SUCCESS?) { -// if (onDone != null) { -// onDone() -// } else { -// tx?.state = nextState -// } -// } -// -// override fun onFailure(t: Throwable) { -// Timber.e("## SAS verification [${tx?.transactionId}] failed to send toDevice in state : ${tx?.state}, reason: ${t.localizedMessage}") -// tx?.cancel(onErrorReason) -// } -// }, listenerExecutor) - - val workLiveData = workManagerProvider.workManager - .getWorkInfosForUniqueWorkLiveData(uniqueQueueName()) - - val observer = object : Observer> { - override fun onChanged(workInfoList: List?) { - workInfoList - ?.firstOrNull { it.id == enqueueInfo.second } - ?.let { wInfo -> - when (wInfo.state) { - WorkInfo.State.FAILED -> { - tx?.cancel(onErrorReason) - workLiveData.removeObserver(this) - } - WorkInfo.State.SUCCEEDED -> { - if (SessionSafeCoroutineWorker.hasFailed(wInfo.outputData)) { - Timber.e("## SAS verification [${tx?.transactionId}] failed to send verification message in state : ${tx?.state}") - tx?.cancel(onErrorReason) - } else { - if (onDone != null) { - onDone() - } else { - tx?.state = nextState - } - } - workLiveData.removeObserver(this) - } - else -> { - // nop - } - } - } - } - } - - // TODO listen to DB to get synced info - coroutineScope.launch(Dispatchers.Main) { - workLiveData.observeForever(observer) - } - } - - override fun sendVerificationRequest(supportedMethods: List, - localId: String, - otherUserId: String, - roomId: String?, - toDevices: List?, - callback: (String?, ValidVerificationInfoRequest?) -> Unit) { - Timber.d("## SAS sending verification request with supported methods: $supportedMethods") - // This transport requires a room - requireNotNull(roomId) - - val validInfo = ValidVerificationInfoRequest( - transactionId = "", - fromDevice = userDeviceId ?: "", - methods = supportedMethods, - timestamp = System.currentTimeMillis() - ) - - val info = MessageVerificationRequestContent( - body = "$userId is requesting to verify your key, but your client does not support in-chat key verification." + - " You will need to use legacy key verification to verify keys.", - fromDevice = validInfo.fromDevice, - toUserId = otherUserId, - timestamp = validInfo.timestamp, - methods = validInfo.methods - ) - val content = info.toContent() - - val event = createEventAndLocalEcho( - localId, - EventType.MESSAGE, - roomId, - content - ) - - val workerParams = WorkerParamsFactory.toData(SendVerificationMessageWorker.Params( - sessionId = sessionId, - eventId = event.eventId ?: "" - )) - - val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() - .setConstraints(WorkManagerProvider.workConstraints) - .setInputData(workerParams) - .setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS) - .build() - - workManagerProvider.workManager - .beginUniqueWork("${roomId}_VerificationWork", ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest) - .enqueue() - - // I cannot just listen to the given work request, because when used in a uniqueWork, - // The callback is called while it is still Running ... - - val workLiveData = workManagerProvider.workManager - .getWorkInfosForUniqueWorkLiveData("${roomId}_VerificationWork") - - val observer = object : Observer> { - override fun onChanged(workInfoList: List?) { - workInfoList - ?.filter { it.state == WorkInfo.State.SUCCEEDED } - ?.firstOrNull { it.id == workRequest.id } - ?.let { wInfo -> - if (SessionSafeCoroutineWorker.hasFailed(wInfo.outputData)) { - callback(null, null) - } else { - val eventId = wInfo.outputData.getString(localId) - if (eventId != null) { - callback(eventId, validInfo) - } else { - callback(null, null) - } - } - workLiveData.removeObserver(this) - } - } - } - - // TODO listen to DB to get synced info - coroutineScope.launch(Dispatchers.Main) { - workLiveData.observeForever(observer) - } - } - - override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String?, code: CancelCode) { - Timber.d("## SAS canceling transaction $transactionId for reason $code") - val event = createEventAndLocalEcho( - type = EventType.KEY_VERIFICATION_CANCEL, - roomId = roomId, - content = MessageVerificationCancelContent.create(transactionId, code).toContent() - ) - val workerParams = WorkerParamsFactory.toData(SendVerificationMessageWorker.Params( - sessionId = sessionId, - eventId = event.eventId ?: "" - )) - enqueueSendWork(workerParams) - } - - override fun done(transactionId: String, - onDone: (() -> Unit)?) { - Timber.d("## SAS sending done for $transactionId") - val event = createEventAndLocalEcho( - type = EventType.KEY_VERIFICATION_DONE, - roomId = roomId, - content = MessageVerificationDoneContent( - relatesTo = RelationDefaultContent( - RelationType.REFERENCE, - transactionId - ) - ).toContent() - ) - val workerParams = WorkerParamsFactory.toData(SendVerificationMessageWorker.Params( - sessionId = sessionId, - eventId = event.eventId ?: "" - )) - val enqueueInfo = enqueueSendWork(workerParams) - - val workLiveData = workManagerProvider.workManager - .getWorkInfosForUniqueWorkLiveData(uniqueQueueName()) - val observer = object : Observer> { - override fun onChanged(workInfoList: List?) { - workInfoList - ?.filter { it.state == WorkInfo.State.SUCCEEDED } - ?.firstOrNull { it.id == enqueueInfo.second } - ?.let { _ -> - onDone?.invoke() - workLiveData.removeObserver(this) - } - } - } - - // TODO listen to DB to get synced info - coroutineScope.launch(Dispatchers.Main) { - workLiveData.observeForever(observer) - } - } - - private fun enqueueSendWork(workerParams: Data): Pair { - val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() - .setConstraints(WorkManagerProvider.workConstraints) - .setInputData(workerParams) - .setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS) - .build() - return workManagerProvider.workManager - .beginUniqueWork(uniqueQueueName(), ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest) - .enqueue() to workRequest.id - } - - private fun uniqueQueueName() = "${roomId}_VerificationWork" - - override fun createAccept(tid: String, - keyAgreementProtocol: String, - hash: String, - commitment: String, - messageAuthenticationCode: String, - shortAuthenticationStrings: List) - : VerificationInfoAccept = MessageVerificationAcceptContent.create( - tid, - keyAgreementProtocol, - hash, - commitment, - messageAuthenticationCode, - shortAuthenticationStrings - ) - - override fun createKey(tid: String, pubKey: String): VerificationInfoKey = MessageVerificationKeyContent.create(tid, pubKey) - - override fun createMac(tid: String, mac: Map, keys: String) = MessageVerificationMacContent.create(tid, mac, keys) - - override fun createStartForSas(fromDevice: String, - transactionId: String, - keyAgreementProtocols: List, - hashes: List, - messageAuthenticationCodes: List, - shortAuthenticationStrings: List): VerificationInfoStart { - return MessageVerificationStartContent( - fromDevice, - hashes, - keyAgreementProtocols, - messageAuthenticationCodes, - shortAuthenticationStrings, - VERIFICATION_METHOD_SAS, - RelationDefaultContent( - type = RelationType.REFERENCE, - eventId = transactionId - ), - null - ) - } - - override fun createStartForQrCode(fromDevice: String, - transactionId: String, - sharedSecret: String): VerificationInfoStart { - return MessageVerificationStartContent( - fromDevice, - null, - null, - null, - null, - VERIFICATION_METHOD_RECIPROCATE, - RelationDefaultContent( - type = RelationType.REFERENCE, - eventId = transactionId - ), - sharedSecret - ) - } - - override fun createReady(tid: String, fromDevice: String, methods: List): VerificationInfoReady { - return MessageVerificationReadyContent( - fromDevice = fromDevice, - relatesTo = RelationDefaultContent( - type = RelationType.REFERENCE, - eventId = tid - ), - methods = methods - ) - } - - private fun createEventAndLocalEcho(localId: String = LocalEcho.createLocalEchoId(), type: String, roomId: String, content: Content): Event { - return Event( - roomId = roomId, - originServerTs = System.currentTimeMillis(), - senderId = userId, - eventId = localId, - type = type, - content = content, - unsignedData = UnsignedData(age = null, transactionId = localId) - ).also { - localEchoEventFactory.createLocalEcho(it) - } - } - - override fun sendVerificationReady(keyReq: VerificationInfoReady, - otherUserId: String, - otherDeviceId: String?, - callback: (() -> Unit)?) { - // Not applicable (send event is called directly) - Timber.w("## SAS ignored verification ready with methods: ${keyReq.methods}") - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessageFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessageFactory.kt deleted file mode 100644 index f89127273b..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportRoomMessageFactory.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2021 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.verification - -import org.matrix.android.sdk.internal.di.DeviceId -import org.matrix.android.sdk.internal.di.SessionId -import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.di.WorkManagerProvider -import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory -import org.matrix.android.sdk.internal.task.TaskExecutor -import javax.inject.Inject - -internal class VerificationTransportRoomMessageFactory @Inject constructor( - private val workManagerProvider: WorkManagerProvider, - @SessionId - private val sessionId: String, - @UserId - private val userId: String, - @DeviceId - private val deviceId: String?, - private val localEchoEventFactory: LocalEchoEventFactory, - private val taskExecutor: TaskExecutor -) { - - fun createTransport(roomId: String, tx: DefaultVerificationTransaction?): VerificationTransportRoomMessage { - return VerificationTransportRoomMessage(workManagerProvider, - sessionId, - userId, - deviceId, - roomId, - localEchoEventFactory, - tx, - taskExecutor.executorScope) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt deleted file mode 100644 index 0dbbe656c7..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.crypto.verification - -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.room.model.message.MessageType -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationAccept -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel -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.KeyVerificationMac -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationReady -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest -import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS -import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask -import org.matrix.android.sdk.internal.task.TaskExecutor -import org.matrix.android.sdk.internal.task.configureWith -import timber.log.Timber - -internal class VerificationTransportToDevice( - private var tx: DefaultVerificationTransaction?, - private var sendToDeviceTask: SendToDeviceTask, - private val myDeviceId: String?, - private var taskExecutor: TaskExecutor -) : VerificationTransport { - - override fun sendVerificationRequest(supportedMethods: List, - localId: String, - otherUserId: String, - roomId: String?, - toDevices: List?, - callback: (String?, ValidVerificationInfoRequest?) -> Unit) { - Timber.d("## SAS sending verification request with supported methods: $supportedMethods") - val contentMap = MXUsersDevicesMap() - val validKeyReq = ValidVerificationInfoRequest( - transactionId = localId, - fromDevice = myDeviceId ?: "", - methods = supportedMethods, - timestamp = System.currentTimeMillis() - ) - val keyReq = KeyVerificationRequest( - fromDevice = validKeyReq.fromDevice, - methods = validKeyReq.methods, - timestamp = validKeyReq.timestamp, - transactionId = validKeyReq.transactionId - ) - toDevices?.forEach { - contentMap.setObject(otherUserId, it, keyReq) - } - sendToDeviceTask - .configureWith(SendToDeviceTask.Params(MessageType.MSGTYPE_VERIFICATION_REQUEST, contentMap, localId)) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: Unit) { - Timber.v("## verification [$tx.transactionId] send toDevice request success") - callback.invoke(localId, validKeyReq) - } - - override fun onFailure(failure: Throwable) { - Timber.e("## verification [$tx.transactionId] failed to send toDevice request") - } - } - } - .executeBy(taskExecutor) - } - - override fun sendVerificationReady(keyReq: VerificationInfoReady, - otherUserId: String, - otherDeviceId: String?, - callback: (() -> Unit)?) { - Timber.d("## SAS sending verification ready with methods: ${keyReq.methods}") - val contentMap = MXUsersDevicesMap() - - contentMap.setObject(otherUserId, otherDeviceId, keyReq) - - sendToDeviceTask - .configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_READY, contentMap)) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: Unit) { - Timber.v("## verification [$tx.transactionId] send toDevice request success") - callback?.invoke() - } - - override fun onFailure(failure: Throwable) { - Timber.e("## verification [$tx.transactionId] failed to send toDevice request") - } - } - } - .executeBy(taskExecutor) - } - - override fun sendToOther(type: String, - verificationInfo: VerificationInfo, - nextState: VerificationTxState, - onErrorReason: CancelCode, - onDone: (() -> Unit)?) { - Timber.d("## SAS sending msg type $type") - Timber.v("## SAS sending msg info $verificationInfo") - val stateBeforeCall = tx?.state - val tx = tx ?: return - val contentMap = MXUsersDevicesMap() - val toSendToDeviceObject = verificationInfo.toSendToDeviceObject() - ?: return Unit.also { tx.cancel() } - - contentMap.setObject(tx.otherUserId, tx.otherDeviceId, toSendToDeviceObject) - - sendToDeviceTask - .configureWith(SendToDeviceTask.Params(type, contentMap, tx.transactionId)) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: Unit) { - Timber.v("## SAS verification [$tx.transactionId] toDevice type '$type' success.") - if (onDone != null) { - onDone() - } else { - // we may have received next state (e.g received accept in sending_start) - // We only put next state if the state was what is was before we started - if (tx.state == stateBeforeCall) { - tx.state = nextState - } - } - } - - override fun onFailure(failure: Throwable) { - Timber.e("## SAS verification [$tx.transactionId] failed to send toDevice in state : $tx.state") - tx.cancel(onErrorReason) - } - } - } - .executeBy(taskExecutor) - } - - override fun done(transactionId: String, onDone: (() -> Unit)?) { - val otherUserId = tx?.otherUserId ?: return - val otherUserDeviceId = tx?.otherDeviceId ?: return - val cancelMessage = KeyVerificationDone(transactionId) - val contentMap = MXUsersDevicesMap() - contentMap.setObject(otherUserId, otherUserDeviceId, cancelMessage) - sendToDeviceTask - .configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_DONE, contentMap, transactionId)) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: Unit) { - onDone?.invoke() - Timber.v("## SAS verification [$transactionId] done") - } - - override fun onFailure(failure: Throwable) { - Timber.e(failure, "## SAS verification [$transactionId] failed to done.") - } - } - } - .executeBy(taskExecutor) - } - - override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String?, code: CancelCode) { - Timber.d("## SAS canceling transaction $transactionId for reason $code") - val cancelMessage = KeyVerificationCancel.create(transactionId, code) - val contentMap = MXUsersDevicesMap() - contentMap.setObject(otherUserId, otherUserDeviceId, cancelMessage) - sendToDeviceTask - .configureWith(SendToDeviceTask.Params(EventType.KEY_VERIFICATION_CANCEL, contentMap, transactionId)) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: Unit) { - Timber.v("## SAS verification [$transactionId] canceled for reason ${code.value}") - } - - override fun onFailure(failure: Throwable) { - Timber.e(failure, "## SAS verification [$transactionId] failed to cancel.") - } - } - } - .executeBy(taskExecutor) - } - - override fun createAccept(tid: String, - keyAgreementProtocol: String, - hash: String, - commitment: String, - messageAuthenticationCode: String, - shortAuthenticationStrings: List): VerificationInfoAccept = KeyVerificationAccept.create( - tid, - keyAgreementProtocol, - hash, - commitment, - messageAuthenticationCode, - shortAuthenticationStrings) - - override fun createKey(tid: String, pubKey: String): VerificationInfoKey = KeyVerificationKey.create(tid, pubKey) - - override fun createMac(tid: String, mac: Map, keys: String) = KeyVerificationMac.create(tid, mac, keys) - - override fun createStartForSas(fromDevice: String, - transactionId: String, - keyAgreementProtocols: List, - hashes: List, - messageAuthenticationCodes: List, - shortAuthenticationStrings: List): VerificationInfoStart { - return KeyVerificationStart( - fromDevice, - VERIFICATION_METHOD_SAS, - transactionId, - keyAgreementProtocols, - hashes, - messageAuthenticationCodes, - shortAuthenticationStrings, - null) - } - - override fun createStartForQrCode(fromDevice: String, - transactionId: String, - sharedSecret: String): VerificationInfoStart { - return KeyVerificationStart( - fromDevice, - VERIFICATION_METHOD_RECIPROCATE, - transactionId, - null, - null, - null, - null, - sharedSecret) - } - - override fun createReady(tid: String, fromDevice: String, methods: List): VerificationInfoReady { - return KeyVerificationReady( - transactionId = tid, - fromDevice = fromDevice, - methods = methods - ) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDeviceFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDeviceFactory.kt deleted file mode 100644 index e9a2c65ef7..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDeviceFactory.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.verification - -import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask -import org.matrix.android.sdk.internal.di.DeviceId -import org.matrix.android.sdk.internal.task.TaskExecutor -import javax.inject.Inject - -internal class VerificationTransportToDeviceFactory @Inject constructor( - private val sendToDeviceTask: SendToDeviceTask, - @DeviceId val myDeviceId: String?, - private val taskExecutor: TaskExecutor) { - - fun createTransport(tx: DefaultVerificationTransaction?): VerificationTransportToDevice { - return VerificationTransportToDevice(tx, sendToDeviceTask, myDeviceId, taskExecutor) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt deleted file mode 100644 index 829e066bf3..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.verification.qrcode - -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64Safe -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationTransaction -import org.matrix.android.sdk.internal.crypto.verification.ValidVerificationInfoStart -import org.matrix.android.sdk.internal.util.exhaustive -import timber.log.Timber - -internal class DefaultQrCodeVerificationTransaction( - setDeviceVerificationAction: SetDeviceVerificationAction, - override val transactionId: String, - override val otherUserId: String, - override var otherDeviceId: String?, - private val crossSigningService: CrossSigningService, - outgoingGossipingRequestManager: OutgoingGossipingRequestManager, - incomingGossipingRequestManager: IncomingGossipingRequestManager, - private val cryptoStore: IMXCryptoStore, - // Not null only if other user is able to scan QR code - private val qrCodeData: QrCodeData?, - val userId: String, - val deviceId: String, - override val isIncoming: Boolean -) : DefaultVerificationTransaction( - setDeviceVerificationAction, - crossSigningService, - outgoingGossipingRequestManager, - incomingGossipingRequestManager, - userId, - transactionId, - otherUserId, - otherDeviceId, - isIncoming), - QrCodeVerificationTransaction { - - override val qrCodeText: String? - get() = qrCodeData?.toEncodedString() - - override var state: VerificationTxState = VerificationTxState.None - set(newState) { - field = newState - - listeners.forEach { - try { - it.transactionUpdated(this) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - - override fun userHasScannedOtherQrCode(otherQrCodeText: String) { - val otherQrCodeData = otherQrCodeText.toQrCodeData() ?: run { - Timber.d("## Verification QR: Invalid QR Code Data") - cancel(CancelCode.QrCodeInvalid) - return - } - - // Perform some checks - if (otherQrCodeData.transactionId != transactionId) { - Timber.d("## Verification QR: Invalid transaction actual ${otherQrCodeData.transactionId} expected:$transactionId") - cancel(CancelCode.QrCodeInvalid) - return - } - - // check master key - val myMasterKey = crossSigningService.getUserCrossSigningKeys(userId)?.masterKey()?.unpaddedBase64PublicKey - var canTrustOtherUserMasterKey = false - - // Check the other device view of my MSK - when (otherQrCodeData) { - is QrCodeData.VerifyingAnotherUser -> { - // key2 (aka otherUserMasterCrossSigningPublicKey) is what the one displaying the QR code (other user) think my MSK is. - // Let's check that it's correct - // If not -> Cancel - if (otherQrCodeData.otherUserMasterCrossSigningPublicKey != myMasterKey) { - Timber.d("## Verification QR: Invalid other master key ${otherQrCodeData.otherUserMasterCrossSigningPublicKey}") - cancel(CancelCode.MismatchedKeys) - return - } else Unit - } - is QrCodeData.SelfVerifyingMasterKeyTrusted -> { - // key1 (aka userMasterCrossSigningPublicKey) is the session displaying the QR code view of our MSK. - // Let's check that I see the same MSK - // If not -> Cancel - if (otherQrCodeData.userMasterCrossSigningPublicKey != myMasterKey) { - Timber.d("## Verification QR: Invalid other master key ${otherQrCodeData.userMasterCrossSigningPublicKey}") - cancel(CancelCode.MismatchedKeys) - return - } else { - // I can trust the MSK then (i see the same one, and other session tell me it's trusted by him) - canTrustOtherUserMasterKey = true - } - } - is QrCodeData.SelfVerifyingMasterKeyNotTrusted -> { - // key2 (aka userMasterCrossSigningPublicKey) is the session displaying the QR code view of our MSK. - // Let's check that it's the good one - // If not -> Cancel - if (otherQrCodeData.userMasterCrossSigningPublicKey != myMasterKey) { - Timber.d("## Verification QR: Invalid other master key ${otherQrCodeData.userMasterCrossSigningPublicKey}") - cancel(CancelCode.MismatchedKeys) - return - } else { - // Nothing special here, we will send a reciprocate start event, and then the other session will trust it's view of the MSK - } - } - }.exhaustive - - val toVerifyDeviceIds = mutableListOf() - - // Let's now check the other user/device key material - when (otherQrCodeData) { - is QrCodeData.VerifyingAnotherUser -> { - // key1(aka userMasterCrossSigningPublicKey) is the MSK of the one displaying the QR code (i.e other user) - // Let's check that it matches what I think it should be - if (otherQrCodeData.userMasterCrossSigningPublicKey - != crossSigningService.getUserCrossSigningKeys(otherUserId)?.masterKey()?.unpaddedBase64PublicKey) { - Timber.d("## Verification QR: Invalid user master key ${otherQrCodeData.userMasterCrossSigningPublicKey}") - cancel(CancelCode.MismatchedKeys) - return - } else { - // It does so i should mark it as trusted - canTrustOtherUserMasterKey = true - Unit - } - } - is QrCodeData.SelfVerifyingMasterKeyTrusted -> { - // key2 (aka otherDeviceKey) is my current device key in POV of the one displaying the QR code (i.e other device) - // Let's check that it's correct - if (otherQrCodeData.otherDeviceKey - != cryptoStore.getUserDevice(userId, deviceId)?.fingerprint()) { - Timber.d("## Verification QR: Invalid other device key ${otherQrCodeData.otherDeviceKey}") - cancel(CancelCode.MismatchedKeys) - return - } else Unit // Nothing special here, we will send a reciprocate start event, and then the other session will trust my device - // and thus allow me to request SSSS secret - } - is QrCodeData.SelfVerifyingMasterKeyNotTrusted -> { - // key1 (aka otherDeviceKey) is the device key of the one displaying the QR code (i.e other device) - // Let's check that it matches what I have locally - if (otherQrCodeData.deviceKey - != cryptoStore.getUserDevice(otherUserId, otherDeviceId ?: "")?.fingerprint()) { - Timber.d("## Verification QR: Invalid device key ${otherQrCodeData.deviceKey}") - cancel(CancelCode.MismatchedKeys) - return - } else { - // Yes it does -> i should trust it and sign then upload the signature - toVerifyDeviceIds.add(otherDeviceId ?: "") - Unit - } - } - }.exhaustive - - if (!canTrustOtherUserMasterKey && toVerifyDeviceIds.isEmpty()) { - // Nothing to verify - cancel(CancelCode.MismatchedKeys) - return - } - - // All checks are correct - // Send the shared secret so that sender can trust me - // qrCodeData.sharedSecret will be used to send the start request - start(otherQrCodeData.sharedSecret) - - trust( - canTrustOtherUserMasterKey = canTrustOtherUserMasterKey, - toVerifyDeviceIds = toVerifyDeviceIds.distinct(), - eventuallyMarkMyMasterKeyAsTrusted = true, - autoDone = false - ) - } - - private fun start(remoteSecret: String, onDone: (() -> Unit)? = null) { - if (state != VerificationTxState.None) { - Timber.e("## Verification QR: start verification from invalid state") - // should I cancel?? - throw IllegalStateException("Interactive Key verification already started") - } - - state = VerificationTxState.Started - val startMessage = transport.createStartForQrCode( - deviceId, - transactionId, - remoteSecret - ) - - transport.sendToOther( - EventType.KEY_VERIFICATION_START, - startMessage, - VerificationTxState.WaitingOtherReciprocateConfirm, - CancelCode.User, - onDone - ) - } - - override fun cancel() { - cancel(CancelCode.User) - } - - override fun cancel(code: CancelCode) { - state = VerificationTxState.Cancelled(code, true) - transport.cancelTransaction(transactionId, otherUserId, otherDeviceId ?: "", code) - } - - override fun isToDeviceTransport() = false - - // Other user has scanned our QR code. check that the secret matched, so we can trust him - fun onStartReceived(startReq: ValidVerificationInfoStart.ReciprocateVerificationInfoStart) { - if (qrCodeData == null) { - // Should not happen - cancel(CancelCode.UnexpectedMessage) - return - } - - if (startReq.sharedSecret.fromBase64Safe()?.contentEquals(qrCodeData.sharedSecret.fromBase64()) == true) { - // Ok, we can trust the other user - // We can only trust the master key in this case - // But first, ask the user for a confirmation - state = VerificationTxState.QrScannedByOther - } else { - // Display a warning - cancel(CancelCode.MismatchedKeys) - } - } - - fun onDoneReceived() { - if (state != VerificationTxState.WaitingOtherReciprocateConfirm) { - cancel(CancelCode.UnexpectedMessage) - return - } - state = VerificationTxState.Verified - transport.done(transactionId) {} - } - - override fun otherUserScannedMyQrCode() { - when (qrCodeData) { - is QrCodeData.VerifyingAnotherUser -> { - // Alice telling Bob that the code was scanned successfully is sufficient for Bob to trust Alice's key, - trust(true, emptyList(), false) - } - is QrCodeData.SelfVerifyingMasterKeyTrusted -> { - // I now know that I have the correct device key for other session, - // and can sign it with the self-signing key and upload the signature - trust(false, listOf(otherDeviceId ?: ""), false) - } - is QrCodeData.SelfVerifyingMasterKeyNotTrusted -> { - // I now know that i can trust my MSK - trust(true, emptyList(), true) - } - } - } - - override fun otherUserDidNotScannedMyQrCode() { - // What can I do then? - // At least remove the transaction... - cancel(CancelCode.MismatchedKeys) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt index 9a936b73c2..37cbc65f3c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt @@ -25,7 +25,6 @@ import org.matrix.android.sdk.internal.crypto.CryptoModule import org.matrix.android.sdk.internal.crypto.SendGossipRequestWorker import org.matrix.android.sdk.internal.crypto.SendGossipWorker import org.matrix.android.sdk.internal.crypto.crosssigning.UpdateTrustWorker -import org.matrix.android.sdk.internal.crypto.verification.SendVerificationMessageWorker import org.matrix.android.sdk.internal.di.MatrixComponent import org.matrix.android.sdk.internal.federation.FederationModule import org.matrix.android.sdk.internal.network.NetworkConnectivityChecker @@ -129,8 +128,6 @@ internal interface SessionComponent { fun inject(worker: AddHttpPusherWorker) - fun inject(worker: SendVerificationMessageWorker) - fun inject(worker: SendGossipRequestWorker) fun inject(worker: CancelGossipRequestWorker) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index e6da21315b..964620c316 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -46,7 +46,6 @@ import org.matrix.android.sdk.api.session.typing.TypingUsersTracker import org.matrix.android.sdk.internal.crypto.secrets.DefaultSharedSecretStorageService import org.matrix.android.sdk.internal.crypto.tasks.DefaultRedactEventTask import org.matrix.android.sdk.internal.crypto.tasks.RedactEventTask -import org.matrix.android.sdk.internal.crypto.verification.VerificationMessageProcessor import org.matrix.android.sdk.internal.database.DatabaseCleaner import org.matrix.android.sdk.internal.database.EventInsertLiveObserver import org.matrix.android.sdk.internal.database.RealmSessionProvider @@ -314,10 +313,6 @@ internal abstract class SessionModule { @IntoSet abstract fun bindRoomCreateEventProcessor(processor: RoomCreateEventProcessor): EventInsertLiveProcessor - @Binds - @IntoSet - abstract fun bindVerificationMessageProcessor(processor: VerificationMessageProcessor): EventInsertLiveProcessor - @Binds @IntoSet abstract fun bindCallEventProcessor(processor: CallEventProcessor): EventInsertLiveProcessor From f609bfaf10d9e923d8707a15a9693bb59ad2f8b8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 8 Jul 2021 18:39:54 +0200 Subject: [PATCH 131/252] This class is not injected. --- .../sdk/internal/crypto/verification/RustVerificationService.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index b77007aa28..dc59845048 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -42,7 +42,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import org.matrix.android.sdk.internal.crypto.model.rest.toValue -import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber import uniffi.olm.Verification @@ -62,7 +61,6 @@ private fun getFlowId(event: Event): String? { } } -@SessionScope internal class RustVerificationService( private val olmMachine: OlmMachine, private val requestSender: RequestSender, From b26aba9fc0b6a9ac7703a80f5a7d6b8bf81498a8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 9 Jul 2021 12:50:34 +0200 Subject: [PATCH 132/252] Remove EventDecryptor and inject the cryptoService when needed Not used anymore in RoomSummaryUpdater, to avoid a DI dependency loop. let's see if this is a problem --- .../internal/crypto/DefaultCryptoService.kt | 1 - .../sdk/internal/crypto/EventDecryptor.kt | 175 ------------------ .../database/EventInsertLiveObserver.kt | 32 +--- .../room/summary/RoomSummaryUpdater.kt | 14 +- .../session/room/timeline/GetEventTask.kt | 6 +- 5 files changed, 11 insertions(+), 217 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 548b0bb583..118d550e65 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -642,7 +642,6 @@ internal class DefaultCryptoService @Inject constructor( */ @Throws(MXCryptoError::class) override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { - return runBlocking { olmMachine!!.decryptRoomEvent(event) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt deleted file mode 100644 index 8d86380e39..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.session.crypto.MXCryptoError -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction -import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask -import org.matrix.android.sdk.internal.extensions.foldToCallback -import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -import timber.log.Timber -import javax.inject.Inject -import kotlin.jvm.Throws - -@SessionScope -internal class EventDecryptor @Inject constructor( - private val cryptoCoroutineScope: CoroutineScope, - private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val roomDecryptorProvider: RoomDecryptorProvider, - private val messageEncrypter: MessageEncrypter, - private val sendToDeviceTask: SendToDeviceTask, - private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction, - private val cryptoStore: IMXCryptoStore -) { - - // The date of the last time we forced establishment - // of a new session for each user:device. - private val lastNewSessionForcedDates = MXUsersDevicesMap() - - /** - * Decrypt an event - * - * @param event the raw event. - * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. - * @return the MXEventDecryptionResult data, or throw in case of error - */ - @Throws(MXCryptoError::class) - fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { - return internalDecryptEvent(event, timeline) - } - - /** - * Decrypt an event asynchronously - * - * @param event the raw event. - * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. - * @param callback the callback to return data or null - */ - fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback) { - // is it needed to do that on the crypto scope?? - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - runCatching { - internalDecryptEvent(event, timeline) - }.foldToCallback(callback) - } - } - - /** - * Decrypt an event - * - * @param event the raw event. - * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. - * @return the MXEventDecryptionResult data, or null in case of error - */ - @Throws(MXCryptoError::class) - private fun internalDecryptEvent(event: Event, timeline: String): MXEventDecryptionResult { - val eventContent = event.content - if (eventContent == null) { - Timber.e("## CRYPTO | decryptEvent : empty event content") - throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON) - } else { - val algorithm = eventContent["algorithm"]?.toString() - val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(event.roomId, algorithm) - if (alg == null) { - val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, algorithm) - Timber.e("## CRYPTO | decryptEvent() : $reason") - throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason) - } else { - try { - return alg.decryptEvent(event, timeline) - } catch (mxCryptoError: MXCryptoError) { - Timber.v("## CRYPTO | internalDecryptEvent : Failed to decrypt ${event.eventId} reason: $mxCryptoError") - if (algorithm == MXCRYPTO_ALGORITHM_OLM) { - if (mxCryptoError is MXCryptoError.Base - && mxCryptoError.errorType == MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE) { - // need to find sending device - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - val olmContent = event.content.toModel() - cryptoStore.getUserDevices(event.senderId ?: "") - ?.values - ?.firstOrNull { it.identityKey() == olmContent?.senderKey } - ?.let { - markOlmSessionForUnwedging(event.senderId ?: "", it) - } - ?: run { - Timber.i("## CRYPTO | internalDecryptEvent() : Failed to find sender crypto device for unwedging") - } - } - } - } - throw mxCryptoError - } - } - } - } - - // coroutineDispatchers.crypto scope - private fun markOlmSessionForUnwedging(senderId: String, deviceInfo: CryptoDeviceInfo) { - val deviceKey = deviceInfo.identityKey() - - val lastForcedDate = lastNewSessionForcedDates.getObject(senderId, deviceKey) ?: 0 - val now = System.currentTimeMillis() - if (now - lastForcedDate < DefaultCryptoService.CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS) { - Timber.w("## CRYPTO | markOlmSessionForUnwedging: New session already forced with device at $lastForcedDate. Not forcing another") - return - } - - Timber.i("## CRYPTO | markOlmSessionForUnwedging from $senderId:${deviceInfo.deviceId}") - lastNewSessionForcedDates.setObject(senderId, deviceKey, now) - - // offload this from crypto thread (?) - cryptoCoroutineScope.launch(coroutineDispatchers.computation) { - val ensured = ensureOlmSessionsForDevicesAction.handle(mapOf(senderId to listOf(deviceInfo)), force = true) - - Timber.i("## CRYPTO | markOlmSessionForUnwedging() : ensureOlmSessionsForDevicesAction isEmpty:${ensured.isEmpty}") - - // Now send a blank message on that session so the other side knows about it. - // (The keyshare request is sent in the clear so that won't do) - // We send this first such that, as long as the toDevice messages arrive in the - // same order we sent them, the other end will get this first, set up the new session, - // then get the keyshare request and send the key over this new session (because it - // is the session it has most recently received a message on). - val payloadJson = mapOf("type" to EventType.DUMMY) - - val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo)) - val sendToDeviceMap = MXUsersDevicesMap() - sendToDeviceMap.setObject(senderId, deviceInfo.deviceId, encodedPayload) - Timber.i("## CRYPTO | markOlmSessionForUnwedging() : sending dummy to $senderId:${deviceInfo.deviceId}") - withContext(coroutineDispatchers.io) { - val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap) - try { - sendToDeviceTask.execute(sendToDeviceParams) - } catch (failure: Throwable) { - Timber.e(failure, "## CRYPTO | markOlmSessionForUnwedging() : failed to send dummy to $senderId:${deviceInfo.deviceId}") - } - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt index 88aa432fb3..bfc3aedfc8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/EventInsertLiveObserver.kt @@ -17,6 +17,9 @@ package org.matrix.android.sdk.internal.database import com.zhuinden.monarchy.Monarchy +import io.realm.RealmConfiguration +import io.realm.RealmResults +import kotlinx.coroutines.launch import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.database.model.EventInsertEntity @@ -24,17 +27,13 @@ import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor -import io.realm.RealmConfiguration -import io.realm.RealmResults -import kotlinx.coroutines.launch -import org.matrix.android.sdk.internal.crypto.EventDecryptor import timber.log.Timber import javax.inject.Inject -internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration, - private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>, - private val eventDecryptor: EventDecryptor) - : RealmLiveEntityObserver(realmConfiguration) { +internal class EventInsertLiveObserver @Inject constructor( + @SessionDatabase realmConfiguration: RealmConfiguration, + private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor> +) : RealmLiveEntityObserver(realmConfiguration) { override val query = Monarchy.Query { it.where(EventInsertEntity::class.java) @@ -86,23 +85,6 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real } } -// private fun decryptIfNeeded(event: Event) { -// if (event.isEncrypted() && event.mxDecryptionResult == null) { -// try { -// val result = eventDecryptor.decryptEvent(event, event.roomId ?: "") -// event.mxDecryptionResult = OlmDecryptionResult( -// payload = result.clearEvent, -// senderKey = result.senderCurve25519Key, -// keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) }, -// forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain -// ) -// } catch (e: MXCryptoError) { -// Timber.v("Failed to decrypt event") -// // TODO -> we should keep track of this and retry, or some processing will never be handled -// } -// } -// } - private fun shouldProcess(eventInsertEntity: EventInsertEntity): Boolean { return processors.any { it.shouldProcess(eventInsertEntity.eventId, eventInsertEntity.eventType, eventInsertEntity.insertType) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 7cbcfee713..77b69991cf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.room.summary import io.realm.Realm import io.realm.kotlin.createObject -import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes @@ -32,11 +31,9 @@ import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.model.VersioningState import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.send.SendState -import org.matrix.android.sdk.internal.crypto.EventDecryptor import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService import org.matrix.android.sdk.internal.database.mapper.ContentMapper -import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.database.model.EventEntityFields @@ -71,7 +68,6 @@ internal class RoomSummaryUpdater @Inject constructor( @UserId private val userId: String, private val roomDisplayNameResolver: RoomDisplayNameResolver, private val roomAvatarResolver: RoomAvatarResolver, - private val eventDecryptor: EventDecryptor, private val crossSigningService: DefaultCrossSigningService, private val roomAccountDataDataSource: RoomAccountDataDataSource) { @@ -156,15 +152,7 @@ internal class RoomSummaryUpdater @Inject constructor( } roomSummaryEntity.updateHasFailedSending() - val root = latestPreviewableEvent?.root - if (root?.type == EventType.ENCRYPTED && root.decryptionResultJson == null) { - Timber.v("Should decrypt ${latestPreviewableEvent.eventId}") - // mmm i want to decrypt now or is it ok to do it async? - tryOrNull { - eventDecryptor.decryptEvent(root.asDomain(), "") - } - ?.let { root.setDecryptionResult(it) } - } + // We do not decrypt Event anymore here, let's see if this is OK if (updateMembers) { val otherRoomMembers = RoomMemberHelper(realm, roomId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt index cbbc54e90d..315b6ea4ed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.session.room.timeline import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.internal.crypto.EventDecryptor +import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest @@ -36,7 +36,7 @@ internal interface GetEventTask : Task { internal class DefaultGetEventTask @Inject constructor( private val roomAPI: RoomAPI, private val globalErrorReceiver: GlobalErrorReceiver, - private val eventDecryptor: EventDecryptor + private val cryptoService: DefaultCryptoService ) : GetEventTask { override suspend fun execute(params: GetEventTask.Params): Event { @@ -47,7 +47,7 @@ internal class DefaultGetEventTask @Inject constructor( // Try to decrypt the Event if (event.isEncrypted()) { tryOrNull(message = "Unable to decrypt the event") { - eventDecryptor.decryptEvent(event, "") + cryptoService.decryptEvent(event, "") } ?.let { result -> event.mxDecryptionResult = OlmDecryptionResult( From 7650e43362a36899fedf03759ff8eacacef36c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Sat, 10 Jul 2021 20:48:57 +0200 Subject: [PATCH 133/252] crypto: Add support to scan QR codes during verification --- .../android/sdk/internal/crypto/OlmMachine.kt | 59 +++++++++++-------- .../internal/crypto/VerificationRequest.kt | 39 ++++++++++++ .../verification/RustVerificationService.kt | 20 +++++-- rust-sdk/Cargo.toml | 4 +- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 39 +++++++++++- rust-sdk/src/olm.udl | 8 +++ 7 files changed, 137 insertions(+), 34 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 3d555cc8e1..77ea896b26 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -160,7 +160,8 @@ internal class Device( internal class QrCodeVerification( private val machine: uniffi.olm.OlmMachine, - private var inner: QrCode, + private var request: org.matrix.android.sdk.internal.crypto.VerificationRequest, + private var inner: QrCode?, private val sender: RequestSender, private val listeners: ArrayList, ) : QrCodeVerificationTransaction { @@ -180,14 +181,17 @@ internal class QrCodeVerification( override val qrCodeText: String? get() { - val data = this.machine.generateQrCode(this.inner.otherUserId, this.inner.flowId) + val data = this.inner?.let { this.machine.generateQrCode(it.otherUserId, it.flowId) } // TODO Why are we encoding this to ISO_8859_1? If we're going to encode, why not base64? return data?.fromBase64()?.toString(Charsets.ISO_8859_1) } override fun userHasScannedOtherQrCode(otherQrCodeText: String) { - TODO("Not yet implemented") + runBlocking { + request.scanQrCode(otherQrCodeText) + } + dispatchTxUpdated() } override fun otherUserScannedMyQrCode() { @@ -203,37 +207,43 @@ internal class QrCodeVerification( override var state: VerificationTxState get() { refreshData() + val inner = this.inner - return when { - inner.isDone -> VerificationTxState.Verified - inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm - inner.otherSideScanned -> VerificationTxState.QrScannedByOther - inner.isCancelled -> { - val cancelCode = safeValueOf(inner.cancelCode) - val byMe = inner.cancelledByUs ?: false - VerificationTxState.Cancelled(cancelCode, byMe) - } - else -> { - VerificationTxState.None + return if (inner != null) { + when { + inner.isDone -> VerificationTxState.Verified + inner.reciprocated -> VerificationTxState.Started + inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm + inner.otherSideScanned -> VerificationTxState.QrScannedByOther + inner.isCancelled -> { + val cancelCode = safeValueOf(inner.cancelCode) + val byMe = inner.cancelledByUs ?: false + VerificationTxState.Cancelled(cancelCode, byMe) + } + else -> { + VerificationTxState.None + } } + } else { + VerificationTxState.None } } @Suppress("UNUSED_PARAMETER") set(value) {} override val transactionId: String - get() = this.inner.flowId + get() = this.request.flowId() override val otherUserId: String - get() = this.inner.otherUserId + get() = this.request.otherUser() override var otherDeviceId: String? - get() = this.inner.otherDeviceId + get() = this.request.otherDeviceId() @Suppress("UNUSED_PARAMETER") set(value) {} override val isIncoming: Boolean - get() = !this.inner.weStarted + get() = !this.request.weStarted() override fun cancel() { cancelHelper(CancelCode.User) @@ -244,13 +254,13 @@ internal class QrCodeVerification( } override fun isToDeviceTransport(): Boolean { - return this.inner.roomId == null + return this.request.roomId() == null } @Throws(CryptoStoreErrorException::class) suspend fun confirm(): OutgoingVerificationRequest? = withContext(Dispatchers.IO) { - machine.confirmVerification(inner.otherUserId, inner.flowId) + machine.confirmVerification(request.otherUser(), request.flowId()) } private fun sendRequest(request: OutgoingVerificationRequest) { @@ -268,7 +278,7 @@ internal class QrCodeVerification( } private fun cancelHelper(code: CancelCode) { - val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value) + val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value) if (request != null) { sendRequest(request) @@ -276,11 +286,12 @@ internal class QrCodeVerification( } private fun refreshData() { - when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { - is Verification.QrCodeV1 -> { + when (val verification = this.machine.getVerification(this.request.otherUser(), this.request.flowId())) { + is Verification.QrCodeV1 -> { this.inner = verification.qrcode } - else -> {} + else -> { + } } return diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 2dd9e6f6fa..458fabf284 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto import android.os.Handler import android.os.Looper +import com.sun.jna.Native.toByteArray import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.verification.CancelCode @@ -27,6 +28,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationI import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf +import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE @@ -76,17 +78,49 @@ internal class VerificationRequest( return this.inner.isDone } + fun flowId(): String { + return this.inner.flowId + } + + fun otherUser(): String { + return this.inner.otherUserId + } + + fun otherDeviceId(): String? { + refreshData() + return this.inner.otherDeviceId + } + + fun weStarted(): Boolean { + return this.inner.weStarted + } + + fun roomId(): String? { + return this.inner.roomId + } + fun isReady(): Boolean { refreshData() return this.inner.isReady } + internal suspend fun scanQrCode(data: String): QrCodeVerification? { + // TODO again, what's the deal with ISO_8859_1? + val byteArray = data.toByteArray(Charsets.ISO_8859_1) + val encodedData = byteArray.toBase64NoPadding() + val result = this.machine.scanQrCode(this.otherUser(), this.flowId(), encodedData) ?: return null + + this.sender.sendVerificationRequest(result.request) + return QrCodeVerification(this.machine, this, result.qr, this.sender, this.listeners) + } + internal fun startQrVerification(): QrCodeVerification? { val qrcode = this.machine.startQrVerification(this.inner.otherUserId, this.inner.flowId) return if (qrcode != null) { QrCodeVerification( this.machine, + this, qrcode, this.sender, this.listeners, @@ -125,6 +159,11 @@ internal class VerificationRequest( } } + fun canScanQrCodes(): Boolean { + refreshData() + return this.inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false + } + suspend fun startSasVerification(): SasVerification? { refreshData() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index dc59845048..ed1363c6e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -219,15 +219,27 @@ internal class RustVerificationService( otherUserId: String, tid: String, ): VerificationTransaction? { - val verification = this.olmMachine.getVerification(otherUserId, tid) ?: return null - - return when (verification) { + return when (val verification = this.olmMachine.getVerification(otherUserId, tid)) { is Verification.QrCodeV1 -> { - QrCodeVerification(this.olmMachine.inner(), verification.qrcode, this.requestSender, this.listeners) + val request = getVerificationRequest(otherUserId, tid) ?: return null + QrCodeVerification(this.olmMachine.inner(), request, verification.qrcode, this.requestSender, this.listeners) } is Verification.SasV1 -> { SasVerification(this.olmMachine.inner(), verification.sas, this.requestSender, this.listeners) } + null -> { + // This branch exists because scanning a QR code is tied to the QrCodeVerification, + // i.e. instead of branching into a scanned QR code verification from the verification request, + // like it's done for SAS verifications, the public API expects us to create an empty dummy + // QrCodeVerification object that gets populated once a QR code is scanned. + val request = getVerificationRequest(otherUserId, tid) ?: return null + + if (request.canScanQrCodes()) { + QrCodeVerification(this.olmMachine.inner(), request, null, this.requestSender, this.listeners) + } else { + null + } + } } } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 29d19c41a6..f4f9a74826 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -25,11 +25,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "c5df7c5356c2540ede95f41e3565e91ca7de5777" +rev = "b53518d1b8dd93ac447d1318c2e8aa4e2004dd2f" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "c5df7c5356c2540ede95f41e3565e91ca7de5777" +rev = "b53518d1b8dd93ac447d1318c2e8aa4e2004dd2f" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index fe02dc3ab7..7d2aef13e0 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -8,7 +8,7 @@ pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; pub use machine::{ - KeyRequestPair, OlmMachine, QrCode, RequestVerificationResult, Sas, StartSasResult, + KeyRequestPair, OlmMachine, QrCode, RequestVerificationResult, Sas, ScanResult, StartSasResult, Verification, VerificationRequest, }; pub use responses::{ diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 7b7a204357..6bacc250e8 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -4,7 +4,7 @@ use std::{ io::Cursor, }; -use base64::encode; +use base64::{decode_config, encode, STANDARD_NO_PAD}; use js_int::UInt; use ruma::{ api::{ @@ -30,8 +30,8 @@ use tokio::runtime::Runtime; use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; use matrix_sdk_crypto::{ - decrypt_key_export, encrypt_key_export, EncryptionSettings, LocalTrust, - OlmMachine as InnerMachine, QrVerification as InnerQr, Sas as InnerSas, + decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, EncryptionSettings, + LocalTrust, OlmMachine as InnerMachine, QrVerification as InnerQr, Sas as InnerSas, Verification as RustVerification, VerificationRequest as InnerVerificationRequest, }; @@ -80,6 +80,7 @@ pub struct QrCode { pub we_started: bool, pub other_side_scanned: bool, pub has_been_confirmed: bool, + pub reciprocated: bool, pub cancel_code: Option, pub cancelled_by_us: Option, } @@ -93,6 +94,7 @@ impl From for QrCode { is_done: qr.is_done(), cancel_code: qr.cancel_code().map(|c| c.to_string()), cancelled_by_us: qr.cancelled_by_us(), + reciprocated: qr.reciprocated(), we_started: qr.we_started(), other_side_scanned: qr.has_been_scanned(), has_been_confirmed: qr.has_been_confirmed(), @@ -107,6 +109,11 @@ pub struct StartSasResult { pub request: OutgoingVerificationRequest, } +pub struct ScanResult { + pub qr: QrCode, + pub request: OutgoingVerificationRequest, +} + impl From for Sas { fn from(sas: InnerSas) -> Self { Self { @@ -758,6 +765,32 @@ impl OlmMachine { }) } + pub fn scan_qr_code(&self, user_id: &str, flow_id: &str, data: &str) -> Option { + let user_id = UserId::try_from(user_id).ok()?; + // TODO create a custom error type + let data = decode_config(data, STANDARD_NO_PAD).ok()?; + let data = QrVerificationData::from_bytes(data).ok()?; + + if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { + if let Some(qr) = self + .runtime + .block_on(verification.scan_qr_code(data)) + .ok()? + { + let request = qr.reciprocate()?; + + Some(ScanResult { + qr: qr.into(), + request: request.into(), + }) + } else { + None + } + } else { + None + } + } + pub fn request_verification( &self, user_id: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 62c36f9a9a..9f02558e43 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -87,12 +87,19 @@ dictionary Sas { boolean supports_emoji; }; +dictionary ScanResult { + QrCode qr; + OutgoingVerificationRequest request; +}; + + dictionary QrCode { string other_user_id; string other_device_id; string flow_id; string? cancel_code; string? room_id; + boolean reciprocated; boolean we_started; boolean has_been_confirmed; boolean? cancelled_by_us; @@ -232,6 +239,7 @@ interface OlmMachine { 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); + ScanResult? scan_qr_code([ByRef] string user_id, [ByRef] string flow_id, [ByRef] string data); string? generate_qr_code([ByRef] string user_id, [ByRef] string flow_id); sequence? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); From b33537fd6e98a0d2551a428f0e3536b7c40d912c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 19 Jul 2021 14:21:11 +0200 Subject: [PATCH 134/252] crypto: Use the new CancelInfo struct --- .../android/sdk/internal/crypto/OlmMachine.kt | 7 ++-- .../internal/crypto/RustSasVerification.kt | 8 ++-- .../internal/crypto/VerificationRequest.kt | 7 ++-- rust-sdk/Cargo.toml | 4 +- rust-sdk/src/lib.rs | 4 +- rust-sdk/src/machine.rs | 39 ++++++++++++------- rust-sdk/src/olm.udl | 14 ++++--- 7 files changed, 50 insertions(+), 33 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 77ea896b26..365f058c00 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -208,6 +208,7 @@ internal class QrCodeVerification( get() { refreshData() val inner = this.inner + val cancelInfo = inner?.cancelInfo return if (inner != null) { when { @@ -215,9 +216,9 @@ internal class QrCodeVerification( inner.reciprocated -> VerificationTxState.Started inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm inner.otherSideScanned -> VerificationTxState.QrScannedByOther - inner.isCancelled -> { - val cancelCode = safeValueOf(inner.cancelCode) - val byMe = inner.cancelledByUs ?: false + cancelInfo != null -> { + val cancelCode = safeValueOf(cancelInfo.cancelCode) + val byMe = cancelInfo.cancelledByUs VerificationTxState.Cancelled(cancelCode, byMe) } else -> { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index 63e2e0f3a4..839bdba5f8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -82,11 +82,11 @@ internal class SasVerification( override var state: VerificationTxState get() { refreshData() + val cancelInfo = this.inner.cancelInfo return when { - this.inner.isCancelled -> { - val cancelCode = safeValueOf(this.inner.cancelCode) - val byMe = this.inner.cancelledByUs ?: false - VerificationTxState.Cancelled(cancelCode, byMe) + cancelInfo != null -> { + val cancelCode = safeValueOf(cancelInfo.cancelCode) + VerificationTxState.Cancelled(cancelCode, cancelInfo.cancelledByUs) } this.inner.isDone -> VerificationTxState.Verified this.inner.haveWeConfirmed -> VerificationTxState.ShortCodeAccepted diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 458fabf284..1adc1e8d0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -180,11 +180,10 @@ internal class VerificationRequest( fun toPendingVerificationRequest(): PendingVerificationRequest { refreshData() - val code = this.inner.cancelCode - + val cancelInfo = this.inner.cancelInfo val cancelCode = - if (code != null) { - safeValueOf(code) + if (cancelInfo != null) { + safeValueOf(cancelInfo.cancelCode) } else { null } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index f4f9a74826..66723de16a 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -25,11 +25,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "b53518d1b8dd93ac447d1318c2e8aa4e2004dd2f" +rev = "3a8ff2f6b43f312b7582146ed712ff245ef9d5aa" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "b53518d1b8dd93ac447d1318c2e8aa4e2004dd2f" +rev = "3a8ff2f6b43f312b7582146ed712ff245ef9d5aa" features = ["sled_cryptostore"] [dependencies.tokio] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 7d2aef13e0..3eb18a96b3 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -8,8 +8,8 @@ pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; pub use machine::{ - KeyRequestPair, OlmMachine, QrCode, RequestVerificationResult, Sas, ScanResult, StartSasResult, - Verification, VerificationRequest, + CancelInfo, KeyRequestPair, OlmMachine, QrCode, RequestVerificationResult, Sas, ScanResult, + StartSasResult, Verification, VerificationRequest, }; pub use responses::{ DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 6bacc250e8..72f269ddce 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -30,9 +30,10 @@ use tokio::runtime::Runtime; use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; use matrix_sdk_crypto::{ - decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, EncryptionSettings, - LocalTrust, OlmMachine as InnerMachine, QrVerification as InnerQr, Sas as InnerSas, - Verification as RustVerification, VerificationRequest as InnerVerificationRequest, + decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, + CancelInfo as RustCancelInfo, EncryptionSettings, LocalTrust, OlmMachine as InnerMachine, + QrVerification as InnerQr, Sas as InnerSas, Verification as RustVerification, + VerificationRequest as InnerVerificationRequest, }; use crate::{ @@ -61,8 +62,7 @@ pub struct Sas { pub have_we_confirmed: bool, pub is_cancelled: bool, pub is_done: bool, - pub cancel_code: Option, - pub cancelled_by_us: Option, + pub cancel_info: Option, pub has_been_accepted: bool, pub we_started: bool, pub can_be_presented: bool, @@ -81,8 +81,7 @@ pub struct QrCode { pub other_side_scanned: bool, pub has_been_confirmed: bool, pub reciprocated: bool, - pub cancel_code: Option, - pub cancelled_by_us: Option, + pub cancel_info: Option, } impl From for QrCode { @@ -92,8 +91,7 @@ impl From for QrCode { 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(), + cancel_info: qr.cancel_info().map(|c| c.into()), reciprocated: qr.reciprocated(), we_started: qr.we_started(), other_side_scanned: qr.has_been_scanned(), @@ -104,6 +102,22 @@ impl From for QrCode { } } +pub struct CancelInfo { + pub reason: String, + pub cancel_code: String, + pub cancelled_by_us: bool, +} + +impl From for CancelInfo { + fn from(c: RustCancelInfo) -> Self { + Self { + reason: c.reason().to_owned(), + cancel_code: c.cancel_code().to_string(), + cancelled_by_us: c.cancelled_by_us(), + } + } +} + pub struct StartSasResult { pub sas: Sas, pub request: OutgoingVerificationRequest, @@ -126,11 +140,10 @@ impl From for Sas { timed_out: sas.timed_out(), supports_emoji: sas.supports_emoji(), have_we_confirmed: sas.have_we_confirmed(), - cancel_code: sas.cancel_code().map(|c| c.as_str().to_owned()), we_started: sas.we_started(), room_id: sas.room_id().map(|r| r.to_string()), - cancelled_by_us: sas.cancelled_by_us(), has_been_accepted: sas.has_been_accepted(), + cancel_info: sas.cancel_info().map(|c| c.into()), } } } @@ -148,11 +161,11 @@ pub struct VerificationRequest { pub is_done: bool, pub is_ready: bool, pub room_id: Option, - pub cancel_code: Option, pub we_started: bool, pub is_passive: bool, pub their_methods: Option>, pub our_methods: Option>, + pub cancel_info: Option, } impl From for VerificationRequest { @@ -165,9 +178,9 @@ impl From for VerificationRequest { is_done: v.is_done(), is_ready: v.is_ready(), room_id: v.room_id().map(|r| r.to_string()), - cancel_code: v.cancel_code().map(|c| c.as_str().to_owned()), we_started: v.we_started(), is_passive: v.is_passive(), + cancel_info: v.cancel_info().map(|c| c.into()), their_methods: v .their_supported_methods() .map(|v| v.into_iter().map(|m| m.to_string()).collect()), diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 9f02558e43..ac4618b22d 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -65,6 +65,12 @@ dictionary Device { boolean cross_signing_trusted; }; +dictionary CancelInfo { + string cancel_code; + string reason; + boolean cancelled_by_us; +}; + dictionary StartSasResult { Sas sas; OutgoingVerificationRequest request; @@ -74,10 +80,8 @@ dictionary Sas { 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 has_been_accepted; boolean have_we_confirmed; boolean is_done; @@ -85,6 +89,7 @@ dictionary Sas { boolean can_be_presented; boolean timed_out; boolean supports_emoji; + CancelInfo? cancel_info; }; dictionary ScanResult { @@ -97,15 +102,14 @@ dictionary QrCode { string other_user_id; string other_device_id; string flow_id; - string? cancel_code; string? room_id; boolean reciprocated; boolean we_started; boolean has_been_confirmed; - boolean? cancelled_by_us; boolean is_done; boolean is_cancelled; boolean other_side_scanned; + CancelInfo? cancel_info; }; dictionary VerificationRequest { @@ -118,7 +122,7 @@ dictionary VerificationRequest { boolean we_started; boolean is_passive; string? room_id; - string? cancel_code; + CancelInfo? cancel_info; sequence? their_methods; sequence? our_methods; From eae2a51a2d6fea1b2478d7654a7492ad6fe0ea5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Jul 2021 14:30:34 +0200 Subject: [PATCH 135/252] crypto: Refactor and document the QR code verification class --- .../android/sdk/internal/crypto/OlmMachine.kt | 150 ------------- .../sdk/internal/crypto/QrCodeVerification.kt | 198 ++++++++++++++++++ 2 files changed, 198 insertions(+), 150 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 365f058c00..91a0e35ac0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -16,8 +16,6 @@ package org.matrix.android.sdk.internal.crypto -import android.os.Handler -import android.os.Looper import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import java.io.File @@ -28,16 +26,11 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext 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.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationService -import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf 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.util.JsonDict import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 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 @@ -53,8 +46,6 @@ import uniffi.olm.Device as InnerDevice import uniffi.olm.DeviceLists import uniffi.olm.KeyRequestPair import uniffi.olm.Logger -import uniffi.olm.OutgoingVerificationRequest -import uniffi.olm.QrCode import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request @@ -158,147 +149,6 @@ internal class Device( } } -internal class QrCodeVerification( - private val machine: uniffi.olm.OlmMachine, - private var request: org.matrix.android.sdk.internal.crypto.VerificationRequest, - private var inner: QrCode?, - private val sender: RequestSender, - private val listeners: ArrayList, -) : QrCodeVerificationTransaction { - private val uiHandler = Handler(Looper.getMainLooper()) - - private fun dispatchTxUpdated() { - uiHandler.post { - listeners.forEach { - try { - it.transactionUpdated(this) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } - - override val qrCodeText: String? - get() { - val data = this.inner?.let { this.machine.generateQrCode(it.otherUserId, it.flowId) } - - // TODO Why are we encoding this to ISO_8859_1? If we're going to encode, why not base64? - return data?.fromBase64()?.toString(Charsets.ISO_8859_1) - } - - override fun userHasScannedOtherQrCode(otherQrCodeText: String) { - runBlocking { - request.scanQrCode(otherQrCodeText) - } - dispatchTxUpdated() - } - - override fun otherUserScannedMyQrCode() { - val request = runBlocking { confirm() } ?: return - sendRequest(request) - } - - override fun otherUserDidNotScannedMyQrCode() { - // TODO Is this code correct here? The old code seems to do this - cancelHelper(CancelCode.MismatchedKeys) - } - - override var state: VerificationTxState - get() { - refreshData() - val inner = this.inner - val cancelInfo = inner?.cancelInfo - - return if (inner != null) { - when { - inner.isDone -> VerificationTxState.Verified - inner.reciprocated -> VerificationTxState.Started - inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm - inner.otherSideScanned -> VerificationTxState.QrScannedByOther - cancelInfo != null -> { - val cancelCode = safeValueOf(cancelInfo.cancelCode) - val byMe = cancelInfo.cancelledByUs - VerificationTxState.Cancelled(cancelCode, byMe) - } - else -> { - VerificationTxState.None - } - } - } else { - VerificationTxState.None - } - } - @Suppress("UNUSED_PARAMETER") - set(value) {} - - override val transactionId: String - get() = this.request.flowId() - - override val otherUserId: String - get() = this.request.otherUser() - - override var otherDeviceId: String? - get() = this.request.otherDeviceId() - @Suppress("UNUSED_PARAMETER") - set(value) {} - - override val isIncoming: Boolean - get() = !this.request.weStarted() - - override fun cancel() { - cancelHelper(CancelCode.User) - } - - override fun cancel(code: CancelCode) { - cancelHelper(code) - } - - override fun isToDeviceTransport(): Boolean { - return this.request.roomId() == null - } - - @Throws(CryptoStoreErrorException::class) - suspend fun confirm(): OutgoingVerificationRequest? = - withContext(Dispatchers.IO) { - machine.confirmVerification(request.otherUser(), request.flowId()) - } - - private fun sendRequest(request: OutgoingVerificationRequest) { - runBlocking { - when (request) { - is OutgoingVerificationRequest.ToDevice -> { - sender.sendToDevice(request) - } - is OutgoingVerificationRequest.InRoom -> TODO() - } - } - - refreshData() - dispatchTxUpdated() - } - - private fun cancelHelper(code: CancelCode) { - val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value) - - if (request != null) { - sendRequest(request) - } - } - - private fun refreshData() { - when (val verification = this.machine.getVerification(this.request.otherUser(), this.request.flowId())) { - is Verification.QrCodeV1 -> { - this.inner = verification.qrcode - } - else -> { - } - } - - return - } -} - internal class OlmMachine( user_id: String, device_id: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt new file mode 100644 index 0000000000..209f060e0a --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto + +import android.os.Handler +import android.os.Looper +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.verification.CancelCode +import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState +import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf +import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 +import timber.log.Timber +import uniffi.olm.CryptoStoreErrorException +import uniffi.olm.OlmMachine +import uniffi.olm.OutgoingVerificationRequest +import uniffi.olm.QrCode +import uniffi.olm.Verification + +internal class QrCodeVerification( + private val machine: OlmMachine, + private var request: VerificationRequest, + private var inner: QrCode?, + private val sender: RequestSender, + private val listeners: ArrayList, +) : QrCodeVerificationTransaction { + private val uiHandler = Handler(Looper.getMainLooper()) + + private fun dispatchTxUpdated() { + uiHandler.post { + listeners.forEach { + try { + it.transactionUpdated(this) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + /** Generate, if possible, data that should be encoded as a QR code for QR code verification. + * + * QR code verification can't verify devices between two users, so in the case that + * we're verifying another user and we don't have or trust our cross signing identity + * no QR code will be generated. + */ + override val qrCodeText: String? + get() { + val data = this.inner?.let { this.machine.generateQrCode(it.otherUserId, it.flowId) } + + // TODO Why are we encoding this to ISO_8859_1? If we're going to encode, why not base64? + return data?.fromBase64()?.toString(Charsets.ISO_8859_1) + } + + /** Pass the data from a scanned QR code into the QR code verification object */ + override fun userHasScannedOtherQrCode(otherQrCodeText: String) { + runBlocking { + request.scanQrCode(otherQrCodeText) + } + dispatchTxUpdated() + } + + /** Confirm that the other side has indeed scanned the QR code we presented */ + override fun otherUserScannedMyQrCode() { + runBlocking { confirm() } + } + + /** Cancel the QR code verification, denying that the other side has scanned the QR code */ + override fun otherUserDidNotScannedMyQrCode() { + // TODO Is this code correct here? The old code seems to do this + cancelHelper(CancelCode.MismatchedKeys) + } + + override var state: VerificationTxState + get() { + refreshData() + val inner = this.inner + val cancelInfo = inner?.cancelInfo + + return if (inner != null) { + when { + cancelInfo != null -> { + val cancelCode = safeValueOf(cancelInfo.cancelCode) + val byMe = cancelInfo.cancelledByUs + VerificationTxState.Cancelled(cancelCode, byMe) + } + inner.isDone -> VerificationTxState.Verified + inner.reciprocated -> VerificationTxState.Started + inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm + inner.otherSideScanned -> VerificationTxState.QrScannedByOther + else -> { + VerificationTxState.None + } + } + } else { + VerificationTxState.None + } + } + @Suppress("UNUSED_PARAMETER") + set(value) { + } + + /** Get the unique id of this verification */ + override val transactionId: String + get() = this.request.flowId() + + /** Get the user id of the other user participating in this verification flow */ + override val otherUserId: String + get() = this.request.otherUser() + + /** Get the device id of the other user's device participating in this verification flow */ + override var otherDeviceId: String? + get() = this.request.otherDeviceId() + @Suppress("UNUSED_PARAMETER") + set(value) { + } + + /** Did the other side initiate this verification flow */ + override val isIncoming: Boolean + get() = !this.request.weStarted() + + /** Cancel the verification flow */ + override fun cancel() { + cancelHelper(CancelCode.User) + } + + /** Cancel the verification with the given cancel code */ + override fun cancel(code: CancelCode) { + cancelHelper(code) + } + + /** Is this verification happening over to-device messages */ + override fun isToDeviceTransport(): Boolean { + return this.request.roomId() == null + } + + /** Confirm the QR code verification + * + * This confirms that the other side has scanned our QR code. + */ + @Throws(CryptoStoreErrorException::class) + suspend fun confirm() { + val request = withContext(Dispatchers.IO) + { + machine.confirmVerification(request.otherUser(), request.flowId()) + } + + if (request != null) { + this.sender.sendVerificationRequest(request) + } + } + + /** Send out a verification request in a blocking manner*/ + private fun sendRequest(request: OutgoingVerificationRequest) { + runBlocking { sender.sendVerificationRequest(request) } + + refreshData() + dispatchTxUpdated() + } + + private fun cancelHelper(code: CancelCode) { + val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value) + + if (request != null) { + sendRequest(request) + } + } + + /** Fetch fetch data from the Rust side for our verification flow */ + private fun refreshData() { + when (val verification = this.machine.getVerification(this.request.otherUser(), this.request.flowId())) { + is Verification.QrCodeV1 -> { + this.inner = verification.qrcode + } + else -> { + } + } + + return + } +} From 2097f4e6c228f71ec13223fe000fa0a9dee67980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Jul 2021 16:34:47 +0200 Subject: [PATCH 136/252] crypto: Document the verification methods in the OlmMachine --- .../android/sdk/internal/crypto/OlmMachine.kt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 91a0e35ac0..3a9d12ce12 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -526,6 +526,11 @@ internal class OlmMachine( return plainDevices } + /** Mark the device for the given user with the given device ID as trusted + * + * This will mark the device locally as trusted, it won't upload any type of cross + * signing signature + * */ @Throws(CryptoStoreErrorException::class) internal suspend fun markDeviceAsTrusted(userId: String, deviceId: String) = withContext(Dispatchers.IO) { @@ -564,15 +569,26 @@ internal class OlmMachine( runBlocking { inner.discardRoomKey(roomId) } } + /** Get all the verification requests we have with the given user + * + * @param userId The ID of the user for which we would like to fetch the + * verification requests + * + * @return The list of VerificationRequests that we share with the given user + */ fun getVerificationRequests(userId: String): List { return this.inner.getVerificationRequests(userId) } + /** Get a verification request for the given user with the given flow ID */ fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? { return this.inner.getVerificationRequest(userId, flowId) } - /** Get an active verification */ + /** Get an active verification for the given user and given flow ID + * + * This can return a SAS verification or a QR code verification + */ fun getVerification(userId: String, flowId: String): Verification? { return this.inner.getVerification(userId, flowId) } From 93f36db43c7527532ab426c6f040fe83e19ca3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 20 Jul 2021 16:35:50 +0200 Subject: [PATCH 137/252] crypto: Add proper scopes to our verification methods --- .../sdk/internal/crypto/QrCodeVerification.kt | 18 +-- .../internal/crypto/RustSasVerification.kt | 80 ++++++------- .../internal/crypto/VerificationRequest.kt | 111 ++++++++---------- .../verification/RustVerificationService.kt | 39 +++--- 4 files changed, 117 insertions(+), 131 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index 209f060e0a..00d00bed5e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -156,7 +156,7 @@ internal class QrCodeVerification( * This confirms that the other side has scanned our QR code. */ @Throws(CryptoStoreErrorException::class) - suspend fun confirm() { + private suspend fun confirm() { val request = withContext(Dispatchers.IO) { machine.confirmVerification(request.otherUser(), request.flowId()) @@ -167,14 +167,6 @@ internal class QrCodeVerification( } } - /** Send out a verification request in a blocking manner*/ - private fun sendRequest(request: OutgoingVerificationRequest) { - runBlocking { sender.sendVerificationRequest(request) } - - refreshData() - dispatchTxUpdated() - } - private fun cancelHelper(code: CancelCode) { val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value) @@ -183,6 +175,14 @@ internal class QrCodeVerification( } } + /** Send out a verification request in a blocking manner*/ + private fun sendRequest(request: OutgoingVerificationRequest) { + runBlocking { sender.sendVerificationRequest(request) } + + refreshData() + dispatchTxUpdated() + } + /** Fetch fetch data from the Rust side for our verification flow */ private fun refreshData() { when (val verification = this.machine.getVerification(this.request.otherUser(), this.request.flowId())) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt index 839bdba5f8..4080a3355e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt @@ -56,18 +56,6 @@ internal class SasVerification( } } - private fun refreshData() { - when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { - is Verification.SasV1 -> { - this.inner = verification.sas - } - else -> { - } - } - - return - } - override val isIncoming: Boolean get() = !this.inner.weStarted @@ -84,7 +72,7 @@ internal class SasVerification( refreshData() val cancelInfo = this.inner.cancelInfo return when { - cancelInfo != null -> { + cancelInfo != null -> { val cancelCode = safeValueOf(cancelInfo.cancelCode) VerificationTxState.Cancelled(cancelCode, cancelInfo.cancelledByUs) } @@ -118,9 +106,8 @@ internal class SasVerification( override fun supportsDecimal(): Boolean { // 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 + // The spec also mandates that devices support at least decimal and + // the rust-sdk cancels if devices don't support it return true } @@ -130,15 +117,26 @@ internal class SasVerification( } override fun userHasVerifiedShortCode() { - val request = runBlocking { confirm() } ?: return - sendRequest(request) + runBlocking { confirm() } } override fun acceptVerification() { runBlocking { accept() } } - suspend fun accept() { + override fun getDecimalCodeRepresentation(): String { + val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId) + + return decimals?.joinToString(" ") ?: "" + } + + override fun getEmojiCodeRepresentation(): List { + val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId) + + return emojiIndex?.map { getEmojiForCode(it) } ?: listOf() + } + + internal suspend fun accept() { val request = this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId) if (request != null) { @@ -149,12 +147,16 @@ internal class SasVerification( } @Throws(CryptoStoreErrorException::class) - suspend fun confirm(): OutgoingVerificationRequest? = - withContext(Dispatchers.IO) { - machine.confirmVerification(inner.otherUserId, inner.flowId) - } + private suspend fun confirm() { + val request = withContext(Dispatchers.IO) { + machine.confirmVerification(inner.otherUserId, inner.flowId) + } + if (request != null) { + this.sender.sendVerificationRequest(request) + } + } - fun cancelHelper(code: CancelCode) { + private fun cancelHelper(code: CancelCode) { val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value) if (request != null) { @@ -162,24 +164,22 @@ internal class SasVerification( } } - override fun getEmojiCodeRepresentation(): List { - val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId) - - return emojiIndex?.map { getEmojiForCode(it) } ?: listOf() - } - - override fun getDecimalCodeRepresentation(): String { - val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId) - - return decimals?.joinToString(" ") ?: "" - } - - fun sendRequest(request: OutgoingVerificationRequest) { - runBlocking { - sender.sendVerificationRequest(request) - } + private fun sendRequest(request: OutgoingVerificationRequest) { + runBlocking { sender.sendVerificationRequest(request) } refreshData() dispatchTxUpdated() } + + private fun refreshData() { + when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { + is Verification.SasV1 -> { + this.inner = verification.sas + } + else -> { + } + } + + return + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 1adc1e8d0f..5e531ec428 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -34,6 +34,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS import org.matrix.android.sdk.internal.crypto.model.rest.toValue +import org.matrix.android.sdk.internal.crypto.verification.prepareMethods import timber.log.Timber import uniffi.olm.OlmMachine import uniffi.olm.VerificationRequest @@ -46,16 +47,6 @@ internal class VerificationRequest( ) { private val uiHandler = Handler(Looper.getMainLooper()) - private fun refreshData() { - val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) - - if (request != null) { - this.inner = request - } - - return - } - internal fun dispatchRequestUpdated() { uiHandler.post { listeners.forEach { @@ -68,42 +59,65 @@ internal class VerificationRequest( } } - fun isCanceled(): Boolean { - refreshData() - return this.inner.isCancelled - } - - fun isDone(): Boolean { - refreshData() - return this.inner.isDone - } - - fun flowId(): String { + internal fun flowId(): String { return this.inner.flowId } - fun otherUser(): String { + internal fun otherUser(): String { return this.inner.otherUserId } - fun otherDeviceId(): String? { + internal fun otherDeviceId(): String? { refreshData() return this.inner.otherDeviceId } - fun weStarted(): Boolean { + internal fun weStarted(): Boolean { return this.inner.weStarted } - fun roomId(): String? { + internal fun roomId(): String? { return this.inner.roomId } - fun isReady(): Boolean { + internal fun isReady(): Boolean { refreshData() return this.inner.isReady } + internal fun canScanQrCodes(): Boolean { + refreshData() + return this.inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false + } + + suspend fun acceptWithMethods(methods: List) { + val stringMethods = prepareMethods(methods) + + val request = this.machine.acceptVerificationRequest( + this.inner.otherUserId, + this.inner.flowId, + stringMethods + ) + + if (request != null) { + this.sender.sendVerificationRequest(request) + this.dispatchRequestUpdated() + } + } + + internal suspend fun startSasVerification(): SasVerification? { + return withContext(Dispatchers.IO) { + val result = machine.startSasVerification(inner.otherUserId, inner.flowId) + + if (result != null) { + sender.sendVerificationRequest(result.request) + SasVerification(machine, result.sas, sender, listeners) + } else { + null + } + } + } + internal suspend fun scanQrCode(data: String): QrCodeVerification? { // TODO again, what's the deal with ISO_8859_1? val byteArray = data.toByteArray(Charsets.ISO_8859_1) @@ -130,18 +144,11 @@ internal class VerificationRequest( } } - suspend fun acceptWithMethods(methods: List) { - val stringMethods: MutableList = methods.map { it.toValue() }.toMutableList() - - if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || - stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { - stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) - } - - val request = this.machine.acceptVerificationRequest( - this.inner.otherUserId, - this.inner.flowId, - stringMethods + internal suspend fun cancel() { + val request = this.machine.cancelVerification( + this.inner.otherUserId, + this.inner.flowId, + CancelCode.User.value ) if (request != null) { @@ -150,35 +157,15 @@ internal class VerificationRequest( } } - suspend fun cancel() { - val request = this.machine.cancelVerification(this.inner.otherUserId, this.inner.flowId, CancelCode.User.value) + private fun refreshData() { + val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) if (request != null) { - this.sender.sendVerificationRequest(request) - this.dispatchRequestUpdated() + this.inner = request } } - fun canScanQrCodes(): Boolean { - refreshData() - return this.inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false - } - - suspend fun startSasVerification(): SasVerification? { - refreshData() - - return withContext(Dispatchers.IO) { - val result = machine.startSasVerification(inner.otherUserId, inner.flowId) - if (result != null) { - sender.sendVerificationRequest(result.request) - SasVerification(machine, result.sas, sender, listeners) - } else { - null - } - } - } - - fun toPendingVerificationRequest(): PendingVerificationRequest { + internal fun toPendingVerificationRequest(): PendingVerificationRequest { refreshData() val cancelInfo = this.inner.cancelInfo val cancelCode = diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index ed1363c6e1..2a11b6f540 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -46,7 +46,7 @@ import timber.log.Timber import uniffi.olm.Verification @JsonClass(generateAdapter = true) -data class ToDeviceVerificationEvent( +internal data class ToDeviceVerificationEvent( @Json(name = "sender") val sender: String?, @Json(name = "transaction_id") val transactionId: String, ) @@ -61,6 +61,17 @@ private fun getFlowId(event: Event): String? { } } +internal fun prepareMethods(methods: List): List { + val stringMethods: MutableList = methods.map { it.toValue() }.toMutableList() + + if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || + stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { + stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) + } + + return stringMethods +} + internal class RustVerificationService( private val olmMachine: OlmMachine, private val requestSender: RequestSender, @@ -117,7 +128,7 @@ internal class RustVerificationService( } } - suspend fun onEvent(event: Event) = when (event.getClearType()) { + internal suspend fun onEvent(event: Event) = when (event.getClearType()) { MessageType.MSGTYPE_VERIFICATION_REQUEST -> onRequest(event) EventType.KEY_VERIFICATION_START -> onStart(event) EventType.KEY_VERIFICATION_READY, @@ -148,11 +159,11 @@ internal class RustVerificationService( if (request != null && request.isReady()) { // If this is a SAS verification originating from a `m.key.verification.request` - // event we auto-accept here considering that we either initiated the request or - // accepted the request, otherwise it's a QR code verification, just dispatch an update. + // event, we auto-accept here considering that we either initiated the request or + // accepted the request. If it's a QR code verification, just dispatch an update. if (verification is SasVerification) { // Accept dispatches an update, no need to do it twice. - Timber.d("## Verification: Auto accepting SAS verification with $sender") + Timber.d("## Verification: Auto accepting SAS verification with $sender") verification.accept() } else { dispatchTxUpdated(verification) @@ -227,7 +238,7 @@ internal class RustVerificationService( is Verification.SasV1 -> { SasVerification(this.olmMachine.inner(), verification.sas, this.requestSender, this.listeners) } - null -> { + null -> { // This branch exists because scanning a QR code is tied to the QrCodeVerification, // i.e. instead of branching into a scanned QR code verification from the verification request, // like it's done for SAS verifications, the public API expects us to create an empty dummy @@ -296,12 +307,7 @@ internal class RustVerificationService( otherUserId: String, otherDevices: List? ): PendingVerificationRequest { - - val stringMethods: MutableList = methods.map { it.toValue() }.toMutableList() - if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || - stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { - stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) - } + val stringMethods = prepareMethods(methods) val result = this.olmMachine.inner().requestSelfVerification(stringMethods) runBlocking { @@ -318,13 +324,7 @@ internal class RustVerificationService( localId: String? ): PendingVerificationRequest { Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") - val stringMethods: MutableList = methods.map { it.toValue() }.toMutableList() - - if (stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SHOW) || - stringMethods.contains(VERIFICATION_METHOD_QR_CODE_SCAN)) { - stringMethods.add(VERIFICATION_METHOD_RECIPROCATE) - } - + val stringMethods = prepareMethods(methods) val content = this.olmMachine.inner().verificationRequestContent(otherUserId, stringMethods)!! val eventID = runBlocking { @@ -376,7 +376,6 @@ internal class RustVerificationService( otherDeviceId: String, transactionId: String? ): String? { - // should check if already one (and cancel it) return if (method == VerificationMethod.SAS) { if (transactionId != null) { val request = this.getVerificationRequest(otherUserId, transactionId) From b500364322cef3e0b936f720c06475ef3ed57ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 21 Jul 2021 12:10:18 +0200 Subject: [PATCH 138/252] crypto: Expand the docs for the QrCodeVerification class a bit --- .../sdk/internal/crypto/QrCodeVerification.kt | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index 00d00bed5e..73fdba28c5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -60,6 +60,12 @@ internal class QrCodeVerification( * QR code verification can't verify devices between two users, so in the case that * we're verifying another user and we don't have or trust our cross signing identity * no QR code will be generated. + * + * @return A ISO_8859_1 encoded string containing data that should be encoded as a QR code. + * The string contains data as specified in the [QR code format] part of the Matrix spec. + * The list of bytes as defined in the spec are then encoded using ISO_8859_1 to get a string. + * + * [QR code format]: https://spec.matrix.org/unstable/client-server-api/#qr-code-format */ override val qrCodeText: String? get() { @@ -136,12 +142,30 @@ internal class QrCodeVerification( override val isIncoming: Boolean get() = !this.request.weStarted() - /** Cancel the verification flow */ + /** Cancel the verification flow + * + * This will send out a m.key.verification.cancel event with the cancel + * code set to m.user. + * + * Cancelling the verification request will also cancel the parent VerificationRequest. + * + * The method turns into a noop, if the verification flow has already been cancelled. + * */ override fun cancel() { cancelHelper(CancelCode.User) } - /** Cancel the verification with the given cancel code */ + /** Cancel the verification flow + * + * This will send out a m.key.verification.cancel event with the cancel + * code set to the given CancelCode. + * + * Cancelling the verification request will also cancel the parent VerificationRequest. + * + * The method turns into a noop, if the verification flow has already been cancelled. + * + * @param code The cancel code that should be given as the reason for the cancellation. + * */ override fun cancel(code: CancelCode) { cancelHelper(code) } @@ -153,7 +177,11 @@ internal class QrCodeVerification( /** Confirm the QR code verification * - * This confirms that the other side has scanned our QR code. + * This confirms that the other side has scanned our QR code and sends + * out a m.key.verification.done event to the other side. + * + * The method turns into a noop if we're not yet ready to confirm the scanning, + * i.e. we didn't yet receive a m.key.verification.start event from the other side. */ @Throws(CryptoStoreErrorException::class) private suspend fun confirm() { @@ -175,7 +203,7 @@ internal class QrCodeVerification( } } - /** Send out a verification request in a blocking manner*/ + /** Send out a verification request in a blocking manner */ private fun sendRequest(request: OutgoingVerificationRequest) { runBlocking { sender.sendVerificationRequest(request) } @@ -183,7 +211,7 @@ internal class QrCodeVerification( dispatchTxUpdated() } - /** Fetch fetch data from the Rust side for our verification flow */ + /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { when (val verification = this.machine.getVerification(this.request.otherUser(), this.request.flowId())) { is Verification.QrCodeV1 -> { From 93615ddba9d45e08b9cbda4781cfcdee646b70d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 21 Jul 2021 12:11:11 +0200 Subject: [PATCH 139/252] crypto: Add docs to the VerificationRequest class --- .../internal/crypto/VerificationRequest.kt | 105 +++++++++++++++++- 1 file changed, 100 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 5e531ec428..540b429db1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.crypto import android.os.Handler import android.os.Looper -import com.sun.jna.Native.toByteArray import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.verification.CancelCode @@ -30,10 +29,6 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE -import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS -import org.matrix.android.sdk.internal.crypto.model.rest.toValue import org.matrix.android.sdk.internal.crypto.verification.prepareMethods import timber.log.Timber import uniffi.olm.OlmMachine @@ -59,37 +54,74 @@ internal class VerificationRequest( } } + /** Get the flow ID of this verification request + * + * This is either the transaction ID if the verification is happening + * over to-device events, or the event ID of the m.key.verification.request + * event that initiated the flow. + */ internal fun flowId(): String { return this.inner.flowId } + /** The user ID of the other user that is participating in this verification flow */ internal fun otherUser(): String { return this.inner.otherUserId } + /** The device ID of the other user's device that is participating in this verification flow + * + * This will we null if we're initiating the request and the other side + * didn't yet accept the verification flow. + * */ internal fun otherDeviceId(): String? { refreshData() return this.inner.otherDeviceId } + /** Did we initiate this verification flow */ internal fun weStarted(): Boolean { return this.inner.weStarted } + /** Get the id of the room where this verification is happening + * + * Will be null if the verification is not happening inside a room. + */ internal fun roomId(): String? { return this.inner.roomId } + /** Did the non-initiating side respond with a m.key.verification.read event + * + * Once the verification request is ready, we're able to transition into a + * concrete verification flow, i.e. we can show/scan a QR code or start emoji + * verification. + */ internal fun isReady(): Boolean { refreshData() return this.inner.isReady } + /** Did we advertise that we're able to scan QR codes */ internal fun canScanQrCodes(): Boolean { refreshData() return this.inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false } + /** Accept the verification request advertising the given methods as supported + * + * This will send out a m.key.verification.ready event advertising support for + * the given verification methods to the other side. After this method call, the + * verification request will be considered to be ready and will be able to transition + * into concrete verification flows. + * + * The method turns into a noop, if the verification flow has already been accepted + * and is in the ready state, which can be checked with the isRead() method. + * + * @param methods The list of VerificationMethod that we wish to advertise to the other + * side as supported. + */ suspend fun acceptWithMethods(methods: List) { val stringMethods = prepareMethods(methods) @@ -105,6 +137,19 @@ internal class VerificationRequest( } } + /** Transition from a ready verification request into emoji verification + * + * This method will move the verification forward into emoji verification, + * it will send out a m.key.verification.start event with the method set to + * m.sas.v1. + * + * Note: This method will be a noop and return null if the verification request + * isn't considered to be ready, you can check if the request is ready using the + * isReady() method. + * + * @return A freshly created SasVerification object that represents the newly started + * emoji verification, or null if we can't yet transition into emoji verification. + */ internal suspend fun startSasVerification(): SasVerification? { return withContext(Dispatchers.IO) { val result = machine.startSasVerification(inner.otherUserId, inner.flowId) @@ -118,6 +163,19 @@ internal class VerificationRequest( } } + /** Scan a QR code and transition into QR code verification + * + * This method will move the verification forward into QR code verification. + * It will send out a m.key.verification.start event with the method + * set to m.reciprocate.v1. + * + * Note: This method will be a noop and return null if the verification request + * isn't considered to be ready, you can check if the request is ready using the + * isReady() method. + * + * @return A freshly created QrCodeVerification object that represents the newly started + * QR code verification, or null if we can't yet transition into QR code verification. + */ internal suspend fun scanQrCode(data: String): QrCodeVerification? { // TODO again, what's the deal with ISO_8859_1? val byteArray = data.toByteArray(Charsets.ISO_8859_1) @@ -128,6 +186,23 @@ internal class VerificationRequest( return QrCodeVerification(this.machine, this, result.qr, this.sender, this.listeners) } + /** Transition into a QR code verification to display a QR code + * + * This method will move the verification forward into QR code verification. + * It will not send out any event out, it should instead be used to display + * a QR code which then can be scanned out of bound by the other side. + * + * A m.key.verification.start event with the method set to m.reciprocate.v1 + * incoming from the other side will only be accepted if this method is called + * and the QR code verification is successfully initiated. + * + * Note: This method will be a noop and return null if the verification request + * isn't considered to be ready, you can check if the request is ready using the + * isReady() method. + * + * @return A freshly created QrCodeVerification object that represents the newly started + * QR code verification, or null if we can't yet transition into QR code verification. + */ internal fun startQrVerification(): QrCodeVerification? { val qrcode = this.machine.startQrVerification(this.inner.otherUserId, this.inner.flowId) @@ -144,6 +219,16 @@ internal class VerificationRequest( } } + /** Cancel the verification flow + * + * This will send out a m.key.verification.cancel event with the cancel + * code set to m.user. + * + * Cancelling the verification request will also cancel any QrcodeVerification and + * SasVerification objects that are related to this verification request. + * + * The method turns into a noop, if the verification flow has already been cancelled. + */ internal suspend fun cancel() { val request = this.machine.cancelVerification( this.inner.otherUserId, @@ -157,6 +242,7 @@ internal class VerificationRequest( } } + /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) @@ -165,6 +251,15 @@ internal class VerificationRequest( } } + /** Convert the VerificationRequest into a PendingVerificationRequest + * + * The public interface of the VerificationService dispatches the data class + * PendingVerificationRequest, this method allows us to easily transform this + * request into the data class. It fetches fresh info from the Rust side before + * it does the transform. + * + * @return The PendingVerificationRequest that matches data from this VerificationRequest. + */ internal fun toPendingVerificationRequest(): PendingVerificationRequest { refreshData() val cancelInfo = this.inner.cancelInfo From 8089e972a573077839c45f59c5827eaebd6c6b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 21 Jul 2021 14:58:12 +0200 Subject: [PATCH 140/252] cyrpto: Document the SasVerification class --- .../sdk/internal/crypto/QrCodeVerification.kt | 7 +- ...tSasVerification.kt => SasVerification.kt} | 78 ++++++++++++++++++- 2 files changed, 81 insertions(+), 4 deletions(-) rename matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/{RustSasVerification.kt => SasVerification.kt} (64%) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index 73fdba28c5..14bd4e3870 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -203,7 +203,12 @@ internal class QrCodeVerification( } } - /** Send out a verification request in a blocking manner */ + /** Send out a verification request in a blocking manner + * + * This is useful since the public methods to accept/confirm/cancel the verification + * aren't suspendable but sending a request out obviously should be. This bridges the + * gap between our suspendable and non-suspendable methods. + */ private fun sendRequest(request: OutgoingVerificationRequest) { runBlocking { sender.sendVerificationRequest(request) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt similarity index 64% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index 4080a3355e..251f56eaae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustSasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -56,16 +56,19 @@ internal class SasVerification( } } - override val isIncoming: Boolean - get() = !this.inner.weStarted + /** The user ID of the other user that is participating in this verification flow */ + override val otherUserId: String = this.inner.otherUserId + /** Get the device id of the other user's device participating in this verification flow */ override var otherDeviceId: String? get() = this.inner.otherDeviceId @Suppress("UNUSED_PARAMETER") set(value) { } - override val otherUserId: String = this.inner.otherUserId + /** Did the other side initiate this verification flow */ + override val isIncoming: Boolean + get() = !this.inner.weStarted override var state: VerificationTxState get() { @@ -87,23 +90,55 @@ internal class SasVerification( set(v) { } + /** Get the unique id of this verification */ override val transactionId: String get() = this.inner.flowId + /** Cancel the verification flow + * + * This will send out a m.key.verification.cancel event with the cancel + * code set to m.user. + * + * Cancelling the verification request will also cancel the parent VerificationRequest. + * + * The method turns into a noop, if the verification flow has already been cancelled. + * */ override fun cancel() { this.cancelHelper(CancelCode.User) } + /** Cancel the verification flow + * + * This will send out a m.key.verification.cancel event with the cancel + * code set to the given CancelCode. + * + * Cancelling the verification request will also cancel the parent VerificationRequest. + * + * The method turns into a noop, if the verification flow has already been cancelled. + * + * @param code The cancel code that should be given as the reason for the cancellation. + * */ override fun cancel(code: CancelCode) { this.cancelHelper(code) } + /** Cancel the verification flow + * + * This will send out a m.key.verification.cancel event with the cancel + * code set to the m.mismatched_sas cancel code. + * + * Cancelling the verification request will also cancel the parent VerificationRequest. + * + * The method turns into a noop, if the verification flow has already been cancelled. + */ override fun shortCodeDoesNotMatch() { this.cancelHelper(CancelCode.MismatchedSas) } + /** Is this verification happening over to-device messages */ override fun isToDeviceTransport(): Boolean = this.inner.roomId == null + /** Does the verification flow support showing decimals as the short auth string */ override fun supportsDecimal(): Boolean { // This is ignored anyways, throw it away? // The spec also mandates that devices support at least decimal and @@ -111,25 +146,55 @@ internal class SasVerification( return true } + /** Does the verification flow support showing emojis as the short auth string */ override fun supportsEmoji(): Boolean { refreshData() return this.inner.supportsEmoji } + /** Confirm that the short authentication code matches on both sides + * + * This sends a m.key.verification.mac event out, the verification isn't yet + * done, we still need to receive such an event from the other side if we haven't + * already done so. + * + * This method is a noop if we're not yet in a presentable state, i.e. we didn't receive + * a m.key.verification.key event from the other side or we're cancelled. + */ override fun userHasVerifiedShortCode() { runBlocking { confirm() } } + /** Accept the verification flow, signaling the other side that we do want to verify + * + * This sends a m.key.verification.accept event out that is a response to a + * m.key.verification.start event from the other side. + * + * This method is a noop if we send the start event out or if the verification has already + * been accepted. + */ override fun acceptVerification() { runBlocking { accept() } } + /** Get the decimal representation of the short auth string + * + * @return A string of three space delimited numbers that + * represent the short auth string or an empty string if we're not yet + * in a presentable state. + */ override fun getDecimalCodeRepresentation(): String { val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId) return decimals?.joinToString(" ") ?: "" } + /** Get the emoji representation of the short auth string + * + * @return A list of 7 EmojiRepresentation objects that represent the + * short auth string or an empty list if we're not yet in a presentable + * state. + */ override fun getEmojiCodeRepresentation(): List { val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId) @@ -164,6 +229,12 @@ internal class SasVerification( } } + /** Send out a verification request in a blocking manner + * + * This is useful since the public methods to accept/confirm/cancel the verification + * aren't suspendable but sending a request out obviously should be. This bridges the + * gap between our suspendable and non-suspendable methods. + */ private fun sendRequest(request: OutgoingVerificationRequest) { runBlocking { sender.sendVerificationRequest(request) } @@ -171,6 +242,7 @@ internal class SasVerification( dispatchTxUpdated() } + /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { is Verification.SasV1 -> { From 38ce3ebed72d9337cd3b38749f9f342143a3ea57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 21 Jul 2021 14:58:41 +0200 Subject: [PATCH 141/252] crypto: Move the Device class into a separate file --- .../android/sdk/internal/crypto/Device.kt | 71 +++++++++++++++++++ .../android/sdk/internal/crypto/OlmMachine.kt | 31 -------- 2 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt new file mode 100644 index 0000000000..fa09f30f8e --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import uniffi.olm.CryptoStoreErrorException +import uniffi.olm.Device as InnerDevice +import uniffi.olm.OlmMachine + +/** Class representing a device that supports E2EE in the Matrix world + * + * This class can be used to directly start a verification flow with the device + * or to manually verify the device. + */ +internal class Device( + private val machine: OlmMachine, + private var inner: InnerDevice, + private val sender: RequestSender, + private val listeners: ArrayList, +) { + /** Start an interactive verification with this device + * + * This sends out a m.key.verification.start event with the method set to + * m.sas.v1 to this device using to-device messaging. + */ + // TODO this has been deprecated in the spec, add a requestVerification() method + // to this class and use that one instead + @Throws(CryptoStoreErrorException::class) + suspend fun startVerification(): SasVerification? { + val result = withContext(Dispatchers.IO) { + machine.startSasWithDevice(inner.userId, inner.deviceId) + } + + return if (result != null) { + this.sender.sendVerificationRequest(result.request) + SasVerification( + this.machine, result.sas, this.sender, this.listeners, + ) + } else { + null + } + } + + /** Mark this device as locally trusted + * + * This won't upload any signatures, it will only mark the device as trusted + * in the local database. + */ + @Throws(CryptoStoreErrorException::class) + suspend fun markAsTrusted() { + withContext(Dispatchers.IO) { + machine.markDeviceAsTrusted(inner.userId, inner.deviceId) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 3a9d12ce12..4ae46fd2d5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -26,7 +26,6 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext 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.verification.VerificationService 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.util.JsonDict @@ -119,36 +118,6 @@ internal class DeviceUpdateObserver { } } -internal class Device( - private val machine: uniffi.olm.OlmMachine, - private var inner: InnerDevice, - private val sender: RequestSender, - private val listeners: ArrayList, -) { - @Throws(CryptoStoreErrorException::class) - suspend fun startVerification(): SasVerification? { - val result = withContext(Dispatchers.IO) { - machine.startSasWithDevice(inner.userId, inner.deviceId) - } - - return if (result != null) { - this.sender.sendVerificationRequest(result.request) - SasVerification( - this.machine, result.sas, this.sender, this.listeners, - ) - } else { - null - } - } - - @Throws(CryptoStoreErrorException::class) - suspend fun markAsTrusted() { - withContext(Dispatchers.IO) { - machine.markDeviceAsTrusted(inner.userId, inner.deviceId) - } - } -} - internal class OlmMachine( user_id: String, device_id: String, From cbed5be8106226f094a316b73d61eaec7318bf0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 21 Jul 2021 16:25:28 +0200 Subject: [PATCH 142/252] crypto: Move most of the getters of verification objecs into the olm machine --- .../internal/crypto/DefaultCryptoService.kt | 4 +- .../android/sdk/internal/crypto/OlmMachine.kt | 87 +++++++++++++++---- .../verification/RustVerificationService.kt | 87 ++++++------------- 3 files changed, 96 insertions(+), 82 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 118d550e65..b295e484bf 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -392,7 +392,7 @@ internal class DefaultCryptoService @Inject constructor( try { setRustLogger() - val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver) + val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver, sender) olmMachine = machine verificationService = RustVerificationService(machine, this.sender) Timber.v( @@ -482,7 +482,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) { runBlocking { - this@DefaultCryptoService.olmMachine?.getDevice(userId, deviceId) + this@DefaultCryptoService.olmMachine?.getCryptoDeviceInfo(userId, deviceId) } } else { null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 4ae46fd2d5..6a1c3de291 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -26,6 +26,8 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext 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.verification.VerificationService +import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction 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.util.JsonDict @@ -49,8 +51,7 @@ import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType -import uniffi.olm.Verification -import uniffi.olm.VerificationRequest +import uniffi.olm.Verification as InnerVerification import uniffi.olm.setLogger class CryptoLogger : Logger { @@ -122,10 +123,12 @@ internal class OlmMachine( user_id: String, device_id: String, path: File, - deviceObserver: DeviceUpdateObserver + deviceObserver: DeviceUpdateObserver, + private val requestSender: RequestSender, ) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) private val deviceUpdateObserver = deviceObserver + internal val verificationListeners = ArrayList() /** Get our own user ID. */ fun userId(): String { @@ -429,17 +432,26 @@ internal class OlmMachine( * @return The Device if it found one. */ @Throws(CryptoStoreErrorException::class) - suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? = - withContext(Dispatchers.IO) { - // Our own device isn't part of our store on the rust side, return it - // using our ownDevice method - if (userId == userId() && deviceId == deviceId()) { - ownDevice() - } else { - val device = inner.getDevice(userId, deviceId) - if (device != null) toCryptoDeviceInfo(device) else null - } - } + suspend fun getCryptoDeviceInfo(userId: String, deviceId: String): CryptoDeviceInfo? { + return if (userId == userId() && deviceId == deviceId()) { + // Our own device isn't part of our store on the Rust side, return it + // using our ownDevice method + ownDevice() + } else { + val device = getRawDevice(userId, deviceId) ?: return null + toCryptoDeviceInfo(device) + } + } + + private suspend fun getRawDevice(userId: String, deviceId: String): InnerDevice? = + withContext(Dispatchers.IO) { + inner.getDevice(userId, deviceId) + } + + suspend fun getDevice(userId: String, deviceId: String): Device? { + val device = this.getRawDevice(userId, deviceId) ?: return null + return Device(this.inner, device, this.requestSender, this.verificationListeners) + } /** * Get all devices of an user. @@ -546,19 +558,58 @@ internal class OlmMachine( * @return The list of VerificationRequests that we share with the given user */ fun getVerificationRequests(userId: String): List { - return this.inner.getVerificationRequests(userId) + return this.inner.getVerificationRequests(userId).map { + VerificationRequest( + this.inner, + it, + this.requestSender, + this.verificationListeners, + ) + } } /** Get a verification request for the given user with the given flow ID */ fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? { - return this.inner.getVerificationRequest(userId, flowId) + val request = this.inner.getVerificationRequest(userId, flowId) + + return if (request != null) { + VerificationRequest( + this.inner, + request, + requestSender, + this.verificationListeners, + ) + } else { + null + } } /** Get an active verification for the given user and given flow ID * * This can return a SAS verification or a QR code verification */ - fun getVerification(userId: String, flowId: String): Verification? { - return this.inner.getVerification(userId, flowId) + fun getVerification(userId: String, flowId: String): VerificationTransaction? { + return when (val verification = this.inner.getVerification(userId, flowId)) { + is uniffi.olm.Verification.QrCodeV1 -> { + val request = this.getVerificationRequest(userId, flowId) ?: return null + QrCodeVerification(inner, request, verification.qrcode, requestSender, verificationListeners) + } + is uniffi.olm.Verification.SasV1 -> { + SasVerification(inner, verification.sas, requestSender, verificationListeners) + } + null -> { + // This branch exists because scanning a QR code is tied to the QrCodeVerification, + // i.e. instead of branching into a scanned QR code verification from the verification request, + // like it's done for SAS verifications, the public API expects us to create an empty dummy + // QrCodeVerification object that gets populated once a QR code is scanned. + val request = getVerificationRequest(userId, flowId) ?: return null + + if (request.canScanQrCodes()) { + QrCodeVerification(inner, request, null, requestSender, verificationListeners) + } else { + null + } + } + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 2a11b6f540..babecfea70 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -20,9 +20,7 @@ import android.os.Handler import android.os.Looper import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService @@ -34,7 +32,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageRelationCont import org.matrix.android.sdk.api.session.room.model.message.MessageType import org.matrix.android.sdk.internal.crypto.Device import org.matrix.android.sdk.internal.crypto.OlmMachine -import org.matrix.android.sdk.internal.crypto.QrCodeVerification import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.SasVerification import org.matrix.android.sdk.internal.crypto.VerificationRequest @@ -43,14 +40,15 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import org.matrix.android.sdk.internal.crypto.model.rest.toValue import timber.log.Timber -import uniffi.olm.Verification +/** A helper class to deserialize to-device `m.key.verification.*` events to fetch the transaction id out */ @JsonClass(generateAdapter = true) internal data class ToDeviceVerificationEvent( @Json(name = "sender") val sender: String?, @Json(name = "transaction_id") val transactionId: String, ) +/** Helper method to fetch the unique ID of the verification event */ private fun getFlowId(event: Event): String? { return if (event.eventId != null) { val relatesTo = event.content.toModel()?.relatesTo @@ -61,6 +59,7 @@ private fun getFlowId(event: Event): String? { } } +/** Convert a list of VerificationMethod into a list of strings that can be passed to the Rust side */ internal fun prepareMethods(methods: List): List { val stringMethods: MutableList = methods.map { it.toValue() }.toMutableList() @@ -77,23 +76,22 @@ internal class RustVerificationService( private val requestSender: RequestSender, ) : VerificationService { private val uiHandler = Handler(Looper.getMainLooper()) - private var listeners = ArrayList() override fun addListener(listener: VerificationService.Listener) { uiHandler.post { - if (!listeners.contains(listener)) { - listeners.add(listener) + if (!this.olmMachine.verificationListeners.contains(listener)) { + this.olmMachine.verificationListeners.add(listener) } } } override fun removeListener(listener: VerificationService.Listener) { - uiHandler.post { listeners.remove(listener) } + uiHandler.post { this.olmMachine.verificationListeners.remove(listener) } } private fun dispatchTxAdded(tx: VerificationTransaction) { uiHandler.post { - listeners.forEach { + this.olmMachine.verificationListeners.forEach { try { it.transactionCreated(tx) } catch (e: Throwable) { @@ -105,7 +103,7 @@ internal class RustVerificationService( private fun dispatchTxUpdated(tx: VerificationTransaction) { uiHandler.post { - listeners.forEach { + this.olmMachine.verificationListeners.forEach { try { it.transactionUpdated(tx) } catch (e: Throwable) { @@ -118,7 +116,7 @@ internal class RustVerificationService( private fun dispatchRequestAdded(tx: PendingVerificationRequest) { Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx") uiHandler.post { - listeners.forEach { + this.olmMachine.verificationListeners.forEach { try { it.verificationRequestCreated(tx) } catch (e: Throwable) { @@ -188,30 +186,11 @@ internal class RustVerificationService( } private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? { - val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) - - return if (request != null) { - VerificationRequest( - this.olmMachine.inner(), - request, - requestSender, - listeners, - ) - } else { - null - } + return this.olmMachine.getVerificationRequest(otherUserId, transactionId) } private suspend fun getDevice(userId: String, deviceID: String): Device? { - val device = withContext(Dispatchers.IO) { - olmMachine.inner().getDevice(userId, deviceID) - } - - return if (device != null) { - Device(this.olmMachine.inner(), device, this.requestSender, this.listeners) - } else { - null - } + return this.olmMachine.getDevice(userId, deviceID) } override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { @@ -230,40 +209,14 @@ internal class RustVerificationService( otherUserId: String, tid: String, ): VerificationTransaction? { - return when (val verification = this.olmMachine.getVerification(otherUserId, tid)) { - is Verification.QrCodeV1 -> { - val request = getVerificationRequest(otherUserId, tid) ?: return null - QrCodeVerification(this.olmMachine.inner(), request, verification.qrcode, this.requestSender, this.listeners) - } - is Verification.SasV1 -> { - SasVerification(this.olmMachine.inner(), verification.sas, this.requestSender, this.listeners) - } - null -> { - // This branch exists because scanning a QR code is tied to the QrCodeVerification, - // i.e. instead of branching into a scanned QR code verification from the verification request, - // like it's done for SAS verifications, the public API expects us to create an empty dummy - // QrCodeVerification object that gets populated once a QR code is scanned. - val request = getVerificationRequest(otherUserId, tid) ?: return null - - if (request.canScanQrCodes()) { - QrCodeVerification(this.olmMachine.inner(), request, null, this.requestSender, this.listeners) - } else { - null - } - } - } + return this.olmMachine.getVerification(otherUserId, tid) } override fun getExistingVerificationRequests( otherUserId: String ): List { return this.olmMachine.getVerificationRequests(otherUserId).map { - VerificationRequest( - this.olmMachine.inner(), - it, - this.requestSender, - this.listeners, - ).toPendingVerificationRequest() + it.toPendingVerificationRequest() } } @@ -314,7 +267,12 @@ internal class RustVerificationService( requestSender.sendVerificationRequest(result!!.request) } - return VerificationRequest(this.olmMachine.inner(), result!!.verification, this.requestSender, this.listeners).toPendingVerificationRequest() + return VerificationRequest( + this.olmMachine.inner(), + result!!.verification, + this.requestSender, + this.olmMachine.verificationListeners + ).toPendingVerificationRequest() } override fun requestKeyVerificationInDMs( @@ -332,7 +290,12 @@ internal class RustVerificationService( } val innerRequest = this.olmMachine.inner().requestVerification(otherUserId, roomId, eventID, stringMethods)!! - return VerificationRequest(this.olmMachine.inner(), innerRequest, this.requestSender, this.listeners).toPendingVerificationRequest() + return VerificationRequest( + this.olmMachine.inner(), + innerRequest, + this.requestSender, + this.olmMachine.verificationListeners + ).toPendingVerificationRequest() } override fun readyPendingVerification( From 3fa9fc5b7bc7108a1fcce0bcec5b767b247a4324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 21 Jul 2021 16:28:12 +0200 Subject: [PATCH 143/252] crypto: Use a background task to fetch user devices --- .../org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 6a1c3de291..21e759cf10 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -51,7 +51,6 @@ import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType -import uniffi.olm.Verification as InnerVerification import uniffi.olm.setLogger class CryptoLogger : Logger { @@ -462,7 +461,9 @@ internal class OlmMachine( */ @Throws(CryptoStoreErrorException::class) suspend fun getUserDevices(userId: String): List { - val devices = inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) }.toMutableList() + val devices = withContext(Dispatchers.IO) { + inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) }.toMutableList() + } // EA doesn't differentiate much between our own and other devices of // while the rust-sdk does, append our own device here. From 3993d2d4f2dbce2e64223d55bb014cf483b9e534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 22 Jul 2021 11:25:29 +0200 Subject: [PATCH 144/252] crypto: Remove some redundant methods from the verification service --- .../internal/crypto/VerificationRequest.kt | 7 +++++ .../verification/RustVerificationService.kt | 29 +++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 540b429db1..dcad660fd4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -34,6 +34,13 @@ import timber.log.Timber import uniffi.olm.OlmMachine import uniffi.olm.VerificationRequest +/** A verification request object + * + * This represents a verification flow that starts with a m.key.verification.request event + * + * Once the VerificationRequest gets to a ready state users can transition into the different + * concrete verification flows. + */ internal class VerificationRequest( private val machine: OlmMachine, private var inner: VerificationRequest, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index babecfea70..c3fdc3a314 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -30,7 +30,6 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent import org.matrix.android.sdk.api.session.room.model.message.MessageType -import org.matrix.android.sdk.internal.crypto.Device import org.matrix.android.sdk.internal.crypto.OlmMachine import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.SasVerification @@ -143,7 +142,7 @@ internal class RustVerificationService( val sender = event.senderId ?: return val flowId = getFlowId(event) ?: return - this.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() + this.olmMachine.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() val verification = this.getExistingTransaction(sender, flowId) ?: return dispatchTxUpdated(verification) } @@ -153,7 +152,7 @@ internal class RustVerificationService( val flowId = getFlowId(event) ?: return val verification = this.getExistingTransaction(sender, flowId) ?: return - val request = this.getVerificationRequest(sender, flowId) + val request = this.olmMachine.getVerificationRequest(sender, flowId) if (request != null && request.isReady()) { // If this is a SAS verification originating from a `m.key.verification.request` @@ -185,18 +184,10 @@ internal class RustVerificationService( dispatchRequestAdded(request) } - private fun getVerificationRequest(otherUserId: String, transactionId: String): VerificationRequest? { - return this.olmMachine.getVerificationRequest(otherUserId, transactionId) - } - - private suspend fun getDevice(userId: String, deviceID: String): Device? { - return this.olmMachine.getDevice(userId, deviceID) - } - override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { // TODO this doesn't seem to be used anymore? runBlocking { - val device = getDevice(userId, deviceID) + val device = olmMachine.getDevice(userId, deviceID) device?.markAsTrusted() } } @@ -225,7 +216,7 @@ internal class RustVerificationService( tid: String? ): PendingVerificationRequest? { return if (tid != null) { - this.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest() + this.olmMachine.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest() } else { null } @@ -303,7 +294,7 @@ internal class RustVerificationService( otherUserId: String, transactionId: String ): Boolean { - val request = this.getVerificationRequest(otherUserId, transactionId) + val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) return if (request != null) { runBlocking { request.acceptWithMethods(methods) } @@ -341,7 +332,7 @@ internal class RustVerificationService( ): String? { return if (method == VerificationMethod.SAS) { if (transactionId != null) { - val request = this.getVerificationRequest(otherUserId, transactionId) + val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) runBlocking { val sas = request?.startSasVerification() @@ -360,7 +351,7 @@ internal class RustVerificationService( // DeviceListBottomSheetViewModel triggers this, interestingly the method that // triggers this is called `manuallyVerify()` runBlocking { - val verification = getDevice(otherUserId, otherDeviceId)?.startVerification() + val verification = olmMachine.getDevice(otherUserId, otherDeviceId)?.startVerification() if (verification != null) { dispatchTxAdded(verification) verification.transactionId @@ -388,7 +379,9 @@ internal class RustVerificationService( } override fun cancelVerificationRequest(request: PendingVerificationRequest) { - val verificationRequest = request.transactionId?.let { this.getVerificationRequest(request.otherUserId, it) } + val verificationRequest = request.transactionId?.let { + this.olmMachine.getVerificationRequest(request.otherUserId, it) + } runBlocking { verificationRequest?.cancel() } } @@ -397,7 +390,7 @@ internal class RustVerificationService( transactionId: String, roomId: String ) { - val verificationRequest = this.getVerificationRequest(otherUserId, transactionId) + val verificationRequest = this.olmMachine.getVerificationRequest(otherUserId, transactionId) runBlocking { verificationRequest?.cancel() } } } From 99ff097fc300be3688bf7c5a111c823ac119f838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 22 Jul 2021 12:10:39 +0200 Subject: [PATCH 145/252] crypto: Move the update dispatching logic into a separate class --- .../sdk/internal/crypto/QrCodeVerification.kt | 18 ++---- .../sdk/internal/crypto/SasVerification.kt | 18 ++---- .../verification/RustVerificationService.kt | 61 ++++++++++++------- 3 files changed, 46 insertions(+), 51 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index 14bd4e3870..7bde4b4b23 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -16,8 +16,6 @@ package org.matrix.android.sdk.internal.crypto -import android.os.Handler -import android.os.Looper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext @@ -27,7 +25,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import timber.log.Timber +import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher import uniffi.olm.CryptoStoreErrorException import uniffi.olm.OlmMachine import uniffi.olm.OutgoingVerificationRequest @@ -39,20 +37,12 @@ internal class QrCodeVerification( private var request: VerificationRequest, private var inner: QrCode?, private val sender: RequestSender, - private val listeners: ArrayList, + listeners: ArrayList, ) : QrCodeVerificationTransaction { - private val uiHandler = Handler(Looper.getMainLooper()) + private val dispatcher = UpdateDispatcher(listeners) private fun dispatchTxUpdated() { - uiHandler.post { - listeners.forEach { - try { - it.transactionUpdated(this) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } + this.dispatcher.dispatchTxUpdated(this) } /** Generate, if possible, data that should be encoded as a QR code for QR code verification. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index 251f56eaae..cd1a7fc188 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -16,8 +16,6 @@ package org.matrix.android.sdk.internal.crypto -import android.os.Handler -import android.os.Looper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext @@ -27,8 +25,8 @@ import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTra import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf +import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode -import timber.log.Timber import uniffi.olm.CryptoStoreErrorException import uniffi.olm.OlmMachine import uniffi.olm.OutgoingVerificationRequest @@ -39,21 +37,13 @@ internal class SasVerification( private val machine: OlmMachine, private var inner: Sas, private val sender: RequestSender, - private val listeners: ArrayList, + listeners: ArrayList, ) : SasVerificationTransaction { - private val uiHandler = Handler(Looper.getMainLooper()) + private val dispatcher = UpdateDispatcher(listeners) private fun dispatchTxUpdated() { - uiHandler.post { - listeners.forEach { - try { - it.transactionUpdated(this) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } + this.dispatcher.dispatchTxUpdated(this) } /** The user ID of the other user that is participating in this verification flow */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index c3fdc3a314..cd0c296825 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -70,27 +70,24 @@ internal fun prepareMethods(methods: List): List { return stringMethods } -internal class RustVerificationService( - private val olmMachine: OlmMachine, - private val requestSender: RequestSender, -) : VerificationService { +internal class UpdateDispatcher(private val listeners: ArrayList) { private val uiHandler = Handler(Looper.getMainLooper()) - override fun addListener(listener: VerificationService.Listener) { + internal fun addListener(listener: VerificationService.Listener) { uiHandler.post { - if (!this.olmMachine.verificationListeners.contains(listener)) { - this.olmMachine.verificationListeners.add(listener) + if (!this.listeners.contains(listener)) { + this.listeners.add(listener) } } } - override fun removeListener(listener: VerificationService.Listener) { - uiHandler.post { this.olmMachine.verificationListeners.remove(listener) } + internal fun removeListener(listener: VerificationService.Listener) { + uiHandler.post { this.listeners.remove(listener) } } - private fun dispatchTxAdded(tx: VerificationTransaction) { + internal fun dispatchTxAdded(tx: VerificationTransaction) { uiHandler.post { - this.olmMachine.verificationListeners.forEach { + this.listeners.forEach { try { it.transactionCreated(tx) } catch (e: Throwable) { @@ -100,9 +97,9 @@ internal class RustVerificationService( } } - private fun dispatchTxUpdated(tx: VerificationTransaction) { + internal fun dispatchTxUpdated(tx: VerificationTransaction) { uiHandler.post { - this.olmMachine.verificationListeners.forEach { + this.listeners.forEach { try { it.transactionUpdated(tx) } catch (e: Throwable) { @@ -112,10 +109,10 @@ internal class RustVerificationService( } } - private fun dispatchRequestAdded(tx: PendingVerificationRequest) { + internal fun dispatchRequestAdded(tx: PendingVerificationRequest) { Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx") uiHandler.post { - this.olmMachine.verificationListeners.forEach { + this.listeners.forEach { try { it.verificationRequestCreated(tx) } catch (e: Throwable) { @@ -124,8 +121,18 @@ internal class RustVerificationService( } } } +} + +internal class RustVerificationService( + private val olmMachine: OlmMachine, + private val requestSender: RequestSender, +) : VerificationService { + private val dispatcher = UpdateDispatcher(this.olmMachine.verificationListeners) internal suspend fun onEvent(event: Event) = when (event.getClearType()) { + // I'm not entirely sure why getClearType() returns a msgtype in one case + // and a event type in the other case, but this is how the old verification + // service did things and it does seem to work. MessageType.MSGTYPE_VERIFICATION_REQUEST -> onRequest(event) EventType.KEY_VERIFICATION_START -> onStart(event) EventType.KEY_VERIFICATION_READY, @@ -144,7 +151,7 @@ internal class RustVerificationService( this.olmMachine.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() val verification = this.getExistingTransaction(sender, flowId) ?: return - dispatchTxUpdated(verification) + this.dispatcher.dispatchTxUpdated(verification) } private suspend fun onStart(event: Event) { @@ -163,15 +170,15 @@ internal class RustVerificationService( Timber.d("## Verification: Auto accepting SAS verification with $sender") verification.accept() } else { - dispatchTxUpdated(verification) + this.dispatcher.dispatchTxUpdated(verification) } } else { // This didn't originate from a request, so tell our listeners that // this is a new verification. - dispatchTxAdded(verification) + this.dispatcher.dispatchTxAdded(verification) // The IncomingVerificationRequestHandler seems to only listen to updates // so let's trigger an update after the addition as well. - dispatchTxUpdated(verification) + this.dispatcher.dispatchTxUpdated(verification) } } @@ -181,7 +188,15 @@ internal class RustVerificationService( val request = this.getExistingVerificationRequest(sender, flowId) ?: return - dispatchRequestAdded(request) + this.dispatcher.dispatchRequestAdded(request) + } + + override fun addListener(listener: VerificationService.Listener) { + this.dispatcher.addListener(listener) + } + + override fun removeListener(listener: VerificationService.Listener) { + this.dispatcher.removeListener(listener) } override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { @@ -303,7 +318,7 @@ internal class RustVerificationService( val qrcode = request.startQrVerification() if (qrcode != null) { - dispatchTxAdded(qrcode) + this.dispatcher.dispatchTxAdded(qrcode) } true @@ -338,7 +353,7 @@ internal class RustVerificationService( val sas = request?.startSasVerification() if (sas != null) { - dispatchTxAdded(sas) + dispatcher.dispatchTxAdded(sas) sas.transactionId } else { null @@ -353,7 +368,7 @@ internal class RustVerificationService( runBlocking { val verification = olmMachine.getDevice(otherUserId, otherDeviceId)?.startVerification() if (verification != null) { - dispatchTxAdded(verification) + dispatcher.dispatchTxAdded(verification) verification.transactionId } else { null From 52dd4bc454b788eb591148c0209f4b6870ea424f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 22 Jul 2021 13:31:42 +0200 Subject: [PATCH 146/252] crypto: Document the private methods of the rusty verification service --- .../verification/RustVerificationService.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index cd0c296825..417e2d5b0d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -70,6 +70,7 @@ internal fun prepareMethods(methods: List): List { return stringMethods } +/** Class that implements some common methods to dispatch updates for the verification related classes */ internal class UpdateDispatcher(private val listeners: ArrayList) { private val uiHandler = Handler(Looper.getMainLooper()) @@ -129,6 +130,16 @@ internal class RustVerificationService( ) : VerificationService { private val dispatcher = UpdateDispatcher(this.olmMachine.verificationListeners) + /** The main entry point for the verification service + * + * All verification related events should be forwarded through this method to + * the verification service. + * + * Since events are at this point already handled by the rust-sdk through the receival + * of the to-device events and the decryption of room events, this method mainly just + * fetches the appropriate rust object that will be created or updated by the event and + * dispatches updates to our listeners. + */ internal suspend fun onEvent(event: Event) = when (event.getClearType()) { // I'm not entirely sure why getClearType() returns a msgtype in one case // and a event type in the other case, but this is how the old verification @@ -145,6 +156,7 @@ internal class RustVerificationService( } } + /** Dispatch updates after a verification event has been received */ private fun onUpdate(event: Event) { val sender = event.senderId ?: return val flowId = getFlowId(event) ?: return @@ -154,6 +166,7 @@ internal class RustVerificationService( this.dispatcher.dispatchTxUpdated(verification) } + /** Check if the start event created new verification objects and dispatch updates */ private suspend fun onStart(event: Event) { val sender = event.senderId ?: return val flowId = getFlowId(event) ?: return @@ -166,7 +179,7 @@ internal class RustVerificationService( // event, we auto-accept here considering that we either initiated the request or // accepted the request. If it's a QR code verification, just dispatch an update. if (verification is SasVerification) { - // Accept dispatches an update, no need to do it twice. + // accept() will dispatch an update, no need to do it twice. Timber.d("## Verification: Auto accepting SAS verification with $sender") verification.accept() } else { @@ -182,6 +195,7 @@ internal class RustVerificationService( } } + /** Check if the request event created a nev verification request object and dispatch that it dis so */ private fun onRequest(event: Event) { val flowId = getFlowId(event) ?: return val sender = event.senderId ?: return From 813b48df6a0bd6733a08bf913e2976f7daa06304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 23 Jul 2021 11:50:34 +0200 Subject: [PATCH 147/252] crypto: Document all the new verification methods on the Rust side --- rust-sdk/src/error.rs | 2 + rust-sdk/src/lib.rs | 30 +- rust-sdk/src/logger.rs | 6 + rust-sdk/src/machine.rs | 656 ++++++++++++++++++++--------------- rust-sdk/src/olm.udl | 52 +-- rust-sdk/src/responses.rs | 2 + rust-sdk/src/verification.rs | 222 ++++++++++++ 7 files changed, 667 insertions(+), 303 deletions(-) create mode 100644 rust-sdk/src/verification.rs diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index 1d0128a809..8355bd14dd 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -1,3 +1,5 @@ +#![allow(missing_docs)] + use matrix_sdk_crypto::{ store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError, }; diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 3eb18a96b3..eb2cb64e8b 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,21 +1,43 @@ +#![deny( + dead_code, + missing_docs, + trivial_casts, + trivial_numeric_casts, + unused_extern_crates, + unused_import_braces, + unused_qualifications +)] + +//! TODO + mod device; mod error; mod logger; mod machine; mod responses; +mod verification; pub use device::Device; pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; pub use logger::{set_logger, Logger}; -pub use machine::{ - CancelInfo, KeyRequestPair, OlmMachine, QrCode, RequestVerificationResult, Sas, ScanResult, - StartSasResult, Verification, VerificationRequest, -}; +pub use machine::{KeyRequestPair, OlmMachine}; pub use responses::{ DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, }; +pub use verification::{ + CancelInfo, QrCode, RequestVerificationResult, Sas, ScanResult, StartSasResult, Verification, + VerificationRequest, +}; +/// Callback that will be passed over the FFI to report progress pub trait ProgressListener { + /// The callback that should be called on the Rust side + /// + /// # Arguments + /// + /// * `progress` - The current number of items that have been handled + /// + /// * `total` - The total number of items that will be handled fn on_progress(&self, progress: i32, total: i32); } diff --git a/rust-sdk/src/logger.rs b/rust-sdk/src/logger.rs index 3ddef223fd..a29b040572 100644 --- a/rust-sdk/src/logger.rs +++ b/rust-sdk/src/logger.rs @@ -4,8 +4,13 @@ use std::{ }; use tracing_subscriber::{fmt::MakeWriter, EnvFilter}; +/// Trait that can be used to forward Rust logs over FFI to a language specific +/// logger. pub trait Logger: Send { + /// Called every time the Rust side wants to post a log line. fn log(&self, log_line: String); + // TODO add support for different log levels, do this by adding more methods + // to the trait. } impl Write for LoggerWrapper { @@ -34,6 +39,7 @@ pub struct LoggerWrapper { inner: Arc>>, } +/// Set the logger that should be used to forward Rust logs over FFI. pub fn set_logger(logger: Box) { let logger = LoggerWrapper { inner: Arc::new(Mutex::new(logger)), diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 72f269ddce..048f417228 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -30,17 +30,16 @@ use tokio::runtime::Runtime; use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; use matrix_sdk_crypto::{ - decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, - CancelInfo as RustCancelInfo, EncryptionSettings, LocalTrust, OlmMachine as InnerMachine, - QrVerification as InnerQr, Sas as InnerSas, Verification as RustVerification, - VerificationRequest as InnerVerificationRequest, + decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, EncryptionSettings, + LocalTrust, OlmMachine as InnerMachine, Verification as RustVerification, }; use crate::{ error::{CryptoStoreError, DecryptionError, MachineCreationError}, responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, - Request, RequestType, + QrCode, Request, RequestType, RequestVerificationResult, ScanResult, StartSasResult, + Verification, VerificationRequest, }; /// A high level state machine that handles E2EE for Matrix. @@ -49,148 +48,6 @@ pub struct OlmMachine { runtime: Runtime, } -pub enum Verification { - SasV1 { sas: Sas }, - QrCodeV1 { qrcode: QrCode }, -} - -pub struct Sas { - pub other_user_id: String, - pub other_device_id: String, - pub flow_id: String, - pub room_id: Option, - pub have_we_confirmed: bool, - pub is_cancelled: bool, - pub is_done: bool, - pub cancel_info: Option, - pub has_been_accepted: bool, - pub we_started: bool, - pub can_be_presented: bool, - pub supports_emoji: 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, - pub is_cancelled: bool, - pub is_done: bool, - pub we_started: bool, - pub other_side_scanned: bool, - pub has_been_confirmed: bool, - pub reciprocated: bool, - pub cancel_info: Option, -} - -impl From 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_info: qr.cancel_info().map(|c| c.into()), - reciprocated: qr.reciprocated(), - we_started: qr.we_started(), - other_side_scanned: qr.has_been_scanned(), - has_been_confirmed: qr.has_been_confirmed(), - other_device_id: qr.other_device_id().to_string(), - room_id: qr.room_id().map(|r| r.to_string()), - } - } -} - -pub struct CancelInfo { - pub reason: String, - pub cancel_code: String, - pub cancelled_by_us: bool, -} - -impl From for CancelInfo { - fn from(c: RustCancelInfo) -> Self { - Self { - reason: c.reason().to_owned(), - cancel_code: c.cancel_code().to_string(), - cancelled_by_us: c.cancelled_by_us(), - } - } -} - -pub struct StartSasResult { - pub sas: Sas, - pub request: OutgoingVerificationRequest, -} - -pub struct ScanResult { - pub qr: QrCode, - pub request: OutgoingVerificationRequest, -} - -impl From for Sas { - fn from(sas: InnerSas) -> Self { - Self { - other_user_id: sas.other_user_id().to_string(), - other_device_id: sas.other_device_id().to_string(), - flow_id: sas.flow_id().as_str().to_owned(), - is_cancelled: sas.is_cancelled(), - is_done: sas.is_done(), - can_be_presented: sas.can_be_presented(), - timed_out: sas.timed_out(), - supports_emoji: sas.supports_emoji(), - have_we_confirmed: sas.have_we_confirmed(), - we_started: sas.we_started(), - room_id: sas.room_id().map(|r| r.to_string()), - has_been_accepted: sas.has_been_accepted(), - cancel_info: sas.cancel_info().map(|c| c.into()), - } - } -} - -pub struct RequestVerificationResult { - pub verification: VerificationRequest, - pub request: OutgoingVerificationRequest, -} - -pub struct VerificationRequest { - pub other_user_id: String, - pub other_device_id: Option, - pub flow_id: String, - pub is_cancelled: bool, - pub is_done: bool, - pub is_ready: bool, - pub room_id: Option, - pub we_started: bool, - pub is_passive: bool, - pub their_methods: Option>, - pub our_methods: Option>, - pub cancel_info: Option, -} - -impl From for VerificationRequest { - fn from(v: InnerVerificationRequest) -> Self { - Self { - other_user_id: v.other_user().to_string(), - other_device_id: v.other_device_id().map(|d| d.to_string()), - flow_id: v.flow_id().as_str().to_owned(), - is_cancelled: v.is_cancelled(), - is_done: v.is_done(), - is_ready: v.is_ready(), - room_id: v.room_id().map(|r| r.to_string()), - we_started: v.we_started(), - is_passive: v.is_passive(), - cancel_info: v.cancel_info().map(|c| c.into()), - their_methods: v - .their_supported_methods() - .map(|v| v.into_iter().map(|m| m.to_string()).collect()), - our_methods: v - .our_supported_methods() - .map(|v| v.into_iter().map(|m| m.to_string()).collect()), - } - } -} - /// A pair of outgoing room key requests, both of those are sendToDevice /// requests. pub struct KeyRequestPair { @@ -254,6 +111,7 @@ impl OlmMachine { .map(|d| d.into())) } + /// Mark the device of the given user with the given device id as trusted. pub fn mark_device_as_trusted( &self, user_id: &str, @@ -696,6 +554,12 @@ impl OlmMachine { Ok(()) } + /// Get all the verification requests that we share with the given user. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to fetch the + /// verification requests. pub fn get_verification_requests(&self, user_id: &str) -> Vec { let user_id = if let Ok(user_id) = UserId::try_from(user_id) { user_id @@ -710,6 +574,15 @@ impl OlmMachine { .collect() } + /// Get a verification requests that we share with the given user with the + /// given flow id. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to fetch the + /// verification requests. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. pub fn get_verification_request( &self, user_id: &str, @@ -722,6 +595,20 @@ impl OlmMachine { .map(|v| v.into()) } + /// Accept a verification requests that we share with the given user with the + /// given flow id. + /// + /// This will move the verification request into the ready state. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to accept the + /// verification requests. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. + /// + /// * `methods` - A list of verification methods that we want to advertise + /// as supported. pub fn accept_verification_request( &self, user_id: &str, @@ -741,69 +628,59 @@ impl OlmMachine { } } - pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { - let user_id = UserId::try_from(user_id).ok()?; - self.inner - .get_verification(&user_id, flow_id) - .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( + /// Get an m.key.verification.request content for the given user. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user which we would like to request to + /// verify. + /// + /// * `methods` - The list of verification methods we want to advertise to + /// support. + pub fn verification_request_content( &self, user_id: &str, - flow_id: &str, - ) -> Result, CryptoStoreError> { + methods: Vec, + ) -> Result, CryptoStoreError> { let user_id = UserId::try_from(user_id)?; - if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { - Ok(self + let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; + + let methods = methods + .into_iter() + .map(|m| VerificationMethod::from(m)) + .collect(); + + Ok(if let Some(identity) = identity.and_then(|i| i.other()) { + let content = 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 { - 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 scan_qr_code(&self, user_id: &str, flow_id: &str, data: &str) -> Option { - let user_id = UserId::try_from(user_id).ok()?; - // TODO create a custom error type - let data = decode_config(data, STANDARD_NO_PAD).ok()?; - let data = QrVerificationData::from_bytes(data).ok()?; - - if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { - if let Some(qr) = self - .runtime - .block_on(verification.scan_qr_code(data)) - .ok()? - { - let request = qr.reciprocate()?; - - Some(ScanResult { - qr: qr.into(), - request: request.into(), - }) - } else { - None - } + .block_on(identity.verification_request_content(Some(methods))); + Some(serde_json::to_string(&content)?) } else { None - } + }) } + /// Request a verification flow to begin with the given user in the given + /// room. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user which we would like to request to + /// verify. + /// + /// * `room_id` - The ID of the room that represents a DM with the given + /// user. + /// + /// * `event_id` - The event ID of the `m.key.verification.request` event + /// that we sent out to request the verification to begin. The content for + /// this request can be created using the [verification_request_content()] + /// method. + /// + /// * `methods` - The list of verification methods we advertised as + /// supported in the `m.key.verification.request` event. + /// + /// [verification_request_content()]: #method.verification_request_content pub fn request_verification( &self, user_id: &str, @@ -835,30 +712,55 @@ impl OlmMachine { }) } - pub fn verification_request_content( + /// Request a verification flow to begin with the given user's device. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user which we would like to request to + /// verify. + /// + /// * `device_id` - The ID of the device that we wish to verify. + /// + /// * `methods` - The list of verification methods we advertised as + /// supported in the `m.key.verification.request` event. + pub fn request_verification_with_device( &self, user_id: &str, + device_id: &str, methods: Vec, - ) -> Result, CryptoStoreError> { + ) -> Result, CryptoStoreError> { let user_id = UserId::try_from(user_id)?; - let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; - let methods = methods .into_iter() .map(|m| VerificationMethod::from(m)) .collect(); - Ok(if let Some(identity) = identity.and_then(|i| i.other()) { - let content = self + Ok( + if let Some(device) = self .runtime - .block_on(identity.verification_request_content(Some(methods))); - Some(serde_json::to_string(&content)?) - } else { - None - }) + .block_on(self.inner.get_device(&user_id, device_id.into()))? + { + let (verification, request) = self + .runtime + .block_on(device.request_verification_with_methods(methods)); + + Some(RequestVerificationResult { + verification: verification.into(), + request: request.into(), + }) + } else { + None + }, + ) } + /// Request a verification flow to begin with our other devices. + /// + /// # Arguments + /// + /// `methods` - The list of verification methods we want to advertise to + /// support. pub fn request_self_verification( &self, methods: Vec, @@ -885,6 +787,239 @@ impl OlmMachine { }) } + /// Get a verification flow object for the given user with the given flow id. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to fetch the + /// verification. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. + pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { + let user_id = UserId::try_from(user_id).ok()?; + self.inner + .get_verification(&user_id, flow_id) + .map(|v| match v { + RustVerification::SasV1(s) => Verification::SasV1 { sas: s.into() }, + RustVerification::QrV1(qr) => Verification::QrCodeV1 { qrcode: qr.into() }, + }) + } + + /// Cancel a verification for the given user with the given flow id using + /// the given cancel code. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to cancel the + /// verification. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. + /// + /// * `cancel_code` - The error code for why the verification was cancelled, + /// manual cancellatio usually happens with `m.user` cancel code. The full + /// list of cancel codes can be found in the [spec] + /// + /// [spec]: https://spec.matrix.org/unstable/client-server-api/#mkeyverificationcancel + pub fn cancel_verification( + &self, + user_id: &str, + flow_id: &str, + cancel_code: &str, + ) -> Option { + let user_id = UserId::try_from(user_id).ok()?; + + if let Some(request) = self.inner.get_verification_request(&user_id, flow_id) { + request.cancel().map(|r| r.into()) + } else if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { + match verification { + RustVerification::SasV1(v) => { + v.cancel_with_code(cancel_code.into()).map(|r| r.into()) + } + RustVerification::QrV1(v) => { + v.cancel_with_code(cancel_code.into()).map(|r| r.into()) + } + } + } else { + None + } + } + + /// Confirm a verification was successful. + /// + /// This method should be called either if a short auth string should be + /// confirmed as matching, or if we want to confirm that the other side has + /// scanned our QR code. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to confirm the + /// verification. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. + pub fn confirm_verification( + &self, + user_id: &str, + flow_id: &str, + ) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + + Ok( + if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { + match verification { + RustVerification::SasV1(v) => { + self.runtime.block_on(v.confirm())?.0.map(|r| r.into()) + } + RustVerification::QrV1(v) => v.confirm_scanning().map(|r| r.into()), + } + } else { + None + }, + ) + } + + /// Transition from a verification request into QR code verification. + /// + /// This method should be called when one wants to display a QR code so the + /// other side can scan it and move the QR code verification forward. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to start the + /// QR code verification. + /// + /// * `flow_id` - The ID of the verification request that initated the + /// verification flow. + pub fn start_qr_verification( + &self, + user_id: &str, + flow_id: &str, + ) -> Result, 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) + } + } + + /// Generate data that should be encoded as a QR code. + /// + /// This method should be called right before a QR code should be displayed, + /// the returned data is base64 encoded (without padding) and needs to be + /// decoded on the other side before it can be put through a QR code + /// generator. + /// + /// *Note*: You'll need to call [start_qr_verification()] before calling this + /// method, otherwise `None` will be returned. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to start the + /// QR code verification. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. + /// + /// [start_qr_verification()]: #method.start_qr_verification + pub fn generate_qr_code(&self, user_id: &str, flow_id: &str) -> Option { + 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()) + }) + } + + /// Pass data from a scanned QR code to an active verification request and + /// transition into QR code verification. + /// + /// This requires an active `VerificationRequest` to succeed, returns `None` + /// if no `VerificationRequest` is found or if the QR code data is invalid. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to start the + /// QR code verification. + /// + /// * `flow_id` - The ID of the verification request that initated the + /// verification flow. + /// + /// * `data` - The data that was extracted from the scanned QR code as an + /// base64 encoded string, without padding. + pub fn scan_qr_code(&self, user_id: &str, flow_id: &str, data: &str) -> Option { + let user_id = UserId::try_from(user_id).ok()?; + let data = decode_config(data, STANDARD_NO_PAD).ok()?; + let data = QrVerificationData::from_bytes(data).ok()?; + + if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { + if let Some(qr) = self + .runtime + .block_on(verification.scan_qr_code(data)) + .ok()? + { + let request = qr.reciprocate()?; + + Some(ScanResult { + qr: qr.into(), + request: request.into(), + }) + } else { + None + } + } else { + None + } + } + + /// Transition from a verification request into short auth string based + /// verification. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to start the + /// SAS verification. + /// + /// * `flow_id` - The ID of the verification request that initated the + /// verification flow. + pub fn start_sas_verification( + &self, + user_id: &str, + flow_id: &str, + ) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + + Ok( + if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { + self.runtime + .block_on(verification.start_sas())? + .map(|(sas, r)| StartSasResult { + sas: sas.into(), + request: r.into(), + }) + } else { + None + }, + ) + } + + /// Start short auth string verification with a device without going + /// through a verification request first. + /// + /// **Note**: This has been largely deprecated and the + /// [request_verification_with_device()] method should be used instead. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to start the + /// SAS verification. + /// + /// * `device_id` - The ID of device we would like to verify. + /// + /// [request_verification_with_device()]: #method.request_verification_with_device pub fn start_sas_with_device( &self, user_id: &str, @@ -909,27 +1044,14 @@ impl OlmMachine { ) } - pub fn start_sas_verification( - &self, - user_id: &str, - flow_id: &str, - ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; - - Ok( - if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { - self.runtime - .block_on(verification.start_sas())? - .map(|(sas, r)| StartSasResult { - sas: sas.into(), - request: r.into(), - }) - } else { - None - }, - ) - } - + /// Accept that we're going forward with the short auth string verification. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to accept the + /// SAS verification. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. pub fn accept_sas_verification( &self, user_id: &str, @@ -942,49 +1064,19 @@ impl OlmMachine { .and_then(|s| s.accept().map(|r| r.into())) } - pub fn cancel_verification( - &self, - user_id: &str, - flow_id: &str, - cancel_code: &str, - ) -> Option { - let user_id = UserId::try_from(user_id).ok()?; - - if let Some(request) = self.inner.get_verification_request(&user_id, flow_id) { - request.cancel().map(|r| r.into()) - } else if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { - match verification { - RustVerification::SasV1(v) => { - v.cancel_with_code(cancel_code.into()).map(|r| r.into()) - } - RustVerification::QrV1(v) => v.cancel().map(|r| r.into()), - } - } else { - None - } - } - - pub fn confirm_verification( - &self, - user_id: &str, - flow_id: &str, - ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; - - Ok( - if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { - match verification { - RustVerification::SasV1(v) => { - self.runtime.block_on(v.confirm())?.0.map(|r| r.into()) - } - RustVerification::QrV1(v) => v.confirm_scanning().map(|r| r.into()), - } - } else { - None - }, - ) - } - + /// Get a list of emoji indices of the emoji representation of the short + /// auth string. + /// + /// *Note*: A SAS verification needs to be started and in the presentable + /// state for this to return the list of emoji indices, otherwise returns + /// `None`. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to get the + /// short auth string. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. pub fn get_emoji_index(&self, user_id: &str, flow_id: &str) -> Option> { let user_id = UserId::try_from(user_id).ok()?; @@ -998,6 +1090,18 @@ impl OlmMachine { }) } + /// Get the decimal representation of the short auth string. + /// + /// *Note*: A SAS verification needs to be started and in the presentable + /// state for this to return the list of decimals, otherwise returns + /// `None`. + /// + /// # Arguments + /// + /// * `user_id` - The ID of the user for which we would like to get the + /// short auth string. + /// + /// * `flow_id` - The ID that uniquely identifies the verification flow. pub fn get_decimals(&self, user_id: &str, flow_id: &str) -> Option> { let user_id = UserId::try_from(user_id).ok()?; diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index ac4618b22d..ef0bdd3495 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -83,12 +83,11 @@ dictionary Sas { string? room_id; boolean we_started; boolean has_been_accepted; + boolean can_be_presented; + boolean supports_emoji; boolean have_we_confirmed; boolean is_done; boolean is_cancelled; - boolean can_be_presented; - boolean timed_out; - boolean supports_emoji; CancelInfo? cancel_info; }; @@ -97,18 +96,17 @@ dictionary ScanResult { OutgoingVerificationRequest request; }; - dictionary QrCode { string other_user_id; string other_device_id; string flow_id; string? room_id; - boolean reciprocated; boolean we_started; + boolean other_side_scanned; boolean has_been_confirmed; + boolean reciprocated; boolean is_done; boolean is_cancelled; - boolean other_side_scanned; CancelInfo? cancel_info; }; @@ -116,12 +114,12 @@ dictionary VerificationRequest { string other_user_id; string? other_device_id; string flow_id; - boolean is_cancelled; - boolean is_done; - boolean is_ready; - boolean we_started; - boolean is_passive; string? room_id; + boolean we_started; + boolean is_ready; + boolean is_passive; + boolean is_done; + boolean is_cancelled; CancelInfo? cancel_info; sequence? their_methods; sequence? our_methods; @@ -209,12 +207,6 @@ interface OlmMachine { VerificationRequest? get_verification_request([ByRef] string user_id, [ByRef] string flow_id); Verification? get_verification([ByRef] string user_id, [ByRef] string flow_id); - OutgoingVerificationRequest? accept_verification_request( - [ByRef] string user_id, - [ByRef] string flow_id, - sequence methods - ); - [Throws=CryptoStoreError] VerificationRequest? request_verification( [ByRef] string user_id, @@ -230,9 +222,18 @@ interface OlmMachine { [Throws=CryptoStoreError] RequestVerificationResult? request_self_verification(sequence methods); [Throws=CryptoStoreError] - StartSasResult? start_sas_with_device([ByRef] string user_id, [ByRef] string device_id); - [Throws=CryptoStoreError] - StartSasResult? start_sas_verification([ByRef] string user_id, [ByRef] string flow_id); + RequestVerificationResult? request_verification_with_device( + [ByRef] string user_id, + [ByRef] string device_id, + sequence methods + ); + + OutgoingVerificationRequest? accept_verification_request( + [ByRef] string user_id, + [ByRef] string flow_id, + sequence methods + ); + [Throws=CryptoStoreError] OutgoingVerificationRequest? confirm_verification([ByRef] string user_id, [ByRef] string flow_id); OutgoingVerificationRequest? cancel_verification( @@ -240,15 +241,20 @@ interface OlmMachine { [ByRef] string flow_id, [ByRef] string cancel_code ); + + [Throws=CryptoStoreError] + StartSasResult? start_sas_with_device([ByRef] string user_id, [ByRef] string device_id); + [Throws=CryptoStoreError] + StartSasResult? start_sas_verification([ByRef] string user_id, [ByRef] string flow_id); OutgoingVerificationRequest? accept_sas_verification([ByRef] string user_id, [ByRef] string flow_id); + sequence? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); + sequence? get_decimals([ByRef] string user_id, [ByRef] string flow_id); + [Throws=CryptoStoreError] QrCode? start_qr_verification([ByRef] string user_id, [ByRef] string flow_id); ScanResult? scan_qr_code([ByRef] string user_id, [ByRef] string flow_id, [ByRef] string data); string? generate_qr_code([ByRef] string user_id, [ByRef] string flow_id); - sequence? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); - sequence? get_decimals([ByRef] string user_id, [ByRef] string flow_id); - [Throws=DecryptionError] KeyRequestPair request_room_key([ByRef] string event, [ByRef] string room_id); diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index b2af4b162a..7ddeb87af7 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -1,3 +1,5 @@ +#![allow(missing_docs)] + use std::{collections::HashMap, convert::TryFrom}; use http::Response; diff --git a/rust-sdk/src/verification.rs b/rust-sdk/src/verification.rs new file mode 100644 index 0000000000..d75bc01d3c --- /dev/null +++ b/rust-sdk/src/verification.rs @@ -0,0 +1,222 @@ +use matrix_sdk_crypto::{ + CancelInfo as RustCancelInfo, QrVerification as InnerQr, Sas as InnerSas, + VerificationRequest as InnerVerificationRequest, +}; + +use crate::OutgoingVerificationRequest; + +/// Enum representing the different verification flows we support. +pub enum Verification { + /// The `m.sas.v1` verification flow. + SasV1 { + #[allow(missing_docs)] + sas: Sas + }, + /// The `m.qr_code.scan.v1`, `m.qr_code.show.v1`, and `m.reciprocate.v1` + /// verification flow. + QrCodeV1 { + #[allow(missing_docs)] + qrcode: QrCode + }, +} + +/// The `m.sas.v1` verification flow. +pub struct Sas { + /// The other user that is participating in the verification flow + pub other_user_id: String, + /// The other user's device that is participating in the verification flow + pub other_device_id: String, + /// The unique ID of this verification flow, will be a random string for + /// to-device events or a event ID for in-room events. + pub flow_id: String, + /// The room ID where this verification is happening, will be `None` if the + /// verification is going through to-device messages + pub room_id: Option, + /// Did we initiate the verification flow + pub we_started: bool, + /// Has the non-initiating side accepted the verification flow + pub has_been_accepted: bool, + /// Can the short auth string be presented + pub can_be_presented: bool, + /// Does the flow support the emoji representation of the short auth string + pub supports_emoji: bool, + /// Have we confirmed that the short auth strings match + pub have_we_confirmed: bool, + /// Has the verification completed successfully + pub is_done: bool, + /// Has the flow been cancelled + pub is_cancelled: bool, + /// Information about the cancellation of the flow, will be `None` if the + /// flow hasn't been cancelled + pub cancel_info: Option, +} + +/// The `m.qr_code.scan.v1`, `m.qr_code.show.v1`, and `m.reciprocate.v1` +/// verification flow. +pub struct QrCode { + /// The other user that is participating in the verification flow + pub other_user_id: String, + /// The other user's device that is participating in the verification flow + pub other_device_id: String, + /// The unique ID of this verification flow, will be a random string for + /// to-device events or a event ID for in-room events. + pub flow_id: String, + /// The room ID where this verification is happening, will be `None` if the + /// verification is going through to-device messages + pub room_id: Option, + /// Did we initiate the verification flow + pub we_started: bool, + /// Has the QR code been scanned by the other side + pub other_side_scanned: bool, + /// Has the scanning of the QR code been confirmed by us + pub has_been_confirmed: bool, + /// Did we scan the QR code and sent out a reciprocation + pub reciprocated: bool, + /// Has the verification completed successfully + pub is_done: bool, + /// Has the flow been cancelled + pub is_cancelled: bool, + /// Information about the cancellation of the flow, will be `None` if the + /// flow hasn't been cancelled + pub cancel_info: Option, +} + +impl From 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_info: qr.cancel_info().map(|c| c.into()), + reciprocated: qr.reciprocated(), + we_started: qr.we_started(), + other_side_scanned: qr.has_been_scanned(), + has_been_confirmed: qr.has_been_confirmed(), + other_device_id: qr.other_device_id().to_string(), + room_id: qr.room_id().map(|r| r.to_string()), + } + } +} + +/// Information on why a verification flow has been cancelled and by whom. +pub struct CancelInfo { + /// The textual representation of the cancel reason + pub reason: String, + /// The code describing the cancel reason + pub cancel_code: String, + /// Was the verification flow cancelled by us + pub cancelled_by_us: bool, +} + +impl From for CancelInfo { + fn from(c: RustCancelInfo) -> Self { + Self { + reason: c.reason().to_owned(), + cancel_code: c.cancel_code().to_string(), + cancelled_by_us: c.cancelled_by_us(), + } + } +} + +/// A result type for starting SAS verifications. +pub struct StartSasResult { + /// The SAS verification object that got created. + pub sas: Sas, + /// The request that needs to be sent out to notify the other side that a + /// SAS verification should start. + pub request: OutgoingVerificationRequest, +} + +/// A result type for scanning QR codes. +pub struct ScanResult { + /// The QR code verification object that got created. + pub qr: QrCode, + /// The request that needs to be sent out to notify the other side that a + /// QR code verification should start. + pub request: OutgoingVerificationRequest, +} + +impl From for Sas { + fn from(sas: InnerSas) -> Self { + Self { + other_user_id: sas.other_user_id().to_string(), + other_device_id: sas.other_device_id().to_string(), + flow_id: sas.flow_id().as_str().to_owned(), + is_cancelled: sas.is_cancelled(), + is_done: sas.is_done(), + can_be_presented: sas.can_be_presented(), + supports_emoji: sas.supports_emoji(), + have_we_confirmed: sas.have_we_confirmed(), + we_started: sas.we_started(), + room_id: sas.room_id().map(|r| r.to_string()), + has_been_accepted: sas.has_been_accepted(), + cancel_info: sas.cancel_info().map(|c| c.into()), + } + } +} + +/// A result type for requesting verifications. +pub struct RequestVerificationResult { + /// The verification request object that got created. + pub verification: VerificationRequest, + /// The request that needs to be sent out to notify the other side that + /// we're requesting verification to begin. + pub request: OutgoingVerificationRequest, +} + +/// The verificatoin request object which then can transition into some concrete +/// verification method +pub struct VerificationRequest { + /// The other user that is participating in the verification flow + pub other_user_id: String, + /// The other user's device that is participating in the verification flow + pub other_device_id: Option, + /// The unique ID of this verification flow, will be a random string for + /// to-device events or a event ID for in-room events. + pub flow_id: String, + /// The room ID where this verification is happening, will be `None` if the + /// verification is going through to-device messages + pub room_id: Option, + /// Did we initiate the verification flow + pub we_started: bool, + /// Did both parties aggree to verification + pub is_ready: bool, + /// Did another device respond to the verification request + pub is_passive: bool, + /// Has the verification completed successfully + pub is_done: bool, + /// Has the flow been cancelled + pub is_cancelled: bool, + /// The list of verification methods that the other side advertised as + /// supported + pub their_methods: Option>, + /// The list of verification methods that we advertised as supported + pub our_methods: Option>, + /// Information about the cancellation of the flow, will be `None` if the + /// flow hasn't been cancelled + pub cancel_info: Option, +} + +impl From for VerificationRequest { + fn from(v: InnerVerificationRequest) -> Self { + Self { + other_user_id: v.other_user().to_string(), + other_device_id: v.other_device_id().map(|d| d.to_string()), + flow_id: v.flow_id().as_str().to_owned(), + is_cancelled: v.is_cancelled(), + is_done: v.is_done(), + is_ready: v.is_ready(), + room_id: v.room_id().map(|r| r.to_string()), + we_started: v.we_started(), + is_passive: v.is_passive(), + cancel_info: v.cancel_info().map(|c| c.into()), + their_methods: v + .their_supported_methods() + .map(|v| v.into_iter().map(|m| m.to_string()).collect()), + our_methods: v + .our_supported_methods() + .map(|v| v.into_iter().map(|m| m.to_string()).collect()), + } + } +} From 2fc691eed22498e241e73238c76a06fc47f66d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 23 Jul 2021 11:54:58 +0200 Subject: [PATCH 148/252] crypto: Add a method to request verification to the Device class --- .../android/sdk/internal/crypto/Device.kt | 25 +++++++++++++++++-- .../sdk/internal/crypto/QrCodeVerification.kt | 1 + .../sdk/internal/crypto/SasVerification.kt | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index fa09f30f8e..ec89cb5f8a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -18,10 +18,13 @@ package org.matrix.android.sdk.internal.crypto import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.internal.crypto.verification.prepareMethods import uniffi.olm.CryptoStoreErrorException import uniffi.olm.Device as InnerDevice import uniffi.olm.OlmMachine +import uniffi.olm.VerificationRequest /** Class representing a device that supports E2EE in the Matrix world * @@ -34,13 +37,31 @@ internal class Device( private val sender: RequestSender, private val listeners: ArrayList, ) { + /** Request an interactive verification to begin + * + * This sends out a m.key.verification.request event over to-device messaging to + * to this device. + */ + @Throws(CryptoStoreErrorException::class) + suspend fun requestVerification(methods: List): VerificationRequest? { + val stringMethods = prepareMethods(methods) + val result = withContext(Dispatchers.IO) { + machine.requestVerificationWithDevice(inner.userId, inner.deviceId, stringMethods) + } + + return if (result != null) { + this.sender.sendVerificationRequest(result.request) + result.verification + } else { + null + } + } + /** Start an interactive verification with this device * * This sends out a m.key.verification.start event with the method set to * m.sas.v1 to this device using to-device messaging. */ - // TODO this has been deprecated in the spec, add a requestVerification() method - // to this class and use that one instead @Throws(CryptoStoreErrorException::class) suspend fun startVerification(): SasVerification? { val result = withContext(Dispatchers.IO) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index 7bde4b4b23..d9d914d789 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -32,6 +32,7 @@ import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.QrCode import uniffi.olm.Verification +/** Class representing a QR code based verification flow */ internal class QrCodeVerification( private val machine: OlmMachine, private var request: VerificationRequest, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index cd1a7fc188..ad8322a2ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -33,6 +33,7 @@ import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.Sas import uniffi.olm.Verification +/** Class representing a short auth string verification flow */ internal class SasVerification( private val machine: OlmMachine, private var inner: Sas, From c551b9e0bb7e39ab3a7545fc566dae837aa30843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 23 Jul 2021 14:06:03 +0200 Subject: [PATCH 149/252] crypto: Fill out the docs for the cross signing service --- .../crosssigning/CrossSigningService.kt | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index 359e33cc2c..709babc23f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -25,9 +25,13 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo interface CrossSigningService { - + /** + * Is our own device signed by our own cross signing identity + */ fun isCrossSigningVerified(): Boolean + // TODO this isn't used anywhere besides in tests? + // Is this the local trust concept that we have for devices? fun isUserTrusted(otherUserId: String): Boolean /** @@ -43,29 +47,55 @@ interface CrossSigningService { fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?, callback: MatrixCallback) + /** + * Does our own user have a valid cross signing identity uploaded. + * + * In other words has any of our devices uploaded public cross signing keys to the server. + */ fun isCrossSigningInitialized(): Boolean = getMyCrossSigningKeys() != null + /** + * Inject the private cross signing keys, likely from backup, into our store. + * + * This will check if the injected private cross signing keys match the public ones provided + * by the server and if they do so + */ fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, uskKeyPrivateKey: String?, sskPrivateKey: String?): UserTrustResult + /** + * Get the public cross signing keys for the given user + * + * @param otherUserId The ID of the user for which we would like to fetch the cross signing keys. + */ fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? fun getLiveCrossSigningKeys(userId: String): LiveData> + /** Get our own public cross signing keys */ fun getMyCrossSigningKeys(): MXCrossSigningInfo? + /** Get our own private cross signing keys */ fun getCrossSigningPrivateKeys(): PrivateKeysInfo? fun getLiveCrossSigningPrivateKeys(): LiveData> + /** + * Can we sign our other devices or other users? + * + * Returning true means that we have the private self-signing and user-signing keys at hand. + */ fun canCrossSign(): Boolean + /** Do we have all our private cross signing keys in storage? */ fun allPrivateKeysKnown(): Boolean + /** Mark a user identity as trusted and sign and upload signatures of our user-signing key to the server */ fun trustUser(otherUserId: String, callback: MatrixCallback) + /** Mark our own master key as trusted */ fun markMyMasterKeyAsTrusted() /** @@ -74,11 +104,20 @@ interface CrossSigningService { fun trustDevice(deviceId: String, callback: MatrixCallback) + /** + * Check if a device is trusted + * + * This will check that we have a valid trust chain from our own master key to a device, either + * using the self-signing key for our own devices or using the user-signing key and the master + * key of another user. + */ fun checkDeviceTrust(otherUserId: String, otherDeviceId: String, + // TODO what is locallyTrusted used for? locallyTrusted: Boolean?): DeviceTrustResult // FIXME Those method do not have to be in the service + // TODO those three methods doesn't seem to be used anywhere? fun onSecretMSKGossip(mskPrivateKey: String) fun onSecretSSKGossip(sskPrivateKey: String) fun onSecretUSKGossip(uskPrivateKey: String) From b012a0ff750ca04d1d7ab525876609b45beac528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 10 Aug 2021 16:37:46 +0200 Subject: [PATCH 150/252] crypto: Export cross signing related methods from the Rust side --- rust-sdk/Cargo.toml | 10 ++- rust-sdk/src/error.rs | 31 +++++-- rust-sdk/src/lib.rs | 62 +++++++++++++- rust-sdk/src/machine.rs | 172 +++++++++++++++++++++++++++++++++----- rust-sdk/src/olm.udl | 84 +++++++++++++++++-- rust-sdk/src/responses.rs | 107 +++++++++++++++++++++++- rust-sdk/src/users.rs | 61 ++++++++++++++ 7 files changed, 484 insertions(+), 43 deletions(-) create mode 100644 rust-sdk/src/users.rs diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 66723de16a..2e5618d727 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -25,11 +25,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "3a8ff2f6b43f312b7582146ed712ff245ef9d5aa" +rev = "b2ff6cb6ae3d1983a510262021cba27a1bc70d77" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "3a8ff2f6b43f312b7582146ed712ff245ef9d5aa" +rev = "b2ff6cb6ae3d1983a510262021cba27a1bc70d77" features = ["sled_cryptostore"] [dependencies.tokio] @@ -38,8 +38,12 @@ default_features = false features = ["rt-multi-thread"] [dependencies.ruma] -version = "0.2.0" +version = "0.3.0" features = ["client-api"] [build-dependencies] uniffi_build = "0.12.0" + +[patch.crates-io] +ruma = { git = "https://github.com/matrix-org/ruma/", branch = "secrets" } +ruma-identifiers = { git = "https://github.com/matrix-org/ruma", branch = "secrets" } diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index 8355bd14dd..dff404f456 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -2,17 +2,10 @@ use matrix_sdk_crypto::{ store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError, + SignatureError as InnerSignatureError, SecretImportError as RustSecretImportError, }; use ruma::identifiers::Error as RumaIdentifierError; -#[derive(Debug, thiserror::Error)] -pub enum MachineCreationError { - #[error(transparent)] - Identifier(#[from] RumaIdentifierError), - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), -} - #[derive(Debug, thiserror::Error)] pub enum KeyImportError { #[error(transparent)] @@ -21,6 +14,28 @@ pub enum KeyImportError { CryptoStore(#[from] InnerStoreError), } +#[derive(Debug, thiserror::Error)] +pub enum SecretImportError { + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), + #[error(transparent)] + Import(#[from] RustSecretImportError), +} + +#[derive(Debug, thiserror::Error)] +pub enum SignatureError { + #[error(transparent)] + Signature(#[from] InnerSignatureError), + #[error(transparent)] + Identifier(#[from] RumaIdentifierError), + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), + #[error("Unknown device {0} {1}")] + UnknownDevice(String, String), + #[error("Unknown user identity {0}")] + UnknownUserIdentity(String), +} + #[derive(Debug, thiserror::Error)] pub enum CryptoStoreError { #[error(transparent)] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index eb2cb64e8b..41842f7b6d 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -15,15 +15,18 @@ mod error; mod logger; mod machine; mod responses; +mod users; mod verification; pub use device::Device; -pub use error::{CryptoStoreError, DecryptionError, KeyImportError, MachineCreationError}; +pub use error::{CryptoStoreError, DecryptionError, KeyImportError, SignatureError, SecretImportError}; pub use logger::{set_logger, Logger}; pub use machine::{KeyRequestPair, OlmMachine}; pub use responses::{ - DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, + DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, SignatureUploadRequest, + BootstrapCrossSigningResult, UploadSigningKeysRequest, }; +pub use users::UserIdentity; pub use verification::{ CancelInfo, QrCode, RequestVerificationResult, Sas, ScanResult, StartSasResult, Verification, VerificationRequest, @@ -55,4 +58,59 @@ pub struct DecryptedEvent { pub forwarding_curve25519_chain: Vec, } +/// Struct representing the state of our private cross signing keys, it shows +/// which private cross signing keys we have locally stored. +#[derive(Debug, Clone)] +pub struct CrossSigningStatus { + /// Do we have the master key. + pub has_master: bool, + /// Do we have the self signing key, this one is necessary to sign our own + /// devices. + pub has_self_signing: bool, + /// Do we have the user signing key, this one is necessary to sign other + /// users. + pub has_user_signing: bool, +} + +/// A struct containing private cross signing keys that can be backed up or +/// uploaded to the secret store. +pub struct CrossSigningKeyExport { + /// The seed of the master key encoded as unpadded base64. + pub master_key: Option, + /// The seed of the self signing key encoded as unpadded base64. + pub self_signing_key: Option, + /// The seed of the user signing key encoded as unpadded base64. + pub user_signing_key: Option, +} + +impl From for CrossSigningKeyExport { + fn from(e: matrix_sdk_crypto::CrossSigningKeyExport) -> Self { + Self { + master_key: e.master_key.clone(), + self_signing_key: e.self_signing_key.clone(), + user_signing_key: e.user_signing_key.clone(), + } + } +} + +impl Into for CrossSigningKeyExport { + fn into(self) -> matrix_sdk_crypto::CrossSigningKeyExport { + matrix_sdk_crypto::CrossSigningKeyExport { + master_key: self.master_key, + self_signing_key: self.self_signing_key, + user_signing_key: self.user_signing_key, + } + } +} + +impl From for CrossSigningStatus { + fn from(s: matrix_sdk_crypto::CrossSigningStatus) -> Self { + Self { + has_master: s.has_master, + has_self_signing: s.has_self_signing, + has_user_signing: s.has_user_signing, + } + } +} + include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 048f417228..0be6f0fde1 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -12,6 +12,7 @@ use ruma::{ keys::{ claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, upload_keys::Response as KeysUploadResponse, + upload_signatures::Response as SignatureUploadResponse, }, sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, to_device::send_event_to_device::Response as ToDeviceResponse, @@ -31,14 +32,15 @@ use tokio::runtime::Runtime; use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; use matrix_sdk_crypto::{ decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, EncryptionSettings, - LocalTrust, OlmMachine as InnerMachine, Verification as RustVerification, + LocalTrust, OlmMachine as InnerMachine, UserIdentities, Verification as RustVerification, }; use crate::{ - error::{CryptoStoreError, DecryptionError, MachineCreationError}, + error::{CryptoStoreError, DecryptionError, SecretImportError, SignatureError}, responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, - DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, ProgressListener, - QrCode, Request, RequestType, RequestVerificationResult, ScanResult, StartSasResult, + BootstrapCrossSigningResult, CrossSigningKeyExport, CrossSigningStatus, DecryptedEvent, Device, + DeviceLists, KeyImportError, KeysImportResult, ProgressListener, QrCode, Request, RequestType, + RequestVerificationResult, ScanResult, SignatureUploadRequest, StartSasResult, UserIdentity, Verification, VerificationRequest, }; @@ -68,7 +70,7 @@ impl OlmMachine { /// * `device_id` - The unique ID of the device that owns this machine. /// /// * `path` - The path where the state of the machine should be persisted. - pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { + pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { let user_id = UserId::try_from(user_id)?; let device_id = device_id.into(); let runtime = Runtime::new().unwrap(); @@ -91,6 +93,67 @@ impl OlmMachine { self.inner.device_id().to_string() } + /// Get the display name of our own device. + pub fn display_name(&self) -> Result, CryptoStoreError> { + Ok(self.runtime.block_on(self.inner.dislpay_name())?) + } + + /// Get a cross signing user identity for the given user ID. + pub fn get_identity(&self, user_id: &str) -> Result, CryptoStoreError> { + let user_id = UserId::try_from(user_id)?; + + Ok( + if let Some(identity) = self.runtime.block_on(self.inner.get_identity(&user_id))? { + Some(self.runtime.block_on(UserIdentity::from_rust(identity))?) + } else { + None + }, + ) + } + + /// Check if a user identity is considered to be verified by us. + pub fn is_identity_verified(&self, user_id: &str) -> Result { + let user_id = UserId::try_from(user_id)?; + + Ok( + if let Some(identity) = self.runtime.block_on(self.inner.get_identity(&user_id))? { + match identity { + UserIdentities::Own(i) => i.is_verified(), + UserIdentities::Other(i) => i.verified(), + } + } else { + false + }, + ) + } + + /// Manually the user with the given user ID. + /// + /// This method will attempt to sign the user identity using either our + /// private cross signing key, for other user identities, or our device keys + /// for our own user identity. + /// + /// This methid can fail if we don't have the private part of our user-signing + /// key. + /// + /// Returns a request that needs to be sent out for the user identity to be + /// marked as verified. + pub fn verify_identity(&self, user_id: &str) -> Result { + let user_id = UserId::try_from(user_id)?; + + let user_identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; + + if let Some(user_identity) = user_identity { + Ok(match user_identity { + UserIdentities::Own(i) => self.runtime.block_on(i.verify())?, + UserIdentities::Other(i) => self.runtime.block_on(i.verify())?, + } + .into()) + } else { + Err(SignatureError::UnknownUserIdentity(user_id.to_string())) + } + } + /// Get a `Device` from the store. /// /// # Arguments @@ -111,6 +174,39 @@ impl OlmMachine { .map(|d| d.into())) } + /// Manually the device of the given user with the given device ID. + /// + /// This method will attempt to sign the device using our private cross + /// signing key. + /// + /// This method will always fail if the device belongs to someone else, we + /// can only sign our own devices. + /// + /// It can also fail if we don't have the private part of our self-signing + /// key. + /// + /// Returns a request that needs to be sent out for the device to be marked + /// as verified. + pub fn verify_device( + &self, + user_id: &str, + device_id: &str, + ) -> Result { + let user_id = UserId::try_from(user_id)?; + let device = self + .runtime + .block_on(self.inner.get_device(&user_id, device_id.into()))?; + + if let Some(device) = device { + Ok(self.runtime.block_on(device.verify())?.into()) + } else { + Err(SignatureError::UnknownDevice( + user_id.to_string(), + device_id.to_string(), + )) + } + } + /// Mark the device of the given user with the given device id as trusted. pub fn mark_device_as_trusted( &self, @@ -206,6 +302,9 @@ impl OlmMachine { RequestType::KeysClaim => { KeysClaimResponse::try_from_http_response(response).map(Into::into) } + RequestType::SignatureUpload => { + SignatureUploadResponse::try_from_http_response(response).map(Into::into) + } } .expect("Can't convert json string to response"); @@ -305,21 +404,7 @@ impl OlmMachine { Ok(self .runtime .block_on(self.inner.get_missing_sessions(users.iter()))? - .map(|(request_id, request)| Request::KeysClaim { - request_id: request_id.to_string(), - one_time_keys: request - .one_time_keys - .into_iter() - .map(|(u, d)| { - ( - u.to_string(), - d.into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - ) - }) - .collect(), - })) + .map(|r| r.into())) } /// Share a room key with the given list of users for the given room. @@ -867,6 +952,8 @@ impl OlmMachine { if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { match verification { RustVerification::SasV1(v) => { + // TODO there's a signature upload request here, we'll + // want to return that one as well. self.runtime.block_on(v.confirm())?.0.map(|r| r.into()) } RustVerification::QrV1(v) => v.confirm_scanning().map(|r| r.into()), @@ -1114,4 +1201,49 @@ impl OlmMachine { }) }) } + + /// Create a new private cross signing identity and create a request to + /// upload the public part of it to the server. + pub fn bootstrap_cross_signing(&self) -> Result { + Ok(self + .runtime + .block_on(self.inner.bootstrap_cross_signing(true))? + .into()) + } + + /// Get the status of the private cross signing keys. + /// + /// This can be used to check which private cross signing keys we have + /// stored locally. + pub fn cross_signing_status(&self) -> CrossSigningStatus { + self.runtime + .block_on(self.inner.cross_signing_status()) + .into() + } + + /// Export all our private cross signing keys. + /// + /// The export will contain the seed for the ed25519 keys as a base64 + /// encoded string. + /// + /// This method returns `None` if we don't have any private cross signing keys. + pub fn export_cross_signing_keys(&self) -> Option { + self.runtime + .block_on(self.inner.export_cross_signing_keys()) + .map(|e| e.into()) + } + + /// Import our private cross signing keys. + /// + /// The export needs to contain the seed for the ed25519 keys as a base64 + /// encoded string. + pub fn import_cross_signing_keys( + &self, + export: CrossSigningKeyExport, + ) -> Result<(), SecretImportError> { + self.runtime + .block_on(self.inner.import_cross_signing_keys(export.into()))?; + + Ok(()) + } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index ef0bdd3495..f54c00cba2 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -10,18 +10,28 @@ callback interface ProgressListener { void on_progress(i32 progress, i32 total); }; -[Error] -enum MachineCreationError { - "Identifier", - "CryptoStore", -}; - [Error] enum KeyImportError { "Export", "CryptoStore", }; +[Error] +enum SignatureError { + "Signature", + "Identifier", + "CryptoStore", + "UnknownDevice", + "UnknownUserIdentity", +}; + +[Error] +enum SecretImportError { + "Import", + "CryptoStore", +}; + + [Error] enum CryptoStoreError { "CryptoStore", @@ -65,6 +75,45 @@ dictionary Device { boolean cross_signing_trusted; }; +[Enum] +interface UserIdentity { + Own( + string user_id, + boolean trusts_our_own_device, + string master_key, + string self_signing_key, + string user_signing_key + ); + Other( + string user_id, + string master_key, + string self_signing_key + ); +}; + +dictionary CrossSigningStatus { + boolean has_master; + boolean has_self_signing; + boolean has_user_signing; +}; + +dictionary CrossSigningKeyExport { + string? master_key; + string? self_signing_key; + string? user_signing_key; +}; + +dictionary UploadSigningKeysRequest { + string master_key; + string self_signing_key; + string user_signing_key; +}; + +dictionary BootstrapCrossSigningResult { + UploadSigningKeysRequest upload_signing_keys_request; + SignatureUploadRequest signature_request; +}; + dictionary CancelInfo { string cancel_code; string reason; @@ -155,6 +204,11 @@ interface Request { KeysQuery(string request_id, sequence users); KeysClaim(string request_id, record> one_time_keys); RoomMessage(string request_id, string room_id, string event_type, string content); + SignatureUpload(string request_id, string body); +}; + +dictionary SignatureUploadRequest { + string body; }; enum RequestType { @@ -162,10 +216,11 @@ enum RequestType { "KeysClaim", "KeysUpload", "ToDevice", + "SignatureUpload", }; interface OlmMachine { - [Throws=MachineCreationError] + [Throws=CryptoStoreError] constructor([ByRef] string user_id, [ByRef] string device_id, [ByRef] string path); record identity_keys(); @@ -190,10 +245,16 @@ interface OlmMachine { [Throws=CryptoStoreError] string encrypt([ByRef] string room_id, [ByRef] string event_type, [ByRef] string content); + [Throws=CryptoStoreError] + UserIdentity? get_identity([ByRef] string user_id); + [Throws=SignatureError] + SignatureUploadRequest verify_identity([ByRef] string user_id); [Throws=CryptoStoreError] Device? get_device([ByRef] string user_id, [ByRef] string device_id); [Throws=CryptoStoreError] void mark_device_as_trusted([ByRef] string user_id, [ByRef] string device_id); + [Throws=SignatureError] + SignatureUploadRequest verify_device([ByRef] string user_id, [ByRef] string device_id); [Throws=CryptoStoreError] sequence get_user_devices([ByRef] string user_id); @@ -268,4 +329,13 @@ interface OlmMachine { ); [Throws=CryptoStoreError] void discard_room_key([ByRef] string room_id); + + CrossSigningStatus cross_signing_status(); + [Throws=CryptoStoreError] + BootstrapCrossSigningResult bootstrap_cross_signing(); + CrossSigningKeyExport? export_cross_signing_keys(); + [Throws=SecretImportError] + void import_cross_signing_keys(CrossSigningKeyExport export); + [Throws=CryptoStoreError] + boolean is_identity_verified([ByRef] string user_id); }; diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index 7ddeb87af7..122324761c 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -3,13 +3,18 @@ use std::{collections::HashMap, convert::TryFrom}; use http::Response; +use matrix_sdk_common::uuid::Uuid; use serde_json::json; use ruma::{ api::client::r0::{ keys::{ - claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, + claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse}, + get_keys::Response as KeysQueryResponse, upload_keys::Response as KeysUploadResponse, + upload_signatures::{ + Request as RustSignatureUploadRequest, Response as SignatureUploadResponse, + }, }, sync::sync_events::DeviceLists as RumaDeviceLists, to_device::send_event_to_device::Response as ToDeviceResponse, @@ -21,9 +26,65 @@ use ruma::{ use matrix_sdk_crypto::{ IncomingResponse, OutgoingRequest, OutgoingVerificationRequest as SdkVerificationRequest, - RoomMessageRequest, ToDeviceRequest, + RoomMessageRequest, ToDeviceRequest, UploadSigningKeysRequest as RustUploadSigningKeysRequest, }; +pub struct SignatureUploadRequest { + pub body: String, +} + +impl From for SignatureUploadRequest { + fn from(r: RustSignatureUploadRequest) -> Self { + Self { + body: serde_json::to_string(&r.signed_keys) + .expect("Can't serialize signature upload request"), + } + } +} + +pub struct UploadSigningKeysRequest { + pub master_key: String, + pub self_signing_key: String, + pub user_signing_key: String, +} + +impl From for UploadSigningKeysRequest { + fn from(r: RustUploadSigningKeysRequest) -> Self { + Self { + master_key: serde_json::to_string( + &r.master_key.expect("Request didn't contain a master key"), + ) + .expect("Can't serialize cross signing master key"), + self_signing_key: serde_json::to_string( + &r.self_signing_key + .expect("Request didn't contain a self-signing key"), + ) + .expect("Can't serialize cross signing self-signing key"), + user_signing_key: serde_json::to_string( + &r.user_signing_key + .expect("Request didn't contain a user-signing key"), + ) + .expect("Can't serialize cross signing user-signing key"), + } + } +} + +pub struct BootstrapCrossSigningResult { + pub upload_signing_keys_request: UploadSigningKeysRequest, + pub signature_request: SignatureUploadRequest, +} + +impl From<(RustUploadSigningKeysRequest, RustSignatureUploadRequest)> + for BootstrapCrossSigningResult +{ + fn from(requests: (RustUploadSigningKeysRequest, RustSignatureUploadRequest)) -> Self { + Self { + upload_signing_keys_request: requests.0.into(), + signature_request: requests.1.into(), + } + } +} + pub enum OutgoingVerificationRequest { ToDevice { request_id: String, @@ -87,6 +148,10 @@ pub enum Request { event_type: String, content: String, }, + SignatureUpload { + request_id: String, + body: String, + }, } impl From for Request { @@ -114,8 +179,13 @@ impl From for Request { } } ToDeviceRequest(t) => Request::from(t), - SignatureUpload(_) => todo!("Uploading signatures isn't yet supported"), + SignatureUpload(t) => Request::SignatureUpload { + request_id: r.request_id().to_string(), + body: serde_json::to_string(&t.signed_keys) + .expect("Can't serialize signature upload request"), + }, RoomMessage(r) => Request::from(r), + KeysClaim(c) => (*r.request_id(), c.clone()).into(), } } } @@ -130,6 +200,28 @@ impl From for Request { } } +impl From<(Uuid, KeysClaimRequest)> for Request { + fn from(request_tuple: (Uuid, KeysClaimRequest)) -> Self { + let (request_id, request) = request_tuple; + + Request::KeysClaim { + request_id: request_id.to_string(), + one_time_keys: request + .one_time_keys + .into_iter() + .map(|(u, d)| { + ( + u.to_string(), + d.into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + ) + }) + .collect(), + } + } +} + impl From<&ToDeviceRequest> for Request { fn from(r: &ToDeviceRequest) -> Self { Request::ToDevice { @@ -163,6 +255,7 @@ pub enum RequestType { KeysClaim, KeysUpload, ToDevice, + SignatureUpload, } pub struct DeviceLists { @@ -197,6 +290,7 @@ pub(crate) enum OwnedResponse { KeysUpload(KeysUploadResponse), KeysQuery(KeysQueryResponse), ToDevice(ToDeviceResponse), + SignatureUpload(SignatureUploadResponse), } impl From for OwnedResponse { @@ -223,6 +317,12 @@ impl From for OwnedResponse { } } +impl From for OwnedResponse { + fn from(response: SignatureUploadResponse) -> Self { + Self::SignatureUpload(response) + } +} + impl<'a> Into> for &'a OwnedResponse { fn into(self) -> IncomingResponse<'a> { match self { @@ -230,6 +330,7 @@ impl<'a> Into> for &'a OwnedResponse { OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r), + OwnedResponse::SignatureUpload(r) => IncomingResponse::SignatureUpload(r), } } } diff --git a/rust-sdk/src/users.rs b/rust-sdk/src/users.rs new file mode 100644 index 0000000000..4c1a05a55a --- /dev/null +++ b/rust-sdk/src/users.rs @@ -0,0 +1,61 @@ +use matrix_sdk_crypto::UserIdentities; +use ruma::encryption::CrossSigningKey; + +use crate::CryptoStoreError; + +/// Enum representing cross signing identities of our own user or some other +/// user. +pub enum UserIdentity { + /// Our own user identity. + Own { + /// The unique id of our own user. + user_id: String, + /// Does our own user identity trust our own device. + trusts_our_own_device: bool, + /// The public master key of our identity. + master_key: String, + /// The public user-signing key of our identity. + user_signing_key: String, + /// The public self-signing key of our identity. + self_signing_key: String, + }, + /// The user identity of other users. + Other { + /// The unique id of the user. + user_id: String, + /// The public master key of the identity. + master_key: String, + /// The public self-signing key of our identity. + self_signing_key: String, + }, +} + +impl UserIdentity { + pub(crate) async fn from_rust(i: UserIdentities) -> Result { + Ok(match i { + UserIdentities::Own(i) => { + let master: CrossSigningKey = i.master_key().to_owned().into(); + let user_signing: CrossSigningKey = i.user_signing_key().to_owned().into(); + let self_signing: CrossSigningKey = i.self_signing_key().to_owned().into(); + + UserIdentity::Own { + user_id: i.user_id().to_string(), + trusts_our_own_device: i.trusts_our_own_device().await?, + master_key: serde_json::to_string(&master)?, + user_signing_key: serde_json::to_string(&user_signing)?, + self_signing_key: serde_json::to_string(&self_signing)?, + } + } + UserIdentities::Other(i) => { + let master: CrossSigningKey = i.master_key().to_owned().into(); + let self_signing: CrossSigningKey = i.self_signing_key().to_owned().into(); + + UserIdentity::Other { + user_id: i.user_id().to_string(), + master_key: serde_json::to_string(&master)?, + self_signing_key: serde_json::to_string(&self_signing)?, + } + } + }) + } +} From c85847df57461ad8249aaba3a4fc0f0566aa1f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 11 Aug 2021 15:27:54 +0200 Subject: [PATCH 151/252] crypto: Add a Rust based CrossSigningService --- .../internal/crypto/DefaultCryptoService.kt | 111 +++++- .../android/sdk/internal/crypto/Device.kt | 82 +++- .../android/sdk/internal/crypto/OlmMachine.kt | 357 ++++++++++++------ .../sdk/internal/crypto/QrCodeVerification.kt | 1 - .../crypto/RustCrossSigningService.kt | 209 ++++++++++ .../sdk/internal/crypto/UserIdentities.kt | 256 +++++++++++++ .../verification/RustVerificationService.kt | 42 +-- 7 files changed, 909 insertions(+), 149 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index b295e484bf..5c5e721100 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -40,6 +40,7 @@ import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.events.model.Content @@ -51,7 +52,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService +import org.matrix.android.sdk.internal.auth.registration.handleUIA import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo @@ -66,6 +67,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse +import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask @@ -78,6 +80,8 @@ import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.SendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask +import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask +import org.matrix.android.sdk.internal.crypto.tasks.UploadSigningKeysTask import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.MoshiProvider @@ -98,6 +102,8 @@ import timber.log.Timber import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.Request import uniffi.olm.RequestType +import uniffi.olm.SignatureUploadRequest +import uniffi.olm.UploadSigningKeysRequest import java.io.File import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicBoolean @@ -109,7 +115,9 @@ internal class RequestSender @Inject constructor( private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, private val uploadKeysTask: UploadKeysTask, private val downloadKeysForUsersTask: DownloadKeysForUsersTask, + private val signaturesUploadTask: UploadSignaturesTask, private val sendVerificationMessageTask: Lazy, + private val uploadSigningKeysTask: UploadSigningKeysTask, ) { suspend fun claimKeys(request: Request.KeysClaim): String { @@ -161,6 +169,55 @@ internal class RequestSender @Inject constructor( return this.sendVerificationMessageTask.get().execute(params) } + suspend fun sendSignatureUpload(request: Request.SignatureUpload) { + sendSignatureUpload(request.body) + } + + suspend fun sendSignatureUpload(request: SignatureUploadRequest) { + sendSignatureUpload(request.body) + } + + private suspend fun sendSignatureUpload(body: String) { + val adapter = MoshiProvider.providesMoshi().adapter>>(Map::class.java) + val signatures = adapter.fromJson(body)!! + val params = UploadSignaturesTask.Params(signatures) + this.signaturesUploadTask.execute(params) + } + + suspend fun uploadCrossSigningKeys( + request: UploadSigningKeysRequest, + interactiveAuthInterceptor: UserInteractiveAuthInterceptor? + ) { + val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) + val masterKey = adapter.fromJson(request.masterKey)!!.toCryptoModel() + val selfSigningKey = adapter.fromJson(request.selfSigningKey)!!.toCryptoModel() + val userSigningKey = adapter.fromJson(request.userSigningKey)!!.toCryptoModel() + + val uploadSigningKeysParams = UploadSigningKeysTask.Params( + masterKey, + userSigningKey, + selfSigningKey, + null + ) + + try { + uploadSigningKeysTask.execute(uploadSigningKeysParams) + } catch (failure: Throwable) { + if (interactiveAuthInterceptor == null + || !handleUIA( + failure = failure, + interceptor = interactiveAuthInterceptor, + retryBlock = { authUpdate -> + uploadSigningKeysTask.execute(uploadSigningKeysParams.copy(userAuthParam = authUpdate)) + } + ) + ) { + Timber.d("## UIA: propagate failure") + throw failure + } + } + } + suspend fun sendToDevice(request: Request.ToDevice) { sendToDevice(request.eventType, request.body, request.requestId) } @@ -208,7 +265,6 @@ internal class DefaultCryptoService @Inject constructor( private val mxCryptoConfig: MXCryptoConfig, // The key backup service. private val keysBackupService: DefaultKeysBackupService, - private val crossSigningService: DefaultCrossSigningService, // Actions private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository, // Tasks @@ -232,6 +288,9 @@ internal class DefaultCryptoService @Inject constructor( // The verification service. private var verificationService: RustVerificationService? = null + // The cross signing service. + private var crossSigningService: RustCrossSigningService? = null + private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() // Locks for some of our operations @@ -294,7 +353,9 @@ internal class DefaultCryptoService @Inject constructor( return if (longFormat) "Rust SDK 0.3" else "0.3" } - override fun getMyDevice(): CryptoDeviceInfo = this.olmMachine!!.ownDevice() + override fun getMyDevice(): CryptoDeviceInfo { + return runBlocking { olmMachine!!.ownDevice() } + } override fun fetchDevicesList(callback: MatrixCallback) { getDevicesTask @@ -394,7 +455,8 @@ internal class DefaultCryptoService @Inject constructor( setRustLogger() val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver, sender) olmMachine = machine - verificationService = RustVerificationService(machine, this.sender) + verificationService = RustVerificationService(machine) + crossSigningService = RustCrossSigningService(machine) Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") @@ -453,7 +515,13 @@ internal class DefaultCryptoService @Inject constructor( return verificationService!! } - override fun crossSigningService() = crossSigningService + override fun crossSigningService(): CrossSigningService { + if (crossSigningService == null) { + internalStart() + } + + return crossSigningService!! + } /** * A sync response has been received @@ -461,6 +529,15 @@ internal class DefaultCryptoService @Inject constructor( suspend fun onSyncCompleted() { if (isStarted()) { sendOutgoingRequests() + // This isn't a copy paste error. Sending the outgoing requests may + // claim one-time keys and establish 1-to-1 Olm sessions with devices, while some + // outgoing requests are waiting for an Olm session to be established (e.g. forwarding + // room keys or sharing secrets). + + // The second call sends out those requests that are waiting for the + // keys claim request to be sent out. + // This could be omitted but then devices might be waiting for the next + sendOutgoingRequests() } cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { @@ -491,7 +568,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getCryptoDeviceInfo(userId: String): List { return runBlocking { - this@DefaultCryptoService.olmMachine?.getUserDevices(userId) ?: listOf() + this@DefaultCryptoService.olmMachine?.getCryptoDeviceInfo(userId) ?: listOf() } } @@ -572,7 +649,7 @@ internal class DefaultCryptoService @Inject constructor( * @return the stored device keys for a user. */ override fun getUserDevices(userId: String): MutableList { - return cryptoStore.getUserDevices(userId)?.values?.toMutableList() ?: ArrayList() + return this.getCryptoDeviceInfo(userId).toMutableList() } private fun isEncryptionEnabledForInvitedUser(): Boolean { @@ -845,36 +922,46 @@ internal class DefaultCryptoService @Inject constructor( olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, response) } + private suspend fun signatureUpload(request: Request.SignatureUpload) { + this.sender.sendSignatureUpload(request) + olmMachine!!.markRequestAsSent(request.requestId, RequestType.SIGNATURE_UPLOAD, "{}") + } + private suspend fun sendOutgoingRequests() { outgoingRequestsLock.withLock { coroutineScope { olmMachine!!.outgoingRequests().map { when (it) { - is Request.KeysUpload -> { + is Request.KeysUpload -> { async { uploadKeys(it) } } - is Request.KeysQuery -> { + is Request.KeysQuery -> { async { queryKeys(it) } } - is Request.ToDevice -> { + is Request.ToDevice -> { async { sendToDevice(it) } } - is Request.KeysClaim -> { + is Request.KeysClaim -> { async { claimKeys(it) } } - is Request.RoomMessage -> { + is Request.RoomMessage -> { async { sender.sendRoomMessage(it) } } + is Request.SignatureUpload -> { + async { + signatureUpload(it) + } + } } }.joinAll() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index ec89cb5f8a..e83300ac00 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -20,10 +20,14 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +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.rest.UnsignedDeviceInfo import org.matrix.android.sdk.internal.crypto.verification.prepareMethods import uniffi.olm.CryptoStoreErrorException import uniffi.olm.Device as InnerDevice import uniffi.olm.OlmMachine +import uniffi.olm.SignatureErrorException import uniffi.olm.VerificationRequest /** Class representing a device that supports E2EE in the Matrix world @@ -37,10 +41,27 @@ internal class Device( private val sender: RequestSender, private val listeners: ArrayList, ) { - /** Request an interactive verification to begin + @Throws(CryptoStoreErrorException::class) + private suspend fun refreshData() { + val device = withContext(Dispatchers.IO) { + machine.getDevice(inner.userId, inner.deviceId) + } + + if (device != null) { + this.inner = device + } + } + + /** + * Request an interactive verification to begin * * This sends out a m.key.verification.request event over to-device messaging to * to this device. + * + * If no specific device should be verified, but we would like to request + * verification from all our devices, the + * [org.matrix.android.sdk.internal.crypto.OwnUserIdentity.requestVerification] + * method can be used instead. */ @Throws(CryptoStoreErrorException::class) suspend fun requestVerification(methods: List): VerificationRequest? { @@ -61,6 +82,10 @@ internal class Device( * * This sends out a m.key.verification.start event with the method set to * m.sas.v1 to this device using to-device messaging. + * + * This method will soon be deprecated by [MSC3122](https://github.com/matrix-org/matrix-doc/pull/3122). + * The [requestVerification] method should be used instead. + * */ @Throws(CryptoStoreErrorException::class) suspend fun startVerification(): SasVerification? { @@ -78,7 +103,8 @@ internal class Device( } } - /** Mark this device as locally trusted + /** + * Mark this device as locally trusted * * This won't upload any signatures, it will only mark the device as trusted * in the local database. @@ -89,4 +115,56 @@ internal class Device( machine.markDeviceAsTrusted(inner.userId, inner.deviceId) } } + + /** + * Manually verify this device + * + * This will sign the device with our self-signing key and upload the signatures + * to the server. + * + * This will fail if the device doesn't belong to use or if we don't have the + * private part of our self-signing key. + */ + @Throws(SignatureErrorException::class) + suspend fun verify(): Boolean { + val request = withContext(Dispatchers.IO) { + machine.verifyDevice(inner.userId, inner.deviceId) + } + + this.sender.sendSignatureUpload(request) + + return true + } + + /** + * Get the DeviceTrustLevel of this device + */ + @Throws(CryptoStoreErrorException::class) + suspend fun trustLevel(): DeviceTrustLevel { + refreshData() + return DeviceTrustLevel(crossSigningVerified = inner.crossSigningTrusted, locallyVerified = inner.locallyTrusted) + } + + /** + * Convert this device to a CryptoDeviceInfo. + * + * This will not fetch out fresh data from the Rust side. + **/ + internal fun toCryptoDeviceInfo(): CryptoDeviceInfo { + val keys = this.inner.keys.map { (keyId, key) -> "$keyId:$this.inner.deviceId" to key }.toMap() + + return CryptoDeviceInfo( + this.inner.deviceId, + this.inner.userId, + this.inner.algorithms, + keys, + // The Kotlin side doesn't need to care about signatures, + // so we're not filling this out + mapOf(), + UnsignedDeviceInfo(this.inner.displayName), + DeviceTrustLevel(crossSigningVerified = this.inner.crossSigningTrusted, locallyVerified = this.inner.locallyTrusted), + this.inner.isBlocked, + // TODO + null) + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 21e759cf10..075378a369 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -24,26 +24,34 @@ import java.util.concurrent.ConcurrentHashMap import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor 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.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction 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.util.JsonDict +import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult 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.RestKeyInfo import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo +import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo 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 import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse import timber.log.Timber +import uniffi.olm.CrossSigningKeyExport +import uniffi.olm.CrossSigningStatus import uniffi.olm.CryptoStoreErrorException import uniffi.olm.DecryptionErrorException -import uniffi.olm.Device as InnerDevice import uniffi.olm.DeviceLists import uniffi.olm.KeyRequestPair import uniffi.olm.Logger @@ -51,6 +59,7 @@ import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType +import uniffi.olm.UserIdentity as RustUserIdentity import uniffi.olm.setLogger class CryptoLogger : Logger { @@ -83,27 +92,34 @@ internal class LiveDevice( } } -fun setRustLogger() { - setLogger(CryptoLogger() as Logger) +internal class LiveUserIdentity( + internal var userId: String, + private var observer: UserIdentityUpdateObserver, +) : MutableLiveData>() { + override fun onActive() { + observer.addUserIdentityUpdateListener(this) + } + + override fun onInactive() { + observer.removeUserIdentityUpdateListener(this) + } } -/** Convert a Rust Device into a Kotlin CryptoDeviceInfo */ -private fun toCryptoDeviceInfo(device: InnerDevice): CryptoDeviceInfo { - val keys = device.keys.map { (keyId, key) -> "$keyId:$device.deviceId" to key }.toMap() +internal class LivePrivateCrossSigningKeys( + private var observer: PrivateCrossSigningKeysUpdateObserver, +) : MutableLiveData>() { - return CryptoDeviceInfo( - device.deviceId, - device.userId, - device.algorithms, - keys, - // TODO pass the signatures here, do we need this, why should the - // Kotlin side care about signatures? - mapOf(), - UnsignedDeviceInfo(device.displayName), - DeviceTrustLevel(crossSigningVerified = device.crossSigningTrusted, locallyVerified = device.locallyTrusted), - device.isBlocked, - // TODO - null) + override fun onActive() { + observer.addUserIdentityUpdateListener(this) + } + + override fun onInactive() { + observer.removeUserIdentityUpdateListener(this) + } +} + +fun setRustLogger() { + setLogger(CryptoLogger() as Logger) } internal class DeviceUpdateObserver { @@ -118,6 +134,30 @@ internal class DeviceUpdateObserver { } } +internal class UserIdentityUpdateObserver { + internal val listeners = ConcurrentHashMap() + + fun addUserIdentityUpdateListener(userIdentity: LiveUserIdentity) { + listeners[userIdentity] = userIdentity.userId + } + + fun removeUserIdentityUpdateListener(userIdentity: LiveUserIdentity) { + listeners.remove(userIdentity) + } +} + +internal class PrivateCrossSigningKeysUpdateObserver { + internal val listeners = ConcurrentHashMap() + + fun addUserIdentityUpdateListener(liveKeys: LivePrivateCrossSigningKeys) { + listeners[liveKeys] = Unit + } + + fun removeUserIdentityUpdateListener(liveKeys: LivePrivateCrossSigningKeys) { + listeners.remove(liveKeys) + } +} + internal class OlmMachine( user_id: String, device_id: String, @@ -127,6 +167,8 @@ internal class OlmMachine( ) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) private val deviceUpdateObserver = deviceObserver + private val userIdentityUpdateObserver = UserIdentityUpdateObserver() + private val privateKeysUpdateObserver = PrivateCrossSigningKeysUpdateObserver() internal val verificationListeners = ArrayList() /** Get our own user ID. */ @@ -148,11 +190,42 @@ internal class OlmMachine( return this.inner } - fun ownDevice(): CryptoDeviceInfo { + /** Update all of our live device listeners. */ + private suspend fun updateLiveDevices() { + for ((liveDevice, users) in deviceUpdateObserver.listeners) { + val devices = getCryptoDeviceInfo(users) + liveDevice.postValue(devices) + } + } + + private suspend fun updateLiveUserIdentities() { + for ((liveIdentity, userId) in userIdentityUpdateObserver.listeners) { + val identity = getIdentity(userId)?.toMxCrossSigningInfo().toOptional() + liveIdentity.postValue(identity) + } + } + + private suspend fun updateLivePrivateKeys() { + val keys = this.exportCrossSigningKeys().toOptional() + + for (liveKeys in privateKeysUpdateObserver.listeners.keys()) { + liveKeys.postValue(keys) + } + } + + /** + * Get our own device info as [CryptoDeviceInfo]. + */ + suspend fun ownDevice(): CryptoDeviceInfo { val deviceId = this.deviceId() val keys = this.identityKeys().map { (keyId, key) -> "$keyId:$deviceId" to key }.toMap() + val crossSigningVerified = when (val ownIdentity = this.getIdentity(this.userId())) { + is OwnUserIdentity -> ownIdentity.trustsOurOwnDevice() + else -> false + } + return CryptoDeviceInfo( this.deviceId(), this.userId(), @@ -161,7 +234,7 @@ internal class OlmMachine( keys, mapOf(), UnsignedDeviceInfo(), - DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), + DeviceTrustLevel(crossSigningVerified, locallyVerified = true), false, null) } @@ -170,7 +243,7 @@ internal class OlmMachine( * Get the list of outgoing requests that need to be sent to the homeserver. * * After the request was sent out and a successful response was received the response body - * should be passed back to the state machine using the markRequestAsSent() method. + * should be passed back to the state machine using the [markRequestAsSent] method. * * @return the list of requests that needs to be sent to the homeserver */ @@ -197,6 +270,7 @@ internal class OlmMachine( if (requestType == RequestType.KEYS_QUERY) { updateLiveDevices() + updateLiveUserIdentities() } } @@ -218,24 +292,30 @@ internal class OlmMachine( toDevice: ToDeviceSyncResponse?, deviceChanges: DeviceListResponse?, keyCounts: DeviceOneTimeKeysCountSyncResponse? - ): ToDeviceSyncResponse = - withContext(Dispatchers.IO) { - val counts: MutableMap = mutableMapOf() + ): ToDeviceSyncResponse { + val response = withContext(Dispatchers.IO) { + val counts: MutableMap = mutableMapOf() - if (keyCounts?.signedCurve25519 != null) { - counts["signed_curve25519"] = keyCounts.signedCurve25519 - } - - val devices = - DeviceLists( - deviceChanges?.changed ?: listOf(), deviceChanges?.left ?: listOf()) - val adapter = - MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) - val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! - - adapter.fromJson(inner.receiveSyncChanges(events, devices, counts))!! + if (keyCounts?.signedCurve25519 != null) { + counts["signed_curve25519"] = keyCounts.signedCurve25519 } + val devices = + DeviceLists( + deviceChanges?.changed ?: listOf(), deviceChanges?.left ?: listOf()) + val adapter = + MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) + val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! + + adapter.fromJson(inner.receiveSyncChanges(events, devices, counts))!! + } + + // We may get cross signing keys over a to-device event, update our listeners. + this.updateLivePrivateKeys() + + return response + } + /** * Mark the given list of users to be tracked, triggering a key query request for them. * @@ -251,13 +331,13 @@ internal class OlmMachine( * Generate one-time key claiming requests for all the users we are missing sessions for. * * After the request was sent out and a successful response was received the response body - * should be passed back to the state machine using the markRequestAsSent() method. + * should be passed back to the state machine using the [markRequestAsSent] method. * - * This method should be called every time before a call to shareRoomKey() is made. + * This method should be called every time before a call to [shareRoomKey] is made. * * @param users The list of users for which we would like to establish 1:1 Olm sessions for. * - * @return A keys claim request that needs to be sent out to the server. + * @return A [Request.KeysClaim] request that needs to be sent out to the server. */ @Throws(CryptoStoreErrorException::class) suspend fun getMissingSessions(users: List): Request? = @@ -279,7 +359,7 @@ internal class OlmMachine( * @param users The list of users which are considered to be members of the room and should * receive the room key. * - * @return The list of requests that need to be sent out. + * @return The list of [Request.ToDevice] that need to be sent out. */ @Throws(CryptoStoreErrorException::class) suspend fun shareRoomKey(roomId: String, users: List): List = @@ -288,21 +368,18 @@ internal class OlmMachine( /** * Encrypt the given event with the given type and content for the given room. * - * **Note**: A room key needs to be shared with the group of users that are members in the given - * room. If this is not done this method will panic. + * **Note**: A room key needs to be shared with the group of users that are members + * in the given room. If this is not done this method will panic. * * The usual flow to encrypt an event using this state machine is as follows: * * 1. Get the one-time key claim request to establish 1:1 Olm sessions for - * ``` - * the room members of the room we wish to participate in. This is done - * using the [`get_missing_sessions()`](#method.get_missing_sessions) - * method. This method call should be locked per call. - * ``` - * 2. Share a room key with all the room members using the shareRoomKey(). - * ``` - * This method call should be locked per room. - * ``` + * the room members of the room we wish to participate in. This is done + * using the [getMissingSessions] method. This method call should be locked per call. + * + * 2. Share a room key with all the room members using the [shareRoomKey]. + * This method call should be locked per room. + * * 3. Encrypt the event using this method. * * 4. Send the encrypted event to the server. @@ -316,7 +393,7 @@ internal class OlmMachine( * * @param content the JSON content of the event * - * @return The encrypted version of the content + * @return The encrypted version of the [Content] */ @Throws(CryptoStoreErrorException::class) suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = @@ -334,7 +411,7 @@ internal class OlmMachine( * * @param event The serialized encrypted version of the event. * - * @return the decrypted version of the event. + * @return the decrypted version of the event as a [MXEventDecryptionResult]. */ @Throws(MXCryptoError::class) suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = @@ -421,9 +498,44 @@ internal class OlmMachine( ImportRoomKeysResult(result.total, result.imported) } + @Throws(CryptoStoreErrorException::class) + suspend fun getIdentity(userId: String): UserIdentities? { + val identity = withContext(Dispatchers.IO) { + inner.getIdentity(userId) + } + val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) + + return when (identity) { + is RustUserIdentity.Other -> { + val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel() + val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel() + + UserIdentity(identity.userId, masterKey, selfSigningKey, this, this.requestSender) + } + is RustUserIdentity.Own -> { + val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel() + val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel() + val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel() + + OwnUserIdentity( + identity.userId, + masterKey, + selfSigningKey, + userSigningKey, + identity.trustsOurOwnDevice, + this, + this.requestSender + ) + } + null -> null + } + } + /** * Get a `Device` from the store. * + * This method returns our own device as well. + * * @param userId The id of the device owner. * * @param deviceId The id of the device itself. @@ -437,21 +549,25 @@ internal class OlmMachine( // using our ownDevice method ownDevice() } else { - val device = getRawDevice(userId, deviceId) ?: return null - toCryptoDeviceInfo(device) + getDevice(userId, deviceId)?.toCryptoDeviceInfo() } } - private suspend fun getRawDevice(userId: String, deviceId: String): InnerDevice? = - withContext(Dispatchers.IO) { - inner.getDevice(userId, deviceId) - } - + @Throws(CryptoStoreErrorException::class) suspend fun getDevice(userId: String, deviceId: String): Device? { - val device = this.getRawDevice(userId, deviceId) ?: return null + val device = withContext(Dispatchers.IO) { + inner.getDevice(userId, deviceId) + } ?: return null + return Device(this.inner, device, this.requestSender, this.verificationListeners) } + suspend fun getUserDevices(userId: String): List { + return withContext(Dispatchers.IO) { + inner.getUserDevices(userId).map { Device(inner, it, requestSender, verificationListeners) } + } + } + /** * Get all devices of an user. * @@ -460,36 +576,18 @@ internal class OlmMachine( * @return The list of Devices or an empty list if there aren't any. */ @Throws(CryptoStoreErrorException::class) - suspend fun getUserDevices(userId: String): List { - val devices = withContext(Dispatchers.IO) { - inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) }.toMutableList() - } + suspend fun getCryptoDeviceInfo(userId: String): List { + val devices = this.getUserDevices(userId).map { it.toCryptoDeviceInfo() }.toMutableList() // EA doesn't differentiate much between our own and other devices of // while the rust-sdk does, append our own device here. - val ownDevice = this.ownDevice() - - if (userId == ownDevice.userId) { - devices.add(ownDevice) + if (userId == this.userId()) { + devices.add(this.ownDevice()) } return devices } - suspend fun getUserDevicesMap(userIds: List): MXUsersDevicesMap { - val userMap = MXUsersDevicesMap() - - for (user in userIds) { - val devices = getUserDevices(user) - - for (device in devices) { - userMap.setObject(user, device.deviceId, device) - } - } - - return userMap - } - /** * Get all the devices of multiple users. * @@ -497,34 +595,45 @@ internal class OlmMachine( * * @return The list of Devices or an empty list if there aren't any. */ - suspend fun getUserDevices(userIds: List): List { + private suspend fun getCryptoDeviceInfo(userIds: List): List { val plainDevices: ArrayList = arrayListOf() for (user in userIds) { - val devices = getUserDevices(user) + val devices = this.getCryptoDeviceInfo(user) plainDevices.addAll(devices) } return plainDevices } - /** Mark the device for the given user with the given device ID as trusted - * - * This will mark the device locally as trusted, it won't upload any type of cross - * signing signature - * */ - @Throws(CryptoStoreErrorException::class) - internal suspend fun markDeviceAsTrusted(userId: String, deviceId: String) = - withContext(Dispatchers.IO) { - inner.markDeviceAsTrusted(userId, deviceId) + suspend fun getUserDevicesMap(userIds: List): MXUsersDevicesMap { + val userMap = MXUsersDevicesMap() + + for (user in userIds) { + val devices = this.getCryptoDeviceInfo(user) + + for (device in devices) { + userMap.setObject(user, device.deviceId, device) + } } - /** Update all of our live device listeners. */ - private suspend fun updateLiveDevices() { - for ((liveDevice, users) in deviceUpdateObserver.listeners) { - val devices = getUserDevices(users) - liveDevice.postValue(devices) - } + return userMap + } + + suspend fun getLiveUserIdentity(userId: String): LiveData> { + val identity = this.getIdentity(userId)?.toMxCrossSigningInfo().toOptional() + val liveIdentity = LiveUserIdentity(userId, this.userIdentityUpdateObserver) + liveIdentity.value = identity + + return liveIdentity + } + + suspend fun getLivePrivateCrossSigningKeys(): LiveData> { + val keys = this.exportCrossSigningKeys().toOptional() + val liveKeys = LivePrivateCrossSigningKeys(this.privateKeysUpdateObserver) + liveKeys.value = keys + + return liveKeys } /** @@ -538,7 +647,7 @@ internal class OlmMachine( * @return The list of Devices or an empty list if there aren't any. */ suspend fun getLiveDevices(userIds: List): LiveData> { - val plainDevices = getUserDevices(userIds) + val plainDevices = getCryptoDeviceInfo(userIds) val devices = LiveDevice(userIds, deviceUpdateObserver) devices.value = plainDevices @@ -556,7 +665,7 @@ internal class OlmMachine( * @param userId The ID of the user for which we would like to fetch the * verification requests * - * @return The list of VerificationRequests that we share with the given user + * @return The list of [VerificationRequest] that we share with the given user */ fun getVerificationRequests(userId: String): List { return this.inner.getVerificationRequests(userId).map { @@ -585,9 +694,10 @@ internal class OlmMachine( } } - /** Get an active verification for the given user and given flow ID + /** Get an active verification for the given user and given flow ID. * - * This can return a SAS verification or a QR code verification + * @return Either a [SasVerification] verification or a [QrCodeVerification] + * verification. */ fun getVerification(userId: String, flowId: String): VerificationTransaction? { return when (val verification = this.inner.getVerification(userId, flowId)) { @@ -613,4 +723,41 @@ internal class OlmMachine( } } } + + suspend fun bootstrapCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?) { + val requests = withContext(Dispatchers.IO) { + inner.bootstrapCrossSigning() + } + + this.requestSender.uploadCrossSigningKeys(requests.uploadSigningKeysRequest, uiaInterceptor) + this.requestSender.sendSignatureUpload(requests.signatureRequest) + } + + /** + * Get the status of our private cross signing keys, i.e. which private keys do we have stored locally. + */ + fun crossSigningStatus(): CrossSigningStatus { + return this.inner.crossSigningStatus() + } + + suspend fun exportCrossSigningKeys(): PrivateKeysInfo? { + val export = withContext(Dispatchers.IO) { + inner.exportCrossSigningKeys() + + } ?: return null + + return PrivateKeysInfo(export.masterKey, export.selfSigningKey, export.userSigningKey) + } + + suspend fun importCrossSigningKeys(export: PrivateKeysInfo): UserTrustResult { + val rustExport = CrossSigningKeyExport(export.master, export.selfSigned, export.user) + + withContext(Dispatchers.IO) { + inner.importCrossSigningKeys(rustExport) + } + + this.updateLivePrivateKeys() + // TODO map the errors from importCrossSigningKeys to the UserTrustResult + return UserTrustResult.Success + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index d9d914d789..ea6eba5c6c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -28,7 +28,6 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher import uniffi.olm.CryptoStoreErrorException import uniffi.olm.OlmMachine -import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.QrCode import uniffi.olm.Verification diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt new file mode 100644 index 0000000000..97a15c3af0 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto + +import androidx.lifecycle.LiveData +import kotlinx.coroutines.runBlocking +import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.NoOpMatrixCallback +import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService +import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustResult +import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult +import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified +import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo +import org.matrix.android.sdk.internal.extensions.foldToCallback + +internal class RustCrossSigningService(private val olmMachine: OlmMachine) : CrossSigningService { + /** + * Is our own device signed by our own cross signing identity + */ + override fun isCrossSigningVerified(): Boolean { + return when (val identity = runBlocking { olmMachine.getIdentity(olmMachine.userId()) }) { + is OwnUserIdentity -> identity.trustsOurOwnDevice() + else -> false + } + } + + override fun isUserTrusted(otherUserId: String): Boolean { + // This seems to be used only in tests. + return this.checkUserTrust(otherUserId).isVerified() + } + + /** + * Will not force a download of the key, but will verify signatures trust chain. + * Checks that my trusted user key has signed the other user UserKey + */ + override fun checkUserTrust(otherUserId: String): UserTrustResult { + val identity = runBlocking { olmMachine.getIdentity(olmMachine.userId()) } + + // While UserTrustResult has many different states, they are by the callers + // converted to a boolean value immediately, thus we don't need to support + // all the values. + return if (identity != null) { + val verified = runBlocking { identity.verified() } + + if (verified) { + UserTrustResult.Success + } else { + UserTrustResult.UnknownCrossSignatureInfo(otherUserId) + } + } else { + UserTrustResult.CrossSigningNotConfigured(otherUserId) + } + } + + /** + * Initialize cross signing for this user. + * Users needs to enter credentials + */ + override fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?, callback: MatrixCallback) { + runBlocking { runCatching { olmMachine.bootstrapCrossSigning(uiaInterceptor) }.foldToCallback(callback) } + } + + /** + * Inject the private cross signing keys, likely from backup, into our store. + * + * This will check if the injected private cross signing keys match the public ones provided + * by the server and if they do so + */ + override fun checkTrustFromPrivateKeys( + masterKeyPrivateKey: String?, + uskKeyPrivateKey: String?, + sskPrivateKey: String? + ): UserTrustResult { + val export = PrivateKeysInfo(masterKeyPrivateKey, sskPrivateKey, uskKeyPrivateKey) + return runBlocking { olmMachine.importCrossSigningKeys(export) } + } + + /** + * Get the public cross signing keys for the given user + * + * @param otherUserId The ID of the user for which we would like to fetch the cross signing keys. + */ + override fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? { + return runBlocking { olmMachine.getIdentity(otherUserId)?.toMxCrossSigningInfo() } + } + + override fun getLiveCrossSigningKeys(userId: String): LiveData> { + return runBlocking { olmMachine.getLiveUserIdentity(userId) } + } + + /** Get our own public cross signing keys */ + override fun getMyCrossSigningKeys(): MXCrossSigningInfo? { + return getUserCrossSigningKeys(olmMachine.userId()) + } + + /** Get our own private cross signing keys */ + override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? { + return runBlocking { olmMachine.exportCrossSigningKeys() } + } + + override fun getLiveCrossSigningPrivateKeys(): LiveData> { + return runBlocking { olmMachine.getLivePrivateCrossSigningKeys() } + } + + /** + * Can we sign our other devices or other users? + * + * Returning true means that we have the private self-signing and user-signing keys at hand. + */ + override fun canCrossSign(): Boolean { + val status = this.olmMachine.crossSigningStatus() + + return status.hasSelfSigning && status.hasUserSigning + } + + override fun allPrivateKeysKnown(): Boolean { + val status = this.olmMachine.crossSigningStatus() + + return status.hasMaster && status.hasSelfSigning && status.hasUserSigning + } + + /** Mark a user identity as trusted and sign and upload signatures of our user-signing key to the server */ + override fun trustUser(otherUserId: String, callback: MatrixCallback) { + // This is only used in a test + val userIdentity = runBlocking { olmMachine.getIdentity(otherUserId) } + + if (userIdentity != null) { + runBlocking { userIdentity.verify() } + callback.onSuccess(Unit) + } else { + callback.onFailure(Throwable("## CrossSigning - CrossSigning is not setup for this account")) + } + } + + /** Mark our own master key as trusted */ + override fun markMyMasterKeyAsTrusted() { + // This doesn't seem to be used? + this.trustUser(this.olmMachine.userId(), NoOpMatrixCallback()) + } + + /** + * Sign one of your devices and upload the signature + */ + override fun trustDevice(deviceId: String, callback: MatrixCallback) { + val device = runBlocking { olmMachine.getDevice(olmMachine.userId(), deviceId) } + + return if (device != null) { + val verified = runBlocking { device.verify() } + + if (verified) { + callback.onSuccess(Unit) + } else { + callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known, or not yours")) + } + } else { + callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known")) + } + } + + /** + * Check if a device is trusted + * + * This will check that we have a valid trust chain from our own master key to a device, either + * using the self-signing key for our own devices or using the user-signing key and the master + * key of another user. + */ + override fun checkDeviceTrust(otherUserId: String, otherDeviceId: String, locallyTrusted: Boolean?): DeviceTrustResult { + val device = runBlocking { olmMachine.getDevice(otherUserId, otherDeviceId) } + + return if (device != null) { + // TODO i don't quite understand the semantics here and there are no docs for + // DeviceTrustResult, what do the different result types mean exactly, + // do you return success only if the Device is cross signing verified? + // what about the local trust if it isn't? why is the local trust passed as an argument here? + DeviceTrustResult.Success(runBlocking { device.trustLevel() }) + } else { + DeviceTrustResult.UnknownDevice(otherDeviceId) + } + } + + override fun onSecretMSKGossip(mskPrivateKey: String) { + // This seems to be unused. + } + + override fun onSecretSSKGossip(sskPrivateKey: String) { + // This as well + } + + override fun onSecretUSKGossip(uskPrivateKey: String) { + // And this. + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt new file mode 100644 index 0000000000..a6d8340063 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey +import org.matrix.android.sdk.internal.crypto.verification.prepareMethods +import uniffi.olm.CryptoStoreErrorException +import uniffi.olm.SignatureErrorException + +/** + * A sealed class representing user identities. + * + * User identities can come in the form of [OwnUserIdentity] which represents + * our own user identity, or [UserIdentity] which represents a user identity + * belonging to another user. + */ +sealed class UserIdentities { + /** + * The unique ID of the user this identity belongs to. + */ + abstract fun userId(): String + + /** + * Check the verification state of the user identity. + * + * @return True if the identity is considered to be verified and trusted, false otherwise. + */ + @Throws(CryptoStoreErrorException::class) + abstract suspend fun verified(): Boolean + + /** + * Manually verify the user identity. + * + * This will either sign the identity with our user-signing key if + * it is a identity belonging to another user, or sign the identity + * with our own device. + * + * Throws a SignatureErrorException if we can't sign the identity, + * if for example we don't have access to our user-signing key. + */ + @Throws(SignatureErrorException::class) + abstract suspend fun verify() + + /** + * Convert the identity into a MxCrossSigningInfo class. + */ + abstract fun toMxCrossSigningInfo(): MXCrossSigningInfo +} + +/** + * A class representing our own user identity. + * + * This is backed by the public parts of our cross signing keys. + **/ +internal class OwnUserIdentity( + private val userId: String, + private val masterKey: CryptoCrossSigningKey, + private val selfSigningKey: CryptoCrossSigningKey, + private val userSigningKey: CryptoCrossSigningKey, + private val trustsOurOwnDevice: Boolean, + private val olmMachine: OlmMachine, + private val requestSender: RequestSender) : UserIdentities() { + /** + * Our own user id. + */ + override fun userId() = this.userId + + /** + * Manually verify our user identity. + * + * This signs the identity with our own device and upload the signatures to the server. + * + * To perform an interactive verification user the [requestVerification] method instead. + */ + @Throws(SignatureErrorException::class) + override suspend fun verify() { + val request = withContext(Dispatchers.Default) { olmMachine.inner().verifyIdentity(userId) } + this.requestSender.sendSignatureUpload(request) + } + + /** + * Check the verification state of the user identity. + * + * @return True if the identity is considered to be verified and trusted, false otherwise. + */ + @Throws(CryptoStoreErrorException::class) + override suspend fun verified(): Boolean { + return withContext(Dispatchers.IO) { olmMachine.inner().isIdentityVerified(userId) } + } + + /** + * Does the identity trust our own device. + */ + fun trustsOurOwnDevice() = this.trustsOurOwnDevice + + /** + * Request an interactive verification to begin + * + * This method should be used if we don't have a specific device we want to verify, + * instead we want to send out a verification request to all our devices. + * + * This sends out an `m.key.verification.request` out to all our devices that support E2EE. + * If the identity should be marked as manually verified, use the [verify] method instead. + * + * If a specific device should be verified instead + * the [org.matrix.android.sdk.internal.crypto.Device.requestVerification] method should be + * used instead. + * + * @param methods The list of [VerificationMethod] that we wish to advertise to the other + * side as being supported. + */ + @Throws(CryptoStoreErrorException::class) + suspend fun requestVerification(methods: List): VerificationRequest { + val stringMethods = prepareMethods(methods) + val result = this.olmMachine.inner().requestSelfVerification(stringMethods) + this.requestSender.sendVerificationRequest(result!!.request) + + return VerificationRequest( + this.olmMachine.inner(), + result.verification, + this.requestSender, + this.olmMachine.verificationListeners + ) + } + + /** + * Convert the identity into a MxCrossSigningInfo class. + */ + override fun toMxCrossSigningInfo(): MXCrossSigningInfo { + val masterKey = this.masterKey + val selfSigningKey = this.selfSigningKey + val userSigningKey = this.userSigningKey + val trustLevel = DeviceTrustLevel(runBlocking { verified() }, false) + // TODO remove this, this is silly, we have way too many methods to check if a user is verified + masterKey.trustLevel = trustLevel + selfSigningKey.trustLevel = trustLevel + userSigningKey.trustLevel = trustLevel + + val crossSigningKeys = listOf(masterKey, selfSigningKey, userSigningKey) + return MXCrossSigningInfo(this.userId, crossSigningKeys) + } +} + +/** + * A class representing another users identity. + * + * This is backed by the public parts of the users cross signing keys. + **/ +internal class UserIdentity( + private val userId: String, + private val masterKey: CryptoCrossSigningKey, + private val selfSigningKey: CryptoCrossSigningKey, + private val olmMachine: OlmMachine, + private val requestSender: RequestSender) : UserIdentities() { + /** + * The unique ID of the user that this identity belongs to. + */ + override fun userId() = this.userId + + /** + * Manually verify this user identity. + * + * This signs the identity with our user-signing key. + * + * This method can fail if we don't have the private part of our user-signing key at hand. + * + * To perform an interactive verification user the [requestVerification] method instead. + */ + @Throws(SignatureErrorException::class) + override suspend fun verify() { + val request = withContext(Dispatchers.Default) { olmMachine.inner().verifyIdentity(userId) } + this.requestSender.sendSignatureUpload(request) + } + + /** + * Check the verification state of the user identity. + * + * @return True if the identity is considered to be verified and trusted, false otherwise. + */ + override suspend fun verified(): Boolean { + return withContext(Dispatchers.IO) { olmMachine.inner().isIdentityVerified(userId) } + } + + /** + * Request an interactive verification to begin. + * + * This method should be used if we don't have a specific device we want to verify, + * instead we want to send out a verification request to all our devices. For user + * identities that aren't our own, this method should be the primary way to verify users + * and their devices. + * + * This sends out an `m.key.verification.request` out to the room with the given room ID. + * The room **must** be a private DM that we share with this user. + * + * If the identity should be marked as manually verified, use the [verify] method instead. + * + * If a specific device should be verified instead + * the [org.matrix.android.sdk.internal.crypto.Device.requestVerification] method should be + * used instead. + * + * @param methods The list of [VerificationMethod] that we wish to advertise to the other + * side as being supported. + * @param roomId The ID of the room which represents a DM that we share with this user. + * @param transactionId The transaction id that should be used for the request that sends + * the `m.key.verification.request` to the room. + */ + @Throws(CryptoStoreErrorException::class) + suspend fun requestVerification( + methods: List, + roomId: String, + transactionId: String + ): VerificationRequest { + val stringMethods = prepareMethods(methods) + val content = this.olmMachine.inner().verificationRequestContent(this.userId, stringMethods)!! + + val eventID = requestSender.sendRoomMessage(EventType.MESSAGE, roomId, content, transactionId) + + val innerRequest = this.olmMachine.inner().requestVerification(this.userId, roomId, eventID, stringMethods)!! + + return VerificationRequest( + this.olmMachine.inner(), + innerRequest, + this.requestSender, + this.olmMachine.verificationListeners + ) + } + + /** + * Convert the identity into a MxCrossSigningInfo class. + */ + override fun toMxCrossSigningInfo(): MXCrossSigningInfo { + val crossSigningKeys = listOf(this.masterKey, this.selfSigningKey) + return MXCrossSigningInfo(this.userId, crossSigningKeys) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 417e2d5b0d..fd407f5bae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -31,9 +31,9 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent 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.RequestSender +import org.matrix.android.sdk.internal.crypto.OwnUserIdentity import org.matrix.android.sdk.internal.crypto.SasVerification -import org.matrix.android.sdk.internal.crypto.VerificationRequest +import org.matrix.android.sdk.internal.crypto.UserIdentity import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE @@ -124,10 +124,7 @@ internal class UpdateDispatcher(private val listeners: ArrayList? ): PendingVerificationRequest { - val stringMethods = prepareMethods(methods) - - val result = this.olmMachine.inner().requestSelfVerification(stringMethods) - runBlocking { - requestSender.sendVerificationRequest(result!!.request) + val verification = when (val identity = runBlocking { olmMachine.getIdentity(otherUserId) }) { + is OwnUserIdentity -> runBlocking { identity.requestVerification(methods) } + is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices") + null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user") } - return VerificationRequest( - this.olmMachine.inner(), - result!!.verification, - this.requestSender, - this.olmMachine.verificationListeners - ).toPendingVerificationRequest() + return verification.toPendingVerificationRequest() } override fun requestKeyVerificationInDMs( @@ -302,20 +293,13 @@ internal class RustVerificationService( localId: String? ): PendingVerificationRequest { Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") - val stringMethods = prepareMethods(methods) - val content = this.olmMachine.inner().verificationRequestContent(otherUserId, stringMethods)!! - - val eventID = runBlocking { - requestSender.sendRoomMessage(EventType.MESSAGE, roomId, content, localId!!) + val verification = when (val identity = runBlocking { olmMachine.getIdentity(otherUserId) }) { + is UserIdentity -> runBlocking { identity.requestVerification(methods, roomId, localId!!) } + is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user") + null -> throw IllegalArgumentException("The user that we wish to verify doesn't support cross signing") } - val innerRequest = this.olmMachine.inner().requestVerification(otherUserId, roomId, eventID, stringMethods)!! - return VerificationRequest( - this.olmMachine.inner(), - innerRequest, - this.requestSender, - this.olmMachine.verificationListeners - ).toPendingVerificationRequest() + return verification.toPendingVerificationRequest() } override fun readyPendingVerification( From 3365c10fe3b7e642f19ecbe517590dcc4ff35925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 11 Aug 2021 15:48:09 +0200 Subject: [PATCH 152/252] crypto: Add a missing dispatchTxUpdated call to the verifications --- .../sdk/internal/crypto/QrCodeVerification.kt | 22 +++---------- .../sdk/internal/crypto/SasVerification.kt | 33 +++++++------------ 2 files changed, 16 insertions(+), 39 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index ea6eba5c6c..de06691f93 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -42,6 +42,7 @@ internal class QrCodeVerification( private val dispatcher = UpdateDispatcher(listeners) private fun dispatchTxUpdated() { + refreshData() this.dispatcher.dispatchTxUpdated(this) } @@ -101,9 +102,7 @@ internal class QrCodeVerification( inner.reciprocated -> VerificationTxState.Started inner.hasBeenConfirmed -> VerificationTxState.WaitingOtherReciprocateConfirm inner.otherSideScanned -> VerificationTxState.QrScannedByOther - else -> { - VerificationTxState.None - } + else -> VerificationTxState.None } } else { VerificationTxState.None @@ -182,6 +181,7 @@ internal class QrCodeVerification( if (request != null) { this.sender.sendVerificationRequest(request) + dispatchTxUpdated() } } @@ -189,23 +189,11 @@ internal class QrCodeVerification( val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value) if (request != null) { - sendRequest(request) + runBlocking { sender.sendVerificationRequest(request) } + dispatchTxUpdated() } } - /** Send out a verification request in a blocking manner - * - * This is useful since the public methods to accept/confirm/cancel the verification - * aren't suspendable but sending a request out obviously should be. This bridges the - * gap between our suspendable and non-suspendable methods. - */ - private fun sendRequest(request: OutgoingVerificationRequest) { - runBlocking { sender.sendVerificationRequest(request) } - - refreshData() - dispatchTxUpdated() - } - /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { when (val verification = this.machine.getVerification(this.request.otherUser(), this.request.flowId())) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index ad8322a2ab..4756ac5b1c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -29,7 +29,6 @@ import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode import uniffi.olm.CryptoStoreErrorException import uniffi.olm.OlmMachine -import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.Sas import uniffi.olm.Verification @@ -44,6 +43,7 @@ internal class SasVerification( private val dispatcher = UpdateDispatcher(listeners) private fun dispatchTxUpdated() { + refreshData() this.dispatcher.dispatchTxUpdated(this) } @@ -65,16 +65,17 @@ internal class SasVerification( get() { refreshData() val cancelInfo = this.inner.cancelInfo + return when { - cancelInfo != null -> { + cancelInfo != null -> { val cancelCode = safeValueOf(cancelInfo.cancelCode) VerificationTxState.Cancelled(cancelCode, cancelInfo.cancelledByUs) } - this.inner.isDone -> VerificationTxState.Verified - this.inner.haveWeConfirmed -> VerificationTxState.ShortCodeAccepted - this.inner.canBePresented -> VerificationTxState.ShortCodeReady - this.inner.hasBeenAccepted -> VerificationTxState.Accepted - else -> VerificationTxState.OnStarted + inner.isDone -> VerificationTxState.Verified + inner.haveWeConfirmed -> VerificationTxState.ShortCodeAccepted + inner.canBePresented -> VerificationTxState.ShortCodeReady + inner.hasBeenAccepted -> VerificationTxState.Accepted + else -> VerificationTxState.OnStarted } } @Suppress("UNUSED_PARAMETER") @@ -197,7 +198,6 @@ internal class SasVerification( if (request != null) { this.sender.sendVerificationRequest(request) - refreshData() dispatchTxUpdated() } } @@ -209,6 +209,7 @@ internal class SasVerification( } if (request != null) { this.sender.sendVerificationRequest(request) + dispatchTxUpdated() } } @@ -216,23 +217,11 @@ internal class SasVerification( val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value) if (request != null) { - sendRequest(request) + runBlocking { sender.sendVerificationRequest(request) } + dispatchTxUpdated() } } - /** Send out a verification request in a blocking manner - * - * This is useful since the public methods to accept/confirm/cancel the verification - * aren't suspendable but sending a request out obviously should be. This bridges the - * gap between our suspendable and non-suspendable methods. - */ - private fun sendRequest(request: OutgoingVerificationRequest) { - runBlocking { sender.sendVerificationRequest(request) } - - refreshData() - dispatchTxUpdated() - } - /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { From 00d12335120f856fec605e5114d23b00a4bb3957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 11 Aug 2021 15:49:37 +0200 Subject: [PATCH 153/252] crypto: Upload signatures when we confirm a verification as well --- .../sdk/internal/crypto/QrCodeVerification.kt | 12 ++++++--- .../sdk/internal/crypto/SasVerification.kt | 13 +++++++--- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 26 ++++++++++++------- rust-sdk/src/olm.udl | 7 ++++- rust-sdk/src/verification.rs | 12 ++++++++- 6 files changed, 54 insertions(+), 18 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index de06691f93..bb6af2a48c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -174,14 +174,20 @@ internal class QrCodeVerification( */ @Throws(CryptoStoreErrorException::class) private suspend fun confirm() { - val request = withContext(Dispatchers.IO) + val result = withContext(Dispatchers.IO) { machine.confirmVerification(request.otherUser(), request.flowId()) } - if (request != null) { - this.sender.sendVerificationRequest(request) + if (result != null) { + this.sender.sendVerificationRequest(result.request) dispatchTxUpdated() + + val signatureRequest = result.signatureRequest + + if (signatureRequest != null) { + this.sender.sendSignatureUpload(signatureRequest) + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index 4756ac5b1c..61e366ea94 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -204,12 +204,19 @@ internal class SasVerification( @Throws(CryptoStoreErrorException::class) private suspend fun confirm() { - val request = withContext(Dispatchers.IO) { + val result = withContext(Dispatchers.IO) { machine.confirmVerification(inner.otherUserId, inner.flowId) } - if (request != null) { - this.sender.sendVerificationRequest(request) + + if (result != null) { + this.sender.sendVerificationRequest(result.request) dispatchTxUpdated() + + val signatureRequest = result.signatureRequest + + if (signatureRequest != null) { + this.sender.sendSignatureUpload(signatureRequest) + } } } diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 41842f7b6d..7d93ac22b4 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -29,7 +29,7 @@ pub use responses::{ pub use users::UserIdentity; pub use verification::{ CancelInfo, QrCode, RequestVerificationResult, Sas, ScanResult, StartSasResult, Verification, - VerificationRequest, + VerificationRequest, ConfirmVerificationResult, }; /// Callback that will be passed over the FFI to report progress diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 0be6f0fde1..701baa0602 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -38,10 +38,10 @@ use matrix_sdk_crypto::{ use crate::{ error::{CryptoStoreError, DecryptionError, SecretImportError, SignatureError}, responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, - BootstrapCrossSigningResult, CrossSigningKeyExport, CrossSigningStatus, DecryptedEvent, Device, - DeviceLists, KeyImportError, KeysImportResult, ProgressListener, QrCode, Request, RequestType, - RequestVerificationResult, ScanResult, SignatureUploadRequest, StartSasResult, UserIdentity, - Verification, VerificationRequest, + BootstrapCrossSigningResult, ConfirmVerificationResult, CrossSigningKeyExport, + CrossSigningStatus, DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, + ProgressListener, QrCode, Request, RequestType, RequestVerificationResult, ScanResult, + SignatureUploadRequest, StartSasResult, UserIdentity, Verification, VerificationRequest, }; /// A high level state machine that handles E2EE for Matrix. @@ -945,18 +945,26 @@ impl OlmMachine { &self, user_id: &str, flow_id: &str, - ) -> Result, CryptoStoreError> { + ) -> Result, CryptoStoreError> { let user_id = UserId::try_from(user_id)?; Ok( if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { match verification { RustVerification::SasV1(v) => { - // TODO there's a signature upload request here, we'll - // want to return that one as well. - self.runtime.block_on(v.confirm())?.0.map(|r| r.into()) + let (request, signature_request) = self.runtime.block_on(v.confirm())?; + + request.map(|r| ConfirmVerificationResult { + request: r.into(), + signature_request: signature_request.map(|s| s.into()), + }) + } + RustVerification::QrV1(v) => { + v.confirm_scanning().map(|r| ConfirmVerificationResult { + request: r.into(), + signature_request: None, + }) } - RustVerification::QrV1(v) => v.confirm_scanning().map(|r| r.into()), } } else { None diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index f54c00cba2..41c5747bf6 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -180,6 +180,11 @@ dictionary RequestVerificationResult { OutgoingVerificationRequest request; }; +dictionary ConfirmVerificationResult { + OutgoingVerificationRequest request; + SignatureUploadRequest? signature_request; +}; + [Enum] interface Verification { SasV1(Sas sas); @@ -296,7 +301,7 @@ interface OlmMachine { ); [Throws=CryptoStoreError] - OutgoingVerificationRequest? confirm_verification([ByRef] string user_id, [ByRef] string flow_id); + ConfirmVerificationResult? confirm_verification([ByRef] string user_id, [ByRef] string flow_id); OutgoingVerificationRequest? cancel_verification( [ByRef] string user_id, [ByRef] string flow_id, diff --git a/rust-sdk/src/verification.rs b/rust-sdk/src/verification.rs index d75bc01d3c..39f3012622 100644 --- a/rust-sdk/src/verification.rs +++ b/rust-sdk/src/verification.rs @@ -3,7 +3,7 @@ use matrix_sdk_crypto::{ VerificationRequest as InnerVerificationRequest, }; -use crate::OutgoingVerificationRequest; +use crate::{OutgoingVerificationRequest, SignatureUploadRequest}; /// Enum representing the different verification flows we support. pub enum Verification { @@ -165,6 +165,16 @@ pub struct RequestVerificationResult { pub request: OutgoingVerificationRequest, } +/// A result type for confirming verifications. +pub struct ConfirmVerificationResult { + /// The request that needs to be sent out to notify the other side that we + /// confirmed the verification. + pub request: OutgoingVerificationRequest, + /// A request that will upload signatures of the verified device or user, if + /// the verification is completed and we're able to sign devices or users + pub signature_request: Option, +} + /// The verificatoin request object which then can transition into some concrete /// verification method pub struct VerificationRequest { From f1da77fb6bdd0c59277c935bc7b5543b0fd6e18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 11 Aug 2021 15:51:24 +0200 Subject: [PATCH 154/252] crypto: Avoid converting numbers in to-device requests to floats This mainly avoid converting the type field in m.olm.v1.curve25519-aes-sha2 variant of an m.room.encrypted event that gets sent out over to-device messages. --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 5c5e721100..eff19dda48 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -88,6 +88,7 @@ import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback +import org.matrix.android.sdk.internal.network.parsing.CheckNumberType import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.session.sync.model.DeviceListResponse @@ -227,9 +228,11 @@ internal class RequestSender @Inject constructor( } suspend fun sendToDevice(eventType: String, body: String, transactionId: String) { - // TODO this produces floats for the Olm type fields, which are integers originally. val adapter = MoshiProvider .providesMoshi() + .newBuilder() + .add(CheckNumberType.JSON_ADAPTER_FACTORY) + .build() .adapter>>(Map::class.java) val jsonBody = adapter.fromJson(body)!! From d0502c4f6b6308382480f704d7bc761b31d6913b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 12 Aug 2021 17:06:19 +0200 Subject: [PATCH 155/252] crypto: Fix some clippy warnings --- rust-sdk/src/lib.rs | 10 +++++----- rust-sdk/src/machine.rs | 14 +++++++------- rust-sdk/src/responses.rs | 14 +++++++------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 7d93ac22b4..968632b914 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -93,12 +93,12 @@ impl From for CrossSigningKeyExport { } } -impl Into for CrossSigningKeyExport { - fn into(self) -> matrix_sdk_crypto::CrossSigningKeyExport { +impl From for matrix_sdk_crypto::CrossSigningKeyExport { + fn from(e: CrossSigningKeyExport) -> Self { matrix_sdk_crypto::CrossSigningKeyExport { - master_key: self.master_key, - self_signing_key: self.self_signing_key, - user_signing_key: self.user_signing_key, + master_key: e.master_key, + self_signing_key: e.self_signing_key, + user_signing_key: e.user_signing_key, } } } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 701baa0602..0b8e3cd7ba 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -287,7 +287,7 @@ impl OlmMachine { ) -> Result<(), CryptoStoreError> { let id = Uuid::parse_str(request_id).expect("Can't parse request id"); - let response = response_from_string(&response_body); + let response = response_from_string(response_body); let response: OwnedResponse = match request_type { RequestType::KeysUpload => { @@ -703,7 +703,7 @@ impl OlmMachine { let user_id = UserId::try_from(user_id).ok()?; let methods = methods .into_iter() - .map(|m| VerificationMethod::from(m)) + .map(VerificationMethod::from) .collect(); if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { @@ -733,7 +733,7 @@ impl OlmMachine { let methods = methods .into_iter() - .map(|m| VerificationMethod::from(m)) + .map(VerificationMethod::from) .collect(); Ok(if let Some(identity) = identity.and_then(|i| i.other()) { @@ -781,7 +781,7 @@ impl OlmMachine { let methods = methods .into_iter() - .map(|m| VerificationMethod::from(m)) + .map(VerificationMethod::from) .collect(); Ok(if let Some(identity) = identity.and_then(|i| i.other()) { @@ -818,7 +818,7 @@ impl OlmMachine { let methods = methods .into_iter() - .map(|m| VerificationMethod::from(m)) + .map(VerificationMethod::from) .collect(); Ok( @@ -856,7 +856,7 @@ impl OlmMachine { let methods = methods .into_iter() - .map(|m| VerificationMethod::from(m)) + .map(VerificationMethod::from) .collect(); Ok(if let Some(identity) = identity.and_then(|i| i.own()) { @@ -1025,7 +1025,7 @@ impl OlmMachine { .get_verification(&user_id, flow_id) .and_then(|v| { v.qr_v1() - .and_then(|qr| qr.to_bytes().map(|b| encode(b)).ok()) + .and_then(|qr| qr.to_bytes().map(encode).ok()) }) } diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index 122324761c..693f4f1845 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -263,15 +263,15 @@ pub struct DeviceLists { pub left: Vec, } -impl Into for DeviceLists { - fn into(self) -> RumaDeviceLists { +impl From for RumaDeviceLists { + fn from(d: DeviceLists) -> Self { assign!(RumaDeviceLists::new(), { - changed: self + changed: d .changed .into_iter() .filter_map(|u| UserId::try_from(u).ok()) .collect(), - left: self + left: d .left .into_iter() .filter_map(|u| UserId::try_from(u).ok()) @@ -323,9 +323,9 @@ impl From for OwnedResponse { } } -impl<'a> Into> for &'a OwnedResponse { - fn into(self) -> IncomingResponse<'a> { - match self { +impl<'a> From<&'a OwnedResponse> for IncomingResponse<'a> { + fn from(r: &'a OwnedResponse) -> Self { + match r { OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), From 504fd95b2656e409464ab3f0bae95ae2ce11e9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 13 Aug 2021 20:33:05 +0200 Subject: [PATCH 156/252] crypto: Bump the rust-sdk revision --- rust-sdk/Cargo.toml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 2e5618d727..6ce3f56a75 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -25,11 +25,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "b2ff6cb6ae3d1983a510262021cba27a1bc70d77" +rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "b2ff6cb6ae3d1983a510262021cba27a1bc70d77" +rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" features = ["sled_cryptostore"] [dependencies.tokio] @@ -43,7 +43,3 @@ features = ["client-api"] [build-dependencies] uniffi_build = "0.12.0" - -[patch.crates-io] -ruma = { git = "https://github.com/matrix-org/ruma/", branch = "secrets" } -ruma-identifiers = { git = "https://github.com/matrix-org/ruma", branch = "secrets" } From c266842da9303fad4b4f958ec2f9915763f81108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 12 Oct 2021 12:08:38 +0200 Subject: [PATCH 157/252] crypto: Use getOrPut instead of getOrDefault getOrDefault won't insert the default value into the map, while we do want it to be inserted. --- .../matrix/android/sdk/internal/crypto/DefaultCryptoService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index eff19dda48..c5d1b20fd8 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -874,7 +874,7 @@ internal class DefaultCryptoService @Inject constructor( } } - val keyShareLock = roomKeyShareLocks.getOrDefault(roomId, Mutex()) + val keyShareLock = roomKeyShareLocks.getOrPut(roomId, { Mutex() }) keyShareLock.withLock { coroutineScope { From 28d457312451f266ebb316988b9dd1da6bcd4769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 12 Oct 2021 12:18:02 +0200 Subject: [PATCH 158/252] crypto: Use the correct copyright header for the new files --- .../main/java/org/matrix/android/sdk/internal/crypto/Device.kt | 2 +- .../java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 2 +- .../matrix/android/sdk/internal/crypto/QrCodeVerification.kt | 2 +- .../android/sdk/internal/crypto/RustCrossSigningService.kt | 2 +- .../org/matrix/android/sdk/internal/crypto/SasVerification.kt | 2 +- .../org/matrix/android/sdk/internal/crypto/UserIdentities.kt | 2 +- .../matrix/android/sdk/internal/crypto/VerificationRequest.kt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index e83300ac00..58a742f174 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 075378a369..cec01c870c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index bb6af2a48c..337d9ded6b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index 97a15c3af0..42abcd9e89 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index 61e366ea94..34b3e9fed6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt index a6d8340063..1373e1bbe7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index dcad660fd4..b98b763355 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From d3a761a73a4394f4263d8f43c4e93dd3f6c705da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 12 Oct 2021 12:29:51 +0200 Subject: [PATCH 159/252] crypto: Retry the crypto related requests --- .../internal/crypto/DefaultCryptoService.kt | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index c5d1b20fd8..2272aec7f9 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -120,10 +120,13 @@ internal class RequestSender @Inject constructor( private val sendVerificationMessageTask: Lazy, private val uploadSigningKeysTask: UploadSigningKeysTask, ) { + companion object { + const val REQUEST_RETRY_COUNT = 3 + } suspend fun claimKeys(request: Request.KeysClaim): String { val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) - val response = oneTimeKeysForUsersDeviceTask.execute(claimParams) + val response = oneTimeKeysForUsersDeviceTask.executeRetry(claimParams, REQUEST_RETRY_COUNT) val adapter = MoshiProvider .providesMoshi() .adapter(KeysClaimResponse::class.java) @@ -132,7 +135,7 @@ internal class RequestSender @Inject constructor( suspend fun queryKeys(request: Request.KeysQuery): String { val params = DownloadKeysForUsersTask.Params(request.users, null) - val response = downloadKeysForUsersTask.execute(params) + val response = downloadKeysForUsersTask.executeRetry(params, REQUEST_RETRY_COUNT) val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) return adapter.toJson(response)!! } @@ -141,7 +144,7 @@ internal class RequestSender @Inject constructor( val body = MoshiProvider.providesMoshi().adapter(Map::class.java).fromJson(request.body)!! val params = UploadKeysTask.Params(body) - val response = uploadKeysTask.execute(params) + val response = uploadKeysTask.executeRetry(params, REQUEST_RETRY_COUNT) val adapter = MoshiProvider.providesMoshi().adapter(KeysUploadResponse::class.java) return adapter.toJson(response)!! @@ -167,7 +170,7 @@ internal class RequestSender @Inject constructor( val jsonContent = adapter.fromJson(content) val event = Event(eventType, transactionId, jsonContent, roomId = roomId) val params = SendVerificationMessageTask.Params(event) - return this.sendVerificationMessageTask.get().execute(params) + return this.sendVerificationMessageTask.get().executeRetry(params, REQUEST_RETRY_COUNT) } suspend fun sendSignatureUpload(request: Request.SignatureUpload) { @@ -182,7 +185,7 @@ internal class RequestSender @Inject constructor( val adapter = MoshiProvider.providesMoshi().adapter>>(Map::class.java) val signatures = adapter.fromJson(body)!! val params = UploadSignaturesTask.Params(signatures) - this.signaturesUploadTask.execute(params) + this.signaturesUploadTask.executeRetry(params, REQUEST_RETRY_COUNT) } suspend fun uploadCrossSigningKeys( @@ -209,7 +212,10 @@ internal class RequestSender @Inject constructor( failure = failure, interceptor = interactiveAuthInterceptor, retryBlock = { authUpdate -> - uploadSigningKeysTask.execute(uploadSigningKeysParams.copy(userAuthParam = authUpdate)) + uploadSigningKeysTask.executeRetry( + uploadSigningKeysParams.copy(userAuthParam = authUpdate), + REQUEST_RETRY_COUNT + ) } ) ) { @@ -240,7 +246,7 @@ internal class RequestSender @Inject constructor( userMap.join(jsonBody) val sendToDeviceParams = SendToDeviceTask.Params(eventType, userMap, transactionId) - sendToDeviceTask.execute(sendToDeviceParams) + sendToDeviceTask.executeRetry(sendToDeviceParams, REQUEST_RETRY_COUNT) } } From 406fd0d8d52ee423746d975cf6872b0fdce66192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Sat, 9 Oct 2021 09:48:23 +0200 Subject: [PATCH 160/252] crypto: Initial support for server-side backups of room keys --- .../internal/crypto/DefaultCryptoService.kt | 71 ++- .../android/sdk/internal/crypto/OlmMachine.kt | 32 ++ .../crypto/keysbackup/RustKeyBackupService.kt | 466 ++++++++++++++++++ rust-sdk/Cargo.toml | 21 +- rust-sdk/src/backup_recovery_key.rs | 117 +++++ rust-sdk/src/lib.rs | 50 +- rust-sdk/src/machine.rs | 122 +++-- rust-sdk/src/olm.udl | 49 +- rust-sdk/src/responses.rs | 15 + .../settings/KeysBackupSettingsViewModel.kt | 5 + 10 files changed, 898 insertions(+), 50 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt create mode 100644 rust-sdk/src/backup_recovery_key.rs diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 2272aec7f9..a551617858 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -37,10 +37,12 @@ import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.crypto.MXCryptoConfig import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.events.model.Content @@ -54,7 +56,14 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.auth.registration.handleUIA import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService +import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask 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.MXEncryptEventContentResult @@ -119,6 +128,10 @@ internal class RequestSender @Inject constructor( private val signaturesUploadTask: UploadSignaturesTask, private val sendVerificationMessageTask: Lazy, private val uploadSigningKeysTask: UploadSigningKeysTask, + private val getKeysBackupLastVersionTask: GetKeysBackupLastVersionTask, + private val getKeysBackupVersionTask: GetKeysBackupVersionTask, + private val deleteBackupTask: DeleteBackupTask, + private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, ) { companion object { const val REQUEST_RETRY_COUNT = 3 @@ -192,7 +205,7 @@ internal class RequestSender @Inject constructor( request: UploadSigningKeysRequest, interactiveAuthInterceptor: UserInteractiveAuthInterceptor? ) { - val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) + val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) val masterKey = adapter.fromJson(request.masterKey)!!.toCryptoModel() val selfSigningKey = adapter.fromJson(request.selfSigningKey)!!.toCryptoModel() val userSigningKey = adapter.fromJson(request.userSigningKey)!!.toCryptoModel() @@ -248,6 +261,32 @@ internal class RequestSender @Inject constructor( val sendToDeviceParams = SendToDeviceTask.Params(eventType, userMap, transactionId) sendToDeviceTask.executeRetry(sendToDeviceParams, REQUEST_RETRY_COUNT) } + + suspend fun getKeyBackupVersion(version: String? = null): KeysVersionResult? { + return try { + if (version != null) { + getKeysBackupVersionTask.execute(version) + } else { + getKeysBackupLastVersionTask.execute(Unit) + } + } catch (failure: Throwable) { + if (failure is Failure.ServerError + && failure.error.code == MatrixError.M_NOT_FOUND) { + null + } else { + throw failure + } + } + } + + suspend fun createKeyBackup(body: CreateKeysBackupVersionBody): KeysVersion { + return createKeysBackupVersionTask.execute(body) + } + + suspend fun deleteKeyBackup(version: String) { + val params = DeleteBackupTask.Params(version) + deleteBackupTask.execute(params) + } } /** @@ -272,8 +311,6 @@ internal class DefaultCryptoService @Inject constructor( private val cryptoStore: IMXCryptoStore, // Set of parameters used to configure/customize the end-to-end crypto. private val mxCryptoConfig: MXCryptoConfig, - // The key backup service. - private val keysBackupService: DefaultKeysBackupService, // Actions private val warnOnUnknownDevicesRepository: WarnOnUnknownDeviceRepository, // Tasks @@ -283,6 +320,7 @@ internal class DefaultCryptoService @Inject constructor( private val setDeviceNameTask: SetDeviceNameTask, private val loadRoomMembersTask: LoadRoomMembersTask, private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, + private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, private val coroutineDispatchers: MatrixCoroutineDispatchers, private val taskExecutor: TaskExecutor, private val cryptoCoroutineScope: CoroutineScope, @@ -300,6 +338,9 @@ internal class DefaultCryptoService @Inject constructor( // The cross signing service. private var crossSigningService: RustCrossSigningService? = null + // The key backup service. + private var keysBackupService: RustKeyBackupService? = null + private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() // Locks for some of our operations @@ -448,9 +489,12 @@ internal class DefaultCryptoService @Inject constructor( cryptoStore.open() // this can throw if no backup + /* + TODO tryOrNull { keysBackupService.checkAndStartKeysBackup() } + */ } } @@ -466,6 +510,7 @@ internal class DefaultCryptoService @Inject constructor( olmMachine = machine verificationService = RustVerificationService(machine) crossSigningService = RustCrossSigningService(machine) + keysBackupService = RustKeyBackupService(machine, sender, coroutineDispatchers, cryptoCoroutineScope) Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") @@ -473,6 +518,10 @@ internal class DefaultCryptoService @Inject constructor( Timber.v("Failed create an Olm machine: $throwable") } + tryOrNull { + keysBackupService!!.checkAndStartKeysBackup() + } + // Open the store cryptoStore.open() @@ -494,7 +543,12 @@ internal class DefaultCryptoService @Inject constructor( /** * @return the Keys backup Service */ - override fun keysBackupService() = keysBackupService + override fun keysBackupService(): KeysBackupService { + if (keysBackupService == null) { + internalStart() + } + return keysBackupService!! + } /** * @return the VerificationService @@ -693,7 +747,7 @@ internal class DefaultCryptoService @Inject constructor( eventType: String, roomId: String, callback: MatrixCallback) { - // moved to crypto scope to have uptodate values + // moved to crypto scope to have up to date values cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { val algorithm = getEncryptionAlgorithm(roomId) @@ -971,6 +1025,11 @@ internal class DefaultCryptoService @Inject constructor( signatureUpload(it) } } + is Request.KeysBackup -> { + async { + TODO() + } + } } }.joinAll() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index cec01c870c..7aa6478f4c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -48,6 +48,8 @@ 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.ToDeviceSyncResponse import timber.log.Timber +import uniffi.olm.BackupKey +import uniffi.olm.BackupKeys import uniffi.olm.CrossSigningKeyExport import uniffi.olm.CrossSigningStatus import uniffi.olm.CryptoStoreErrorException @@ -59,6 +61,7 @@ import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType +import uniffi.olm.RoomKeyCounts import uniffi.olm.UserIdentity as RustUserIdentity import uniffi.olm.setLogger @@ -760,4 +763,33 @@ internal class OlmMachine( // TODO map the errors from importCrossSigningKeys to the UserTrustResult return UserTrustResult.Success } + + suspend fun sign(message: String): Map> { + return withContext(Dispatchers.Default) { + inner.sign(message) + } + } + + @Throws(CryptoStoreErrorException::class) + suspend fun enableBackup(key: String, version: String) { + return withContext(Dispatchers.Default) { + val backupKey = BackupKey(key, mapOf(), null) + inner.enableBackup(backupKey, version) + } + } + + fun roomKeyCounts(): RoomKeyCounts { + // TODO convert this to a suspendable method + return inner.roomKeyCounts() + } + + fun getBackupKeys(): BackupKeys? { + // TODO this needs to be suspendable + return inner.getBackupKeys() + } + + fun saveRecoveryKey(key: String?, version: String?) { + // TODO convert this to a suspendable method + inner.saveRecoveryKey(key, version) + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt new file mode 100644 index 0000000000..c75281304f --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -0,0 +1,466 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.keysbackup + +import android.os.Handler +import android.os.Looper +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.listeners.ProgressListener +import org.matrix.android.sdk.api.listeners.StepProgressListener +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener +import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP +import org.matrix.android.sdk.internal.crypto.OlmMachine +import org.matrix.android.sdk.internal.crypto.RequestSender +import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust +import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData +import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo +import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult +import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo +import org.matrix.android.sdk.internal.extensions.foldToCallback +import org.matrix.android.sdk.internal.session.SessionScope +import org.matrix.android.sdk.internal.util.JsonCanonicalizer +import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers +import timber.log.Timber +import uniffi.olm.BackupRecoveryKey +import javax.inject.Inject + +/** + * A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys) + * to the user's homeserver. + */ +@SessionScope +internal class RustKeyBackupService @Inject constructor( + private val olmMachine: OlmMachine, + private val sender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val cryptoCoroutineScope: CoroutineScope, +) : KeysBackupService { + + private val uiHandler = Handler(Looper.getMainLooper()) + + private val keysBackupStateManager = KeysBackupStateManager(uiHandler) + + // The backup version + override var keysBackupVersion: KeysVersionResult? = null + private set + + private var backupAllGroupSessionsCallback: MatrixCallback? = null + + private var keysBackupStateListener: KeysBackupStateListener? = null + + override val isEnabled: Boolean + get() = keysBackupStateManager.isEnabled + + override val isStucked: Boolean + get() = keysBackupStateManager.isStucked + + override val state: KeysBackupState + get() = keysBackupStateManager.state + + override val currentBackupVersion: String? + get() = keysBackupVersion?.version + + override fun addListener(listener: KeysBackupStateListener) { + keysBackupStateManager.addListener(listener) + } + + override fun removeListener(listener: KeysBackupStateListener) { + keysBackupStateManager.removeListener(listener) + } + + override fun prepareKeysBackupVersion(password: String?, + progressListener: ProgressListener?, + callback: MatrixCallback) { + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + runCatching { + withContext(coroutineDispatchers.crypto) { + val key = if (password != null) { + BackupRecoveryKey.fromPassphrase(password) + } else { + BackupRecoveryKey() + } + + val publicKey = key.publicKey() + val backupAuthData = SignalableMegolmBackupAuthData( + publicKey = publicKey.publicKey, + privateKeySalt = publicKey.passphraseInfo?.privateKeySalt, + privateKeyIterations = publicKey.passphraseInfo?.privateKeyIterations + ) + val canonicalJson = JsonCanonicalizer.getCanonicalJson( + Map::class.java, + backupAuthData.signalableJSONDictionary() + ) + + val signedMegolmBackupAuthData = MegolmBackupAuthData( + publicKey = backupAuthData.publicKey, + privateKeySalt = backupAuthData.privateKeySalt, + privateKeyIterations = backupAuthData.privateKeyIterations, + signatures = olmMachine.sign(canonicalJson) + ) + + MegolmBackupCreationInfo( + algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP, + authData = signedMegolmBackupAuthData, + recoveryKey = key.toBase58() + ) + } + }.foldToCallback(callback) + } + } + + override fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, + callback: MatrixCallback) { + @Suppress("UNCHECKED_CAST") + val createKeysBackupVersionBody = CreateKeysBackupVersionBody( + algorithm = keysBackupCreationInfo.algorithm, + authData = keysBackupCreationInfo.authData.toJsonDict() + ) + + keysBackupStateManager.state = KeysBackupState.Enabling + + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + try { + val data = sender.createKeyBackup(createKeysBackupVersionBody) + // Reset backup markers. + // Don't we need to join the task here? Isn't this a race condition? + cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { + // TODO reset our backup state here, i.e. the `backed_up` flag on inbound group sessions + } + + olmMachine.enableBackup(keysBackupCreationInfo.authData.publicKey, data.version) + + callback.onSuccess(data) + } catch (failure: Throwable) { + keysBackupStateManager.state = KeysBackupState.Disabled + callback.onFailure(failure) + } + } + } + + override fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) { + cryptoCoroutineScope.launch { + olmMachine.saveRecoveryKey(recoveryKey, version) + } + } + + private fun resetBackupAllGroupSessionsListeners() { + backupAllGroupSessionsCallback = null + + keysBackupStateListener?.let { + keysBackupStateManager.removeListener(it) + } + + keysBackupStateListener = null + } + + /** + * Reset all local key backup data. + * + * Note: This method does not update the state + */ + private fun resetKeysBackupData() { + resetBackupAllGroupSessionsListeners() + + /* + + TODO reset data on the rust side + cryptoStore.setKeyBackupVersion(null) + cryptoStore.setKeysBackupData(null) + backupOlmPkEncryption?.releaseEncryption() + backupOlmPkEncryption = null + + // Reset backup markers + cryptoStore.resetBackupMarkers() + */ + } + + override fun deleteBackup(version: String, callback: MatrixCallback?) { + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + withContext(coroutineDispatchers.crypto) { + if (keysBackupVersion != null && version == keysBackupVersion?.version) { + resetKeysBackupData() + keysBackupVersion = null + keysBackupStateManager.state = KeysBackupState.Unknown + } + + fun eventuallyRestartBackup() { + // Do not stay in KeysBackupState.Unknown but check what is available on the homeserver + if (state == KeysBackupState.Unknown) { + checkAndStartKeysBackup() + } + } + + try { + sender.deleteKeyBackup(version) + eventuallyRestartBackup() + uiHandler.post { callback?.onSuccess(Unit) } + } catch (failure: Throwable) { + eventuallyRestartBackup() + uiHandler.post { callback?.onFailure(failure) } + } + } + } + } + + override fun canRestoreKeys(): Boolean { + // TODO + return false + } + + override fun getTotalNumbersOfKeys(): Int { + return olmMachine.roomKeyCounts().total.toInt() + } + + override fun getTotalNumbersOfBackedUpKeys(): Int { + return olmMachine.roomKeyCounts().backedUp.toInt() + } + + override fun backupAllGroupSessions(progressListener: ProgressListener?, + callback: MatrixCallback?) { + TODO() + } + + override fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult, + callback: MatrixCallback) { + Timber.d("BACKUP: HELLOO TRYING TO CHECK THE TRUST") + // TODO + callback.onSuccess(KeysBackupVersionTrust(false)) + } + + override fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, + trust: Boolean, + callback: MatrixCallback) { + Timber.v("trustKeyBackupVersion: $trust, version ${keysBackupVersion.version}") + TODO() + } + + override fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, + recoveryKey: String, + callback: MatrixCallback) { + Timber.v("trustKeysBackupVersionWithRecoveryKey: version ${keysBackupVersion.version}") + TODO() + } + + override fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, + password: String, + callback: MatrixCallback) { + TODO() + } + + override fun onSecretKeyGossip(secret: String) { + Timber.i("## CrossSigning - onSecretKeyGossip") + TODO() + } + + override fun getBackupProgress(progressListener: ProgressListener) { + val backedUpKeys = getTotalNumbersOfBackedUpKeys() + val total = getTotalNumbersOfKeys() + + progressListener.onProgress(backedUpKeys, total) + } + + override fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, + recoveryKey: String, + roomId: String?, + sessionId: String?, + stepProgressListener: StepProgressListener?, + callback: MatrixCallback) { + // TODO + Timber.v("restoreKeysWithRecoveryKey: From backup version: ${keysVersionResult.version}") + } + + override fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, + password: String, + roomId: String?, + sessionId: String?, + stepProgressListener: StepProgressListener?, + callback: MatrixCallback) { + // TODO + Timber.v("[MXKeyBackup] restoreKeyBackup with password: From backup version: ${keysBackupVersion.version}") + } + + override fun getVersion(version: String, callback: MatrixCallback) { + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + runCatching { + sender.getKeyBackupVersion(version) + }.foldToCallback(callback) + } + } + + override fun getCurrentVersion(callback: MatrixCallback) { + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + runCatching { + sender.getKeyBackupVersion() + }.foldToCallback(callback) + } + } + + private suspend fun forceUsingLastVersionHelper(): Boolean { + val response = sender.getKeyBackupVersion() + val serverBackupVersion = response?.version + val localBackupVersion = keysBackupVersion?.version + + Timber.d("BACKUP: $serverBackupVersion") + + return if (serverBackupVersion == null) { + if (localBackupVersion == null) { + // No backup on the server, and backup is not active + true + } else { + // No backup on the server, and we are currently backing up, so stop backing up + resetKeysBackupData() + keysBackupVersion = null + keysBackupStateManager.state = KeysBackupState.Disabled + false + } + } else { + if (localBackupVersion == null) { + // Do a check + checkAndStartWithKeysBackupVersion(response) + // backup on the server, and backup is not active + false + } else { + // Backup on the server, and we are currently backing up, compare version + if (localBackupVersion == serverBackupVersion) { + // We are already using the last version of the backup + true + } else { + // This will automatically check for the last version then + deleteBackup(localBackupVersion, null) + // We are not using the last version, so delete the current version we are using on the server + false + } + } + } + } + + override fun forceUsingLastVersion(callback: MatrixCallback) { + cryptoCoroutineScope.launch { + runCatching { + forceUsingLastVersionHelper() + }.foldToCallback(callback) + } + } + + override fun checkAndStartKeysBackup() { + if (!isStucked) { + // Try to start or restart the backup only if it is in unknown or bad state + Timber.w("checkAndStartKeysBackup: invalid state: $state") + + return + } + + keysBackupVersion = null + keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver + + getCurrentVersion(object : MatrixCallback { + override fun onSuccess(data: KeysVersionResult?) { + checkAndStartWithKeysBackupVersion(data) + } + + override fun onFailure(failure: Throwable) { + Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version") + keysBackupStateManager.state = KeysBackupState.Unknown + } + }) + } + + private fun checkAndStartWithKeysBackupVersion(keyBackupVersion: KeysVersionResult?) { + Timber.v("checkAndStartWithKeyBackupVersion: ${keyBackupVersion?.version}") + + keysBackupVersion = keyBackupVersion + + if (keyBackupVersion == null) { + Timber.v("checkAndStartWithKeysBackupVersion: Found no key backup version on the homeserver") + resetKeysBackupData() + keysBackupStateManager.state = KeysBackupState.Disabled + } else { + getKeysBackupTrust(keyBackupVersion, object : MatrixCallback { + override fun onSuccess(data: KeysBackupVersionTrust) { + val versionInStore = getKeyBackupRecoveryKeyInfo()?.version + + if (data.usable) { + Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: ${keyBackupVersion.version}") + // Check the version we used at the previous app run + if (versionInStore != null && versionInStore != keyBackupVersion.version) { + Timber.v(" -> clean the previously used version $versionInStore") + resetKeysBackupData() + } + + Timber.v(" -> enabling key backups") + // TODO + // enableKeysBackup(keyBackupVersion) + } else { + Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: ${keyBackupVersion.version}") + if (versionInStore != null) { + Timber.v(" -> disabling key backup") + resetKeysBackupData() + } + + keysBackupStateManager.state = KeysBackupState.NotTrusted + } + } + + override fun onFailure(failure: Throwable) { + // Cannot happen + } + }) + } + } + + override fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback) { + val keysBackupVersion = keysBackupVersion ?: return Unit.also { callback.onSuccess(false) } + + try { + val key = BackupRecoveryKey.fromBase64(recoveryKey) + val publicKey = key.publicKey().publicKey + val authData = getMegolmBackupAuthData(keysBackupVersion) ?: return Unit.also { callback.onSuccess(false) } + + callback.onSuccess(authData.publicKey == publicKey) + } catch (error: Throwable) { + callback.onFailure(error) + } + } + + override fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? { + val info = olmMachine.getBackupKeys() ?: return null + return SavedKeyBackupKeyInfo(info.recoveryKey, info.backupVersion) + } + + /** + * Extract MegolmBackupAuthData data from a backup version. + * + * @param keysBackupData the key backup data + * + * @return the authentication if found and valid, null in other case + */ + private fun getMegolmBackupAuthData(keysBackupData: KeysVersionResult): MegolmBackupAuthData? { + return keysBackupData + .takeIf { it.version.isNotEmpty() && it.algorithm == MXCRYPTO_ALGORITHM_MEGOLM_BACKUP } + ?.getAuthDataAsMegolmBackupAuthData() + ?.takeIf { it.publicKey.isNotEmpty() } + } +} diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 6ce3f56a75..0b8d791281 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -18,19 +18,25 @@ thiserror = "1.0.25" tracing = "0.1.26" tracing-subscriber = "0.2.18" uniffi = "0.12.0" +pbkdf2 = "0.8.0" +sha2 = "0.9.5" +rand = "0.8.4" +hmac = "0.11.0" [dependencies.js_int] version = "0.2.1" features = ["lax_deserialize"] [dependencies.matrix-sdk-common] -git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" +path = "/home/poljar/werk/priv/nio-rust/crates/matrix-sdk-common/" +# git = "https://github.com/matrix-org/matrix-rust-sdk/" +# rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" [dependencies.matrix-sdk-crypto] -git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" -features = ["sled_cryptostore"] +# git = "https://github.com/matrix-org/matrix-rust-sdk/" +# rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" +path = "/home/poljar/werk/priv/nio-rust/crates/matrix-sdk-crypto/" +features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] version = "1.7.1" @@ -38,8 +44,9 @@ default_features = false features = ["rt-multi-thread"] [dependencies.ruma] -version = "0.3.0" -features = ["client-api"] +git = "https://github.com/ruma/ruma" +rev = "0101e110f" +features = ["client-api-c"] [build-dependencies] uniffi_build = "0.12.0" diff --git a/rust-sdk/src/backup_recovery_key.rs b/rust-sdk/src/backup_recovery_key.rs new file mode 100644 index 0000000000..13f7241176 --- /dev/null +++ b/rust-sdk/src/backup_recovery_key.rs @@ -0,0 +1,117 @@ +use hmac::Hmac; +use pbkdf2::pbkdf2; +use rand::{distributions::Alphanumeric, thread_rng, Rng}; +use sha2::Sha512; +use std::{collections::HashMap, iter}; + +use matrix_sdk_crypto::backups::RecoveryKey; + +/// TODO +pub struct BackupRecoveryKey { + pub(crate) inner: RecoveryKey, + passphrase_info: Option, +} + +/// TODO +#[derive(Debug, Clone)] +pub struct PassphraseInfo { + /// TODO + pub private_key_salt: String, + /// TODO + pub private_key_iterations: i32, +} + +/// TODO +pub struct BackupKey { + /// TODO + pub public_key: String, + /// TODO + pub signatures: HashMap>, + /// TODO + pub passphrase_info: Option, +} + +impl BackupRecoveryKey { + const KEY_SIZE: usize = 32; + const SALT_SIZE: usize = 32; + const PBKDF_ROUNDS: u32 = 500_000; + + /// TODO + pub fn new() -> Self { + Self { + inner: RecoveryKey::new() + .expect("Can't gather enough randomness to create a recovery key"), + passphrase_info: None, + } + } + + /// TODO + pub fn from_base64(key: String) -> Self { + Self { + inner: RecoveryKey::from_base64(key).unwrap(), + passphrase_info: None, + } + } + + /// TODO + pub fn from_base58(key: String) -> Self { + Self { + inner: RecoveryKey::from_base58(&key).unwrap(), + passphrase_info: None, + } + } + + /// TODO + pub fn from_passphrase(passphrase: String) -> Self { + let mut key = [0u8; Self::KEY_SIZE]; + + let mut rng = thread_rng(); + let salt: String = iter::repeat(()) + .map(|()| rng.sample(Alphanumeric)) + .map(char::from) + .take(Self::SALT_SIZE) + .collect(); + + pbkdf2::>( + passphrase.as_bytes(), + salt.as_bytes(), + Self::PBKDF_ROUNDS, + &mut key, + ); + + Self { + inner: RecoveryKey::from_bytes(key), + passphrase_info: Some(PassphraseInfo { + private_key_salt: salt, + private_key_iterations: Self::PBKDF_ROUNDS as i32, + }), + } + } + + /// TODO + pub fn public_key(&self) -> BackupKey { + let public_key = self.inner.public_key(); + + let signatures: HashMap> = public_key + .signatures() + .into_iter() + .map(|(k, v)| { + ( + k.to_string(), + v.into_iter().map(|(k, v)| (k.to_string(), v)).collect(), + ) + }) + .collect(); + + BackupKey { + public_key: public_key.encoded_key(), + signatures, + passphrase_info: self.passphrase_info.clone(), + } + } + + /// TODO + pub fn to_base58(&self) -> String { + self.inner.to_base58() + } +} diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 968632b914..c489b71602 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -10,6 +10,7 @@ //! TODO +mod backup_recovery_key; mod device; mod error; mod logger; @@ -18,18 +19,21 @@ mod responses; mod users; mod verification; +pub use backup_recovery_key::{BackupKey, BackupRecoveryKey, PassphraseInfo}; pub use device::Device; -pub use error::{CryptoStoreError, DecryptionError, KeyImportError, SignatureError, SecretImportError}; +pub use error::{ + CryptoStoreError, DecryptionError, KeyImportError, SecretImportError, SignatureError, +}; pub use logger::{set_logger, Logger}; pub use machine::{KeyRequestPair, OlmMachine}; pub use responses::{ - DeviceLists, KeysImportResult, OutgoingVerificationRequest, Request, RequestType, SignatureUploadRequest, - BootstrapCrossSigningResult, UploadSigningKeysRequest, + BootstrapCrossSigningResult, DeviceLists, KeysImportResult, OutgoingVerificationRequest, + Request, RequestType, SignatureUploadRequest, UploadSigningKeysRequest, }; pub use users::UserIdentity; pub use verification::{ - CancelInfo, QrCode, RequestVerificationResult, Sas, ScanResult, StartSasResult, Verification, - VerificationRequest, ConfirmVerificationResult, + CancelInfo, ConfirmVerificationResult, QrCode, RequestVerificationResult, Sas, ScanResult, + StartSasResult, Verification, VerificationRequest, }; /// Callback that will be passed over the FFI to report progress @@ -83,6 +87,42 @@ pub struct CrossSigningKeyExport { pub user_signing_key: Option, } +/// TODO +pub struct RoomKeyCounts { + /// TODO + pub total: i64, + /// TODO + pub backed_up: i64, +} + +/// TODO +pub struct BackupKeys { + /// TODO + pub recovery_key: String, + /// TODO + pub backup_version: String, +} + +impl std::convert::TryFrom for BackupKeys { + type Error = (); + + fn try_from(keys: matrix_sdk_crypto::store::BackupKeys) -> Result { + Ok(Self { + recovery_key: keys.recovery_key.ok_or(())?.to_base64(), + backup_version: keys.backup_version.ok_or(())?, + }) + } +} + +impl From for RoomKeyCounts { + fn from(count: matrix_sdk_crypto::store::RoomKeyCounts) -> Self { + Self { + total: count.total as i64, + backed_up: count.backed_up as i64, + } + } +} + impl From for CrossSigningKeyExport { fn from(e: matrix_sdk_crypto::CrossSigningKeyExport) -> Self { Self { diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 0b8e3cd7ba..a4d0260378 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -9,6 +9,7 @@ use js_int::UInt; use ruma::{ api::{ client::r0::{ + backup::add_backup_keys::Response as KeysBackupResponse, keys::{ claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, upload_keys::Response as KeysUploadResponse, @@ -31,17 +32,21 @@ use tokio::runtime::Runtime; use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; use matrix_sdk_crypto::{ - decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, EncryptionSettings, - LocalTrust, OlmMachine as InnerMachine, UserIdentities, Verification as RustVerification, + backups::{MegolmV1BackupKey, RecoveryKey}, + decrypt_key_export, encrypt_key_export, + matrix_qrcode::QrVerificationData, + EncryptionSettings, LocalTrust, OlmMachine as InnerMachine, UserIdentities, + Verification as RustVerification, }; use crate::{ error::{CryptoStoreError, DecryptionError, SecretImportError, SignatureError}, responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, - BootstrapCrossSigningResult, ConfirmVerificationResult, CrossSigningKeyExport, - CrossSigningStatus, DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, - ProgressListener, QrCode, Request, RequestType, RequestVerificationResult, ScanResult, - SignatureUploadRequest, StartSasResult, UserIdentity, Verification, VerificationRequest, + BackupKey, BackupKeys, BootstrapCrossSigningResult, ConfirmVerificationResult, + CrossSigningKeyExport, CrossSigningStatus, DecryptedEvent, Device, DeviceLists, KeyImportError, + KeysImportResult, ProgressListener, QrCode, Request, RequestType, RequestVerificationResult, + RoomKeyCounts, ScanResult, SignatureUploadRequest, StartSasResult, UserIdentity, Verification, + VerificationRequest, }; /// A high level state machine that handles E2EE for Matrix. @@ -95,7 +100,7 @@ impl OlmMachine { /// Get the display name of our own device. pub fn display_name(&self) -> Result, CryptoStoreError> { - Ok(self.runtime.block_on(self.inner.dislpay_name())?) + Ok(self.runtime.block_on(self.inner.display_name())?) } /// Get a cross signing user identity for the given user ID. @@ -305,6 +310,9 @@ impl OlmMachine { RequestType::SignatureUpload => { SignatureUploadResponse::try_from_http_response(response).map(Into::into) } + RequestType::KeysBackup => { + KeysBackupResponse::try_from_http_response(response).map(Into::into) + } } .expect("Can't convert json string to response"); @@ -701,10 +709,7 @@ impl OlmMachine { methods: Vec, ) -> Option { let user_id = UserId::try_from(user_id).ok()?; - let methods = methods - .into_iter() - .map(VerificationMethod::from) - .collect(); + let methods = methods.into_iter().map(VerificationMethod::from).collect(); if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { verification.accept_with_methods(methods).map(|r| r.into()) @@ -731,10 +736,7 @@ impl OlmMachine { let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; - let methods = methods - .into_iter() - .map(VerificationMethod::from) - .collect(); + let methods = methods.into_iter().map(VerificationMethod::from).collect(); Ok(if let Some(identity) = identity.and_then(|i| i.other()) { let content = self @@ -779,10 +781,7 @@ impl OlmMachine { let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; - let methods = methods - .into_iter() - .map(VerificationMethod::from) - .collect(); + let methods = methods.into_iter().map(VerificationMethod::from).collect(); Ok(if let Some(identity) = identity.and_then(|i| i.other()) { let request = self.runtime.block_on(identity.request_verification( @@ -816,10 +815,7 @@ impl OlmMachine { ) -> Result, CryptoStoreError> { let user_id = UserId::try_from(user_id)?; - let methods = methods - .into_iter() - .map(VerificationMethod::from) - .collect(); + let methods = methods.into_iter().map(VerificationMethod::from).collect(); Ok( if let Some(device) = self @@ -854,10 +850,7 @@ impl OlmMachine { .runtime .block_on(self.inner.get_identity(self.inner.user_id()))?; - let methods = methods - .into_iter() - .map(VerificationMethod::from) - .collect(); + let methods = methods.into_iter().map(VerificationMethod::from).collect(); Ok(if let Some(identity) = identity.and_then(|i| i.own()) { let (verification, request) = self @@ -1023,10 +1016,7 @@ impl OlmMachine { 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(encode).ok()) - }) + .and_then(|v| v.qr_v1().and_then(|qr| qr.to_bytes().map(encode).ok())) } /// Pass data from a scanned QR code to an active verification request and @@ -1254,4 +1244,74 @@ impl OlmMachine { Ok(()) } + + /// TODO + pub fn enable_backup(&self, key: BackupKey, version: String) -> Result<(), CryptoStoreError> { + let backup_key = MegolmV1BackupKey::from_base64(&key.public_key).unwrap(); + backup_key.set_version(version); + + self.runtime + .block_on(self.inner.backup_machine().enable_backup(backup_key))?; + + Ok(()) + } + + /// TODO + pub fn disable_backup(&self) -> Result<(), CryptoStoreError> { + Ok(self + .runtime + .block_on(self.inner.backup_machine().disable_backup())?) + } + + /// TODO + pub fn backup_room_keys(&self) -> Result, CryptoStoreError> { + let request = self + .runtime + .block_on(self.inner.backup_machine().backup())?; + + Ok(request.map(|r| r.into())) + } + + /// TODO + pub fn room_key_counts(&self) -> Result { + Ok(self + .runtime + .block_on(self.inner.backup_machine().room_key_counts())? + .into()) + } + + /// TODO + pub fn save_recovery_key( + &self, + key: Option, + version: Option, + ) -> Result<(), CryptoStoreError> { + let key = key.map(RecoveryKey::from_base64).transpose().ok().flatten(); + Ok(self + .runtime + .block_on(self.inner.backup_machine().save_recovery_key(key, version))?) + } + + /// TODO + pub fn get_backup_keys(&self) -> Result, CryptoStoreError> { + Ok(self + .runtime + .block_on(self.inner.backup_machine().get_backup_keys())? + .try_into() + .ok()) + } + + /// TODO + pub fn sign(&self, message: &str) -> HashMap> { + self.runtime + .block_on(self.inner.sign(message)) + .into_iter() + .map(|(k, v)| { + ( + k.to_string(), + v.into_iter().map(|(k, v)| (k.to_string(), v)).collect(), + ) + }) + .collect() + } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 41c5747bf6..d3af9e6a7a 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -110,7 +110,7 @@ dictionary UploadSigningKeysRequest { }; dictionary BootstrapCrossSigningResult { - UploadSigningKeysRequest upload_signing_keys_request; + UploadSigningKeysRequest upload_signing_keys_request; SignatureUploadRequest signature_request; }; @@ -208,6 +208,7 @@ interface Request { KeysUpload(string request_id, string body); KeysQuery(string request_id, sequence users); KeysClaim(string request_id, record> one_time_keys); + KeysBackup(string request_id, record> rooms); RoomMessage(string request_id, string room_id, string event_type, string content); SignatureUpload(string request_id, string body); }; @@ -222,6 +223,7 @@ enum RequestType { "KeysUpload", "ToDevice", "SignatureUpload", + "KeysBackup", }; interface OlmMachine { @@ -343,4 +345,49 @@ interface OlmMachine { void import_cross_signing_keys(CrossSigningKeyExport export); [Throws=CryptoStoreError] boolean is_identity_verified([ByRef] string user_id); + + record> sign([ByRef] string message); + [Throws=CryptoStoreError] + void enable_backup(BackupKey key, string version); + [Throws=CryptoStoreError] + void disable_backup(); + [Throws=CryptoStoreError] + Request? backup_room_keys(); + [Throws=CryptoStoreError] + void save_recovery_key(string? key, string? version); + [Throws=CryptoStoreError] + RoomKeyCounts room_key_counts(); + [Throws=CryptoStoreError] + BackupKeys? get_backup_keys(); +}; + +dictionary PassphraseInfo { + string private_key_salt; + i32 private_key_iterations; +}; + +dictionary BackupKey { + string public_key; + record> signatures; + PassphraseInfo? passphrase_info; +}; + +dictionary BackupKeys { + string recovery_key; + string backup_version; +}; + +dictionary RoomKeyCounts { + i64 total; + i64 backed_up; +}; + +interface BackupRecoveryKey { + constructor(); + [Name=from_base64] + constructor(string key); + [Name=from_passphrase] + constructor(string key); + string to_base58(); + BackupKey public_key(); }; diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index 693f4f1845..ef2f836d8e 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -8,6 +8,7 @@ use serde_json::json; use ruma::{ api::client::r0::{ + backup::add_backup_keys::Response as KeysBackupResponse, keys::{ claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse}, get_keys::Response as KeysQueryResponse, @@ -152,6 +153,10 @@ pub enum Request { request_id: String, body: String, }, + KeysBackup { + request_id: String, + rooms: HashMap>, + } } impl From for Request { @@ -186,6 +191,7 @@ impl From for Request { }, RoomMessage(r) => Request::from(r), KeysClaim(c) => (*r.request_id(), c.clone()).into(), + KeysBackup(_) => todo!(), } } } @@ -256,6 +262,7 @@ pub enum RequestType { KeysUpload, ToDevice, SignatureUpload, + KeysBackup, } pub struct DeviceLists { @@ -291,6 +298,7 @@ pub(crate) enum OwnedResponse { KeysQuery(KeysQueryResponse), ToDevice(ToDeviceResponse), SignatureUpload(SignatureUploadResponse), + KeysBackup(KeysBackupResponse), } impl From for OwnedResponse { @@ -323,6 +331,12 @@ impl From for OwnedResponse { } } +impl From for OwnedResponse { + fn from(r: KeysBackupResponse) -> Self { + Self::KeysBackup(r) + } +} + impl<'a> From<&'a OwnedResponse> for IncomingResponse<'a> { fn from(r: &'a OwnedResponse) -> Self { match r { @@ -331,6 +345,7 @@ impl<'a> From<&'a OwnedResponse> for IncomingResponse<'a> { OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r), OwnedResponse::SignatureUpload(r) => IncomingResponse::SignatureUpload(r), + OwnedResponse::KeysBackup(r) => IncomingResponse::KeysBackup(r), } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index cb8a6ce4e9..312bef06d1 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -34,6 +34,7 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust +import timber.log.Timber class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState, session: Session @@ -81,6 +82,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS private fun getKeysBackupTrust() = withState { state -> val versionResult = keysBackupService.keysBackupVersion + Timber.d("BACKUP: HEEEEEEE $versionResult ${state.keysBackupVersionTrust}") if (state.keysBackupVersionTrust is Uninitialized && versionResult != null) { setState { @@ -89,10 +91,12 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS deleteBackupRequest = Uninitialized ) } + Timber.d("BACKUP: HEEEEEEE TWO") keysBackupService .getKeysBackupTrust(versionResult, object : MatrixCallback { override fun onSuccess(data: KeysBackupVersionTrust) { + Timber.d("BACKUP: HEEEE suceeeded $data") setState { copy( keysBackupVersionTrust = Success(data) @@ -101,6 +105,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS } override fun onFailure(failure: Throwable) { + Timber.d("BACKUP: HEEEE FAILED $failure") setState { copy( keysBackupVersionTrust = Fail(failure) From 021041fc2e121470b43abbaab48b606f578d1a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 18 Oct 2021 09:36:32 +0200 Subject: [PATCH 161/252] crypto: Support to send out backup HTTP requests --- .../internal/crypto/DefaultCryptoService.kt | 52 ++++- .../android/sdk/internal/crypto/OlmMachine.kt | 14 ++ .../crypto/keysbackup/RustKeyBackupService.kt | 185 +++++++++++++++++- rust-sdk/src/machine.rs | 9 +- rust-sdk/src/olm.udl | 3 +- rust-sdk/src/responses.rs | 13 +- 6 files changed, 266 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index a551617858..e853237e2f 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -57,13 +57,17 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.auth.registration.handleUIA import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask 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.MXEncryptEventContentResult @@ -132,7 +136,8 @@ internal class RequestSender @Inject constructor( private val getKeysBackupVersionTask: GetKeysBackupVersionTask, private val deleteBackupTask: DeleteBackupTask, private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, -) { + private val backupRoomKeysTask: StoreSessionsDataTask, + ) { companion object { const val REQUEST_RETRY_COUNT = 3 } @@ -287,6 +292,49 @@ internal class RequestSender @Inject constructor( val params = DeleteBackupTask.Params(version) deleteBackupTask.execute(params) } + + suspend fun backupRoomKeys(request: Request.KeysBackup): String { + val adapter = MoshiProvider + .providesMoshi() + .newBuilder() + .build() + .adapter>(MutableMap::class.java) + val keys = adapter.fromJson(request.rooms)!! + Timber.d("BACKUP: CONVERTED KEYS TO HASHMAP $keys") + /* + val keyAdapter = MoshiProvider.providesMoshi().adapter(KeyBackupData::class.java) + val keysBackupData = KeysBackupData() + for (room in keys) { + val sessions = room.value.getOrDefault("sessions", mapOf()) + + for (session in sessions) { + Timber.d("BACKUP: HEEELOO CONVERTING KEY ${session.value}") + val key = keyAdapter.fromJson(session.value)!! + Timber.d("BACKUP: HEEELOO CONVERTED KEY $key") + + keysBackupData + .roomIdToRoomKeysBackupData + .getOrPut(room.key, { RoomKeysBackupData() }) + .sessionIdToKeyBackupData[session.key] = key + } + } + + + */ + /* + for ((roomId, backupData) in keys) { + val roomData = backup.roomIdToRoomKeysBackupData.getOrPut(roomId, { RoomKeysBackupData() }) + for ((sessionId, key) in backupData.sessionIdToKeyBackupData) { + Timber.d("BACKUP INSERTING KEY $key") + roomData.sessionIdToKeyBackupData[sessionId] = key + } + } + */ + val params = StoreSessionsDataTask.Params(request.version, KeysBackupData()) + val response = backupRoomKeysTask.execute(params) + val responseAdapter = MoshiProvider.providesMoshi().adapter(BackupKeysResult::class.java) + return responseAdapter.toJson(response)!! + } } /** @@ -1025,7 +1073,7 @@ internal class DefaultCryptoService @Inject constructor( signatureUpload(it) } } - is Request.KeysBackup -> { + is Request.KeysBackup -> { async { TODO() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 7aa6478f4c..59b5ea51f0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -778,6 +778,10 @@ internal class OlmMachine( } } + fun backupEnabled(): Boolean { + return inner.backupEnabled() + } + fun roomKeyCounts(): RoomKeyCounts { // TODO convert this to a suspendable method return inner.roomKeyCounts() @@ -792,4 +796,14 @@ internal class OlmMachine( // TODO convert this to a suspendable method inner.saveRecoveryKey(key, version) } + + @Throws(CryptoStoreErrorException::class) + suspend fun backupRoomKeys(): Request? { + return withContext(Dispatchers.Default) { + Timber.d("BACKUP CREATING REQUEST") + val request = inner.backupRoomKeys() + Timber.d("BACKUP CREATED REQUEST: $request") + request + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index c75281304f..55c074916d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -18,10 +18,15 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import android.os.Handler import android.os.Looper +import androidx.annotation.UiThread import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService @@ -43,9 +48,13 @@ import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.util.JsonCanonicalizer import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers +import org.matrix.olm.OlmException import timber.log.Timber import uniffi.olm.BackupRecoveryKey +import uniffi.olm.Request +import uniffi.olm.RequestType import javax.inject.Inject +import kotlin.random.Random /** * A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys) @@ -58,6 +67,10 @@ internal class RustKeyBackupService @Inject constructor( private val coroutineDispatchers: MatrixCoroutineDispatchers, private val cryptoCoroutineScope: CoroutineScope, ) : KeysBackupService { + companion object { + // Maximum delay in ms in {@link maybeBackupKeys} + private const val KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS = 10_000L + } private val uiHandler = Handler(Looper.getMainLooper()) @@ -150,7 +163,16 @@ internal class RustKeyBackupService @Inject constructor( // TODO reset our backup state here, i.e. the `backed_up` flag on inbound group sessions } - olmMachine.enableBackup(keysBackupCreationInfo.authData.publicKey, data.version) + val keyBackupVersion = KeysVersionResult( + algorithm = createKeysBackupVersionBody.algorithm, + authData = createKeysBackupVersionBody.authData, + version = data.version, + // We can assume that the server does not have keys yet + count = 0, + hash = "" + ) + + enableKeysBackup(keyBackupVersion) callback.onSuccess(data) } catch (failure: Throwable) { @@ -226,8 +248,12 @@ internal class RustKeyBackupService @Inject constructor( } override fun canRestoreKeys(): Boolean { - // TODO - return false + val keyCountOnServer = keysBackupVersion?.count ?: return false + val keyCountLocally = getTotalNumbersOfKeys() + + // TODO is this sensible? We may have the same number of keys, or even more keys locally + // but the set of keys doesn't necessarily overlap + return keyCountLocally < keyCountOnServer } override fun getTotalNumbersOfKeys(): Int { @@ -463,4 +489,157 @@ internal class RustKeyBackupService @Inject constructor( ?.getAuthDataAsMegolmBackupAuthData() ?.takeIf { it.publicKey.isNotEmpty() } } + + /** + * Enable backing up of keys. + * This method will update the state and will start sending keys in nominal case + * + * @param keysVersionResult backup information object as returned by [getCurrentVersion]. + */ + private suspend fun enableKeysBackup(keysVersionResult: KeysVersionResult) { + val retrievedMegolmBackupAuthData = keysVersionResult.getAuthDataAsMegolmBackupAuthData() + + if (retrievedMegolmBackupAuthData != null) { + try { + olmMachine.enableBackup(retrievedMegolmBackupAuthData.publicKey, keysVersionResult.version) + keysBackupVersion = keysVersionResult + } catch (e: OlmException) { + Timber.e(e, "OlmException") + keysBackupStateManager.state = KeysBackupState.Disabled + return + } + + keysBackupStateManager.state = KeysBackupState.ReadyToBackUp + maybeBackupKeys() + } else { + Timber.e("Invalid authentication data") + keysBackupStateManager.state = KeysBackupState.Disabled + } + } + + /** + * Do a backup if there are new keys, with a delay + */ + private fun maybeBackupKeys() { + when { + isStucked -> { + // If not already done, or in error case, check for a valid backup version on the homeserver. + // If there is one, maybeBackupKeys will be called again. + checkAndStartKeysBackup() + } + state == KeysBackupState.ReadyToBackUp -> { + keysBackupStateManager.state = KeysBackupState.WillBackUp + + // Wait between 0 and 10 seconds, to avoid backup requests from + // different clients hitting the server all at the same time when a + // new key is sent + val delayInMs = Random.nextLong(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS) + + cryptoCoroutineScope.launch { + delay(delayInMs) + // TODO is this correct? we used to call uiHandler.post() instead of this + withContext(Dispatchers.Main) { + backupKeys() + } + } + } + else -> { + Timber.v("maybeBackupKeys: Skip it because state: $state") + } + } + } + + /** + * Send a chunk of keys to backup + */ + @UiThread + private suspend fun backupKeys() { + Timber.v("backupKeys") + + // Sanity check, as this method can be called after a delay, the state may have change during the delay + if (!isEnabled || !olmMachine.backupEnabled() || keysBackupVersion == null) { + Timber.v("backupKeys: Invalid configuration $isEnabled ${olmMachine.backupEnabled()} $keysBackupVersion") + backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration")) + resetBackupAllGroupSessionsListeners() + + return + } + + if (state === KeysBackupState.BackingUp) { + // Do nothing if we are already backing up + Timber.v("backupKeys: Invalid state: $state") + return + } + + Timber.d("BACKUP: CREATING REQUEST") + + val request = olmMachine.backupRoomKeys() + + Timber.d("BACKUP: GOT REQUEST $request") + + if (request == null) { + // Backup is up to date + // Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess() + keysBackupStateManager.state = KeysBackupState.ReadyToBackUp + + backupAllGroupSessionsCallback?.onSuccess(Unit) + resetBackupAllGroupSessionsListeners() + } else { + try { + if (request is Request.KeysBackup) { + keysBackupStateManager.state = KeysBackupState.BackingUp + + Timber.d("BACKUP SENDING REQUEST") + val response = sender.backupRoomKeys(request) + Timber.d("BACKUP GOT RESPONSE $response") + olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_BACKUP, response) + Timber.d("BACKUP MARKED REQUEST AS SENT") + + // TODO again is this correct? + withContext(Dispatchers.Main) { + backupKeys() + } + } else { + // Can't happen, do we want to panic? + } + } catch (failure: Throwable) { + if (failure is Failure.ServerError) { + withContext(Dispatchers.Main) { + Timber.e(failure, "backupKeys: backupKeys failed.") + + when (failure.error.code) { + MatrixError.M_NOT_FOUND, + MatrixError.M_WRONG_ROOM_KEYS_VERSION -> { + // Backup has been deleted on the server, or we are not using + // the last backup version + keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion + backupAllGroupSessionsCallback?.onFailure(failure) + resetBackupAllGroupSessionsListeners() + resetKeysBackupData() + keysBackupVersion = null + + // Do not stay in KeysBackupState.WrongBackUpVersion but check what + // is available on the homeserver + checkAndStartKeysBackup() + } + else -> + // Come back to the ready state so that we will retry on the next received key + keysBackupStateManager.state = KeysBackupState.ReadyToBackUp + } + } + } else { + withContext(Dispatchers.Main) { + backupAllGroupSessionsCallback?.onFailure(failure) + resetBackupAllGroupSessionsListeners() + + Timber.e("backupKeys: backupKeys failed: $failure") + + // Retry a bit later + keysBackupStateManager.state = KeysBackupState.ReadyToBackUp + maybeBackupKeys() + } + } + } + } + } } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index a4d0260378..4f420e13d1 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -1256,6 +1256,11 @@ impl OlmMachine { Ok(()) } + /// TODO + pub fn backup_enabled(&self) -> bool { + self.runtime.block_on(self.inner.backup_machine().enabled()) + } + /// TODO pub fn disable_backup(&self) -> Result<(), CryptoStoreError> { Ok(self @@ -1269,7 +1274,9 @@ impl OlmMachine { .runtime .block_on(self.inner.backup_machine().backup())?; - Ok(request.map(|r| r.into())) + let request = request.map(|r| r.into()); + + Ok(request) } /// TODO diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index d3af9e6a7a..5d9cfd48e0 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -208,7 +208,7 @@ interface Request { KeysUpload(string request_id, string body); KeysQuery(string request_id, sequence users); KeysClaim(string request_id, record> one_time_keys); - KeysBackup(string request_id, record> rooms); + KeysBackup(string request_id, string version, string rooms); RoomMessage(string request_id, string room_id, string event_type, string content); SignatureUpload(string request_id, string body); }; @@ -359,6 +359,7 @@ interface OlmMachine { RoomKeyCounts room_key_counts(); [Throws=CryptoStoreError] BackupKeys? get_backup_keys(); + boolean backup_enabled(); }; dictionary PassphraseInfo { diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index ef2f836d8e..5b0d21599e 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -125,6 +125,7 @@ impl From for OutgoingVerificationRequest { } } +#[derive(Debug)] pub enum Request { ToDevice { request_id: String, @@ -155,8 +156,9 @@ pub enum Request { }, KeysBackup { request_id: String, - rooms: HashMap>, - } + version: String, + rooms: String, + }, } impl From for Request { @@ -191,7 +193,12 @@ impl From for Request { }, RoomMessage(r) => Request::from(r), KeysClaim(c) => (*r.request_id(), c.clone()).into(), - KeysBackup(_) => todo!(), + KeysBackup(b) => Request::KeysBackup { + request_id: r.request_id().to_string(), + version: b.version.to_owned(), + rooms: serde_json::to_string(&b.rooms) + .expect("Can't serialize keys backup request"), + }, } } } From 3b93d6b08ce999bb37ee590758e411cdc04b0950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 22 Oct 2021 10:44:07 +0200 Subject: [PATCH 162/252] crypto: Fill out all the methods to support backups --- .../internal/crypto/DefaultCryptoService.kt | 57 +++----- .../android/sdk/internal/crypto/Device.kt | 16 +-- .../android/sdk/internal/crypto/OlmMachine.kt | 53 ++++--- .../sdk/internal/crypto/QrCodeVerification.kt | 4 +- .../sdk/internal/crypto/SasVerification.kt | 4 +- .../sdk/internal/crypto/UserIdentities.kt | 18 +-- .../keysbackup/DefaultKeysBackupService.kt | 1 + .../crypto/keysbackup/RustKeyBackupService.kt | 134 ++++++++++++++++-- rust-sdk/Cargo.toml | 6 +- rust-sdk/src/lib.rs | 2 - rust-sdk/src/machine.rs | 8 ++ rust-sdk/src/olm.udl | 4 + 12 files changed, 221 insertions(+), 86 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index e853237e2f..e9c28376ff 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -20,6 +20,7 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.lifecycle.LiveData import androidx.paging.PagedList +import com.squareup.moshi.Types import dagger.Lazy import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope @@ -57,17 +58,20 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.auth.registration.handleUIA import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService +import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask 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.MXEncryptEventContentResult @@ -137,6 +141,7 @@ internal class RequestSender @Inject constructor( private val deleteBackupTask: DeleteBackupTask, private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, private val backupRoomKeysTask: StoreSessionsDataTask, + private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask, ) { companion object { const val REQUEST_RETRY_COUNT = 3 @@ -297,44 +302,25 @@ internal class RequestSender @Inject constructor( val adapter = MoshiProvider .providesMoshi() .newBuilder() + .add(CheckNumberType.JSON_ADAPTER_FACTORY) .build() - .adapter>(MutableMap::class.java) + .adapter>( + Types.newParameterizedType( + Map::class.java, + String::class.java, + RoomKeysBackupData::class.java + )) val keys = adapter.fromJson(request.rooms)!! - Timber.d("BACKUP: CONVERTED KEYS TO HASHMAP $keys") - /* - val keyAdapter = MoshiProvider.providesMoshi().adapter(KeyBackupData::class.java) - val keysBackupData = KeysBackupData() - for (room in keys) { - val sessions = room.value.getOrDefault("sessions", mapOf()) - - for (session in sessions) { - Timber.d("BACKUP: HEEELOO CONVERTING KEY ${session.value}") - val key = keyAdapter.fromJson(session.value)!! - Timber.d("BACKUP: HEEELOO CONVERTED KEY $key") - - keysBackupData - .roomIdToRoomKeysBackupData - .getOrPut(room.key, { RoomKeysBackupData() }) - .sessionIdToKeyBackupData[session.key] = key - } - } - - - */ - /* - for ((roomId, backupData) in keys) { - val roomData = backup.roomIdToRoomKeysBackupData.getOrPut(roomId, { RoomKeysBackupData() }) - for ((sessionId, key) in backupData.sessionIdToKeyBackupData) { - Timber.d("BACKUP INSERTING KEY $key") - roomData.sessionIdToKeyBackupData[sessionId] = key - } - } - */ - val params = StoreSessionsDataTask.Params(request.version, KeysBackupData()) - val response = backupRoomKeysTask.execute(params) + val params = StoreSessionsDataTask.Params(request.version, KeysBackupData(keys)) + val response = backupRoomKeysTask.executeRetry(params, REQUEST_RETRY_COUNT) val responseAdapter = MoshiProvider.providesMoshi().adapter(BackupKeysResult::class.java) return responseAdapter.toJson(response)!! } + + suspend fun updateBackup(keysBackupVersion: KeysVersionResult, body: UpdateKeysBackupVersionBody) { + val params = UpdateKeysBackupVersionTask.Params(keysBackupVersion.version, body) + updateKeysBackupVersionTask.executeRetry(params, REQUEST_RETRY_COUNT) + } } /** @@ -566,6 +552,8 @@ internal class DefaultCryptoService @Inject constructor( Timber.v("Failed create an Olm machine: $throwable") } + // We try to enable key backups, if the backup version on the server is trusted, + // we're gonna continue backing up. tryOrNull { keysBackupService!!.checkAndStartKeysBackup() } @@ -1075,7 +1063,8 @@ internal class DefaultCryptoService @Inject constructor( } is Request.KeysBackup -> { async { - TODO() + // The rust-sdk won't ever produce KeysBackup requests here, + // those only get explicitly created. } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index 58a742f174..e1db5ddbe9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -24,10 +24,10 @@ 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.rest.UnsignedDeviceInfo import org.matrix.android.sdk.internal.crypto.verification.prepareMethods -import uniffi.olm.CryptoStoreErrorException +import uniffi.olm.CryptoStoreException import uniffi.olm.Device as InnerDevice import uniffi.olm.OlmMachine -import uniffi.olm.SignatureErrorException +import uniffi.olm.SignatureException import uniffi.olm.VerificationRequest /** Class representing a device that supports E2EE in the Matrix world @@ -41,7 +41,7 @@ internal class Device( private val sender: RequestSender, private val listeners: ArrayList, ) { - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) private suspend fun refreshData() { val device = withContext(Dispatchers.IO) { machine.getDevice(inner.userId, inner.deviceId) @@ -63,7 +63,7 @@ internal class Device( * [org.matrix.android.sdk.internal.crypto.OwnUserIdentity.requestVerification] * method can be used instead. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun requestVerification(methods: List): VerificationRequest? { val stringMethods = prepareMethods(methods) val result = withContext(Dispatchers.IO) { @@ -87,7 +87,7 @@ internal class Device( * The [requestVerification] method should be used instead. * */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun startVerification(): SasVerification? { val result = withContext(Dispatchers.IO) { machine.startSasWithDevice(inner.userId, inner.deviceId) @@ -109,7 +109,7 @@ internal class Device( * This won't upload any signatures, it will only mark the device as trusted * in the local database. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun markAsTrusted() { withContext(Dispatchers.IO) { machine.markDeviceAsTrusted(inner.userId, inner.deviceId) @@ -125,7 +125,7 @@ internal class Device( * This will fail if the device doesn't belong to use or if we don't have the * private part of our self-signing key. */ - @Throws(SignatureErrorException::class) + @Throws(SignatureException::class) suspend fun verify(): Boolean { val request = withContext(Dispatchers.IO) { machine.verifyDevice(inner.userId, inner.deviceId) @@ -139,7 +139,7 @@ internal class Device( /** * Get the DeviceTrustLevel of this device */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun trustLevel(): DeviceTrustLevel { refreshData() return DeviceTrustLevel(crossSigningVerified = inner.crossSigningTrusted, locallyVerified = inner.locallyTrusted) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 59b5ea51f0..e4f01c842b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import com.squareup.moshi.Types import java.io.File import java.nio.charset.Charset import java.util.concurrent.ConcurrentHashMap @@ -37,6 +38,8 @@ import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData 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 @@ -44,16 +47,18 @@ import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.network.parsing.CheckNumberType 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.ToDeviceSyncResponse +import org.matrix.android.sdk.internal.util.JsonCanonicalizer import timber.log.Timber import uniffi.olm.BackupKey import uniffi.olm.BackupKeys import uniffi.olm.CrossSigningKeyExport import uniffi.olm.CrossSigningStatus -import uniffi.olm.CryptoStoreErrorException -import uniffi.olm.DecryptionErrorException +import uniffi.olm.CryptoStoreException +import uniffi.olm.DecryptionException import uniffi.olm.DeviceLists import uniffi.olm.KeyRequestPair import uniffi.olm.Logger @@ -262,7 +267,7 @@ internal class OlmMachine( * * @param responseBody The body of the response that was received. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun markRequestAsSent( requestId: String, requestType: RequestType, @@ -290,7 +295,7 @@ internal class OlmMachine( * * @param keyCounts The map of uploaded one-time key types and counts. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun receiveSyncChanges( toDevice: ToDeviceSyncResponse?, deviceChanges: DeviceListResponse?, @@ -342,7 +347,7 @@ internal class OlmMachine( * * @return A [Request.KeysClaim] request that needs to be sent out to the server. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun getMissingSessions(users: List): Request? = withContext(Dispatchers.IO) { inner.getMissingSessions(users) } @@ -364,7 +369,7 @@ internal class OlmMachine( * * @return The list of [Request.ToDevice] that need to be sent out. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun shareRoomKey(roomId: String, users: List): List = withContext(Dispatchers.IO) { inner.shareRoomKey(roomId, users) } @@ -398,7 +403,7 @@ internal class OlmMachine( * * @return The encrypted version of the [Content] */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) @@ -453,7 +458,7 @@ internal class OlmMachine( * request itself. The cancellation *must* be sent out before the request, otherwise devices * will ignore the key request. */ - @Throws(DecryptionErrorException::class) + @Throws(DecryptionException::class) suspend fun requestRoomKey(event: Event): KeyRequestPair = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) @@ -472,7 +477,7 @@ internal class OlmMachine( * * @return the encrypted key export as a bytearray. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun exportKeys(passphrase: String, rounds: Int): ByteArray = withContext(Dispatchers.IO) { inner.exportKeys(passphrase, rounds).toByteArray() } @@ -485,7 +490,7 @@ internal class OlmMachine( * * @param listener A callback that can be used to introspect the progress of the key import. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun importKeys( keys: ByteArray, passphrase: String, @@ -501,7 +506,7 @@ internal class OlmMachine( ImportRoomKeysResult(result.total, result.imported) } - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun getIdentity(userId: String): UserIdentities? { val identity = withContext(Dispatchers.IO) { inner.getIdentity(userId) @@ -545,7 +550,7 @@ internal class OlmMachine( * * @return The Device if it found one. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun getCryptoDeviceInfo(userId: String, deviceId: String): CryptoDeviceInfo? { return if (userId == userId() && deviceId == deviceId()) { // Our own device isn't part of our store on the Rust side, return it @@ -556,7 +561,7 @@ internal class OlmMachine( } } - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun getDevice(userId: String, deviceId: String): Device? { val device = withContext(Dispatchers.IO) { inner.getDevice(userId, deviceId) @@ -578,7 +583,7 @@ internal class OlmMachine( * * @return The list of Devices or an empty list if there aren't any. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun getCryptoDeviceInfo(userId: String): List { val devices = this.getUserDevices(userId).map { it.toCryptoDeviceInfo() }.toMutableList() @@ -658,7 +663,7 @@ internal class OlmMachine( } /** Discard the currently active room key for the given room if there is one. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) fun discardRoomKey(roomId: String) { runBlocking { inner.discardRoomKey(roomId) } } @@ -770,7 +775,7 @@ internal class OlmMachine( } } - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun enableBackup(key: String, version: String) { return withContext(Dispatchers.Default) { val backupKey = BackupKey(key, mapOf(), null) @@ -797,7 +802,7 @@ internal class OlmMachine( inner.saveRecoveryKey(key, version) } - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun backupRoomKeys(): Request? { return withContext(Dispatchers.Default) { Timber.d("BACKUP CREATING REQUEST") @@ -806,4 +811,18 @@ internal class OlmMachine( request } } + + @Throws(CryptoStoreException::class) + suspend fun checkAuthDataSignature(authData: MegolmBackupAuthData): Boolean { + return withContext(Dispatchers.Default) { + val adapter = MoshiProvider + .providesMoshi() + .newBuilder() + .add(CheckNumberType.JSON_ADAPTER_FACTORY) + .build() + .adapter(MegolmBackupAuthData::class.java) + val serializedAuthData = adapter.toJson(authData) + inner.verifyBackup(serializedAuthData) + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index 337d9ded6b..fefabf2bd4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -26,7 +26,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxStat import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher -import uniffi.olm.CryptoStoreErrorException +import uniffi.olm.CryptoStoreException import uniffi.olm.OlmMachine import uniffi.olm.QrCode import uniffi.olm.Verification @@ -172,7 +172,7 @@ internal class QrCodeVerification( * The method turns into a noop if we're not yet ready to confirm the scanning, * i.e. we didn't yet receive a m.key.verification.start event from the other side. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) private suspend fun confirm() { val result = withContext(Dispatchers.IO) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index 34b3e9fed6..53c7fef231 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -27,7 +27,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxStat import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode -import uniffi.olm.CryptoStoreErrorException +import uniffi.olm.CryptoStoreException import uniffi.olm.OlmMachine import uniffi.olm.Sas import uniffi.olm.Verification @@ -202,7 +202,7 @@ internal class SasVerification( } } - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) private suspend fun confirm() { val result = withContext(Dispatchers.IO) { machine.confirmVerification(inner.otherUserId, inner.flowId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt index 1373e1bbe7..4d21d796c5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt @@ -25,8 +25,8 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey import org.matrix.android.sdk.internal.crypto.verification.prepareMethods -import uniffi.olm.CryptoStoreErrorException -import uniffi.olm.SignatureErrorException +import uniffi.olm.CryptoStoreException +import uniffi.olm.SignatureException /** * A sealed class representing user identities. @@ -46,7 +46,7 @@ sealed class UserIdentities { * * @return True if the identity is considered to be verified and trusted, false otherwise. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) abstract suspend fun verified(): Boolean /** @@ -59,7 +59,7 @@ sealed class UserIdentities { * Throws a SignatureErrorException if we can't sign the identity, * if for example we don't have access to our user-signing key. */ - @Throws(SignatureErrorException::class) + @Throws(SignatureException::class) abstract suspend fun verify() /** @@ -93,7 +93,7 @@ internal class OwnUserIdentity( * * To perform an interactive verification user the [requestVerification] method instead. */ - @Throws(SignatureErrorException::class) + @Throws(SignatureException::class) override suspend fun verify() { val request = withContext(Dispatchers.Default) { olmMachine.inner().verifyIdentity(userId) } this.requestSender.sendSignatureUpload(request) @@ -104,7 +104,7 @@ internal class OwnUserIdentity( * * @return True if the identity is considered to be verified and trusted, false otherwise. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) override suspend fun verified(): Boolean { return withContext(Dispatchers.IO) { olmMachine.inner().isIdentityVerified(userId) } } @@ -130,7 +130,7 @@ internal class OwnUserIdentity( * @param methods The list of [VerificationMethod] that we wish to advertise to the other * side as being supported. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun requestVerification(methods: List): VerificationRequest { val stringMethods = prepareMethods(methods) val result = this.olmMachine.inner().requestSelfVerification(stringMethods) @@ -187,7 +187,7 @@ internal class UserIdentity( * * To perform an interactive verification user the [requestVerification] method instead. */ - @Throws(SignatureErrorException::class) + @Throws(SignatureException::class) override suspend fun verify() { val request = withContext(Dispatchers.Default) { olmMachine.inner().verifyIdentity(userId) } this.requestSender.sendSignatureUpload(request) @@ -225,7 +225,7 @@ internal class UserIdentity( * @param transactionId The transaction id that should be used for the request that sends * the `m.key.verification.request` to the room. */ - @Throws(CryptoStoreErrorException::class) + @Throws(CryptoStoreException::class) suspend fun requestVerification( methods: List, roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index fbcf5cfdeb..8c721068d5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -84,6 +84,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import okhttp3.internal.wait import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData import org.matrix.olm.OlmException import org.matrix.olm.OlmPkDecryption diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 55c074916d..645ea4f63c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -42,6 +42,7 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmB import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo import org.matrix.android.sdk.internal.extensions.foldToCallback @@ -266,34 +267,148 @@ internal class RustKeyBackupService @Inject constructor( override fun backupAllGroupSessions(progressListener: ProgressListener?, callback: MatrixCallback?) { + // This is only used in tests? TODO() } + private suspend fun checkBackupTrust(authData: MegolmBackupAuthData?): KeysBackupVersionTrust { + return if (authData == null || authData.publicKey.isEmpty() || authData.signatures.isEmpty()) { + Timber.v("getKeysBackupTrust: Key backup is absent or missing required data") + KeysBackupVersionTrust() + } else { + KeysBackupVersionTrust(olmMachine.checkAuthDataSignature(authData)) + } + } + override fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult, callback: MatrixCallback) { - Timber.d("BACKUP: HELLOO TRYING TO CHECK THE TRUST") - // TODO - callback.onSuccess(KeysBackupVersionTrust(false)) + val authData = keysBackupVersion.getAuthDataAsMegolmBackupAuthData() + + cryptoCoroutineScope.launch { + try { + callback.onSuccess(checkBackupTrust(authData)) + } catch (exception: Throwable) { + callback.onFailure(exception) + } + } } override fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, trust: Boolean, callback: MatrixCallback) { Timber.v("trustKeyBackupVersion: $trust, version ${keysBackupVersion.version}") - TODO() + + // Get auth data to update it + val authData = getMegolmBackupAuthData(keysBackupVersion) + + if (authData == null) { + Timber.w("trustKeyBackupVersion:trust: Key backup is missing required data") + + callback.onFailure(IllegalArgumentException("Missing element")) + } else { + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + val body = withContext(coroutineDispatchers.crypto) { + // Get current signatures, or create an empty set + val userId = olmMachine.userId() + val signatures = authData.signatures[userId].orEmpty().toMutableMap() + + if (trust) { + // Add current device signature + val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, authData.signalableJSONDictionary()) + val deviceSignature = olmMachine.sign(canonicalJson) + + deviceSignature[userId]?.forEach { entry -> + signatures[entry.key] = entry.value + } + } else { + signatures.remove("ed25519:${olmMachine.deviceId()}") + } + + val newAuthData = authData.copy() + val newSignatures = newAuthData.signatures.toMutableMap() + newSignatures[userId] = signatures + + @Suppress("UNCHECKED_CAST") + UpdateKeysBackupVersionBody( + algorithm = keysBackupVersion.algorithm, + authData = newAuthData.copy(signatures = newSignatures).toJsonDict(), + version = keysBackupVersion.version) + } + try { + sender.updateBackup(keysBackupVersion, body) + + val newKeysBackupVersion = KeysVersionResult( + algorithm = keysBackupVersion.algorithm, + authData = body.authData, + version = keysBackupVersion.version, + hash = keysBackupVersion.hash, + count = keysBackupVersion.count + ) + + checkAndStartWithKeysBackupVersion(newKeysBackupVersion) + callback.onSuccess(Unit) + } catch (exception: Throwable) { + callback.onFailure(exception) + } + } + } + } + + // Check that the recovery key matches to the public key that we downloaded from the server. + // If they match, we can trust the public key and enable backups since we have the private key. + private fun checkRecoveryKey(recoveryKey: BackupRecoveryKey, keysBackupData: KeysVersionResult) { + val backupKey = recoveryKey.publicKey() + val authData = getMegolmBackupAuthData(keysBackupData) + + when { + authData == null -> { + Timber.w("isValidRecoveryKeyForKeysBackupVersion: Key backup is missing required data") + throw IllegalArgumentException("Missing element") + + } + backupKey.publicKey != authData.publicKey -> { + Timber.w("isValidRecoveryKeyForKeysBackupVersion: Public keys mismatch") + throw IllegalArgumentException("Invalid recovery key or password") + } + else -> { + // This case is fine, the public key on the server matches the public key the + // recovery key produced. + } + } } override fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, recoveryKey: String, callback: MatrixCallback) { Timber.v("trustKeysBackupVersionWithRecoveryKey: version ${keysBackupVersion.version}") - TODO() + + cryptoCoroutineScope.launch { + try { + // This is ~nowhere mentioned, the string here is actually a base58 encoded key. + // This not really supported by the spec for the backup key, the 4S key supports + // base58 encoding and the same method seems to be used here. + val key = BackupRecoveryKey.fromBase58(recoveryKey) + checkRecoveryKey(key, keysBackupVersion) + trustKeysBackupVersion(keysBackupVersion, true, callback) + + } catch (exception: Throwable) { + callback.onFailure(exception) + } + } } override fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, password: String, callback: MatrixCallback) { - TODO() + cryptoCoroutineScope.launch { + try { + val key = BackupRecoveryKey.fromPassphrase(password) + checkRecoveryKey(key, keysBackupVersion) + trustKeysBackupVersion(keysBackupVersion, true, callback) + } catch (exception: Throwable) { + callback.onFailure(exception) + } + } } override fun onSecretKeyGossip(secret: String) { @@ -437,8 +552,9 @@ internal class RustKeyBackupService @Inject constructor( } Timber.v(" -> enabling key backups") - // TODO - // enableKeysBackup(keyBackupVersion) + cryptoCoroutineScope.launch { + enableKeysBackup(keyBackupVersion) + } } else { Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: ${keyBackupVersion.version}") if (versionInStore != null) { @@ -595,7 +711,7 @@ internal class RustKeyBackupService @Inject constructor( olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_BACKUP, response) Timber.d("BACKUP MARKED REQUEST AS SENT") - // TODO again is this correct? + // TODO, again is this correct? withContext(Dispatchers.Main) { backupKeys() } diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 0b8d791281..566baa71cb 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -17,7 +17,7 @@ base64 = "0.13.0" thiserror = "1.0.25" tracing = "0.1.26" tracing-subscriber = "0.2.18" -uniffi = "0.12.0" +uniffi = "0.14.0" pbkdf2 = "0.8.0" sha2 = "0.9.5" rand = "0.8.4" @@ -28,14 +28,14 @@ version = "0.2.1" features = ["lax_deserialize"] [dependencies.matrix-sdk-common] -path = "/home/poljar/werk/priv/nio-rust/crates/matrix-sdk-common/" +path = "/home/poljar/werk/matrix/nio-rust/crates/matrix-sdk-common/" # git = "https://github.com/matrix-org/matrix-rust-sdk/" # rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" [dependencies.matrix-sdk-crypto] # git = "https://github.com/matrix-org/matrix-rust-sdk/" # rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" -path = "/home/poljar/werk/priv/nio-rust/crates/matrix-sdk-crypto/" +path = "/home/poljar/werk/matrix/nio-rust/crates/matrix-sdk-crypto/" features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index c489b71602..6a2ca6a819 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -1,11 +1,9 @@ #![deny( dead_code, - missing_docs, trivial_casts, trivial_numeric_casts, unused_extern_crates, unused_import_braces, - unused_qualifications )] //! TODO diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 4f420e13d1..e61c97b365 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -1321,4 +1321,12 @@ impl OlmMachine { }) .collect() } + + /// TODO + pub fn verify_backup(&self, auth_data: &str) -> Result { + let auth_data = serde_json::from_str(auth_data)?; + Ok(self + .runtime + .block_on(self.inner.backup_machine().verify_backup(auth_data))?) + } } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 5d9cfd48e0..e1b9f06e05 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -360,6 +360,8 @@ interface OlmMachine { [Throws=CryptoStoreError] BackupKeys? get_backup_keys(); boolean backup_enabled(); + [Throws=CryptoStoreError] + boolean verify_backup([ByRef] string auth_data); }; dictionary PassphraseInfo { @@ -389,6 +391,8 @@ interface BackupRecoveryKey { constructor(string key); [Name=from_passphrase] constructor(string key); + [Name=from_base58] + constructor(string key); string to_base58(); BackupKey public_key(); }; From 2b8783b489283e327baf41e733a6c360a9e90788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 2 Nov 2021 16:14:49 +0100 Subject: [PATCH 163/252] crypto: Add support for key backup restoring --- .../internal/crypto/DefaultCryptoService.kt | 27 ++- .../android/sdk/internal/crypto/OlmMachine.kt | 31 +++- .../crypto/keysbackup/RustKeyBackupService.kt | 165 ++++++++++++++++-- rust-sdk/src/backup_recovery_key.rs | 27 ++- rust-sdk/src/lib.rs | 2 +- rust-sdk/src/machine.rs | 42 +++-- rust-sdk/src/olm.udl | 13 ++ 7 files changed, 272 insertions(+), 35 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index e9c28376ff..3d23c64d32 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -58,7 +58,6 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.auth.registration.handleUIA import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData @@ -70,6 +69,9 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupV import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionDataTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionsDataTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetSessionsDataTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo @@ -142,6 +144,9 @@ internal class RequestSender @Inject constructor( private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, private val backupRoomKeysTask: StoreSessionsDataTask, private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask, + private val getSessionsDataTask: GetSessionsDataTask, + private val getRoomSessionsDataTask: GetRoomSessionsDataTask, + private val getRoomSessionDataTask: GetRoomSessionDataTask, ) { companion object { const val REQUEST_RETRY_COUNT = 3 @@ -321,6 +326,26 @@ internal class RequestSender @Inject constructor( val params = UpdateKeysBackupVersionTask.Params(keysBackupVersion.version, body) updateKeysBackupVersionTask.executeRetry(params, REQUEST_RETRY_COUNT) } + + suspend fun downloadBackedUpKeys(version: String, roomId: String, sessionId: String): KeysBackupData { + val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version)) + + return KeysBackupData(mutableMapOf( + roomId to RoomKeysBackupData(mutableMapOf( + sessionId to data + )) + )) + } + + suspend fun downloadBackedUpKeys(version: String, roomId: String): KeysBackupData { + val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version)) + // Convert to KeysBackupData + return KeysBackupData(mutableMapOf(roomId to data)) + } + + suspend fun downloadBackedUpKeys(version: String): KeysBackupData { + return getSessionsDataTask.execute(GetSessionsDataTask.Params(version)) + } } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index e4f01c842b..54b899f6d4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -18,10 +18,6 @@ package org.matrix.android.sdk.internal.crypto import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.squareup.moshi.Types -import java.io.File -import java.nio.charset.Charset -import java.util.concurrent.ConcurrentHashMap import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext @@ -39,7 +35,6 @@ import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData 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 @@ -51,7 +46,6 @@ import org.matrix.android.sdk.internal.network.parsing.CheckNumberType 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.ToDeviceSyncResponse -import org.matrix.android.sdk.internal.util.JsonCanonicalizer import timber.log.Timber import uniffi.olm.BackupKey import uniffi.olm.BackupKeys @@ -62,13 +56,16 @@ import uniffi.olm.DecryptionException import uniffi.olm.DeviceLists import uniffi.olm.KeyRequestPair import uniffi.olm.Logger -import uniffi.olm.OlmMachine as InnerMachine -import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.Request import uniffi.olm.RequestType import uniffi.olm.RoomKeyCounts -import uniffi.olm.UserIdentity as RustUserIdentity import uniffi.olm.setLogger +import java.io.File +import java.nio.charset.Charset +import java.util.concurrent.ConcurrentHashMap +import uniffi.olm.OlmMachine as InnerMachine +import uniffi.olm.ProgressListener as RustProgressListener +import uniffi.olm.UserIdentity as RustUserIdentity class CryptoLogger : Logger { override fun log(logLine: String) { @@ -506,6 +503,22 @@ internal class OlmMachine( ImportRoomKeysResult(result.total, result.imported) } + @Throws(CryptoStoreException::class) + suspend fun importDecryptedKeys( + keys: List, + listener: ProgressListener? + ): ImportRoomKeysResult = + withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(List::class.java) + val encodedKeys = adapter.toJson(keys) + + val rustListener = CryptoProgressListener(listener) + + val result = inner.importDecryptedKeys(encodedKeys, rustListener) + + ImportRoomKeysResult(result.total, result.imported) + } + @Throws(CryptoStoreException::class) suspend fun getIdentity(userId: String): UserIdentities? { val identity = withContext(Dispatchers.IO) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 645ea4f63c..ad224a7d7f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -19,6 +19,8 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import android.os.Handler import android.os.Looper import androidx.annotation.UiThread +import androidx.annotation.VisibleForTesting +import androidx.annotation.WorkerThread import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -33,6 +35,7 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP +import org.matrix.android.sdk.internal.crypto.MegolmSessionData import org.matrix.android.sdk.internal.crypto.OlmMachine import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust @@ -40,11 +43,14 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthD import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo +import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.util.JsonCanonicalizer @@ -54,6 +60,7 @@ import timber.log.Timber import uniffi.olm.BackupRecoveryKey import uniffi.olm.Request import uniffi.olm.RequestType +import java.security.InvalidParameterException import javax.inject.Inject import kotlin.random.Random @@ -330,9 +337,9 @@ internal class RustKeyBackupService @Inject constructor( @Suppress("UNCHECKED_CAST") UpdateKeysBackupVersionBody( - algorithm = keysBackupVersion.algorithm, - authData = newAuthData.copy(signatures = newSignatures).toJsonDict(), - version = keysBackupVersion.version) + algorithm = keysBackupVersion.algorithm, + authData = newAuthData.copy(signatures = newSignatures).toJsonDict(), + version = keysBackupVersion.version) } try { sender.updateBackup(keysBackupVersion, body) @@ -364,7 +371,6 @@ internal class RustKeyBackupService @Inject constructor( authData == null -> { Timber.w("isValidRecoveryKeyForKeysBackupVersion: Key backup is missing required data") throw IllegalArgumentException("Missing element") - } backupKey.publicKey != authData.publicKey -> { Timber.w("isValidRecoveryKeyForKeysBackupVersion: Public keys mismatch") @@ -390,7 +396,6 @@ internal class RustKeyBackupService @Inject constructor( val key = BackupRecoveryKey.fromBase58(recoveryKey) checkRecoveryKey(key, keysBackupVersion) trustKeysBackupVersion(keysBackupVersion, true, callback) - } catch (exception: Throwable) { callback.onFailure(exception) } @@ -423,14 +428,141 @@ internal class RustKeyBackupService @Inject constructor( progressListener.onProgress(backedUpKeys, total) } + /** + * Same method as [RoomKeysRestClient.getRoomKey] except that it accepts nullable + * parameters and always returns a KeysBackupData object through the Callback + */ + private suspend fun getKeys(sessionId: String?, roomId: String?, version: String): KeysBackupData { + return when { + roomId != null && sessionId != null -> { + sender.downloadBackedUpKeys(version, roomId, sessionId) + } + roomId != null -> { + sender.downloadBackedUpKeys(version, roomId) + } + else -> { + sender.downloadBackedUpKeys(version) + } + } + } + + @VisibleForTesting + @WorkerThread + fun decryptKeyBackupData(keyBackupData: KeyBackupData, sessionId: String, roomId: String, key: BackupRecoveryKey): MegolmSessionData? { + var sessionBackupData: MegolmSessionData? = null + + val jsonObject = keyBackupData.sessionData + + val ciphertext = jsonObject["ciphertext"]?.toString() + val mac = jsonObject["mac"]?.toString() + val ephemeralKey = jsonObject["ephemeral"]?.toString() + + if (ciphertext != null && mac != null && ephemeralKey != null) { + try { + val decrypted = key.decrypt(ephemeralKey, mac, ciphertext) + + val moshi = MoshiProvider.providesMoshi() + val adapter = moshi.adapter(MegolmSessionData::class.java) + + sessionBackupData = adapter.fromJson(decrypted) + } catch (e: Throwable) { + Timber.e(e, "OlmException") + } + + if (sessionBackupData != null) { + sessionBackupData = sessionBackupData.copy( + sessionId = sessionId, + roomId = roomId + ) + } + } + + return sessionBackupData + } + + private suspend fun restoreBackup( + keysVersionResult: KeysVersionResult, + recoveryKey: BackupRecoveryKey, + roomId: String?, + sessionId: String?, + stepProgressListener: StepProgressListener?, + ): ImportRoomKeysResult { + withContext(coroutineDispatchers.crypto) { + // Check if the recovery is valid before going any further + if (!isValidRecoveryKey(recoveryKey, keysVersionResult)) { + Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key for this keys version") + throw InvalidParameterException("Invalid recovery key") + } + } + + stepProgressListener?.onStepProgress(StepProgressListener.Step.DownloadingKey) + + // Get backed up keys from the homeserver + val data = getKeys(sessionId, roomId, keysVersionResult.version) + + return withContext(coroutineDispatchers.computation) { + val sessionsData = ArrayList() + // Restore that data + var sessionsFromHsCount = 0 + for ((roomIdLoop, backupData) in data.roomIdToRoomKeysBackupData) { + for ((sessionIdLoop, keyBackupData) in backupData.sessionIdToKeyBackupData) { + sessionsFromHsCount++ + + val sessionData = decryptKeyBackupData(keyBackupData, sessionIdLoop, roomIdLoop, recoveryKey) + + sessionData?.let { + sessionsData.add(it) + } + } + } + Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" + + " of $sessionsFromHsCount from the backup store on the homeserver") + + // Do not trigger a backup for them if they come from the backup version we are using + val backUp = keysVersionResult.version != keysBackupVersion?.version + if (backUp) { + Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up" + + " to backup version: ${keysBackupVersion?.version}") + } + + // Import them into the crypto store + val progressListener = if (stepProgressListener != null) { + object : ProgressListener { + override fun onProgress(progress: Int, total: Int) { + // Note: no need to post to UI thread, importMegolmSessionsData() will do it + stepProgressListener.onStepProgress(StepProgressListener.Step.ImportingKey(progress, total)) + } + } + } else { + null + } + + val result = olmMachine.importDecryptedKeys(sessionsData, progressListener) + + // Do not back up the key if it comes from a backup recovery + if (backUp) { + maybeBackupKeys() + } + + // Save for next time and for gossiping + saveBackupRecoveryKey(recoveryKey.toBase64(), keysVersionResult.version) + result + } + } + override fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, recoveryKey: String, roomId: String?, sessionId: String?, stepProgressListener: StepProgressListener?, callback: MatrixCallback) { - // TODO Timber.v("restoreKeysWithRecoveryKey: From backup version: ${keysVersionResult.version}") + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + runCatching { + val key = BackupRecoveryKey.fromBase58(recoveryKey) + restoreBackup(keysVersionResult, key, roomId, sessionId, stepProgressListener) + }.foldToCallback(callback) + } } override fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, @@ -439,8 +571,16 @@ internal class RustKeyBackupService @Inject constructor( sessionId: String?, stepProgressListener: StepProgressListener?, callback: MatrixCallback) { - // TODO Timber.v("[MXKeyBackup] restoreKeyBackup with password: From backup version: ${keysBackupVersion.version}") + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + runCatching { + val recoveryKey = withContext(coroutineDispatchers.crypto) { + BackupRecoveryKey.fromPassphrase(password) + } + + restoreBackup(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener) + }.foldToCallback(callback) + } } override fun getVersion(version: String, callback: MatrixCallback) { @@ -573,15 +713,18 @@ internal class RustKeyBackupService @Inject constructor( } } + private fun isValidRecoveryKey(recoveryKey: BackupRecoveryKey, version: KeysVersionResult): Boolean { + val publicKey = recoveryKey.publicKey().publicKey + val authData = getMegolmBackupAuthData(version) ?: return false + return authData.publicKey == publicKey + } + override fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback) { val keysBackupVersion = keysBackupVersion ?: return Unit.also { callback.onSuccess(false) } try { val key = BackupRecoveryKey.fromBase64(recoveryKey) - val publicKey = key.publicKey().publicKey - val authData = getMegolmBackupAuthData(keysBackupVersion) ?: return Unit.also { callback.onSuccess(false) } - - callback.onSuccess(authData.publicKey == publicKey) + callback.onSuccess(isValidRecoveryKey(key, keysBackupVersion)) } catch (error: Throwable) { callback.onFailure(error) } diff --git a/rust-sdk/src/backup_recovery_key.rs b/rust-sdk/src/backup_recovery_key.rs index 13f7241176..9a5d54414a 100644 --- a/rust-sdk/src/backup_recovery_key.rs +++ b/rust-sdk/src/backup_recovery_key.rs @@ -3,8 +3,9 @@ use pbkdf2::pbkdf2; use rand::{distributions::Alphanumeric, thread_rng, Rng}; use sha2::Sha512; use std::{collections::HashMap, iter}; +use thiserror::Error; -use matrix_sdk_crypto::backups::RecoveryKey; +use matrix_sdk_crypto::backups::{RecoveryKey, OlmPkDecryptionError}; /// TODO pub struct BackupRecoveryKey { @@ -12,6 +13,14 @@ pub struct BackupRecoveryKey { passphrase_info: Option, } +/// TODO +#[derive(Debug, Error)] +pub enum PkDecryptionError { + /// TODO + #[error("Error decryption a PkMessage {0}")] + Olm(#[from] OlmPkDecryptionError), +} + /// TODO #[derive(Debug, Clone)] pub struct PassphraseInfo { @@ -114,4 +123,20 @@ impl BackupRecoveryKey { pub fn to_base58(&self) -> String { self.inner.to_base58() } + + /// TODO + pub fn to_base64(&self) -> String { + self.inner.to_base64() + } + + pub fn decrypt( + &self, + ephemeral_key: String, + mac: String, + ciphertext: String, + ) -> Result { + self.inner + .decrypt(ephemeral_key, mac, ciphertext) + .map_err(|e| e.into()) + } } diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 6a2ca6a819..301eebf776 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -17,7 +17,7 @@ mod responses; mod users; mod verification; -pub use backup_recovery_key::{BackupKey, BackupRecoveryKey, PassphraseInfo}; +pub use backup_recovery_key::{BackupKey, BackupRecoveryKey, PassphraseInfo, PkDecryptionError}; pub use device::Device; pub use error::{ CryptoStoreError, DecryptionError, KeyImportError, SecretImportError, SignatureError, diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index e61c97b365..b7cd409839 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -35,6 +35,7 @@ use matrix_sdk_crypto::{ backups::{MegolmV1BackupKey, RecoveryKey}, decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, + olm::ExportedRoomKey, EncryptionSettings, LocalTrust, OlmMachine as InnerMachine, UserIdentities, Verification as RustVerification, }; @@ -603,6 +604,25 @@ impl OlmMachine { Ok(encrypted) } + fn impor_keys_helper( + &self, + keys: Vec, + progress_listener: Box, + ) -> Result { + let listener = |progress: usize, total: usize| { + progress_listener.on_progress(progress as i32, total as i32) + }; + + let result = self + .runtime + .block_on(self.inner.import_keys(keys, listener))?; + + Ok(KeysImportResult { + total: result.1 as i32, + imported: result.0 as i32, + }) + } + /// Import room keys from the given serialized key export. /// /// # Arguments @@ -621,19 +641,17 @@ impl OlmMachine { ) -> Result { let keys = Cursor::new(keys); let keys = decrypt_key_export(keys, passphrase)?; + self.impor_keys_helper(keys, progress_listener) + } - let listener = |progress: usize, total: usize| { - progress_listener.on_progress(progress as i32, total as i32) - }; - - let result = self - .runtime - .block_on(self.inner.import_keys(keys, listener))?; - - Ok(KeysImportResult { - total: result.1 as i32, - imported: result.0 as i32, - }) + /// TODO + pub fn import_decrypted_keys( + &self, + keys: &str, + progress_listener: Box, + ) -> Result { + let keys: Vec = serde_json::from_str(keys).unwrap(); + self.impor_keys_helper(keys, progress_listener) } /// Discard the currently active room key for the given room if there is diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index e1b9f06e05..0006dc4ae5 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -10,6 +10,11 @@ callback interface ProgressListener { void on_progress(i32 progress, i32 total); }; +[Error] +enum PkDecryptionError { + "Olm", +}; + [Error] enum KeyImportError { "Export", @@ -334,6 +339,11 @@ interface OlmMachine { [ByRef] string passphrase, ProgressListener progress_listener ); + [Throws=KeyImportError] + KeysImportResult import_decrypted_keys( + [ByRef] string keys, + ProgressListener progress_listener + ); [Throws=CryptoStoreError] void discard_room_key([ByRef] string room_id); @@ -394,5 +404,8 @@ interface BackupRecoveryKey { [Name=from_base58] constructor(string key); string to_base58(); + string to_base64(); BackupKey public_key(); + [Throws=PkDecryptionError] + string decrypt(string ephemeral_key, string mac, string ciphertext); }; From f9476f12af1630fdb54182e96c9c9a9c2d9536f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 3 Nov 2021 12:17:10 +0100 Subject: [PATCH 164/252] crypto: Correctly continue backing up room keys --- .../sdk/internal/crypto/keysbackup/RustKeyBackupService.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index ad224a7d7f..3fae94c731 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -812,7 +812,7 @@ internal class RustKeyBackupService @Inject constructor( * Send a chunk of keys to backup */ @UiThread - private suspend fun backupKeys() { + private suspend fun backupKeys(forceRecheck: Boolean = false) { Timber.v("backupKeys") // Sanity check, as this method can be called after a delay, the state may have change during the delay @@ -824,7 +824,7 @@ internal class RustKeyBackupService @Inject constructor( return } - if (state === KeysBackupState.BackingUp) { + if (state === KeysBackupState.BackingUp && !forceRecheck) { // Do nothing if we are already backing up Timber.v("backupKeys: Invalid state: $state") return @@ -856,7 +856,7 @@ internal class RustKeyBackupService @Inject constructor( // TODO, again is this correct? withContext(Dispatchers.Main) { - backupKeys() + backupKeys(true) } } else { // Can't happen, do we want to panic? From 5c7b248ed2878b14a14aeb2d1b8fe3bd97812f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 3 Nov 2021 12:24:58 +0100 Subject: [PATCH 165/252] crypto: Back up room keys when we create or receive new ones --- .../sdk/internal/crypto/DefaultCryptoService.kt | 16 ++++++++++++++-- .../crypto/keysbackup/RustKeyBackupService.kt | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 3d23c64d32..9f92db5a6c 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -379,7 +379,6 @@ internal class DefaultCryptoService @Inject constructor( private val setDeviceNameTask: SetDeviceNameTask, private val loadRoomMembersTask: LoadRoomMembersTask, private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, - private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, private val coroutineDispatchers: MatrixCoroutineDispatchers, private val taskExecutor: TaskExecutor, private val cryptoCoroutineScope: CoroutineScope, @@ -662,6 +661,8 @@ internal class DefaultCryptoService @Inject constructor( // keys claim request to be sent out. // This could be omitted but then devices might be waiting for the next sendOutgoingRequests() + + keysBackupService?.maybeBackupKeys() } cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { @@ -996,12 +997,14 @@ internal class DefaultCryptoService @Inject constructor( } val keyShareLock = roomKeyShareLocks.getOrPut(roomId, { Mutex() }) + var sharedKey = false keyShareLock.withLock { coroutineScope { this@DefaultCryptoService.olmMachine!!.shareRoomKey(roomId, roomMembers).map { when (it) { is Request.ToDevice -> { + sharedKey = true async { sendToDevice(it) } @@ -1016,6 +1019,12 @@ internal class DefaultCryptoService @Inject constructor( }.joinAll() } } + + // If we sent out a room key over to-device messages it's likely that we created a new one + // Try to back the key up + if (sharedKey) { + keysBackupService?.maybeBackupKeys() + } } private suspend fun encrypt(roomId: String, eventType: String, content: Content): Content { @@ -1120,7 +1129,10 @@ internal class DefaultCryptoService @Inject constructor( override suspend fun importRoomKeys(roomKeysAsArray: ByteArray, password: String, progressListener: ProgressListener?): ImportRoomKeysResult { - return olmMachine!!.importKeys(roomKeysAsArray, password, progressListener) + val result = olmMachine!!.importKeys(roomKeysAsArray, password, progressListener) + keysBackupService?.maybeBackupKeys() + + return result } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 3fae94c731..cd523cf758 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -779,7 +779,7 @@ internal class RustKeyBackupService @Inject constructor( /** * Do a backup if there are new keys, with a delay */ - private fun maybeBackupKeys() { + fun maybeBackupKeys() { when { isStucked -> { // If not already done, or in error case, check for a valid backup version on the homeserver. From d6ecc7d330ec092bb74d92d52c385f34a87af785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 4 Nov 2021 13:32:25 +0100 Subject: [PATCH 166/252] crypto: Connect the backup disabling method --- .../android/sdk/internal/crypto/OlmMachine.kt | 8 ++++++++ .../crypto/keysbackup/RustKeyBackupService.kt | 15 ++------------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 54b899f6d4..16211912e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -796,20 +796,28 @@ internal class OlmMachine( } } + @Throws(CryptoStoreException::class) + fun disableBackup() { + inner.disableBackup() + } + fun backupEnabled(): Boolean { return inner.backupEnabled() } + @Throws(CryptoStoreException::class) fun roomKeyCounts(): RoomKeyCounts { // TODO convert this to a suspendable method return inner.roomKeyCounts() } + @Throws(CryptoStoreException::class) fun getBackupKeys(): BackupKeys? { // TODO this needs to be suspendable return inner.getBackupKeys() } + @Throws(CryptoStoreException::class) fun saveRecoveryKey(key: String?, version: String?) { // TODO convert this to a suspendable method inner.saveRecoveryKey(key, version) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index cd523cf758..392d34ad4a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -168,7 +168,7 @@ internal class RustKeyBackupService @Inject constructor( // Reset backup markers. // Don't we need to join the task here? Isn't this a race condition? cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - // TODO reset our backup state here, i.e. the `backed_up` flag on inbound group sessions + olmMachine.disableBackup() } val keyBackupVersion = KeysVersionResult( @@ -213,18 +213,7 @@ internal class RustKeyBackupService @Inject constructor( */ private fun resetKeysBackupData() { resetBackupAllGroupSessionsListeners() - - /* - - TODO reset data on the rust side - cryptoStore.setKeyBackupVersion(null) - cryptoStore.setKeysBackupData(null) - backupOlmPkEncryption?.releaseEncryption() - backupOlmPkEncryption = null - - // Reset backup markers - cryptoStore.resetBackupMarkers() - */ + olmMachine.disableBackup() } override fun deleteBackup(version: String, callback: MatrixCallback?) { From 50268540c371bca48cf833b8d042ce169a084da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 4 Nov 2021 14:35:01 +0100 Subject: [PATCH 167/252] crypto: Try to import the recovery key if it was gossiped to us --- .../internal/crypto/DefaultCryptoService.kt | 7 +++++ .../crypto/keysbackup/RustKeyBackupService.kt | 27 ++++++++++++++++++- rust-sdk/src/backup_recovery_key.rs | 2 +- rust-sdk/src/machine.rs | 2 +- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 9f92db5a6c..e3dd7710f4 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -80,6 +80,7 @@ import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent +import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent @@ -973,6 +974,12 @@ internal class DefaultCryptoService @Inject constructor( notifyRoomKeyReceived(roomId, sessionId) } + EventType.SEND_SECRET -> { + // The rust-sdk will clear this event if it's invalid, this will produce an invalid base64 error + // when we try to construct the recovery key. + val secretContent = event.getClearContent().toModel() ?: return@forEach + this.keysBackupService?.onSecretKeyGossip(secretContent.secretValue) + } else -> { this.verificationService?.onEvent(event) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 392d34ad4a..26d44bfc38 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -55,6 +55,7 @@ import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.util.JsonCanonicalizer import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers +import org.matrix.android.sdk.internal.util.awaitCallback import org.matrix.olm.OlmException import timber.log.Timber import uniffi.olm.BackupRecoveryKey @@ -407,7 +408,31 @@ internal class RustKeyBackupService @Inject constructor( override fun onSecretKeyGossip(secret: String) { Timber.i("## CrossSigning - onSecretKeyGossip") - TODO() + cryptoCoroutineScope.launch(coroutineDispatchers.main) { + try { + val version = sender.getKeyBackupVersion() + + if (version != null) { + val key = BackupRecoveryKey.fromBase64(secret) + + awaitCallback { + trustKeysBackupVersion(version, true, it) + } + val importResult = awaitCallback { + cryptoCoroutineScope.launch { + restoreBackup(version, key, null, null, null) + } + } + Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") + + saveBackupRecoveryKey(secret, version.version) + } else { + Timber.e("onSecretKeyGossip: Failed to import backup recovery key, no backup version was found on the server") + } + } catch (failure: Throwable) { + Timber.e("onSecretKeyGossip: failed to trust key backup version ${keysBackupVersion?.version}: $failure") + } + } } override fun getBackupProgress(progressListener: ProgressListener) { diff --git a/rust-sdk/src/backup_recovery_key.rs b/rust-sdk/src/backup_recovery_key.rs index 9a5d54414a..6ddf6d05ff 100644 --- a/rust-sdk/src/backup_recovery_key.rs +++ b/rust-sdk/src/backup_recovery_key.rs @@ -57,7 +57,7 @@ impl BackupRecoveryKey { /// TODO pub fn from_base64(key: String) -> Self { Self { - inner: RecoveryKey::from_base64(key).unwrap(), + inner: RecoveryKey::from_base64(&key).unwrap(), passphrase_info: None, } } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index b7cd409839..6b1e5b44c1 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -1311,7 +1311,7 @@ impl OlmMachine { key: Option, version: Option, ) -> Result<(), CryptoStoreError> { - let key = key.map(RecoveryKey::from_base64).transpose().ok().flatten(); + let key = key.map(|k| RecoveryKey::from_base64(&k)).transpose().ok().flatten(); Ok(self .runtime .block_on(self.inner.backup_machine().save_recovery_key(key, version))?) From f1da5a1c7c606edc164100de83f6755da66ff2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 9 Nov 2021 14:10:24 +0100 Subject: [PATCH 168/252] crypto: Update to the latest ruma --- rust-sdk/Cargo.toml | 2 +- rust-sdk/src/machine.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 566baa71cb..572df5452e 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -45,7 +45,7 @@ features = ["rt-multi-thread"] [dependencies.ruma] git = "https://github.com/ruma/ruma" -rev = "0101e110f" +rev = "ac6ecc3e5" features = ["client-api-c"] [build-dependencies] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 6b1e5b44c1..272d675779 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -21,7 +21,7 @@ use ruma::{ IncomingResponse, }, events::{ - key::verification::VerificationMethod, room::encrypted::EncryptedEventContent, + key::verification::VerificationMethod, room::encrypted::RoomEncryptedEventContent, AnyMessageEventContent, EventContent, SyncMessageEvent, }, DeviceKeyAlgorithm, EventId, RoomId, UserId, @@ -527,7 +527,7 @@ impl OlmMachine { content: &'a RawValue, } - let event: SyncMessageEvent = serde_json::from_str(event)?; + let event: SyncMessageEvent = serde_json::from_str(event)?; let room_id = RoomId::try_from(room_id)?; let decrypted = self @@ -570,7 +570,7 @@ impl OlmMachine { event: &str, room_id: &str, ) -> Result { - let event: SyncMessageEvent = serde_json::from_str(event)?; + let event: SyncMessageEvent = serde_json::from_str(event)?; let room_id = RoomId::try_from(room_id)?; let (cancel, request) = self From 7cb143e970cddfb68189cd8d6b8271519e13b3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 11 Nov 2021 16:00:35 +0100 Subject: [PATCH 169/252] crypto: Don't create a new salt when we just want to rederive a recovery key --- .../crypto/keysbackup/RustKeyBackupService.kt | 51 ++++++++++++++-- rust-sdk/src/backup_recovery_key.rs | 61 +++++++++++-------- rust-sdk/src/machine.rs | 6 +- rust-sdk/src/olm.udl | 4 +- 4 files changed, 90 insertions(+), 32 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 26d44bfc38..e1c46b48be 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -120,7 +120,7 @@ internal class RustKeyBackupService @Inject constructor( runCatching { withContext(coroutineDispatchers.crypto) { val key = if (password != null) { - BackupRecoveryKey.fromPassphrase(password) + BackupRecoveryKey.newFromPassphrase(password) } else { BackupRecoveryKey() } @@ -397,9 +397,15 @@ internal class RustKeyBackupService @Inject constructor( callback: MatrixCallback) { cryptoCoroutineScope.launch { try { - val key = BackupRecoveryKey.fromPassphrase(password) - checkRecoveryKey(key, keysBackupVersion) - trustKeysBackupVersion(keysBackupVersion, true, callback) + val key = recoveryKeyFromPassword(password, keysBackupVersion) + + if (key == null) { + Timber.w("trustKeysBackupVersionWithPassphrase: Key backup is missing required data") + callback.onFailure(IllegalArgumentException("Missing element")) + } else { + checkRecoveryKey(key, keysBackupVersion) + trustKeysBackupVersion(keysBackupVersion, true, callback) + } } catch (exception: Throwable) { callback.onFailure(exception) } @@ -589,7 +595,15 @@ internal class RustKeyBackupService @Inject constructor( cryptoCoroutineScope.launch(coroutineDispatchers.main) { runCatching { val recoveryKey = withContext(coroutineDispatchers.crypto) { - BackupRecoveryKey.fromPassphrase(password) + val key = recoveryKeyFromPassword(password, keysBackupVersion) + + if (key == null) { + Timber.w("trustKeysBackupVersionWithPassphrase: Key backup is missing required data") + + throw IllegalArgumentException("Missing element") + } else { + key + } } restoreBackup(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener) @@ -749,6 +763,33 @@ internal class RustKeyBackupService @Inject constructor( return SavedKeyBackupKeyInfo(info.recoveryKey, info.backupVersion) } + /** + * Compute the recovery key from a password and key backup version. + * + * @param password the password. + * @param keysBackupData the backup and its auth data. + * + * @return the recovery key if successful, null in other cases + */ + @WorkerThread + private fun recoveryKeyFromPassword(password: String, keysBackupData: KeysVersionResult): BackupRecoveryKey? { + val authData = getMegolmBackupAuthData(keysBackupData) + + if (authData == null) { + Timber.w("recoveryKeyFromPassword: invalid parameter") + return null + } + + if (authData.privateKeySalt.isNullOrBlank() + || authData.privateKeyIterations == null) { + Timber.w("recoveryKeyFromPassword: Salt and/or iterations not found in key backup auth data") + + return null + } + + return BackupRecoveryKey.fromPassphrase(password, authData.privateKeySalt, authData.privateKeyIterations) + } + /** * Extract MegolmBackupAuthData data from a backup version. * diff --git a/rust-sdk/src/backup_recovery_key.rs b/rust-sdk/src/backup_recovery_key.rs index 6ddf6d05ff..3eb82a30c5 100644 --- a/rust-sdk/src/backup_recovery_key.rs +++ b/rust-sdk/src/backup_recovery_key.rs @@ -5,47 +5,48 @@ use sha2::Sha512; use std::{collections::HashMap, iter}; use thiserror::Error; -use matrix_sdk_crypto::backups::{RecoveryKey, OlmPkDecryptionError}; +use matrix_sdk_crypto::backups::{OlmPkDecryptionError, RecoveryKey}; -/// TODO +/// The private part of the backup key, the one used for recovery. pub struct BackupRecoveryKey { pub(crate) inner: RecoveryKey, passphrase_info: Option, } -/// TODO +/// Error type for the decryption of backed up room keys. #[derive(Debug, Error)] pub enum PkDecryptionError { - /// TODO + /// An internal libolm error happened during decryption. #[error("Error decryption a PkMessage {0}")] Olm(#[from] OlmPkDecryptionError), } -/// TODO +/// Struct containing info about the way the backup key got derived from a +/// passphrase. #[derive(Debug, Clone)] pub struct PassphraseInfo { - /// TODO + /// The salt that was used during key derivation. pub private_key_salt: String, - /// TODO + /// The number of PBKDF rounds that were used for key derivation. pub private_key_iterations: i32, } -/// TODO +/// The public part of the backup key. pub struct BackupKey { - /// TODO + /// The actuall base64 encoded public key. pub public_key: String, - /// TODO + /// Signatures that have signed our backup key. pub signatures: HashMap>, - /// TODO + /// The passphrase info, if the key was derived from one. pub passphrase_info: Option, } impl BackupRecoveryKey { const KEY_SIZE: usize = 32; const SALT_SIZE: usize = 32; - const PBKDF_ROUNDS: u32 = 500_000; + const PBKDF_ROUNDS: i32 = 500_000; - /// TODO + /// Create a new random [`BackupRecoveryKey`]. pub fn new() -> Self { Self { inner: RecoveryKey::new() @@ -54,26 +55,26 @@ impl BackupRecoveryKey { } } - /// TODO + /// Try to create a [`BackupRecoveryKey`] from a base 64 encoded string. pub fn from_base64(key: String) -> Self { Self { + // TODO remove the unwrap inner: RecoveryKey::from_base64(&key).unwrap(), passphrase_info: None, } } - /// TODO + /// Try to create a [`BackupRecoveryKey`] from a base 58 encoded string. pub fn from_base58(key: String) -> Self { Self { + // TODO remove the unwrap inner: RecoveryKey::from_base58(&key).unwrap(), passphrase_info: None, } } - /// TODO - pub fn from_passphrase(passphrase: String) -> Self { - let mut key = [0u8; Self::KEY_SIZE]; - + /// Create a new [`BackupRecoveryKey`] from the given passphrase. + pub fn new_from_passphrase(passphrase: String) -> Self { let mut rng = thread_rng(); let salt: String = iter::repeat(()) .map(|()| rng.sample(Alphanumeric)) @@ -81,10 +82,18 @@ impl BackupRecoveryKey { .take(Self::SALT_SIZE) .collect(); + Self::from_passphrase(passphrase, salt, Self::PBKDF_ROUNDS) + } + + /// Restore a [`BackupRecoveryKey`] from the given passphrase. + pub fn from_passphrase(passphrase: String, salt: String, rounds: i32) -> Self { + let mut key = [0u8; Self::KEY_SIZE]; + let rounds = rounds as u32; + pbkdf2::>( passphrase.as_bytes(), salt.as_bytes(), - Self::PBKDF_ROUNDS, + rounds, &mut key, ); @@ -92,12 +101,12 @@ impl BackupRecoveryKey { inner: RecoveryKey::from_bytes(key), passphrase_info: Some(PassphraseInfo { private_key_salt: salt, - private_key_iterations: Self::PBKDF_ROUNDS as i32, + private_key_iterations: rounds as i32, }), } } - /// TODO + /// Get the public part of the backup key. pub fn public_key(&self) -> BackupKey { let public_key = self.inner.public_key(); @@ -113,22 +122,24 @@ impl BackupRecoveryKey { .collect(); BackupKey { - public_key: public_key.encoded_key(), + public_key: public_key.to_base64(), signatures, passphrase_info: self.passphrase_info.clone(), } } - /// TODO + /// Convert the recovery key to a base 58 encoded string. pub fn to_base58(&self) -> String { self.inner.to_base58() } - /// TODO + /// Convert the recovery key to a base 64 encoded string. pub fn to_base64(&self) -> String { self.inner.to_base64() } + /// Try to decrypt a message that was encrypted using the public part of the + /// backup key. pub fn decrypt( &self, ephemeral_key: String, diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 272d675779..f8cc596ef7 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -1311,7 +1311,11 @@ impl OlmMachine { key: Option, version: Option, ) -> Result<(), CryptoStoreError> { - let key = key.map(|k| RecoveryKey::from_base64(&k)).transpose().ok().flatten(); + let key = key + .map(|k| RecoveryKey::from_base64(&k)) + .transpose() + .ok() + .flatten(); Ok(self .runtime .block_on(self.inner.backup_machine().save_recovery_key(key, version))?) diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 0006dc4ae5..41d77a3aca 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -400,7 +400,9 @@ interface BackupRecoveryKey { [Name=from_base64] constructor(string key); [Name=from_passphrase] - constructor(string key); + constructor(string passphrase, string salt, i32 rounds); + [Name=new_from_passphrase] + constructor(string passphrase); [Name=from_base58] constructor(string key); string to_base58(); From e5af7e6109addbabac4666981940b0af83cbb7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 12 Nov 2021 11:57:52 +0100 Subject: [PATCH 170/252] crypto: Update for the new room key import result --- .../org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 5 +++-- rust-sdk/src/machine.rs | 4 ++-- rust-sdk/src/olm.udl | 4 ++-- rust-sdk/src/responses.rs | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 16211912e1..c2001931d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -500,7 +500,8 @@ internal class OlmMachine( val result = inner.importKeys(decodedKeys, passphrase, rustListener) - ImportRoomKeysResult(result.total, result.imported) + // TODO do we want to remove the cast here? + ImportRoomKeysResult(result.total.toInt(), result.imported.toInt()) } @Throws(CryptoStoreException::class) @@ -516,7 +517,7 @@ internal class OlmMachine( val result = inner.importDecryptedKeys(encodedKeys, rustListener) - ImportRoomKeysResult(result.total, result.imported) + ImportRoomKeysResult(result.total.toInt(), result.imported.toInt()) } @Throws(CryptoStoreException::class) diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index f8cc596ef7..f3859cffdd 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -618,8 +618,8 @@ impl OlmMachine { .block_on(self.inner.import_keys(keys, listener))?; Ok(KeysImportResult { - total: result.1 as i32, - imported: result.0 as i32, + total: result.total_count as i64, + imported: result.imported_count as i64, }) } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 41d77a3aca..977b171e9c 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -58,8 +58,8 @@ dictionary DeviceLists { }; dictionary KeysImportResult { - i32 total; - i32 imported; + i64 total; + i64 imported; }; dictionary DecryptedEvent { diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index 5b0d21599e..a7e9308d32 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -295,8 +295,8 @@ impl From for RumaDeviceLists { } pub struct KeysImportResult { - pub total: i32, - pub imported: i32, + pub total: i64, + pub imported: i64, } pub(crate) enum OwnedResponse { From 097f05af579dbbc289715991f86878d3b63d02a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 12 Nov 2021 11:58:14 +0100 Subject: [PATCH 171/252] crypto: Throw exceptions when restoring a recovery key from a passphrase --- .../crypto/keysbackup/RustKeyBackupService.kt | 45 +++++++------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index e1c46b48be..f378fae189 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -398,15 +398,10 @@ internal class RustKeyBackupService @Inject constructor( cryptoCoroutineScope.launch { try { val key = recoveryKeyFromPassword(password, keysBackupVersion) - - if (key == null) { - Timber.w("trustKeysBackupVersionWithPassphrase: Key backup is missing required data") - callback.onFailure(IllegalArgumentException("Missing element")) - } else { - checkRecoveryKey(key, keysBackupVersion) - trustKeysBackupVersion(keysBackupVersion, true, callback) - } + checkRecoveryKey(key, keysBackupVersion) + trustKeysBackupVersion(keysBackupVersion, true, callback) } catch (exception: Throwable) { + Timber.w(exception) callback.onFailure(exception) } } @@ -595,15 +590,7 @@ internal class RustKeyBackupService @Inject constructor( cryptoCoroutineScope.launch(coroutineDispatchers.main) { runCatching { val recoveryKey = withContext(coroutineDispatchers.crypto) { - val key = recoveryKeyFromPassword(password, keysBackupVersion) - - if (key == null) { - Timber.w("trustKeysBackupVersionWithPassphrase: Key backup is missing required data") - - throw IllegalArgumentException("Missing element") - } else { - key - } + recoveryKeyFromPassword(password, keysBackupVersion) } restoreBackup(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener) @@ -772,22 +759,20 @@ internal class RustKeyBackupService @Inject constructor( * @return the recovery key if successful, null in other cases */ @WorkerThread - private fun recoveryKeyFromPassword(password: String, keysBackupData: KeysVersionResult): BackupRecoveryKey? { + private fun recoveryKeyFromPassword(password: String, keysBackupData: KeysVersionResult): BackupRecoveryKey { val authData = getMegolmBackupAuthData(keysBackupData) - if (authData == null) { - Timber.w("recoveryKeyFromPassword: invalid parameter") - return null + return when { + authData == null -> { + throw IllegalArgumentException("recoveryKeyFromPassword: invalid parameter") + } + authData.privateKeySalt.isNullOrBlank() || authData.privateKeyIterations == null -> { + throw java.lang.IllegalArgumentException("recoveryKeyFromPassword: Salt and/or iterations not found in key backup auth data") + } + else -> { + BackupRecoveryKey.fromPassphrase(password, authData.privateKeySalt, authData.privateKeyIterations) + } } - - if (authData.privateKeySalt.isNullOrBlank() - || authData.privateKeyIterations == null) { - Timber.w("recoveryKeyFromPassword: Salt and/or iterations not found in key backup auth data") - - return null - } - - return BackupRecoveryKey.fromPassphrase(password, authData.privateKeySalt, authData.privateKeyIterations) } /** From ba7aa3513bac06ebf599e3d8a4afb5a55567dcb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 15 Nov 2021 10:31:07 +0100 Subject: [PATCH 172/252] crypto: Depend on a hosted rust-sdk version --- rust-sdk/Cargo.toml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 572df5452e..014ec17454 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -28,14 +28,12 @@ version = "0.2.1" features = ["lax_deserialize"] [dependencies.matrix-sdk-common] -path = "/home/poljar/werk/matrix/nio-rust/crates/matrix-sdk-common/" -# git = "https://github.com/matrix-org/matrix-rust-sdk/" -# rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" +git = "https://github.com/matrix-org/matrix-rust-sdk/" +rev = "1943840b82fd323455d9ca9ce27243d37a660569" [dependencies.matrix-sdk-crypto] -# git = "https://github.com/matrix-org/matrix-rust-sdk/" -# rev = "9bae87b0ac213f9d37c033e76ea3a336e164cf02" -path = "/home/poljar/werk/matrix/nio-rust/crates/matrix-sdk-crypto/" +git = "https://github.com/matrix-org/matrix-rust-sdk/" +rev = "1943840b82fd323455d9ca9ce27243d37a660569" features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] From a3af73261cdeea0f97681d0128482e4ae1fe2f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 15 Nov 2021 10:31:55 +0100 Subject: [PATCH 173/252] crypto: Throw decode errors when creating a recovery key --- rust-sdk/src/backup_recovery_key.rs | 32 ++++++++++++++--------------- rust-sdk/src/lib.rs | 6 ++++-- rust-sdk/src/olm.udl | 11 +++++++--- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/rust-sdk/src/backup_recovery_key.rs b/rust-sdk/src/backup_recovery_key.rs index 3eb82a30c5..67b9c16290 100644 --- a/rust-sdk/src/backup_recovery_key.rs +++ b/rust-sdk/src/backup_recovery_key.rs @@ -21,6 +21,13 @@ pub enum PkDecryptionError { Olm(#[from] OlmPkDecryptionError), } +#[derive(Debug, Error)] +pub enum DecodeError { + /// An error happened while decoding the recovery key. + #[error(transparent)] + Decode(#[from] matrix_sdk_crypto::backups::DecodeError), +} + /// Struct containing info about the way the backup key got derived from a /// passphrase. #[derive(Debug, Clone)] @@ -56,21 +63,19 @@ impl BackupRecoveryKey { } /// Try to create a [`BackupRecoveryKey`] from a base 64 encoded string. - pub fn from_base64(key: String) -> Self { - Self { - // TODO remove the unwrap - inner: RecoveryKey::from_base64(&key).unwrap(), + pub fn from_base64(key: String) -> Result { + Ok(Self { + inner: RecoveryKey::from_base64(&key)?, passphrase_info: None, - } + }) } /// Try to create a [`BackupRecoveryKey`] from a base 58 encoded string. - pub fn from_base58(key: String) -> Self { - Self { - // TODO remove the unwrap - inner: RecoveryKey::from_base58(&key).unwrap(), + pub fn from_base58(key: String) -> Result { + Ok(Self { + inner: RecoveryKey::from_base58(&key)?, passphrase_info: None, - } + }) } /// Create a new [`BackupRecoveryKey`] from the given passphrase. @@ -90,12 +95,7 @@ impl BackupRecoveryKey { let mut key = [0u8; Self::KEY_SIZE]; let rounds = rounds as u32; - pbkdf2::>( - passphrase.as_bytes(), - salt.as_bytes(), - rounds, - &mut key, - ); + pbkdf2::>(passphrase.as_bytes(), salt.as_bytes(), rounds, &mut key); Self { inner: RecoveryKey::from_bytes(key), diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 301eebf776..0add76b18c 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -3,7 +3,7 @@ trivial_casts, trivial_numeric_casts, unused_extern_crates, - unused_import_braces, + unused_import_braces )] //! TODO @@ -17,7 +17,9 @@ mod responses; mod users; mod verification; -pub use backup_recovery_key::{BackupKey, BackupRecoveryKey, PassphraseInfo, PkDecryptionError}; +pub use backup_recovery_key::{ + BackupKey, BackupRecoveryKey, DecodeError, PassphraseInfo, PkDecryptionError, +}; pub use device::Device; pub use error::{ CryptoStoreError, DecryptionError, KeyImportError, SecretImportError, SignatureError, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 977b171e9c..10ca65fc0c 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -395,15 +395,20 @@ dictionary RoomKeyCounts { i64 backed_up; }; +[Error] +enum DecodeError { + "Decode", +}; + interface BackupRecoveryKey { constructor(); - [Name=from_base64] - constructor(string key); [Name=from_passphrase] constructor(string passphrase, string salt, i32 rounds); [Name=new_from_passphrase] constructor(string passphrase); - [Name=from_base58] + [Name=from_base64, Throws=DecodeError] + constructor(string key); + [Name=from_base58, Throws=DecodeError] constructor(string key); string to_base58(); string to_base64(); From 50cdbaf04134b9ed4ae2a030f9e965fd95577b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 17 Nov 2021 13:22:15 +0100 Subject: [PATCH 174/252] crypto: Update to the latest rust-sdk version --- .../android/sdk/internal/crypto/OlmMachine.kt | 8 +- .../crypto/keysbackup/RustKeyBackupService.kt | 15 ++-- rust-sdk/Cargo.toml | 4 +- rust-sdk/src/backup_recovery_key.rs | 23 ++++-- rust-sdk/src/error.rs | 4 +- rust-sdk/src/lib.rs | 14 ++-- rust-sdk/src/machine.rs | 77 +++++++++++++------ rust-sdk/src/olm.udl | 13 ++-- rust-sdk/src/verification.rs | 4 +- 9 files changed, 105 insertions(+), 57 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index c2001931d6..ee83f7f602 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -47,7 +47,6 @@ 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.ToDeviceSyncResponse import timber.log.Timber -import uniffi.olm.BackupKey import uniffi.olm.BackupKeys import uniffi.olm.CrossSigningKeyExport import uniffi.olm.CrossSigningStatus @@ -56,6 +55,7 @@ import uniffi.olm.DecryptionException import uniffi.olm.DeviceLists import uniffi.olm.KeyRequestPair import uniffi.olm.Logger +import uniffi.olm.MegolmV1BackupKey import uniffi.olm.Request import uniffi.olm.RequestType import uniffi.olm.RoomKeyCounts @@ -790,10 +790,10 @@ internal class OlmMachine( } @Throws(CryptoStoreException::class) - suspend fun enableBackup(key: String, version: String) { + suspend fun enableBackupV1(key: String, version: String) { return withContext(Dispatchers.Default) { - val backupKey = BackupKey(key, mapOf(), null) - inner.enableBackup(backupKey, version) + val backupKey = MegolmV1BackupKey(key, mapOf(), null, MXCRYPTO_ALGORITHM_MEGOLM_BACKUP) + inner.enableBackupV1(backupKey, version) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index f378fae189..af5c0a4d41 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -125,7 +125,7 @@ internal class RustKeyBackupService @Inject constructor( BackupRecoveryKey() } - val publicKey = key.publicKey() + val publicKey = key.megolmV1PublicKey() val backupAuthData = SignalableMegolmBackupAuthData( publicKey = publicKey.publicKey, privateKeySalt = publicKey.passphraseInfo?.privateKeySalt, @@ -144,7 +144,7 @@ internal class RustKeyBackupService @Inject constructor( ) MegolmBackupCreationInfo( - algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP, + algorithm = publicKey.backupAlgorithm, authData = signedMegolmBackupAuthData, recoveryKey = key.toBase58() ) @@ -264,7 +264,8 @@ internal class RustKeyBackupService @Inject constructor( override fun backupAllGroupSessions(progressListener: ProgressListener?, callback: MatrixCallback?) { - // This is only used in tests? + // This is only used in tests? While it's fine have methods that are + // only used for tests, this one has a lot of logic that is nowhere else used. TODO() } @@ -354,7 +355,7 @@ internal class RustKeyBackupService @Inject constructor( // Check that the recovery key matches to the public key that we downloaded from the server. // If they match, we can trust the public key and enable backups since we have the private key. private fun checkRecoveryKey(recoveryKey: BackupRecoveryKey, keysBackupData: KeysVersionResult) { - val backupKey = recoveryKey.publicKey() + val backupKey = recoveryKey.megolmV1PublicKey() val authData = getMegolmBackupAuthData(keysBackupData) when { @@ -474,7 +475,7 @@ internal class RustKeyBackupService @Inject constructor( if (ciphertext != null && mac != null && ephemeralKey != null) { try { - val decrypted = key.decrypt(ephemeralKey, mac, ciphertext) + val decrypted = key.decryptV1(ephemeralKey, mac, ciphertext) val moshi = MoshiProvider.providesMoshi() val adapter = moshi.adapter(MegolmSessionData::class.java) @@ -729,7 +730,7 @@ internal class RustKeyBackupService @Inject constructor( } private fun isValidRecoveryKey(recoveryKey: BackupRecoveryKey, version: KeysVersionResult): Boolean { - val publicKey = recoveryKey.publicKey().publicKey + val publicKey = recoveryKey.megolmV1PublicKey().publicKey val authData = getMegolmBackupAuthData(version) ?: return false return authData.publicKey == publicKey } @@ -800,7 +801,7 @@ internal class RustKeyBackupService @Inject constructor( if (retrievedMegolmBackupAuthData != null) { try { - olmMachine.enableBackup(retrievedMegolmBackupAuthData.publicKey, keysVersionResult.version) + olmMachine.enableBackupV1(retrievedMegolmBackupAuthData.publicKey, keysVersionResult.version) keysBackupVersion = keysVersionResult } catch (e: OlmException) { Timber.e(e, "OlmException") diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 014ec17454..e1f5b84001 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -29,11 +29,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "1943840b82fd323455d9ca9ce27243d37a660569" +rev = "2e4d5f25cba03bd26415b91defd6e762e8c31b63" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "1943840b82fd323455d9ca9ce27243d37a660569" +rev = "2e4d5f25cba03bd26415b91defd6e762e8c31b63" features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] diff --git a/rust-sdk/src/backup_recovery_key.rs b/rust-sdk/src/backup_recovery_key.rs index 67b9c16290..4a867294cf 100644 --- a/rust-sdk/src/backup_recovery_key.rs +++ b/rust-sdk/src/backup_recovery_key.rs @@ -5,7 +5,10 @@ use sha2::Sha512; use std::{collections::HashMap, iter}; use thiserror::Error; -use matrix_sdk_crypto::backups::{OlmPkDecryptionError, RecoveryKey}; +use matrix_sdk_crypto::{ + backups::{OlmPkDecryptionError, RecoveryKey}, + store::CryptoStoreError as InnerStoreError, +}; /// The private part of the backup key, the one used for recovery. pub struct BackupRecoveryKey { @@ -26,6 +29,9 @@ pub enum DecodeError { /// An error happened while decoding the recovery key. #[error(transparent)] Decode(#[from] matrix_sdk_crypto::backups::DecodeError), + /// An error happened in the storage layer, + #[error(transparent)] + CryptoStore(#[from] InnerStoreError), } /// Struct containing info about the way the backup key got derived from a @@ -39,13 +45,15 @@ pub struct PassphraseInfo { } /// The public part of the backup key. -pub struct BackupKey { +pub struct MegolmV1BackupKey { /// The actuall base64 encoded public key. pub public_key: String, /// Signatures that have signed our backup key. pub signatures: HashMap>, /// The passphrase info, if the key was derived from one. pub passphrase_info: Option, + /// Get the full name of the backup algorithm this backup key supports. + pub backup_algorithm: String, } impl BackupRecoveryKey { @@ -107,8 +115,8 @@ impl BackupRecoveryKey { } /// Get the public part of the backup key. - pub fn public_key(&self) -> BackupKey { - let public_key = self.inner.public_key(); + pub fn megolm_v1_public_key(&self) -> MegolmV1BackupKey { + let public_key = self.inner.megolm_v1_public_key(); let signatures: HashMap> = public_key .signatures() @@ -121,10 +129,11 @@ impl BackupRecoveryKey { }) .collect(); - BackupKey { + MegolmV1BackupKey { public_key: public_key.to_base64(), signatures, passphrase_info: self.passphrase_info.clone(), + backup_algorithm: public_key.backup_algorithm().to_owned(), } } @@ -140,14 +149,14 @@ impl BackupRecoveryKey { /// Try to decrypt a message that was encrypted using the public part of the /// backup key. - pub fn decrypt( + pub fn decrypt_v1( &self, ephemeral_key: String, mac: String, ciphertext: String, ) -> Result { self.inner - .decrypt(ephemeral_key, mac, ciphertext) + .decrypt_v1(ephemeral_key, mac, ciphertext) .map_err(|e| e.into()) } } diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index dff404f456..caa7c44983 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -2,7 +2,7 @@ use matrix_sdk_crypto::{ store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError, - SignatureError as InnerSignatureError, SecretImportError as RustSecretImportError, + SecretImportError as RustSecretImportError, SignatureError as InnerSignatureError, }; use ruma::identifiers::Error as RumaIdentifierError; @@ -12,6 +12,8 @@ pub enum KeyImportError { Export(#[from] KeyExportError), #[error(transparent)] CryptoStore(#[from] InnerStoreError), + #[error(transparent)] + Json(#[from] serde_json::Error), } #[derive(Debug, thiserror::Error)] diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 0add76b18c..35f62fca4e 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -18,7 +18,7 @@ mod users; mod verification; pub use backup_recovery_key::{ - BackupKey, BackupRecoveryKey, DecodeError, PassphraseInfo, PkDecryptionError, + BackupRecoveryKey, DecodeError, MegolmV1BackupKey, PassphraseInfo, PkDecryptionError, }; pub use device::Device; pub use error::{ @@ -87,19 +87,19 @@ pub struct CrossSigningKeyExport { pub user_signing_key: Option, } -/// TODO +/// Struct holding the number of room keys we have. pub struct RoomKeyCounts { - /// TODO + /// The total number of room keys. pub total: i64, - /// TODO + /// The number of backed up room keys. pub backed_up: i64, } -/// TODO +/// Backup keys and information we load from the store. pub struct BackupKeys { - /// TODO + /// The recovery key as a base64 encoded string. pub recovery_key: String, - /// TODO + /// The version that is used with the recovery key. pub backup_version: String, } diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index f3859cffdd..7581c2b4e7 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -32,7 +32,7 @@ use tokio::runtime::Runtime; use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; use matrix_sdk_crypto::{ - backups::{MegolmV1BackupKey, RecoveryKey}, + backups::{MegolmV1BackupKey as RustBackupKey, RecoveryKey}, decrypt_key_export, encrypt_key_export, matrix_qrcode::QrVerificationData, olm::ExportedRoomKey, @@ -43,11 +43,11 @@ use matrix_sdk_crypto::{ use crate::{ error::{CryptoStoreError, DecryptionError, SecretImportError, SignatureError}, responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, - BackupKey, BackupKeys, BootstrapCrossSigningResult, ConfirmVerificationResult, - CrossSigningKeyExport, CrossSigningStatus, DecryptedEvent, Device, DeviceLists, KeyImportError, - KeysImportResult, ProgressListener, QrCode, Request, RequestType, RequestVerificationResult, - RoomKeyCounts, ScanResult, SignatureUploadRequest, StartSasResult, UserIdentity, Verification, - VerificationRequest, + BackupKeys, BootstrapCrossSigningResult, ConfirmVerificationResult, CrossSigningKeyExport, + CrossSigningStatus, DecodeError, DecryptedEvent, Device, DeviceLists, KeyImportError, + KeysImportResult, MegolmV1BackupKey, ProgressListener, QrCode, Request, RequestType, + RequestVerificationResult, RoomKeyCounts, ScanResult, SignatureUploadRequest, StartSasResult, + UserIdentity, Verification, VerificationRequest, }; /// A high level state machine that handles E2EE for Matrix. @@ -79,7 +79,7 @@ impl OlmMachine { pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { let user_id = UserId::try_from(user_id)?; let device_id = device_id.into(); - let runtime = Runtime::new().unwrap(); + let runtime = Runtime::new().expect("Couldn't create a tokio runtime"); Ok(OlmMachine { inner: runtime.block_on(InnerMachine::new_with_default_store( @@ -499,7 +499,7 @@ impl OlmMachine { let encrypted_content = self .runtime .block_on(self.inner.encrypt(&room_id, content)) - .unwrap(); + .expect("Encrypting an event produced an error"); Ok(serde_json::to_string(&encrypted_content)?) } @@ -644,13 +644,24 @@ impl OlmMachine { self.impor_keys_helper(keys, progress_listener) } - /// TODO + /// Import room keys from the given serialized unencrypted key export. + /// + /// This method is the same as [`OlmMachine::import_keys`] but the + /// decryption step is skipped and should be performed by the caller. This + /// may be useful for custom handling or for server-side key backups. + /// + /// # Arguments + /// + /// * `keys` - The serialized version of the unencrypted key export. + /// + /// * `progress_listener` - A callback that can be used to introspect the + /// progress of the key import. pub fn import_decrypted_keys( &self, keys: &str, progress_listener: Box, ) -> Result { - let keys: Vec = serde_json::from_str(keys).unwrap(); + let keys: Vec = serde_json::from_str(keys)?; self.impor_keys_helper(keys, progress_listener) } @@ -1263,30 +1274,47 @@ impl OlmMachine { Ok(()) } - /// TODO - pub fn enable_backup(&self, key: BackupKey, version: String) -> Result<(), CryptoStoreError> { - let backup_key = MegolmV1BackupKey::from_base64(&key.public_key).unwrap(); + /// Activate the given backup key to be used with the given backup version. + /// + /// **Warning**: The caller needs to make sure that the given `BackupKey` is + /// trusted, otherwise we might be encrypting room keys that a malicious + /// party could decrypt. + /// + /// The [`OlmMachine::verify_backup`] method can be used to so. + pub fn enable_backup_v1( + &self, + key: MegolmV1BackupKey, + version: String, + ) -> Result<(), DecodeError> { + let backup_key = RustBackupKey::from_base64(&key.public_key)?; backup_key.set_version(version); self.runtime - .block_on(self.inner.backup_machine().enable_backup(backup_key))?; + .block_on(self.inner.backup_machine().enable_backup_v1(backup_key))?; Ok(()) } - /// TODO + /// Are we able to encrypt room keys. + /// + /// This returns true if we have an active `BackupKey` and backup version + /// registered with the state machine. pub fn backup_enabled(&self) -> bool { self.runtime.block_on(self.inner.backup_machine().enabled()) } - /// TODO + /// Disable and reset our backup state. + /// + /// This will remove any pending backup request, remove the backup key and + /// reset the backup state of each room key we have. pub fn disable_backup(&self) -> Result<(), CryptoStoreError> { Ok(self .runtime .block_on(self.inner.backup_machine().disable_backup())?) } - /// TODO + /// Encrypt a batch of room keys and return a request that needs to be sent + /// out to backup the room keys. pub fn backup_room_keys(&self) -> Result, CryptoStoreError> { let request = self .runtime @@ -1297,7 +1325,7 @@ impl OlmMachine { Ok(request) } - /// TODO + /// Get the number of backed up room keys and the total number of room keys. pub fn room_key_counts(&self) -> Result { Ok(self .runtime @@ -1305,7 +1333,10 @@ impl OlmMachine { .into()) } - /// TODO + /// Store the recovery key in the cryptostore. + /// + /// This is useful if the client wants to support gossiping of the backup + /// key. pub fn save_recovery_key( &self, key: Option, @@ -1321,7 +1352,7 @@ impl OlmMachine { .block_on(self.inner.backup_machine().save_recovery_key(key, version))?) } - /// TODO + /// Get the backup keys we have saved in our crypto store. pub fn get_backup_keys(&self) -> Result, CryptoStoreError> { Ok(self .runtime @@ -1330,7 +1361,8 @@ impl OlmMachine { .ok()) } - /// TODO + /// Sign the given message using our device key and if available cross + /// signing master key. pub fn sign(&self, message: &str) -> HashMap> { self.runtime .block_on(self.inner.sign(message)) @@ -1344,7 +1376,8 @@ impl OlmMachine { .collect() } - /// TODO + /// Check if the given backup has been verified by us or by another of our + /// devices that we trust. pub fn verify_backup(&self, auth_data: &str) -> Result { let auth_data = serde_json::from_str(auth_data)?; Ok(self diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 10ca65fc0c..2590afbed7 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -19,6 +19,7 @@ enum PkDecryptionError { enum KeyImportError { "Export", "CryptoStore", + "Json", }; [Error] @@ -357,8 +358,8 @@ interface OlmMachine { boolean is_identity_verified([ByRef] string user_id); record> sign([ByRef] string message); - [Throws=CryptoStoreError] - void enable_backup(BackupKey key, string version); + [Throws=DecodeError] + void enable_backup_v1(MegolmV1BackupKey key, string version); [Throws=CryptoStoreError] void disable_backup(); [Throws=CryptoStoreError] @@ -379,10 +380,11 @@ dictionary PassphraseInfo { i32 private_key_iterations; }; -dictionary BackupKey { +dictionary MegolmV1BackupKey { string public_key; record> signatures; PassphraseInfo? passphrase_info; + string backup_algorithm; }; dictionary BackupKeys { @@ -398,6 +400,7 @@ dictionary RoomKeyCounts { [Error] enum DecodeError { "Decode", + "CryptoStore", }; interface BackupRecoveryKey { @@ -412,7 +415,7 @@ interface BackupRecoveryKey { constructor(string key); string to_base58(); string to_base64(); - BackupKey public_key(); + MegolmV1BackupKey megolm_v1_public_key(); [Throws=PkDecryptionError] - string decrypt(string ephemeral_key, string mac, string ciphertext); + string decrypt_v1(string ephemeral_key, string mac, string ciphertext); }; diff --git a/rust-sdk/src/verification.rs b/rust-sdk/src/verification.rs index 39f3012622..13d7204d92 100644 --- a/rust-sdk/src/verification.rs +++ b/rust-sdk/src/verification.rs @@ -10,13 +10,13 @@ pub enum Verification { /// The `m.sas.v1` verification flow. SasV1 { #[allow(missing_docs)] - sas: Sas + sas: Sas, }, /// The `m.qr_code.scan.v1`, `m.qr_code.show.v1`, and `m.reciprocate.v1` /// verification flow. QrCodeV1 { #[allow(missing_docs)] - qrcode: QrCode + qrcode: QrCode, }, } From f209ae26bcf94c28eee36845552a1b07da42eda7 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 29 Oct 2021 15:24:18 +0200 Subject: [PATCH 175/252] Wire compute room shields with rust --- .gitignore | 2 + .../sdk/api/session/crypto/CryptoService.kt | 9 +- .../crosssigning/CrossSigningService.kt | 3 + .../sdk/internal/crypto/CryptoModule.kt | 11 +- .../crypto/CryptoSessionInfoProvider.kt | 50 +- .../internal/crypto/DefaultCryptoService.kt | 394 +--- .../android/sdk/internal/crypto/Device.kt | 2 +- .../sdk/internal/crypto/DeviceListManager.kt | 1 + .../android/sdk/internal/crypto/OlmMachine.kt | 12 +- .../sdk/internal/crypto/OlmMachineProvider.kt | 37 + .../sdk/internal/crypto/QrCodeVerification.kt | 2 +- .../sdk/internal/crypto/RequestSender.kt | 282 +++ .../crypto/RustCrossSigningService.kt | 59 +- .../sdk/internal/crypto/SasVerification.kt | 2 +- .../sdk/internal/crypto/UserIdentities.kt | 11 +- .../internal/crypto/VerificationRequest.kt | 2 +- .../sdk/internal/crypto/api/CryptoApi.kt | 1 - .../DefaultCrossSigningService.kt | 1602 ++++++++--------- .../crypto/crosssigning/UpdateTrustWorker.kt | 736 ++++---- .../crypto/model/rest/KeysClaimResponse.kt | 4 +- .../ClaimOneTimeKeysForUsersDeviceTask.kt | 3 - .../internal/crypto/tasks/UploadKeysTask.kt | 2 - .../verification/RustVerificationService.kt | 72 +- .../crypto/verification/UpdateDispatcher.kt | 78 + .../database/mapper/RoomSummaryMapper.kt | 2 +- .../sdk/internal/session/SessionComponent.kt | 6 +- .../room/create/CreateRoomBodyBuilder.kt | 16 +- .../room/membership/LoadRoomMembersTask.kt | 10 +- .../room/summary/RoomSummaryUpdater.kt | 11 +- rust-sdk/Makefile | 18 +- 30 files changed, 1867 insertions(+), 1573 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/UpdateDispatcher.kt diff --git a/.gitignore b/.gitignore index 2661fdd7fe..d4f9f385ac 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ Cargo.lock /fastlane/report.xml /library/build + +matrix-sdk-android/src/main/jniLibs/ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 7d9bc33ba3..fc53540c5f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -35,13 +35,11 @@ import org.matrix.android.sdk.internal.crypto.OutgoingRoomKeyRequest 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.MXDeviceInfo import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody interface CryptoService { @@ -153,4 +151,11 @@ interface CryptoService { * send, in order to speed up sending of the message. */ fun prepareToEncrypt(roomId: String, callback: MatrixCallback) + + /** + * When LL all room members might not be loaded when setting up encryption. + * This is called after room members have been loaded + * ... not sure if shoud be API + */ + fun onE2ERoomMemberLoadedFromServer(roomId: String) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index 709babc23f..c226e4aa92 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.session.crypto.crosssigning import androidx.lifecycle.LiveData import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustResult import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult @@ -104,6 +105,8 @@ interface CrossSigningService { fun trustDevice(deviceId: String, callback: MatrixCallback) + suspend fun shieldForGroup(userIds: List) : RoomEncryptionTrustLevel + /** * Check if a device is trusted * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index fe388b44e2..eb898188ae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -27,7 +27,6 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningServic import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.crosssigning.ComputeTrustTask import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultComputeTrustTask -import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DefaultCreateKeysBackupVersionTask @@ -96,6 +95,11 @@ import org.matrix.android.sdk.internal.di.UserMd5 import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.cache.ClearCacheTask import org.matrix.android.sdk.internal.session.cache.RealmClearCacheTask +import io.realm.RealmConfiguration +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import retrofit2.Retrofit import java.io.File @@ -238,7 +242,10 @@ internal abstract class CryptoModule { abstract fun bindClaimOneTimeKeysForUsersDeviceTask(task: DefaultClaimOneTimeKeysForUsersDevice): ClaimOneTimeKeysForUsersDeviceTask @Binds - abstract fun bindCrossSigningService(service: DefaultCrossSigningService): CrossSigningService + abstract fun bindCrossSigningService(service: RustCrossSigningService): CrossSigningService + + @Binds + abstract fun bindVerificationService(service: RustVerificationService): VerificationService @Binds abstract fun bindCryptoStore(store: RealmCryptoStore): IMXCryptoStore diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt index 5338e7e92f..b80bdc4537 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt @@ -17,13 +17,21 @@ package org.matrix.android.sdk.internal.crypto import com.zhuinden.monarchy.Monarchy +import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity +import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity +import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.database.query.whereType import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.util.fetchCopied +import org.matrix.android.sdk.internal.util.logLimit +import timber.log.Timber import javax.inject.Inject /** @@ -31,7 +39,8 @@ import javax.inject.Inject * in the session DB, this class encapsulate this functionality */ internal class CryptoSessionInfoProvider @Inject constructor( - @SessionDatabase private val monarchy: Monarchy + @SessionDatabase private val monarchy: Monarchy, + @UserId private val myUserId: String ) { fun isRoomEncrypted(roomId: String): Boolean { @@ -47,7 +56,7 @@ internal class CryptoSessionInfoProvider @Inject constructor( /** * @param allActive if true return joined as well as invited, if false, only joined */ - fun getRoomUserIds(roomId: String, allActive: Boolean): List { + fun getRoomUserIds(roomId: String, allActive: Boolean): List { var userIds: List = emptyList() monarchy.doWithRealm { realm -> userIds = if (allActive) { @@ -58,4 +67,41 @@ internal class CryptoSessionInfoProvider @Inject constructor( } return userIds } + + fun getUserListForShieldComputation(roomId: String): List { + var userIds: List = emptyList() + monarchy.doWithRealm { realm -> + userIds = RoomMemberHelper(realm, roomId).getActiveRoomMemberIds() + } + var isDirect = false + monarchy.doWithRealm { realm -> + isDirect = RoomSummaryEntity.where(realm, roomId = roomId).findFirst()?.isDirect == true + } + + return if (isDirect || userIds.size <= 2) { + userIds.filter { it != myUserId } + } else { + userIds + } + } + + fun getRoomsWhereUsersAreParticipating(userList: List): List { + var roomIds: List? = null + monarchy.doWithRealm { sessionRealm -> + roomIds = sessionRealm.where(RoomMemberSummaryEntity::class.java) + .`in`(RoomMemberSummaryEntityFields.USER_ID, userList.toTypedArray()) + .distinct(RoomMemberSummaryEntityFields.ROOM_ID) + .findAll() + .map { it.roomId } + .also { Timber.d("## CrossSigning - ... impacted rooms ${it.logLimit()}") } + } + return roomIds.orEmpty() + } + + fun updateShieldForRoom(roomId: String, shield: RoomEncryptionTrustLevel) { + monarchy.writeAsync { realm -> + val summary = RoomSummaryEntity.where(realm, roomId = roomId).findFirst() + summary?.roomEncryptionTrustLevel = shield + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 6d1d4a9935..021b4ff42d 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -88,31 +88,17 @@ import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent -import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse -import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse -import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse -import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask -import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask -import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask -import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask -import org.matrix.android.sdk.internal.crypto.tasks.SendVerificationMessageTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask -import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask -import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask -import org.matrix.android.sdk.internal.crypto.tasks.UploadSigningKeysTask import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import org.matrix.android.sdk.internal.di.DeviceId -import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback -import org.matrix.android.sdk.internal.network.parsing.CheckNumberType import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.task.TaskExecutor @@ -120,235 +106,13 @@ import org.matrix.android.sdk.internal.task.TaskThread import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.task.launchToCallback import timber.log.Timber -import uniffi.olm.OutgoingVerificationRequest import uniffi.olm.Request import uniffi.olm.RequestType -import uniffi.olm.SignatureUploadRequest -import uniffi.olm.UploadSigningKeysRequest -import java.io.File import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import kotlin.math.max -internal class RequestSender @Inject constructor( - private val sendToDeviceTask: SendToDeviceTask, - private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, - private val uploadKeysTask: UploadKeysTask, - private val downloadKeysForUsersTask: DownloadKeysForUsersTask, - private val signaturesUploadTask: UploadSignaturesTask, - private val sendVerificationMessageTask: Lazy, - private val uploadSigningKeysTask: UploadSigningKeysTask, - private val getKeysBackupLastVersionTask: GetKeysBackupLastVersionTask, - private val getKeysBackupVersionTask: GetKeysBackupVersionTask, - private val deleteBackupTask: DeleteBackupTask, - private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, - private val backupRoomKeysTask: StoreSessionsDataTask, - private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask, - private val getSessionsDataTask: GetSessionsDataTask, - private val getRoomSessionsDataTask: GetRoomSessionsDataTask, - private val getRoomSessionDataTask: GetRoomSessionDataTask, - ) { - companion object { - const val REQUEST_RETRY_COUNT = 3 - } - - suspend fun claimKeys(request: Request.KeysClaim): String { - val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) - val response = oneTimeKeysForUsersDeviceTask.executeRetry(claimParams, REQUEST_RETRY_COUNT) - val adapter = MoshiProvider - .providesMoshi() - .adapter(KeysClaimResponse::class.java) - return adapter.toJson(response)!! - } - - suspend fun queryKeys(request: Request.KeysQuery): String { - val params = DownloadKeysForUsersTask.Params(request.users, null) - val response = downloadKeysForUsersTask.executeRetry(params, REQUEST_RETRY_COUNT) - val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) - return adapter.toJson(response)!! - } - - suspend fun uploadKeys(request: Request.KeysUpload): String { - val body = MoshiProvider.providesMoshi().adapter(Map::class.java).fromJson(request.body)!! - val params = UploadKeysTask.Params(body) - - val response = uploadKeysTask.executeRetry(params, REQUEST_RETRY_COUNT) - val adapter = MoshiProvider.providesMoshi().adapter(KeysUploadResponse::class.java) - - return adapter.toJson(response)!! - } - - suspend fun sendVerificationRequest(request: OutgoingVerificationRequest) { - when (request) { - is OutgoingVerificationRequest.InRoom -> sendRoomMessage(request) - is OutgoingVerificationRequest.ToDevice -> sendToDevice(request) - } - } - - suspend fun sendRoomMessage(request: OutgoingVerificationRequest.InRoom): String { - return sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) - } - - suspend fun sendRoomMessage(request: Request.RoomMessage): String { - return sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) - } - - suspend fun sendRoomMessage(eventType: String, roomId: String, content: String, transactionId: String): String { - val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) - val jsonContent = adapter.fromJson(content) - val event = Event(eventType, transactionId, jsonContent, roomId = roomId) - val params = SendVerificationMessageTask.Params(event) - return this.sendVerificationMessageTask.get().executeRetry(params, REQUEST_RETRY_COUNT) - } - - suspend fun sendSignatureUpload(request: Request.SignatureUpload) { - sendSignatureUpload(request.body) - } - - suspend fun sendSignatureUpload(request: SignatureUploadRequest) { - sendSignatureUpload(request.body) - } - - private suspend fun sendSignatureUpload(body: String) { - val adapter = MoshiProvider.providesMoshi().adapter>>(Map::class.java) - val signatures = adapter.fromJson(body)!! - val params = UploadSignaturesTask.Params(signatures) - this.signaturesUploadTask.executeRetry(params, REQUEST_RETRY_COUNT) - } - - suspend fun uploadCrossSigningKeys( - request: UploadSigningKeysRequest, - interactiveAuthInterceptor: UserInteractiveAuthInterceptor? - ) { - val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) - val masterKey = adapter.fromJson(request.masterKey)!!.toCryptoModel() - val selfSigningKey = adapter.fromJson(request.selfSigningKey)!!.toCryptoModel() - val userSigningKey = adapter.fromJson(request.userSigningKey)!!.toCryptoModel() - - val uploadSigningKeysParams = UploadSigningKeysTask.Params( - masterKey, - userSigningKey, - selfSigningKey, - null - ) - - try { - uploadSigningKeysTask.execute(uploadSigningKeysParams) - } catch (failure: Throwable) { - if (interactiveAuthInterceptor == null - || !handleUIA( - failure = failure, - interceptor = interactiveAuthInterceptor, - retryBlock = { authUpdate -> - uploadSigningKeysTask.executeRetry( - uploadSigningKeysParams.copy(userAuthParam = authUpdate), - REQUEST_RETRY_COUNT - ) - } - ) - ) { - Timber.d("## UIA: propagate failure") - throw failure - } - } - } - - suspend fun sendToDevice(request: Request.ToDevice) { - sendToDevice(request.eventType, request.body, request.requestId) - } - - suspend fun sendToDevice(request: OutgoingVerificationRequest.ToDevice) { - sendToDevice(request.eventType, request.body, request.requestId) - } - - suspend fun sendToDevice(eventType: String, body: String, transactionId: String) { - val adapter = MoshiProvider - .providesMoshi() - .newBuilder() - .add(CheckNumberType.JSON_ADAPTER_FACTORY) - .build() - .adapter>>(Map::class.java) - val jsonBody = adapter.fromJson(body)!! - - val userMap = MXUsersDevicesMap() - userMap.join(jsonBody) - - val sendToDeviceParams = SendToDeviceTask.Params(eventType, userMap, transactionId) - sendToDeviceTask.executeRetry(sendToDeviceParams, REQUEST_RETRY_COUNT) - } - - suspend fun getKeyBackupVersion(version: String? = null): KeysVersionResult? { - return try { - if (version != null) { - getKeysBackupVersionTask.execute(version) - } else { - getKeysBackupLastVersionTask.execute(Unit) - } - } catch (failure: Throwable) { - if (failure is Failure.ServerError - && failure.error.code == MatrixError.M_NOT_FOUND) { - null - } else { - throw failure - } - } - } - - suspend fun createKeyBackup(body: CreateKeysBackupVersionBody): KeysVersion { - return createKeysBackupVersionTask.execute(body) - } - - suspend fun deleteKeyBackup(version: String) { - val params = DeleteBackupTask.Params(version) - deleteBackupTask.execute(params) - } - - suspend fun backupRoomKeys(request: Request.KeysBackup): String { - val adapter = MoshiProvider - .providesMoshi() - .newBuilder() - .add(CheckNumberType.JSON_ADAPTER_FACTORY) - .build() - .adapter>( - Types.newParameterizedType( - Map::class.java, - String::class.java, - RoomKeysBackupData::class.java - )) - val keys = adapter.fromJson(request.rooms)!! - val params = StoreSessionsDataTask.Params(request.version, KeysBackupData(keys)) - val response = backupRoomKeysTask.executeRetry(params, REQUEST_RETRY_COUNT) - val responseAdapter = MoshiProvider.providesMoshi().adapter(BackupKeysResult::class.java) - return responseAdapter.toJson(response)!! - } - - suspend fun updateBackup(keysBackupVersion: KeysVersionResult, body: UpdateKeysBackupVersionBody) { - val params = UpdateKeysBackupVersionTask.Params(keysBackupVersion.version, body) - updateKeysBackupVersionTask.executeRetry(params, REQUEST_RETRY_COUNT) - } - - suspend fun downloadBackedUpKeys(version: String, roomId: String, sessionId: String): KeysBackupData { - val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version)) - - return KeysBackupData(mutableMapOf( - roomId to RoomKeysBackupData(mutableMapOf( - sessionId to data - )) - )) - } - - suspend fun downloadBackedUpKeys(version: String, roomId: String): KeysBackupData { - val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version)) - // Convert to KeysBackupData - return KeysBackupData(mutableMapOf(roomId to data)) - } - - suspend fun downloadBackedUpKeys(version: String): KeysBackupData { - return getSessionsDataTask.execute(GetSessionsDataTask.Params(version)) - } -} - /** * A `CryptoService` class instance manages the end-to-end crypto for a session. * @@ -365,8 +129,10 @@ internal class DefaultCryptoService @Inject constructor( private val userId: String, @DeviceId private val deviceId: String?, - @SessionFilesDirectory - private val dataDir: File, +// @SessionId +// private val sessionId: String, +// @SessionFilesDirectory +// private val dataDir: File, // the crypto store private val cryptoStore: IMXCryptoStore, // Set of parameters used to configure/customize the end-to-end crypto. @@ -384,18 +150,20 @@ internal class DefaultCryptoService @Inject constructor( private val taskExecutor: TaskExecutor, private val cryptoCoroutineScope: CoroutineScope, private val sender: RequestSender, + private val crossSigningService: CrossSigningService, + private val verificationService: RustVerificationService, + private val olmMachineProvider: OlmMachineProvider ) : CryptoService { private val isStarting = AtomicBoolean(false) private val isStarted = AtomicBoolean(false) - private var olmMachine: OlmMachine? = null + private val olmMachine by lazy { olmMachineProvider.olmMachine } // The verification service. - private var verificationService: RustVerificationService? = null +// private var verificationService: RustVerificationService? = null - // The cross signing service. - private var crossSigningService: RustCrossSigningService? = null +// private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() // The key backup service. private var keysBackupService: RustKeyBackupService? = null @@ -410,7 +178,7 @@ internal class DefaultCryptoService @Inject constructor( // TODO does this need to be concurrent? private val newSessionListeners = ArrayList() - suspend fun onStateEvent(roomId: String, event: Event) { + fun onStateEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) @@ -418,12 +186,14 @@ internal class DefaultCryptoService @Inject constructor( } } - suspend fun onLiveEvent(roomId: String, event: Event) { + fun onLiveEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) - else -> this.verificationService?.onEvent(event) + else -> cryptoCoroutineScope.launch { + this@DefaultCryptoService.verificationService?.onEvent(event) + } } } @@ -463,7 +233,7 @@ internal class DefaultCryptoService @Inject constructor( } override fun getMyDevice(): CryptoDeviceInfo { - return runBlocking { olmMachine!!.ownDevice() } + return runBlocking { olmMachine.ownDevice() } } override fun fetchDevicesList(callback: MatrixCallback) { @@ -565,14 +335,10 @@ internal class DefaultCryptoService @Inject constructor( try { setRustLogger() - val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver, sender) - olmMachine = machine - verificationService = RustVerificationService(machine) - crossSigningService = RustCrossSigningService(machine) keysBackupService = RustKeyBackupService(machine, sender, coroutineDispatchers, cryptoCoroutineScope) Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + - "${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}") + "${userId}, ${deviceId}, identity keys: ${this.olmMachine.identityKeys()}") } catch (throwable: Throwable) { Timber.v("Failed create an Olm machine: $throwable") } @@ -614,38 +380,9 @@ internal class DefaultCryptoService @Inject constructor( /** * @return the VerificationService */ - override fun verificationService(): VerificationService { - // TODO yet another problem because the CryptoService is started in the - // sync loop - // - // The `KeyRequestHandler` and `IncomingVerificationHandler` want to add - // listeners to the verification service, they are initialized in the - // `ActiveSessionHolder` class in the `setActiveSession()` method. In - // the `setActiveSession()` method we call the `start()` method of the - // handlers without first calling the `start()` method of the - // `DefaultCryptoService`. - // - // The start method of the crypto service isn't part of the - // `CryptoService` interface so it currently can't be called there. I'm - // inclined to believe that it should be, and that it should be - // initialized before anything else tries to do something with it. - // - // Let's initialize here as a workaround until we figure out if the - // above conclusion is correct. - if (verificationService == null) { - internalStart() - } + override fun verificationService() = verificationService - return verificationService!! - } - - override fun crossSigningService(): CrossSigningService { - if (crossSigningService == null) { - internalStart() - } - - return crossSigningService!! - } + override fun crossSigningService() = crossSigningService /** * A sync response has been received @@ -685,7 +422,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) { runBlocking { - this@DefaultCryptoService.olmMachine?.getCryptoDeviceInfo(userId, deviceId) + this@DefaultCryptoService.olmMachine.getCryptoDeviceInfo(userId, deviceId) } } else { null @@ -694,7 +431,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getCryptoDeviceInfo(userId: String): List { return runBlocking { - this@DefaultCryptoService.olmMachine?.getCryptoDeviceInfo(userId) ?: listOf() + this@DefaultCryptoService.olmMachine.getCryptoDeviceInfo(userId) ?: listOf() } } @@ -704,7 +441,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getLiveCryptoDeviceInfo(userIds: List): LiveData> { return runBlocking { - this@DefaultCryptoService.olmMachine?.getLiveDevices(userIds) ?: LiveDevice(userIds, deviceObserver) + this@DefaultCryptoService.olmMachine.getLiveDevices(userIds) //?: LiveDevice(userIds, deviceObserver) } } @@ -755,7 +492,7 @@ internal class DefaultCryptoService @Inject constructor( Timber.v("Enabling encryption in $roomId for the first time; invalidating device lists for all users therein") val userIds = ArrayList(membersId) - olmMachine!!.updateTrackedUsers(userIds) + olmMachine.updateTrackedUsers(userIds) } return true @@ -833,7 +570,7 @@ internal class DefaultCryptoService @Inject constructor( } override fun discardOutboundSession(roomId: String) { - olmMachine?.discardRoomKey(roomId) + olmMachine.discardRoomKey(roomId) } /** @@ -846,7 +583,7 @@ internal class DefaultCryptoService @Inject constructor( @Throws(MXCryptoError::class) override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { return runBlocking { - olmMachine!!.decryptRoomEvent(event) + olmMachine.decryptRoomEvent(event) } } @@ -873,20 +610,29 @@ internal class DefaultCryptoService @Inject constructor( Timber.w("Invalid encryption event") return } + + // Do not load members here, would defeat lazy loading cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - val params = LoadRoomMembersTask.Params(roomId) - try { - loadRoomMembersTask.execute(params) - } catch (throwable: Throwable) { - Timber.e(throwable, "## CRYPTO | onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ") - } finally { - val userIds = getRoomUserIds(roomId) - olmMachine!!.updateTrackedUsers(userIds) - setEncryptionInRoom(roomId, event.content?.get("algorithm")?.toString(), userIds) - } +// val params = LoadRoomMembersTask.Params(roomId) +// try { +// loadRoomMembersTask.execute(params) +// } catch (throwable: Throwable) { +// Timber.e(throwable, "## CRYPTO | onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ") +// } finally { + val userIds = getRoomUserIds(roomId) + olmMachine.updateTrackedUsers(userIds) + setEncryptionInRoom(roomId, event.content?.get("algorithm")?.toString(), userIds) +// } } } + override fun onE2ERoomMemberLoadedFromServer(roomId: String) { + cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { + val userIds = getRoomUserIds(roomId) + // Because of LL we might want to update tracked users + olmMachine.updateTrackedUsers(userIds) + } + } private fun getRoomUserIds(roomId: String): List { val encryptForInvitedMembers = isEncryptionEnabledForInvitedUser() && shouldEncryptForInvitedMembers(roomId) @@ -898,7 +644,7 @@ internal class DefaultCryptoService @Inject constructor( * * @param event the membership event causing the change */ - private suspend fun onRoomMembershipEvent(roomId: String, event: Event) { + private fun onRoomMembershipEvent(roomId: String, event: Event) { // We only care about the memberships if this room is encrypted if (isRoomEncrypted(roomId)) { return @@ -909,7 +655,9 @@ internal class DefaultCryptoService @Inject constructor( val membership = roomMember?.membership if (membership == Membership.JOIN) { // make sure we are tracking the deviceList for this user. - olmMachine!!.updateTrackedUsers(listOf(userId)) + cryptoCoroutineScope.launch { + olmMachine.updateTrackedUsers(listOf(userId)) + } } else if (membership == Membership.INVITE && shouldEncryptForInvitedMembers(roomId) && isEncryptionEnabledForInvitedUser()) { @@ -918,7 +666,11 @@ internal class DefaultCryptoService @Inject constructor( // know what other servers are in the room at the time they've been invited. // They therefore will not send device updates if a user logs in whilst // their state is invite. - olmMachine!!.updateTrackedUsers(listOf(userId)) + cryptoCoroutineScope.launch { + olmMachine.updateTrackedUsers(listOf(userId)) + } + } else { + // nop } } } @@ -952,7 +704,7 @@ internal class DefaultCryptoService @Inject constructor( deviceChanges: DeviceListResponse?, keyCounts: DeviceOneTimeKeysCountSyncResponse?) { // Decrypt and handle our to-device events - val toDeviceEvents = this.olmMachine!!.receiveSyncChanges(toDevice, deviceChanges, keyCounts) + val toDeviceEvents = this.olmMachine.receiveSyncChanges(toDevice, deviceChanges, keyCounts) // Notify the our listeners about room keys so decryption is retried. if (toDeviceEvents.events != null) { @@ -981,7 +733,7 @@ internal class DefaultCryptoService @Inject constructor( this.keysBackupService?.onSecretKeyGossip(secretContent.secretValue) } else -> { - this.verificationService?.onEvent(event) + this.verificationService.onEvent(event) } } } @@ -990,7 +742,7 @@ internal class DefaultCryptoService @Inject constructor( private suspend fun preshareRoomKey(roomId: String, roomMembers: List) { keyClaimLock.withLock { - val request = this.olmMachine!!.getMissingSessions(roomMembers) + val request = this.olmMachine.getMissingSessions(roomMembers) // This request can only be a keys claim request. if (request != null) { when (request) { @@ -1008,7 +760,7 @@ internal class DefaultCryptoService @Inject constructor( keyShareLock.withLock { coroutineScope { - this@DefaultCryptoService.olmMachine!!.shareRoomKey(roomId, roomMembers).map { + this@DefaultCryptoService.olmMachine.shareRoomKey(roomId, roomMembers).map { when (it) { is Request.ToDevice -> { sharedKey = true @@ -1035,18 +787,28 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun encrypt(roomId: String, eventType: String, content: Content): Content { - return olmMachine!!.encrypt(roomId, eventType, content) + return olmMachine.encrypt(roomId, eventType, content) } private suspend fun uploadKeys(request: Request.KeysUpload) { val response = this.sender.uploadKeys(request) - this.olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_UPLOAD, response) + this.olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_UPLOAD, response) } private suspend fun queryKeys(request: Request.KeysQuery) { try { val response = this.sender.queryKeys(request) - this.olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_QUERY, response) + this.olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_QUERY, response) + + // Update the shields! + cryptoCoroutineScope.launch { + cryptoSessionInfoProvider.getRoomsWhereUsersAreParticipating(request.users).forEach { roomId -> + val userGroup = cryptoSessionInfoProvider.getUserListForShieldComputation(roomId) + val shield = crossSigningService.shieldForGroup(userGroup) + cryptoSessionInfoProvider.updateShieldForRoom(roomId, shield) + } + } + } catch (throwable: Throwable) { Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") } @@ -1054,23 +816,23 @@ internal class DefaultCryptoService @Inject constructor( private suspend fun sendToDevice(request: Request.ToDevice) { this.sender.sendToDevice(request) - olmMachine!!.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}") + olmMachine.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}") } private suspend fun claimKeys(request: Request.KeysClaim) { val response = this.sender.claimKeys(request) - olmMachine!!.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, response) + olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, response) } private suspend fun signatureUpload(request: Request.SignatureUpload) { this.sender.sendSignatureUpload(request) - olmMachine!!.markRequestAsSent(request.requestId, RequestType.SIGNATURE_UPLOAD, "{}") + olmMachine.markRequestAsSent(request.requestId, RequestType.SIGNATURE_UPLOAD, "{}") } private suspend fun sendOutgoingRequests() { outgoingRequestsLock.withLock { coroutineScope { - olmMachine!!.outgoingRequests().map { + olmMachine.outgoingRequests().map { when (it) { is Request.KeysUpload -> { async { @@ -1122,7 +884,7 @@ internal class DefaultCryptoService @Inject constructor( */ override suspend fun exportRoomKeys(password: String): ByteArray { val iterationCount = max(10000, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT) - return olmMachine!!.exportKeys(password, iterationCount) + return olmMachine.exportKeys(password, iterationCount) } /** @@ -1234,7 +996,7 @@ internal class DefaultCryptoService @Inject constructor( */ override fun reRequestRoomKeyForEvent(event: Event) { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - val requestPair = olmMachine!!.requestRoomKey(event) + val requestPair = olmMachine.requestRoomKey(event) val cancellation = requestPair.cancellation val request = requestPair.keyRequest @@ -1279,9 +1041,9 @@ internal class DefaultCryptoService @Inject constructor( if (forceDownload) { // TODO replicate the logic from the device list manager // where we would download the fresh info from the server. - this@DefaultCryptoService.olmMachine?.getUserDevicesMap(userIds) ?: MXUsersDevicesMap() + this@DefaultCryptoService.olmMachine.getUserDevicesMap(userIds) // ?: MXUsersDevicesMap() } else { - this@DefaultCryptoService.olmMachine?.getUserDevicesMap(userIds) ?: MXUsersDevicesMap() + this@DefaultCryptoService.olmMachine.getUserDevicesMap(userIds) //?: MXUsersDevicesMap() } }.foldToCallback(callback) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index e1db5ddbe9..dfe1994d9d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -39,7 +39,7 @@ internal class Device( private val machine: OlmMachine, private var inner: InnerDevice, private val sender: RequestSender, - private val listeners: ArrayList, + private val listeners: ArrayList ) { @Throws(CryptoStoreException::class) private suspend fun refreshData() { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt index 494e6d7cc7..9493dddecc 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt @@ -35,6 +35,7 @@ import timber.log.Timber import javax.inject.Inject // Legacy name: MXDeviceList +@Deprecated("In favor of rust olmMachine") @SessionScope internal class DeviceListManager @Inject constructor(private val cryptoStore: IMXCryptoStore, private val olmDevice: MXOlmDevice, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 53a3e42d42..8f213ee5d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.extensions.orFalse 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.crosssigning.MXCrossSigningInfo @@ -99,7 +100,7 @@ internal class LiveDevice( internal class LiveUserIdentity( internal var userId: String, - private var observer: UserIdentityUpdateObserver, + private var observer: UserIdentityUpdateObserver ) : MutableLiveData>() { override fun onActive() { observer.addUserIdentityUpdateListener(this) @@ -529,8 +530,13 @@ internal class OlmMachine( return when (identity) { is RustUserIdentity.Other -> { - val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel() - val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel() + val verified = this.inner().isIdentityVerified(userId) + val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } UserIdentity(identity.userId, masterKey, selfSigningKey, this, this.requestSender) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt new file mode 100644 index 0000000000..f2de3b3724 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto + +import org.matrix.android.sdk.internal.di.DeviceId +import org.matrix.android.sdk.internal.di.SessionFilesDirectory +import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.session.SessionScope +import java.io.File +import javax.inject.Inject + +@SessionScope +internal class OlmMachineProvider @Inject constructor( + @UserId private val userId: String, + @DeviceId private val deviceId: String?, + @SessionFilesDirectory private val dataDir: File, + requestSender: RequestSender +) { + + private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() + + var olmMachine: OlmMachine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver, requestSender) +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index fefabf2bd4..278c3fec5f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -37,7 +37,7 @@ internal class QrCodeVerification( private var request: VerificationRequest, private var inner: QrCode?, private val sender: RequestSender, - listeners: ArrayList, + listeners: ArrayList ) : QrCodeVerificationTransaction { private val dispatcher = UpdateDispatcher(listeners) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt new file mode 100644 index 0000000000..d0711567cf --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto + +import com.squareup.moshi.Types +import dagger.Lazy +import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.failure.MatrixError +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.util.JsonDict +import org.matrix.android.sdk.internal.auth.registration.handleUIA +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionDataTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionsDataTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetSessionsDataTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask +import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask +import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse +import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse +import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse +import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo +import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask +import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendVerificationMessageTask +import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask +import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask +import org.matrix.android.sdk.internal.crypto.tasks.SendVerificationMessageTask +import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask +import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask +import org.matrix.android.sdk.internal.crypto.tasks.UploadSigningKeysTask +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.network.parsing.CheckNumberType +import timber.log.Timber +import uniffi.olm.OutgoingVerificationRequest +import uniffi.olm.Request +import uniffi.olm.SignatureUploadRequest +import uniffi.olm.UploadSigningKeysRequest +import javax.inject.Inject + +internal class RequestSender @Inject constructor( + private val sendToDeviceTask: SendToDeviceTask, + private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask, + private val uploadKeysTask: UploadKeysTask, + private val downloadKeysForUsersTask: DownloadKeysForUsersTask, + private val signaturesUploadTask: UploadSignaturesTask, + private val sendVerificationMessageTask: Lazy, + private val uploadSigningKeysTask: UploadSigningKeysTask, + private val getKeysBackupLastVersionTask: GetKeysBackupLastVersionTask, + private val getKeysBackupVersionTask: GetKeysBackupVersionTask, + private val deleteBackupTask: DeleteBackupTask, + private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, + private val backupRoomKeysTask: StoreSessionsDataTask, + private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask, + private val getSessionsDataTask: GetSessionsDataTask, + private val getRoomSessionsDataTask: GetRoomSessionsDataTask, + private val getRoomSessionDataTask: GetRoomSessionDataTask, +) { + companion object { + const val REQUEST_RETRY_COUNT = 3 + } + + suspend fun claimKeys(request: Request.KeysClaim): String { + val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(request.oneTimeKeys) + val response = oneTimeKeysForUsersDeviceTask.executeRetry(claimParams, REQUEST_RETRY_COUNT) + val adapter = MoshiProvider + .providesMoshi() + .adapter(KeysClaimResponse::class.java) + return adapter.toJson(response)!! + } + + suspend fun queryKeys(request: Request.KeysQuery): String { + val params = DownloadKeysForUsersTask.Params(request.users, null) + val response = downloadKeysForUsersTask.executeRetry(params, REQUEST_RETRY_COUNT) + val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) + return adapter.toJson(response)!! + } + + suspend fun uploadKeys(request: Request.KeysUpload): String { + val body = MoshiProvider.providesMoshi().adapter(Map::class.java).fromJson(request.body)!! + val params = UploadKeysTask.Params(body) + + val response = uploadKeysTask.executeRetry(params, REQUEST_RETRY_COUNT) + val adapter = MoshiProvider.providesMoshi().adapter(KeysUploadResponse::class.java) + + return adapter.toJson(response)!! + } + + suspend fun sendVerificationRequest(request: OutgoingVerificationRequest) { + when (request) { + is OutgoingVerificationRequest.InRoom -> sendRoomMessage(request) + is OutgoingVerificationRequest.ToDevice -> sendToDevice(request) + } + } + + suspend fun sendRoomMessage(request: OutgoingVerificationRequest.InRoom): String { + return sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) + } + + suspend fun sendRoomMessage(request: Request.RoomMessage): String { + return sendRoomMessage(request.eventType, request.roomId, request.content, request.requestId) + } + + suspend fun sendRoomMessage(eventType: String, roomId: String, content: String, transactionId: String): String { + val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val jsonContent = adapter.fromJson(content) + val event = Event(eventType, transactionId, jsonContent, roomId = roomId) + val params = SendVerificationMessageTask.Params(event) + return this.sendVerificationMessageTask.get().executeRetry(params, REQUEST_RETRY_COUNT) + } + + suspend fun sendSignatureUpload(request: Request.SignatureUpload) { + sendSignatureUpload(request.body) + } + + suspend fun sendSignatureUpload(request: SignatureUploadRequest) { + sendSignatureUpload(request.body) + } + + private suspend fun sendSignatureUpload(body: String) { + val adapter = MoshiProvider.providesMoshi().adapter>>(Map::class.java) + val signatures = adapter.fromJson(body)!! + val params = UploadSignaturesTask.Params(signatures) + this.signaturesUploadTask.executeRetry(params, REQUEST_RETRY_COUNT) + } + + suspend fun uploadCrossSigningKeys( + request: UploadSigningKeysRequest, + interactiveAuthInterceptor: UserInteractiveAuthInterceptor? + ) { + val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) + val masterKey = adapter.fromJson(request.masterKey)!!.toCryptoModel() + val selfSigningKey = adapter.fromJson(request.selfSigningKey)!!.toCryptoModel() + val userSigningKey = adapter.fromJson(request.userSigningKey)!!.toCryptoModel() + + val uploadSigningKeysParams = UploadSigningKeysTask.Params( + masterKey, + userSigningKey, + selfSigningKey, + null + ) + + try { + uploadSigningKeysTask.execute(uploadSigningKeysParams) + } catch (failure: Throwable) { + if (interactiveAuthInterceptor == null + || !handleUIA( + failure = failure, + interceptor = interactiveAuthInterceptor, + retryBlock = { authUpdate -> + uploadSigningKeysTask.executeRetry( + uploadSigningKeysParams.copy(userAuthParam = authUpdate), + REQUEST_RETRY_COUNT + ) + } + ) + ) { + Timber.d("## UIA: propagate failure") + throw failure + } + } + } + + suspend fun sendToDevice(request: Request.ToDevice) { + sendToDevice(request.eventType, request.body, request.requestId) + } + + suspend fun sendToDevice(request: OutgoingVerificationRequest.ToDevice) { + sendToDevice(request.eventType, request.body, request.requestId) + } + + suspend fun sendToDevice(eventType: String, body: String, transactionId: String) { + val adapter = MoshiProvider + .providesMoshi() + .newBuilder() + .add(CheckNumberType.JSON_ADAPTER_FACTORY) + .build() + .adapter>>(Map::class.java) + val jsonBody = adapter.fromJson(body)!! + + val userMap = MXUsersDevicesMap() + userMap.join(jsonBody) + + val sendToDeviceParams = SendToDeviceTask.Params(eventType, userMap, transactionId) + sendToDeviceTask.executeRetry(sendToDeviceParams, REQUEST_RETRY_COUNT) + } + + suspend fun getKeyBackupVersion(version: String? = null): KeysVersionResult? { + return try { + if (version != null) { + getKeysBackupVersionTask.execute(version) + } else { + getKeysBackupLastVersionTask.execute(Unit) + } + } catch (failure: Throwable) { + if (failure is Failure.ServerError + && failure.error.code == MatrixError.M_NOT_FOUND) { + null + } else { + throw failure + } + } + } + + suspend fun createKeyBackup(body: CreateKeysBackupVersionBody): KeysVersion { + return createKeysBackupVersionTask.execute(body) + } + + suspend fun deleteKeyBackup(version: String) { + val params = DeleteBackupTask.Params(version) + deleteBackupTask.execute(params) + } + + suspend fun backupRoomKeys(request: Request.KeysBackup): String { + val adapter = MoshiProvider + .providesMoshi() + .newBuilder() + .add(CheckNumberType.JSON_ADAPTER_FACTORY) + .build() + .adapter>( + Types.newParameterizedType( + Map::class.java, + String::class.java, + RoomKeysBackupData::class.java + )) + val keys = adapter.fromJson(request.rooms)!! + val params = StoreSessionsDataTask.Params(request.version, KeysBackupData(keys)) + val response = backupRoomKeysTask.executeRetry(params, REQUEST_RETRY_COUNT) + val responseAdapter = MoshiProvider.providesMoshi().adapter(BackupKeysResult::class.java) + return responseAdapter.toJson(response)!! + } + + suspend fun updateBackup(keysBackupVersion: KeysVersionResult, body: UpdateKeysBackupVersionBody) { + val params = UpdateKeysBackupVersionTask.Params(keysBackupVersion.version, body) + updateKeysBackupVersionTask.executeRetry(params, REQUEST_RETRY_COUNT) + } + + suspend fun downloadBackedUpKeys(version: String, roomId: String, sessionId: String): KeysBackupData { + val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version)) + + return KeysBackupData(mutableMapOf( + roomId to RoomKeysBackupData(mutableMapOf( + sessionId to data + )) + )) + } + + suspend fun downloadBackedUpKeys(version: String, roomId: String): KeysBackupData { + val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version)) + // Convert to KeysBackupData + return KeysBackupData(mutableMapOf(roomId to data)) + } + + suspend fun downloadBackedUpKeys(version: String): KeysBackupData { + return getSessionsDataTask.execute(GetSessionsDataTask.Params(version)) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index 42abcd9e89..bf5d0eca9e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -21,6 +21,8 @@ import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.util.Optional @@ -28,9 +30,18 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustResult import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo +import org.matrix.android.sdk.internal.di.SessionId +import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback +import javax.inject.Inject -internal class RustCrossSigningService(private val olmMachine: OlmMachine) : CrossSigningService { +internal class RustCrossSigningService @Inject constructor( + @SessionId private val sessionId: String, + @UserId private val myUserId: String, + private val olmMachineProvider: OlmMachineProvider +) : CrossSigningService { + + val olmMachine = olmMachineProvider.olmMachine /** * Is our own device signed by our own cross signing identity */ @@ -89,7 +100,9 @@ internal class RustCrossSigningService(private val olmMachine: OlmMachine) : Cro sskPrivateKey: String? ): UserTrustResult { val export = PrivateKeysInfo(masterKeyPrivateKey, sskPrivateKey, uskKeyPrivateKey) - return runBlocking { olmMachine.importCrossSigningKeys(export) } + return runBlocking { + olmMachineProvider.olmMachine.importCrossSigningKeys(export) + } } /** @@ -206,4 +219,46 @@ internal class RustCrossSigningService(private val olmMachine: OlmMachine) : Cro override fun onSecretUSKGossip(uskPrivateKey: String) { // And this. } + + override suspend fun shieldForGroup(userIds: List): RoomEncryptionTrustLevel { + val myIdentity = olmMachine.getIdentity(myUserId) + val allTrustedUserIds = userIds + .filter { userId -> + olmMachine.getIdentity(userId)?.verified() == true + } + + return if (allTrustedUserIds.isEmpty()) { + RoomEncryptionTrustLevel.Default + } else { + // If one of the verified user as an untrusted device -> warning + // If all devices of all verified users are trusted -> green + // else -> black + allTrustedUserIds + .map { userId -> + olmMachineProvider.olmMachine.getUserDevices(userId) + } + .flatten() + .let { allDevices -> + if (myIdentity != null) { + allDevices.any { !it.toCryptoDeviceInfo().trustLevel?.crossSigningVerified.orFalse() } + } else { + // TODO check that if myIdentity is null ean + // Legacy method + allDevices.any { !it.toCryptoDeviceInfo().isVerified } + } + } + .let { hasWarning -> + if (hasWarning) { + RoomEncryptionTrustLevel.Warning + } else { + if (userIds.size == allTrustedUserIds.size) { + // all users are trusted and all devices are verified + RoomEncryptionTrustLevel.Trusted + } else { + RoomEncryptionTrustLevel.Default + } + } + } + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index 53c7fef231..11a00c3b64 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -37,7 +37,7 @@ internal class SasVerification( private val machine: OlmMachine, private var inner: Sas, private val sender: RequestSender, - listeners: ArrayList, + listeners: ArrayList ) : SasVerificationTransaction { private val dispatcher = UpdateDispatcher(listeners) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt index 4d21d796c5..733d4a5e1f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt @@ -250,7 +250,14 @@ internal class UserIdentity( * Convert the identity into a MxCrossSigningInfo class. */ override fun toMxCrossSigningInfo(): MXCrossSigningInfo { - val crossSigningKeys = listOf(this.masterKey, this.selfSigningKey) - return MXCrossSigningInfo(this.userId, crossSigningKeys) +// val crossSigningKeys = listOf(this.masterKey, this.selfSigningKey) + val trustLevel = DeviceTrustLevel(runBlocking { verified() }, false) + // TODO remove this, this is silly, we have way too many methods to check if a user is verified + masterKey.trustLevel = trustLevel + selfSigningKey.trustLevel = trustLevel + return MXCrossSigningInfo(this.userId, listOf( + this.masterKey.also { it.trustLevel = trustLevel }, + this.selfSigningKey.also { it.trustLevel = trustLevel } + )) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index b98b763355..ebd17307d1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -45,7 +45,7 @@ internal class VerificationRequest( private val machine: OlmMachine, private var inner: VerificationRequest, private val sender: RequestSender, - private val listeners: ArrayList, + private val listeners: ArrayList ) { private val uiHandler = Handler(Looper.getMainLooper()) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt index d46d58c969..72490322a6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt @@ -24,7 +24,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse -import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.crypto.model.rest.SendToDeviceBody import org.matrix.android.sdk.internal.crypto.model.rest.SignatureUploadResponse diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt index 83de06a668..64b423cca7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt @@ -1,807 +1,807 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.crosssigning - -import androidx.lifecycle.LiveData -import androidx.work.BackoffPolicy -import androidx.work.ExistingWorkPolicy -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.MatrixCoroutineDispatchers -import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor -import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo -import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.DeviceListManager -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.UploadSignatureQueryBuilder -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo -import org.matrix.android.sdk.internal.crypto.tasks.InitializeCrossSigningTask -import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask -import org.matrix.android.sdk.internal.di.SessionId -import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.di.WorkManagerProvider -import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.task.TaskExecutor -import org.matrix.android.sdk.internal.task.TaskThread -import org.matrix.android.sdk.internal.task.configureWith -import org.matrix.android.sdk.internal.util.JsonCanonicalizer -import org.matrix.android.sdk.internal.util.logLimit -import org.matrix.android.sdk.internal.worker.WorkerParamsFactory -import org.matrix.olm.OlmPkSigning -import org.matrix.olm.OlmUtility -import timber.log.Timber -import java.util.concurrent.TimeUnit -import javax.inject.Inject - -@SessionScope -internal class DefaultCrossSigningService @Inject constructor( - @UserId private val userId: String, - @SessionId private val sessionId: String, - private val cryptoStore: IMXCryptoStore, - private val deviceListManager: DeviceListManager, - private val initializeCrossSigningTask: InitializeCrossSigningTask, - private val uploadSignaturesTask: UploadSignaturesTask, - private val taskExecutor: TaskExecutor, - private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val cryptoCoroutineScope: CoroutineScope, - private val workManagerProvider: WorkManagerProvider, - private val updateTrustWorkerDataRepository: UpdateTrustWorkerDataRepository -) : CrossSigningService, - DeviceListManager.UserDevicesUpdateListener { - - private var olmUtility: OlmUtility? = null - - private var masterPkSigning: OlmPkSigning? = null - private var userPkSigning: OlmPkSigning? = null - private var selfSigningPkSigning: OlmPkSigning? = null - - init { - try { - olmUtility = OlmUtility() - - // Try to get stored keys if they exist - cryptoStore.getMyCrossSigningInfo()?.let { mxCrossSigningInfo -> - Timber.i("## CrossSigning - Found Existing self signed keys") - Timber.i("## CrossSigning - Checking if private keys are known") - - cryptoStore.getCrossSigningPrivateKeys()?.let { privateKeysInfo -> - privateKeysInfo.master - ?.fromBase64() - ?.let { privateKeySeed -> - val pkSigning = OlmPkSigning() - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { - masterPkSigning = pkSigning - Timber.i("## CrossSigning - Loading master key success") - } else { - Timber.w("## CrossSigning - Public master key does not match the private key") - pkSigning.releaseSigning() - // TODO untrust? - } - } - privateKeysInfo.user - ?.fromBase64() - ?.let { privateKeySeed -> - val pkSigning = OlmPkSigning() - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { - userPkSigning = pkSigning - Timber.i("## CrossSigning - Loading User Signing key success") - } else { - Timber.w("## CrossSigning - Public User key does not match the private key") - pkSigning.releaseSigning() - // TODO untrust? - } - } - privateKeysInfo.selfSigned - ?.fromBase64() - ?.let { privateKeySeed -> - val pkSigning = OlmPkSigning() - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { - selfSigningPkSigning = pkSigning - Timber.i("## CrossSigning - Loading Self Signing key success") - } else { - Timber.w("## CrossSigning - Public Self Signing key does not match the private key") - pkSigning.releaseSigning() - // TODO untrust? - } - } - } - - // Recover local trust in case private key are there? - setUserKeysAsTrusted(userId, checkUserTrust(userId).isVerified()) - } - } catch (e: Throwable) { - // Mmm this kind of a big issue - Timber.e(e, "Failed to initialize Cross Signing") - } - - deviceListManager.addListener(this) - } - - fun release() { - olmUtility?.releaseUtility() - listOf(masterPkSigning, userPkSigning, selfSigningPkSigning).forEach { it?.releaseSigning() } - deviceListManager.removeListener(this) - } - - protected fun finalize() { - release() - } - - /** - * - Make 3 key pairs (MSK, USK, SSK) - * - Save the private keys with proper security - * - Sign the keys and upload them - * - Sign the current device with SSK and sign MSK with device key (migration) and upload signatures - */ - override fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?, callback: MatrixCallback) { - Timber.d("## CrossSigning initializeCrossSigning") - - val params = InitializeCrossSigningTask.Params( - interactiveAuthInterceptor = uiaInterceptor - ) - initializeCrossSigningTask.configureWith(params) { - this.callbackThread = TaskThread.CRYPTO - this.callback = object : MatrixCallback { - override fun onFailure(failure: Throwable) { - Timber.e(failure, "Error in initializeCrossSigning()") - callback.onFailure(failure) - } - - override fun onSuccess(data: InitializeCrossSigningTask.Result) { - val crossSigningInfo = MXCrossSigningInfo(userId, listOf(data.masterKeyInfo, data.userKeyInfo, data.selfSignedKeyInfo)) - cryptoStore.setMyCrossSigningInfo(crossSigningInfo) - setUserKeysAsTrusted(userId, true) - cryptoStore.storePrivateKeysInfo(data.masterKeyPK, data.userKeyPK, data.selfSigningKeyPK) - masterPkSigning = OlmPkSigning().apply { initWithSeed(data.masterKeyPK.fromBase64()) } - userPkSigning = OlmPkSigning().apply { initWithSeed(data.userKeyPK.fromBase64()) } - selfSigningPkSigning = OlmPkSigning().apply { initWithSeed(data.selfSigningKeyPK.fromBase64()) } - - callback.onSuccess(Unit) - } - } - }.executeBy(taskExecutor) - } - - override fun onSecretMSKGossip(mskPrivateKey: String) { - Timber.i("## CrossSigning - onSecretSSKGossip") - val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { - Timber.e("## CrossSigning - onSecretMSKGossip() received secret but public key is not known") - } - - mskPrivateKey.fromBase64() - .let { privateKeySeed -> - val pkSigning = OlmPkSigning() - try { - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { - masterPkSigning?.releaseSigning() - masterPkSigning = pkSigning - Timber.i("## CrossSigning - Loading MSK success") - cryptoStore.storeMSKPrivateKey(mskPrivateKey) - return - } else { - Timber.e("## CrossSigning - onSecretMSKGossip() private key do not match public key") - pkSigning.releaseSigning() - } - } catch (failure: Throwable) { - Timber.e("## CrossSigning - onSecretMSKGossip() ${failure.localizedMessage}") - pkSigning.releaseSigning() - } - } - } - - override fun onSecretSSKGossip(sskPrivateKey: String) { - Timber.i("## CrossSigning - onSecretSSKGossip") - val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { - Timber.e("## CrossSigning - onSecretSSKGossip() received secret but public key is not known") - } - - sskPrivateKey.fromBase64() - .let { privateKeySeed -> - val pkSigning = OlmPkSigning() - try { - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { - selfSigningPkSigning?.releaseSigning() - selfSigningPkSigning = pkSigning - Timber.i("## CrossSigning - Loading SSK success") - cryptoStore.storeSSKPrivateKey(sskPrivateKey) - return - } else { - Timber.e("## CrossSigning - onSecretSSKGossip() private key do not match public key") - pkSigning.releaseSigning() - } - } catch (failure: Throwable) { - Timber.e("## CrossSigning - onSecretSSKGossip() ${failure.localizedMessage}") - pkSigning.releaseSigning() - } - } - } - - override fun onSecretUSKGossip(uskPrivateKey: String) { - Timber.i("## CrossSigning - onSecretUSKGossip") - val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { - Timber.e("## CrossSigning - onSecretUSKGossip() received secret but public key is not knwow ") - } - - uskPrivateKey.fromBase64() - .let { privateKeySeed -> - val pkSigning = OlmPkSigning() - try { - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { - userPkSigning?.releaseSigning() - userPkSigning = pkSigning - Timber.i("## CrossSigning - Loading USK success") - cryptoStore.storeUSKPrivateKey(uskPrivateKey) - return - } else { - Timber.e("## CrossSigning - onSecretUSKGossip() private key do not match public key") - pkSigning.releaseSigning() - } - } catch (failure: Throwable) { - pkSigning.releaseSigning() - } - } - } - - override fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, - uskKeyPrivateKey: String?, - sskPrivateKey: String? - ): UserTrustResult { - val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return UserTrustResult.CrossSigningNotConfigured(userId) - - var masterKeyIsTrusted = false - var userKeyIsTrusted = false - var selfSignedKeyIsTrusted = false - - masterKeyPrivateKey?.fromBase64() - ?.let { privateKeySeed -> - val pkSigning = OlmPkSigning() - try { - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { - masterPkSigning?.releaseSigning() - masterPkSigning = pkSigning - masterKeyIsTrusted = true - Timber.i("## CrossSigning - Loading master key success") - } else { - pkSigning.releaseSigning() - } - } catch (failure: Throwable) { - pkSigning.releaseSigning() - } - } - - uskKeyPrivateKey?.fromBase64() - ?.let { privateKeySeed -> - val pkSigning = OlmPkSigning() - try { - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { - userPkSigning?.releaseSigning() - userPkSigning = pkSigning - userKeyIsTrusted = true - Timber.i("## CrossSigning - Loading master key success") - } else { - pkSigning.releaseSigning() - } - } catch (failure: Throwable) { - pkSigning.releaseSigning() - } - } - - sskPrivateKey?.fromBase64() - ?.let { privateKeySeed -> - val pkSigning = OlmPkSigning() - try { - if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { - selfSigningPkSigning?.releaseSigning() - selfSigningPkSigning = pkSigning - selfSignedKeyIsTrusted = true - Timber.i("## CrossSigning - Loading master key success") - } else { - pkSigning.releaseSigning() - } - } catch (failure: Throwable) { - pkSigning.releaseSigning() - } - } - - if (!masterKeyIsTrusted || !userKeyIsTrusted || !selfSignedKeyIsTrusted) { - return UserTrustResult.KeysNotTrusted(mxCrossSigningInfo) - } else { - cryptoStore.markMyMasterKeyAsLocallyTrusted(true) - val checkSelfTrust = checkSelfTrust() - if (checkSelfTrust.isVerified()) { - cryptoStore.storePrivateKeysInfo(masterKeyPrivateKey, uskKeyPrivateKey, sskPrivateKey) - setUserKeysAsTrusted(userId, true) - } - return checkSelfTrust - } - } - - /** - * - * ┏━━━━━━━━┓ ┏━━━━━━━━┓ - * ┃ ALICE ┃ ┃ BOB ┃ - * ┗━━━━━━━━┛ ┗━━━━━━━━┛ - * MSK ┌────────────▶ MSK - * │ - * │ │ - * │ SSK │ - * │ │ - * │ │ - * └──▶ USK ────────────┘ - */ - override fun isUserTrusted(otherUserId: String): Boolean { - return cryptoStore.getCrossSigningInfo(userId)?.isTrusted() == true - } - - override fun isCrossSigningVerified(): Boolean { - return checkSelfTrust().isVerified() - } - - /** - * Will not force a download of the key, but will verify signatures trust chain - */ - override fun checkUserTrust(otherUserId: String): UserTrustResult { - Timber.v("## CrossSigning checkUserTrust for $otherUserId") - if (otherUserId == userId) { - return checkSelfTrust() - } - // I trust a user if I trust his master key - // I can trust the master key if it is signed by my user key - // TODO what if the master key is signed by a device key that i have verified - - // First let's get my user key - val myCrossSigningInfo = cryptoStore.getCrossSigningInfo(userId) - - checkOtherMSKTrusted(myCrossSigningInfo, cryptoStore.getCrossSigningInfo(otherUserId)) - - return UserTrustResult.Success - } - - fun checkOtherMSKTrusted(myCrossSigningInfo: MXCrossSigningInfo?, otherInfo: MXCrossSigningInfo?): UserTrustResult { - val myUserKey = myCrossSigningInfo?.userKey() - ?: return UserTrustResult.CrossSigningNotConfigured(userId) - - if (!myCrossSigningInfo.isTrusted()) { - return UserTrustResult.KeysNotTrusted(myCrossSigningInfo) - } - - // Let's get the other user master key - val otherMasterKey = otherInfo?.masterKey() - ?: return UserTrustResult.UnknownCrossSignatureInfo(otherInfo?.userId ?: "") - - val masterKeySignaturesMadeByMyUserKey = otherMasterKey.signatures - ?.get(userId) // Signatures made by me - ?.get("ed25519:${myUserKey.unpaddedBase64PublicKey}") - - if (masterKeySignaturesMadeByMyUserKey.isNullOrBlank()) { - Timber.d("## CrossSigning checkUserTrust false for ${otherInfo.userId}, not signed by my UserSigningKey") - return UserTrustResult.KeyNotSigned(otherMasterKey) - } - - // Check that Alice USK signature of Bob MSK is valid - try { - olmUtility!!.verifyEd25519Signature(masterKeySignaturesMadeByMyUserKey, myUserKey.unpaddedBase64PublicKey, otherMasterKey.canonicalSignable()) - } catch (failure: Throwable) { - return UserTrustResult.InvalidSignature(myUserKey, masterKeySignaturesMadeByMyUserKey) - } - - return UserTrustResult.Success - } - - private fun checkSelfTrust(): UserTrustResult { - // Special case when it's me, - // I have to check that MSK -> USK -> SSK - // and that MSK is trusted (i know the private key, or is signed by a trusted device) - val myCrossSigningInfo = cryptoStore.getCrossSigningInfo(userId) - - return checkSelfTrust(myCrossSigningInfo, cryptoStore.getUserDeviceList(userId)) - } - - fun checkSelfTrust(myCrossSigningInfo: MXCrossSigningInfo?, myDevices: List?): UserTrustResult { - // Special case when it's me, - // I have to check that MSK -> USK -> SSK - // and that MSK is trusted (i know the private key, or is signed by a trusted device) +// /* +// * Copyright 2020 The Matrix.org Foundation C.I.C. +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +// package org.matrix.android.sdk.internal.crypto.crosssigning +// +// import androidx.lifecycle.LiveData +// import androidx.work.BackoffPolicy +// import androidx.work.ExistingWorkPolicy +// import kotlinx.coroutines.CoroutineScope +// import kotlinx.coroutines.launch +// import org.matrix.android.sdk.api.MatrixCallback +// import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +// import org.matrix.android.sdk.api.extensions.orFalse +// import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService +// import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +// import org.matrix.android.sdk.api.util.Optional +// import org.matrix.android.sdk.internal.crypto.DeviceListManager +// import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +// import org.matrix.android.sdk.internal.crypto.model.rest.UploadSignatureQueryBuilder +// import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +// import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo +// import org.matrix.android.sdk.internal.crypto.tasks.InitializeCrossSigningTask +// import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask +// import org.matrix.android.sdk.internal.di.SessionId +// import org.matrix.android.sdk.internal.di.UserId +// import org.matrix.android.sdk.internal.di.WorkManagerProvider +// import org.matrix.android.sdk.internal.session.SessionScope +// import org.matrix.android.sdk.internal.task.TaskExecutor +// import org.matrix.android.sdk.internal.task.TaskThread +// import org.matrix.android.sdk.internal.task.configureWith +// import org.matrix.android.sdk.internal.util.JsonCanonicalizer +// import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers +// import org.matrix.android.sdk.internal.util.logLimit +// import org.matrix.android.sdk.internal.worker.WorkerParamsFactory +// import org.matrix.olm.OlmPkSigning +// import org.matrix.olm.OlmUtility +// import timber.log.Timber +// import java.util.concurrent.TimeUnit +// import javax.inject.Inject +// +// @SessionScope +// internal class DefaultCrossSigningService @Inject constructor( +// @UserId private val userId: String, +// @SessionId private val sessionId: String, +// private val cryptoStore: IMXCryptoStore, +// private val deviceListManager: DeviceListManager, +// private val initializeCrossSigningTask: InitializeCrossSigningTask, +// private val uploadSignaturesTask: UploadSignaturesTask, +// private val taskExecutor: TaskExecutor, +// private val coroutineDispatchers: MatrixCoroutineDispatchers, +// private val cryptoCoroutineScope: CoroutineScope, +// private val workManagerProvider: WorkManagerProvider, +// private val updateTrustWorkerDataRepository: UpdateTrustWorkerDataRepository +// ) : CrossSigningService, +// DeviceListManager.UserDevicesUpdateListener { +// +// private var olmUtility: OlmUtility? = null +// +// private var masterPkSigning: OlmPkSigning? = null +// private var userPkSigning: OlmPkSigning? = null +// private var selfSigningPkSigning: OlmPkSigning? = null +// +// init { +// try { +// olmUtility = OlmUtility() +// +// // Try to get stored keys if they exist +// cryptoStore.getMyCrossSigningInfo()?.let { mxCrossSigningInfo -> +// Timber.i("## CrossSigning - Found Existing self signed keys") +// Timber.i("## CrossSigning - Checking if private keys are known") +// +// cryptoStore.getCrossSigningPrivateKeys()?.let { privateKeysInfo -> +// privateKeysInfo.master +// ?.fromBase64() +// ?.let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { +// masterPkSigning = pkSigning +// Timber.i("## CrossSigning - Loading master key success") +// } else { +// Timber.w("## CrossSigning - Public master key does not match the private key") +// pkSigning.releaseSigning() +// // TODO untrust? +// } +// } +// privateKeysInfo.user +// ?.fromBase64() +// ?.let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { +// userPkSigning = pkSigning +// Timber.i("## CrossSigning - Loading User Signing key success") +// } else { +// Timber.w("## CrossSigning - Public User key does not match the private key") +// pkSigning.releaseSigning() +// // TODO untrust? +// } +// } +// privateKeysInfo.selfSigned +// ?.fromBase64() +// ?.let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { +// selfSigningPkSigning = pkSigning +// Timber.i("## CrossSigning - Loading Self Signing key success") +// } else { +// Timber.w("## CrossSigning - Public Self Signing key does not match the private key") +// pkSigning.releaseSigning() +// // TODO untrust? +// } +// } +// } +// +// // Recover local trust in case private key are there? +// setUserKeysAsTrusted(userId, checkUserTrust(userId).isVerified()) +// } +// } catch (e: Throwable) { +// // Mmm this kind of a big issue +// Timber.e(e, "Failed to initialize Cross Signing") +// } +// +// deviceListManager.addListener(this) +// } +// +// fun release() { +// olmUtility?.releaseUtility() +// listOf(masterPkSigning, userPkSigning, selfSigningPkSigning).forEach { it?.releaseSigning() } +// deviceListManager.removeListener(this) +// } +// +// protected fun finalize() { +// release() +// } +// +// /** +// * - Make 3 key pairs (MSK, USK, SSK) +// * - Save the private keys with proper security +// * - Sign the keys and upload them +// * - Sign the current device with SSK and sign MSK with device key (migration) and upload signatures +// */ +// override fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?, callback: MatrixCallback) { +// Timber.d("## CrossSigning initializeCrossSigning") +// +// val params = InitializeCrossSigningTask.Params( +// interactiveAuthInterceptor = uiaInterceptor +// ) +// initializeCrossSigningTask.configureWith(params) { +// this.callbackThread = TaskThread.CRYPTO +// this.callback = object : MatrixCallback { +// override fun onFailure(failure: Throwable) { +// Timber.e(failure, "Error in initializeCrossSigning()") +// callback.onFailure(failure) +// } +// +// override fun onSuccess(data: InitializeCrossSigningTask.Result) { +// val crossSigningInfo = MXCrossSigningInfo(userId, listOf(data.masterKeyInfo, data.userKeyInfo, data.selfSignedKeyInfo)) +// cryptoStore.setMyCrossSigningInfo(crossSigningInfo) +// setUserKeysAsTrusted(userId, true) +// cryptoStore.storePrivateKeysInfo(data.masterKeyPK, data.userKeyPK, data.selfSigningKeyPK) +// masterPkSigning = OlmPkSigning().apply { initWithSeed(data.masterKeyPK.fromBase64()) } +// userPkSigning = OlmPkSigning().apply { initWithSeed(data.userKeyPK.fromBase64()) } +// selfSigningPkSigning = OlmPkSigning().apply { initWithSeed(data.selfSigningKeyPK.fromBase64()) } +// +// callback.onSuccess(Unit) +// } +// } +// }.executeBy(taskExecutor) +// } +// +// override fun onSecretMSKGossip(mskPrivateKey: String) { +// Timber.i("## CrossSigning - onSecretSSKGossip") +// val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { +// Timber.e("## CrossSigning - onSecretMSKGossip() received secret but public key is not known") +// } +// +// mskPrivateKey.fromBase64() +// .let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// try { +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { +// masterPkSigning?.releaseSigning() +// masterPkSigning = pkSigning +// Timber.i("## CrossSigning - Loading MSK success") +// cryptoStore.storeMSKPrivateKey(mskPrivateKey) +// return +// } else { +// Timber.e("## CrossSigning - onSecretMSKGossip() private key do not match public key") +// pkSigning.releaseSigning() +// } +// } catch (failure: Throwable) { +// Timber.e("## CrossSigning - onSecretMSKGossip() ${failure.localizedMessage}") +// pkSigning.releaseSigning() +// } +// } +// } +// +// override fun onSecretSSKGossip(sskPrivateKey: String) { +// Timber.i("## CrossSigning - onSecretSSKGossip") +// val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { +// Timber.e("## CrossSigning - onSecretSSKGossip() received secret but public key is not known") +// } +// +// sskPrivateKey.fromBase64() +// .let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// try { +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { +// selfSigningPkSigning?.releaseSigning() +// selfSigningPkSigning = pkSigning +// Timber.i("## CrossSigning - Loading SSK success") +// cryptoStore.storeSSKPrivateKey(sskPrivateKey) +// return +// } else { +// Timber.e("## CrossSigning - onSecretSSKGossip() private key do not match public key") +// pkSigning.releaseSigning() +// } +// } catch (failure: Throwable) { +// Timber.e("## CrossSigning - onSecretSSKGossip() ${failure.localizedMessage}") +// pkSigning.releaseSigning() +// } +// } +// } +// +// override fun onSecretUSKGossip(uskPrivateKey: String) { +// Timber.i("## CrossSigning - onSecretUSKGossip") +// val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { +// Timber.e("## CrossSigning - onSecretUSKGossip() received secret but public key is not knwow ") +// } +// +// uskPrivateKey.fromBase64() +// .let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// try { +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { +// userPkSigning?.releaseSigning() +// userPkSigning = pkSigning +// Timber.i("## CrossSigning - Loading USK success") +// cryptoStore.storeUSKPrivateKey(uskPrivateKey) +// return +// } else { +// Timber.e("## CrossSigning - onSecretUSKGossip() private key do not match public key") +// pkSigning.releaseSigning() +// } +// } catch (failure: Throwable) { +// pkSigning.releaseSigning() +// } +// } +// } +// +// override fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, +// uskKeyPrivateKey: String?, +// sskPrivateKey: String? +// ): UserTrustResult { +// val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return UserTrustResult.CrossSigningNotConfigured(userId) +// +// var masterKeyIsTrusted = false +// var userKeyIsTrusted = false +// var selfSignedKeyIsTrusted = false +// +// masterKeyPrivateKey?.fromBase64() +// ?.let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// try { +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { +// masterPkSigning?.releaseSigning() +// masterPkSigning = pkSigning +// masterKeyIsTrusted = true +// Timber.i("## CrossSigning - Loading master key success") +// } else { +// pkSigning.releaseSigning() +// } +// } catch (failure: Throwable) { +// pkSigning.releaseSigning() +// } +// } +// +// uskKeyPrivateKey?.fromBase64() +// ?.let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// try { +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { +// userPkSigning?.releaseSigning() +// userPkSigning = pkSigning +// userKeyIsTrusted = true +// Timber.i("## CrossSigning - Loading master key success") +// } else { +// pkSigning.releaseSigning() +// } +// } catch (failure: Throwable) { +// pkSigning.releaseSigning() +// } +// } +// +// sskPrivateKey?.fromBase64() +// ?.let { privateKeySeed -> +// val pkSigning = OlmPkSigning() +// try { +// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { +// selfSigningPkSigning?.releaseSigning() +// selfSigningPkSigning = pkSigning +// selfSignedKeyIsTrusted = true +// Timber.i("## CrossSigning - Loading master key success") +// } else { +// pkSigning.releaseSigning() +// } +// } catch (failure: Throwable) { +// pkSigning.releaseSigning() +// } +// } +// +// if (!masterKeyIsTrusted || !userKeyIsTrusted || !selfSignedKeyIsTrusted) { +// return UserTrustResult.KeysNotTrusted(mxCrossSigningInfo) +// } else { +// cryptoStore.markMyMasterKeyAsLocallyTrusted(true) +// val checkSelfTrust = checkSelfTrust() +// if (checkSelfTrust.isVerified()) { +// cryptoStore.storePrivateKeysInfo(masterKeyPrivateKey, uskKeyPrivateKey, sskPrivateKey) +// setUserKeysAsTrusted(userId, true) +// } +// return checkSelfTrust +// } +// } +// +// /** +// * +// * ┏━━━━━━━━┓ ┏━━━━━━━━┓ +// * ┃ ALICE ┃ ┃ BOB ┃ +// * ┗━━━━━━━━┛ ┗━━━━━━━━┛ +// * MSK ┌────────────▶ MSK +// * │ +// * │ │ +// * │ SSK │ +// * │ │ +// * │ │ +// * └──▶ USK ────────────┘ +// */ +// override fun isUserTrusted(otherUserId: String): Boolean { +// return cryptoStore.getCrossSigningInfo(userId)?.isTrusted() == true +// } +// +// override fun isCrossSigningVerified(): Boolean { +// return checkSelfTrust().isVerified() +// } +// +// /** +// * Will not force a download of the key, but will verify signatures trust chain +// */ +// override fun checkUserTrust(otherUserId: String): UserTrustResult { +// Timber.v("## CrossSigning checkUserTrust for $otherUserId") +// if (otherUserId == userId) { +// return checkSelfTrust() +// } +// // I trust a user if I trust his master key +// // I can trust the master key if it is signed by my user key +// // TODO what if the master key is signed by a device key that i have verified +// +// // First let's get my user key // val myCrossSigningInfo = cryptoStore.getCrossSigningInfo(userId) - - val myMasterKey = myCrossSigningInfo?.masterKey() - ?: return UserTrustResult.CrossSigningNotConfigured(userId) - - // Is the master key trusted - // 1) check if I know the private key - val masterPrivateKey = cryptoStore.getCrossSigningPrivateKeys() - ?.master - ?.fromBase64() - - var isMaterKeyTrusted = false - if (myMasterKey.trustLevel?.locallyVerified == true) { - isMaterKeyTrusted = true - } else if (masterPrivateKey != null) { - // Check if private match public - var olmPkSigning: OlmPkSigning? = null - try { - olmPkSigning = OlmPkSigning() - val expectedPK = olmPkSigning.initWithSeed(masterPrivateKey) - isMaterKeyTrusted = myMasterKey.unpaddedBase64PublicKey == expectedPK - } catch (failure: Throwable) { - Timber.e(failure) - } - olmPkSigning?.releaseSigning() - } else { - // Maybe it's signed by a locally trusted device? - myMasterKey.signatures?.get(userId)?.forEach { (key, value) -> - val potentialDeviceId = key.removePrefix("ed25519:") - val potentialDevice = myDevices?.firstOrNull { it.deviceId == potentialDeviceId } // cryptoStore.getUserDevice(userId, potentialDeviceId) - if (potentialDevice != null && potentialDevice.isVerified) { - // Check signature validity? - try { - olmUtility?.verifyEd25519Signature(value, potentialDevice.fingerprint(), myMasterKey.canonicalSignable()) - isMaterKeyTrusted = true - return@forEach - } catch (failure: Throwable) { - // log - Timber.w(failure, "Signature not valid?") - } - } - } - } - - if (!isMaterKeyTrusted) { - return UserTrustResult.KeysNotTrusted(myCrossSigningInfo) - } - - val myUserKey = myCrossSigningInfo.userKey() - ?: return UserTrustResult.CrossSigningNotConfigured(userId) - - val userKeySignaturesMadeByMyMasterKey = myUserKey.signatures - ?.get(userId) // Signatures made by me - ?.get("ed25519:${myMasterKey.unpaddedBase64PublicKey}") - - if (userKeySignaturesMadeByMyMasterKey.isNullOrBlank()) { - Timber.d("## CrossSigning checkUserTrust false for $userId, USK not signed by MSK") - return UserTrustResult.KeyNotSigned(myUserKey) - } - - // Check that Alice USK signature of Alice MSK is valid - try { - olmUtility!!.verifyEd25519Signature(userKeySignaturesMadeByMyMasterKey, myMasterKey.unpaddedBase64PublicKey, myUserKey.canonicalSignable()) - } catch (failure: Throwable) { - return UserTrustResult.InvalidSignature(myUserKey, userKeySignaturesMadeByMyMasterKey) - } - - val mySSKey = myCrossSigningInfo.selfSigningKey() - ?: return UserTrustResult.CrossSigningNotConfigured(userId) - - val ssKeySignaturesMadeByMyMasterKey = mySSKey.signatures - ?.get(userId) // Signatures made by me - ?.get("ed25519:${myMasterKey.unpaddedBase64PublicKey}") - - if (ssKeySignaturesMadeByMyMasterKey.isNullOrBlank()) { - Timber.d("## CrossSigning checkUserTrust false for $userId, SSK not signed by MSK") - return UserTrustResult.KeyNotSigned(mySSKey) - } - - // Check that Alice USK signature of Alice MSK is valid - try { - olmUtility!!.verifyEd25519Signature(ssKeySignaturesMadeByMyMasterKey, myMasterKey.unpaddedBase64PublicKey, mySSKey.canonicalSignable()) - } catch (failure: Throwable) { - return UserTrustResult.InvalidSignature(mySSKey, ssKeySignaturesMadeByMyMasterKey) - } - - return UserTrustResult.Success - } - - override fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? { - return cryptoStore.getCrossSigningInfo(otherUserId) - } - - override fun getLiveCrossSigningKeys(userId: String): LiveData> { - return cryptoStore.getLiveCrossSigningInfo(userId) - } - - override fun getMyCrossSigningKeys(): MXCrossSigningInfo? { - return cryptoStore.getMyCrossSigningInfo() - } - - override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? { - return cryptoStore.getCrossSigningPrivateKeys() - } - - override fun getLiveCrossSigningPrivateKeys(): LiveData> { - return cryptoStore.getLiveCrossSigningPrivateKeys() - } - - override fun canCrossSign(): Boolean { - return checkSelfTrust().isVerified() && cryptoStore.getCrossSigningPrivateKeys()?.selfSigned != null && - cryptoStore.getCrossSigningPrivateKeys()?.user != null - } - - override fun allPrivateKeysKnown(): Boolean { - return checkSelfTrust().isVerified() && - cryptoStore.getCrossSigningPrivateKeys()?.allKnown().orFalse() - } - - override fun trustUser(otherUserId: String, callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - Timber.d("## CrossSigning - Mark user $userId as trusted ") - // We should have this user keys - val otherMasterKeys = getUserCrossSigningKeys(otherUserId)?.masterKey() - if (otherMasterKeys == null) { - callback.onFailure(Throwable("## CrossSigning - Other master signing key is not known")) - return@launch - } - val myKeys = getUserCrossSigningKeys(userId) - if (myKeys == null) { - callback.onFailure(Throwable("## CrossSigning - CrossSigning is not setup for this account")) - return@launch - } - val userPubKey = myKeys.userKey()?.unpaddedBase64PublicKey - if (userPubKey == null || userPkSigning == null) { - callback.onFailure(Throwable("## CrossSigning - Cannot sign from this account, privateKeyUnknown $userPubKey")) - return@launch - } - - // Sign the other MasterKey with our UserSigning key - val newSignature = JsonCanonicalizer.getCanonicalJson(Map::class.java, - otherMasterKeys.signalableJSONDictionary()).let { userPkSigning?.sign(it) } - - if (newSignature == null) { - // race?? - callback.onFailure(Throwable("## CrossSigning - Failed to sign")) - return@launch - } - - cryptoStore.setUserKeysAsTrusted(otherUserId, true) - // TODO update local copy with new signature directly here? kind of local echo of trust? - - Timber.d("## CrossSigning - Upload signature of $userId MSK signed by USK") - val uploadQuery = UploadSignatureQueryBuilder() - .withSigningKeyInfo(otherMasterKeys.copyForSignature(userId, userPubKey, newSignature)) - .build() - uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadQuery)) { - this.executionThread = TaskThread.CRYPTO - this.callback = callback - }.executeBy(taskExecutor) - } - } - - override fun markMyMasterKeyAsTrusted() { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - cryptoStore.markMyMasterKeyAsLocallyTrusted(true) - checkSelfTrust() - // re-verify all trusts - onUsersDeviceUpdate(listOf(userId)) - } - } - - override fun trustDevice(deviceId: String, callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - // This device should be yours - val device = cryptoStore.getUserDevice(userId, deviceId) - if (device == null) { - callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known, or not yours")) - return@launch - } - - val myKeys = getUserCrossSigningKeys(userId) - if (myKeys == null) { - callback.onFailure(Throwable("CrossSigning is not setup for this account")) - return@launch - } - - val ssPubKey = myKeys.selfSigningKey()?.unpaddedBase64PublicKey - if (ssPubKey == null || selfSigningPkSigning == null) { - callback.onFailure(Throwable("Cannot sign from this account, public and/or privateKey Unknown $ssPubKey")) - return@launch - } - - // Sign with self signing - val newSignature = selfSigningPkSigning?.sign(device.canonicalSignable()) - - if (newSignature == null) { - // race?? - callback.onFailure(Throwable("Failed to sign")) - return@launch - } - val toUpload = device.copy( - signatures = mapOf( - userId - to - mapOf( - "ed25519:$ssPubKey" to newSignature - ) - ) - ) - - val uploadQuery = UploadSignatureQueryBuilder() - .withDeviceInfo(toUpload) - .build() - uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadQuery)) { - this.executionThread = TaskThread.CRYPTO - this.callback = callback - }.executeBy(taskExecutor) - } - } - - override fun checkDeviceTrust(otherUserId: String, otherDeviceId: String, locallyTrusted: Boolean?): DeviceTrustResult { - val otherDevice = cryptoStore.getUserDevice(otherUserId, otherDeviceId) - ?: return DeviceTrustResult.UnknownDevice(otherDeviceId) - - val myKeys = getUserCrossSigningKeys(userId) - ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(userId)) - - if (!myKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(myKeys)) - - val otherKeys = getUserCrossSigningKeys(otherUserId) - ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(otherUserId)) - - // TODO should we force verification ? - if (!otherKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(otherKeys)) - - // Check if the trust chain is valid - /* - * ┏━━━━━━━━┓ ┏━━━━━━━━┓ - * ┃ ALICE ┃ ┃ BOB ┃ - * ┗━━━━━━━━┛ ┗━━━━━━━━┛ - * MSK ┌────────────▶MSK - * │ - * │ │ │ - * │ SSK │ └──▶ SSK ──────────────────┐ - * │ │ │ - * │ │ USK │ - * └──▶ USK ────────────┘ (not visible by │ - * Alice) │ - * ▼ - * ┌──────────────┐ - * │ BOB's Device │ - * └──────────────┘ - */ - - val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}") - ?: return legacyFallbackTrust( - locallyTrusted, - DeviceTrustResult.MissingDeviceSignature(otherDeviceId, otherKeys.selfSigningKey() - ?.unpaddedBase64PublicKey - ?: "" - ) - ) - - // Check bob's device is signed by bob's SSK - try { - olmUtility!!.verifyEd25519Signature(otherSSKSignature, otherKeys.selfSigningKey()?.unpaddedBase64PublicKey, otherDevice.canonicalSignable()) - } catch (e: Throwable) { - return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.InvalidDeviceSignature(otherDeviceId, otherSSKSignature, e)) - } - - return DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = true, locallyVerified = locallyTrusted)) - } - - fun checkDeviceTrust(myKeys: MXCrossSigningInfo?, otherKeys: MXCrossSigningInfo?, otherDevice: CryptoDeviceInfo): DeviceTrustResult { - val locallyTrusted = otherDevice.trustLevel?.isLocallyVerified() - myKeys ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(userId)) - - if (!myKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(myKeys)) - - otherKeys ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(otherDevice.userId)) - - // TODO should we force verification ? - if (!otherKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(otherKeys)) - - // Check if the trust chain is valid - /* - * ┏━━━━━━━━┓ ┏━━━━━━━━┓ - * ┃ ALICE ┃ ┃ BOB ┃ - * ┗━━━━━━━━┛ ┗━━━━━━━━┛ - * MSK ┌────────────▶MSK - * │ - * │ │ │ - * │ SSK │ └──▶ SSK ──────────────────┐ - * │ │ │ - * │ │ USK │ - * └──▶ USK ────────────┘ (not visible by │ - * Alice) │ - * ▼ - * ┌──────────────┐ - * │ BOB's Device │ - * └──────────────┘ - */ - - val otherSSKSignature = otherDevice.signatures?.get(otherKeys.userId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}") - ?: return legacyFallbackTrust( - locallyTrusted, - DeviceTrustResult.MissingDeviceSignature(otherDevice.deviceId, otherKeys.selfSigningKey() - ?.unpaddedBase64PublicKey - ?: "" - ) - ) - - // Check bob's device is signed by bob's SSK - try { - olmUtility!!.verifyEd25519Signature(otherSSKSignature, otherKeys.selfSigningKey()?.unpaddedBase64PublicKey, otherDevice.canonicalSignable()) - } catch (e: Throwable) { - return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.InvalidDeviceSignature(otherDevice.deviceId, otherSSKSignature, e)) - } - - return DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = true, locallyVerified = locallyTrusted)) - } - - private fun legacyFallbackTrust(locallyTrusted: Boolean?, crossSignTrustFail: DeviceTrustResult): DeviceTrustResult { - return if (locallyTrusted == true) { - DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true)) - } else { - crossSignTrustFail - } - } - - override fun onUsersDeviceUpdate(userIds: List) { - Timber.d("## CrossSigning - onUsersDeviceUpdate for users: ${userIds.logLimit()}") - val workerParams = UpdateTrustWorker.Params( - sessionId = sessionId, - filename = updateTrustWorkerDataRepository.createParam(userIds) - ) - val workerData = WorkerParamsFactory.toData(workerParams) - - val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() - .setInputData(workerData) - .setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS) - .build() - - workManagerProvider.workManager - .beginUniqueWork("TRUST_UPDATE_QUEUE", ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest) - .enqueue() - } - - private fun setUserKeysAsTrusted(otherUserId: String, trusted: Boolean) { - val currentTrust = cryptoStore.getCrossSigningInfo(otherUserId)?.isTrusted() - cryptoStore.setUserKeysAsTrusted(otherUserId, trusted) - // If it's me, recheck trust of all users and devices? - val users = ArrayList() - if (otherUserId == userId && currentTrust != trusted) { -// reRequestAllPendingRoomKeyRequest() - cryptoStore.updateUsersTrust { - users.add(it) - checkUserTrust(it).isVerified() - } - - users.forEach { - cryptoStore.getUserDeviceList(it)?.forEach { device -> - val updatedTrust = checkDeviceTrust(it, device.deviceId, device.trustLevel?.isLocallyVerified() ?: false) - Timber.v("## CrossSigning - update trust for device ${device.deviceId} of user $otherUserId , verified=$updatedTrust") - cryptoStore.setDeviceTrust(it, device.deviceId, updatedTrust.isCrossSignedVerified(), updatedTrust.isLocallyVerified()) - } - } - } - } - -// private fun reRequestAllPendingRoomKeyRequest() { -// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// Timber.d("## CrossSigning - reRequest pending outgoing room key requests") -// cryptoStore.getOutgoingRoomKeyRequests().forEach { -// it.requestBody?.let { requestBody -> -// if (cryptoStore.getInboundGroupSession(requestBody.sessionId ?: "", requestBody.senderKey ?: "") == null) { -// outgoingRoomKeyRequestManager.resendRoomKeyRequest(requestBody) -// } else { -// outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody) +// +// checkOtherMSKTrusted(myCrossSigningInfo, cryptoStore.getCrossSigningInfo(otherUserId)) +// +// return UserTrustResult.Success +// } +// +// fun checkOtherMSKTrusted(myCrossSigningInfo: MXCrossSigningInfo?, otherInfo: MXCrossSigningInfo?): UserTrustResult { +// val myUserKey = myCrossSigningInfo?.userKey() +// ?: return UserTrustResult.CrossSigningNotConfigured(userId) +// +// if (!myCrossSigningInfo.isTrusted()) { +// return UserTrustResult.KeysNotTrusted(myCrossSigningInfo) +// } +// +// // Let's get the other user master key +// val otherMasterKey = otherInfo?.masterKey() +// ?: return UserTrustResult.UnknownCrossSignatureInfo(otherInfo?.userId ?: "") +// +// val masterKeySignaturesMadeByMyUserKey = otherMasterKey.signatures +// ?.get(userId) // Signatures made by me +// ?.get("ed25519:${myUserKey.unpaddedBase64PublicKey}") +// +// if (masterKeySignaturesMadeByMyUserKey.isNullOrBlank()) { +// Timber.d("## CrossSigning checkUserTrust false for ${otherInfo.userId}, not signed by my UserSigningKey") +// return UserTrustResult.KeyNotSigned(otherMasterKey) +// } +// +// // Check that Alice USK signature of Bob MSK is valid +// try { +// olmUtility!!.verifyEd25519Signature(masterKeySignaturesMadeByMyUserKey, myUserKey.unpaddedBase64PublicKey, otherMasterKey.canonicalSignable()) +// } catch (failure: Throwable) { +// return UserTrustResult.InvalidSignature(myUserKey, masterKeySignaturesMadeByMyUserKey) +// } +// +// return UserTrustResult.Success +// } +// +// private fun checkSelfTrust(): UserTrustResult { +// // Special case when it's me, +// // I have to check that MSK -> USK -> SSK +// // and that MSK is trusted (i know the private key, or is signed by a trusted device) +// val myCrossSigningInfo = cryptoStore.getCrossSigningInfo(userId) +// +// return checkSelfTrust(myCrossSigningInfo, cryptoStore.getUserDeviceList(userId)) +// } +// +// fun checkSelfTrust(myCrossSigningInfo: MXCrossSigningInfo?, myDevices: List?): UserTrustResult { +// // Special case when it's me, +// // I have to check that MSK -> USK -> SSK +// // and that MSK is trusted (i know the private key, or is signed by a trusted device) +// // val myCrossSigningInfo = cryptoStore.getCrossSigningInfo(userId) +// +// val myMasterKey = myCrossSigningInfo?.masterKey() +// ?: return UserTrustResult.CrossSigningNotConfigured(userId) +// +// // Is the master key trusted +// // 1) check if I know the private key +// val masterPrivateKey = cryptoStore.getCrossSigningPrivateKeys() +// ?.master +// ?.fromBase64() +// +// var isMaterKeyTrusted = false +// if (myMasterKey.trustLevel?.locallyVerified == true) { +// isMaterKeyTrusted = true +// } else if (masterPrivateKey != null) { +// // Check if private match public +// var olmPkSigning: OlmPkSigning? = null +// try { +// olmPkSigning = OlmPkSigning() +// val expectedPK = olmPkSigning.initWithSeed(masterPrivateKey) +// isMaterKeyTrusted = myMasterKey.unpaddedBase64PublicKey == expectedPK +// } catch (failure: Throwable) { +// Timber.e(failure) +// } +// olmPkSigning?.releaseSigning() +// } else { +// // Maybe it's signed by a locally trusted device? +// myMasterKey.signatures?.get(userId)?.forEach { (key, value) -> +// val potentialDeviceId = key.removePrefix("ed25519:") +// val potentialDevice = myDevices?.firstOrNull { it.deviceId == potentialDeviceId } // cryptoStore.getUserDevice(userId, potentialDeviceId) +// if (potentialDevice != null && potentialDevice.isVerified) { +// // Check signature validity? +// try { +// olmUtility?.verifyEd25519Signature(value, potentialDevice.fingerprint(), myMasterKey.canonicalSignable()) +// isMaterKeyTrusted = true +// return@forEach +// } catch (failure: Throwable) { +// // log +// Timber.w(failure, "Signature not valid?") // } // } // } // } +// +// if (!isMaterKeyTrusted) { +// return UserTrustResult.KeysNotTrusted(myCrossSigningInfo) +// } +// +// val myUserKey = myCrossSigningInfo.userKey() +// ?: return UserTrustResult.CrossSigningNotConfigured(userId) +// +// val userKeySignaturesMadeByMyMasterKey = myUserKey.signatures +// ?.get(userId) // Signatures made by me +// ?.get("ed25519:${myMasterKey.unpaddedBase64PublicKey}") +// +// if (userKeySignaturesMadeByMyMasterKey.isNullOrBlank()) { +// Timber.d("## CrossSigning checkUserTrust false for $userId, USK not signed by MSK") +// return UserTrustResult.KeyNotSigned(myUserKey) +// } +// +// // Check that Alice USK signature of Alice MSK is valid +// try { +// olmUtility!!.verifyEd25519Signature(userKeySignaturesMadeByMyMasterKey, myMasterKey.unpaddedBase64PublicKey, myUserKey.canonicalSignable()) +// } catch (failure: Throwable) { +// return UserTrustResult.InvalidSignature(myUserKey, userKeySignaturesMadeByMyMasterKey) +// } +// +// val mySSKey = myCrossSigningInfo.selfSigningKey() +// ?: return UserTrustResult.CrossSigningNotConfigured(userId) +// +// val ssKeySignaturesMadeByMyMasterKey = mySSKey.signatures +// ?.get(userId) // Signatures made by me +// ?.get("ed25519:${myMasterKey.unpaddedBase64PublicKey}") +// +// if (ssKeySignaturesMadeByMyMasterKey.isNullOrBlank()) { +// Timber.d("## CrossSigning checkUserTrust false for $userId, SSK not signed by MSK") +// return UserTrustResult.KeyNotSigned(mySSKey) +// } +// +// // Check that Alice USK signature of Alice MSK is valid +// try { +// olmUtility!!.verifyEd25519Signature(ssKeySignaturesMadeByMyMasterKey, myMasterKey.unpaddedBase64PublicKey, mySSKey.canonicalSignable()) +// } catch (failure: Throwable) { +// return UserTrustResult.InvalidSignature(mySSKey, ssKeySignaturesMadeByMyMasterKey) +// } +// +// return UserTrustResult.Success // } -} +// +// override fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? { +// return cryptoStore.getCrossSigningInfo(otherUserId) +// } +// +// override fun getLiveCrossSigningKeys(userId: String): LiveData> { +// return cryptoStore.getLiveCrossSigningInfo(userId) +// } +// +// override fun getMyCrossSigningKeys(): MXCrossSigningInfo? { +// return cryptoStore.getMyCrossSigningInfo() +// } +// +// override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? { +// return cryptoStore.getCrossSigningPrivateKeys() +// } +// +// override fun getLiveCrossSigningPrivateKeys(): LiveData> { +// return cryptoStore.getLiveCrossSigningPrivateKeys() +// } +// +// override fun canCrossSign(): Boolean { +// return checkSelfTrust().isVerified() && cryptoStore.getCrossSigningPrivateKeys()?.selfSigned != null +// && cryptoStore.getCrossSigningPrivateKeys()?.user != null +// } +// +// override fun allPrivateKeysKnown(): Boolean { +// return checkSelfTrust().isVerified() +// && cryptoStore.getCrossSigningPrivateKeys()?.allKnown().orFalse() +// } +// +// override fun trustUser(otherUserId: String, callback: MatrixCallback) { +// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { +// Timber.d("## CrossSigning - Mark user $userId as trusted ") +// // We should have this user keys +// val otherMasterKeys = getUserCrossSigningKeys(otherUserId)?.masterKey() +// if (otherMasterKeys == null) { +// callback.onFailure(Throwable("## CrossSigning - Other master signing key is not known")) +// return@launch +// } +// val myKeys = getUserCrossSigningKeys(userId) +// if (myKeys == null) { +// callback.onFailure(Throwable("## CrossSigning - CrossSigning is not setup for this account")) +// return@launch +// } +// val userPubKey = myKeys.userKey()?.unpaddedBase64PublicKey +// if (userPubKey == null || userPkSigning == null) { +// callback.onFailure(Throwable("## CrossSigning - Cannot sign from this account, privateKeyUnknown $userPubKey")) +// return@launch +// } +// +// // Sign the other MasterKey with our UserSigning key +// val newSignature = JsonCanonicalizer.getCanonicalJson(Map::class.java, +// otherMasterKeys.signalableJSONDictionary()).let { userPkSigning?.sign(it) } +// +// if (newSignature == null) { +// // race?? +// callback.onFailure(Throwable("## CrossSigning - Failed to sign")) +// return@launch +// } +// +// cryptoStore.setUserKeysAsTrusted(otherUserId, true) +// // TODO update local copy with new signature directly here? kind of local echo of trust? +// +// Timber.d("## CrossSigning - Upload signature of $userId MSK signed by USK") +// val uploadQuery = UploadSignatureQueryBuilder() +// .withSigningKeyInfo(otherMasterKeys.copyForSignature(userId, userPubKey, newSignature)) +// .build() +// uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadQuery)) { +// this.executionThread = TaskThread.CRYPTO +// this.callback = callback +// }.executeBy(taskExecutor) +// } +// } +// +// override fun markMyMasterKeyAsTrusted() { +// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { +// cryptoStore.markMyMasterKeyAsLocallyTrusted(true) +// checkSelfTrust() +// // re-verify all trusts +// onUsersDeviceUpdate(listOf(userId)) +// } +// } +// +// override fun trustDevice(deviceId: String, callback: MatrixCallback) { +// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { +// // This device should be yours +// val device = cryptoStore.getUserDevice(userId, deviceId) +// if (device == null) { +// callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known, or not yours")) +// return@launch +// } +// +// val myKeys = getUserCrossSigningKeys(userId) +// if (myKeys == null) { +// callback.onFailure(Throwable("CrossSigning is not setup for this account")) +// return@launch +// } +// +// val ssPubKey = myKeys.selfSigningKey()?.unpaddedBase64PublicKey +// if (ssPubKey == null || selfSigningPkSigning == null) { +// callback.onFailure(Throwable("Cannot sign from this account, public and/or privateKey Unknown $ssPubKey")) +// return@launch +// } +// +// // Sign with self signing +// val newSignature = selfSigningPkSigning?.sign(device.canonicalSignable()) +// +// if (newSignature == null) { +// // race?? +// callback.onFailure(Throwable("Failed to sign")) +// return@launch +// } +// val toUpload = device.copy( +// signatures = mapOf( +// userId +// to +// mapOf( +// "ed25519:$ssPubKey" to newSignature +// ) +// ) +// ) +// +// val uploadQuery = UploadSignatureQueryBuilder() +// .withDeviceInfo(toUpload) +// .build() +// uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadQuery)) { +// this.executionThread = TaskThread.CRYPTO +// this.callback = callback +// }.executeBy(taskExecutor) +// } +// } +// +// override fun checkDeviceTrust(otherUserId: String, otherDeviceId: String, locallyTrusted: Boolean?): DeviceTrustResult { +// val otherDevice = cryptoStore.getUserDevice(otherUserId, otherDeviceId) +// ?: return DeviceTrustResult.UnknownDevice(otherDeviceId) +// +// val myKeys = getUserCrossSigningKeys(userId) +// ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(userId)) +// +// if (!myKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(myKeys)) +// +// val otherKeys = getUserCrossSigningKeys(otherUserId) +// ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(otherUserId)) +// +// // TODO should we force verification ? +// if (!otherKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(otherKeys)) +// +// // Check if the trust chain is valid +// /* +// * ┏━━━━━━━━┓ ┏━━━━━━━━┓ +// * ┃ ALICE ┃ ┃ BOB ┃ +// * ┗━━━━━━━━┛ ┗━━━━━━━━┛ +// * MSK ┌────────────▶MSK +// * │ +// * │ │ │ +// * │ SSK │ └──▶ SSK ──────────────────┐ +// * │ │ │ +// * │ │ USK │ +// * └──▶ USK ────────────┘ (not visible by │ +// * Alice) │ +// * ▼ +// * ┌──────────────┐ +// * │ BOB's Device │ +// * └──────────────┘ +// */ +// +// val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}") +// ?: return legacyFallbackTrust( +// locallyTrusted, +// DeviceTrustResult.MissingDeviceSignature(otherDeviceId, otherKeys.selfSigningKey() +// ?.unpaddedBase64PublicKey +// ?: "" +// ) +// ) +// +// // Check bob's device is signed by bob's SSK +// try { +// olmUtility!!.verifyEd25519Signature(otherSSKSignature, otherKeys.selfSigningKey()?.unpaddedBase64PublicKey, otherDevice.canonicalSignable()) +// } catch (e: Throwable) { +// return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.InvalidDeviceSignature(otherDeviceId, otherSSKSignature, e)) +// } +// +// return DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = true, locallyVerified = locallyTrusted)) +// } +// +// fun checkDeviceTrust(myKeys: MXCrossSigningInfo?, otherKeys: MXCrossSigningInfo?, otherDevice: CryptoDeviceInfo): DeviceTrustResult { +// val locallyTrusted = otherDevice.trustLevel?.isLocallyVerified() +// myKeys ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(userId)) +// +// if (!myKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(myKeys)) +// +// otherKeys ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(otherDevice.userId)) +// +// // TODO should we force verification ? +// if (!otherKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(otherKeys)) +// +// // Check if the trust chain is valid +// /* +// * ┏━━━━━━━━┓ ┏━━━━━━━━┓ +// * ┃ ALICE ┃ ┃ BOB ┃ +// * ┗━━━━━━━━┛ ┗━━━━━━━━┛ +// * MSK ┌────────────▶MSK +// * │ +// * │ │ │ +// * │ SSK │ └──▶ SSK ──────────────────┐ +// * │ │ │ +// * │ │ USK │ +// * └──▶ USK ────────────┘ (not visible by │ +// * Alice) │ +// * ▼ +// * ┌──────────────┐ +// * │ BOB's Device │ +// * └──────────────┘ +// */ +// +// val otherSSKSignature = otherDevice.signatures?.get(otherKeys.userId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}") +// ?: return legacyFallbackTrust( +// locallyTrusted, +// DeviceTrustResult.MissingDeviceSignature(otherDevice.deviceId, otherKeys.selfSigningKey() +// ?.unpaddedBase64PublicKey +// ?: "" +// ) +// ) +// +// // Check bob's device is signed by bob's SSK +// try { +// olmUtility!!.verifyEd25519Signature(otherSSKSignature, otherKeys.selfSigningKey()?.unpaddedBase64PublicKey, otherDevice.canonicalSignable()) +// } catch (e: Throwable) { +// return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.InvalidDeviceSignature(otherDevice.deviceId, otherSSKSignature, e)) +// } +// +// return DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = true, locallyVerified = locallyTrusted)) +// } +// +// private fun legacyFallbackTrust(locallyTrusted: Boolean?, crossSignTrustFail: DeviceTrustResult): DeviceTrustResult { +// return if (locallyTrusted == true) { +// DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true)) +// } else { +// crossSignTrustFail +// } +// } +// +// override fun onUsersDeviceUpdate(userIds: List) { +// Timber.d("## CrossSigning - onUsersDeviceUpdate for users: ${userIds.logLimit()}") +// val workerParams = UpdateTrustWorker.Params( +// sessionId = sessionId, +// filename = updateTrustWorkerDataRepository.createParam(userIds) +// ) +// val workerData = WorkerParamsFactory.toData(workerParams) +// +// val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() +// .setInputData(workerData) +// .setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS) +// .build() +// +// workManagerProvider.workManager +// .beginUniqueWork("TRUST_UPDATE_QUEUE", ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest) +// .enqueue() +// } +// +// private fun setUserKeysAsTrusted(otherUserId: String, trusted: Boolean) { +// val currentTrust = cryptoStore.getCrossSigningInfo(otherUserId)?.isTrusted() +// cryptoStore.setUserKeysAsTrusted(otherUserId, trusted) +// // If it's me, recheck trust of all users and devices? +// val users = ArrayList() +// if (otherUserId == userId && currentTrust != trusted) { +// // reRequestAllPendingRoomKeyRequest() +// cryptoStore.updateUsersTrust { +// users.add(it) +// checkUserTrust(it).isVerified() +// } +// +// users.forEach { +// cryptoStore.getUserDeviceList(it)?.forEach { device -> +// val updatedTrust = checkDeviceTrust(it, device.deviceId, device.trustLevel?.isLocallyVerified() ?: false) +// Timber.v("## CrossSigning - update trust for device ${device.deviceId} of user $otherUserId , verified=$updatedTrust") +// cryptoStore.setDeviceTrust(it, device.deviceId, updatedTrust.isCrossSignedVerified(), updatedTrust.isLocallyVerified()) +// } +// } +// } +// } +// +// // private fun reRequestAllPendingRoomKeyRequest() { +// // cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { +// // Timber.d("## CrossSigning - reRequest pending outgoing room key requests") +// // cryptoStore.getOutgoingRoomKeyRequests().forEach { +// // it.requestBody?.let { requestBody -> +// // if (cryptoStore.getInboundGroupSession(requestBody.sessionId ?: "", requestBody.senderKey ?: "") == null) { +// // outgoingRoomKeyRequestManager.resendRoomKeyRequest(requestBody) +// // } else { +// // outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody) +// // } +// // } +// // } +// // } +// // } +// } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt index 3326d3707a..3121e99572 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt @@ -1,347 +1,389 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.crosssigning - -import android.content.Context -import androidx.work.WorkerParameters -import com.squareup.moshi.JsonClass -import io.realm.Realm -import io.realm.RealmConfiguration -import io.realm.kotlin.where -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel -import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper -import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMapper -import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields -import org.matrix.android.sdk.internal.database.awaitTransaction -import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity -import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields -import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity -import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields -import org.matrix.android.sdk.internal.database.query.where -import org.matrix.android.sdk.internal.di.CryptoDatabase -import org.matrix.android.sdk.internal.di.SessionDatabase -import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.session.SessionComponent -import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper -import org.matrix.android.sdk.internal.util.logLimit -import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker -import org.matrix.android.sdk.internal.worker.SessionWorkerParams -import timber.log.Timber -import javax.inject.Inject - -internal class UpdateTrustWorker(context: Context, - params: WorkerParameters) : - SessionSafeCoroutineWorker(context, params, Params::class.java) { - - @JsonClass(generateAdapter = true) - internal data class Params( - override val sessionId: String, - override val lastFailureMessage: String? = null, - // Kept for compatibility, but not used anymore (can be used for pending Worker) - val updatedUserIds: List? = null, - // Passing a long list of userId can break the Work Manager due to data size limitation. - // so now we use a temporary file to store the data - val filename: String? = null - ) : SessionWorkerParams - - @Inject lateinit var crossSigningService: DefaultCrossSigningService - - // It breaks the crypto store contract, but we need to batch things :/ - @CryptoDatabase - @Inject lateinit var cryptoRealmConfiguration: RealmConfiguration - - @SessionDatabase - @Inject lateinit var sessionRealmConfiguration: RealmConfiguration - - @UserId - @Inject lateinit var myUserId: String - @Inject lateinit var crossSigningKeysMapper: CrossSigningKeysMapper - @Inject lateinit var updateTrustWorkerDataRepository: UpdateTrustWorkerDataRepository - - // @Inject lateinit var roomSummaryUpdater: RoomSummaryUpdater - @Inject lateinit var cryptoStore: IMXCryptoStore - - override fun injectWith(injector: SessionComponent) { - injector.inject(this) - } - - override suspend fun doSafeWork(params: Params): Result { - val userList = params.filename - ?.let { updateTrustWorkerDataRepository.getParam(it) } - ?.userIds - ?: params.updatedUserIds.orEmpty() - - // List should not be empty, but let's avoid go further in case of empty list - if (userList.isNotEmpty()) { - // Unfortunately we don't have much info on what did exactly changed (is it the cross signing keys of that user, - // or a new device?) So we check all again :/ - Timber.d("## CrossSigning - Updating trust for users: ${userList.logLimit()}") - updateTrust(userList) - } - - cleanup(params) - return Result.success() - } - - private suspend fun updateTrust(userListParam: List) { - var userList = userListParam - var myCrossSigningInfo: MXCrossSigningInfo? = null - - // First we check that the users MSK are trusted by mine - // After that we check the trust chain for each devices of each users - awaitTransaction(cryptoRealmConfiguration) { cryptoRealm -> - // By mapping here to model, this object is not live - // I should update it if needed - myCrossSigningInfo = getCrossSigningInfo(cryptoRealm, myUserId) - - var myTrustResult: UserTrustResult? = null - - if (userList.contains(myUserId)) { - Timber.d("## CrossSigning - Clear all trust as a change on my user was detected") - // i am in the list.. but i don't know exactly the delta of change :/ - // If it's my cross signing keys we should refresh all trust - // do it anyway ? - userList = cryptoRealm.where(CrossSigningInfoEntity::class.java) - .findAll() - .mapNotNull { it.userId } - - // check right now my keys and mark it as trusted as other trust depends on it - val myDevices = cryptoRealm.where() - .equalTo(UserEntityFields.USER_ID, myUserId) - .findFirst() - ?.devices - ?.map { CryptoMapper.mapToModel(it) } - - myTrustResult = crossSigningService.checkSelfTrust(myCrossSigningInfo, myDevices) - updateCrossSigningKeysTrust(cryptoRealm, myUserId, myTrustResult.isVerified()) - // update model reference - myCrossSigningInfo = getCrossSigningInfo(cryptoRealm, myUserId) - } - - val otherInfos = userList.associateWith { userId -> - getCrossSigningInfo(cryptoRealm, userId) - } - - val trusts = otherInfos.mapValues { entry -> - when (entry.key) { - myUserId -> myTrustResult - else -> { - crossSigningService.checkOtherMSKTrusted(myCrossSigningInfo, entry.value).also { - Timber.d("## CrossSigning - user:${entry.key} result:$it") - } - } - } - } - - // TODO! if it's me and my keys has changed... I have to reset trust for everyone! - // i have all the new trusts, update DB - trusts.forEach { - val verified = it.value?.isVerified() == true - updateCrossSigningKeysTrust(cryptoRealm, it.key, verified) - } - - // Ok so now we have to check device trust for all these users.. - Timber.v("## CrossSigning - Updating devices cross trust users: ${trusts.keys.logLimit()}") - trusts.keys.forEach { userId -> - val devicesEntities = cryptoRealm.where() - .equalTo(UserEntityFields.USER_ID, userId) - .findFirst() - ?.devices - - val trustMap = devicesEntities?.associateWith { device -> - // get up to date from DB has could have been updated - val otherInfo = getCrossSigningInfo(cryptoRealm, userId) - crossSigningService.checkDeviceTrust(myCrossSigningInfo, otherInfo, CryptoMapper.mapToModel(device)) - } - - // Update trust if needed - devicesEntities?.forEach { device -> - val crossSignedVerified = trustMap?.get(device)?.isCrossSignedVerified() - Timber.d("## CrossSigning - Trust for ${device.userId}|${device.deviceId} : cross verified: ${trustMap?.get(device)}") - if (device.trustLevelEntity?.crossSignedVerified != crossSignedVerified) { - Timber.d("## CrossSigning - Trust change detected for ${device.userId}|${device.deviceId} : cross verified: $crossSignedVerified") - // need to save - val trustEntity = device.trustLevelEntity - if (trustEntity == null) { - device.trustLevelEntity = cryptoRealm.createObject(TrustLevelEntity::class.java).also { - it.locallyVerified = false - it.crossSignedVerified = crossSignedVerified - } - } else { - trustEntity.crossSignedVerified = crossSignedVerified - } - } - } - } - } - - // So Cross Signing keys trust is updated, device trust is updated - // We can now update room shields? in the session DB? - updateTrustStep2(userList, myCrossSigningInfo) - } - - private suspend fun updateTrustStep2(userList: List, myCrossSigningInfo: MXCrossSigningInfo?) { - Timber.d("## CrossSigning - Updating shields for impacted rooms...") - awaitTransaction(sessionRealmConfiguration) { sessionRealm -> - Realm.getInstance(cryptoRealmConfiguration).use { cryptoRealm -> - sessionRealm.where(RoomMemberSummaryEntity::class.java) - .`in`(RoomMemberSummaryEntityFields.USER_ID, userList.toTypedArray()) - .distinct(RoomMemberSummaryEntityFields.ROOM_ID) - .findAll() - .map { it.roomId } - .also { Timber.d("## CrossSigning - ... impacted rooms ${it.logLimit()}") } - .forEach { roomId -> - RoomSummaryEntity.where(sessionRealm, roomId) - .equalTo(RoomSummaryEntityFields.IS_ENCRYPTED, true) - .findFirst() - ?.let { roomSummary -> - Timber.d("## CrossSigning - Check shield state for room $roomId") - val allActiveRoomMembers = RoomMemberHelper(sessionRealm, roomId).getActiveRoomMemberIds() - try { - val updatedTrust = computeRoomShield( - myCrossSigningInfo, - cryptoRealm, - allActiveRoomMembers, - roomSummary - ) - if (roomSummary.roomEncryptionTrustLevel != updatedTrust) { - Timber.d("## CrossSigning - Shield change detected for $roomId -> $updatedTrust") - roomSummary.roomEncryptionTrustLevel = updatedTrust - } - } catch (failure: Throwable) { - Timber.e(failure) - } - } - } - } - } - } - - private fun getCrossSigningInfo(cryptoRealm: Realm, userId: String): MXCrossSigningInfo? { - return cryptoRealm.where(CrossSigningInfoEntity::class.java) - .equalTo(CrossSigningInfoEntityFields.USER_ID, userId) - .findFirst() - ?.let { mapCrossSigningInfoEntity(it) } - } - - private fun cleanup(params: Params) { - params.filename - ?.let { updateTrustWorkerDataRepository.delete(it) } - } - - private fun updateCrossSigningKeysTrust(cryptoRealm: Realm, userId: String, verified: Boolean) { - cryptoRealm.where(CrossSigningInfoEntity::class.java) - .equalTo(CrossSigningInfoEntityFields.USER_ID, userId) - .findFirst() - ?.crossSigningKeys - ?.forEach { info -> - // optimization to avoid trigger updates when there is no change.. - if (info.trustLevelEntity?.isVerified() != verified) { - Timber.d("## CrossSigning - Trust change for $userId : $verified") - val level = info.trustLevelEntity - if (level == null) { - info.trustLevelEntity = cryptoRealm.createObject(TrustLevelEntity::class.java).also { - it.locallyVerified = verified - it.crossSignedVerified = verified - } - } else { - level.locallyVerified = verified - level.crossSignedVerified = verified - } - } - } - } - - private fun computeRoomShield(myCrossSigningInfo: MXCrossSigningInfo?, - cryptoRealm: Realm, - activeMemberUserIds: List, - roomSummaryEntity: RoomSummaryEntity): RoomEncryptionTrustLevel { - Timber.d("## CrossSigning - computeRoomShield ${roomSummaryEntity.roomId} -> ${activeMemberUserIds.logLimit()}") - // The set of “all users” depends on the type of room: - // For regular / topic rooms which have more than 2 members (including yourself) are considered when decorating a room - // For 1:1 and group DM rooms, all other users (i.e. excluding yourself) are considered when decorating a room - val listToCheck = if (roomSummaryEntity.isDirect || activeMemberUserIds.size <= 2) { - activeMemberUserIds.filter { it != myUserId } - } else { - activeMemberUserIds - } - - val allTrustedUserIds = listToCheck - .filter { userId -> - getCrossSigningInfo(cryptoRealm, userId)?.isTrusted() == true - } - - return if (allTrustedUserIds.isEmpty()) { - RoomEncryptionTrustLevel.Default - } else { - // If one of the verified user as an untrusted device -> warning - // If all devices of all verified users are trusted -> green - // else -> black - allTrustedUserIds - .mapNotNull { userId -> - cryptoRealm.where() - .equalTo(UserEntityFields.USER_ID, userId) - .findFirst() - ?.devices - ?.map { CryptoMapper.mapToModel(it) } - } - .flatten() - .let { allDevices -> - Timber.v("## CrossSigning - computeRoomShield ${roomSummaryEntity.roomId} devices ${allDevices.map { it.deviceId }.logLimit()}") - if (myCrossSigningInfo != null) { - allDevices.any { !it.trustLevel?.crossSigningVerified.orFalse() } - } else { - // Legacy method - allDevices.any { !it.isVerified } - } - } - .let { hasWarning -> - if (hasWarning) { - RoomEncryptionTrustLevel.Warning - } else { - if (listToCheck.size == allTrustedUserIds.size) { - // all users are trusted and all devices are verified - RoomEncryptionTrustLevel.Trusted - } else { - RoomEncryptionTrustLevel.Default - } - } - } - } - } - - private fun mapCrossSigningInfoEntity(xsignInfo: CrossSigningInfoEntity): MXCrossSigningInfo { - val userId = xsignInfo.userId ?: "" - return MXCrossSigningInfo( - userId = userId, - crossSigningKeys = xsignInfo.crossSigningKeys.mapNotNull { - crossSigningKeysMapper.map(userId, it) - } - ) - } - - override fun buildErrorParams(params: Params, message: String): Params { - return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) - } -} +// /* +// * Copyright 2020 The Matrix.org Foundation C.I.C. +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +// package org.matrix.android.sdk.internal.crypto.crosssigning +// +// import android.content.Context +// import androidx.work.WorkerParameters +// import com.squareup.moshi.JsonClass +// import io.realm.Realm +// import io.realm.RealmConfiguration +// import io.realm.kotlin.where +// import kotlinx.coroutines.runBlocking +// import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +// import org.matrix.android.sdk.api.extensions.orFalse +// import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +// import org.matrix.android.sdk.internal.crypto.OlmMachineProvider +// import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +// import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper +// import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity +// import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields +// import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMapper +// import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntity +// import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity +// import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields +// import org.matrix.android.sdk.internal.database.awaitTransaction +// import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity +// import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields +// import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity +// import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +// import org.matrix.android.sdk.internal.database.query.where +// import org.matrix.android.sdk.internal.di.CryptoDatabase +// import org.matrix.android.sdk.internal.di.SessionDatabase +// import org.matrix.android.sdk.internal.di.UserId +// import org.matrix.android.sdk.internal.session.SessionComponent +// import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper +// import org.matrix.android.sdk.internal.util.logLimit +// import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker +// import org.matrix.android.sdk.internal.worker.SessionWorkerParams +// import timber.log.Timber +// import javax.inject.Inject +// +// @Deprecated("Now using olm machine") +// internal class UpdateTrustWorker(context: Context, +// params: WorkerParameters) +// : SessionSafeCoroutineWorker(context, params, Params::class.java) { +// +// @JsonClass(generateAdapter = true) +// internal data class Params( +// override val sessionId: String, +// override val lastFailureMessage: String? = null, +// // Kept for compatibility, but not used anymore (can be used for pending Worker) +// val updatedUserIds: List? = null, +// // Passing a long list of userId can break the Work Manager due to data size limitation. +// // so now we use a temporary file to store the data +// val filename: String? = null +// ) : SessionWorkerParams +// +// // @Inject lateinit var crossSigningService: RustCrossSigningService +// @Inject lateinit var olmMachineProvider: OlmMachineProvider//: RustCrossSigningService +// +// // It breaks the crypto store contract, but we need to batch things :/ +// @CryptoDatabase +// @Inject lateinit var cryptoRealmConfiguration: RealmConfiguration +// +// @SessionDatabase +// @Inject lateinit var sessionRealmConfiguration: RealmConfiguration +// +// @UserId +// @Inject lateinit var myUserId: String +// @Inject lateinit var crossSigningKeysMapper: CrossSigningKeysMapper +// @Inject lateinit var updateTrustWorkerDataRepository: UpdateTrustWorkerDataRepository +// +// // @Inject lateinit var roomSummaryUpdater: RoomSummaryUpdater +// @Inject lateinit var cryptoStore: IMXCryptoStore +// +// override fun injectWith(injector: SessionComponent) { +// injector.inject(this) +// } +// +// override suspend fun doSafeWork(params: Params): Result { +// val userList = params.filename +// ?.let { updateTrustWorkerDataRepository.getParam(it) } +// ?.userIds +// ?: params.updatedUserIds.orEmpty() +// +// // List should not be empty, but let's avoid go further in case of empty list +// if (userList.isNotEmpty()) { +// // Unfortunately we don't have much info on what did exactly changed (is it the cross signing keys of that user, +// // or a new device?) So we check all again :/ +// Timber.d("## CrossSigning - Updating trust for users: ${userList.logLimit()}") +// updateTrust(userList) +// } +// +// cleanup(params) +// return Result.success() +// } +// +// private suspend fun updateTrust(userListParam: List) { +// var userList = userListParam +// var myCrossSigningInfo: MXCrossSigningInfo? = null +// +// // First we check that the users MSK are trusted by mine +// // After that we check the trust chain for each devices of each users +// awaitTransaction(cryptoRealmConfiguration) { cryptoRealm -> +// // By mapping here to model, this object is not live +// // I should update it if needed +// myCrossSigningInfo = getCrossSigningInfo(cryptoRealm, myUserId) +// +// var myTrustResult: UserTrustResult? = null +// +// if (userList.contains(myUserId)) { +// Timber.d("## CrossSigning - Clear all trust as a change on my user was detected") +// // i am in the list.. but i don't know exactly the delta of change :/ +// // If it's my cross signing keys we should refresh all trust +// // do it anyway ? +// userList = cryptoRealm.where(CrossSigningInfoEntity::class.java) +// .findAll() +// .mapNotNull { it.userId } +// +// // check right now my keys and mark it as trusted as other trust depends on it +// // val myDevices = olmMachineProvider.olmMachine.getUserDevices(myUserId) +// // cryptoRealm.where() +// // .equalTo(UserEntityFields.USER_ID, myUserId) +// // .findFirst() +// // ?.devices +// // ?.map { CryptoMapper.mapToModel(it) } +// +// +// val identity = olmMachineProvider.olmMachine.getIdentity(olmMachineProvider.olmMachine.userId()) +// myTrustResult = if (identity?.verified() == true) { +// UserTrustResult.Success +// } else { +// if (identity?.toMxCrossSigningInfo() == null) { +// UserTrustResult.CrossSigningNotConfigured(olmMachineProvider.olmMachine.userId()) +// } else { +// UserTrustResult.KeysNotTrusted(identity.toMxCrossSigningInfo()) +// } +// } +// +// // crossSigningService.checkSelfTrust(myCrossSigningInfo, myDevices) +// updateCrossSigningKeysTrust(cryptoRealm, myUserId, myTrustResult.isVerified()) +// // update model reference +// myCrossSigningInfo = getCrossSigningInfo(cryptoRealm, myUserId) +// } +// +// val otherInfos = userList.associateWith { userId -> +// getCrossSigningInfo(cryptoRealm, userId) +// } +// +// val trusts = otherInfos.mapValues { entry -> +// when (entry.key) { +// myUserId -> myTrustResult +// else -> { +// val userId = entry.value?.userId ?: "" +// val identity = olmMachineProvider.olmMachine.getIdentity(userId) +// if (identity?.verified() == true) { +// UserTrustResult.Success +// } else { +// if (identity?.toMxCrossSigningInfo() == null) { +// UserTrustResult.CrossSigningNotConfigured(userId) +// } else { +// UserTrustResult.KeysNotTrusted(identity.toMxCrossSigningInfo()) +// } +// } +// } +// } +// } +// +// // TODO! if it's me and my keys has changed... I have to reset trust for everyone! +// // i have all the new trusts, update DB +// // trusts.forEach { +// // val verified = it.value?.isVerified() == true +// // updateCrossSigningKeysTrust(cryptoRealm, it.key, verified) +// // } +// +// // Ok so now we have to check device trust for all these users.. +// Timber.v("## CrossSigning - Updating devices cross trust users: ${trusts.keys.logLimit()}") +// trusts.keys.forEach { userId -> +// val devicesEntities = olmMachineProvider.olmMachine.getUserDevices(userId) +// // cryptoRealm.where() +// // .equalTo(UserEntityFields.USER_ID, userId) +// // .findFirst() +// // ?.devices +// +// val trustMap = devicesEntities.associateWith { device -> +// // val cryptoDevice = device.toCryptoDeviceInfo() +// // get up to date from DB has could have been updated +// // val otherInfo = getCrossSigningInfo(cryptoRealm, userId) +// // val deviceId = device.i deviceId ?: "" +// // val device = olmMachineProvider.olmMachine.getDevice(userId, deviceId) +// // if (device != null) { +// // TODO i don't quite understand the semantics here and there are no docs for +// // DeviceTrustResult, what do the different result types mean exactly, +// // do you return success only if the Device is cross signing verified? +// // what about the local trust if it isn't? why is the local trust passed as an argument here? +// DeviceTrustResult.Success(runBlocking { device.trustLevel() }) +// // } else { +// // DeviceTrustResult.UnknownDevice(deviceId) +// // } +// // crossSigningService.checkDeviceTrust(myCrossSigningInfo, otherInfo, CryptoMapper.mapToModel(device)) +// } +// +// // Update trust if needed +// // devicesEntities?.forEach { device -> +// // val crossSignedVerified = trustMap?.get(device)?.isCrossSignedVerified() +// // Timber.d("## CrossSigning - Trust for ${device.userId}|${device.deviceId} : cross verified: ${trustMap?.get(device)}") +// // if (device.trustLevelEntity?.crossSignedVerified != crossSignedVerified) { +// // Timber.d("## CrossSigning - Trust change detected for ${device.userId}|${device.deviceId} : cross verified: $crossSignedVerified") +// // // need to save +// // val trustEntity = device.trustLevelEntity +// // if (trustEntity == null) { +// // device.trustLevelEntity = cryptoRealm.createObject(TrustLevelEntity::class.java).also { +// // it.locallyVerified = false +// // it.crossSignedVerified = crossSignedVerified +// // } +// // } else { +// // trustEntity.crossSignedVerified = crossSignedVerified +// // } +// // } +// // } +// } +// } +// +// // So Cross Signing keys trust is updated, device trust is updated +// // We can now update room shields? in the session DB? +// updateTrustStep2(userList, myCrossSigningInfo) +// } +// +// private suspend fun updateTrustStep2(userList: List, myCrossSigningInfo: MXCrossSigningInfo?) { +// Timber.d("## CrossSigning - Updating shields for impacted rooms...") +// awaitTransaction(sessionRealmConfiguration) { sessionRealm -> +// Realm.getInstance(cryptoRealmConfiguration).use { cryptoRealm -> +// sessionRealm.where(RoomMemberSummaryEntity::class.java) +// .`in`(RoomMemberSummaryEntityFields.USER_ID, userList.toTypedArray()) +// .distinct(RoomMemberSummaryEntityFields.ROOM_ID) +// .findAll() +// .map { it.roomId } +// .also { Timber.d("## CrossSigning - ... impacted rooms ${it.logLimit()}") } +// .forEach { roomId -> +// RoomSummaryEntity.where(sessionRealm, roomId) +// .equalTo(RoomSummaryEntityFields.IS_ENCRYPTED, true) +// .findFirst() +// ?.let { roomSummary -> +// Timber.d("## CrossSigning - Check shield state for room $roomId") +// val allActiveRoomMembers = RoomMemberHelper(sessionRealm, roomId).getActiveRoomMemberIds() +// try { +// val updatedTrust = computeRoomShield( +// myCrossSigningInfo, +// cryptoRealm, +// allActiveRoomMembers, +// roomSummary +// ) +// if (roomSummary.roomEncryptionTrustLevel != updatedTrust) { +// Timber.d("## CrossSigning - Shield change detected for $roomId -> $updatedTrust") +// roomSummary.roomEncryptionTrustLevel = updatedTrust +// } +// } catch (failure: Throwable) { +// Timber.e(failure) +// } +// } +// } +// } +// } +// } +// +// private suspend fun getCrossSigningInfo(cryptoRealm: Realm, userId: String): MXCrossSigningInfo? { +// return olmMachineProvider.olmMachine.getIdentity(userId)?.toMxCrossSigningInfo() +// // cryptoRealm.where(CrossSigningInfoEntity::class.java) +// // .equalTo(CrossSigningInfoEntityFields.USER_ID, userId) +// // .findFirst() +// // ?.let { mapCrossSigningInfoEntity(it) } +// } +// +// private fun cleanup(params: Params) { +// params.filename +// ?.let { updateTrustWorkerDataRepository.delete(it) } +// } +// +// private fun updateCrossSigningKeysTrust(cryptoRealm: Realm, userId: String, verified: Boolean) { +// cryptoRealm.where(CrossSigningInfoEntity::class.java) +// .equalTo(CrossSigningInfoEntityFields.USER_ID, userId) +// .findFirst() +// ?.crossSigningKeys +// ?.forEach { info -> +// // optimization to avoid trigger updates when there is no change.. +// if (info.trustLevelEntity?.isVerified() != verified) { +// Timber.d("## CrossSigning - Trust change for $userId : $verified") +// val level = info.trustLevelEntity +// if (level == null) { +// info.trustLevelEntity = cryptoRealm.createObject(TrustLevelEntity::class.java).also { +// it.locallyVerified = verified +// it.crossSignedVerified = verified +// } +// } else { +// level.locallyVerified = verified +// level.crossSignedVerified = verified +// } +// } +// } +// } +// +// private suspend fun computeRoomShield(myCrossSigningInfo: MXCrossSigningInfo?, +// cryptoRealm: Realm, +// activeMemberUserIds: List, +// roomSummaryEntity: RoomSummaryEntity): RoomEncryptionTrustLevel { +// Timber.d("## CrossSigning - computeRoomShield ${roomSummaryEntity.roomId} -> ${activeMemberUserIds.logLimit()}") +// // The set of “all users” depends on the type of room: +// // For regular / topic rooms which have more than 2 members (including yourself) are considered when decorating a room +// // For 1:1 and group DM rooms, all other users (i.e. excluding yourself) are considered when decorating a room +// val listToCheck = if (roomSummaryEntity.isDirect || activeMemberUserIds.size <= 2) { +// activeMemberUserIds.filter { it != myUserId } +// } else { +// activeMemberUserIds +// } +// +// val allTrustedUserIds = listToCheck +// .filter { userId -> +// getCrossSigningInfo(cryptoRealm, userId)?.isTrusted() == true +// } +// Timber.d("## CrossSigning - allTrustedIds ${allTrustedUserIds}") +// +// return if (allTrustedUserIds.isEmpty()) { +// RoomEncryptionTrustLevel.Default +// } else { +// // If one of the verified user as an untrusted device -> warning +// // If all devices of all verified users are trusted -> green +// // else -> black +// allTrustedUserIds +// .mapNotNull { userId -> +// // cryptoRealm.where() +// // .equalTo(UserEntityFields.USER_ID, userId) +// // .findFirst() +// // ?.devices +// // ?.map { CryptoMapper.mapToModel(it) } +// olmMachineProvider.olmMachine.getUserDevices(userId) +// } +// .flatten() +// .let { allDevices -> +// Timber.v("## CrossSigning - computeRoomShield ${roomSummaryEntity.roomId} devices ${allDevices.map { "${it.toCryptoDeviceInfo().deviceId} trust ${it.toCryptoDeviceInfo().trustLevel}" }.logLimit()}") +// +// if (myCrossSigningInfo != null) { +// allDevices.any { !it.toCryptoDeviceInfo().trustLevel?.crossSigningVerified.orFalse() } +// } else { +// // Legacy method +// allDevices.any { !it.toCryptoDeviceInfo().isVerified } +// } +// } +// .let { hasWarning -> +// if (hasWarning) { +// RoomEncryptionTrustLevel.Warning +// } else { +// if (listToCheck.size == allTrustedUserIds.size) { +// // all users are trusted and all devices are verified +// RoomEncryptionTrustLevel.Trusted +// } else { +// RoomEncryptionTrustLevel.Default +// } +// } +// } +// } +// } +// +// private fun mapCrossSigningInfoEntity(xsignInfo: CrossSigningInfoEntity): MXCrossSigningInfo { +// val userId = xsignInfo.userId ?: "" +// return MXCrossSigningInfo( +// userId = userId, +// crossSigningKeys = xsignInfo.crossSigningKeys.mapNotNull { +// crossSigningKeysMapper.map(userId, it) +// } +// ) +// } +// +// override fun buildErrorParams(params: Params, message: String): Params { +// return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) +// } +// } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeysClaimResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeysClaimResponse.kt index 2dfdfe09a8..2309a7254b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeysClaimResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeysClaimResponse.kt @@ -24,8 +24,8 @@ import com.squareup.moshi.JsonClass */ @JsonClass(generateAdapter = true) internal data class KeysClaimResponse( - /// If any remote homeservers could not be reached, they are recorded here. - /// The names of the properties are the names of the unreachable servers. + // / If any remote homeservers could not be reached, they are recorded here. + // / The names of the properties are the names of the unreachable servers. @Json(name = "failures") val failures: Map, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt index 356dcd3535..a16cb11eae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt @@ -17,14 +17,11 @@ package org.matrix.android.sdk.internal.crypto.tasks import org.matrix.android.sdk.internal.crypto.api.CryptoApi -import org.matrix.android.sdk.internal.crypto.model.MXKey -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task -import timber.log.Timber import javax.inject.Inject internal interface ClaimOneTimeKeysForUsersDeviceTask : Task { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt index 7f7e89aa45..8c32466a7a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadKeysTask.kt @@ -18,8 +18,6 @@ package org.matrix.android.sdk.internal.crypto.tasks import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.crypto.api.CryptoApi -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceKeys -import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index fd407f5bae..262342b054 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -16,8 +16,6 @@ package org.matrix.android.sdk.internal.crypto.verification -import android.os.Handler -import android.os.Looper import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import kotlinx.coroutines.runBlocking @@ -30,7 +28,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent 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.OlmMachineProvider import org.matrix.android.sdk.internal.crypto.OwnUserIdentity import org.matrix.android.sdk.internal.crypto.SasVerification import org.matrix.android.sdk.internal.crypto.UserIdentity @@ -38,13 +36,15 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE import org.matrix.android.sdk.internal.crypto.model.rest.toValue +import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber +import javax.inject.Inject /** A helper class to deserialize to-device `m.key.verification.*` events to fetch the transaction id out */ @JsonClass(generateAdapter = true) internal data class ToDeviceVerificationEvent( @Json(name = "sender") val sender: String?, - @Json(name = "transaction_id") val transactionId: String, + @Json(name = "transaction_id") val transactionId: String ) /** Helper method to fetch the unique ID of the verification event */ @@ -70,61 +70,13 @@ internal fun prepareMethods(methods: List): List { return stringMethods } -/** Class that implements some common methods to dispatch updates for the verification related classes */ -internal class UpdateDispatcher(private val listeners: ArrayList) { - private val uiHandler = Handler(Looper.getMainLooper()) +@SessionScope +internal class RustVerificationService @Inject constructor(private val olmMachineProvider: OlmMachineProvider) : VerificationService { - internal fun addListener(listener: VerificationService.Listener) { - uiHandler.post { - if (!this.listeners.contains(listener)) { - this.listeners.add(listener) - } - } + val olmMachine by lazy { + olmMachineProvider.olmMachine } - internal fun removeListener(listener: VerificationService.Listener) { - uiHandler.post { this.listeners.remove(listener) } - } - - internal fun dispatchTxAdded(tx: VerificationTransaction) { - uiHandler.post { - this.listeners.forEach { - try { - it.transactionCreated(tx) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } - - internal fun dispatchTxUpdated(tx: VerificationTransaction) { - uiHandler.post { - this.listeners.forEach { - try { - it.transactionUpdated(tx) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } - - internal fun dispatchRequestAdded(tx: PendingVerificationRequest) { - Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx") - uiHandler.post { - this.listeners.forEach { - try { - it.verificationRequestCreated(tx) - } catch (e: Throwable) { - Timber.e(e, "## Error while notifying listeners") - } - } - } - } -} - -internal class RustVerificationService(private val olmMachine: OlmMachine) : VerificationService { private val dispatcher = UpdateDispatcher(this.olmMachine.verificationListeners) /** The main entry point for the verification service @@ -279,8 +231,8 @@ internal class RustVerificationService(private val olmMachine: OlmMachine) : Ver ): PendingVerificationRequest { val verification = when (val identity = runBlocking { olmMachine.getIdentity(otherUserId) }) { is OwnUserIdentity -> runBlocking { identity.requestVerification(methods) } - is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices") - null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user") + is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices") + null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user") } return verification.toPendingVerificationRequest() @@ -294,9 +246,9 @@ internal class RustVerificationService(private val olmMachine: OlmMachine) : Ver ): PendingVerificationRequest { Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") val verification = when (val identity = runBlocking { olmMachine.getIdentity(otherUserId) }) { - is UserIdentity -> runBlocking { identity.requestVerification(methods, roomId, localId!!) } + is UserIdentity -> runBlocking { identity.requestVerification(methods, roomId, localId!!) } is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user") - null -> throw IllegalArgumentException("The user that we wish to verify doesn't support cross signing") + null -> throw IllegalArgumentException("The user that we wish to verify doesn't support cross signing") } return verification.toPendingVerificationRequest() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/UpdateDispatcher.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/UpdateDispatcher.kt new file mode 100644 index 0000000000..0b2e1673ec --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/UpdateDispatcher.kt @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.verification + +import android.os.Handler +import android.os.Looper +import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction +import timber.log.Timber + +/** Class that implements some common methods to dispatch updates for the verification related classes */ +internal class UpdateDispatcher(private val listeners: ArrayList) { + private val uiHandler = Handler(Looper.getMainLooper()) + + internal fun addListener(listener: VerificationService.Listener) { + uiHandler.post { + if (!this.listeners.contains(listener)) { + this.listeners.add(listener) + } + } + } + + internal fun removeListener(listener: VerificationService.Listener) { + uiHandler.post { this.listeners.remove(listener) } + } + + internal fun dispatchTxAdded(tx: VerificationTransaction) { + uiHandler.post { + this.listeners.forEach { + try { + it.transactionCreated(tx) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + internal fun dispatchTxUpdated(tx: VerificationTransaction) { + uiHandler.post { + this.listeners.forEach { + try { + it.transactionUpdated(tx) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } + + internal fun dispatchRequestAdded(tx: PendingVerificationRequest) { + Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx") + uiHandler.post { + this.listeners.forEach { + try { + it.verificationRequestCreated(tx) + } catch (e: Throwable) { + Timber.e(e, "## Error while notifying listeners") + } + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt index 3a15e0acf0..a09189b57c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt @@ -68,7 +68,7 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa isEncrypted = roomSummaryEntity.isEncrypted, encryptionEventTs = roomSummaryEntity.encryptionEventTs, breadcrumbsIndex = roomSummaryEntity.breadcrumbsIndex, - roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel, + roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel.takeIf { roomSummaryEntity.isEncrypted }, inviterId = roomSummaryEntity.inviterId, hasFailedSending = roomSummaryEntity.hasFailedSending, roomType = roomSummaryEntity.roomType, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt index fd4b9fb209..eb325b0e28 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionComponent.kt @@ -23,9 +23,9 @@ import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.internal.crypto.CancelGossipRequestWorker import org.matrix.android.sdk.internal.crypto.CryptoModule +import org.matrix.android.sdk.internal.crypto.OlmMachineProvider import org.matrix.android.sdk.internal.crypto.SendGossipRequestWorker import org.matrix.android.sdk.internal.crypto.SendGossipWorker -import org.matrix.android.sdk.internal.crypto.crosssigning.UpdateTrustWorker import org.matrix.android.sdk.internal.di.MatrixComponent import org.matrix.android.sdk.internal.federation.FederationModule import org.matrix.android.sdk.internal.network.NetworkConnectivityChecker @@ -117,6 +117,8 @@ internal interface SessionComponent { fun taskExecutor(): TaskExecutor + fun olmMachineProvider() : OlmMachineProvider + fun inject(worker: SendEventWorker) fun inject(worker: MultipleEventSendingDispatcherWorker) @@ -137,7 +139,7 @@ internal interface SessionComponent { fun inject(worker: SendGossipWorker) - fun inject(worker: UpdateTrustWorker) +// fun inject(worker: UpdateTrustWorker) @Component.Factory interface Factory { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt index 84261e6ebf..c9d9dbdbf3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt @@ -23,8 +23,8 @@ import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.toMedium import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.util.MimeTypes -import org.matrix.android.sdk.internal.crypto.DeviceListManager import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.internal.crypto.OlmMachineProvider import org.matrix.android.sdk.internal.di.AuthenticatedIdentity import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.network.token.AccessTokenProvider @@ -39,7 +39,8 @@ import javax.inject.Inject internal class CreateRoomBodyBuilder @Inject constructor( private val ensureIdentityTokenTask: EnsureIdentityTokenTask, - private val deviceListManager: DeviceListManager, +// private val deviceListManager: DeviceListManager, + private val olmMachineProvider: OlmMachineProvider, private val identityStore: IdentityStore, private val fileUploader: FileUploader, @UserId @@ -173,14 +174,15 @@ internal class CreateRoomBodyBuilder @Inject constructor( } private suspend fun canEnableEncryption(params: CreateRoomParams): Boolean { - return params.enableEncryptionIfInvitedUsersSupportIt && + return params.enableEncryptionIfInvitedUsersSupportIt // Parity with web, enable if users have encryption ready devices // for now remove checks on cross signing and 3pid invites // && crossSigningService.isCrossSigningVerified() - params.invite3pids.isEmpty() && - params.invitedUserIds.isNotEmpty() && - params.invitedUserIds.let { userIds -> - val keys = deviceListManager.downloadKeys(userIds, forceDownload = false) + && params.invite3pids.isEmpty() + && params.invitedUserIds.isNotEmpty() + && params.invitedUserIds.let { userIds -> + val keys = olmMachineProvider.olmMachine.getUserDevicesMap(userIds) + // deviceListManager.downloadKeys(userIds, forceDownload = false) userIds.all { userId -> keys.map[userId].let { deviceMap -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 3d0f51b831..d9a9da5aff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -17,13 +17,14 @@ package org.matrix.android.sdk.internal.session.room.membership import com.zhuinden.monarchy.Monarchy +import dagger.Lazy import io.realm.Realm import io.realm.kotlin.createObject import kotlinx.coroutines.TimeoutCancellationException +import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider -import org.matrix.android.sdk.internal.crypto.DeviceListManager import org.matrix.android.sdk.internal.database.awaitNotEmptyResult import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity @@ -60,7 +61,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( private val roomSummaryUpdater: RoomSummaryUpdater, private val roomMemberEventHandler: RoomMemberEventHandler, private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, - private val deviceListManager: DeviceListManager, + private val cryptoService: Lazy, private val globalErrorReceiver: GlobalErrorReceiver ) : LoadRoomMembersTask { @@ -130,7 +131,10 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( } if (cryptoSessionInfoProvider.isRoomEncrypted(roomId)) { - deviceListManager.onRoomMembersLoadedFor(roomId) + cryptoService.get().onE2ERoomMemberLoadedFromServer(roomId) +// val userIds = cryptoSessionInfoProvider.getRoomUserIds(roomId, true) +// olmMachineProvider.olmMachine.updateTrackedUsers(userIds) +// deviceListManager.onRoomMembersLoadedFor(roomId) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 1d45c8cd5a..4298c20e58 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.room.summary import io.realm.Realm import io.realm.kotlin.createObject +import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes @@ -36,7 +37,6 @@ import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.sync.model.RoomSyncSummary import org.matrix.android.sdk.api.session.sync.model.RoomSyncUnreadNotifications import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity import org.matrix.android.sdk.internal.database.model.EventEntity @@ -71,9 +71,8 @@ internal class RoomSummaryUpdater @Inject constructor( @UserId private val userId: String, private val roomDisplayNameResolver: RoomDisplayNameResolver, private val roomAvatarResolver: RoomAvatarResolver, - private val crossSigningService: DefaultCrossSigningService, - private val roomAccountDataDataSource: RoomAccountDataDataSource, - private val normalizer: Normalizer) { + private val crossSigningService: CrossSigningService, + private val roomAccountDataDataSource: RoomAccountDataDataSource) { fun update(realm: Realm, roomId: String, @@ -168,8 +167,8 @@ internal class RoomSummaryUpdater @Inject constructor( roomSummaryEntity.otherMemberIds.clear() roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers) if (roomSummaryEntity.isEncrypted && otherRoomMembers.isNotEmpty()) { - // mmm maybe we could only refresh shield instead of checking trust also? - crossSigningService.onUsersDeviceUpdate(otherRoomMembers) + // TODO do we really need to force a shield refresh here? + // crossSigningService.ensureRoomShieldForRoom(roomId) } } } diff --git a/rust-sdk/Makefile b/rust-sdk/Makefile index 131e26bdec..1ceb1dd1c9 100644 --- a/rust-sdk/Makefile +++ b/rust-sdk/Makefile @@ -1,11 +1,19 @@ -x86_64: - cargo build --release --target x86_64-linux-android - install -D target/x86_64-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86_64/libuniffi_olm.so +# x86_64: +# cargo build --release --target x86_64-linux-android +# mkdir -p ../matrix-sdk-android/src/main/jniLibs/x86_64/ +# cp target/x86_64-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86_64/libuniffi_olm.so x86: cargo build --release --target i686-linux-android - install -D target/i686-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86/libuniffi_olm.so + mkdir -p ../matrix-sdk-android/src/main/jniLibs/x86/ + cp target/i686-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86/libuniffi_olm.so aarch64: cargo build --release --target aarch64-linux-android - install -D target/aarch64-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/arm64-v8a/libuniffi_olm.so + mkdir -p ../matrix-sdk-android/src/main/jniLibs/arm64-v8a/ + cp target/aarch64-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/arm64-v8a/libuniffi_olm.so + +armv7-linux-androideabi: + cargo build --release --target armv7-linux-androideabi + mkdir -p ../matrix-sdk-android/src/main/jniLibs/armeabi-v7a/ + cp target/armv7-linux-androideabi/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/armeabi-v7a/libuniffi_olm.so \ No newline at end of file From 9e055d97933aecebb756a42e2b33e0b2f6cbeb85 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 19 Nov 2021 15:14:04 +0100 Subject: [PATCH 176/252] post rebase fix --- .../sdk/internal/crypto/CryptoModule.kt | 7 +-- .../internal/crypto/DefaultCryptoService.kt | 47 +++---------------- .../sdk/internal/crypto/MXOlmDevice.kt | 1 + .../crypto/RustCrossSigningService.kt | 4 +- .../actions/MegolmSessionDataImporter.kt | 1 + .../crypto/algorithms/IMXDecrypting.kt | 1 + .../crypto/algorithms/IMXEncrypting.kt | 1 + .../crypto/algorithms/IMXGroupEncryption.kt | 1 + .../crypto/algorithms/IMXWithHeldExtension.kt | 1 + .../algorithms/megolm/MXMegolmEncryption.kt | 1 + .../keysbackup/DefaultKeysBackupService.kt | 1 + .../crypto/keysbackup/RustKeyBackupService.kt | 5 +- 12 files changed, 23 insertions(+), 48 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index eb898188ae..dc3b99fcb8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -24,6 +24,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.crosssigning.ComputeTrustTask import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultComputeTrustTask @@ -88,6 +89,7 @@ import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask import org.matrix.android.sdk.internal.crypto.tasks.UploadSigningKeysTask +import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import org.matrix.android.sdk.internal.database.RealmKeysUtils import org.matrix.android.sdk.internal.di.CryptoDatabase import org.matrix.android.sdk.internal.di.SessionFilesDirectory @@ -95,11 +97,6 @@ import org.matrix.android.sdk.internal.di.UserMd5 import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.cache.ClearCacheTask import org.matrix.android.sdk.internal.session.cache.RealmClearCacheTask -import io.realm.RealmConfiguration -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import org.matrix.android.sdk.api.session.crypto.verification.VerificationService -import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import retrofit2.Retrofit import java.io.File diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 021b4ff42d..526797d3be 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -20,8 +20,6 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.lifecycle.LiveData import androidx.paging.PagedList -import com.squareup.moshi.Types -import dagger.Lazy import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async @@ -39,14 +37,12 @@ import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.crypto.MXCryptoConfig import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure -import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener -import org.matrix.android.sdk.api.session.crypto.verification.VerificationService 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.EventType @@ -58,26 +54,8 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.sync.model.DeviceListResponse import org.matrix.android.sdk.api.session.sync.model.DeviceOneTimeKeysCountSyncResponse import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse -import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.auth.registration.handleUIA import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask 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.MXEncryptEventContentResult @@ -96,7 +74,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import org.matrix.android.sdk.internal.di.DeviceId -import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope @@ -152,6 +129,7 @@ internal class DefaultCryptoService @Inject constructor( private val sender: RequestSender, private val crossSigningService: CrossSigningService, private val verificationService: RustVerificationService, + private val keysBackupService: RustKeyBackupService, private val olmMachineProvider: OlmMachineProvider ) : CryptoService { @@ -165,11 +143,6 @@ internal class DefaultCryptoService @Inject constructor( // private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() - // The key backup service. - private var keysBackupService: RustKeyBackupService? = null - - private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() - // Locks for some of our operations private val keyClaimLock: Mutex = Mutex() private val outgoingRequestsLock: Mutex = Mutex() @@ -335,7 +308,6 @@ internal class DefaultCryptoService @Inject constructor( try { setRustLogger() - keysBackupService = RustKeyBackupService(machine, sender, coroutineDispatchers, cryptoCoroutineScope) Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + "${userId}, ${deviceId}, identity keys: ${this.olmMachine.identityKeys()}") @@ -346,7 +318,7 @@ internal class DefaultCryptoService @Inject constructor( // We try to enable key backups, if the backup version on the server is trusted, // we're gonna continue backing up. tryOrNull { - keysBackupService!!.checkAndStartKeysBackup() + keysBackupService.checkAndStartKeysBackup() } // Open the store @@ -370,12 +342,7 @@ internal class DefaultCryptoService @Inject constructor( /** * @return the Keys backup Service */ - override fun keysBackupService(): KeysBackupService { - if (keysBackupService == null) { - internalStart() - } - return keysBackupService!! - } + override fun keysBackupService() = keysBackupService /** * @return the VerificationService @@ -400,7 +367,7 @@ internal class DefaultCryptoService @Inject constructor( // This could be omitted but then devices might be waiting for the next sendOutgoingRequests() - keysBackupService?.maybeBackupKeys() + keysBackupService.maybeBackupKeys() } cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { @@ -431,7 +398,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getCryptoDeviceInfo(userId: String): List { return runBlocking { - this@DefaultCryptoService.olmMachine.getCryptoDeviceInfo(userId) ?: listOf() + this@DefaultCryptoService.olmMachine.getCryptoDeviceInfo(userId) } } @@ -633,6 +600,7 @@ internal class DefaultCryptoService @Inject constructor( olmMachine.updateTrackedUsers(userIds) } } + private fun getRoomUserIds(roomId: String): List { val encryptForInvitedMembers = isEncryptionEnabledForInvitedUser() && shouldEncryptForInvitedMembers(roomId) @@ -726,7 +694,7 @@ internal class DefaultCryptoService @Inject constructor( notifyRoomKeyReceived(roomId, sessionId) } - EventType.SEND_SECRET -> { + EventType.SEND_SECRET -> { // The rust-sdk will clear this event if it's invalid, this will produce an invalid base64 error // when we try to construct the recovery key. val secretContent = event.getClearContent().toModel() ?: return@forEach @@ -808,7 +776,6 @@ internal class DefaultCryptoService @Inject constructor( cryptoSessionInfoProvider.updateShieldForRoom(roomId, shield) } } - } catch (throwable: Throwable) { Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 441dfe4a5d..7a3ae7c1b9 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -41,6 +41,7 @@ import java.net.URLEncoder import javax.inject.Inject // The libolm wrapper. +@Deprecated("rust") @SessionScope internal class MXOlmDevice @Inject constructor( /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index bf5d0eca9e..4c9d62f610 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -30,18 +30,18 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustResult import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo -import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.extensions.foldToCallback import javax.inject.Inject internal class RustCrossSigningService @Inject constructor( - @SessionId private val sessionId: String, +// @SessionId private val sessionId: String, @UserId private val myUserId: String, private val olmMachineProvider: OlmMachineProvider ) : CrossSigningService { val olmMachine = olmMachineProvider.olmMachine + /** * Is our own device signed by our own cross signing identity */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt index 0d78f68e5c..e0748a0d1f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt @@ -28,6 +28,7 @@ import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import timber.log.Timber import javax.inject.Inject +@Deprecated("rust") internal class MegolmSessionDataImporter @Inject constructor(private val olmDevice: MXOlmDevice, private val roomDecryptorProvider: RoomDecryptorProvider, private val outgoingGossipingRequestManager: OutgoingGossipingRequestManager, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt index 79c7608cbf..b9cfd942ce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt @@ -26,6 +26,7 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupServic /** * An interface for decrypting data */ +@Deprecated("rust") internal interface IMXDecrypting { /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt index 5294429198..b0f411cbcc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt @@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.session.events.model.Content /** * An interface for encrypting data */ +@Deprecated("rust") internal interface IMXEncrypting { /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt index 1fd5061a65..7d191861e7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto.algorithms +@Deprecated("rust") internal interface IMXGroupEncryption { /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXWithHeldExtension.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXWithHeldExtension.kt index 91f10adf4c..7a03217ea5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXWithHeldExtension.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXWithHeldExtension.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto.algorithms import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent +@Deprecated("rust") internal interface IMXWithHeldExtension { fun onRoomKeyWithHeldEvent(withHeldInfo: RoomKeyWithHeldContent) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index 031bb4e194..5e748d3739 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -43,6 +43,7 @@ import org.matrix.android.sdk.internal.util.JsonCanonicalizer import org.matrix.android.sdk.internal.util.convertToUTF8 import timber.log.Timber +@Deprecated("in favour of rust") internal class MXMegolmEncryption( // The id of the room we will be sending to. private val roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index b20168eaa3..b0c7c8b610 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -99,6 +99,7 @@ import kotlin.random.Random * to the user's homeserver. */ @SessionScope +@Deprecated("use rust") internal class DefaultKeysBackupService @Inject constructor( @UserId private val userId: String, private val credentials: Credentials, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 3b9ce5b67e..0ec13ced19 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -38,6 +38,7 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListe import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP import org.matrix.android.sdk.internal.crypto.MegolmSessionData import org.matrix.android.sdk.internal.crypto.OlmMachine +import org.matrix.android.sdk.internal.crypto.OlmMachineProvider import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData @@ -71,7 +72,7 @@ import kotlin.random.Random */ @SessionScope internal class RustKeyBackupService @Inject constructor( - private val olmMachine: OlmMachine, + olmMachineProvider: OlmMachineProvider, private val sender: RequestSender, private val coroutineDispatchers: MatrixCoroutineDispatchers, private val cryptoCoroutineScope: CoroutineScope, @@ -85,6 +86,8 @@ internal class RustKeyBackupService @Inject constructor( private val keysBackupStateManager = KeysBackupStateManager(uiHandler) + private val olmMachine = olmMachineProvider.olmMachine + // The backup version override var keysBackupVersion: KeysVersionResult? = null private set From c01998ddd32a4dc445759db4382d5f85f981296b Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 19 Nov 2021 15:16:29 +0100 Subject: [PATCH 177/252] Cleaning --- .../crypto/crosssigning/CrossSigningService.kt | 2 +- .../sdk/internal/crypto/DefaultCryptoService.kt | 13 ++++++------- .../matrix/android/sdk/internal/crypto/Device.kt | 2 +- .../android/sdk/internal/crypto/OlmMachine.kt | 2 -- .../sdk/internal/crypto/QrCodeVerification.kt | 3 +-- .../android/sdk/internal/crypto/RequestSender.kt | 8 ++++---- .../crypto/keysbackup/RustKeyBackupService.kt | 1 - .../crypto/verification/VerificationInfoStart.kt | 4 ++-- .../sdk/internal/session/SessionComponent.kt | 2 +- .../session/room/create/CreateRoomBodyBuilder.kt | 8 ++++---- .../session/room/summary/RoomSummaryUpdater.kt | 1 - .../app/features/navigation/DefaultNavigator.kt | 1 - 12 files changed, 20 insertions(+), 27 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index c226e4aa92..7c3a0101c8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -105,7 +105,7 @@ interface CrossSigningService { fun trustDevice(deviceId: String, callback: MatrixCallback) - suspend fun shieldForGroup(userIds: List) : RoomEncryptionTrustLevel + suspend fun shieldForGroup(userIds: List): RoomEncryptionTrustLevel /** * Check if a device is trusted diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 526797d3be..a87d2483e0 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -41,7 +41,6 @@ import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event @@ -310,7 +309,7 @@ internal class DefaultCryptoService @Inject constructor( setRustLogger() Timber.v( "## CRYPTO | Successfully started up an Olm machine for " + - "${userId}, ${deviceId}, identity keys: ${this.olmMachine.identityKeys()}") + "$userId, $deviceId, identity keys: ${this.olmMachine.identityKeys()}") } catch (throwable: Throwable) { Timber.v("Failed create an Olm machine: $throwable") } @@ -408,7 +407,7 @@ internal class DefaultCryptoService @Inject constructor( override fun getLiveCryptoDeviceInfo(userIds: List): LiveData> { return runBlocking { - this@DefaultCryptoService.olmMachine.getLiveDevices(userIds) //?: LiveDevice(userIds, deviceObserver) + this@DefaultCryptoService.olmMachine.getLiveDevices(userIds) // ?: LiveDevice(userIds, deviceObserver) } } @@ -626,9 +625,9 @@ internal class DefaultCryptoService @Inject constructor( cryptoCoroutineScope.launch { olmMachine.updateTrackedUsers(listOf(userId)) } - } else if (membership == Membership.INVITE - && shouldEncryptForInvitedMembers(roomId) - && isEncryptionEnabledForInvitedUser()) { + } else if (membership == Membership.INVITE && + shouldEncryptForInvitedMembers(roomId) && + isEncryptionEnabledForInvitedUser()) { // track the deviceList for this invited user. // Caution: there's a big edge case here in that federated servers do not // know what other servers are in the room at the time they've been invited. @@ -1010,7 +1009,7 @@ internal class DefaultCryptoService @Inject constructor( // where we would download the fresh info from the server. this@DefaultCryptoService.olmMachine.getUserDevicesMap(userIds) // ?: MXUsersDevicesMap() } else { - this@DefaultCryptoService.olmMachine.getUserDevicesMap(userIds) //?: MXUsersDevicesMap() + this@DefaultCryptoService.olmMachine.getUserDevicesMap(userIds) // ?: MXUsersDevicesMap() } }.foldToCallback(callback) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index dfe1994d9d..9ef3cb200a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -25,10 +25,10 @@ import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo import org.matrix.android.sdk.internal.crypto.verification.prepareMethods import uniffi.olm.CryptoStoreException -import uniffi.olm.Device as InnerDevice import uniffi.olm.OlmMachine import uniffi.olm.SignatureException import uniffi.olm.VerificationRequest +import uniffi.olm.Device as InnerDevice /** Class representing a device that supports E2EE in the Matrix world * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 8f213ee5d8..710490b372 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -22,7 +22,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor -import org.matrix.android.sdk.api.extensions.orFalse 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.crosssigning.MXCrossSigningInfo @@ -771,7 +770,6 @@ internal class OlmMachine( suspend fun exportCrossSigningKeys(): PrivateKeysInfo? { val export = withContext(Dispatchers.IO) { inner.exportCrossSigningKeys() - } ?: return null return PrivateKeysInfo(export.masterKey, export.selfSigningKey, export.userSigningKey) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index 278c3fec5f..e61c5c8f8f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -174,8 +174,7 @@ internal class QrCodeVerification( */ @Throws(CryptoStoreException::class) private suspend fun confirm() { - val result = withContext(Dispatchers.IO) - { + val result = withContext(Dispatchers.IO) { machine.confirmVerification(request.otherUser(), request.flowId()) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt index d0711567cf..a0e3ea835c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt @@ -168,8 +168,8 @@ internal class RequestSender @Inject constructor( try { uploadSigningKeysTask.execute(uploadSigningKeysParams) } catch (failure: Throwable) { - if (interactiveAuthInterceptor == null - || !handleUIA( + if (interactiveAuthInterceptor == null || + !handleUIA( failure = failure, interceptor = interactiveAuthInterceptor, retryBlock = { authUpdate -> @@ -218,8 +218,8 @@ internal class RequestSender @Inject constructor( getKeysBackupLastVersionTask.execute(Unit) } } catch (failure: Throwable) { - if (failure is Failure.ServerError - && failure.error.code == MatrixError.M_NOT_FOUND) { + if (failure is Failure.ServerError && + failure.error.code == MatrixError.M_NOT_FOUND) { null } else { throw failure diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 0ec13ced19..35b7711027 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -37,7 +37,6 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP import org.matrix.android.sdk.internal.crypto.MegolmSessionData -import org.matrix.android.sdk.internal.crypto.OlmMachine import org.matrix.android.sdk.internal.crypto.OlmMachineProvider import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt index 04699c1395..6713b5a16a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt @@ -73,8 +73,8 @@ internal interface VerificationInfoStart : VerificationInfo + params.invite3pids.isEmpty() && + params.invitedUserIds.isNotEmpty() && + params.invitedUserIds.let { userIds -> val keys = olmMachineProvider.olmMachine.getUserDevicesMap(userIds) // deviceListManager.downloadKeys(userIds, forceDownload = false) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 4298c20e58..81484a098b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -62,7 +62,6 @@ import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataD import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.room.relationship.RoomChildRelationInfo -import org.matrix.android.sdk.internal.util.Normalizer import timber.log.Timber import javax.inject.Inject import kotlin.system.measureTimeMillis diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 1716067700..36b72f5d96 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -88,7 +88,6 @@ import im.vector.app.features.widgets.WidgetActivity import im.vector.app.features.widgets.WidgetArgsBuilder import im.vector.app.space import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.terms.TermsService From a5c500cccd007306b2bf5b7f6531e31217f722e7 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 19 Nov 2021 15:27:47 +0100 Subject: [PATCH 178/252] Cleaning + fix copyright --- .../sdk/internal/crypto/OlmMachineProvider.kt | 2 +- .../sdk/internal/crypto/RequestSender.kt | 2 +- .../DefaultCrossSigningService.kt | 807 ------------------ .../crypto/crosssigning/UpdateTrustWorker.kt | 389 --------- .../crypto/keysbackup/RustKeyBackupService.kt | 2 +- .../crypto/verification/UpdateDispatcher.kt | 2 +- 6 files changed, 4 insertions(+), 1200 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt index f2de3b3724..441fe5acd0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt index a0e3ea835c..6ce0fea71e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt deleted file mode 100644 index 64b423cca7..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt +++ /dev/null @@ -1,807 +0,0 @@ -// /* -// * Copyright 2020 The Matrix.org Foundation C.I.C. -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ -// -// package org.matrix.android.sdk.internal.crypto.crosssigning -// -// import androidx.lifecycle.LiveData -// import androidx.work.BackoffPolicy -// import androidx.work.ExistingWorkPolicy -// import kotlinx.coroutines.CoroutineScope -// import kotlinx.coroutines.launch -// import org.matrix.android.sdk.api.MatrixCallback -// import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor -// import org.matrix.android.sdk.api.extensions.orFalse -// import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService -// import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo -// import org.matrix.android.sdk.api.util.Optional -// import org.matrix.android.sdk.internal.crypto.DeviceListManager -// import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -// import org.matrix.android.sdk.internal.crypto.model.rest.UploadSignatureQueryBuilder -// import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -// import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo -// import org.matrix.android.sdk.internal.crypto.tasks.InitializeCrossSigningTask -// import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask -// import org.matrix.android.sdk.internal.di.SessionId -// import org.matrix.android.sdk.internal.di.UserId -// import org.matrix.android.sdk.internal.di.WorkManagerProvider -// import org.matrix.android.sdk.internal.session.SessionScope -// import org.matrix.android.sdk.internal.task.TaskExecutor -// import org.matrix.android.sdk.internal.task.TaskThread -// import org.matrix.android.sdk.internal.task.configureWith -// import org.matrix.android.sdk.internal.util.JsonCanonicalizer -// import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers -// import org.matrix.android.sdk.internal.util.logLimit -// import org.matrix.android.sdk.internal.worker.WorkerParamsFactory -// import org.matrix.olm.OlmPkSigning -// import org.matrix.olm.OlmUtility -// import timber.log.Timber -// import java.util.concurrent.TimeUnit -// import javax.inject.Inject -// -// @SessionScope -// internal class DefaultCrossSigningService @Inject constructor( -// @UserId private val userId: String, -// @SessionId private val sessionId: String, -// private val cryptoStore: IMXCryptoStore, -// private val deviceListManager: DeviceListManager, -// private val initializeCrossSigningTask: InitializeCrossSigningTask, -// private val uploadSignaturesTask: UploadSignaturesTask, -// private val taskExecutor: TaskExecutor, -// private val coroutineDispatchers: MatrixCoroutineDispatchers, -// private val cryptoCoroutineScope: CoroutineScope, -// private val workManagerProvider: WorkManagerProvider, -// private val updateTrustWorkerDataRepository: UpdateTrustWorkerDataRepository -// ) : CrossSigningService, -// DeviceListManager.UserDevicesUpdateListener { -// -// private var olmUtility: OlmUtility? = null -// -// private var masterPkSigning: OlmPkSigning? = null -// private var userPkSigning: OlmPkSigning? = null -// private var selfSigningPkSigning: OlmPkSigning? = null -// -// init { -// try { -// olmUtility = OlmUtility() -// -// // Try to get stored keys if they exist -// cryptoStore.getMyCrossSigningInfo()?.let { mxCrossSigningInfo -> -// Timber.i("## CrossSigning - Found Existing self signed keys") -// Timber.i("## CrossSigning - Checking if private keys are known") -// -// cryptoStore.getCrossSigningPrivateKeys()?.let { privateKeysInfo -> -// privateKeysInfo.master -// ?.fromBase64() -// ?.let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { -// masterPkSigning = pkSigning -// Timber.i("## CrossSigning - Loading master key success") -// } else { -// Timber.w("## CrossSigning - Public master key does not match the private key") -// pkSigning.releaseSigning() -// // TODO untrust? -// } -// } -// privateKeysInfo.user -// ?.fromBase64() -// ?.let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { -// userPkSigning = pkSigning -// Timber.i("## CrossSigning - Loading User Signing key success") -// } else { -// Timber.w("## CrossSigning - Public User key does not match the private key") -// pkSigning.releaseSigning() -// // TODO untrust? -// } -// } -// privateKeysInfo.selfSigned -// ?.fromBase64() -// ?.let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { -// selfSigningPkSigning = pkSigning -// Timber.i("## CrossSigning - Loading Self Signing key success") -// } else { -// Timber.w("## CrossSigning - Public Self Signing key does not match the private key") -// pkSigning.releaseSigning() -// // TODO untrust? -// } -// } -// } -// -// // Recover local trust in case private key are there? -// setUserKeysAsTrusted(userId, checkUserTrust(userId).isVerified()) -// } -// } catch (e: Throwable) { -// // Mmm this kind of a big issue -// Timber.e(e, "Failed to initialize Cross Signing") -// } -// -// deviceListManager.addListener(this) -// } -// -// fun release() { -// olmUtility?.releaseUtility() -// listOf(masterPkSigning, userPkSigning, selfSigningPkSigning).forEach { it?.releaseSigning() } -// deviceListManager.removeListener(this) -// } -// -// protected fun finalize() { -// release() -// } -// -// /** -// * - Make 3 key pairs (MSK, USK, SSK) -// * - Save the private keys with proper security -// * - Sign the keys and upload them -// * - Sign the current device with SSK and sign MSK with device key (migration) and upload signatures -// */ -// override fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?, callback: MatrixCallback) { -// Timber.d("## CrossSigning initializeCrossSigning") -// -// val params = InitializeCrossSigningTask.Params( -// interactiveAuthInterceptor = uiaInterceptor -// ) -// initializeCrossSigningTask.configureWith(params) { -// this.callbackThread = TaskThread.CRYPTO -// this.callback = object : MatrixCallback { -// override fun onFailure(failure: Throwable) { -// Timber.e(failure, "Error in initializeCrossSigning()") -// callback.onFailure(failure) -// } -// -// override fun onSuccess(data: InitializeCrossSigningTask.Result) { -// val crossSigningInfo = MXCrossSigningInfo(userId, listOf(data.masterKeyInfo, data.userKeyInfo, data.selfSignedKeyInfo)) -// cryptoStore.setMyCrossSigningInfo(crossSigningInfo) -// setUserKeysAsTrusted(userId, true) -// cryptoStore.storePrivateKeysInfo(data.masterKeyPK, data.userKeyPK, data.selfSigningKeyPK) -// masterPkSigning = OlmPkSigning().apply { initWithSeed(data.masterKeyPK.fromBase64()) } -// userPkSigning = OlmPkSigning().apply { initWithSeed(data.userKeyPK.fromBase64()) } -// selfSigningPkSigning = OlmPkSigning().apply { initWithSeed(data.selfSigningKeyPK.fromBase64()) } -// -// callback.onSuccess(Unit) -// } -// } -// }.executeBy(taskExecutor) -// } -// -// override fun onSecretMSKGossip(mskPrivateKey: String) { -// Timber.i("## CrossSigning - onSecretSSKGossip") -// val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { -// Timber.e("## CrossSigning - onSecretMSKGossip() received secret but public key is not known") -// } -// -// mskPrivateKey.fromBase64() -// .let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// try { -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { -// masterPkSigning?.releaseSigning() -// masterPkSigning = pkSigning -// Timber.i("## CrossSigning - Loading MSK success") -// cryptoStore.storeMSKPrivateKey(mskPrivateKey) -// return -// } else { -// Timber.e("## CrossSigning - onSecretMSKGossip() private key do not match public key") -// pkSigning.releaseSigning() -// } -// } catch (failure: Throwable) { -// Timber.e("## CrossSigning - onSecretMSKGossip() ${failure.localizedMessage}") -// pkSigning.releaseSigning() -// } -// } -// } -// -// override fun onSecretSSKGossip(sskPrivateKey: String) { -// Timber.i("## CrossSigning - onSecretSSKGossip") -// val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { -// Timber.e("## CrossSigning - onSecretSSKGossip() received secret but public key is not known") -// } -// -// sskPrivateKey.fromBase64() -// .let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// try { -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { -// selfSigningPkSigning?.releaseSigning() -// selfSigningPkSigning = pkSigning -// Timber.i("## CrossSigning - Loading SSK success") -// cryptoStore.storeSSKPrivateKey(sskPrivateKey) -// return -// } else { -// Timber.e("## CrossSigning - onSecretSSKGossip() private key do not match public key") -// pkSigning.releaseSigning() -// } -// } catch (failure: Throwable) { -// Timber.e("## CrossSigning - onSecretSSKGossip() ${failure.localizedMessage}") -// pkSigning.releaseSigning() -// } -// } -// } -// -// override fun onSecretUSKGossip(uskPrivateKey: String) { -// Timber.i("## CrossSigning - onSecretUSKGossip") -// val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { -// Timber.e("## CrossSigning - onSecretUSKGossip() received secret but public key is not knwow ") -// } -// -// uskPrivateKey.fromBase64() -// .let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// try { -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { -// userPkSigning?.releaseSigning() -// userPkSigning = pkSigning -// Timber.i("## CrossSigning - Loading USK success") -// cryptoStore.storeUSKPrivateKey(uskPrivateKey) -// return -// } else { -// Timber.e("## CrossSigning - onSecretUSKGossip() private key do not match public key") -// pkSigning.releaseSigning() -// } -// } catch (failure: Throwable) { -// pkSigning.releaseSigning() -// } -// } -// } -// -// override fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, -// uskKeyPrivateKey: String?, -// sskPrivateKey: String? -// ): UserTrustResult { -// val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return UserTrustResult.CrossSigningNotConfigured(userId) -// -// var masterKeyIsTrusted = false -// var userKeyIsTrusted = false -// var selfSignedKeyIsTrusted = false -// -// masterKeyPrivateKey?.fromBase64() -// ?.let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// try { -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { -// masterPkSigning?.releaseSigning() -// masterPkSigning = pkSigning -// masterKeyIsTrusted = true -// Timber.i("## CrossSigning - Loading master key success") -// } else { -// pkSigning.releaseSigning() -// } -// } catch (failure: Throwable) { -// pkSigning.releaseSigning() -// } -// } -// -// uskKeyPrivateKey?.fromBase64() -// ?.let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// try { -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.userKey()?.unpaddedBase64PublicKey) { -// userPkSigning?.releaseSigning() -// userPkSigning = pkSigning -// userKeyIsTrusted = true -// Timber.i("## CrossSigning - Loading master key success") -// } else { -// pkSigning.releaseSigning() -// } -// } catch (failure: Throwable) { -// pkSigning.releaseSigning() -// } -// } -// -// sskPrivateKey?.fromBase64() -// ?.let { privateKeySeed -> -// val pkSigning = OlmPkSigning() -// try { -// if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.selfSigningKey()?.unpaddedBase64PublicKey) { -// selfSigningPkSigning?.releaseSigning() -// selfSigningPkSigning = pkSigning -// selfSignedKeyIsTrusted = true -// Timber.i("## CrossSigning - Loading master key success") -// } else { -// pkSigning.releaseSigning() -// } -// } catch (failure: Throwable) { -// pkSigning.releaseSigning() -// } -// } -// -// if (!masterKeyIsTrusted || !userKeyIsTrusted || !selfSignedKeyIsTrusted) { -// return UserTrustResult.KeysNotTrusted(mxCrossSigningInfo) -// } else { -// cryptoStore.markMyMasterKeyAsLocallyTrusted(true) -// val checkSelfTrust = checkSelfTrust() -// if (checkSelfTrust.isVerified()) { -// cryptoStore.storePrivateKeysInfo(masterKeyPrivateKey, uskKeyPrivateKey, sskPrivateKey) -// setUserKeysAsTrusted(userId, true) -// } -// return checkSelfTrust -// } -// } -// -// /** -// * -// * ┏━━━━━━━━┓ ┏━━━━━━━━┓ -// * ┃ ALICE ┃ ┃ BOB ┃ -// * ┗━━━━━━━━┛ ┗━━━━━━━━┛ -// * MSK ┌────────────▶ MSK -// * │ -// * │ │ -// * │ SSK │ -// * │ │ -// * │ │ -// * └──▶ USK ────────────┘ -// */ -// override fun isUserTrusted(otherUserId: String): Boolean { -// return cryptoStore.getCrossSigningInfo(userId)?.isTrusted() == true -// } -// -// override fun isCrossSigningVerified(): Boolean { -// return checkSelfTrust().isVerified() -// } -// -// /** -// * Will not force a download of the key, but will verify signatures trust chain -// */ -// override fun checkUserTrust(otherUserId: String): UserTrustResult { -// Timber.v("## CrossSigning checkUserTrust for $otherUserId") -// if (otherUserId == userId) { -// return checkSelfTrust() -// } -// // I trust a user if I trust his master key -// // I can trust the master key if it is signed by my user key -// // TODO what if the master key is signed by a device key that i have verified -// -// // First let's get my user key -// val myCrossSigningInfo = cryptoStore.getCrossSigningInfo(userId) -// -// checkOtherMSKTrusted(myCrossSigningInfo, cryptoStore.getCrossSigningInfo(otherUserId)) -// -// return UserTrustResult.Success -// } -// -// fun checkOtherMSKTrusted(myCrossSigningInfo: MXCrossSigningInfo?, otherInfo: MXCrossSigningInfo?): UserTrustResult { -// val myUserKey = myCrossSigningInfo?.userKey() -// ?: return UserTrustResult.CrossSigningNotConfigured(userId) -// -// if (!myCrossSigningInfo.isTrusted()) { -// return UserTrustResult.KeysNotTrusted(myCrossSigningInfo) -// } -// -// // Let's get the other user master key -// val otherMasterKey = otherInfo?.masterKey() -// ?: return UserTrustResult.UnknownCrossSignatureInfo(otherInfo?.userId ?: "") -// -// val masterKeySignaturesMadeByMyUserKey = otherMasterKey.signatures -// ?.get(userId) // Signatures made by me -// ?.get("ed25519:${myUserKey.unpaddedBase64PublicKey}") -// -// if (masterKeySignaturesMadeByMyUserKey.isNullOrBlank()) { -// Timber.d("## CrossSigning checkUserTrust false for ${otherInfo.userId}, not signed by my UserSigningKey") -// return UserTrustResult.KeyNotSigned(otherMasterKey) -// } -// -// // Check that Alice USK signature of Bob MSK is valid -// try { -// olmUtility!!.verifyEd25519Signature(masterKeySignaturesMadeByMyUserKey, myUserKey.unpaddedBase64PublicKey, otherMasterKey.canonicalSignable()) -// } catch (failure: Throwable) { -// return UserTrustResult.InvalidSignature(myUserKey, masterKeySignaturesMadeByMyUserKey) -// } -// -// return UserTrustResult.Success -// } -// -// private fun checkSelfTrust(): UserTrustResult { -// // Special case when it's me, -// // I have to check that MSK -> USK -> SSK -// // and that MSK is trusted (i know the private key, or is signed by a trusted device) -// val myCrossSigningInfo = cryptoStore.getCrossSigningInfo(userId) -// -// return checkSelfTrust(myCrossSigningInfo, cryptoStore.getUserDeviceList(userId)) -// } -// -// fun checkSelfTrust(myCrossSigningInfo: MXCrossSigningInfo?, myDevices: List?): UserTrustResult { -// // Special case when it's me, -// // I have to check that MSK -> USK -> SSK -// // and that MSK is trusted (i know the private key, or is signed by a trusted device) -// // val myCrossSigningInfo = cryptoStore.getCrossSigningInfo(userId) -// -// val myMasterKey = myCrossSigningInfo?.masterKey() -// ?: return UserTrustResult.CrossSigningNotConfigured(userId) -// -// // Is the master key trusted -// // 1) check if I know the private key -// val masterPrivateKey = cryptoStore.getCrossSigningPrivateKeys() -// ?.master -// ?.fromBase64() -// -// var isMaterKeyTrusted = false -// if (myMasterKey.trustLevel?.locallyVerified == true) { -// isMaterKeyTrusted = true -// } else if (masterPrivateKey != null) { -// // Check if private match public -// var olmPkSigning: OlmPkSigning? = null -// try { -// olmPkSigning = OlmPkSigning() -// val expectedPK = olmPkSigning.initWithSeed(masterPrivateKey) -// isMaterKeyTrusted = myMasterKey.unpaddedBase64PublicKey == expectedPK -// } catch (failure: Throwable) { -// Timber.e(failure) -// } -// olmPkSigning?.releaseSigning() -// } else { -// // Maybe it's signed by a locally trusted device? -// myMasterKey.signatures?.get(userId)?.forEach { (key, value) -> -// val potentialDeviceId = key.removePrefix("ed25519:") -// val potentialDevice = myDevices?.firstOrNull { it.deviceId == potentialDeviceId } // cryptoStore.getUserDevice(userId, potentialDeviceId) -// if (potentialDevice != null && potentialDevice.isVerified) { -// // Check signature validity? -// try { -// olmUtility?.verifyEd25519Signature(value, potentialDevice.fingerprint(), myMasterKey.canonicalSignable()) -// isMaterKeyTrusted = true -// return@forEach -// } catch (failure: Throwable) { -// // log -// Timber.w(failure, "Signature not valid?") -// } -// } -// } -// } -// -// if (!isMaterKeyTrusted) { -// return UserTrustResult.KeysNotTrusted(myCrossSigningInfo) -// } -// -// val myUserKey = myCrossSigningInfo.userKey() -// ?: return UserTrustResult.CrossSigningNotConfigured(userId) -// -// val userKeySignaturesMadeByMyMasterKey = myUserKey.signatures -// ?.get(userId) // Signatures made by me -// ?.get("ed25519:${myMasterKey.unpaddedBase64PublicKey}") -// -// if (userKeySignaturesMadeByMyMasterKey.isNullOrBlank()) { -// Timber.d("## CrossSigning checkUserTrust false for $userId, USK not signed by MSK") -// return UserTrustResult.KeyNotSigned(myUserKey) -// } -// -// // Check that Alice USK signature of Alice MSK is valid -// try { -// olmUtility!!.verifyEd25519Signature(userKeySignaturesMadeByMyMasterKey, myMasterKey.unpaddedBase64PublicKey, myUserKey.canonicalSignable()) -// } catch (failure: Throwable) { -// return UserTrustResult.InvalidSignature(myUserKey, userKeySignaturesMadeByMyMasterKey) -// } -// -// val mySSKey = myCrossSigningInfo.selfSigningKey() -// ?: return UserTrustResult.CrossSigningNotConfigured(userId) -// -// val ssKeySignaturesMadeByMyMasterKey = mySSKey.signatures -// ?.get(userId) // Signatures made by me -// ?.get("ed25519:${myMasterKey.unpaddedBase64PublicKey}") -// -// if (ssKeySignaturesMadeByMyMasterKey.isNullOrBlank()) { -// Timber.d("## CrossSigning checkUserTrust false for $userId, SSK not signed by MSK") -// return UserTrustResult.KeyNotSigned(mySSKey) -// } -// -// // Check that Alice USK signature of Alice MSK is valid -// try { -// olmUtility!!.verifyEd25519Signature(ssKeySignaturesMadeByMyMasterKey, myMasterKey.unpaddedBase64PublicKey, mySSKey.canonicalSignable()) -// } catch (failure: Throwable) { -// return UserTrustResult.InvalidSignature(mySSKey, ssKeySignaturesMadeByMyMasterKey) -// } -// -// return UserTrustResult.Success -// } -// -// override fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? { -// return cryptoStore.getCrossSigningInfo(otherUserId) -// } -// -// override fun getLiveCrossSigningKeys(userId: String): LiveData> { -// return cryptoStore.getLiveCrossSigningInfo(userId) -// } -// -// override fun getMyCrossSigningKeys(): MXCrossSigningInfo? { -// return cryptoStore.getMyCrossSigningInfo() -// } -// -// override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? { -// return cryptoStore.getCrossSigningPrivateKeys() -// } -// -// override fun getLiveCrossSigningPrivateKeys(): LiveData> { -// return cryptoStore.getLiveCrossSigningPrivateKeys() -// } -// -// override fun canCrossSign(): Boolean { -// return checkSelfTrust().isVerified() && cryptoStore.getCrossSigningPrivateKeys()?.selfSigned != null -// && cryptoStore.getCrossSigningPrivateKeys()?.user != null -// } -// -// override fun allPrivateKeysKnown(): Boolean { -// return checkSelfTrust().isVerified() -// && cryptoStore.getCrossSigningPrivateKeys()?.allKnown().orFalse() -// } -// -// override fun trustUser(otherUserId: String, callback: MatrixCallback) { -// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// Timber.d("## CrossSigning - Mark user $userId as trusted ") -// // We should have this user keys -// val otherMasterKeys = getUserCrossSigningKeys(otherUserId)?.masterKey() -// if (otherMasterKeys == null) { -// callback.onFailure(Throwable("## CrossSigning - Other master signing key is not known")) -// return@launch -// } -// val myKeys = getUserCrossSigningKeys(userId) -// if (myKeys == null) { -// callback.onFailure(Throwable("## CrossSigning - CrossSigning is not setup for this account")) -// return@launch -// } -// val userPubKey = myKeys.userKey()?.unpaddedBase64PublicKey -// if (userPubKey == null || userPkSigning == null) { -// callback.onFailure(Throwable("## CrossSigning - Cannot sign from this account, privateKeyUnknown $userPubKey")) -// return@launch -// } -// -// // Sign the other MasterKey with our UserSigning key -// val newSignature = JsonCanonicalizer.getCanonicalJson(Map::class.java, -// otherMasterKeys.signalableJSONDictionary()).let { userPkSigning?.sign(it) } -// -// if (newSignature == null) { -// // race?? -// callback.onFailure(Throwable("## CrossSigning - Failed to sign")) -// return@launch -// } -// -// cryptoStore.setUserKeysAsTrusted(otherUserId, true) -// // TODO update local copy with new signature directly here? kind of local echo of trust? -// -// Timber.d("## CrossSigning - Upload signature of $userId MSK signed by USK") -// val uploadQuery = UploadSignatureQueryBuilder() -// .withSigningKeyInfo(otherMasterKeys.copyForSignature(userId, userPubKey, newSignature)) -// .build() -// uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadQuery)) { -// this.executionThread = TaskThread.CRYPTO -// this.callback = callback -// }.executeBy(taskExecutor) -// } -// } -// -// override fun markMyMasterKeyAsTrusted() { -// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// cryptoStore.markMyMasterKeyAsLocallyTrusted(true) -// checkSelfTrust() -// // re-verify all trusts -// onUsersDeviceUpdate(listOf(userId)) -// } -// } -// -// override fun trustDevice(deviceId: String, callback: MatrixCallback) { -// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// // This device should be yours -// val device = cryptoStore.getUserDevice(userId, deviceId) -// if (device == null) { -// callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known, or not yours")) -// return@launch -// } -// -// val myKeys = getUserCrossSigningKeys(userId) -// if (myKeys == null) { -// callback.onFailure(Throwable("CrossSigning is not setup for this account")) -// return@launch -// } -// -// val ssPubKey = myKeys.selfSigningKey()?.unpaddedBase64PublicKey -// if (ssPubKey == null || selfSigningPkSigning == null) { -// callback.onFailure(Throwable("Cannot sign from this account, public and/or privateKey Unknown $ssPubKey")) -// return@launch -// } -// -// // Sign with self signing -// val newSignature = selfSigningPkSigning?.sign(device.canonicalSignable()) -// -// if (newSignature == null) { -// // race?? -// callback.onFailure(Throwable("Failed to sign")) -// return@launch -// } -// val toUpload = device.copy( -// signatures = mapOf( -// userId -// to -// mapOf( -// "ed25519:$ssPubKey" to newSignature -// ) -// ) -// ) -// -// val uploadQuery = UploadSignatureQueryBuilder() -// .withDeviceInfo(toUpload) -// .build() -// uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadQuery)) { -// this.executionThread = TaskThread.CRYPTO -// this.callback = callback -// }.executeBy(taskExecutor) -// } -// } -// -// override fun checkDeviceTrust(otherUserId: String, otherDeviceId: String, locallyTrusted: Boolean?): DeviceTrustResult { -// val otherDevice = cryptoStore.getUserDevice(otherUserId, otherDeviceId) -// ?: return DeviceTrustResult.UnknownDevice(otherDeviceId) -// -// val myKeys = getUserCrossSigningKeys(userId) -// ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(userId)) -// -// if (!myKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(myKeys)) -// -// val otherKeys = getUserCrossSigningKeys(otherUserId) -// ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(otherUserId)) -// -// // TODO should we force verification ? -// if (!otherKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(otherKeys)) -// -// // Check if the trust chain is valid -// /* -// * ┏━━━━━━━━┓ ┏━━━━━━━━┓ -// * ┃ ALICE ┃ ┃ BOB ┃ -// * ┗━━━━━━━━┛ ┗━━━━━━━━┛ -// * MSK ┌────────────▶MSK -// * │ -// * │ │ │ -// * │ SSK │ └──▶ SSK ──────────────────┐ -// * │ │ │ -// * │ │ USK │ -// * └──▶ USK ────────────┘ (not visible by │ -// * Alice) │ -// * ▼ -// * ┌──────────────┐ -// * │ BOB's Device │ -// * └──────────────┘ -// */ -// -// val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}") -// ?: return legacyFallbackTrust( -// locallyTrusted, -// DeviceTrustResult.MissingDeviceSignature(otherDeviceId, otherKeys.selfSigningKey() -// ?.unpaddedBase64PublicKey -// ?: "" -// ) -// ) -// -// // Check bob's device is signed by bob's SSK -// try { -// olmUtility!!.verifyEd25519Signature(otherSSKSignature, otherKeys.selfSigningKey()?.unpaddedBase64PublicKey, otherDevice.canonicalSignable()) -// } catch (e: Throwable) { -// return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.InvalidDeviceSignature(otherDeviceId, otherSSKSignature, e)) -// } -// -// return DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = true, locallyVerified = locallyTrusted)) -// } -// -// fun checkDeviceTrust(myKeys: MXCrossSigningInfo?, otherKeys: MXCrossSigningInfo?, otherDevice: CryptoDeviceInfo): DeviceTrustResult { -// val locallyTrusted = otherDevice.trustLevel?.isLocallyVerified() -// myKeys ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(userId)) -// -// if (!myKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(myKeys)) -// -// otherKeys ?: return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.CrossSigningNotConfigured(otherDevice.userId)) -// -// // TODO should we force verification ? -// if (!otherKeys.isTrusted()) return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.KeysNotTrusted(otherKeys)) -// -// // Check if the trust chain is valid -// /* -// * ┏━━━━━━━━┓ ┏━━━━━━━━┓ -// * ┃ ALICE ┃ ┃ BOB ┃ -// * ┗━━━━━━━━┛ ┗━━━━━━━━┛ -// * MSK ┌────────────▶MSK -// * │ -// * │ │ │ -// * │ SSK │ └──▶ SSK ──────────────────┐ -// * │ │ │ -// * │ │ USK │ -// * └──▶ USK ────────────┘ (not visible by │ -// * Alice) │ -// * ▼ -// * ┌──────────────┐ -// * │ BOB's Device │ -// * └──────────────┘ -// */ -// -// val otherSSKSignature = otherDevice.signatures?.get(otherKeys.userId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}") -// ?: return legacyFallbackTrust( -// locallyTrusted, -// DeviceTrustResult.MissingDeviceSignature(otherDevice.deviceId, otherKeys.selfSigningKey() -// ?.unpaddedBase64PublicKey -// ?: "" -// ) -// ) -// -// // Check bob's device is signed by bob's SSK -// try { -// olmUtility!!.verifyEd25519Signature(otherSSKSignature, otherKeys.selfSigningKey()?.unpaddedBase64PublicKey, otherDevice.canonicalSignable()) -// } catch (e: Throwable) { -// return legacyFallbackTrust(locallyTrusted, DeviceTrustResult.InvalidDeviceSignature(otherDevice.deviceId, otherSSKSignature, e)) -// } -// -// return DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = true, locallyVerified = locallyTrusted)) -// } -// -// private fun legacyFallbackTrust(locallyTrusted: Boolean?, crossSignTrustFail: DeviceTrustResult): DeviceTrustResult { -// return if (locallyTrusted == true) { -// DeviceTrustResult.Success(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true)) -// } else { -// crossSignTrustFail -// } -// } -// -// override fun onUsersDeviceUpdate(userIds: List) { -// Timber.d("## CrossSigning - onUsersDeviceUpdate for users: ${userIds.logLimit()}") -// val workerParams = UpdateTrustWorker.Params( -// sessionId = sessionId, -// filename = updateTrustWorkerDataRepository.createParam(userIds) -// ) -// val workerData = WorkerParamsFactory.toData(workerParams) -// -// val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder() -// .setInputData(workerData) -// .setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS) -// .build() -// -// workManagerProvider.workManager -// .beginUniqueWork("TRUST_UPDATE_QUEUE", ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest) -// .enqueue() -// } -// -// private fun setUserKeysAsTrusted(otherUserId: String, trusted: Boolean) { -// val currentTrust = cryptoStore.getCrossSigningInfo(otherUserId)?.isTrusted() -// cryptoStore.setUserKeysAsTrusted(otherUserId, trusted) -// // If it's me, recheck trust of all users and devices? -// val users = ArrayList() -// if (otherUserId == userId && currentTrust != trusted) { -// // reRequestAllPendingRoomKeyRequest() -// cryptoStore.updateUsersTrust { -// users.add(it) -// checkUserTrust(it).isVerified() -// } -// -// users.forEach { -// cryptoStore.getUserDeviceList(it)?.forEach { device -> -// val updatedTrust = checkDeviceTrust(it, device.deviceId, device.trustLevel?.isLocallyVerified() ?: false) -// Timber.v("## CrossSigning - update trust for device ${device.deviceId} of user $otherUserId , verified=$updatedTrust") -// cryptoStore.setDeviceTrust(it, device.deviceId, updatedTrust.isCrossSignedVerified(), updatedTrust.isLocallyVerified()) -// } -// } -// } -// } -// -// // private fun reRequestAllPendingRoomKeyRequest() { -// // cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// // Timber.d("## CrossSigning - reRequest pending outgoing room key requests") -// // cryptoStore.getOutgoingRoomKeyRequests().forEach { -// // it.requestBody?.let { requestBody -> -// // if (cryptoStore.getInboundGroupSession(requestBody.sessionId ?: "", requestBody.senderKey ?: "") == null) { -// // outgoingRoomKeyRequestManager.resendRoomKeyRequest(requestBody) -// // } else { -// // outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody) -// // } -// // } -// // } -// // } -// // } -// } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt deleted file mode 100644 index 3121e99572..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt +++ /dev/null @@ -1,389 +0,0 @@ -// /* -// * Copyright 2020 The Matrix.org Foundation C.I.C. -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ -// -// package org.matrix.android.sdk.internal.crypto.crosssigning -// -// import android.content.Context -// import androidx.work.WorkerParameters -// import com.squareup.moshi.JsonClass -// import io.realm.Realm -// import io.realm.RealmConfiguration -// import io.realm.kotlin.where -// import kotlinx.coroutines.runBlocking -// import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel -// import org.matrix.android.sdk.api.extensions.orFalse -// import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo -// import org.matrix.android.sdk.internal.crypto.OlmMachineProvider -// import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -// import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper -// import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity -// import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields -// import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMapper -// import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntity -// import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity -// import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields -// import org.matrix.android.sdk.internal.database.awaitTransaction -// import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity -// import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields -// import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity -// import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields -// import org.matrix.android.sdk.internal.database.query.where -// import org.matrix.android.sdk.internal.di.CryptoDatabase -// import org.matrix.android.sdk.internal.di.SessionDatabase -// import org.matrix.android.sdk.internal.di.UserId -// import org.matrix.android.sdk.internal.session.SessionComponent -// import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper -// import org.matrix.android.sdk.internal.util.logLimit -// import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker -// import org.matrix.android.sdk.internal.worker.SessionWorkerParams -// import timber.log.Timber -// import javax.inject.Inject -// -// @Deprecated("Now using olm machine") -// internal class UpdateTrustWorker(context: Context, -// params: WorkerParameters) -// : SessionSafeCoroutineWorker(context, params, Params::class.java) { -// -// @JsonClass(generateAdapter = true) -// internal data class Params( -// override val sessionId: String, -// override val lastFailureMessage: String? = null, -// // Kept for compatibility, but not used anymore (can be used for pending Worker) -// val updatedUserIds: List? = null, -// // Passing a long list of userId can break the Work Manager due to data size limitation. -// // so now we use a temporary file to store the data -// val filename: String? = null -// ) : SessionWorkerParams -// -// // @Inject lateinit var crossSigningService: RustCrossSigningService -// @Inject lateinit var olmMachineProvider: OlmMachineProvider//: RustCrossSigningService -// -// // It breaks the crypto store contract, but we need to batch things :/ -// @CryptoDatabase -// @Inject lateinit var cryptoRealmConfiguration: RealmConfiguration -// -// @SessionDatabase -// @Inject lateinit var sessionRealmConfiguration: RealmConfiguration -// -// @UserId -// @Inject lateinit var myUserId: String -// @Inject lateinit var crossSigningKeysMapper: CrossSigningKeysMapper -// @Inject lateinit var updateTrustWorkerDataRepository: UpdateTrustWorkerDataRepository -// -// // @Inject lateinit var roomSummaryUpdater: RoomSummaryUpdater -// @Inject lateinit var cryptoStore: IMXCryptoStore -// -// override fun injectWith(injector: SessionComponent) { -// injector.inject(this) -// } -// -// override suspend fun doSafeWork(params: Params): Result { -// val userList = params.filename -// ?.let { updateTrustWorkerDataRepository.getParam(it) } -// ?.userIds -// ?: params.updatedUserIds.orEmpty() -// -// // List should not be empty, but let's avoid go further in case of empty list -// if (userList.isNotEmpty()) { -// // Unfortunately we don't have much info on what did exactly changed (is it the cross signing keys of that user, -// // or a new device?) So we check all again :/ -// Timber.d("## CrossSigning - Updating trust for users: ${userList.logLimit()}") -// updateTrust(userList) -// } -// -// cleanup(params) -// return Result.success() -// } -// -// private suspend fun updateTrust(userListParam: List) { -// var userList = userListParam -// var myCrossSigningInfo: MXCrossSigningInfo? = null -// -// // First we check that the users MSK are trusted by mine -// // After that we check the trust chain for each devices of each users -// awaitTransaction(cryptoRealmConfiguration) { cryptoRealm -> -// // By mapping here to model, this object is not live -// // I should update it if needed -// myCrossSigningInfo = getCrossSigningInfo(cryptoRealm, myUserId) -// -// var myTrustResult: UserTrustResult? = null -// -// if (userList.contains(myUserId)) { -// Timber.d("## CrossSigning - Clear all trust as a change on my user was detected") -// // i am in the list.. but i don't know exactly the delta of change :/ -// // If it's my cross signing keys we should refresh all trust -// // do it anyway ? -// userList = cryptoRealm.where(CrossSigningInfoEntity::class.java) -// .findAll() -// .mapNotNull { it.userId } -// -// // check right now my keys and mark it as trusted as other trust depends on it -// // val myDevices = olmMachineProvider.olmMachine.getUserDevices(myUserId) -// // cryptoRealm.where() -// // .equalTo(UserEntityFields.USER_ID, myUserId) -// // .findFirst() -// // ?.devices -// // ?.map { CryptoMapper.mapToModel(it) } -// -// -// val identity = olmMachineProvider.olmMachine.getIdentity(olmMachineProvider.olmMachine.userId()) -// myTrustResult = if (identity?.verified() == true) { -// UserTrustResult.Success -// } else { -// if (identity?.toMxCrossSigningInfo() == null) { -// UserTrustResult.CrossSigningNotConfigured(olmMachineProvider.olmMachine.userId()) -// } else { -// UserTrustResult.KeysNotTrusted(identity.toMxCrossSigningInfo()) -// } -// } -// -// // crossSigningService.checkSelfTrust(myCrossSigningInfo, myDevices) -// updateCrossSigningKeysTrust(cryptoRealm, myUserId, myTrustResult.isVerified()) -// // update model reference -// myCrossSigningInfo = getCrossSigningInfo(cryptoRealm, myUserId) -// } -// -// val otherInfos = userList.associateWith { userId -> -// getCrossSigningInfo(cryptoRealm, userId) -// } -// -// val trusts = otherInfos.mapValues { entry -> -// when (entry.key) { -// myUserId -> myTrustResult -// else -> { -// val userId = entry.value?.userId ?: "" -// val identity = olmMachineProvider.olmMachine.getIdentity(userId) -// if (identity?.verified() == true) { -// UserTrustResult.Success -// } else { -// if (identity?.toMxCrossSigningInfo() == null) { -// UserTrustResult.CrossSigningNotConfigured(userId) -// } else { -// UserTrustResult.KeysNotTrusted(identity.toMxCrossSigningInfo()) -// } -// } -// } -// } -// } -// -// // TODO! if it's me and my keys has changed... I have to reset trust for everyone! -// // i have all the new trusts, update DB -// // trusts.forEach { -// // val verified = it.value?.isVerified() == true -// // updateCrossSigningKeysTrust(cryptoRealm, it.key, verified) -// // } -// -// // Ok so now we have to check device trust for all these users.. -// Timber.v("## CrossSigning - Updating devices cross trust users: ${trusts.keys.logLimit()}") -// trusts.keys.forEach { userId -> -// val devicesEntities = olmMachineProvider.olmMachine.getUserDevices(userId) -// // cryptoRealm.where() -// // .equalTo(UserEntityFields.USER_ID, userId) -// // .findFirst() -// // ?.devices -// -// val trustMap = devicesEntities.associateWith { device -> -// // val cryptoDevice = device.toCryptoDeviceInfo() -// // get up to date from DB has could have been updated -// // val otherInfo = getCrossSigningInfo(cryptoRealm, userId) -// // val deviceId = device.i deviceId ?: "" -// // val device = olmMachineProvider.olmMachine.getDevice(userId, deviceId) -// // if (device != null) { -// // TODO i don't quite understand the semantics here and there are no docs for -// // DeviceTrustResult, what do the different result types mean exactly, -// // do you return success only if the Device is cross signing verified? -// // what about the local trust if it isn't? why is the local trust passed as an argument here? -// DeviceTrustResult.Success(runBlocking { device.trustLevel() }) -// // } else { -// // DeviceTrustResult.UnknownDevice(deviceId) -// // } -// // crossSigningService.checkDeviceTrust(myCrossSigningInfo, otherInfo, CryptoMapper.mapToModel(device)) -// } -// -// // Update trust if needed -// // devicesEntities?.forEach { device -> -// // val crossSignedVerified = trustMap?.get(device)?.isCrossSignedVerified() -// // Timber.d("## CrossSigning - Trust for ${device.userId}|${device.deviceId} : cross verified: ${trustMap?.get(device)}") -// // if (device.trustLevelEntity?.crossSignedVerified != crossSignedVerified) { -// // Timber.d("## CrossSigning - Trust change detected for ${device.userId}|${device.deviceId} : cross verified: $crossSignedVerified") -// // // need to save -// // val trustEntity = device.trustLevelEntity -// // if (trustEntity == null) { -// // device.trustLevelEntity = cryptoRealm.createObject(TrustLevelEntity::class.java).also { -// // it.locallyVerified = false -// // it.crossSignedVerified = crossSignedVerified -// // } -// // } else { -// // trustEntity.crossSignedVerified = crossSignedVerified -// // } -// // } -// // } -// } -// } -// -// // So Cross Signing keys trust is updated, device trust is updated -// // We can now update room shields? in the session DB? -// updateTrustStep2(userList, myCrossSigningInfo) -// } -// -// private suspend fun updateTrustStep2(userList: List, myCrossSigningInfo: MXCrossSigningInfo?) { -// Timber.d("## CrossSigning - Updating shields for impacted rooms...") -// awaitTransaction(sessionRealmConfiguration) { sessionRealm -> -// Realm.getInstance(cryptoRealmConfiguration).use { cryptoRealm -> -// sessionRealm.where(RoomMemberSummaryEntity::class.java) -// .`in`(RoomMemberSummaryEntityFields.USER_ID, userList.toTypedArray()) -// .distinct(RoomMemberSummaryEntityFields.ROOM_ID) -// .findAll() -// .map { it.roomId } -// .also { Timber.d("## CrossSigning - ... impacted rooms ${it.logLimit()}") } -// .forEach { roomId -> -// RoomSummaryEntity.where(sessionRealm, roomId) -// .equalTo(RoomSummaryEntityFields.IS_ENCRYPTED, true) -// .findFirst() -// ?.let { roomSummary -> -// Timber.d("## CrossSigning - Check shield state for room $roomId") -// val allActiveRoomMembers = RoomMemberHelper(sessionRealm, roomId).getActiveRoomMemberIds() -// try { -// val updatedTrust = computeRoomShield( -// myCrossSigningInfo, -// cryptoRealm, -// allActiveRoomMembers, -// roomSummary -// ) -// if (roomSummary.roomEncryptionTrustLevel != updatedTrust) { -// Timber.d("## CrossSigning - Shield change detected for $roomId -> $updatedTrust") -// roomSummary.roomEncryptionTrustLevel = updatedTrust -// } -// } catch (failure: Throwable) { -// Timber.e(failure) -// } -// } -// } -// } -// } -// } -// -// private suspend fun getCrossSigningInfo(cryptoRealm: Realm, userId: String): MXCrossSigningInfo? { -// return olmMachineProvider.olmMachine.getIdentity(userId)?.toMxCrossSigningInfo() -// // cryptoRealm.where(CrossSigningInfoEntity::class.java) -// // .equalTo(CrossSigningInfoEntityFields.USER_ID, userId) -// // .findFirst() -// // ?.let { mapCrossSigningInfoEntity(it) } -// } -// -// private fun cleanup(params: Params) { -// params.filename -// ?.let { updateTrustWorkerDataRepository.delete(it) } -// } -// -// private fun updateCrossSigningKeysTrust(cryptoRealm: Realm, userId: String, verified: Boolean) { -// cryptoRealm.where(CrossSigningInfoEntity::class.java) -// .equalTo(CrossSigningInfoEntityFields.USER_ID, userId) -// .findFirst() -// ?.crossSigningKeys -// ?.forEach { info -> -// // optimization to avoid trigger updates when there is no change.. -// if (info.trustLevelEntity?.isVerified() != verified) { -// Timber.d("## CrossSigning - Trust change for $userId : $verified") -// val level = info.trustLevelEntity -// if (level == null) { -// info.trustLevelEntity = cryptoRealm.createObject(TrustLevelEntity::class.java).also { -// it.locallyVerified = verified -// it.crossSignedVerified = verified -// } -// } else { -// level.locallyVerified = verified -// level.crossSignedVerified = verified -// } -// } -// } -// } -// -// private suspend fun computeRoomShield(myCrossSigningInfo: MXCrossSigningInfo?, -// cryptoRealm: Realm, -// activeMemberUserIds: List, -// roomSummaryEntity: RoomSummaryEntity): RoomEncryptionTrustLevel { -// Timber.d("## CrossSigning - computeRoomShield ${roomSummaryEntity.roomId} -> ${activeMemberUserIds.logLimit()}") -// // The set of “all users” depends on the type of room: -// // For regular / topic rooms which have more than 2 members (including yourself) are considered when decorating a room -// // For 1:1 and group DM rooms, all other users (i.e. excluding yourself) are considered when decorating a room -// val listToCheck = if (roomSummaryEntity.isDirect || activeMemberUserIds.size <= 2) { -// activeMemberUserIds.filter { it != myUserId } -// } else { -// activeMemberUserIds -// } -// -// val allTrustedUserIds = listToCheck -// .filter { userId -> -// getCrossSigningInfo(cryptoRealm, userId)?.isTrusted() == true -// } -// Timber.d("## CrossSigning - allTrustedIds ${allTrustedUserIds}") -// -// return if (allTrustedUserIds.isEmpty()) { -// RoomEncryptionTrustLevel.Default -// } else { -// // If one of the verified user as an untrusted device -> warning -// // If all devices of all verified users are trusted -> green -// // else -> black -// allTrustedUserIds -// .mapNotNull { userId -> -// // cryptoRealm.where() -// // .equalTo(UserEntityFields.USER_ID, userId) -// // .findFirst() -// // ?.devices -// // ?.map { CryptoMapper.mapToModel(it) } -// olmMachineProvider.olmMachine.getUserDevices(userId) -// } -// .flatten() -// .let { allDevices -> -// Timber.v("## CrossSigning - computeRoomShield ${roomSummaryEntity.roomId} devices ${allDevices.map { "${it.toCryptoDeviceInfo().deviceId} trust ${it.toCryptoDeviceInfo().trustLevel}" }.logLimit()}") -// -// if (myCrossSigningInfo != null) { -// allDevices.any { !it.toCryptoDeviceInfo().trustLevel?.crossSigningVerified.orFalse() } -// } else { -// // Legacy method -// allDevices.any { !it.toCryptoDeviceInfo().isVerified } -// } -// } -// .let { hasWarning -> -// if (hasWarning) { -// RoomEncryptionTrustLevel.Warning -// } else { -// if (listToCheck.size == allTrustedUserIds.size) { -// // all users are trusted and all devices are verified -// RoomEncryptionTrustLevel.Trusted -// } else { -// RoomEncryptionTrustLevel.Default -// } -// } -// } -// } -// } -// -// private fun mapCrossSigningInfoEntity(xsignInfo: CrossSigningInfoEntity): MXCrossSigningInfo { -// val userId = xsignInfo.userId ?: "" -// return MXCrossSigningInfo( -// userId = userId, -// crossSigningKeys = xsignInfo.crossSigningKeys.mapNotNull { -// crossSigningKeysMapper.map(userId, it) -// } -// ) -// } -// -// override fun buildErrorParams(params: Params, message: String): Params { -// return params.copy(lastFailureMessage = params.lastFailureMessage ?: message) -// } -// } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 35b7711027..4134c0e8aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/UpdateDispatcher.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/UpdateDispatcher.kt index 0b2e1673ec..ada206caea 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/UpdateDispatcher.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/UpdateDispatcher.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 87339fb0ee2a3cc00ccf726f598e0bf1363a7266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Nov 2021 14:11:32 +0100 Subject: [PATCH 179/252] rust: Bump the uniffi version --- rust-sdk/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index e1f5b84001..bb4fadf147 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -17,7 +17,7 @@ base64 = "0.13.0" thiserror = "1.0.25" tracing = "0.1.26" tracing-subscriber = "0.2.18" -uniffi = "0.14.0" +uniffi = "0.15.1" pbkdf2 = "0.8.0" sha2 = "0.9.5" rand = "0.8.4" @@ -47,4 +47,4 @@ rev = "ac6ecc3e5" features = ["client-api-c"] [build-dependencies] -uniffi_build = "0.12.0" +uniffi_build = "0.15.1" From ac153c80d5810b622e4d17979844f16fe2914dfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Nov 2021 14:11:56 +0100 Subject: [PATCH 180/252] rust: Expose a method to check if a user is tracked --- rust-sdk/src/machine.rs | 9 +++++++++ rust-sdk/src/olm.udl | 2 ++ 2 files changed, 11 insertions(+) diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 7581c2b4e7..c250d0d8e5 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -387,6 +387,15 @@ impl OlmMachine { .block_on(self.inner.update_tracked_users(users.iter())); } + /// Check if the given user is considered to be tracked. + /// + /// A user can be marked for tracking using the + /// [`OlmMachine::update_tracked_users()`] method. + pub fn is_user_tracked(&self, user_id: &str) -> Result { + let user_id = UserId::try_from(user_id)?; + Ok(self.inner.tracked_users().contains(&user_id)) + } + /// Generate one-time key claiming requests for all the users we are missing /// sessions for. /// diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 2590afbed7..894d9afe3c 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -271,6 +271,8 @@ interface OlmMachine { [Throws=CryptoStoreError] sequence get_user_devices([ByRef] string user_id); + [Throws=CryptoStoreError] + boolean is_user_tracked([ByRef] string user_id); void update_tracked_users(sequence users); [Throws=CryptoStoreError] Request? get_missing_sessions(sequence users); From 38644f0aa29211a669cfbb7d754b337d4860814f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 24 Nov 2021 14:35:52 +0100 Subject: [PATCH 181/252] crypto: Rewrap and use the new isUserTracked method --- .../sdk/internal/crypto/DefaultCryptoService.kt | 6 +++++- .../matrix/android/sdk/internal/crypto/OlmMachine.kt | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index a87d2483e0..70e792d4f6 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -255,7 +255,11 @@ internal class DefaultCryptoService @Inject constructor( * @return the tracking status */ override fun getDeviceTrackingStatus(userId: String): Int { - return cryptoStore.getDeviceTrackingStatus(userId, DeviceListManager.TRACKING_STATUS_NOT_TRACKED) + return if (olmMachine.isUserTracked(userId)) { + 3 + } else { + -1 + } } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 710490b372..2d503c1df0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -332,6 +332,17 @@ internal class OlmMachine( suspend fun updateTrackedUsers(users: List) = withContext(Dispatchers.IO) { inner.updateTrackedUsers(users) } + + /** + * Check if the given user is considered to be tracked. + * A user can be marked for tracking using the + * [OlmMachine.updateTrackedUsers] method. + */ + @Throws(CryptoStoreException::class) + fun isUserTracked(userId: String): Boolean { + return this.inner.isUserTracked(userId) + } + /** * Generate one-time key claiming requests for all the users we are missing sessions for. * From 3f710ef4c06d434deec021ac57058c184ff5391d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 25 Nov 2021 10:38:39 +0100 Subject: [PATCH 182/252] rust: Allow individual room keys to be invalid when importing --- rust-sdk/src/machine.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index c250d0d8e5..c842334897 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -27,7 +27,7 @@ use ruma::{ DeviceKeyAlgorithm, EventId, RoomId, UserId, }; use serde::{Deserialize, Serialize}; -use serde_json::value::RawValue; +use serde_json::{value::RawValue, Value}; use tokio::runtime::Runtime; use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; @@ -613,7 +613,7 @@ impl OlmMachine { Ok(encrypted) } - fn impor_keys_helper( + fn import_keys_helper( &self, keys: Vec, progress_listener: Box, @@ -650,7 +650,7 @@ impl OlmMachine { ) -> Result { let keys = Cursor::new(keys); let keys = decrypt_key_export(keys, passphrase)?; - self.impor_keys_helper(keys, progress_listener) + self.import_keys_helper(keys, progress_listener) } /// Import room keys from the given serialized unencrypted key export. @@ -670,8 +670,15 @@ impl OlmMachine { keys: &str, progress_listener: Box, ) -> Result { - let keys: Vec = serde_json::from_str(keys)?; - self.impor_keys_helper(keys, progress_listener) + let keys: Vec = serde_json::from_str(keys)?; + + let keys = keys + .into_iter() + .map(serde_json::from_value) + .filter_map(|k| k.ok()) + .collect(); + + self.import_keys_helper(keys, progress_listener) } /// Discard the currently active room key for the given room if there is From 00280ccb861eccd2fea5014e2bc950ac76651e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 25 Nov 2021 11:24:47 +0100 Subject: [PATCH 183/252] rust: Mark room keys that are imported from the backup as backed up --- rust-sdk/Cargo.toml | 4 ++-- rust-sdk/src/machine.rs | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index bb4fadf147..9ee7b4bbf7 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -29,11 +29,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "2e4d5f25cba03bd26415b91defd6e762e8c31b63" +rev = "fc74526699b82ba5be3349e810ded51138dae7fc" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "2e4d5f25cba03bd26415b91defd6e762e8c31b63" +rev = "fc74526699b82ba5be3349e810ded51138dae7fc" features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index c842334897..c7fa9741ab 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -616,6 +616,7 @@ impl OlmMachine { fn import_keys_helper( &self, keys: Vec, + from_backup: bool, progress_listener: Box, ) -> Result { let listener = |progress: usize, total: usize| { @@ -624,7 +625,7 @@ impl OlmMachine { let result = self .runtime - .block_on(self.inner.import_keys(keys, listener))?; + .block_on(self.inner.import_keys(keys, from_backup, listener))?; Ok(KeysImportResult { total: result.total_count as i64, @@ -650,14 +651,15 @@ impl OlmMachine { ) -> Result { let keys = Cursor::new(keys); let keys = decrypt_key_export(keys, passphrase)?; - self.import_keys_helper(keys, progress_listener) + self.import_keys_helper(keys, false, progress_listener) } /// Import room keys from the given serialized unencrypted key export. /// /// This method is the same as [`OlmMachine::import_keys`] but the /// decryption step is skipped and should be performed by the caller. This - /// may be useful for custom handling or for server-side key backups. + /// should be used if the room keys are comming from the server-side backup, + /// the method will mark all imported room keys as backed up. /// /// # Arguments /// @@ -678,7 +680,7 @@ impl OlmMachine { .filter_map(|k| k.ok()) .collect(); - self.import_keys_helper(keys, progress_listener) + self.import_keys_helper(keys, true, progress_listener) } /// Discard the currently active room key for the given room if there is From 9118b26d2f1b065e02e8e491dc711ecda8c34f09 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 23 Nov 2021 17:40:43 +0100 Subject: [PATCH 184/252] Fix DM are not e2e by default --- .../internal/crypto/DefaultCryptoService.kt | 8 +---- .../android/sdk/internal/crypto/OlmMachine.kt | 32 +++++++++++++++++++ .../room/create/CreateRoomBodyBuilder.kt | 2 +- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 70e792d4f6..cf58e11e52 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -1008,13 +1008,7 @@ internal class DefaultCryptoService @Inject constructor( override fun downloadKeys(userIds: List, forceDownload: Boolean, callback: MatrixCallback>) { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { runCatching { - if (forceDownload) { - // TODO replicate the logic from the device list manager - // where we would download the fresh info from the server. - this@DefaultCryptoService.olmMachine.getUserDevicesMap(userIds) // ?: MXUsersDevicesMap() - } else { - this@DefaultCryptoService.olmMachine.getUserDevicesMap(userIds) // ?: MXUsersDevicesMap() - } + olmMachine.ensureUserDevicesMap(userIds, forceDownload) }.foldToCallback(callback) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 2d503c1df0..b42f02b2e6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.extensions.tryOrNull 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.crosssigning.MXCrossSigningInfo @@ -62,6 +63,7 @@ import uniffi.olm.RoomKeyCounts import uniffi.olm.setLogger import java.io.File import java.nio.charset.Charset +import java.util.UUID import java.util.concurrent.ConcurrentHashMap import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener @@ -644,6 +646,17 @@ internal class OlmMachine( return plainDevices } + @Throws + suspend fun forceKeyDownload(userIds: List): MXUsersDevicesMap { + withContext(Dispatchers.IO) { + val requestId = UUID.randomUUID().toString() + val response = requestSender.queryKeys(Request.KeysQuery(requestId, userIds)) + markRequestAsSent(requestId, RequestType.KEYS_QUERY, response) + } + // TODO notify shield listener (?) + return getUserDevicesMap(userIds) + } + suspend fun getUserDevicesMap(userIds: List): MXUsersDevicesMap { val userMap = MXUsersDevicesMap() @@ -658,6 +671,25 @@ internal class OlmMachine( return userMap } + /** + * If the user is untracked or forceDownload is set to true, a key query request will be made. + * It will suspend until query response, and the device list will be returned. + * As there is no API to know tracking status, we consider that if there are no known devices the user is un tracked. + * + * The key query request will be retried a few time in case of shaky connection, but could fail. + */ + suspend fun ensureUserDevicesMap(userIds: List, forceDownload: Boolean = false): MXUsersDevicesMap { + val known = getUserDevicesMap(userIds) + return if (known.isEmpty /* We have no api to know if was tracked..*/ || forceDownload) { + updateTrackedUsers(userIds) + tryOrNull("Failed to download keys for $userIds") { + forceKeyDownload(userIds) + } ?: known + } else { + known + } + } + suspend fun getLiveUserIdentity(userId: String): LiveData> { val identity = this.getIdentity(userId)?.toMxCrossSigningInfo().toOptional() val liveIdentity = LiveUserIdentity(userId, this.userIdentityUpdateObserver) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt index 7fcc6c3614..9b56354672 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt @@ -181,7 +181,7 @@ internal class CreateRoomBodyBuilder @Inject constructor( params.invite3pids.isEmpty() && params.invitedUserIds.isNotEmpty() && params.invitedUserIds.let { userIds -> - val keys = olmMachineProvider.olmMachine.getUserDevicesMap(userIds) + val keys = olmMachineProvider.olmMachine.ensureUserDevicesMap(userIds, forceDownload = false) // deviceListManager.downloadKeys(userIds, forceDownload = false) userIds.all { userId -> From 7fd9ca03be161f3340db568c3de2b0096f7786de Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 25 Nov 2021 15:42:52 +0100 Subject: [PATCH 185/252] Use new isUserTracked API --- .../android/sdk/internal/crypto/OlmMachine.kt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index b42f02b2e6..c44d7ff0e8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -334,7 +334,6 @@ internal class OlmMachine( suspend fun updateTrackedUsers(users: List) = withContext(Dispatchers.IO) { inner.updateTrackedUsers(users) } - /** * Check if the given user is considered to be tracked. * A user can be marked for tracking using the @@ -647,14 +646,12 @@ internal class OlmMachine( } @Throws - suspend fun forceKeyDownload(userIds: List): MXUsersDevicesMap { + suspend fun forceKeyDownload(userIds: List) { withContext(Dispatchers.IO) { val requestId = UUID.randomUUID().toString() val response = requestSender.queryKeys(Request.KeysQuery(requestId, userIds)) markRequestAsSent(requestId, RequestType.KEYS_QUERY, response) } - // TODO notify shield listener (?) - return getUserDevicesMap(userIds) } suspend fun getUserDevicesMap(userIds: List): MXUsersDevicesMap { @@ -674,20 +671,23 @@ internal class OlmMachine( /** * If the user is untracked or forceDownload is set to true, a key query request will be made. * It will suspend until query response, and the device list will be returned. - * As there is no API to know tracking status, we consider that if there are no known devices the user is un tracked. * * The key query request will be retried a few time in case of shaky connection, but could fail. */ suspend fun ensureUserDevicesMap(userIds: List, forceDownload: Boolean = false): MXUsersDevicesMap { - val known = getUserDevicesMap(userIds) - return if (known.isEmpty /* We have no api to know if was tracked..*/ || forceDownload) { - updateTrackedUsers(userIds) - tryOrNull("Failed to download keys for $userIds") { - forceKeyDownload(userIds) - } ?: known + val toDownload = if (forceDownload) { + userIds } else { - known + userIds.mapNotNull { userId -> + userId.takeIf { !isUserTracked(it) } + }.also { + updateTrackedUsers(it) + } } + tryOrNull("Failed to download keys for $toDownload") { + forceKeyDownload(toDownload) + } + return getUserDevicesMap(userIds) } suspend fun getLiveUserIdentity(userId: String): LiveData> { @@ -795,7 +795,7 @@ internal class OlmMachine( } suspend fun bootstrapCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?) { - val requests = withContext(Dispatchers.IO) { + val requests = withContext(Dispatchers.IO) { inner.bootstrapCrossSigning() } From 8bebcc93e7bbcd85c23908a71a6912cb5c6460bf Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 25 Nov 2021 15:58:59 +0100 Subject: [PATCH 186/252] remove some force unwrap --- .../android/sdk/internal/crypto/OlmMachine.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index c44d7ff0e8..82a3952d3e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -308,13 +308,12 @@ internal class OlmMachine( } val devices = - DeviceLists( - deviceChanges?.changed ?: listOf(), deviceChanges?.left ?: listOf()) + DeviceLists(deviceChanges?.changed.orEmpty(), deviceChanges?.left.orEmpty()) val adapter = MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) - val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! + val events = toDevice?.let { adapter.toJson(it) } ?: "[]" - adapter.fromJson(inner.receiveSyncChanges(events, devices, counts))!! + adapter.fromJson(inner.receiveSyncChanges(events, devices, counts)) ?: ToDeviceSyncResponse() } // We may get cross signing keys over a to-device event, update our listeners. @@ -435,13 +434,16 @@ internal class OlmMachine( withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) val serializedEvent = adapter.toJson(event) - try { - val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId!!) + if (event.roomId.isNullOrBlank()) { + throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON) + } + val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId) val deserializationAdapter = MoshiProvider.providesMoshi().adapter(Map::class.java) - val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent)!! + val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent) + ?: throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON) MXEventDecryptionResult( clearEvent, From c4bddadebbdf1310ddd89c6799fdbd314b66dd94 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 25 Nov 2021 16:03:47 +0100 Subject: [PATCH 187/252] clean unnecessary safe calls error --- .../sdk/internal/crypto/DefaultCryptoService.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index cf58e11e52..cc74805d28 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -164,7 +164,7 @@ internal class DefaultCryptoService @Inject constructor( EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) else -> cryptoCoroutineScope.launch { - this@DefaultCryptoService.verificationService?.onEvent(event) + this@DefaultCryptoService.verificationService.onEvent(event) } } } @@ -701,7 +701,7 @@ internal class DefaultCryptoService @Inject constructor( // The rust-sdk will clear this event if it's invalid, this will produce an invalid base64 error // when we try to construct the recovery key. val secretContent = event.getClearContent().toModel() ?: return@forEach - this.keysBackupService?.onSecretKeyGossip(secretContent.secretValue) + this.keysBackupService.onSecretKeyGossip(secretContent.secretValue) } else -> { this.verificationService.onEvent(event) @@ -753,7 +753,7 @@ internal class DefaultCryptoService @Inject constructor( // If we sent out a room key over to-device messages it's likely that we created a new one // Try to back the key up if (sharedKey) { - keysBackupService?.maybeBackupKeys() + keysBackupService.maybeBackupKeys() } } @@ -868,8 +868,8 @@ internal class DefaultCryptoService @Inject constructor( override suspend fun importRoomKeys(roomKeysAsArray: ByteArray, password: String, progressListener: ProgressListener?): ImportRoomKeysResult { - val result = olmMachine!!.importKeys(roomKeysAsArray, password, progressListener) - keysBackupService?.maybeBackupKeys() + val result = olmMachine.importKeys(roomKeysAsArray, password, progressListener) + keysBackupService.maybeBackupKeys() return result } From fbe098f54bd6eb3af9654d9a17967ade5e49d5dc Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 25 Nov 2021 16:04:35 +0100 Subject: [PATCH 188/252] Add all target --- rust-sdk/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust-sdk/Makefile b/rust-sdk/Makefile index 1ceb1dd1c9..beeab61b22 100644 --- a/rust-sdk/Makefile +++ b/rust-sdk/Makefile @@ -1,3 +1,5 @@ +all: x86 aarch64 armv7-linux-androideabi + # x86_64: # cargo build --release --target x86_64-linux-android # mkdir -p ../matrix-sdk-android/src/main/jniLibs/x86_64/ From 893e6e3962c4506830693f246218d30c229cd7a0 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 25 Nov 2021 16:56:46 +0100 Subject: [PATCH 189/252] code review --- .../java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 82a3952d3e..e10778bfbd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -311,7 +311,7 @@ internal class OlmMachine( DeviceLists(deviceChanges?.changed.orEmpty(), deviceChanges?.left.orEmpty()) val adapter = MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) - val events = toDevice?.let { adapter.toJson(it) } ?: "[]" + val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! adapter.fromJson(inner.receiveSyncChanges(events, devices, counts)) ?: ToDeviceSyncResponse() } From 46ba0eec9f204b55158af58ef29ad62ae08427f5 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 25 Nov 2021 16:57:03 +0100 Subject: [PATCH 190/252] use crypto service in CreateRoomBodyBuilder --- .../sdk/api/session/crypto/CryptoService.kt | 2 +- .../internal/crypto/DefaultCryptoService.kt | 17 +++++--- .../room/create/CreateRoomBodyBuilder.kt | 28 ++++++------ .../crypto/keysrequest/KeyRequestHandler.kt | 43 +++++++++++++------ .../features/home/HomeActivityViewModel.kt | 6 +-- .../settings/devices/DevicesViewModel.kt | 2 +- 6 files changed, 57 insertions(+), 41 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index fc53540c5f..699dbf1d92 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -119,7 +119,7 @@ interface CryptoService { fun shouldEncryptForInvitedMembers(roomId: String): Boolean - fun downloadKeys(userIds: List, forceDownload: Boolean, callback: MatrixCallback>) + suspend fun downloadKeys(userIds: List, forceDownload: Boolean = false): MXUsersDevicesMap fun getCryptoDeviceInfo(userId: String): List diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index cc74805d28..e188bc2ca3 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -30,6 +30,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.NoOpMatrixCallback @@ -178,7 +179,13 @@ internal class DefaultCryptoService @Inject constructor( this.callback = object : MatrixCallback { override fun onSuccess(data: Unit) { // bg refresh of crypto device - downloadKeys(listOf(userId), true, NoOpMatrixCallback()) + cryptoCoroutineScope.launch { + try { + downloadKeys(listOf(userId), true) + } catch (failure: Throwable) { + Timber.w(failure, "setDeviceName: Failed to refresh of crypto device") + } + } callback.onSuccess(data) } @@ -1005,11 +1012,9 @@ internal class DefaultCryptoService @Inject constructor( // TODO } - override fun downloadKeys(userIds: List, forceDownload: Boolean, callback: MatrixCallback>) { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - runCatching { - olmMachine.ensureUserDevicesMap(userIds, forceDownload) - }.foldToCallback(callback) + override suspend fun downloadKeys(userIds: List, forceDownload: Boolean): MXUsersDevicesMap { + return withContext(coroutineDispatchers.crypto) { + olmMachine.ensureUserDevicesMap(userIds, forceDownload) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt index 9b56354672..d8be0c1506 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.create import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.identity.IdentityServiceError @@ -24,7 +25,6 @@ import org.matrix.android.sdk.api.session.identity.toMedium import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.util.MimeTypes import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.OlmMachineProvider import org.matrix.android.sdk.internal.di.AuthenticatedIdentity import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.network.token.AccessTokenProvider @@ -40,7 +40,7 @@ import javax.inject.Inject internal class CreateRoomBodyBuilder @Inject constructor( private val ensureIdentityTokenTask: EnsureIdentityTokenTask, // private val deviceListManager: DeviceListManager, - private val olmMachineProvider: OlmMachineProvider, + private val cryptoService: CryptoService, private val identityStore: IdentityStore, private val fileUploader: FileUploader, @UserId @@ -181,20 +181,20 @@ internal class CreateRoomBodyBuilder @Inject constructor( params.invite3pids.isEmpty() && params.invitedUserIds.isNotEmpty() && params.invitedUserIds.let { userIds -> - val keys = olmMachineProvider.olmMachine.ensureUserDevicesMap(userIds, forceDownload = false) - // deviceListManager.downloadKeys(userIds, forceDownload = false) + val keys = cryptoService.downloadKeys(userIds, forceDownload = false) + // deviceListManager.downloadKeys(userIds, forceDownload = false) - userIds.all { userId -> - keys.map[userId].let { deviceMap -> - if (deviceMap.isNullOrEmpty()) { - // A user has no device, so do not enable encryption - false - } else { - // Check that every user's device have at least one key - deviceMap.values.all { !it.keys.isNullOrEmpty() } + userIds.all { userId -> + keys.map[userId].let { deviceMap -> + if (deviceMap.isNullOrEmpty()) { + // A user has no device, so do not enable encryption + false + } else { + // Check that every user's device have at least one key + deviceMap.values.all { !it.keys.isNullOrEmpty() } + } + } } } - } - } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt index 85250a94ce..949037bc3c 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt @@ -22,7 +22,13 @@ import im.vector.app.core.date.DateFormatKind import im.vector.app.core.date.VectorDateFormatter import im.vector.app.features.popup.DefaultVectorAlert import im.vector.app.features.popup.PopupAlertManager -import org.matrix.android.sdk.api.MatrixCallback +import im.vector.app.features.session.coroutineScope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction @@ -34,7 +40,6 @@ import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest 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.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import timber.log.Timber import javax.inject.Inject @@ -48,6 +53,7 @@ import javax.inject.Singleton * depending on user action) */ +// TODO Do we ever request to users anymore? @Singleton class KeyRequestHandler @Inject constructor( private val context: Context, @@ -60,13 +66,18 @@ class KeyRequestHandler @Inject constructor( var session: Session? = null + var scope: CoroutineScope? = null + fun start(session: Session) { this.session = session + scope = CoroutineScope(SupervisorJob() + session.coroutineScope.coroutineContext) session.cryptoService().verificationService().addListener(this) session.cryptoService().addRoomKeysRequestListener(this) } fun stop() { + scope?.cancel() + scope = null session?.cryptoService()?.verificationService()?.removeListener(this) session?.cryptoService()?.removeRoomKeysRequestListener(this) session = null @@ -104,15 +115,16 @@ class KeyRequestHandler @Inject constructor( alertsToRequests[mappingKey] = ArrayList().apply { this.add(request) } - // Add a notification for every incoming request - session?.cryptoService()?.downloadKeys(listOf(userId), false, object : MatrixCallback> { - override fun onSuccess(data: MXUsersDevicesMap) { + scope?.launch { + try { + val data = session?.cryptoService()?.downloadKeys(listOf(userId), false) + ?: return@launch val deviceInfo = data.getObject(userId, deviceId) if (null == deviceInfo) { Timber.e("## displayKeyShareDialog() : No details found for device $userId:$deviceId") // ignore - return + return@launch } if (deviceInfo.isUnknown) { @@ -122,20 +134,23 @@ class KeyRequestHandler @Inject constructor( // can we get more info on this device? session?.cryptoService()?.getMyDevicesInfo()?.firstOrNull { it.deviceId == deviceId }?.let { - postAlert(context, userId, deviceId, true, deviceInfo, it) + withContext(Dispatchers.Main) { + postAlert(context, userId, deviceId, true, deviceInfo, it) + } } ?: run { - postAlert(context, userId, deviceId, true, deviceInfo) + withContext(Dispatchers.Main) { + postAlert(context, userId, deviceId, true, deviceInfo) + } } } else { - postAlert(context, userId, deviceId, false, deviceInfo) + withContext(Dispatchers.Main) { + postAlert(context, userId, deviceId, false, deviceInfo) + } } - } - - override fun onFailure(failure: Throwable) { - // ignore + } catch (failure: Throwable) { Timber.e(failure, "## displayKeyShareDialog : downloadKeys") } - }) + } } private fun postAlert(context: Context, diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 59b9cafd6e..782bde4e5e 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -47,8 +47,6 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import kotlin.coroutines.Continuation @@ -181,9 +179,7 @@ class HomeActivityViewModel @AssistedInject constructor( val session = activeSessionHolder.getSafeActiveSession() ?: return@launch tryOrNull("## MaybeBootstrapCrossSigning: Failed to download keys") { - awaitCallback> { - session.cryptoService().downloadKeys(listOf(session.myUserId), true, it) - } + session.cryptoService().downloadKeys(listOf(session.myUserId), true) } // From there we are up to date with server diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index 67ed2e18f2..c8b595a5ed 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -169,7 +169,7 @@ class DevicesViewModel @AssistedInject constructor( refreshSource.stream().throttleFirst(4_000) .onEach { session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) - session.cryptoService().downloadKeys(listOf(session.myUserId), true, NoOpMatrixCallback()) + session.cryptoService().downloadKeys(listOf(session.myUserId), true) } .launchIn(viewModelScope) // then force download From d138306b0826fb81ae5922c9c595012760ba6bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 25 Nov 2021 16:50:28 +0100 Subject: [PATCH 191/252] rust: Return the map of room keys that were imported --- rust-sdk/Cargo.toml | 4 ++-- rust-sdk/src/machine.rs | 14 +++++++++++++- rust-sdk/src/olm.udl | 3 ++- rust-sdk/src/responses.rs | 9 ++++++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 9ee7b4bbf7..3d256ec661 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -29,11 +29,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "fc74526699b82ba5be3349e810ded51138dae7fc" +rev = "7b6132b71e499224ed25bdc571b2a54d076551d6" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "fc74526699b82ba5be3349e810ded51138dae7fc" +rev = "7b6132b71e499224ed25bdc571b2a54d076551d6" features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index c7fa9741ab..1ffc30c764 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -628,8 +628,20 @@ impl OlmMachine { .block_on(self.inner.import_keys(keys, from_backup, listener))?; Ok(KeysImportResult { - total: result.total_count as i64, imported: result.imported_count as i64, + total: result.total_count as i64, + keys: result + .keys + .into_iter() + .map(|(r, m)| { + ( + r.to_string(), + m.into_iter() + .map(|(s, k)| (s, k.into_iter().collect())) + .collect(), + ) + }) + .collect(), }) } diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 894d9afe3c..675dc466e6 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -59,8 +59,9 @@ dictionary DeviceLists { }; dictionary KeysImportResult { - i64 total; i64 imported; + i64 total; + record>> keys; }; dictionary DecryptedEvent { diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index a7e9308d32..23ea870ec7 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -295,8 +295,15 @@ impl From for RumaDeviceLists { } pub struct KeysImportResult { - pub total: i64, + /// The number of room keys that were imported. pub imported: i64, + /// The total number of room keys that were found in the export. + pub total: i64, + /// The map of keys that were imported. + /// + /// It's a map from room id to a map of the sender key to a list of session + /// ids. + pub keys: HashMap>>, } pub(crate) enum OwnedResponse { From 3f2755b67c4ab0f9b5f1e9b02565beccb3fb68d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 29 Nov 2021 15:23:44 +0100 Subject: [PATCH 192/252] rust: Bump the rust-sdk version --- rust-sdk/Cargo.toml | 4 ++-- rust-sdk/src/device.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 3d256ec661..a8ceb9cd7f 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -29,11 +29,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "7b6132b71e499224ed25bdc571b2a54d076551d6" +rev = "a628e84b63f6b761af383655e00f544ef6a09082" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "7b6132b71e499224ed25bdc571b2a54d076551d6" +rev = "a628e84b63f6b761af383655e00f544ef6a09082" features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] diff --git a/rust-sdk/src/device.rs b/rust-sdk/src/device.rs index 5aa36bd5bb..ecd571c118 100644 --- a/rust-sdk/src/device.rs +++ b/rust-sdk/src/device.rs @@ -37,7 +37,7 @@ impl From for Device { .map(|(k, v)| (k.to_string(), v.to_string())) .collect(), algorithms: d.algorithms().iter().map(|a| a.to_string()).collect(), - display_name: d.display_name().clone(), + display_name: d.display_name().map(|d| d.to_owned()), is_blocked: d.is_blacklisted(), locally_trusted: d.is_locally_trusted(), cross_signing_trusted: d.is_cross_signing_trusted(), From f0f64d8380c3b51addd666b0474f9332008bc997 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 19 Nov 2021 19:38:10 +0100 Subject: [PATCH 193/252] Fix verify with passphrase own device not trusted --- .../crypto/crosssigning/XSigningTest.kt | 4 +- .../crypto/gossiping/KeyShareTests.kt | 2 +- .../crypto/gossiping/WithHeldTests.kt | 7 ++-- .../crosssigning/CrossSigningService.kt | 6 +-- .../android/sdk/internal/crypto/OlmMachine.kt | 39 +++++++++++++++---- .../crypto/RustCrossSigningService.kt | 20 +++++----- .../crypto/crosssigning/UserTrustResult.kt | 12 +++--- .../VerificationBottomSheetViewModel.kt | 15 ++++--- .../settings/devices/DevicesViewModel.kt | 4 +- 9 files changed, 63 insertions(+), 46 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt index 44af87bcbe..f3650b87be 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt @@ -183,8 +183,8 @@ class XSigningTest : InstrumentedTest { assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice) // Manually mark it as trusted from first session - mTestHelper.doSync { - bobSession.cryptoService().crossSigningService().trustDevice(bobSecondDeviceId, it) + mTestHelper.runBlockingTest { + bobSession.cryptoService().crossSigningService().trustDevice(bobSecondDeviceId) } // Now alice should cross trust bob's second device diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 40659cef11..d1dc65ba83 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -103,7 +103,7 @@ class KeyShareTests : InstrumentedTest { val outgoingRequestsBefore = aliceSession2.cryptoService().getOutgoingRoomKeyRequests() // Try to request - aliceSession2.cryptoService().requestRoomKeyForEvent(receivedEvent.root) + aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root) val waitLatch = CountDownLatch(1) val eventMegolmSessionId = receivedEvent.root.content.toModel()?.sessionId diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt index c939952dc9..ac0f50df9a 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt @@ -24,7 +24,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.EventType @@ -217,8 +216,10 @@ class WithHeldTests : InstrumentedTest { mCryptoTestHelper.initializeCrossSigning(bobSecondSession) // Trust bob second device from Alice POV - aliceSession.cryptoService().crossSigningService().trustDevice(bobSecondSession.sessionParams.deviceId!!, NoOpMatrixCallback()) - bobSecondSession.cryptoService().crossSigningService().trustDevice(aliceSession.sessionParams.deviceId!!, NoOpMatrixCallback()) + mTestHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().trustDevice(bobSecondSession.sessionParams.deviceId!!) + bobSecondSession.cryptoService().crossSigningService().trustDevice(aliceSession.sessionParams.deviceId!!) + } var sessionId: String? = null // Check that the diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index 7c3a0101c8..1d97488ebc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -61,7 +61,7 @@ interface CrossSigningService { * This will check if the injected private cross signing keys match the public ones provided * by the server and if they do so */ - fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, + suspend fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, uskKeyPrivateKey: String?, sskPrivateKey: String?): UserTrustResult @@ -102,8 +102,8 @@ interface CrossSigningService { /** * Sign one of your devices and upload the signature */ - fun trustDevice(deviceId: String, - callback: MatrixCallback) + @Throws + suspend fun trustDevice(deviceId: String) suspend fun shieldForGroup(userIds: List): RoomEncryptionTrustLevel diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index e10778bfbd..dfb76401e0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -554,9 +554,17 @@ internal class OlmMachine( UserIdentity(identity.userId, masterKey, selfSigningKey, this, this.requestSender) } is RustUserIdentity.Own -> { - val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel() - val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel() - val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel() + val verified = this.inner().isIdentityVerified(userId) + + val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } OwnUserIdentity( identity.userId, @@ -823,13 +831,28 @@ internal class OlmMachine( suspend fun importCrossSigningKeys(export: PrivateKeysInfo): UserTrustResult { val rustExport = CrossSigningKeyExport(export.master, export.selfSigned, export.user) + var result: UserTrustResult withContext(Dispatchers.IO) { - inner.importCrossSigningKeys(rustExport) - } + result = try { + inner.importCrossSigningKeys(rustExport) - this.updateLivePrivateKeys() - // TODO map the errors from importCrossSigningKeys to the UserTrustResult - return UserTrustResult.Success + // Sign the cross signing keys with our device + // Fail silently if signature upload fails?? + try { + getIdentity(userId())?.verify() + } catch (failure: Throwable) { + Timber.e(failure, "Failed to sign x-keys with own device") + } + UserTrustResult.Success + } catch (failure: Exception) { + // KeyImportError? + UserTrustResult.Failure(failure.localizedMessage) + } + } + withContext(Dispatchers.Main) { + this@OlmMachine.updateLivePrivateKeys() + } + return result } suspend fun sign(message: String): Map> { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index 4c9d62f610..07918870d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -73,7 +73,7 @@ internal class RustCrossSigningService @Inject constructor( if (verified) { UserTrustResult.Success } else { - UserTrustResult.UnknownCrossSignatureInfo(otherUserId) + UserTrustResult.Failure("failed to verify $otherUserId") } } else { UserTrustResult.CrossSigningNotConfigured(otherUserId) @@ -94,15 +94,13 @@ internal class RustCrossSigningService @Inject constructor( * This will check if the injected private cross signing keys match the public ones provided * by the server and if they do so */ - override fun checkTrustFromPrivateKeys( + override suspend fun checkTrustFromPrivateKeys( masterKeyPrivateKey: String?, uskKeyPrivateKey: String?, sskPrivateKey: String? ): UserTrustResult { val export = PrivateKeysInfo(masterKeyPrivateKey, sskPrivateKey, uskKeyPrivateKey) - return runBlocking { - olmMachineProvider.olmMachine.importCrossSigningKeys(export) - } + return olmMachine.importCrossSigningKeys(export) } /** @@ -171,19 +169,19 @@ internal class RustCrossSigningService @Inject constructor( /** * Sign one of your devices and upload the signature */ - override fun trustDevice(deviceId: String, callback: MatrixCallback) { - val device = runBlocking { olmMachine.getDevice(olmMachine.userId(), deviceId) } + override suspend fun trustDevice(deviceId: String) { + val device = olmMachine.getDevice(olmMachine.userId(), deviceId) return if (device != null) { - val verified = runBlocking { device.verify() } + val verified = device.verify() if (verified) { - callback.onSuccess(Unit) + return } else { - callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known, or not yours")) + throw IllegalArgumentException("This device [$deviceId] is not known, or not yours") } } else { - callback.onFailure(IllegalArgumentException("This device [$deviceId] is not known")) + throw IllegalArgumentException("This device [$deviceId] is not known") } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt index 20e7ca09ab..e86c9c377a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt @@ -16,9 +16,6 @@ package org.matrix.android.sdk.internal.crypto.crosssigning -import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey - sealed class UserTrustResult { object Success : UserTrustResult() @@ -26,10 +23,11 @@ sealed class UserTrustResult { // data class UnknownDevice(val deviceID: String) : UserTrustResult() data class CrossSigningNotConfigured(val userID: String) : UserTrustResult() - data class UnknownCrossSignatureInfo(val userID: String) : UserTrustResult() - data class KeysNotTrusted(val key: MXCrossSigningInfo) : UserTrustResult() - data class KeyNotSigned(val key: CryptoCrossSigningKey) : UserTrustResult() - data class InvalidSignature(val key: CryptoCrossSigningKey, val signature: String) : UserTrustResult() + data class Failure(val message: String) : UserTrustResult() +// data class UnknownCrossSignatureInfo(val userID: String) : UserTrustResult() +// data class KeysNotTrusted(val key: MXCrossSigningInfo) : UserTrustResult() +// data class KeyNotSigned(val key: CryptoCrossSigningKey) : UserTrustResult() +// data class InvalidSignature(val key: CryptoCrossSigningKey, val signature: String) : UserTrustResult() } fun UserTrustResult.isVerified() = this is UserTrustResult.Success diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 03940e89e2..ed29f5b1d0 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -33,7 +33,6 @@ import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME @@ -372,7 +371,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( try { action.cypherData.fromBase64().inputStream().use { ins -> val res = session.loadSecureSecret>(ins, action.alias) - val trustResult = session.cryptoService().crossSigningService().checkTrustFromPrivateKeys( + val crossSigningService = session.cryptoService().crossSigningService() + val trustResult = crossSigningService.checkTrustFromPrivateKeys( res?.get(MASTER_KEY_SSSS_NAME), res?.get(USER_SIGNING_KEY_SSSS_NAME), res?.get(SELF_SIGNING_KEY_SSSS_NAME) @@ -380,12 +380,11 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( if (trustResult.isVerified()) { // Sign this device and upload the signature session.sessionParams.deviceId?.let { deviceId -> - session.cryptoService() - .crossSigningService().trustDevice(deviceId, object : MatrixCallback { - override fun onFailure(failure: Throwable) { - Timber.w(failure, "Failed to sign my device after recovery") - } - }) + try { + crossSigningService.trustDevice(deviceId) + } catch (failure: Exception) { + Timber.w(failure, "Failed to sign my device after recovery") + } } setState { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index c8b595a5ed..b99d1f0aff 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -261,9 +261,7 @@ class DevicesViewModel @AssistedInject constructor( viewModelScope.launch { if (state.hasAccountCrossSigning) { try { - awaitCallback { - session.cryptoService().crossSigningService().trustDevice(action.cryptoDeviceInfo.deviceId, it) - } + session.cryptoService().crossSigningService().trustDevice(action.cryptoDeviceInfo.deviceId) } catch (failure: Throwable) { Timber.e("Failed to manually cross sign device ${action.cryptoDeviceInfo.deviceId} : ${failure.localizedMessage}") _viewEvents.post(DevicesViewEvents.Failure(failure)) From 210e0241d3b3cd9b015eb7866d80450ea1bfaa36 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 25 Nov 2021 12:19:31 +0100 Subject: [PATCH 194/252] Make keybackup service suspend + fixes --- .../sdk/api/listeners/StepProgressListener.kt | 1 + .../crypto/keysbackup/KeysBackupService.kt | 81 +- .../internal/crypto/DefaultCryptoService.kt | 13 +- .../sdk/internal/crypto/MegolmSessionData.kt | 13 +- .../sdk/internal/crypto/RequestSender.kt | 5 +- .../crypto/algorithms/IMXDecrypting.kt | 3 +- .../algorithms/megolm/MXMegolmDecryption.kt | 5 +- .../algorithms/megolm/MXMegolmEncryption.kt | 6 +- .../megolm/MXMegolmEncryptionFactory.kt | 5 +- .../keysbackup/DefaultKeysBackupService.kt | 2876 ++++++++--------- .../keysbackup/KeysBackupStateManager.kt | 11 +- .../crypto/keysbackup/RustKeyBackupService.kt | 763 +++-- .../restore/KeysBackupRestoreActivity.kt | 5 - .../KeysBackupRestoreSharedViewModel.kt | 169 +- .../settings/KeysBackupSettingsViewModel.kt | 61 +- .../setup/KeysBackupSetupSharedViewModel.kt | 131 +- .../recover/BackupToQuadSMigrationTask.kt | 28 +- .../recover/BootstrapCrossSigningTask.kt | 30 +- .../recover/BootstrapSharedViewModel.kt | 12 +- .../VerificationBottomSheetViewModel.kt | 36 +- .../signout/ServerBackupStatusViewModel.kt | 4 +- .../workers/signout/SignoutCheckViewModel.kt | 8 +- vector/src/main/res/values/strings.xml | 2 + 23 files changed, 2105 insertions(+), 2163 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/listeners/StepProgressListener.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/listeners/StepProgressListener.kt index 0fabfed2ff..423885299f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/listeners/StepProgressListener.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/listeners/StepProgressListener.kt @@ -24,6 +24,7 @@ interface StepProgressListener { sealed class Step { data class ComputingKey(val progress: Int, val total: Int) : Step() object DownloadingKey : Step() + data class DecryptingKey(val progress: Int, val total: Int) : Step() data class ImportingKey(val progress: Int, val total: Int) : Step() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index 4464427b90..6bb4dbc620 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.api.session.crypto.keysbackup -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust @@ -31,18 +30,17 @@ interface KeysBackupService { * Retrieve the current version of the backup from the homeserver * * It can be different than keysBackupVersion. - * @param callback onSuccess(null) will be called if there is no backup on the server */ - fun getCurrentVersion(callback: MatrixCallback) + suspend fun getCurrentVersion(): KeysVersionResult? /** * Create a new keys backup version and enable it, using the information return from [prepareKeysBackupVersion]. * * @param keysBackupCreationInfo the info object from [prepareKeysBackupVersion]. - * @param callback Asynchronous callback + * @return KeysVersion */ - fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, - callback: MatrixCallback) + @Throws + suspend fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo): KeysVersion /** * Facility method to get the total number of locally stored keys @@ -54,23 +52,21 @@ interface KeysBackupService { */ fun getTotalNumbersOfBackedUpKeys(): Int - /** - * Start to back up keys immediately. - * - * @param progressListener the callback to follow the progress - * @param callback the main callback - */ - fun backupAllGroupSessions(progressListener: ProgressListener?, - callback: MatrixCallback?) +// /** +// * Start to back up keys immediately. +// * +// * @param progressListener the callback to follow the progress +// * @param callback the main callback +// */ +// fun backupAllGroupSessions(progressListener: ProgressListener?, +// callback: MatrixCallback?) /** * Check trust on a key backup version. * * @param keysBackupVersion the backup version to check. - * @param callback block called when the operations completes. */ - fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult, - callback: MatrixCallback) + suspend fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult): KeysBackupVersionTrust /** * Return the current progress of the backup @@ -82,18 +78,16 @@ interface KeysBackupService { * * It can be different than keysBackupVersion. * @param version the backup version - * @param callback */ - fun getVersion(version: String, - callback: MatrixCallback) + suspend fun getVersion(version: String): KeysVersionResult? /** * This method fetches the last backup version on the server, then compare to the currently backup version use. * If versions are not the same, the current backup is deleted (on server or locally), then the backup may be started again, using the last version. * - * @param callback true if backup is already using the last version, and false if it is not the case + * @return true if backup is already using the last version, and false if it is not the case */ - fun forceUsingLastVersion(callback: MatrixCallback) + suspend fun forceUsingLastVersion(): Boolean /** * Check the server for an active key backup. @@ -101,7 +95,7 @@ interface KeysBackupService { * If one is present and has a valid signature from one of the user's verified * devices, start backing up to it. */ - fun checkAndStartKeysBackup() + suspend fun checkAndStartKeysBackup() fun addListener(listener: KeysBackupStateListener) @@ -119,19 +113,16 @@ interface KeysBackupService { * @param progressListener a progress listener, as generating private key from password may take a while * @param callback Asynchronous callback */ - fun prepareKeysBackupVersion(password: String?, - progressListener: ProgressListener?, - callback: MatrixCallback) + suspend fun prepareKeysBackupVersion(password: String?): MegolmBackupCreationInfo /** * Delete a keys backup version. It will delete all backed up keys on the server, and the backup itself. * If we are backing up to this version. Backup will be stopped. * * @param version the backup version to delete. - * @param callback Asynchronous callback */ - fun deleteBackup(version: String, - callback: MatrixCallback?) + @Throws + suspend fun deleteBackup(version: String) /** * Ask if the backup on the server contains keys that we may do not have locally. @@ -145,35 +136,29 @@ interface KeysBackupService { * * @param keysBackupVersion the backup version to check. * @param trust the trust to set to the keys backup. - * @param callback block called when the operations completes. */ - fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, - trust: Boolean, - callback: MatrixCallback) + @Throws + suspend fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, trust: Boolean) /** * Set trust on a keys backup version. * * @param keysBackupVersion the backup version to check. * @param recoveryKey the recovery key to challenge with the key backup public key. - * @param callback block called when the operations completes. */ - fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, - recoveryKey: String, - callback: MatrixCallback) + suspend fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, + recoveryKey: String) /** * Set trust on a keys backup version. * * @param keysBackupVersion the backup version to check. * @param password the pass phrase to challenge with the keyBackupVersion public key. - * @param callback block called when the operations completes. */ - fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, - password: String, - callback: MatrixCallback) + suspend fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, + password: String) - fun onSecretKeyGossip(secret: String) + suspend fun onSecretKeyGossip(secret: String) /** * Restore a backup with a recovery key from a given backup version stored on the homeserver. @@ -185,11 +170,10 @@ interface KeysBackupService { * @param stepProgressListener the step progress listener * @param callback Callback. It provides the number of found keys and the number of successfully imported keys. */ - fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, + suspend fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, recoveryKey: String, roomId: String?, sessionId: String?, - stepProgressListener: StepProgressListener?, - callback: MatrixCallback) + stepProgressListener: StepProgressListener?): ImportRoomKeysResult /** * Restore a backup with a password from a given backup version stored on the homeserver. @@ -201,12 +185,11 @@ interface KeysBackupService { * @param stepProgressListener the step progress listener * @param callback Callback. It provides the number of found keys and the number of successfully imported keys. */ - fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, + suspend fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, password: String, roomId: String?, sessionId: String?, - stepProgressListener: StepProgressListener?, - callback: MatrixCallback) + stepProgressListener: StepProgressListener?): ImportRoomKeysResult val keysBackupVersion: KeysVersionResult? val currentBackupVersion: String? @@ -218,5 +201,5 @@ interface KeysBackupService { fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? - fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback) + suspend fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String): Boolean } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 3c24df1e0f..1a006c51c5 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -256,7 +256,12 @@ internal class DefaultCryptoService @Inject constructor( } override fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int { - return cryptoStore.inboundGroupSessionsCount(onlyBackedUp) + return if (onlyBackedUp) { + keysBackupService.getTotalNumbersOfBackedUpKeys() + } else { + keysBackupService.getTotalNumbersOfKeys() + } + // return cryptoStore.inboundGroupSessionsCount(onlyBackedUp) } /** @@ -331,8 +336,10 @@ internal class DefaultCryptoService @Inject constructor( // We try to enable key backups, if the backup version on the server is trusted, // we're gonna continue backing up. - tryOrNull { - keysBackupService.checkAndStartKeysBackup() + cryptoCoroutineScope.launch { + tryOrNull { + keysBackupService.checkAndStartKeysBackup() + } } // Open the store diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt index caff2d76f1..d3100ede7d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt @@ -70,4 +70,15 @@ data class MegolmSessionData( */ @Json(name = "forwarding_curve25519_key_chain") val forwardingCurve25519KeyChain: List? = null -) +) { + + fun isValid(): Boolean { + return roomId != null && + forwardingCurve25519KeyChain != null && + algorithm != null && + senderKey != null && + senderClaimedKeys != null && + sessionId != null && + sessionKey != null + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt index 6ce0fea71e..45644d951f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt @@ -213,13 +213,14 @@ internal class RequestSender @Inject constructor( suspend fun getKeyBackupVersion(version: String? = null): KeysVersionResult? { return try { if (version != null) { - getKeysBackupVersionTask.execute(version) + getKeysBackupVersionTask.executeRetry(version, 3) } else { - getKeysBackupLastVersionTask.execute(Unit) + getKeysBackupLastVersionTask.executeRetry(Unit, 3) } } catch (failure: Throwable) { if (failure is Failure.ServerError && failure.error.code == MatrixError.M_NOT_FOUND) { + // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup null } else { throw failure diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt index b9cfd942ce..54ccbf016f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt @@ -21,7 +21,6 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult -import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService /** * An interface for decrypting data @@ -44,7 +43,7 @@ internal interface IMXDecrypting { * * @param event the key event. */ - fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {} + fun onRoomKeyEvent(event: Event/*, defaultKeysBackupService: DefaultKeysBackupService*/) {} /** * Check if the some messages can be decrypted with a new session diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index 8bbc71543c..ea239dad53 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -34,7 +34,6 @@ import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevice import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter import org.matrix.android.sdk.internal.crypto.algorithms.IMXDecrypting import org.matrix.android.sdk.internal.crypto.algorithms.IMXWithHeldExtension -import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent @@ -232,7 +231,7 @@ internal class MXMegolmDecryption(private val userId: String, * * @param event the key event. */ - override fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) { + override fun onRoomKeyEvent(event: Event/*, defaultKeysBackupService: DefaultKeysBackupService*/) { Timber.tag(loggerTag.value).v("onRoomKeyEvent()") var exportFormat = false val roomKeyContent = event.getClearContent().toModel() ?: return @@ -295,7 +294,7 @@ internal class MXMegolmDecryption(private val userId: String, exportFormat) if (added) { - defaultKeysBackupService.maybeBackupKeys() + // defaultKeysBackupService.maybeBackupKeys() val content = RoomKeyRequestBody( algorithm = roomKeyContent.algorithm, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index 44b59b208a..bc479f0537 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -31,7 +31,7 @@ import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevice import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting import org.matrix.android.sdk.internal.crypto.algorithms.IMXGroupEncryption -import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService +// import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent @@ -53,7 +53,7 @@ internal class MXMegolmEncryption( // The id of the room we will be sending to. private val roomId: String, private val olmDevice: MXOlmDevice, - private val defaultKeysBackupService: DefaultKeysBackupService, +// private val defaultKeysBackupService: DefaultKeysBackupService, private val cryptoStore: IMXCryptoStore, private val deviceListManager: DeviceListManager, private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction, @@ -149,7 +149,7 @@ internal class MXMegolmEncryption( olmDevice.addInboundGroupSession(sessionId!!, olmDevice.getSessionKey(sessionId)!!, roomId, olmDevice.deviceCurve25519Key!!, emptyList(), keysClaimedMap, false) - defaultKeysBackupService.maybeBackupKeys() +// defaultKeysBackupService.maybeBackupKeys() return MXOutboundSessionInfo(sessionId, SharedWithHelper(roomId, sessionId, cryptoStore)) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt index 136fdc05f5..3797f3a588 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryptionFactory.kt @@ -22,7 +22,6 @@ import org.matrix.android.sdk.internal.crypto.DeviceListManager import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter -import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask @@ -32,7 +31,7 @@ import javax.inject.Inject internal class MXMegolmEncryptionFactory @Inject constructor( private val olmDevice: MXOlmDevice, - private val defaultKeysBackupService: DefaultKeysBackupService, +// private val defaultKeysBackupService: DefaultKeysBackupService, private val cryptoStore: IMXCryptoStore, private val deviceListManager: DeviceListManager, private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction, @@ -48,7 +47,7 @@ internal class MXMegolmEncryptionFactory @Inject constructor( return MXMegolmEncryption( roomId = roomId, olmDevice = olmDevice, - defaultKeysBackupService = defaultKeysBackupService, +// defaultKeysBackupService = defaultKeysBackupService, cryptoStore = cryptoStore, deviceListManager = deviceListManager, ensureOlmSessionsForDevicesAction = ensureOlmSessionsForDevicesAction, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index b0c7c8b610..c70a01f54e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -1,1438 +1,1438 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.keysbackup - -import android.os.Handler -import android.os.Looper -import androidx.annotation.UiThread -import androidx.annotation.VisibleForTesting -import androidx.annotation.WorkerThread -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.MatrixCoroutineDispatchers -import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.api.failure.Failure -import org.matrix.android.sdk.api.failure.MatrixError -import org.matrix.android.sdk.api.listeners.ProgressListener -import org.matrix.android.sdk.api.listeners.StepProgressListener -import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService -import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState -import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP -import org.matrix.android.sdk.internal.crypto.MXOlmDevice -import org.matrix.android.sdk.internal.crypto.MegolmSessionData -import org.matrix.android.sdk.internal.crypto.ObjectSigner -import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrustSignature -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteRoomSessionDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteRoomSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask -import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask -import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey -import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo -import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity -import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.extensions.foldToCallback -import org.matrix.android.sdk.internal.session.SessionScope -import org.matrix.android.sdk.internal.task.Task -import org.matrix.android.sdk.internal.task.TaskExecutor -import org.matrix.android.sdk.internal.task.TaskThread -import org.matrix.android.sdk.internal.task.configureWith -import org.matrix.android.sdk.internal.util.JsonCanonicalizer -import org.matrix.android.sdk.internal.util.awaitCallback -import org.matrix.olm.OlmException -import org.matrix.olm.OlmPkDecryption -import org.matrix.olm.OlmPkEncryption -import org.matrix.olm.OlmPkMessage -import timber.log.Timber -import java.security.InvalidParameterException -import javax.inject.Inject -import kotlin.random.Random - -/** - * A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys) - * to the user's homeserver. - */ -@SessionScope -@Deprecated("use rust") -internal class DefaultKeysBackupService @Inject constructor( - @UserId private val userId: String, - private val credentials: Credentials, - private val cryptoStore: IMXCryptoStore, - private val olmDevice: MXOlmDevice, - private val objectSigner: ObjectSigner, - // Actions - private val megolmSessionDataImporter: MegolmSessionDataImporter, - // Tasks - private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, - private val deleteBackupTask: DeleteBackupTask, - private val deleteRoomSessionDataTask: DeleteRoomSessionDataTask, - private val deleteRoomSessionsDataTask: DeleteRoomSessionsDataTask, - private val deleteSessionDataTask: DeleteSessionsDataTask, - private val getKeysBackupLastVersionTask: GetKeysBackupLastVersionTask, - private val getKeysBackupVersionTask: GetKeysBackupVersionTask, - private val getRoomSessionDataTask: GetRoomSessionDataTask, - private val getRoomSessionsDataTask: GetRoomSessionsDataTask, - private val getSessionsDataTask: GetSessionsDataTask, - private val storeRoomSessionDataTask: StoreRoomSessionDataTask, - private val storeSessionsDataTask: StoreRoomSessionsDataTask, - private val storeSessionDataTask: StoreSessionsDataTask, - private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask, - // Task executor - private val taskExecutor: TaskExecutor, - private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val cryptoCoroutineScope: CoroutineScope -) : KeysBackupService { - - private val uiHandler = Handler(Looper.getMainLooper()) - - private val keysBackupStateManager = KeysBackupStateManager(uiHandler) - - // The backup version - override var keysBackupVersion: KeysVersionResult? = null - private set - - // The backup key being used. - private var backupOlmPkEncryption: OlmPkEncryption? = null - - private var backupAllGroupSessionsCallback: MatrixCallback? = null - - private var keysBackupStateListener: KeysBackupStateListener? = null - - override val isEnabled: Boolean - get() = keysBackupStateManager.isEnabled - - override val isStucked: Boolean - get() = keysBackupStateManager.isStucked - - override val state: KeysBackupState - get() = keysBackupStateManager.state - - override val currentBackupVersion: String? - get() = keysBackupVersion?.version - - override fun addListener(listener: KeysBackupStateListener) { - keysBackupStateManager.addListener(listener) - } - - override fun removeListener(listener: KeysBackupStateListener) { - keysBackupStateManager.removeListener(listener) - } - - override fun prepareKeysBackupVersion(password: String?, - progressListener: ProgressListener?, - callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - withContext(coroutineDispatchers.crypto) { - val olmPkDecryption = OlmPkDecryption() - val signalableMegolmBackupAuthData = if (password != null) { - // Generate a private key from the password - val backgroundProgressListener = if (progressListener == null) { - null - } else { - object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - uiHandler.post { - try { - progressListener.onProgress(progress, total) - } catch (e: Exception) { - Timber.e(e, "prepareKeysBackupVersion: onProgress failure") - } - } - } - } - } - - val generatePrivateKeyResult = generatePrivateKeyWithPassword(password, backgroundProgressListener) - SignalableMegolmBackupAuthData( - publicKey = olmPkDecryption.setPrivateKey(generatePrivateKeyResult.privateKey), - privateKeySalt = generatePrivateKeyResult.salt, - privateKeyIterations = generatePrivateKeyResult.iterations - ) - } else { - val publicKey = olmPkDecryption.generateKey() - - SignalableMegolmBackupAuthData( - publicKey = publicKey - ) - } - - val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableMegolmBackupAuthData.signalableJSONDictionary()) - - val signedMegolmBackupAuthData = MegolmBackupAuthData( - publicKey = signalableMegolmBackupAuthData.publicKey, - privateKeySalt = signalableMegolmBackupAuthData.privateKeySalt, - privateKeyIterations = signalableMegolmBackupAuthData.privateKeyIterations, - signatures = objectSigner.signObject(canonicalJson) - ) - - MegolmBackupCreationInfo( - algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP, - authData = signedMegolmBackupAuthData, - recoveryKey = computeRecoveryKey(olmPkDecryption.privateKey()) - ) - } - }.foldToCallback(callback) - } - } - - override fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, - callback: MatrixCallback) { - @Suppress("UNCHECKED_CAST") - val createKeysBackupVersionBody = CreateKeysBackupVersionBody( - algorithm = keysBackupCreationInfo.algorithm, - authData = keysBackupCreationInfo.authData.toJsonDict() - ) - - keysBackupStateManager.state = KeysBackupState.Enabling - - createKeysBackupVersionTask - .configureWith(createKeysBackupVersionBody) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: KeysVersion) { - // Reset backup markers. - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - // move tx out of UI thread - cryptoStore.resetBackupMarkers() - } - - val keyBackupVersion = KeysVersionResult( - algorithm = createKeysBackupVersionBody.algorithm, - authData = createKeysBackupVersionBody.authData, - version = data.version, - // We can consider that the server does not have keys yet - count = 0, - hash = "" - ) - - enableKeysBackup(keyBackupVersion) - - callback.onSuccess(data) - } - - override fun onFailure(failure: Throwable) { - keysBackupStateManager.state = KeysBackupState.Disabled - callback.onFailure(failure) - } - } - } - .executeBy(taskExecutor) - } - - override fun deleteBackup(version: String, callback: MatrixCallback?) { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - withContext(coroutineDispatchers.crypto) { - // If we're currently backing up to this backup... stop. - // (We start using it automatically in createKeysBackupVersion so this is symmetrical). - if (keysBackupVersion != null && version == keysBackupVersion?.version) { - resetKeysBackupData() - keysBackupVersion = null - keysBackupStateManager.state = KeysBackupState.Unknown - } - - deleteBackupTask - .configureWith(DeleteBackupTask.Params(version)) { - this.callback = object : MatrixCallback { - private fun eventuallyRestartBackup() { - // Do not stay in KeysBackupState.Unknown but check what is available on the homeserver - if (state == KeysBackupState.Unknown) { - checkAndStartKeysBackup() - } - } - - override fun onSuccess(data: Unit) { - eventuallyRestartBackup() - - uiHandler.post { callback?.onSuccess(Unit) } - } - - override fun onFailure(failure: Throwable) { - eventuallyRestartBackup() - - uiHandler.post { callback?.onFailure(failure) } - } - } - } - .executeBy(taskExecutor) - } - } - } - - override fun canRestoreKeys(): Boolean { - // Server contains more keys than locally - val totalNumberOfKeysLocally = getTotalNumbersOfKeys() - - val keysBackupData = cryptoStore.getKeysBackupData() - - val totalNumberOfKeysServer = keysBackupData?.backupLastServerNumberOfKeys ?: -1 - // Not used for the moment - // val hashServer = keysBackupData?.backupLastServerHash - - return when { - totalNumberOfKeysLocally < totalNumberOfKeysServer -> { - // Server contains more keys than this device - true - } - totalNumberOfKeysLocally == totalNumberOfKeysServer -> { - // Same number, compare hash? - // TODO We have not found any algorithm to determine if a restore is recommended here. Return false for the moment - false - } - else -> false - } - } - - override fun getTotalNumbersOfKeys(): Int { - return cryptoStore.inboundGroupSessionsCount(false) - } - - override fun getTotalNumbersOfBackedUpKeys(): Int { - return cryptoStore.inboundGroupSessionsCount(true) - } - - override fun backupAllGroupSessions(progressListener: ProgressListener?, - callback: MatrixCallback?) { - // Get a status right now - getBackupProgress(object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - // Reset previous listeners if any - resetBackupAllGroupSessionsListeners() - Timber.v("backupAllGroupSessions: backupProgress: $progress/$total") - try { - progressListener?.onProgress(progress, total) - } catch (e: Exception) { - Timber.e(e, "backupAllGroupSessions: onProgress failure") - } - - if (progress == total) { - Timber.v("backupAllGroupSessions: complete") - callback?.onSuccess(Unit) - return - } - - backupAllGroupSessionsCallback = callback - - // Listen to `state` change to determine when to call onBackupProgress and onComplete - keysBackupStateListener = object : KeysBackupStateListener { - override fun onStateChange(newState: KeysBackupState) { - getBackupProgress(object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - try { - progressListener?.onProgress(progress, total) - } catch (e: Exception) { - Timber.e(e, "backupAllGroupSessions: onProgress failure 2") - } - - // If backup is finished, notify the main listener - if (state === KeysBackupState.ReadyToBackUp) { - backupAllGroupSessionsCallback?.onSuccess(Unit) - resetBackupAllGroupSessionsListeners() - } - } - }) - } - }.also { keysBackupStateManager.addListener(it) } - - backupKeys() - } - }) - } - - override fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult, - callback: MatrixCallback) { - // TODO Validate with François that this is correct - object : Task { - override suspend fun execute(params: KeysVersionResult): KeysBackupVersionTrust { - return getKeysBackupTrustBg(params) - } - } - .configureWith(keysBackupVersion) { - this.callback = callback - this.executionThread = TaskThread.COMPUTATION - } - .executeBy(taskExecutor) - } - - /** - * Check trust on a key backup version. - * This has to be called on background thread. - * - * @param keysBackupVersion the backup version to check. - * @return a KeysBackupVersionTrust object - */ - @WorkerThread - private fun getKeysBackupTrustBg(keysBackupVersion: KeysVersionResult): KeysBackupVersionTrust { - val keysBackupVersionTrust = KeysBackupVersionTrust() - val authData = keysBackupVersion.getAuthDataAsMegolmBackupAuthData() - - if (authData == null || authData.publicKey.isEmpty() || authData.signatures.isNullOrEmpty()) { - Timber.v("getKeysBackupTrust: Key backup is absent or missing required data") - return keysBackupVersionTrust - } - - val mySigs = authData.signatures[userId] - if (mySigs.isNullOrEmpty()) { - Timber.v("getKeysBackupTrust: Ignoring key backup because it lacks any signatures from this user") - return keysBackupVersionTrust - } - - for ((keyId, mySignature) in mySigs) { - // XXX: is this how we're supposed to get the device id? - var deviceId: String? = null - val components = keyId.split(":") - if (components.size == 2) { - deviceId = components[1] - } - - if (deviceId != null) { - val device = cryptoStore.getUserDevice(userId, deviceId) - var isSignatureValid = false - - if (device == null) { - Timber.v("getKeysBackupTrust: Signature from unknown device $deviceId") - } else { - val fingerprint = device.fingerprint() - if (fingerprint != null) { - try { - olmDevice.verifySignature(fingerprint, authData.signalableJSONDictionary(), mySignature) - isSignatureValid = true - } catch (e: OlmException) { - Timber.w(e, "getKeysBackupTrust: Bad signature from device ${device.deviceId}") - } - } - - if (isSignatureValid && device.isVerified) { - keysBackupVersionTrust.usable = true - } - } - - val signature = KeysBackupVersionTrustSignature() - signature.device = device - signature.valid = isSignatureValid - signature.deviceId = deviceId - keysBackupVersionTrust.signatures.add(signature) - } - } - - return keysBackupVersionTrust - } - - override fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, - trust: Boolean, - callback: MatrixCallback) { - Timber.v("trustKeyBackupVersion: $trust, version ${keysBackupVersion.version}") - - // Get auth data to update it - val authData = getMegolmBackupAuthData(keysBackupVersion) - - if (authData == null) { - Timber.w("trustKeyBackupVersion:trust: Key backup is missing required data") - - callback.onFailure(IllegalArgumentException("Missing element")) - } else { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - val updateKeysBackupVersionBody = withContext(coroutineDispatchers.crypto) { - // Get current signatures, or create an empty set - val myUserSignatures = authData.signatures?.get(userId).orEmpty().toMutableMap() - - if (trust) { - // Add current device signature - val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, authData.signalableJSONDictionary()) - - val deviceSignatures = objectSigner.signObject(canonicalJson) - - deviceSignatures[userId]?.forEach { entry -> - myUserSignatures[entry.key] = entry.value - } - } else { - // Remove current device signature - myUserSignatures.remove("ed25519:${credentials.deviceId}") - } - - // Create an updated version of KeysVersionResult - val newMegolmBackupAuthData = authData.copy() - - val newSignatures = newMegolmBackupAuthData.signatures.orEmpty().toMutableMap() - newSignatures[userId] = myUserSignatures - - val newMegolmBackupAuthDataWithNewSignature = newMegolmBackupAuthData.copy( - signatures = newSignatures - ) - - @Suppress("UNCHECKED_CAST") - UpdateKeysBackupVersionBody( - algorithm = keysBackupVersion.algorithm, - authData = newMegolmBackupAuthDataWithNewSignature.toJsonDict(), - version = keysBackupVersion.version) - } - - // And send it to the homeserver - updateKeysBackupVersionTask - .configureWith(UpdateKeysBackupVersionTask.Params(keysBackupVersion.version, updateKeysBackupVersionBody)) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: Unit) { - // Relaunch the state machine on this updated backup version - val newKeysBackupVersion = KeysVersionResult( - algorithm = keysBackupVersion.algorithm, - authData = updateKeysBackupVersionBody.authData, - version = keysBackupVersion.version, - hash = keysBackupVersion.hash, - count = keysBackupVersion.count - ) - - checkAndStartWithKeysBackupVersion(newKeysBackupVersion) - - callback.onSuccess(data) - } - - override fun onFailure(failure: Throwable) { - callback.onFailure(failure) - } - } - } - .executeBy(taskExecutor) - } - } - } - - override fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, - recoveryKey: String, - callback: MatrixCallback) { - Timber.v("trustKeysBackupVersionWithRecoveryKey: version ${keysBackupVersion.version}") - - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - val isValid = withContext(coroutineDispatchers.crypto) { - isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion) - } - - if (!isValid) { - Timber.w("trustKeyBackupVersionWithRecoveryKey: Invalid recovery key.") - - callback.onFailure(IllegalArgumentException("Invalid recovery key or password")) - } else { - trustKeysBackupVersion(keysBackupVersion, true, callback) - } - } - } - - override fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, - password: String, - callback: MatrixCallback) { - Timber.v("trustKeysBackupVersionWithPassphrase: version ${keysBackupVersion.version}") - - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - val recoveryKey = withContext(coroutineDispatchers.crypto) { - recoveryKeyFromPassword(password, keysBackupVersion, null) - } - - if (recoveryKey == null) { - Timber.w("trustKeysBackupVersionWithPassphrase: Key backup is missing required data") - - callback.onFailure(IllegalArgumentException("Missing element")) - } else { - // Check trust using the recovery key - trustKeysBackupVersionWithRecoveryKey(keysBackupVersion, recoveryKey, callback) - } - } - } - - override fun onSecretKeyGossip(secret: String) { - Timber.i("## CrossSigning - onSecretKeyGossip") - - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - try { - val keysBackupVersion = getKeysBackupLastVersionTask.execute(Unit) - val recoveryKey = computeRecoveryKey(secret.fromBase64()) - if (isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)) { - awaitCallback { - trustKeysBackupVersion(keysBackupVersion, true, it) - } - val importResult = awaitCallback { - restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, null, null, null, it) - } - withContext(coroutineDispatchers.crypto) { - cryptoStore.saveBackupRecoveryKey(recoveryKey, keysBackupVersion.version) - } - Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") - } else { - Timber.e("onSecretKeyGossip: Recovery key is not valid ${keysBackupVersion.version}") - } - } catch (failure: Throwable) { - Timber.e("onSecretKeyGossip: failed to trust key backup version ${keysBackupVersion?.version}") - } - } - } - - /** - * Get public key from a Recovery key - * - * @param recoveryKey the recovery key - * @return the corresponding public key, from Olm - */ - @WorkerThread - private fun pkPublicKeyFromRecoveryKey(recoveryKey: String): String? { - // Extract the primary key - val privateKey = extractCurveKeyFromRecoveryKey(recoveryKey) - - if (privateKey == null) { - Timber.w("pkPublicKeyFromRecoveryKey: private key is null") - - return null - } - - // Built the PK decryption with it - val pkPublicKey: String - - try { - val decryption = OlmPkDecryption() - pkPublicKey = decryption.setPrivateKey(privateKey) - } catch (e: OlmException) { - return null - } - - return pkPublicKey - } - - private fun resetBackupAllGroupSessionsListeners() { - backupAllGroupSessionsCallback = null - - keysBackupStateListener?.let { - keysBackupStateManager.removeListener(it) - } - - keysBackupStateListener = null - } - - override fun getBackupProgress(progressListener: ProgressListener) { - val backedUpKeys = cryptoStore.inboundGroupSessionsCount(true) - val total = cryptoStore.inboundGroupSessionsCount(false) - - progressListener.onProgress(backedUpKeys, total) - } - - override fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, - recoveryKey: String, - roomId: String?, - sessionId: String?, - stepProgressListener: StepProgressListener?, - callback: MatrixCallback) { - Timber.v("restoreKeysWithRecoveryKey: From backup version: ${keysVersionResult.version}") - - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - val decryption = withContext(coroutineDispatchers.crypto) { - // Check if the recovery is valid before going any further - if (!isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysVersionResult)) { - Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key for this keys version") - throw InvalidParameterException("Invalid recovery key") - } - - // Get a PK decryption instance - pkDecryptionFromRecoveryKey(recoveryKey) - } - if (decryption == null) { - // This should not happen anymore - Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key. Error") - throw InvalidParameterException("Invalid recovery key") - } - - stepProgressListener?.onStepProgress(StepProgressListener.Step.DownloadingKey) - - // Get backed up keys from the homeserver - val data = getKeys(sessionId, roomId, keysVersionResult.version) - - withContext(coroutineDispatchers.computation) { - val sessionsData = ArrayList() - // Restore that data - var sessionsFromHsCount = 0 - for ((roomIdLoop, backupData) in data.roomIdToRoomKeysBackupData) { - for ((sessionIdLoop, keyBackupData) in backupData.sessionIdToKeyBackupData) { - sessionsFromHsCount++ - - val sessionData = decryptKeyBackupData(keyBackupData, sessionIdLoop, roomIdLoop, decryption) - - sessionData?.let { - sessionsData.add(it) - } - } - } - Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" + - " of $sessionsFromHsCount from the backup store on the homeserver") - - // Do not trigger a backup for them if they come from the backup version we are using - val backUp = keysVersionResult.version != keysBackupVersion?.version - if (backUp) { - Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up" + - " to backup version: ${keysBackupVersion?.version}") - } - - // Import them into the crypto store - val progressListener = if (stepProgressListener != null) { - object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - // Note: no need to post to UI thread, importMegolmSessionsData() will do it - stepProgressListener.onStepProgress(StepProgressListener.Step.ImportingKey(progress, total)) - } - } - } else { - null - } - - val result = megolmSessionDataImporter.handle(sessionsData, !backUp, progressListener) - - // Do not back up the key if it comes from a backup recovery - if (backUp) { - maybeBackupKeys() - } - // Save for next time and for gossiping - saveBackupRecoveryKey(recoveryKey, keysVersionResult.version) - result - } - }.foldToCallback(callback) - } - } - - override fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, - password: String, - roomId: String?, - sessionId: String?, - stepProgressListener: StepProgressListener?, - callback: MatrixCallback) { - Timber.v("[MXKeyBackup] restoreKeyBackup with password: From backup version: ${keysBackupVersion.version}") - - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - val progressListener = if (stepProgressListener != null) { - object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - uiHandler.post { - stepProgressListener.onStepProgress(StepProgressListener.Step.ComputingKey(progress, total)) - } - } - } - } else { - null - } - - val recoveryKey = withContext(coroutineDispatchers.crypto) { - recoveryKeyFromPassword(password, keysBackupVersion, progressListener) - } - if (recoveryKey == null) { - Timber.v("backupKeys: Invalid configuration") - throw IllegalStateException("Invalid configuration") - } else { - awaitCallback { - restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener, it) - } - } - }.foldToCallback(callback) - } - } - - /** - * Same method as [RoomKeysRestClient.getRoomKey] except that it accepts nullable - * parameters and always returns a KeysBackupData object through the Callback - */ - private suspend fun getKeys(sessionId: String?, - roomId: String?, - version: String): KeysBackupData { - return if (roomId != null && sessionId != null) { - // Get key for the room and for the session - val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version)) - // Convert to KeysBackupData - KeysBackupData(mutableMapOf( - roomId to RoomKeysBackupData(mutableMapOf( - sessionId to data - )) - )) - } else if (roomId != null) { - // Get all keys for the room - val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version)) - // Convert to KeysBackupData - KeysBackupData(mutableMapOf(roomId to data)) - } else { - // Get all keys - getSessionsDataTask.execute(GetSessionsDataTask.Params(version)) - } - } - - @VisibleForTesting - @WorkerThread - fun pkDecryptionFromRecoveryKey(recoveryKey: String): OlmPkDecryption? { - // Extract the primary key - val privateKey = extractCurveKeyFromRecoveryKey(recoveryKey) - - // Built the PK decryption with it - var decryption: OlmPkDecryption? = null - if (privateKey != null) { - try { - decryption = OlmPkDecryption() - decryption.setPrivateKey(privateKey) - } catch (e: OlmException) { - Timber.e(e, "OlmException") - } - } - - return decryption - } - - /** - * Do a backup if there are new keys, with a delay - */ - fun maybeBackupKeys() { - when { - isStucked -> { - // If not already done, or in error case, check for a valid backup version on the homeserver. - // If there is one, maybeBackupKeys will be called again. - checkAndStartKeysBackup() - } - state == KeysBackupState.ReadyToBackUp -> { - keysBackupStateManager.state = KeysBackupState.WillBackUp - - // Wait between 0 and 10 seconds, to avoid backup requests from - // different clients hitting the server all at the same time when a - // new key is sent - val delayInMs = Random.nextLong(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS) - - cryptoCoroutineScope.launch { - delay(delayInMs) - uiHandler.post { backupKeys() } - } - } - else -> { - Timber.v("maybeBackupKeys: Skip it because state: $state") - } - } - } - - override fun getVersion(version: String, - callback: MatrixCallback) { - getKeysBackupVersionTask - .configureWith(version) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult) { - callback.onSuccess(data) - } - - override fun onFailure(failure: Throwable) { - if (failure is Failure.ServerError && - failure.error.code == MatrixError.M_NOT_FOUND) { - // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup - callback.onSuccess(null) - } else { - // Transmit the error - callback.onFailure(failure) - } - } - } - } - .executeBy(taskExecutor) - } - - override fun getCurrentVersion(callback: MatrixCallback) { - getKeysBackupLastVersionTask - .configureWith { - this.callback = object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult) { - callback.onSuccess(data) - } - - override fun onFailure(failure: Throwable) { - if (failure is Failure.ServerError && - failure.error.code == MatrixError.M_NOT_FOUND) { - // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup - callback.onSuccess(null) - } else { - // Transmit the error - callback.onFailure(failure) - } - } - } - } - .executeBy(taskExecutor) - } - - override fun forceUsingLastVersion(callback: MatrixCallback) { - getCurrentVersion(object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult?) { - val localBackupVersion = keysBackupVersion?.version - val serverBackupVersion = data?.version - - if (serverBackupVersion == null) { - if (localBackupVersion == null) { - // No backup on the server, and backup is not active - callback.onSuccess(true) - } else { - // No backup on the server, and we are currently backing up, so stop backing up - callback.onSuccess(false) - resetKeysBackupData() - keysBackupVersion = null - keysBackupStateManager.state = KeysBackupState.Disabled - } - } else { - if (localBackupVersion == null) { - // backup on the server, and backup is not active - callback.onSuccess(false) - // Do a check - checkAndStartWithKeysBackupVersion(data) - } else { - // Backup on the server, and we are currently backing up, compare version - if (localBackupVersion == serverBackupVersion) { - // We are already using the last version of the backup - callback.onSuccess(true) - } else { - // We are not using the last version, so delete the current version we are using on the server - callback.onSuccess(false) - - // This will automatically check for the last version then - deleteBackup(localBackupVersion, null) - } - } - } - } - - override fun onFailure(failure: Throwable) { - callback.onFailure(failure) - } - }) - } - - override fun checkAndStartKeysBackup() { - if (!isStucked) { - // Try to start or restart the backup only if it is in unknown or bad state - Timber.w("checkAndStartKeysBackup: invalid state: $state") - - return - } - - keysBackupVersion = null - keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver - - getCurrentVersion(object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult?) { - checkAndStartWithKeysBackupVersion(data) - } - - override fun onFailure(failure: Throwable) { - Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version") - keysBackupStateManager.state = KeysBackupState.Unknown - } - }) - } - - private fun checkAndStartWithKeysBackupVersion(keyBackupVersion: KeysVersionResult?) { - Timber.v("checkAndStartWithKeyBackupVersion: ${keyBackupVersion?.version}") - - keysBackupVersion = keyBackupVersion - - if (keyBackupVersion == null) { - Timber.v("checkAndStartWithKeysBackupVersion: Found no key backup version on the homeserver") - resetKeysBackupData() - keysBackupStateManager.state = KeysBackupState.Disabled - } else { - getKeysBackupTrust(keyBackupVersion, object : MatrixCallback { - override fun onSuccess(data: KeysBackupVersionTrust) { - val versionInStore = cryptoStore.getKeyBackupVersion() - - if (data.usable) { - Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: ${keyBackupVersion.version}") - // Check the version we used at the previous app run - if (versionInStore != null && versionInStore != keyBackupVersion.version) { - Timber.v(" -> clean the previously used version $versionInStore") - resetKeysBackupData() - } - - Timber.v(" -> enabling key backups") - enableKeysBackup(keyBackupVersion) - } else { - Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: ${keyBackupVersion.version}") - if (versionInStore != null) { - Timber.v(" -> disabling key backup") - resetKeysBackupData() - } - - keysBackupStateManager.state = KeysBackupState.NotTrusted - } - } - - override fun onFailure(failure: Throwable) { - // Cannot happen - } - }) - } - } - -/* ========================================================================================== - * Private - * ========================================================================================== */ - - /** - * Extract MegolmBackupAuthData data from a backup version. - * - * @param keysBackupData the key backup data - * - * @return the authentication if found and valid, null in other case - */ - private fun getMegolmBackupAuthData(keysBackupData: KeysVersionResult): MegolmBackupAuthData? { - return keysBackupData - .takeIf { it.version.isNotEmpty() && it.algorithm == MXCRYPTO_ALGORITHM_MEGOLM_BACKUP } - ?.getAuthDataAsMegolmBackupAuthData() - ?.takeIf { it.publicKey.isNotEmpty() } - } - - /** - * Compute the recovery key from a password and key backup version. - * - * @param password the password. - * @param keysBackupData the backup and its auth data. - * - * @return the recovery key if successful, null in other cases - */ - @WorkerThread - private fun recoveryKeyFromPassword(password: String, keysBackupData: KeysVersionResult, progressListener: ProgressListener?): String? { - val authData = getMegolmBackupAuthData(keysBackupData) - - if (authData == null) { - Timber.w("recoveryKeyFromPassword: invalid parameter") - return null - } - - if (authData.privateKeySalt.isNullOrBlank() || - authData.privateKeyIterations == null) { - Timber.w("recoveryKeyFromPassword: Salt and/or iterations not found in key backup auth data") - - return null - } - - // Extract the recovery key from the passphrase - val data = retrievePrivateKeyWithPassword(password, authData.privateKeySalt, authData.privateKeyIterations, progressListener) - - return computeRecoveryKey(data) - } - - /** - * Check if a recovery key matches key backup authentication data. - * - * @param recoveryKey the recovery key to challenge. - * @param keysBackupData the backup and its auth data. - * - * @return true if successful. - */ - @WorkerThread - private fun isValidRecoveryKeyForKeysBackupVersion(recoveryKey: String, keysBackupData: KeysVersionResult): Boolean { - // Build PK decryption instance with the recovery key - val publicKey = pkPublicKeyFromRecoveryKey(recoveryKey) - - if (publicKey == null) { - Timber.w("isValidRecoveryKeyForKeysBackupVersion: public key is null") - - return false - } - - val authData = getMegolmBackupAuthData(keysBackupData) - - if (authData == null) { - Timber.w("isValidRecoveryKeyForKeysBackupVersion: Key backup is missing required data") - - return false - } - - // Compare both - if (publicKey != authData.publicKey) { - Timber.w("isValidRecoveryKeyForKeysBackupVersion: Public keys mismatch") - - return false - } - - // Public keys match! - return true - } - - override fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback) { - val safeKeysBackupVersion = keysBackupVersion ?: return Unit.also { callback.onSuccess(false) } - - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - isValidRecoveryKeyForKeysBackupVersion(recoveryKey, safeKeysBackupVersion).let { - callback.onSuccess(it) - } - } - } - - /** - * Enable backing up of keys. - * This method will update the state and will start sending keys in nominal case - * - * @param keysVersionResult backup information object as returned by [getCurrentVersion]. - */ - private fun enableKeysBackup(keysVersionResult: KeysVersionResult) { - val retrievedMegolmBackupAuthData = keysVersionResult.getAuthDataAsMegolmBackupAuthData() - - if (retrievedMegolmBackupAuthData != null) { - keysBackupVersion = keysVersionResult - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - cryptoStore.setKeyBackupVersion(keysVersionResult.version) - } - - onServerDataRetrieved(keysVersionResult.count, keysVersionResult.hash) - - try { - backupOlmPkEncryption = OlmPkEncryption().apply { - setRecipientKey(retrievedMegolmBackupAuthData.publicKey) - } - } catch (e: OlmException) { - Timber.e(e, "OlmException") - keysBackupStateManager.state = KeysBackupState.Disabled - return - } - - keysBackupStateManager.state = KeysBackupState.ReadyToBackUp - - maybeBackupKeys() - } else { - Timber.e("Invalid authentication data") - keysBackupStateManager.state = KeysBackupState.Disabled - } - } - - /** - * Update the DB with data fetch from the server - */ - private fun onServerDataRetrieved(count: Int?, etag: String?) { - cryptoStore.setKeysBackupData(KeysBackupDataEntity() - .apply { - backupLastServerNumberOfKeys = count - backupLastServerHash = etag - } - ) - } - - /** - * Reset all local key backup data. - * - * Note: This method does not update the state - */ - private fun resetKeysBackupData() { - resetBackupAllGroupSessionsListeners() - - cryptoStore.setKeyBackupVersion(null) - cryptoStore.setKeysBackupData(null) - backupOlmPkEncryption?.releaseEncryption() - backupOlmPkEncryption = null - - // Reset backup markers - cryptoStore.resetBackupMarkers() - } - - /** - * Send a chunk of keys to backup - */ - @UiThread - private fun backupKeys() { - Timber.v("backupKeys") - - // Sanity check, as this method can be called after a delay, the state may have change during the delay - if (!isEnabled || backupOlmPkEncryption == null || keysBackupVersion == null) { - Timber.v("backupKeys: Invalid configuration") - backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration")) - resetBackupAllGroupSessionsListeners() - - return - } - - if (state === KeysBackupState.BackingUp) { - // Do nothing if we are already backing up - Timber.v("backupKeys: Invalid state: $state") - return - } - - // Get a chunk of keys to backup - val olmInboundGroupSessionWrappers = cryptoStore.inboundGroupSessionsToBackup(KEY_BACKUP_SEND_KEYS_MAX_COUNT) - - Timber.v("backupKeys: 1 - ${olmInboundGroupSessionWrappers.size} sessions to back up") - - if (olmInboundGroupSessionWrappers.isEmpty()) { - // Backup is up to date - keysBackupStateManager.state = KeysBackupState.ReadyToBackUp - - backupAllGroupSessionsCallback?.onSuccess(Unit) - resetBackupAllGroupSessionsListeners() - return - } - - keysBackupStateManager.state = KeysBackupState.BackingUp - - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - withContext(coroutineDispatchers.crypto) { - Timber.v("backupKeys: 2 - Encrypting keys") - - // Gather data to send to the homeserver - // roomId -> sessionId -> MXKeyBackupData - val keysBackupData = KeysBackupData() - - olmInboundGroupSessionWrappers.forEach { olmInboundGroupSessionWrapper -> - val roomId = olmInboundGroupSessionWrapper.roomId ?: return@forEach - val olmInboundGroupSession = olmInboundGroupSessionWrapper.olmInboundGroupSession ?: return@forEach - - try { - encryptGroupSession(olmInboundGroupSessionWrapper) - ?.let { - keysBackupData.roomIdToRoomKeysBackupData - .getOrPut(roomId) { RoomKeysBackupData() } - .sessionIdToKeyBackupData[olmInboundGroupSession.sessionIdentifier()] = it - } - } catch (e: OlmException) { - Timber.e(e, "OlmException") - } - } - - Timber.v("backupKeys: 4 - Sending request") - - // Make the request - val version = keysBackupVersion?.version ?: return@withContext - - storeSessionDataTask - .configureWith(StoreSessionsDataTask.Params(version, keysBackupData)) { - this.callback = object : MatrixCallback { - override fun onSuccess(data: BackupKeysResult) { - uiHandler.post { - Timber.v("backupKeys: 5a - Request complete") - - // Mark keys as backed up - cryptoStore.markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers) - - if (olmInboundGroupSessionWrappers.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) { - Timber.v("backupKeys: All keys have been backed up") - onServerDataRetrieved(data.count, data.hash) - - // Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess() - keysBackupStateManager.state = KeysBackupState.ReadyToBackUp - } else { - Timber.v("backupKeys: Continue to back up keys") - keysBackupStateManager.state = KeysBackupState.WillBackUp - - backupKeys() - } - } - } - - override fun onFailure(failure: Throwable) { - if (failure is Failure.ServerError) { - uiHandler.post { - Timber.e(failure, "backupKeys: backupKeys failed.") - - when (failure.error.code) { - MatrixError.M_NOT_FOUND, - MatrixError.M_WRONG_ROOM_KEYS_VERSION -> { - // Backup has been deleted on the server, or we are not using the last backup version - keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion - backupAllGroupSessionsCallback?.onFailure(failure) - resetBackupAllGroupSessionsListeners() - resetKeysBackupData() - keysBackupVersion = null - - // Do not stay in KeysBackupState.WrongBackUpVersion but check what is available on the homeserver - checkAndStartKeysBackup() - } - else -> - // Come back to the ready state so that we will retry on the next received key - keysBackupStateManager.state = KeysBackupState.ReadyToBackUp - } - } - } else { - uiHandler.post { - backupAllGroupSessionsCallback?.onFailure(failure) - resetBackupAllGroupSessionsListeners() - - Timber.e("backupKeys: backupKeys failed.") - - // Retry a bit later - keysBackupStateManager.state = KeysBackupState.ReadyToBackUp - maybeBackupKeys() - } - } - } - } - } - .executeBy(taskExecutor) - } - } - } - - @VisibleForTesting - @WorkerThread - fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2): KeyBackupData? { - // Gather information for each key - val device = olmInboundGroupSessionWrapper.senderKey?.let { cryptoStore.deviceWithIdentityKey(it) } - - // Build the m.megolm_backup.v1.curve25519-aes-sha2 data as defined at - // https://github.com/uhoreg/matrix-doc/blob/e2e_backup/proposals/1219-storing-megolm-keys-serverside.md#mmegolm_backupv1curve25519-aes-sha2-key-format - val sessionData = olmInboundGroupSessionWrapper.exportKeys() ?: return null - val sessionBackupData = mapOf( - "algorithm" to sessionData.algorithm, - "sender_key" to sessionData.senderKey, - "sender_claimed_keys" to sessionData.senderClaimedKeys, - "forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()), - "session_key" to sessionData.sessionKey) - - val json = MoshiProvider.providesMoshi() - .adapter(Map::class.java) - .toJson(sessionBackupData) - - val encryptedSessionBackupData = try { - backupOlmPkEncryption?.encrypt(json) - } catch (e: OlmException) { - Timber.e(e, "OlmException") - null - } - ?: return null - - // Build backup data for that key - return KeyBackupData( - firstMessageIndex = try { - olmInboundGroupSessionWrapper.olmInboundGroupSession?.firstKnownIndex ?: 0 - } catch (e: OlmException) { - Timber.e(e, "OlmException") - 0L - }, - forwardedCount = olmInboundGroupSessionWrapper.forwardingCurve25519KeyChain.orEmpty().size, - isVerified = device?.isVerified == true, - - sessionData = mapOf( - "ciphertext" to encryptedSessionBackupData.mCipherText, - "mac" to encryptedSessionBackupData.mMac, - "ephemeral" to encryptedSessionBackupData.mEphemeralKey) - ) - } - - @VisibleForTesting - @WorkerThread - fun decryptKeyBackupData(keyBackupData: KeyBackupData, sessionId: String, roomId: String, decryption: OlmPkDecryption): MegolmSessionData? { - var sessionBackupData: MegolmSessionData? = null - - val jsonObject = keyBackupData.sessionData - - val ciphertext = jsonObject["ciphertext"]?.toString() - val mac = jsonObject["mac"]?.toString() - val ephemeralKey = jsonObject["ephemeral"]?.toString() - - if (ciphertext != null && mac != null && ephemeralKey != null) { - val encrypted = OlmPkMessage() - encrypted.mCipherText = ciphertext - encrypted.mMac = mac - encrypted.mEphemeralKey = ephemeralKey - - try { - val decrypted = decryption.decrypt(encrypted) - - val moshi = MoshiProvider.providesMoshi() - val adapter = moshi.adapter(MegolmSessionData::class.java) - - sessionBackupData = adapter.fromJson(decrypted) - } catch (e: OlmException) { - Timber.e(e, "OlmException") - } - - if (sessionBackupData != null) { - sessionBackupData = sessionBackupData.copy( - sessionId = sessionId, - roomId = roomId - ) - } - } - - return sessionBackupData - } - - /* ========================================================================================== - * For test only - * ========================================================================================== */ - - // Direct access for test only - @VisibleForTesting - val store - get() = cryptoStore - - @VisibleForTesting - fun createFakeKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, - callback: MatrixCallback) { - @Suppress("UNCHECKED_CAST") - val createKeysBackupVersionBody = CreateKeysBackupVersionBody( - algorithm = keysBackupCreationInfo.algorithm, - authData = keysBackupCreationInfo.authData.toJsonDict() - ) - - createKeysBackupVersionTask - .configureWith(createKeysBackupVersionBody) { - this.callback = callback - } - .executeBy(taskExecutor) - } - - override fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? { - return cryptoStore.getKeyBackupRecoveryKeyInfo() - } - - override fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) { - cryptoStore.saveBackupRecoveryKey(recoveryKey, version) - } - - companion object { - // Maximum delay in ms in {@link maybeBackupKeys} - private const val KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS = 10_000L - - // Maximum number of keys to send at a time to the homeserver. - private const val KEY_BACKUP_SEND_KEYS_MAX_COUNT = 100 - } - -/* ========================================================================================== - * DEBUG INFO - * ========================================================================================== */ - - override fun toString() = "KeysBackup for $userId" -} +///* +// * Copyright 2020 The Matrix.org Foundation C.I.C. +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package org.matrix.android.sdk.internal.crypto.keysbackup +// +//import android.os.Handler +//import android.os.Looper +//import androidx.annotation.UiThread +//import androidx.annotation.VisibleForTesting +//import androidx.annotation.WorkerThread +//import kotlinx.coroutines.CoroutineScope +//import kotlinx.coroutines.delay +//import kotlinx.coroutines.launch +//import kotlinx.coroutines.withContext +//import org.matrix.android.sdk.api.MatrixCallback +//import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +//import org.matrix.android.sdk.api.auth.data.Credentials +//import org.matrix.android.sdk.api.failure.Failure +//import org.matrix.android.sdk.api.failure.MatrixError +//import org.matrix.android.sdk.api.listeners.ProgressListener +//import org.matrix.android.sdk.api.listeners.StepProgressListener +//import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService +//import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState +//import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener +//import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP +//import org.matrix.android.sdk.internal.crypto.MXOlmDevice +//import org.matrix.android.sdk.internal.crypto.MegolmSessionData +//import org.matrix.android.sdk.internal.crypto.ObjectSigner +//import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter +//import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrustSignature +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData +//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteRoomSessionDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteRoomSessionsDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteSessionsDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionsDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetSessionsDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionsDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask +//import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey +//import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey +//import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult +//import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 +//import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore +//import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo +//import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity +//import org.matrix.android.sdk.internal.di.MoshiProvider +//import org.matrix.android.sdk.internal.di.UserId +//import org.matrix.android.sdk.internal.extensions.foldToCallback +//import org.matrix.android.sdk.internal.session.SessionScope +//import org.matrix.android.sdk.internal.task.Task +//import org.matrix.android.sdk.internal.task.TaskExecutor +//import org.matrix.android.sdk.internal.task.TaskThread +//import org.matrix.android.sdk.internal.task.configureWith +//import org.matrix.android.sdk.internal.util.JsonCanonicalizer +//import org.matrix.android.sdk.internal.util.awaitCallback +//import org.matrix.olm.OlmException +//import org.matrix.olm.OlmPkDecryption +//import org.matrix.olm.OlmPkEncryption +//import org.matrix.olm.OlmPkMessage +//import timber.log.Timber +//import java.security.InvalidParameterException +//import javax.inject.Inject +//import kotlin.random.Random +// +///** +// * A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys) +// * to the user's homeserver. +// */ +//@SessionScope +//@Deprecated("use rust") +//internal class DefaultKeysBackupService @Inject constructor( +// @UserId private val userId: String, +// private val credentials: Credentials, +// private val cryptoStore: IMXCryptoStore, +// private val olmDevice: MXOlmDevice, +// private val objectSigner: ObjectSigner, +// // Actions +// private val megolmSessionDataImporter: MegolmSessionDataImporter, +// // Tasks +// private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, +// private val deleteBackupTask: DeleteBackupTask, +// private val deleteRoomSessionDataTask: DeleteRoomSessionDataTask, +// private val deleteRoomSessionsDataTask: DeleteRoomSessionsDataTask, +// private val deleteSessionDataTask: DeleteSessionsDataTask, +// private val getKeysBackupLastVersionTask: GetKeysBackupLastVersionTask, +// private val getKeysBackupVersionTask: GetKeysBackupVersionTask, +// private val getRoomSessionDataTask: GetRoomSessionDataTask, +// private val getRoomSessionsDataTask: GetRoomSessionsDataTask, +// private val getSessionsDataTask: GetSessionsDataTask, +// private val storeRoomSessionDataTask: StoreRoomSessionDataTask, +// private val storeSessionsDataTask: StoreRoomSessionsDataTask, +// private val storeSessionDataTask: StoreSessionsDataTask, +// private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask, +// // Task executor +// private val taskExecutor: TaskExecutor, +// private val coroutineDispatchers: MatrixCoroutineDispatchers, +// private val cryptoCoroutineScope: CoroutineScope +//) : KeysBackupService { +// +// private val uiHandler = Handler(Looper.getMainLooper()) +// +// private val keysBackupStateManager = KeysBackupStateManager(uiHandler) +// +// // The backup version +// override var keysBackupVersion: KeysVersionResult? = null +// private set +// +// // The backup key being used. +// private var backupOlmPkEncryption: OlmPkEncryption? = null +// +// private var backupAllGroupSessionsCallback: MatrixCallback? = null +// +// private var keysBackupStateListener: KeysBackupStateListener? = null +// +// override val isEnabled: Boolean +// get() = keysBackupStateManager.isEnabled +// +// override val isStucked: Boolean +// get() = keysBackupStateManager.isStucked +// +// override val state: KeysBackupState +// get() = keysBackupStateManager.state +// +// override val currentBackupVersion: String? +// get() = keysBackupVersion?.version +// +// override fun addListener(listener: KeysBackupStateListener) { +// keysBackupStateManager.addListener(listener) +// } +// +// override fun removeListener(listener: KeysBackupStateListener) { +// keysBackupStateManager.removeListener(listener) +// } +// +// override fun prepareKeysBackupVersion(password: String?, +// progressListener: ProgressListener?, +// callback: MatrixCallback) { +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// runCatching { +// withContext(coroutineDispatchers.crypto) { +// val olmPkDecryption = OlmPkDecryption() +// val signalableMegolmBackupAuthData = if (password != null) { +// // Generate a private key from the password +// val backgroundProgressListener = if (progressListener == null) { +// null +// } else { +// object : ProgressListener { +// override fun onProgress(progress: Int, total: Int) { +// uiHandler.post { +// try { +// progressListener.onProgress(progress, total) +// } catch (e: Exception) { +// Timber.e(e, "prepareKeysBackupVersion: onProgress failure") +// } +// } +// } +// } +// } +// +// val generatePrivateKeyResult = generatePrivateKeyWithPassword(password, backgroundProgressListener) +// SignalableMegolmBackupAuthData( +// publicKey = olmPkDecryption.setPrivateKey(generatePrivateKeyResult.privateKey), +// privateKeySalt = generatePrivateKeyResult.salt, +// privateKeyIterations = generatePrivateKeyResult.iterations +// ) +// } else { +// val publicKey = olmPkDecryption.generateKey() +// +// SignalableMegolmBackupAuthData( +// publicKey = publicKey +// ) +// } +// +// val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableMegolmBackupAuthData.signalableJSONDictionary()) +// +// val signedMegolmBackupAuthData = MegolmBackupAuthData( +// publicKey = signalableMegolmBackupAuthData.publicKey, +// privateKeySalt = signalableMegolmBackupAuthData.privateKeySalt, +// privateKeyIterations = signalableMegolmBackupAuthData.privateKeyIterations, +// signatures = objectSigner.signObject(canonicalJson) +// ) +// +// MegolmBackupCreationInfo( +// algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP, +// authData = signedMegolmBackupAuthData, +// recoveryKey = computeRecoveryKey(olmPkDecryption.privateKey()) +// ) +// } +// }.foldToCallback(callback) +// } +// } +// +// override fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, +// callback: MatrixCallback) { +// @Suppress("UNCHECKED_CAST") +// val createKeysBackupVersionBody = CreateKeysBackupVersionBody( +// algorithm = keysBackupCreationInfo.algorithm, +// authData = keysBackupCreationInfo.authData.toJsonDict() +// ) +// +// keysBackupStateManager.state = KeysBackupState.Enabling +// +// createKeysBackupVersionTask +// .configureWith(createKeysBackupVersionBody) { +// this.callback = object : MatrixCallback { +// override fun onSuccess(data: KeysVersion) { +// // Reset backup markers. +// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { +// // move tx out of UI thread +// cryptoStore.resetBackupMarkers() +// } +// +// val keyBackupVersion = KeysVersionResult( +// algorithm = createKeysBackupVersionBody.algorithm, +// authData = createKeysBackupVersionBody.authData, +// version = data.version, +// // We can consider that the server does not have keys yet +// count = 0, +// hash = "" +// ) +// +// enableKeysBackup(keyBackupVersion) +// +// callback.onSuccess(data) +// } +// +// override fun onFailure(failure: Throwable) { +// keysBackupStateManager.state = KeysBackupState.Disabled +// callback.onFailure(failure) +// } +// } +// } +// .executeBy(taskExecutor) +// } +// +// override fun deleteBackup(version: String, callback: MatrixCallback?) { +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// withContext(coroutineDispatchers.crypto) { +// // If we're currently backing up to this backup... stop. +// // (We start using it automatically in createKeysBackupVersion so this is symmetrical). +// if (keysBackupVersion != null && version == keysBackupVersion?.version) { +// resetKeysBackupData() +// keysBackupVersion = null +// keysBackupStateManager.state = KeysBackupState.Unknown +// } +// +// deleteBackupTask +// .configureWith(DeleteBackupTask.Params(version)) { +// this.callback = object : MatrixCallback { +// private fun eventuallyRestartBackup() { +// // Do not stay in KeysBackupState.Unknown but check what is available on the homeserver +// if (state == KeysBackupState.Unknown) { +// checkAndStartKeysBackup() +// } +// } +// +// override fun onSuccess(data: Unit) { +// eventuallyRestartBackup() +// +// uiHandler.post { callback?.onSuccess(Unit) } +// } +// +// override fun onFailure(failure: Throwable) { +// eventuallyRestartBackup() +// +// uiHandler.post { callback?.onFailure(failure) } +// } +// } +// } +// .executeBy(taskExecutor) +// } +// } +// } +// +// override fun canRestoreKeys(): Boolean { +// // Server contains more keys than locally +// val totalNumberOfKeysLocally = getTotalNumbersOfKeys() +// +// val keysBackupData = cryptoStore.getKeysBackupData() +// +// val totalNumberOfKeysServer = keysBackupData?.backupLastServerNumberOfKeys ?: -1 +// // Not used for the moment +// // val hashServer = keysBackupData?.backupLastServerHash +// +// return when { +// totalNumberOfKeysLocally < totalNumberOfKeysServer -> { +// // Server contains more keys than this device +// true +// } +// totalNumberOfKeysLocally == totalNumberOfKeysServer -> { +// // Same number, compare hash? +// // TODO We have not found any algorithm to determine if a restore is recommended here. Return false for the moment +// false +// } +// else -> false +// } +// } +// +// override fun getTotalNumbersOfKeys(): Int { +// return cryptoStore.inboundGroupSessionsCount(false) +// } +// +// override fun getTotalNumbersOfBackedUpKeys(): Int { +// return cryptoStore.inboundGroupSessionsCount(true) +// } +// +// override fun backupAllGroupSessions(progressListener: ProgressListener?, +// callback: MatrixCallback?) { +// // Get a status right now +// getBackupProgress(object : ProgressListener { +// override fun onProgress(progress: Int, total: Int) { +// // Reset previous listeners if any +// resetBackupAllGroupSessionsListeners() +// Timber.v("backupAllGroupSessions: backupProgress: $progress/$total") +// try { +// progressListener?.onProgress(progress, total) +// } catch (e: Exception) { +// Timber.e(e, "backupAllGroupSessions: onProgress failure") +// } +// +// if (progress == total) { +// Timber.v("backupAllGroupSessions: complete") +// callback?.onSuccess(Unit) +// return +// } +// +// backupAllGroupSessionsCallback = callback +// +// // Listen to `state` change to determine when to call onBackupProgress and onComplete +// keysBackupStateListener = object : KeysBackupStateListener { +// override fun onStateChange(newState: KeysBackupState) { +// getBackupProgress(object : ProgressListener { +// override fun onProgress(progress: Int, total: Int) { +// try { +// progressListener?.onProgress(progress, total) +// } catch (e: Exception) { +// Timber.e(e, "backupAllGroupSessions: onProgress failure 2") +// } +// +// // If backup is finished, notify the main listener +// if (state === KeysBackupState.ReadyToBackUp) { +// backupAllGroupSessionsCallback?.onSuccess(Unit) +// resetBackupAllGroupSessionsListeners() +// } +// } +// }) +// } +// }.also { keysBackupStateManager.addListener(it) } +// +// backupKeys() +// } +// }) +// } +// +// override fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult, +// callback: MatrixCallback) { +// // TODO Validate with François that this is correct +// object : Task { +// override suspend fun execute(params: KeysVersionResult): KeysBackupVersionTrust { +// return getKeysBackupTrustBg(params) +// } +// } +// .configureWith(keysBackupVersion) { +// this.callback = callback +// this.executionThread = TaskThread.COMPUTATION +// } +// .executeBy(taskExecutor) +// } +// +// /** +// * Check trust on a key backup version. +// * This has to be called on background thread. +// * +// * @param keysBackupVersion the backup version to check. +// * @return a KeysBackupVersionTrust object +// */ +// @WorkerThread +// private fun getKeysBackupTrustBg(keysBackupVersion: KeysVersionResult): KeysBackupVersionTrust { +// val keysBackupVersionTrust = KeysBackupVersionTrust() +// val authData = keysBackupVersion.getAuthDataAsMegolmBackupAuthData() +// +// if (authData == null || authData.publicKey.isEmpty() || authData.signatures.isNullOrEmpty()) { +// Timber.v("getKeysBackupTrust: Key backup is absent or missing required data") +// return keysBackupVersionTrust +// } +// +// val mySigs = authData.signatures[userId] +// if (mySigs.isNullOrEmpty()) { +// Timber.v("getKeysBackupTrust: Ignoring key backup because it lacks any signatures from this user") +// return keysBackupVersionTrust +// } +// +// for ((keyId, mySignature) in mySigs) { +// // XXX: is this how we're supposed to get the device id? +// var deviceId: String? = null +// val components = keyId.split(":") +// if (components.size == 2) { +// deviceId = components[1] +// } +// +// if (deviceId != null) { +// val device = cryptoStore.getUserDevice(userId, deviceId) +// var isSignatureValid = false +// +// if (device == null) { +// Timber.v("getKeysBackupTrust: Signature from unknown device $deviceId") +// } else { +// val fingerprint = device.fingerprint() +// if (fingerprint != null) { +// try { +// olmDevice.verifySignature(fingerprint, authData.signalableJSONDictionary(), mySignature) +// isSignatureValid = true +// } catch (e: OlmException) { +// Timber.w(e, "getKeysBackupTrust: Bad signature from device ${device.deviceId}") +// } +// } +// +// if (isSignatureValid && device.isVerified) { +// keysBackupVersionTrust.usable = true +// } +// } +// +// val signature = KeysBackupVersionTrustSignature() +// signature.device = device +// signature.valid = isSignatureValid +// signature.deviceId = deviceId +// keysBackupVersionTrust.signatures.add(signature) +// } +// } +// +// return keysBackupVersionTrust +// } +// +// override fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, +// trust: Boolean, +// callback: MatrixCallback) { +// Timber.v("trustKeyBackupVersion: $trust, version ${keysBackupVersion.version}") +// +// // Get auth data to update it +// val authData = getMegolmBackupAuthData(keysBackupVersion) +// +// if (authData == null) { +// Timber.w("trustKeyBackupVersion:trust: Key backup is missing required data") +// +// callback.onFailure(IllegalArgumentException("Missing element")) +// } else { +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// val updateKeysBackupVersionBody = withContext(coroutineDispatchers.crypto) { +// // Get current signatures, or create an empty set +// val myUserSignatures = authData.signatures?.get(userId).orEmpty().toMutableMap() +// +// if (trust) { +// // Add current device signature +// val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, authData.signalableJSONDictionary()) +// +// val deviceSignatures = objectSigner.signObject(canonicalJson) +// +// deviceSignatures[userId]?.forEach { entry -> +// myUserSignatures[entry.key] = entry.value +// } +// } else { +// // Remove current device signature +// myUserSignatures.remove("ed25519:${credentials.deviceId}") +// } +// +// // Create an updated version of KeysVersionResult +// val newMegolmBackupAuthData = authData.copy() +// +// val newSignatures = newMegolmBackupAuthData.signatures.orEmpty().toMutableMap() +// newSignatures[userId] = myUserSignatures +// +// val newMegolmBackupAuthDataWithNewSignature = newMegolmBackupAuthData.copy( +// signatures = newSignatures +// ) +// +// @Suppress("UNCHECKED_CAST") +// UpdateKeysBackupVersionBody( +// algorithm = keysBackupVersion.algorithm, +// authData = newMegolmBackupAuthDataWithNewSignature.toJsonDict(), +// version = keysBackupVersion.version) +// } +// +// // And send it to the homeserver +// updateKeysBackupVersionTask +// .configureWith(UpdateKeysBackupVersionTask.Params(keysBackupVersion.version, updateKeysBackupVersionBody)) { +// this.callback = object : MatrixCallback { +// override fun onSuccess(data: Unit) { +// // Relaunch the state machine on this updated backup version +// val newKeysBackupVersion = KeysVersionResult( +// algorithm = keysBackupVersion.algorithm, +// authData = updateKeysBackupVersionBody.authData, +// version = keysBackupVersion.version, +// hash = keysBackupVersion.hash, +// count = keysBackupVersion.count +// ) +// +// checkAndStartWithKeysBackupVersion(newKeysBackupVersion) +// +// callback.onSuccess(data) +// } +// +// override fun onFailure(failure: Throwable) { +// callback.onFailure(failure) +// } +// } +// } +// .executeBy(taskExecutor) +// } +// } +// } +// +// override fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, +// recoveryKey: String, +// callback: MatrixCallback) { +// Timber.v("trustKeysBackupVersionWithRecoveryKey: version ${keysBackupVersion.version}") +// +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// val isValid = withContext(coroutineDispatchers.crypto) { +// isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion) +// } +// +// if (!isValid) { +// Timber.w("trustKeyBackupVersionWithRecoveryKey: Invalid recovery key.") +// +// callback.onFailure(IllegalArgumentException("Invalid recovery key or password")) +// } else { +// trustKeysBackupVersion(keysBackupVersion, true, callback) +// } +// } +// } +// +// override fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, +// password: String, +// callback: MatrixCallback) { +// Timber.v("trustKeysBackupVersionWithPassphrase: version ${keysBackupVersion.version}") +// +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// val recoveryKey = withContext(coroutineDispatchers.crypto) { +// recoveryKeyFromPassword(password, keysBackupVersion, null) +// } +// +// if (recoveryKey == null) { +// Timber.w("trustKeysBackupVersionWithPassphrase: Key backup is missing required data") +// +// callback.onFailure(IllegalArgumentException("Missing element")) +// } else { +// // Check trust using the recovery key +// trustKeysBackupVersionWithRecoveryKey(keysBackupVersion, recoveryKey, callback) +// } +// } +// } +// +// override fun onSecretKeyGossip(secret: String) { +// Timber.i("## CrossSigning - onSecretKeyGossip") +// +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// try { +// val keysBackupVersion = getKeysBackupLastVersionTask.execute(Unit) +// val recoveryKey = computeRecoveryKey(secret.fromBase64()) +// if (isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)) { +// awaitCallback { +// trustKeysBackupVersion(keysBackupVersion, true, it) +// } +// val importResult = awaitCallback { +// restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, null, null, null, it) +// } +// withContext(coroutineDispatchers.crypto) { +// cryptoStore.saveBackupRecoveryKey(recoveryKey, keysBackupVersion.version) +// } +// Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") +// } else { +// Timber.e("onSecretKeyGossip: Recovery key is not valid ${keysBackupVersion.version}") +// } +// } catch (failure: Throwable) { +// Timber.e("onSecretKeyGossip: failed to trust key backup version ${keysBackupVersion?.version}") +// } +// } +// } +// +// /** +// * Get public key from a Recovery key +// * +// * @param recoveryKey the recovery key +// * @return the corresponding public key, from Olm +// */ +// @WorkerThread +// private fun pkPublicKeyFromRecoveryKey(recoveryKey: String): String? { +// // Extract the primary key +// val privateKey = extractCurveKeyFromRecoveryKey(recoveryKey) +// +// if (privateKey == null) { +// Timber.w("pkPublicKeyFromRecoveryKey: private key is null") +// +// return null +// } +// +// // Built the PK decryption with it +// val pkPublicKey: String +// +// try { +// val decryption = OlmPkDecryption() +// pkPublicKey = decryption.setPrivateKey(privateKey) +// } catch (e: OlmException) { +// return null +// } +// +// return pkPublicKey +// } +// +// private fun resetBackupAllGroupSessionsListeners() { +// backupAllGroupSessionsCallback = null +// +// keysBackupStateListener?.let { +// keysBackupStateManager.removeListener(it) +// } +// +// keysBackupStateListener = null +// } +// +// override fun getBackupProgress(progressListener: ProgressListener) { +// val backedUpKeys = cryptoStore.inboundGroupSessionsCount(true) +// val total = cryptoStore.inboundGroupSessionsCount(false) +// +// progressListener.onProgress(backedUpKeys, total) +// } +// +// override fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, +// recoveryKey: String, +// roomId: String?, +// sessionId: String?, +// stepProgressListener: StepProgressListener?, +// callback: MatrixCallback) { +// Timber.v("restoreKeysWithRecoveryKey: From backup version: ${keysVersionResult.version}") +// +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// runCatching { +// val decryption = withContext(coroutineDispatchers.crypto) { +// // Check if the recovery is valid before going any further +// if (!isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysVersionResult)) { +// Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key for this keys version") +// throw InvalidParameterException("Invalid recovery key") +// } +// +// // Get a PK decryption instance +// pkDecryptionFromRecoveryKey(recoveryKey) +// } +// if (decryption == null) { +// // This should not happen anymore +// Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key. Error") +// throw InvalidParameterException("Invalid recovery key") +// } +// +// stepProgressListener?.onStepProgress(StepProgressListener.Step.DownloadingKey) +// +// // Get backed up keys from the homeserver +// val data = getKeys(sessionId, roomId, keysVersionResult.version) +// +// withContext(coroutineDispatchers.computation) { +// val sessionsData = ArrayList() +// // Restore that data +// var sessionsFromHsCount = 0 +// for ((roomIdLoop, backupData) in data.roomIdToRoomKeysBackupData) { +// for ((sessionIdLoop, keyBackupData) in backupData.sessionIdToKeyBackupData) { +// sessionsFromHsCount++ +// +// val sessionData = decryptKeyBackupData(keyBackupData, sessionIdLoop, roomIdLoop, decryption) +// +// sessionData?.let { +// sessionsData.add(it) +// } +// } +// } +// Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" + +// " of $sessionsFromHsCount from the backup store on the homeserver") +// +// // Do not trigger a backup for them if they come from the backup version we are using +// val backUp = keysVersionResult.version != keysBackupVersion?.version +// if (backUp) { +// Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up" + +// " to backup version: ${keysBackupVersion?.version}") +// } +// +// // Import them into the crypto store +// val progressListener = if (stepProgressListener != null) { +// object : ProgressListener { +// override fun onProgress(progress: Int, total: Int) { +// // Note: no need to post to UI thread, importMegolmSessionsData() will do it +// stepProgressListener.onStepProgress(StepProgressListener.Step.ImportingKey(progress, total)) +// } +// } +// } else { +// null +// } +// +// val result = megolmSessionDataImporter.handle(sessionsData, !backUp, progressListener) +// +// // Do not back up the key if it comes from a backup recovery +// if (backUp) { +// maybeBackupKeys() +// } +// // Save for next time and for gossiping +// saveBackupRecoveryKey(recoveryKey, keysVersionResult.version) +// result +// } +// }.foldToCallback(callback) +// } +// } +// +// override fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, +// password: String, +// roomId: String?, +// sessionId: String?, +// stepProgressListener: StepProgressListener?, +// callback: MatrixCallback) { +// Timber.v("[MXKeyBackup] restoreKeyBackup with password: From backup version: ${keysBackupVersion.version}") +// +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// runCatching { +// val progressListener = if (stepProgressListener != null) { +// object : ProgressListener { +// override fun onProgress(progress: Int, total: Int) { +// uiHandler.post { +// stepProgressListener.onStepProgress(StepProgressListener.Step.ComputingKey(progress, total)) +// } +// } +// } +// } else { +// null +// } +// +// val recoveryKey = withContext(coroutineDispatchers.crypto) { +// recoveryKeyFromPassword(password, keysBackupVersion, progressListener) +// } +// if (recoveryKey == null) { +// Timber.v("backupKeys: Invalid configuration") +// throw IllegalStateException("Invalid configuration") +// } else { +// awaitCallback { +// restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener, it) +// } +// } +// }.foldToCallback(callback) +// } +// } +// +// /** +// * Same method as [RoomKeysRestClient.getRoomKey] except that it accepts nullable +// * parameters and always returns a KeysBackupData object through the Callback +// */ +// private suspend fun getKeys(sessionId: String?, +// roomId: String?, +// version: String): KeysBackupData { +// return if (roomId != null && sessionId != null) { +// // Get key for the room and for the session +// val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version)) +// // Convert to KeysBackupData +// KeysBackupData(mutableMapOf( +// roomId to RoomKeysBackupData(mutableMapOf( +// sessionId to data +// )) +// )) +// } else if (roomId != null) { +// // Get all keys for the room +// val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version)) +// // Convert to KeysBackupData +// KeysBackupData(mutableMapOf(roomId to data)) +// } else { +// // Get all keys +// getSessionsDataTask.execute(GetSessionsDataTask.Params(version)) +// } +// } +// +// @VisibleForTesting +// @WorkerThread +// fun pkDecryptionFromRecoveryKey(recoveryKey: String): OlmPkDecryption? { +// // Extract the primary key +// val privateKey = extractCurveKeyFromRecoveryKey(recoveryKey) +// +// // Built the PK decryption with it +// var decryption: OlmPkDecryption? = null +// if (privateKey != null) { +// try { +// decryption = OlmPkDecryption() +// decryption.setPrivateKey(privateKey) +// } catch (e: OlmException) { +// Timber.e(e, "OlmException") +// } +// } +// +// return decryption +// } +// +// /** +// * Do a backup if there are new keys, with a delay +// */ +// fun maybeBackupKeys() { +// when { +// isStucked -> { +// // If not already done, or in error case, check for a valid backup version on the homeserver. +// // If there is one, maybeBackupKeys will be called again. +// checkAndStartKeysBackup() +// } +// state == KeysBackupState.ReadyToBackUp -> { +// keysBackupStateManager.state = KeysBackupState.WillBackUp +// +// // Wait between 0 and 10 seconds, to avoid backup requests from +// // different clients hitting the server all at the same time when a +// // new key is sent +// val delayInMs = Random.nextLong(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS) +// +// cryptoCoroutineScope.launch { +// delay(delayInMs) +// uiHandler.post { backupKeys() } +// } +// } +// else -> { +// Timber.v("maybeBackupKeys: Skip it because state: $state") +// } +// } +// } +// +// override fun getVersion(version: String, +// callback: MatrixCallback) { +// getKeysBackupVersionTask +// .configureWith(version) { +// this.callback = object : MatrixCallback { +// override fun onSuccess(data: KeysVersionResult) { +// callback.onSuccess(data) +// } +// +// override fun onFailure(failure: Throwable) { +// if (failure is Failure.ServerError && +// failure.error.code == MatrixError.M_NOT_FOUND) { +// // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup +// callback.onSuccess(null) +// } else { +// // Transmit the error +// callback.onFailure(failure) +// } +// } +// } +// } +// .executeBy(taskExecutor) +// } +// +// override fun getCurrentVersion(callback: MatrixCallback) { +// getKeysBackupLastVersionTask +// .configureWith { +// this.callback = object : MatrixCallback { +// override fun onSuccess(data: KeysVersionResult) { +// callback.onSuccess(data) +// } +// +// override fun onFailure(failure: Throwable) { +// if (failure is Failure.ServerError && +// failure.error.code == MatrixError.M_NOT_FOUND) { +// // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup +// callback.onSuccess(null) +// } else { +// // Transmit the error +// callback.onFailure(failure) +// } +// } +// } +// } +// .executeBy(taskExecutor) +// } +// +// override fun forceUsingLastVersion(callback: MatrixCallback) { +// getCurrentVersion(object : MatrixCallback { +// override fun onSuccess(data: KeysVersionResult?) { +// val localBackupVersion = keysBackupVersion?.version +// val serverBackupVersion = data?.version +// +// if (serverBackupVersion == null) { +// if (localBackupVersion == null) { +// // No backup on the server, and backup is not active +// callback.onSuccess(true) +// } else { +// // No backup on the server, and we are currently backing up, so stop backing up +// callback.onSuccess(false) +// resetKeysBackupData() +// keysBackupVersion = null +// keysBackupStateManager.state = KeysBackupState.Disabled +// } +// } else { +// if (localBackupVersion == null) { +// // backup on the server, and backup is not active +// callback.onSuccess(false) +// // Do a check +// checkAndStartWithKeysBackupVersion(data) +// } else { +// // Backup on the server, and we are currently backing up, compare version +// if (localBackupVersion == serverBackupVersion) { +// // We are already using the last version of the backup +// callback.onSuccess(true) +// } else { +// // We are not using the last version, so delete the current version we are using on the server +// callback.onSuccess(false) +// +// // This will automatically check for the last version then +// deleteBackup(localBackupVersion, null) +// } +// } +// } +// } +// +// override fun onFailure(failure: Throwable) { +// callback.onFailure(failure) +// } +// }) +// } +// +// override fun checkAndStartKeysBackup() { +// if (!isStucked) { +// // Try to start or restart the backup only if it is in unknown or bad state +// Timber.w("checkAndStartKeysBackup: invalid state: $state") +// +// return +// } +// +// keysBackupVersion = null +// keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver +// +// getCurrentVersion(object : MatrixCallback { +// override fun onSuccess(data: KeysVersionResult?) { +// checkAndStartWithKeysBackupVersion(data) +// } +// +// override fun onFailure(failure: Throwable) { +// Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version") +// keysBackupStateManager.state = KeysBackupState.Unknown +// } +// }) +// } +// +// private fun checkAndStartWithKeysBackupVersion(keyBackupVersion: KeysVersionResult?) { +// Timber.v("checkAndStartWithKeyBackupVersion: ${keyBackupVersion?.version}") +// +// keysBackupVersion = keyBackupVersion +// +// if (keyBackupVersion == null) { +// Timber.v("checkAndStartWithKeysBackupVersion: Found no key backup version on the homeserver") +// resetKeysBackupData() +// keysBackupStateManager.state = KeysBackupState.Disabled +// } else { +// getKeysBackupTrust(keyBackupVersion, object : MatrixCallback { +// override fun onSuccess(data: KeysBackupVersionTrust) { +// val versionInStore = cryptoStore.getKeyBackupVersion() +// +// if (data.usable) { +// Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: ${keyBackupVersion.version}") +// // Check the version we used at the previous app run +// if (versionInStore != null && versionInStore != keyBackupVersion.version) { +// Timber.v(" -> clean the previously used version $versionInStore") +// resetKeysBackupData() +// } +// +// Timber.v(" -> enabling key backups") +// enableKeysBackup(keyBackupVersion) +// } else { +// Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: ${keyBackupVersion.version}") +// if (versionInStore != null) { +// Timber.v(" -> disabling key backup") +// resetKeysBackupData() +// } +// +// keysBackupStateManager.state = KeysBackupState.NotTrusted +// } +// } +// +// override fun onFailure(failure: Throwable) { +// // Cannot happen +// } +// }) +// } +// } +// +///* ========================================================================================== +// * Private +// * ========================================================================================== */ +// +// /** +// * Extract MegolmBackupAuthData data from a backup version. +// * +// * @param keysBackupData the key backup data +// * +// * @return the authentication if found and valid, null in other case +// */ +// private fun getMegolmBackupAuthData(keysBackupData: KeysVersionResult): MegolmBackupAuthData? { +// return keysBackupData +// .takeIf { it.version.isNotEmpty() && it.algorithm == MXCRYPTO_ALGORITHM_MEGOLM_BACKUP } +// ?.getAuthDataAsMegolmBackupAuthData() +// ?.takeIf { it.publicKey.isNotEmpty() } +// } +// +// /** +// * Compute the recovery key from a password and key backup version. +// * +// * @param password the password. +// * @param keysBackupData the backup and its auth data. +// * +// * @return the recovery key if successful, null in other cases +// */ +// @WorkerThread +// private fun recoveryKeyFromPassword(password: String, keysBackupData: KeysVersionResult, progressListener: ProgressListener?): String? { +// val authData = getMegolmBackupAuthData(keysBackupData) +// +// if (authData == null) { +// Timber.w("recoveryKeyFromPassword: invalid parameter") +// return null +// } +// +// if (authData.privateKeySalt.isNullOrBlank() || +// authData.privateKeyIterations == null) { +// Timber.w("recoveryKeyFromPassword: Salt and/or iterations not found in key backup auth data") +// +// return null +// } +// +// // Extract the recovery key from the passphrase +// val data = retrievePrivateKeyWithPassword(password, authData.privateKeySalt, authData.privateKeyIterations, progressListener) +// +// return computeRecoveryKey(data) +// } +// +// /** +// * Check if a recovery key matches key backup authentication data. +// * +// * @param recoveryKey the recovery key to challenge. +// * @param keysBackupData the backup and its auth data. +// * +// * @return true if successful. +// */ +// @WorkerThread +// private fun isValidRecoveryKeyForKeysBackupVersion(recoveryKey: String, keysBackupData: KeysVersionResult): Boolean { +// // Build PK decryption instance with the recovery key +// val publicKey = pkPublicKeyFromRecoveryKey(recoveryKey) +// +// if (publicKey == null) { +// Timber.w("isValidRecoveryKeyForKeysBackupVersion: public key is null") +// +// return false +// } +// +// val authData = getMegolmBackupAuthData(keysBackupData) +// +// if (authData == null) { +// Timber.w("isValidRecoveryKeyForKeysBackupVersion: Key backup is missing required data") +// +// return false +// } +// +// // Compare both +// if (publicKey != authData.publicKey) { +// Timber.w("isValidRecoveryKeyForKeysBackupVersion: Public keys mismatch") +// +// return false +// } +// +// // Public keys match! +// return true +// } +// +// override fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback) { +// val safeKeysBackupVersion = keysBackupVersion ?: return Unit.also { callback.onSuccess(false) } +// +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// isValidRecoveryKeyForKeysBackupVersion(recoveryKey, safeKeysBackupVersion).let { +// callback.onSuccess(it) +// } +// } +// } +// +// /** +// * Enable backing up of keys. +// * This method will update the state and will start sending keys in nominal case +// * +// * @param keysVersionResult backup information object as returned by [getCurrentVersion]. +// */ +// private fun enableKeysBackup(keysVersionResult: KeysVersionResult) { +// val retrievedMegolmBackupAuthData = keysVersionResult.getAuthDataAsMegolmBackupAuthData() +// +// if (retrievedMegolmBackupAuthData != null) { +// keysBackupVersion = keysVersionResult +// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { +// cryptoStore.setKeyBackupVersion(keysVersionResult.version) +// } +// +// onServerDataRetrieved(keysVersionResult.count, keysVersionResult.hash) +// +// try { +// backupOlmPkEncryption = OlmPkEncryption().apply { +// setRecipientKey(retrievedMegolmBackupAuthData.publicKey) +// } +// } catch (e: OlmException) { +// Timber.e(e, "OlmException") +// keysBackupStateManager.state = KeysBackupState.Disabled +// return +// } +// +// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp +// +// maybeBackupKeys() +// } else { +// Timber.e("Invalid authentication data") +// keysBackupStateManager.state = KeysBackupState.Disabled +// } +// } +// +// /** +// * Update the DB with data fetch from the server +// */ +// private fun onServerDataRetrieved(count: Int?, etag: String?) { +// cryptoStore.setKeysBackupData(KeysBackupDataEntity() +// .apply { +// backupLastServerNumberOfKeys = count +// backupLastServerHash = etag +// } +// ) +// } +// +// /** +// * Reset all local key backup data. +// * +// * Note: This method does not update the state +// */ +// private fun resetKeysBackupData() { +// resetBackupAllGroupSessionsListeners() +// +// cryptoStore.setKeyBackupVersion(null) +// cryptoStore.setKeysBackupData(null) +// backupOlmPkEncryption?.releaseEncryption() +// backupOlmPkEncryption = null +// +// // Reset backup markers +// cryptoStore.resetBackupMarkers() +// } +// +// /** +// * Send a chunk of keys to backup +// */ +// @UiThread +// private fun backupKeys() { +// Timber.v("backupKeys") +// +// // Sanity check, as this method can be called after a delay, the state may have change during the delay +// if (!isEnabled || backupOlmPkEncryption == null || keysBackupVersion == null) { +// Timber.v("backupKeys: Invalid configuration") +// backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration")) +// resetBackupAllGroupSessionsListeners() +// +// return +// } +// +// if (state === KeysBackupState.BackingUp) { +// // Do nothing if we are already backing up +// Timber.v("backupKeys: Invalid state: $state") +// return +// } +// +// // Get a chunk of keys to backup +// val olmInboundGroupSessionWrappers = cryptoStore.inboundGroupSessionsToBackup(KEY_BACKUP_SEND_KEYS_MAX_COUNT) +// +// Timber.v("backupKeys: 1 - ${olmInboundGroupSessionWrappers.size} sessions to back up") +// +// if (olmInboundGroupSessionWrappers.isEmpty()) { +// // Backup is up to date +// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp +// +// backupAllGroupSessionsCallback?.onSuccess(Unit) +// resetBackupAllGroupSessionsListeners() +// return +// } +// +// keysBackupStateManager.state = KeysBackupState.BackingUp +// +// cryptoCoroutineScope.launch(coroutineDispatchers.main) { +// withContext(coroutineDispatchers.crypto) { +// Timber.v("backupKeys: 2 - Encrypting keys") +// +// // Gather data to send to the homeserver +// // roomId -> sessionId -> MXKeyBackupData +// val keysBackupData = KeysBackupData() +// +// olmInboundGroupSessionWrappers.forEach { olmInboundGroupSessionWrapper -> +// val roomId = olmInboundGroupSessionWrapper.roomId ?: return@forEach +// val olmInboundGroupSession = olmInboundGroupSessionWrapper.olmInboundGroupSession ?: return@forEach +// +// try { +// encryptGroupSession(olmInboundGroupSessionWrapper) +// ?.let { +// keysBackupData.roomIdToRoomKeysBackupData +// .getOrPut(roomId) { RoomKeysBackupData() } +// .sessionIdToKeyBackupData[olmInboundGroupSession.sessionIdentifier()] = it +// } +// } catch (e: OlmException) { +// Timber.e(e, "OlmException") +// } +// } +// +// Timber.v("backupKeys: 4 - Sending request") +// +// // Make the request +// val version = keysBackupVersion?.version ?: return@withContext +// +// storeSessionDataTask +// .configureWith(StoreSessionsDataTask.Params(version, keysBackupData)) { +// this.callback = object : MatrixCallback { +// override fun onSuccess(data: BackupKeysResult) { +// uiHandler.post { +// Timber.v("backupKeys: 5a - Request complete") +// +// // Mark keys as backed up +// cryptoStore.markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers) +// +// if (olmInboundGroupSessionWrappers.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) { +// Timber.v("backupKeys: All keys have been backed up") +// onServerDataRetrieved(data.count, data.hash) +// +// // Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess() +// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp +// } else { +// Timber.v("backupKeys: Continue to back up keys") +// keysBackupStateManager.state = KeysBackupState.WillBackUp +// +// backupKeys() +// } +// } +// } +// +// override fun onFailure(failure: Throwable) { +// if (failure is Failure.ServerError) { +// uiHandler.post { +// Timber.e(failure, "backupKeys: backupKeys failed.") +// +// when (failure.error.code) { +// MatrixError.M_NOT_FOUND, +// MatrixError.M_WRONG_ROOM_KEYS_VERSION -> { +// // Backup has been deleted on the server, or we are not using the last backup version +// keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion +// backupAllGroupSessionsCallback?.onFailure(failure) +// resetBackupAllGroupSessionsListeners() +// resetKeysBackupData() +// keysBackupVersion = null +// +// // Do not stay in KeysBackupState.WrongBackUpVersion but check what is available on the homeserver +// checkAndStartKeysBackup() +// } +// else -> +// // Come back to the ready state so that we will retry on the next received key +// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp +// } +// } +// } else { +// uiHandler.post { +// backupAllGroupSessionsCallback?.onFailure(failure) +// resetBackupAllGroupSessionsListeners() +// +// Timber.e("backupKeys: backupKeys failed.") +// +// // Retry a bit later +// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp +// maybeBackupKeys() +// } +// } +// } +// } +// } +// .executeBy(taskExecutor) +// } +// } +// } +// +// @VisibleForTesting +// @WorkerThread +// fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2): KeyBackupData? { +// // Gather information for each key +// val device = olmInboundGroupSessionWrapper.senderKey?.let { cryptoStore.deviceWithIdentityKey(it) } +// +// // Build the m.megolm_backup.v1.curve25519-aes-sha2 data as defined at +// // https://github.com/uhoreg/matrix-doc/blob/e2e_backup/proposals/1219-storing-megolm-keys-serverside.md#mmegolm_backupv1curve25519-aes-sha2-key-format +// val sessionData = olmInboundGroupSessionWrapper.exportKeys() ?: return null +// val sessionBackupData = mapOf( +// "algorithm" to sessionData.algorithm, +// "sender_key" to sessionData.senderKey, +// "sender_claimed_keys" to sessionData.senderClaimedKeys, +// "forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()), +// "session_key" to sessionData.sessionKey) +// +// val json = MoshiProvider.providesMoshi() +// .adapter(Map::class.java) +// .toJson(sessionBackupData) +// +// val encryptedSessionBackupData = try { +// backupOlmPkEncryption?.encrypt(json) +// } catch (e: OlmException) { +// Timber.e(e, "OlmException") +// null +// } +// ?: return null +// +// // Build backup data for that key +// return KeyBackupData( +// firstMessageIndex = try { +// olmInboundGroupSessionWrapper.olmInboundGroupSession?.firstKnownIndex ?: 0 +// } catch (e: OlmException) { +// Timber.e(e, "OlmException") +// 0L +// }, +// forwardedCount = olmInboundGroupSessionWrapper.forwardingCurve25519KeyChain.orEmpty().size, +// isVerified = device?.isVerified == true, +// +// sessionData = mapOf( +// "ciphertext" to encryptedSessionBackupData.mCipherText, +// "mac" to encryptedSessionBackupData.mMac, +// "ephemeral" to encryptedSessionBackupData.mEphemeralKey) +// ) +// } +// +// @VisibleForTesting +// @WorkerThread +// fun decryptKeyBackupData(keyBackupData: KeyBackupData, sessionId: String, roomId: String, decryption: OlmPkDecryption): MegolmSessionData? { +// var sessionBackupData: MegolmSessionData? = null +// +// val jsonObject = keyBackupData.sessionData +// +// val ciphertext = jsonObject["ciphertext"]?.toString() +// val mac = jsonObject["mac"]?.toString() +// val ephemeralKey = jsonObject["ephemeral"]?.toString() +// +// if (ciphertext != null && mac != null && ephemeralKey != null) { +// val encrypted = OlmPkMessage() +// encrypted.mCipherText = ciphertext +// encrypted.mMac = mac +// encrypted.mEphemeralKey = ephemeralKey +// +// try { +// val decrypted = decryption.decrypt(encrypted) +// +// val moshi = MoshiProvider.providesMoshi() +// val adapter = moshi.adapter(MegolmSessionData::class.java) +// +// sessionBackupData = adapter.fromJson(decrypted) +// } catch (e: OlmException) { +// Timber.e(e, "OlmException") +// } +// +// if (sessionBackupData != null) { +// sessionBackupData = sessionBackupData.copy( +// sessionId = sessionId, +// roomId = roomId +// ) +// } +// } +// +// return sessionBackupData +// } +// +// /* ========================================================================================== +// * For test only +// * ========================================================================================== */ +// +// // Direct access for test only +// @VisibleForTesting +// val store +// get() = cryptoStore +// +// @VisibleForTesting +// fun createFakeKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, +// callback: MatrixCallback) { +// @Suppress("UNCHECKED_CAST") +// val createKeysBackupVersionBody = CreateKeysBackupVersionBody( +// algorithm = keysBackupCreationInfo.algorithm, +// authData = keysBackupCreationInfo.authData.toJsonDict() +// ) +// +// createKeysBackupVersionTask +// .configureWith(createKeysBackupVersionBody) { +// this.callback = callback +// } +// .executeBy(taskExecutor) +// } +// +// override fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? { +// return cryptoStore.getKeyBackupRecoveryKeyInfo() +// } +// +// override fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) { +// cryptoStore.saveBackupRecoveryKey(recoveryKey, version) +// } +// +// companion object { +// // Maximum delay in ms in {@link maybeBackupKeys} +// private const val KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS = 10_000L +// +// // Maximum number of keys to send at a time to the homeserver. +// private const val KEY_BACKUP_SEND_KEYS_MAX_COUNT = 100 +// } +// +///* ========================================================================================== +// * DEBUG INFO +// * ========================================================================================== */ +// +// override fun toString() = "KeysBackup for $userId" +//} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupStateManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupStateManager.kt index 78ef958bbf..1dbccf15bd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupStateManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupStateManager.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import android.os.Handler +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener import timber.log.Timber @@ -33,11 +34,13 @@ internal class KeysBackupStateManager(private val uiHandler: Handler) { field = newState // Notify listeners about the state change, on the ui thread - uiHandler.post { - synchronized(listeners) { - listeners.forEach { + synchronized(listeners) { + listeners.forEach { + uiHandler.post { // Use newState because state may have already changed again - it.onStateChange(newState) + tryOrNull { + it.onStateChange(newState) + } } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 4134c0e8aa..40d27c926d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -18,16 +18,16 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import android.os.Handler import android.os.Looper -import androidx.annotation.UiThread import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.listeners.ProgressListener @@ -52,10 +52,8 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBa import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.util.JsonCanonicalizer -import org.matrix.android.sdk.internal.util.awaitCallback import org.matrix.olm.OlmException import timber.log.Timber import uniffi.olm.BackupRecoveryKey @@ -91,7 +89,9 @@ internal class RustKeyBackupService @Inject constructor( override var keysBackupVersion: KeysVersionResult? = null private set - private var backupAllGroupSessionsCallback: MatrixCallback? = null +// private var backupAllGroupSessionsCallback: MatrixCallback? = null + + private val importScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) private var keysBackupStateListener: KeysBackupStateListener? = null @@ -115,64 +115,57 @@ internal class RustKeyBackupService @Inject constructor( keysBackupStateManager.removeListener(listener) } - override fun prepareKeysBackupVersion(password: String?, - progressListener: ProgressListener?, - callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - withContext(coroutineDispatchers.crypto) { - val key = if (password != null) { - BackupRecoveryKey.newFromPassphrase(password) - } else { - BackupRecoveryKey() - } + override suspend fun prepareKeysBackupVersion(password: String?): MegolmBackupCreationInfo { + return withContext(coroutineDispatchers.computation) { + val key = if (password != null) { + // this might be a bit slow as it's stretching the password + BackupRecoveryKey.newFromPassphrase(password) + } else { + BackupRecoveryKey() + } - val publicKey = key.megolmV1PublicKey() - val backupAuthData = SignalableMegolmBackupAuthData( - publicKey = publicKey.publicKey, - privateKeySalt = publicKey.passphraseInfo?.privateKeySalt, - privateKeyIterations = publicKey.passphraseInfo?.privateKeyIterations - ) - val canonicalJson = JsonCanonicalizer.getCanonicalJson( - Map::class.java, - backupAuthData.signalableJSONDictionary() - ) + val publicKey = key.megolmV1PublicKey() + val backupAuthData = SignalableMegolmBackupAuthData( + publicKey = publicKey.publicKey, + privateKeySalt = publicKey.passphraseInfo?.privateKeySalt, + privateKeyIterations = publicKey.passphraseInfo?.privateKeyIterations + ) + val canonicalJson = JsonCanonicalizer.getCanonicalJson( + Map::class.java, + backupAuthData.signalableJSONDictionary() + ) - val signedMegolmBackupAuthData = MegolmBackupAuthData( - publicKey = backupAuthData.publicKey, - privateKeySalt = backupAuthData.privateKeySalt, - privateKeyIterations = backupAuthData.privateKeyIterations, - signatures = olmMachine.sign(canonicalJson) - ) + val signedMegolmBackupAuthData = MegolmBackupAuthData( + publicKey = backupAuthData.publicKey, + privateKeySalt = backupAuthData.privateKeySalt, + privateKeyIterations = backupAuthData.privateKeyIterations, + signatures = olmMachine.sign(canonicalJson) + ) - MegolmBackupCreationInfo( - algorithm = publicKey.backupAlgorithm, - authData = signedMegolmBackupAuthData, - recoveryKey = key.toBase58() - ) - } - }.foldToCallback(callback) + MegolmBackupCreationInfo( + algorithm = publicKey.backupAlgorithm, + authData = signedMegolmBackupAuthData, + recoveryKey = key.toBase58() + ) } } - override fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, - callback: MatrixCallback) { - @Suppress("UNCHECKED_CAST") - val createKeysBackupVersionBody = CreateKeysBackupVersionBody( - algorithm = keysBackupCreationInfo.algorithm, - authData = keysBackupCreationInfo.authData.toJsonDict() - ) + override suspend fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo): KeysVersion { + return withContext(coroutineDispatchers.crypto) { + val createKeysBackupVersionBody = CreateKeysBackupVersionBody( + algorithm = keysBackupCreationInfo.algorithm, + authData = keysBackupCreationInfo.authData.toJsonDict() + ) - keysBackupStateManager.state = KeysBackupState.Enabling + keysBackupStateManager.state = KeysBackupState.Enabling - cryptoCoroutineScope.launch(coroutineDispatchers.main) { try { - val data = sender.createKeyBackup(createKeysBackupVersionBody) + val data = withContext(coroutineDispatchers.io) { + sender.createKeyBackup(createKeysBackupVersionBody) + } // Reset backup markers. // Don't we need to join the task here? Isn't this a race condition? - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { - olmMachine.disableBackup() - } + olmMachine.disableBackup() val keyBackupVersion = KeysVersionResult( algorithm = createKeysBackupVersionBody.algorithm, @@ -182,13 +175,11 @@ internal class RustKeyBackupService @Inject constructor( count = 0, hash = "" ) - enableKeysBackup(keyBackupVersion) - - callback.onSuccess(data) + data } catch (failure: Throwable) { keysBackupStateManager.state = KeysBackupState.Disabled - callback.onFailure(failure) + throw failure } } } @@ -200,7 +191,7 @@ internal class RustKeyBackupService @Inject constructor( } private fun resetBackupAllGroupSessionsListeners() { - backupAllGroupSessionsCallback = null +// backupAllGroupSessionsCallback = null keysBackupStateListener?.let { keysBackupStateManager.removeListener(it) @@ -219,29 +210,24 @@ internal class RustKeyBackupService @Inject constructor( olmMachine.disableBackup() } - override fun deleteBackup(version: String, callback: MatrixCallback?) { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - withContext(coroutineDispatchers.crypto) { - if (keysBackupVersion != null && version == keysBackupVersion?.version) { - resetKeysBackupData() - keysBackupVersion = null - keysBackupStateManager.state = KeysBackupState.Unknown - } + override suspend fun deleteBackup(version: String) { + withContext(coroutineDispatchers.crypto) { + if (keysBackupVersion != null && version == keysBackupVersion?.version) { + resetKeysBackupData() + keysBackupVersion = null + keysBackupStateManager.state = KeysBackupState.Unknown + } - fun eventuallyRestartBackup() { - // Do not stay in KeysBackupState.Unknown but check what is available on the homeserver - if (state == KeysBackupState.Unknown) { - checkAndStartKeysBackup() - } + try { + sender.deleteKeyBackup(version) + // Do not stay in KeysBackupState.Unknown but check what is available on the homeserver + if (state == KeysBackupState.Unknown) { + checkAndStartKeysBackup() } - - try { - sender.deleteKeyBackup(version) - eventuallyRestartBackup() - uiHandler.post { callback?.onSuccess(Unit) } - } catch (failure: Throwable) { - eventuallyRestartBackup() - uiHandler.post { callback?.onFailure(failure) } + } catch (failure: Throwable) { + // Do not stay in KeysBackupState.Unknown but check what is available on the homeserver + if (state == KeysBackupState.Unknown) { + checkAndStartKeysBackup() } } } @@ -264,12 +250,12 @@ internal class RustKeyBackupService @Inject constructor( return olmMachine.roomKeyCounts().backedUp.toInt() } - override fun backupAllGroupSessions(progressListener: ProgressListener?, - callback: MatrixCallback?) { - // This is only used in tests? While it's fine have methods that are - // only used for tests, this one has a lot of logic that is nowhere else used. - TODO() - } +// override fun backupAllGroupSessions(progressListener: ProgressListener?, +// callback: MatrixCallback?) { +// // This is only used in tests? While it's fine have methods that are +// // only used for tests, this one has a lot of logic that is nowhere else used. +// TODO() +// } private suspend fun checkBackupTrust(authData: MegolmBackupAuthData?): KeysBackupVersionTrust { return if (authData == null || authData.publicKey.isEmpty() || authData.signatures.isNullOrEmpty()) { @@ -280,82 +266,68 @@ internal class RustKeyBackupService @Inject constructor( } } - override fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult, - callback: MatrixCallback) { + override suspend fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult): KeysBackupVersionTrust { val authData = keysBackupVersion.getAuthDataAsMegolmBackupAuthData() - - cryptoCoroutineScope.launch { - try { - callback.onSuccess(checkBackupTrust(authData)) - } catch (exception: Throwable) { - callback.onFailure(exception) - } + return withContext(coroutineDispatchers.crypto) { + checkBackupTrust(authData) } } - override fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, - trust: Boolean, - callback: MatrixCallback) { - Timber.v("trustKeyBackupVersion: $trust, version ${keysBackupVersion.version}") + override suspend fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, trust: Boolean) { + withContext(coroutineDispatchers.crypto) { + Timber.v("trustKeyBackupVersion: $trust, version ${keysBackupVersion.version}") - // Get auth data to update it - val authData = getMegolmBackupAuthData(keysBackupVersion) + // Get auth data to update it + val authData = getMegolmBackupAuthData(keysBackupVersion) - if (authData == null) { - Timber.w("trustKeyBackupVersion:trust: Key backup is missing required data") + if (authData == null) { + Timber.w("trustKeyBackupVersion:trust: Key backup is missing required data") + throw IllegalArgumentException("Missing element") + } else { + // Get current signatures, or create an empty set + val userId = olmMachine.userId() + val signatures = authData.signatures?.get(userId).orEmpty().toMutableMap() - callback.onFailure(IllegalArgumentException("Missing element")) - } else { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - val body = withContext(coroutineDispatchers.crypto) { - // Get current signatures, or create an empty set - val userId = olmMachine.userId() - val signatures = authData.signatures?.get(userId).orEmpty().toMutableMap() + if (trust) { + // Add current device signature + val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, authData.signalableJSONDictionary()) + val deviceSignature = olmMachine.sign(canonicalJson) - if (trust) { - // Add current device signature - val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, authData.signalableJSONDictionary()) - val deviceSignature = olmMachine.sign(canonicalJson) - - deviceSignature[userId]?.forEach { entry -> - signatures[entry.key] = entry.value - } - } else { - signatures.remove("ed25519:${olmMachine.deviceId()}") + deviceSignature[userId]?.forEach { entry -> + signatures[entry.key] = entry.value } - - val newAuthData = authData.copy() - val newSignatures = newAuthData.signatures.orEmpty().toMutableMap() - newSignatures[userId] = signatures - - @Suppress("UNCHECKED_CAST") - UpdateKeysBackupVersionBody( - algorithm = keysBackupVersion.algorithm, - authData = newAuthData.copy(signatures = newSignatures).toJsonDict(), - version = keysBackupVersion.version) + } else { + signatures.remove("ed25519:${olmMachine.deviceId()}") } - try { + + val newAuthData = authData.copy() + val newSignatures = newAuthData.signatures.orEmpty().toMutableMap() + newSignatures[userId] = signatures + + val body = UpdateKeysBackupVersionBody( + algorithm = keysBackupVersion.algorithm, + authData = newAuthData.copy(signatures = newSignatures).toJsonDict(), + version = keysBackupVersion.version) + + withContext(coroutineDispatchers.io) { sender.updateBackup(keysBackupVersion, body) - - val newKeysBackupVersion = KeysVersionResult( - algorithm = keysBackupVersion.algorithm, - authData = body.authData, - version = keysBackupVersion.version, - hash = keysBackupVersion.hash, - count = keysBackupVersion.count - ) - - checkAndStartWithKeysBackupVersion(newKeysBackupVersion) - callback.onSuccess(Unit) - } catch (exception: Throwable) { - callback.onFailure(exception) } + + val newKeysBackupVersion = KeysVersionResult( + algorithm = keysBackupVersion.algorithm, + authData = body.authData, + version = keysBackupVersion.version, + hash = keysBackupVersion.hash, + count = keysBackupVersion.count + ) + + checkAndStartWithKeysBackupVersion(newKeysBackupVersion) } } } // Check that the recovery key matches to the public key that we downloaded from the server. - // If they match, we can trust the public key and enable backups since we have the private key. +// If they match, we can trust the public key and enable backups since we have the private key. private fun checkRecoveryKey(recoveryKey: BackupRecoveryKey, keysBackupData: KeysVersionResult) { val backupKey = recoveryKey.megolmV1PublicKey() val authData = getMegolmBackupAuthData(keysBackupData) @@ -376,60 +348,50 @@ internal class RustKeyBackupService @Inject constructor( } } - override fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, - recoveryKey: String, - callback: MatrixCallback) { + override suspend fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, recoveryKey: String) { Timber.v("trustKeysBackupVersionWithRecoveryKey: version ${keysBackupVersion.version}") - - cryptoCoroutineScope.launch { - try { - // This is ~nowhere mentioned, the string here is actually a base58 encoded key. - // This not really supported by the spec for the backup key, the 4S key supports - // base58 encoding and the same method seems to be used here. - val key = BackupRecoveryKey.fromBase58(recoveryKey) - checkRecoveryKey(key, keysBackupVersion) - trustKeysBackupVersion(keysBackupVersion, true, callback) - } catch (exception: Throwable) { - callback.onFailure(exception) - } + withContext(coroutineDispatchers.crypto) { + // This is ~nowhere mentioned, the string here is actually a base58 encoded key. + // This not really supported by the spec for the backup key, the 4S key supports + // base58 encoding and the same method seems to be used here. + val key = BackupRecoveryKey.fromBase58(recoveryKey) + checkRecoveryKey(key, keysBackupVersion) + trustKeysBackupVersion(keysBackupVersion, true) } } - override fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, - password: String, - callback: MatrixCallback) { - cryptoCoroutineScope.launch { - try { - val key = recoveryKeyFromPassword(password, keysBackupVersion) - checkRecoveryKey(key, keysBackupVersion) - trustKeysBackupVersion(keysBackupVersion, true, callback) - } catch (exception: Throwable) { - Timber.w(exception) - callback.onFailure(exception) - } + override suspend fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, password: String) { + withContext(coroutineDispatchers.crypto) { + val key = recoveryKeyFromPassword(password, keysBackupVersion) + checkRecoveryKey(key, keysBackupVersion) + trustKeysBackupVersion(keysBackupVersion, true) } } - override fun onSecretKeyGossip(secret: String) { + override suspend fun onSecretKeyGossip(curveKeyBase64: String) { Timber.i("## CrossSigning - onSecretKeyGossip") - cryptoCoroutineScope.launch(coroutineDispatchers.main) { + withContext(coroutineDispatchers.crypto) { try { val version = sender.getKeyBackupVersion() if (version != null) { - val key = BackupRecoveryKey.fromBase64(secret) + val key = BackupRecoveryKey.fromBase64(curveKeyBase64) + if (isValidRecoveryKey(key, version)) { + trustKeysBackupVersion(version, true) + // we don't want to wait for that + importScope.launch { + try { + val importResult = restoreBackup(version, key, null, null, null) - awaitCallback { - trustKeysBackupVersion(version, true, it) - } - val importResult = awaitCallback { - cryptoCoroutineScope.launch { - restoreBackup(version, key, null, null, null) + Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") + } catch (failure: Throwable) { + // fail silently.. + Timber.e(failure, "onSecretKeyGossip: Failed to import keys from backup") + } } + // we can save, it's valid + saveBackupRecoveryKey(key.toBase64(), version.version) } - Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") - - saveBackupRecoveryKey(secret, version.version) } else { Timber.e("onSecretKeyGossip: Failed to import backup recovery key, no backup version was found on the server") } @@ -511,9 +473,14 @@ internal class RustKeyBackupService @Inject constructor( Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key for this keys version") throw InvalidParameterException("Invalid recovery key") } + + // Save for next time and for gossiping + saveBackupRecoveryKey(recoveryKey.toBase64(), keysVersionResult.version) } - stepProgressListener?.onStepProgress(StepProgressListener.Step.DownloadingKey) + withContext(coroutineDispatchers.main) { + stepProgressListener?.onStepProgress(StepProgressListener.Step.DownloadingKey) + } // Get backed up keys from the homeserver val data = getKeys(sessionId, roomId, keysVersionResult.version) @@ -522,13 +489,33 @@ internal class RustKeyBackupService @Inject constructor( val sessionsData = ArrayList() // Restore that data var sessionsFromHsCount = 0 + cryptoCoroutineScope.launch(Dispatchers.Main) { + stepProgressListener?.onStepProgress(StepProgressListener.Step.DecryptingKey(0, data.roomIdToRoomKeysBackupData.size)) + } + var progressDecryptIndex = 0 + + // TODO this is quite long, could we add some concurrency here? for ((roomIdLoop, backupData) in data.roomIdToRoomKeysBackupData) { + val roomIndex = progressDecryptIndex + progressDecryptIndex++ + cryptoCoroutineScope.launch(Dispatchers.Main) { + stepProgressListener?.onStepProgress(StepProgressListener.Step.DecryptingKey(roomIndex, data.roomIdToRoomKeysBackupData.size)) + } for ((sessionIdLoop, keyBackupData) in backupData.sessionIdToKeyBackupData) { sessionsFromHsCount++ val sessionData = decryptKeyBackupData(keyBackupData, sessionIdLoop, roomIdLoop, recoveryKey) - sessionData?.let { + // rust is not very lax and will throw if field are missing, + // add a check + // TODO maybe could be done on rust side? + sessionData?.takeIf { + it.isValid().also { + if (!it) { + Timber.w("restoreKeysWithRecoveryKey: malformed sessionData $sessionData") + } + } + }?.let { sessionsData.add(it) } } @@ -548,7 +535,9 @@ internal class RustKeyBackupService @Inject constructor( object : ProgressListener { override fun onProgress(progress: Int, total: Int) { // Note: no need to post to UI thread, importMegolmSessionsData() will do it - stepProgressListener.onStepProgress(StepProgressListener.Step.ImportingKey(progress, total)) + cryptoCoroutineScope.launch(Dispatchers.Main) { + stepProgressListener.onStepProgress(StepProgressListener.Step.ImportingKey(progress, total)) + } } } } else { @@ -562,132 +551,120 @@ internal class RustKeyBackupService @Inject constructor( maybeBackupKeys() } - // Save for next time and for gossiping - saveBackupRecoveryKey(recoveryKey.toBase64(), keysVersionResult.version) result } } - override fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, - recoveryKey: String, - roomId: String?, - sessionId: String?, - stepProgressListener: StepProgressListener?, - callback: MatrixCallback) { + override suspend fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, + recoveryKey: String, + roomId: String?, + sessionId: String?, + stepProgressListener: StepProgressListener?): ImportRoomKeysResult { Timber.v("restoreKeysWithRecoveryKey: From backup version: ${keysVersionResult.version}") - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - val key = BackupRecoveryKey.fromBase58(recoveryKey) - restoreBackup(keysVersionResult, key, roomId, sessionId, stepProgressListener) - }.foldToCallback(callback) - } + + val key = BackupRecoveryKey.fromBase58(recoveryKey) + + return restoreBackup(keysVersionResult, key, roomId, sessionId, stepProgressListener) } - override fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, - password: String, - roomId: String?, - sessionId: String?, - stepProgressListener: StepProgressListener?, - callback: MatrixCallback) { + override suspend fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, + password: String, + roomId: String?, + sessionId: String?, + stepProgressListener: StepProgressListener?): ImportRoomKeysResult { Timber.v("[MXKeyBackup] restoreKeyBackup with password: From backup version: ${keysBackupVersion.version}") - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - val recoveryKey = withContext(coroutineDispatchers.crypto) { - recoveryKeyFromPassword(password, keysBackupVersion) - } + val recoveryKey = withContext(coroutineDispatchers.crypto) { + recoveryKeyFromPassword(password, keysBackupVersion) + } - restoreBackup(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener) - }.foldToCallback(callback) + return restoreBackup(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener) + } + + override suspend fun getVersion(version: String): KeysVersionResult? { + return withContext(coroutineDispatchers.io) { + sender.getKeyBackupVersion(version) } } - override fun getVersion(version: String, callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - sender.getKeyBackupVersion(version) - }.foldToCallback(callback) + @Throws + override suspend fun getCurrentVersion(): KeysVersionResult? { + return withContext(coroutineDispatchers.io) { + sender.getKeyBackupVersion() } } - override fun getCurrentVersion(callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - sender.getKeyBackupVersion() - }.foldToCallback(callback) + override suspend fun forceUsingLastVersion(): Boolean { + val response = withContext(coroutineDispatchers.io) { + sender.getKeyBackupVersion() } - } - private suspend fun forceUsingLastVersionHelper(): Boolean { - val response = sender.getKeyBackupVersion() - val serverBackupVersion = response?.version - val localBackupVersion = keysBackupVersion?.version + return withContext(coroutineDispatchers.crypto) { + val serverBackupVersion = response?.version + val localBackupVersion = keysBackupVersion?.version - Timber.d("BACKUP: $serverBackupVersion") + Timber.d("BACKUP: $serverBackupVersion") - return if (serverBackupVersion == null) { - if (localBackupVersion == null) { - // No backup on the server, and backup is not active - true - } else { - // No backup on the server, and we are currently backing up, so stop backing up - resetKeysBackupData() - keysBackupVersion = null - keysBackupStateManager.state = KeysBackupState.Disabled - false - } - } else { - if (localBackupVersion == null) { - // Do a check - checkAndStartWithKeysBackupVersion(response) - // backup on the server, and backup is not active - false - } else { - // Backup on the server, and we are currently backing up, compare version - if (localBackupVersion == serverBackupVersion) { - // We are already using the last version of the backup + if (serverBackupVersion == null) { + if (localBackupVersion == null) { + // No backup on the server, and backup is not active true } else { - // This will automatically check for the last version then - deleteBackup(localBackupVersion, null) - // We are not using the last version, so delete the current version we are using on the server + // No backup on the server, and we are currently backing up, so stop backing up + resetKeysBackupData() + keysBackupVersion = null + keysBackupStateManager.state = KeysBackupState.Disabled false } + } else { + if (localBackupVersion == null) { + // Do a check + checkAndStartWithKeysBackupVersion(response) + // backup on the server, and backup is not active + false + } else { + // Backup on the server, and we are currently backing up, compare version + if (localBackupVersion == serverBackupVersion) { + // We are already using the last version of the backup + true + } else { + // This will automatically check for the last version then + tryOrNull("Failed to automatically check for the last version") { + deleteBackup(localBackupVersion) + } + // We are not using the last version, so delete the current version we are using on the server + false + } + } } } } - override fun forceUsingLastVersion(callback: MatrixCallback) { - cryptoCoroutineScope.launch { - runCatching { - forceUsingLastVersionHelper() - }.foldToCallback(callback) + override suspend fun checkAndStartKeysBackup() { + withContext(coroutineDispatchers.crypto) { + if (!isStucked) { + // Try to start or restart the backup only if it is in unknown or bad state + Timber.w("checkAndStartKeysBackup: invalid state: $state") + return@withContext + } + + keysBackupVersion = null + keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver + + withContext(coroutineDispatchers.io) { + try { + val data = getCurrentVersion() + withContext(coroutineDispatchers.crypto) { + checkAndStartWithKeysBackupVersion(data) + } + } catch (failure: Throwable) { + Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version") + keysBackupStateManager.state = KeysBackupState.Unknown + } + } } } - override fun checkAndStartKeysBackup() { - if (!isStucked) { - // Try to start or restart the backup only if it is in unknown or bad state - Timber.w("checkAndStartKeysBackup: invalid state: $state") - - return - } - - keysBackupVersion = null - keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver - - getCurrentVersion(object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult?) { - checkAndStartWithKeysBackupVersion(data) - } - - override fun onFailure(failure: Throwable) { - Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version") - keysBackupStateManager.state = KeysBackupState.Unknown - } - }) - } - - private fun checkAndStartWithKeysBackupVersion(keyBackupVersion: KeysVersionResult?) { + private suspend fun checkAndStartWithKeysBackupVersion(keyBackupVersion: KeysVersionResult?) { Timber.v("checkAndStartWithKeyBackupVersion: ${keyBackupVersion?.version}") keysBackupVersion = keyBackupVersion @@ -697,37 +674,34 @@ internal class RustKeyBackupService @Inject constructor( resetKeysBackupData() keysBackupStateManager.state = KeysBackupState.Disabled } else { - getKeysBackupTrust(keyBackupVersion, object : MatrixCallback { - override fun onSuccess(data: KeysBackupVersionTrust) { - val versionInStore = getKeyBackupRecoveryKeyInfo()?.version + try { + val data = getKeysBackupTrust(keyBackupVersion) + val versionInStore = getKeyBackupRecoveryKeyInfo()?.version - if (data.usable) { - Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: ${keyBackupVersion.version}") - // Check the version we used at the previous app run - if (versionInStore != null && versionInStore != keyBackupVersion.version) { - Timber.v(" -> clean the previously used version $versionInStore") - resetKeysBackupData() - } - - Timber.v(" -> enabling key backups") - cryptoCoroutineScope.launch { - enableKeysBackup(keyBackupVersion) - } - } else { - Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: ${keyBackupVersion.version}") - if (versionInStore != null) { - Timber.v(" -> disabling key backup") - resetKeysBackupData() - } - - keysBackupStateManager.state = KeysBackupState.NotTrusted + if (data.usable) { + Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: ${keyBackupVersion.version}") + // Check the version we used at the previous app run + if (versionInStore != null && versionInStore != keyBackupVersion.version) { + Timber.v(" -> clean the previously used version $versionInStore") + resetKeysBackupData() } - } - override fun onFailure(failure: Throwable) { - // Cannot happen + Timber.v(" -> enabling key backups") + cryptoCoroutineScope.launch { + enableKeysBackup(keyBackupVersion) + } + } else { + Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: ${keyBackupVersion.version}") + if (versionInStore != null) { + Timber.v(" -> disabling key backup") + resetKeysBackupData() + } + + keysBackupStateManager.state = KeysBackupState.NotTrusted } - }) + } catch (failure: Throwable) { + Timber.e(failure, "Failed to checkAndStartWithKeysBackupVersion $keyBackupVersion") + } } } @@ -737,14 +711,17 @@ internal class RustKeyBackupService @Inject constructor( return authData.publicKey == publicKey } - override fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback) { - val keysBackupVersion = keysBackupVersion ?: return Unit.also { callback.onSuccess(false) } + override suspend fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String): Boolean { + return withContext(coroutineDispatchers.crypto) { + val keysBackupVersion = keysBackupVersion ?: return@withContext false - try { val key = BackupRecoveryKey.fromBase64(recoveryKey) - callback.onSuccess(isValidRecoveryKey(key, keysBackupVersion)) - } catch (error: Throwable) { - callback.onFailure(error) + try { + isValidRecoveryKey(key, keysBackupVersion) + } catch (failure: Throwable) { + Timber.i("isValidRecoveryKeyForCurrentVersion: Invalid recovery key") + false + } } } @@ -822,31 +799,30 @@ internal class RustKeyBackupService @Inject constructor( /** * Do a backup if there are new keys, with a delay */ - fun maybeBackupKeys() { - when { - isStucked -> { - // If not already done, or in error case, check for a valid backup version on the homeserver. - // If there is one, maybeBackupKeys will be called again. - checkAndStartKeysBackup() - } - state == KeysBackupState.ReadyToBackUp -> { - keysBackupStateManager.state = KeysBackupState.WillBackUp + suspend fun maybeBackupKeys() { + withContext(coroutineDispatchers.crypto) { + when { + isStucked -> { + // If not already done, or in error case, check for a valid backup version on the homeserver. + // If there is one, maybeBackupKeys will be called again. + checkAndStartKeysBackup() + } + state == KeysBackupState.ReadyToBackUp -> { + keysBackupStateManager.state = KeysBackupState.WillBackUp - // Wait between 0 and 10 seconds, to avoid backup requests from - // different clients hitting the server all at the same time when a - // new key is sent - val delayInMs = Random.nextLong(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS) + // Wait between 0 and 10 seconds, to avoid backup requests from + // different clients hitting the server all at the same time when a + // new key is sent + val delayInMs = Random.nextLong(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS) - cryptoCoroutineScope.launch { - delay(delayInMs) - // TODO is this correct? we used to call uiHandler.post() instead of this - withContext(Dispatchers.Main) { - backupKeys() + importScope.launch { + delay(delayInMs) + tryOrNull("AUTO backup failed") { backupKeys() } } } - } - else -> { - Timber.v("maybeBackupKeys: Skip it because state: $state") + else -> { + Timber.v("maybeBackupKeys: Skip it because state: $state") + } } } } @@ -854,84 +830,79 @@ internal class RustKeyBackupService @Inject constructor( /** * Send a chunk of keys to backup */ - @UiThread private suspend fun backupKeys(forceRecheck: Boolean = false) { Timber.v("backupKeys") + withContext(coroutineDispatchers.crypto) { + // Sanity check, as this method can be called after a delay, the state may have change during the delay + if (!isEnabled || !olmMachine.backupEnabled() || keysBackupVersion == null) { + Timber.v("backupKeys: Invalid configuration $isEnabled ${olmMachine.backupEnabled()} $keysBackupVersion") +// backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration")) + resetBackupAllGroupSessionsListeners() - // Sanity check, as this method can be called after a delay, the state may have change during the delay - if (!isEnabled || !olmMachine.backupEnabled() || keysBackupVersion == null) { - Timber.v("backupKeys: Invalid configuration $isEnabled ${olmMachine.backupEnabled()} $keysBackupVersion") - backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration")) - resetBackupAllGroupSessionsListeners() + return@withContext + } - return - } + if (state === KeysBackupState.BackingUp && !forceRecheck) { + // Do nothing if we are already backing up + Timber.v("backupKeys: Invalid state: $state") + return@withContext + } - if (state === KeysBackupState.BackingUp && !forceRecheck) { - // Do nothing if we are already backing up - Timber.v("backupKeys: Invalid state: $state") - return - } + Timber.d("BACKUP: CREATING REQUEST") - Timber.d("BACKUP: CREATING REQUEST") + val request = olmMachine.backupRoomKeys() - val request = olmMachine.backupRoomKeys() + Timber.d("BACKUP: GOT REQUEST $request") - Timber.d("BACKUP: GOT REQUEST $request") + if (request == null) { + // Backup is up to date + // Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess() + keysBackupStateManager.state = KeysBackupState.ReadyToBackUp - if (request == null) { - // Backup is up to date - // Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess() - keysBackupStateManager.state = KeysBackupState.ReadyToBackUp +// backupAllGroupSessionsCallback?.onSuccess(Unit) + resetBackupAllGroupSessionsListeners() + } else { + try { + if (request is Request.KeysBackup) { + keysBackupStateManager.state = KeysBackupState.BackingUp - backupAllGroupSessionsCallback?.onSuccess(Unit) - resetBackupAllGroupSessionsListeners() - } else { - try { - if (request is Request.KeysBackup) { - keysBackupStateManager.state = KeysBackupState.BackingUp + Timber.d("BACKUP SENDING REQUEST") + val response = withContext(coroutineDispatchers.io) { sender.backupRoomKeys(request) } + Timber.d("BACKUP GOT RESPONSE $response") + olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_BACKUP, response) + Timber.d("BACKUP MARKED REQUEST AS SENT") - Timber.d("BACKUP SENDING REQUEST") - val response = sender.backupRoomKeys(request) - Timber.d("BACKUP GOT RESPONSE $response") - olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_BACKUP, response) - Timber.d("BACKUP MARKED REQUEST AS SENT") - - // TODO, again is this correct? - withContext(Dispatchers.Main) { backupKeys(true) + } else { + // Can't happen, do we want to panic? } - } else { - // Can't happen, do we want to panic? - } - } catch (failure: Throwable) { - if (failure is Failure.ServerError) { - withContext(Dispatchers.Main) { - Timber.e(failure, "backupKeys: backupKeys failed.") + } catch (failure: Throwable) { + if (failure is Failure.ServerError) { + withContext(Dispatchers.Main) { + Timber.e(failure, "backupKeys: backupKeys failed.") - when (failure.error.code) { - MatrixError.M_NOT_FOUND, - MatrixError.M_WRONG_ROOM_KEYS_VERSION -> { - // Backup has been deleted on the server, or we are not using - // the last backup version - keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion - backupAllGroupSessionsCallback?.onFailure(failure) - resetBackupAllGroupSessionsListeners() - resetKeysBackupData() - keysBackupVersion = null + when (failure.error.code) { + MatrixError.M_NOT_FOUND, + MatrixError.M_WRONG_ROOM_KEYS_VERSION -> { + // Backup has been deleted on the server, or we are not using + // the last backup version + keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion +// backupAllGroupSessionsCallback?.onFailure(failure) + resetBackupAllGroupSessionsListeners() + resetKeysBackupData() + keysBackupVersion = null - // Do not stay in KeysBackupState.WrongBackUpVersion but check what - // is available on the homeserver - checkAndStartKeysBackup() + // Do not stay in KeysBackupState.WrongBackUpVersion but check what + // is available on the homeserver + checkAndStartKeysBackup() + } + else -> + // Come back to the ready state so that we will retry on the next received key + keysBackupStateManager.state = KeysBackupState.ReadyToBackUp } - else -> - // Come back to the ready state so that we will retry on the next received key - keysBackupStateManager.state = KeysBackupState.ReadyToBackUp } - } - } else { - withContext(Dispatchers.Main) { - backupAllGroupSessionsCallback?.onFailure(failure) + } else { +// backupAllGroupSessionsCallback?.onFailure(failure) resetBackupAllGroupSessionsListeners() Timber.e("backupKeys: backupKeys failed: $failure") diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt index bdae975846..0f532e4fea 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt @@ -83,11 +83,6 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() { .show() } - if (viewModel.keyVersionResult.value == null) { - // We need to fetch from API - viewModel.getLatestVersion() - } - viewModel.navigateEvent.observeEvent(this) { uxStateEvent -> when (uxStateEvent) { KeysBackupRestoreSharedViewModel.NAVIGATE_TO_RECOVER_WITH_KEY -> { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt index 8362a3566e..079828dc52 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt @@ -23,9 +23,11 @@ import im.vector.app.R import im.vector.app.core.platform.WaitingViewData import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.LiveEvent +import im.vector.app.features.session.coroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.MatrixCallback +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.listeners.StepProgressListener import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME @@ -35,7 +37,6 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import javax.inject.Inject @@ -75,10 +76,15 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( var importRoomKeysFinishWithResult: MutableLiveData> = MutableLiveData() fun initSession(session: Session) { - this.session = session + if (!this::session.isInitialized) { + this.session = session + viewModelScope.launch { + getLatestVersion() + } + } } - val progressObserver = object : StepProgressListener { + private val progressObserver = object : StepProgressListener { override fun onStepProgress(step: StepProgressListener.Step) { when (step) { is StepProgressListener.Step.ComputingKey -> { @@ -106,62 +112,71 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( step.total)) } } + is StepProgressListener.Step.DecryptingKey -> { + if (step.progress == 0) { + loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) + + "\n" + stringProvider.getString(R.string.keys_backup_restoring_decrypting_keys_waiting_message), + isIndeterminate = true)) + } else { + loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restoring_waiting_message) + + "\n" + stringProvider.getString(R.string.keys_backup_restoring_decrypting_keys_waiting_message), + step.progress, + step.total)) + } + } } } } - fun getLatestVersion() { + private suspend fun getLatestVersion() { val keysBackup = session.cryptoService().keysBackupService() - loadingEvent.value = WaitingViewData(stringProvider.getString(R.string.keys_backup_restore_is_getting_backup_version)) + loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restore_is_getting_backup_version))) - viewModelScope.launch(Dispatchers.IO) { - try { - val version = awaitCallback { - keysBackup.getCurrentVersion(it) - } - if (version?.version == null) { - loadingEvent.postValue(null) - _keyVersionResultError.postValue(LiveEvent(stringProvider.getString(R.string.keys_backup_get_version_error, ""))) - return@launch - } + try { + val version = keysBackup.getCurrentVersion() + if (version?.version == null) { + loadingEvent.postValue(null) + _keyVersionResultError.postValue(LiveEvent(stringProvider.getString(R.string.keys_backup_get_version_error, ""))) + return + } - keyVersionResult.postValue(version) - // Let's check if there is quads - val isBackupKeyInQuadS = isBackupKeyInQuadS() + keyVersionResult.postValue(version) + // Let's check if there is quads + val isBackupKeyInQuadS = isBackupKeyInQuadS() - val savedSecret = session.cryptoService().keysBackupService().getKeyBackupRecoveryKeyInfo() - if (savedSecret != null && savedSecret.version == version.version) { - // key is in memory! - keySourceModel.postValue( - KeySource(isInMemory = true, isInQuadS = true) - ) - // Go and use it!! - try { - recoverUsingBackupRecoveryKey(savedSecret.recoveryKey) - } catch (failure: Throwable) { - keySourceModel.postValue( - KeySource(isInMemory = false, isInQuadS = true) - ) - } - } else if (isBackupKeyInQuadS) { - // key is in QuadS! + val savedSecret = session.cryptoService().keysBackupService().getKeyBackupRecoveryKeyInfo() + if (savedSecret != null && savedSecret.version == version.version) { + // key is in memory! + keySourceModel.postValue( + KeySource(isInMemory = true, isInQuadS = true) + ) + // Go and use it!! + try { + recoverUsingBackupRecoveryKey(computeRecoveryKey(savedSecret.recoveryKey.fromBase64()), version) + } catch (failure: Throwable) { + Timber.e(failure, "## recoverUsingBackupRecoveryKey FAILED") keySourceModel.postValue( KeySource(isInMemory = false, isInQuadS = true) ) - _navigateEvent.postValue(LiveEvent(NAVIGATE_TO_4S)) - } else { - // we need to restore directly - keySourceModel.postValue( - KeySource(isInMemory = false, isInQuadS = false) - ) } - - loadingEvent.postValue(null) - } catch (failure: Throwable) { - loadingEvent.postValue(null) - _keyVersionResultError.postValue(LiveEvent(stringProvider.getString(R.string.keys_backup_get_version_error, failure.localizedMessage))) + } else if (isBackupKeyInQuadS) { + // key is in QuadS! + keySourceModel.postValue( + KeySource(isInMemory = false, isInQuadS = true) + ) + _navigateEvent.postValue(LiveEvent(NAVIGATE_TO_4S)) + } else { + // we need to restore directly + keySourceModel.postValue( + KeySource(isInMemory = false, isInQuadS = false) + ) } + + loadingEvent.postValue(null) + } catch (failure: Throwable) { + loadingEvent.postValue(null) + _keyVersionResultError.postValue(LiveEvent(stringProvider.getString(R.string.keys_backup_get_version_error, failure.localizedMessage))) } } @@ -176,11 +191,11 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( ) return } - loadingEvent.value = WaitingViewData(stringProvider.getString(R.string.keys_backup_restore_is_getting_backup_version)) + loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.keys_backup_restore_is_getting_backup_version))) viewModelScope.launch(Dispatchers.IO) { try { - recoverUsingBackupRecoveryKey(computeRecoveryKey(secret.fromBase64())) + recoverUsingBackupRecoveryKey(secret) } catch (failure: Throwable) { _navigateEvent.postValue( LiveEvent(NAVIGATE_FAILED_TO_LOAD_4S) @@ -202,15 +217,12 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.loading))) try { - val result = awaitCallback { - keysBackup.restoreKeyBackupWithPassword(keyVersion, - passphrase, - null, - session.myUserId, - progressObserver, - it - ) - } + val result = keysBackup.restoreKeyBackupWithPassword(keyVersion, + passphrase, + null, + session.myUserId, + progressObserver + ) loadingEvent.postValue(null) didRecoverSucceed(result) trustOnDecrypt(keysBackup, keyVersion) @@ -220,26 +232,27 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( } } - suspend fun recoverUsingBackupRecoveryKey(recoveryKey: String) { + suspend fun recoverUsingBackupRecoveryKey(recoveryKey: String, keyVersion: KeysVersionResult? = null) { val keysBackup = session.cryptoService().keysBackupService() - val keyVersion = keyVersionResult.value ?: return + // This is badddddd + val version = keyVersion ?: keyVersionResult.value ?: return loadingEvent.postValue(WaitingViewData(stringProvider.getString(R.string.loading))) try { - val result = awaitCallback { - keysBackup.restoreKeysWithRecoveryKey(keyVersion, - recoveryKey, - null, - session.myUserId, - progressObserver, - it - ) - } + val result = keysBackup.restoreKeysWithRecoveryKey(version, + recoveryKey, + null, + session.myUserId, + progressObserver + ) loadingEvent.postValue(null) - didRecoverSucceed(result) - trustOnDecrypt(keysBackup, keyVersion) + withContext(Dispatchers.Main) { + didRecoverSucceed(result) + trustOnDecrypt(keysBackup, version) + } } catch (failure: Throwable) { + Timber.e(failure, "## restoreKeysWithRecoveryKey failure") loadingEvent.postValue(null) throw failure } @@ -258,19 +271,19 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( } private fun trustOnDecrypt(keysBackup: KeysBackupService, keysVersionResult: KeysVersionResult) { - keysBackup.trustKeysBackupVersion(keysVersionResult, true, - object : MatrixCallback { - override fun onSuccess(data: Unit) { - Timber.v("##### trustKeysBackupVersion onSuccess") - } - }) + // do that on session scope because could happen outside of view model lifecycle + session.coroutineScope.launch { + tryOrNull("## Failed to trustKeysBackupVersion") { + keysBackup.trustKeysBackupVersion(keysVersionResult, true) + } + } } fun moveToRecoverWithKey() { - _navigateEvent.value = LiveEvent(NAVIGATE_TO_RECOVER_WITH_KEY) + _navigateEvent.postValue(LiveEvent(NAVIGATE_TO_RECOVER_WITH_KEY)) } - fun didRecoverSucceed(result: ImportRoomKeysResult) { + private fun didRecoverSucceed(result: ImportRoomKeysResult) { importKeyResult = result _navigateEvent.postValue(LiveEvent(NAVIGATE_TO_SUCCESS)) } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index 9a5c62f2c8..51213fcd38 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -27,13 +27,11 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.NoOpMatrixCallback +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust import timber.log.Timber class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState, @@ -70,7 +68,9 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS } private fun init() { - keysBackupService.forceUsingLastVersion(NoOpMatrixCallback()) + viewModelScope.launch { + keysBackupService.forceUsingLastVersion() + } } private fun getKeysBackupTrust() = withState { state -> @@ -86,26 +86,24 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS } Timber.d("BACKUP: HEEEEEEE TWO") - keysBackupService - .getKeysBackupTrust(versionResult, object : MatrixCallback { - override fun onSuccess(data: KeysBackupVersionTrust) { - Timber.d("BACKUP: HEEEE suceeeded $data") - setState { - copy( - keysBackupVersionTrust = Success(data) - ) - } - } - - override fun onFailure(failure: Throwable) { - Timber.d("BACKUP: HEEEE FAILED $failure") - setState { - copy( - keysBackupVersionTrust = Fail(failure) - ) - } - } - }) + viewModelScope.launch { + try { + val data = keysBackupService.getKeysBackupTrust(versionResult) + Timber.d("BACKUP: HEEEE suceeeded $data") + setState { + copy( + keysBackupVersionTrust = Success(data) + ) + } + } catch (failure: Throwable) { + Timber.d("BACKUP: HEEEE FAILED $failure") + setState { + copy( + keysBackupVersionTrust = Fail(failure) + ) + } + } + } } } @@ -128,15 +126,16 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS private fun deleteCurrentBackup() { val keysBackupService = keysBackupService - if (keysBackupService.currentBackupVersion != null) { + val currentBackupVersion = keysBackupService.currentBackupVersion + if (currentBackupVersion != null) { setState { copy( deleteBackupRequest = Loading() ) } - - keysBackupService.deleteBackup(keysBackupService.currentBackupVersion!!, object : MatrixCallback { - override fun onSuccess(data: Unit) { + viewModelScope.launch { + try { + keysBackupService.deleteBackup(currentBackupVersion) setState { copy( keysBackupVersion = null, @@ -145,16 +144,14 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS deleteBackupRequest = Uninitialized ) } - } - - override fun onFailure(failure: Throwable) { + } catch (failure: Throwable) { setState { copy( deleteBackupRequest = Fail(failure) ) } } - }) + } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt index 1141886689..bc3479860a 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt @@ -19,17 +19,16 @@ package im.vector.app.features.crypto.keysbackup.setup import android.content.Context import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.nulabinc.zxcvbn.Strength import im.vector.app.R import im.vector.app.core.platform.WaitingViewData import im.vector.app.core.utils.LiveEvent -import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.listeners.ProgressListener +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import timber.log.Timber import javax.inject.Inject @@ -89,48 +88,30 @@ class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() { recoveryKey.value = null prepareRecoverFailError.value = null - session.let { mxSession -> - val requestedId = currentRequestId.value!! + val requestedId = currentRequestId.value!! + viewModelScope.launch { + try { + val data = session.cryptoService().keysBackupService().prepareKeysBackupVersion(withPassphrase) + if (requestedId != currentRequestId.value) { + // this is an old request, we can't cancel but we can ignore + return@launch + } + recoveryKey.postValue(data.recoveryKey) + megolmBackupCreationInfo = data + copyHasBeenMade = false - mxSession.cryptoService().keysBackupService().prepareKeysBackupVersion(withPassphrase, - object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - if (requestedId != currentRequestId.value) { - // this is an old request, we can't cancel but we can ignore - return - } + val keyBackup = session.cryptoService().keysBackupService() + createKeysBackup(context, keyBackup) + } catch (failure: Throwable) { + if (requestedId != currentRequestId.value) { + // this is an old request, we can't cancel but we can ignore + return@launch + } - loadingStatus.value = WaitingViewData(context.getString(R.string.keys_backup_setup_step3_generating_key_status), - progress, - total) - } - }, - object : MatrixCallback { - override fun onSuccess(data: MegolmBackupCreationInfo) { - if (requestedId != currentRequestId.value) { - // this is an old request, we can't cancel but we can ignore - return - } - recoveryKey.value = data.recoveryKey - megolmBackupCreationInfo = data - copyHasBeenMade = false - - val keyBackup = session.cryptoService().keysBackupService() - createKeysBackup(context, keyBackup) - } - - override fun onFailure(failure: Throwable) { - if (requestedId != currentRequestId.value) { - // this is an old request, we can't cancel but we can ignore - return - } - - loadingStatus.value = null - - isCreatingBackupVersion.value = false - prepareRecoverFailError.value = failure - } - }) + loadingStatus.postValue(null) + isCreatingBackupVersion.postValue(false) + prepareRecoverFailError.postValue(failure) + } } } @@ -140,9 +121,11 @@ class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() { } fun stopAndKeepAfterDetectingExistingOnServer() { - loadingStatus.value = null - navigateEvent.value = LiveEvent(NAVIGATE_FINISH) - session.cryptoService().keysBackupService().checkAndStartKeysBackup() + loadingStatus.postValue(null) + navigateEvent.postValue(LiveEvent(NAVIGATE_FINISH)) + viewModelScope.launch { + session.cryptoService().keysBackupService().checkAndStartKeysBackup() + } } private fun createKeysBackup(context: Context, keysBackup: KeysBackupService, forceOverride: Boolean = false) { @@ -150,45 +133,35 @@ class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() { creatingBackupError.value = null - keysBackup.getCurrentVersion(object : MatrixCallback { - override fun onSuccess(data: KeysVersionResult?) { + viewModelScope.launch { + try { + val data = keysBackup.getCurrentVersion() if (data?.version.isNullOrBlank() || forceOverride) { - processOnCreate() + processOnCreate(keysBackup) } else { - loadingStatus.value = null + loadingStatus.postValue(null) // we should prompt - isCreatingBackupVersion.value = false - navigateEvent.value = LiveEvent(NAVIGATE_PROMPT_REPLACE) + isCreatingBackupVersion.postValue(false) + navigateEvent.postValue(LiveEvent(NAVIGATE_PROMPT_REPLACE)) } + } catch (failure: Throwable) { } + } + } - override fun onFailure(failure: Throwable) { - Timber.e(failure, "## createKeyBackupVersion") - loadingStatus.value = null + suspend fun processOnCreate(keysBackup: KeysBackupService) { + try { + loadingStatus.postValue(null) + val created = keysBackup.createKeysBackupVersion(megolmBackupCreationInfo!!) + isCreatingBackupVersion.postValue(false) + keysVersion.postValue(created) + navigateEvent.value = LiveEvent(NAVIGATE_TO_STEP_3) + } catch (failure: Throwable) { + Timber.e(failure, "## createKeyBackupVersion") + loadingStatus.postValue(null) - isCreatingBackupVersion.value = false - creatingBackupError.value = failure - } - - fun processOnCreate() { - keysBackup.createKeysBackupVersion(megolmBackupCreationInfo!!, object : MatrixCallback { - override fun onSuccess(data: KeysVersion) { - loadingStatus.value = null - - isCreatingBackupVersion.value = false - keysVersion.value = data - navigateEvent.value = LiveEvent(NAVIGATE_TO_STEP_3) - } - - override fun onFailure(failure: Throwable) { - Timber.e(failure, "## createKeyBackupVersion") - loadingStatus.value = null - - isCreatingBackupVersion.value = false - creatingBackupError.value = failure - } - }) - } - }) + isCreatingBackupVersion.postValue(false) + creatingBackupError.postValue(failure) + } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt index 74bab9b0b6..a962dbcf6c 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt @@ -20,7 +20,9 @@ import im.vector.app.R import im.vector.app.core.platform.ViewModelTask import im.vector.app.core.platform.WaitingViewData import im.vector.app.core.resources.StringProvider -import org.matrix.android.sdk.api.NoOpMatrixCallback +import im.vector.app.features.session.coroutineScope +import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME @@ -32,7 +34,6 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.keysbackup.deriveKey import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import java.util.UUID import javax.inject.Inject @@ -87,9 +88,7 @@ class BackupToQuadSMigrationTask @Inject constructor( reportProgress(params, R.string.bootstrap_progress_compute_curve_key) val recoveryKey = computeRecoveryKey(curveKey) - val isValid = awaitCallback { - keysBackupService.isValidRecoveryKeyForCurrentVersion(recoveryKey, it) - } + val isValid = keysBackupService.isValidRecoveryKeyForCurrentVersion(recoveryKey) if (!isValid) return Result.InvalidRecoverySecret @@ -141,14 +140,17 @@ class BackupToQuadSMigrationTask @Inject constructor( keysBackupService.saveBackupRecoveryKey(recoveryKey, version.version) // while we are there let's restore, but do not block - session.cryptoService().keysBackupService().restoreKeysWithRecoveryKey( - version, - recoveryKey, - null, - null, - null, - NoOpMatrixCallback() - ) + session.coroutineScope.launch { + tryOrNull { + session.cryptoService().keysBackupService().restoreKeysWithRecoveryKey( + version, + recoveryKey, + null, + null, + null + ) + } + } return Result.Success } catch (failure: Throwable) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt index cc863346aa..de627e1f78 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt @@ -33,9 +33,6 @@ import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageServi import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber @@ -221,9 +218,7 @@ class BootstrapCrossSigningTask @Inject constructor( Timber.d("## BootstrapCrossSigningTask: Creating 4S - Checking megolm backup") // First ensure that in sync - var serverVersion = awaitCallback { - session.cryptoService().keysBackupService().getCurrentVersion(it) - } + var serverVersion = session.cryptoService().keysBackupService().getCurrentVersion() val knownMegolmSecret = session.cryptoService().keysBackupService().getKeyBackupRecoveryKeyInfo() val isMegolmBackupSecretKnown = knownMegolmSecret != null && knownMegolmSecret.version == serverVersion?.version @@ -233,21 +228,14 @@ class BootstrapCrossSigningTask @Inject constructor( if (shouldCreateKeyBackup) { // clear all existing backups while (serverVersion != null) { - awaitCallback { - session.cryptoService().keysBackupService().deleteBackup(serverVersion!!.version, it) - } - serverVersion = awaitCallback { - session.cryptoService().keysBackupService().getCurrentVersion(it) - } + session.cryptoService().keysBackupService().deleteBackup(serverVersion.version) + serverVersion = session.cryptoService().keysBackupService().getCurrentVersion() } Timber.d("## BootstrapCrossSigningTask: Creating 4S - Create megolm backup") - val creationInfo = awaitCallback { - session.cryptoService().keysBackupService().prepareKeysBackupVersion(null, null, it) - } - val version = awaitCallback { - session.cryptoService().keysBackupService().createKeysBackupVersion(creationInfo, it) - } + val creationInfo = session.cryptoService().keysBackupService().prepareKeysBackupVersion(null) + val version = session.cryptoService().keysBackupService().createKeysBackupVersion(creationInfo) + // Save it for gossiping Timber.d("## BootstrapCrossSigningTask: Creating 4S - Save megolm backup key for gossiping") session.cryptoService().keysBackupService().saveBackupRecoveryKey(creationInfo.recoveryKey, version = version.version) @@ -264,12 +252,10 @@ class BootstrapCrossSigningTask @Inject constructor( // ensure we store existing backup secret if we have it! if (isMegolmBackupSecretKnown) { // check it matches - val isValid = awaitCallback { - session.cryptoService().keysBackupService().isValidRecoveryKeyForCurrentVersion(knownMegolmSecret!!.recoveryKey, it) - } + val isValid = session.cryptoService().keysBackupService().isValidRecoveryKeyForCurrentVersion(knownMegolmSecret!!.recoveryKey) if (isValid) { Timber.d("## BootstrapCrossSigningTask: Creating 4S - Megolm key valid and known") - extractCurveKeyFromRecoveryKey(knownMegolmSecret!!.recoveryKey)?.toBase64NoPadding()?.let { secret -> + extractCurveKeyFromRecoveryKey(knownMegolmSecret.recoveryKey)?.toBase64NoPadding()?.let { secret -> ssssService.storeSecret( KEYBACKUP_SECRET_SSSS_NAME, secret, diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt index f75ab634b8..1e7eab64e7 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt @@ -42,14 +42,13 @@ import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth -import org.matrix.android.sdk.internal.util.awaitCallback import java.io.OutputStream import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -104,9 +103,8 @@ class BootstrapSharedViewModel @AssistedInject constructor( // We need to check if there is an existing backup viewModelScope.launch(Dispatchers.IO) { - val version = awaitCallback { - session.cryptoService().keysBackupService().getCurrentVersion(it) - } + val version = tryOrNull { session.cryptoService().keysBackupService().getCurrentVersion() } + if (version == null) { // we just resume plain bootstrap doesKeyBackupExist = false @@ -115,8 +113,8 @@ class BootstrapSharedViewModel @AssistedInject constructor( } } else { // we need to get existing backup passphrase/key and convert to SSSS - val keyVersion = awaitCallback { - session.cryptoService().keysBackupService().getVersion(version.version, it) + val keyVersion = tryOrNull { + session.cryptoService().keysBackupService().getVersion(version.version) } if (keyVersion == null) { // strange case... just finish? diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index ed29f5b1d0..ee3bbe8f31 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -31,8 +31,10 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider +import im.vector.app.features.session.coroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME @@ -51,10 +53,7 @@ import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber data class VerificationBottomSheetViewState( @@ -419,30 +418,27 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } private fun tentativeRestoreBackup(res: Map?) { - viewModelScope.launch(Dispatchers.IO) { + // on session scope because will happen after viewmodel is cleared + session.coroutineScope.launch { try { val secret = res?.get(KEYBACKUP_SECRET_SSSS_NAME) ?: return@launch Unit.also { Timber.v("## Keybackup secret not restored from SSSS") } - val version = awaitCallback { - session.cryptoService().keysBackupService().getCurrentVersion(it) - } ?: return@launch + val version = tryOrNull { session.cryptoService().keysBackupService().getCurrentVersion() } + ?: return@launch - awaitCallback { - session.cryptoService().keysBackupService().restoreKeysWithRecoveryKey( - version, - computeRecoveryKey(secret.fromBase64()), - null, - null, - null, - it - ) - } + // TODO maybe mark as trusted earlier by checking recovery key early, then download? - awaitCallback { - session.cryptoService().keysBackupService().trustKeysBackupVersion(version, true, it) - } + session.cryptoService().keysBackupService().restoreKeysWithRecoveryKey( + version, + computeRecoveryKey(secret.fromBase64()), + null, + null, + null + ) + + session.cryptoService().keysBackupService().trustKeysBackupVersion(version, true) } catch (failure: Throwable) { // Just ignore for now Timber.e(failure, "## Failed to restore backup after SSSS recovery") diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt index 8fb5b27376..ded42e23e0 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt @@ -155,7 +155,9 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS fun refreshRemoteStateIfNeeded() { if (keysBackupState.value == KeysBackupState.Disabled) { - session.cryptoService().keysBackupService().checkAndStartKeysBackup() + viewModelScope.launch { + session.cryptoService().keysBackupService().checkAndStartKeysBackup() + } } } diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt index 4daaef6fe1..0fbbb3812e 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt @@ -73,7 +73,9 @@ class SignoutCheckViewModel @AssistedInject constructor( init { session.cryptoService().keysBackupService().addListener(this) - session.cryptoService().keysBackupService().checkAndStartKeysBackup() + viewModelScope.launch { + session.cryptoService().keysBackupService().checkAndStartKeysBackup() + } val quad4SIsSetup = session.sharedSecretStorageService.isRecoverySetup() val allKeysKnown = session.cryptoService().crossSigningService().allPrivateKeysKnown() @@ -112,7 +114,9 @@ class SignoutCheckViewModel @AssistedInject constructor( fun refreshRemoteStateIfNeeded() = withState { state -> if (state.keysBackupState == KeysBackupState.Disabled) { - session.cryptoService().keysBackupService().checkAndStartKeysBackup() + viewModelScope.launch { + session.cryptoService().keysBackupService().checkAndStartKeysBackup() + } } } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index dec9e6e8db..6bec52f1b1 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2041,6 +2041,7 @@ Computing recovery key… Downloading keys… Importing keys… + Decrypting keys… Unlock History Please enter a recovery key Backup could not be decrypted with this recovery key: please verify that you entered the correct recovery key. @@ -3442,6 +3443,7 @@ Join the Space with the given id Leave room with given id (or current room if null) Upgrades a room to a new version + Gen keys Sending Sent From 0e44e32d2a20c5e3bbfdc9ef77d779f225068d55 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 25 Nov 2021 18:32:10 +0100 Subject: [PATCH 195/252] Fix test compilation (not passing) --- .../crypto/crosssigning/XSigningTest.kt | 12 +- .../crypto/gossiping/KeyShareTests.kt | 16 +- .../keysbackup/KeysBackupScenarioData.kt | 2 +- .../crypto/keysbackup/KeysBackupTest.kt | 559 +++++++++--------- .../crypto/keysbackup/KeysBackupTestHelper.kt | 63 +- 5 files changed, 343 insertions(+), 309 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt index f3650b87be..65b1e38f0b 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt @@ -112,7 +112,7 @@ class XSigningTest : InstrumentedTest { }, it) } // Check that alice can see bob keys - mTestHelper.doSync> { aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), true, it) } + mTestHelper.runBlockingTest { aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), true) } val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobSession.myUserId) assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV!!.masterKey()) @@ -157,7 +157,7 @@ class XSigningTest : InstrumentedTest { // Check that alice can see bob keys val bobUserId = bobSession.myUserId - mTestHelper.doSync> { aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true, it) } + mTestHelper.runBlockingTest { aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true) } val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobUserId) assertTrue("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV?.isTrusted() == false) @@ -171,8 +171,8 @@ class XSigningTest : InstrumentedTest { val bobSecondDeviceId = bobSession2.sessionParams.deviceId!! // Check that bob first session sees the new login - val data = mTestHelper.doSync> { - bobSession.cryptoService().downloadKeys(listOf(bobUserId), true, it) + val data = mTestHelper.runBlockingTest { + bobSession.cryptoService().downloadKeys(listOf(bobUserId), true) } if (data.getUserDeviceIds(bobUserId)?.contains(bobSecondDeviceId) == false) { @@ -188,8 +188,8 @@ class XSigningTest : InstrumentedTest { } // Now alice should cross trust bob's second device - val data2 = mTestHelper.doSync> { - aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true, it) + val data2 = mTestHelper.runBlockingTest { + aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true) } // check that the device is seen diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index d1dc65ba83..6c118dfc00 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -218,11 +218,11 @@ class KeyShareTests : InstrumentedTest { } // Also bootstrap keybackup on first session - val creationInfo = mTestHelper.doSync { - aliceSession1.cryptoService().keysBackupService().prepareKeysBackupVersion(null, null, it) + val creationInfo = mTestHelper.runBlockingTest { + aliceSession1.cryptoService().keysBackupService().prepareKeysBackupVersion(null) } - val version = mTestHelper.doSync { - aliceSession1.cryptoService().keysBackupService().createKeysBackupVersion(creationInfo, it) + val version = mTestHelper.runBlockingTest { + aliceSession1.cryptoService().keysBackupService().createKeysBackupVersion(creationInfo) } // Save it for gossiping aliceSession1.cryptoService().keysBackupService().saveBackupRecoveryKey(creationInfo.recoveryKey, version = version.version) @@ -233,11 +233,11 @@ class KeyShareTests : InstrumentedTest { val aliceVerificationService2 = aliceSession2.cryptoService().verificationService() // force keys download - mTestHelper.doSync> { - aliceSession1.cryptoService().downloadKeys(listOf(aliceSession1.myUserId), true, it) + mTestHelper.runBlockingTest { + aliceSession1.cryptoService().downloadKeys(listOf(aliceSession1.myUserId), true) } - mTestHelper.doSync> { - aliceSession2.cryptoService().downloadKeys(listOf(aliceSession2.myUserId), true, it) + mTestHelper.runBlockingTest { + aliceSession2.cryptoService().downloadKeys(listOf(aliceSession2.myUserId), true) } var session1ShortCode: String? = null diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt index 864f3c12e4..c5b9da235c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt @@ -25,7 +25,7 @@ import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrappe * Data class to store result of [KeysBackupTestHelper.createKeysBackupScenarioWithPassword] */ data class KeysBackupScenarioData(val cryptoTestData: CryptoTestData, - val aliceKeys: List, + val aliceKeys: Int, val prepareKeysBackupDataResult: PrepareKeysBackupDataResult, val aliceSession2: Session) { fun cleanUp(testHelper: CommonTestHelper) { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index 0785dba8b9..f6e1348fb5 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.delay import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull @@ -60,40 +61,40 @@ class KeysBackupTest : InstrumentedTest { * - Check backup keys after having marked one as backed up * - Reset keys backup markers */ - @Test - fun roomKeysTest_testBackupStore_ok() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() - - // From doE2ETestWithAliceAndBobInARoomWithEncryptedMessages, we should have no backed up keys - val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store - val sessions = cryptoStore.inboundGroupSessionsToBackup(100) - val sessionsCount = sessions.size - - assertFalse(sessions.isEmpty()) - assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)) - assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)) - - // - Check backup keys after having marked one as backed up - val session = sessions[0] - - cryptoStore.markBackupDoneForInboundGroupSessions(Collections.singletonList(session)) - - assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)) - assertEquals(1, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)) - - val sessions2 = cryptoStore.inboundGroupSessionsToBackup(100) - assertEquals(sessionsCount - 1, sessions2.size) - - // - Reset keys backup markers - cryptoStore.resetBackupMarkers() - - val sessions3 = cryptoStore.inboundGroupSessionsToBackup(100) - assertEquals(sessionsCount, sessions3.size) - assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)) - assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)) - - cryptoTestData.cleanUp(mTestHelper) - } +// @Test +// fun roomKeysTest_testBackupStore_ok() { +// val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() +// +// // From doE2ETestWithAliceAndBobInARoomWithEncryptedMessages, we should have no backed up keys +// val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store +// val sessions = cryptoStore.inboundGroupSessionsToBackup(100) +// val sessionsCount = sessions.size +// +// assertFalse(sessions.isEmpty()) +// assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)) +// assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)) +// +// // - Check backup keys after having marked one as backed up +// val session = sessions[0] +// +// cryptoStore.markBackupDoneForInboundGroupSessions(Collections.singletonList(session)) +// +// assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)) +// assertEquals(1, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)) +// +// val sessions2 = cryptoStore.inboundGroupSessionsToBackup(100) +// assertEquals(sessionsCount - 1, sessions2.size) +// +// // - Reset keys backup markers +// cryptoStore.resetBackupMarkers() +// +// val sessions3 = cryptoStore.inboundGroupSessionsToBackup(100) +// assertEquals(sessionsCount, sessions3.size) +// assertEquals(sessionsCount, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)) +// assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)) +// +// cryptoTestData.cleanUp(mTestHelper) +// } /** * Check that prepareKeysBackupVersionWithPassword returns valid data @@ -110,8 +111,8 @@ class KeysBackupTest : InstrumentedTest { assertFalse(keysBackup.isEnabled) - val megolmBackupCreationInfo = mTestHelper.doSync { - keysBackup.prepareKeysBackupVersion(null, null, it) + val megolmBackupCreationInfo = mTestHelper.runBlockingTest { + keysBackup.prepareKeysBackupVersion(null) } assertEquals(MXCRYPTO_ALGORITHM_MEGOLM_BACKUP, megolmBackupCreationInfo.algorithm) @@ -136,15 +137,15 @@ class KeysBackupTest : InstrumentedTest { assertFalse(keysBackup.isEnabled) - val megolmBackupCreationInfo = mTestHelper.doSync { - keysBackup.prepareKeysBackupVersion(null, null, it) + val megolmBackupCreationInfo = mTestHelper.runBlockingTest { + keysBackup.prepareKeysBackupVersion(null) } assertFalse(keysBackup.isEnabled) // Create the version - mTestHelper.doSync { - keysBackup.createKeysBackupVersion(megolmBackupCreationInfo, it) + mTestHelper.runBlockingTest { + keysBackup.createKeysBackupVersion(megolmBackupCreationInfo) } // Backup must be enable now @@ -197,41 +198,41 @@ class KeysBackupTest : InstrumentedTest { /** * Check that backupAllGroupSessions() returns valid data */ - @Test - fun backupAllGroupSessionsTest() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() - - val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() - - val stateObserver = StateObserver(keysBackup) - - mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) - - // Check that backupAllGroupSessions returns valid data - val nbOfKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false) - - assertEquals(2, nbOfKeys) - - var lastBackedUpKeysProgress = 0 - - mTestHelper.doSync { - keysBackup.backupAllGroupSessions(object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - assertEquals(nbOfKeys, total) - lastBackedUpKeysProgress = progress - } - }, it) - } - - assertEquals(nbOfKeys, lastBackedUpKeysProgress) - - val backedUpKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true) - - assertEquals("All keys must have been marked as backed up", nbOfKeys, backedUpKeys) - - stateObserver.stopAndCheckStates(null) - cryptoTestData.cleanUp(mTestHelper) - } +// @Test +// fun backupAllGroupSessionsTest() { +// val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() +// +// val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() +// +// val stateObserver = StateObserver(keysBackup) +// +// mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) +// +// // Check that backupAllGroupSessions returns valid data +// val nbOfKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false) +// +// assertEquals(2, nbOfKeys) +// +// var lastBackedUpKeysProgress = 0 +// +// mTestHelper.doSync { +// keysBackup.backupAllGroupSessions(object : ProgressListener { +// override fun onProgress(progress: Int, total: Int) { +// assertEquals(nbOfKeys, total) +// lastBackedUpKeysProgress = progress +// } +// }, it) +// } +// +// assertEquals(nbOfKeys, lastBackedUpKeysProgress) +// +// val backedUpKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true) +// +// assertEquals("All keys must have been marked as backed up", nbOfKeys, backedUpKeys) +// +// stateObserver.stopAndCheckStates(null) +// cryptoTestData.cleanUp(mTestHelper) +// } /** * Check encryption and decryption of megolm keys in the backup. @@ -241,40 +242,40 @@ class KeysBackupTest : InstrumentedTest { * - Check [MXKeyBackup decryptKeyBackupData] returns stg * - Compare the decrypted megolm key with the original one */ - @Test - fun testEncryptAndDecryptKeysBackupData() { - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() - - val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService - - val stateObserver = StateObserver(keysBackup) - - // - Pick a megolm key - val session = keysBackup.store.inboundGroupSessionsToBackup(1)[0] - - val keyBackupCreationInfo = mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup).megolmBackupCreationInfo - - // - Check encryptGroupSession() returns stg - val keyBackupData = keysBackup.encryptGroupSession(session) - assertNotNull(keyBackupData) - assertNotNull(keyBackupData!!.sessionData) - - // - Check pkDecryptionFromRecoveryKey() is able to create a OlmPkDecryption - val decryption = keysBackup.pkDecryptionFromRecoveryKey(keyBackupCreationInfo.recoveryKey) - assertNotNull(decryption) - // - Check decryptKeyBackupData() returns stg - val sessionData = keysBackup - .decryptKeyBackupData(keyBackupData, - session.olmInboundGroupSession!!.sessionIdentifier(), - cryptoTestData.roomId, - decryption!!) - assertNotNull(sessionData) - // - Compare the decrypted megolm key with the original one - mKeysBackupTestHelper.assertKeysEquals(session.exportKeys(), sessionData) - - stateObserver.stopAndCheckStates(null) - cryptoTestData.cleanUp(mTestHelper) - } +// @Test +// fun testEncryptAndDecryptKeysBackupData() { +// val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() +// +// val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService +// +// val stateObserver = StateObserver(keysBackup) +// +// // - Pick a megolm key +// val session = keysBackup.store.inboundGroupSessionsToBackup(1)[0] +// +// val keyBackupCreationInfo = mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup).megolmBackupCreationInfo +// +// // - Check encryptGroupSession() returns stg +// val keyBackupData = keysBackup.encryptGroupSession(session) +// assertNotNull(keyBackupData) +// assertNotNull(keyBackupData!!.sessionData) +// +// // - Check pkDecryptionFromRecoveryKey() is able to create a OlmPkDecryption +// val decryption = keysBackup.pkDecryptionFromRecoveryKey(keyBackupCreationInfo.recoveryKey) +// assertNotNull(decryption) +// // - Check decryptKeyBackupData() returns stg +// val sessionData = keysBackup +// .decryptKeyBackupData(keyBackupData, +// session.olmInboundGroupSession!!.sessionIdentifier(), +// cryptoTestData.roomId, +// decryption!!) +// assertNotNull(sessionData) +// // - Compare the decrypted megolm key with the original one +// mKeysBackupTestHelper.assertKeysEquals(session.exportKeys(), sessionData) +// +// stateObserver.stopAndCheckStates(null) +// cryptoTestData.cleanUp(mTestHelper) +// } /** * - Do an e2e backup to the homeserver with a recovery key @@ -287,13 +288,12 @@ class KeysBackupTest : InstrumentedTest { val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null) // - Restore the e2e backup from the homeserver - val importRoomKeysResult = mTestHelper.doSync { + val importRoomKeysResult = mTestHelper.runBlockingTest { testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey, null, null, - null, - it + null ) } @@ -379,11 +379,10 @@ class KeysBackupTest : InstrumentedTest { assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) // - Trust the backup from the new device - mTestHelper.doSync { + mTestHelper.runBlockingTest { testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersion( testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, - true, - it + true ) } @@ -395,15 +394,15 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = mTestHelper.doSync { - testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) + val keysVersionResult = mTestHelper.runBlockingTest { + testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion() } // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) - val keysBackupVersionTrust = mTestHelper.doSync { - testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult, it) + val keysBackupVersionTrust = mTestHelper.runBlockingTest { + testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult) } // - It must be trusted and must have 2 signatures now @@ -438,11 +437,10 @@ class KeysBackupTest : InstrumentedTest { assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) // - Trust the backup from the new device with the recovery key - mTestHelper.doSync { + mTestHelper.runBlockingTest { testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithRecoveryKey( testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, - testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey, - it + testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey ) } @@ -454,15 +452,15 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = mTestHelper.doSync { - testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) + val keysVersionResult = mTestHelper.runBlockingTest{ + testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion() } // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) - val keysBackupVersionTrust = mTestHelper.doSync { - testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult, it) + val keysBackupVersionTrust = mTestHelper.runBlockingTest { + testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult) } // - It must be trusted and must have 2 signatures now @@ -495,13 +493,17 @@ class KeysBackupTest : InstrumentedTest { assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) // - Try to trust the backup from the new device with a wrong recovery key - val latch = CountDownLatch(1) - testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithRecoveryKey( - testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, - "Bad recovery key", - TestMatrixCallback(latch, false) - ) - mTestHelper.await(latch) + mTestHelper.runBlockingTest { + try { + testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithRecoveryKey( + testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, + "Bad recovery key" + ) + fail("Should have failed to trust") + } catch (failure: Throwable) { + + } + } // - The new device must still see the previous backup as not trusted assertNotNull(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion) @@ -538,11 +540,10 @@ class KeysBackupTest : InstrumentedTest { assertEquals(KeysBackupState.NotTrusted, testData.aliceSession2.cryptoService().keysBackupService().state) // - Trust the backup from the new device with the password - mTestHelper.doSync { + mTestHelper.runBlockingTest { testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithPassphrase( testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, - password, - it + password ) } @@ -554,15 +555,15 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = mTestHelper.doSync { - testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) + val keysVersionResult = mTestHelper.runBlockingTest { + testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion() } // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) - val keysBackupVersionTrust = mTestHelper.doSync { - testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult, it) + val keysBackupVersionTrust = mTestHelper.runBlockingTest { + testData.aliceSession2.cryptoService().keysBackupService().getKeysBackupTrust(keysVersionResult) } // - It must be trusted and must have 2 signatures now @@ -599,11 +600,17 @@ class KeysBackupTest : InstrumentedTest { // - Try to trust the backup from the new device with a wrong password val latch = CountDownLatch(1) - testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithPassphrase( - testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, - badPassword, - TestMatrixCallback(latch, false) - ) + mTestHelper.runBlockingTest { + try { + testData.aliceSession2.cryptoService().keysBackupService().trustKeysBackupVersionWithPassphrase( + testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, + badPassword + ) + fail("Should have fail to trust") + } catch (failure: Throwable) { + + } + } mTestHelper.await(latch) // - The new device must still see the previous backup as not trusted @@ -626,21 +633,17 @@ class KeysBackupTest : InstrumentedTest { val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(null) // - Try to restore the e2e backup with a wrong recovery key - val latch2 = CountDownLatch(1) var importRoomKeysResult: ImportRoomKeysResult? = null - testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, - "EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d", - null, - null, - null, - object : TestMatrixCallback(latch2, false) { - override fun onSuccess(data: ImportRoomKeysResult) { - importRoomKeysResult = data - super.onSuccess(data) - } - } - ) - mTestHelper.await(latch2) + mTestHelper.runBlockingTest { + testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, + "EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d", + null, + null, + null + ).let { data -> + importRoomKeysResult = data + } + } // onSuccess may not have been called assertNull(importRoomKeysResult) @@ -663,7 +666,7 @@ class KeysBackupTest : InstrumentedTest { // - Restore the e2e backup with the password val steps = ArrayList() - val importRoomKeysResult = mTestHelper.doSync { + val importRoomKeysResult = mTestHelper.runBlockingTest { testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, password, null, @@ -672,8 +675,7 @@ class KeysBackupTest : InstrumentedTest { override fun onStepProgress(step: StepProgressListener.Step) { steps.add(step) } - }, - it + } ) } @@ -719,20 +721,16 @@ class KeysBackupTest : InstrumentedTest { // - Try to restore the e2e backup with a wrong password val latch2 = CountDownLatch(1) var importRoomKeysResult: ImportRoomKeysResult? = null - testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, - wrongPassword, - null, - null, - null, - object : TestMatrixCallback(latch2, false) { - override fun onSuccess(data: ImportRoomKeysResult) { - importRoomKeysResult = data - super.onSuccess(data) - } - } - ) - mTestHelper.await(latch2) - + mTestHelper.runBlockingTest { + testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, + wrongPassword, + null, + null, + null + ).let { + importRoomKeysResult = it + } + } // onSuccess may not have been called assertNull(importRoomKeysResult) @@ -752,13 +750,12 @@ class KeysBackupTest : InstrumentedTest { val testData = mKeysBackupTestHelper.createKeysBackupScenarioWithPassword(password) // - Restore the e2e backup with the recovery key. - val importRoomKeysResult = mTestHelper.doSync { + val importRoomKeysResult = mTestHelper.runBlockingTest { testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey, null, null, - null, - it + null ) } @@ -780,18 +777,16 @@ class KeysBackupTest : InstrumentedTest { // - Try to restore the e2e backup with a password val latch2 = CountDownLatch(1) var importRoomKeysResult: ImportRoomKeysResult? = null - testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, - "password", - null, - null, - null, - object : TestMatrixCallback(latch2, false) { - override fun onSuccess(data: ImportRoomKeysResult) { - importRoomKeysResult = data - super.onSuccess(data) - } - } - ) + mTestHelper.runBlockingTest { + testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!, + "password", + null, + null, + null + ).let { + importRoomKeysResult = it + } + } mTestHelper.await(latch2) // onSuccess may not have been called @@ -817,13 +812,13 @@ class KeysBackupTest : InstrumentedTest { mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) // Get key backup version from the homeserver - val keysVersionResult = mTestHelper.doSync { - keysBackup.getCurrentVersion(it) + val keysVersionResult = mTestHelper.runBlockingTest { + keysBackup.getCurrentVersion() } // - Check the returned KeyBackupVersion is trusted - val keysBackupVersionTrust = mTestHelper.doSync { - keysBackup.getKeysBackupTrust(keysVersionResult!!, it) + val keysBackupVersionTrust = mTestHelper.runBlockingTest { + keysBackup.getKeysBackupTrust(keysVersionResult!!) } assertNotNull(keysBackupVersionTrust) @@ -908,64 +903,64 @@ class KeysBackupTest : InstrumentedTest { * - Make alice back up all her keys again * -> That must fail and her backup state must be WrongBackUpVersion */ - @Test - fun testBackupWhenAnotherBackupWasCreated() { - // - Create a backup version - val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() - - val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() - - val stateObserver = StateObserver(keysBackup) - - assertFalse(keysBackup.isEnabled) - - // Wait for keys backup to be finished - val latch0 = CountDownLatch(1) - var count = 0 - keysBackup.addListener(object : KeysBackupStateListener { - override fun onStateChange(newState: KeysBackupState) { - // Check the backup completes - if (newState == KeysBackupState.ReadyToBackUp) { - count++ - - if (count == 2) { - // Remove itself from the list of listeners - keysBackup.removeListener(this) - - latch0.countDown() - } - } - } - }) - - // - Make alice back up her keys to her homeserver - mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) - - assertTrue(keysBackup.isEnabled) - - mTestHelper.await(latch0) - - // - Create a new backup with fake data on the homeserver, directly using the rest client - val megolmBackupCreationInfo = mCryptoTestHelper.createFakeMegolmBackupCreationInfo() - mTestHelper.doSync { - (keysBackup as DefaultKeysBackupService).createFakeKeysBackupVersion(megolmBackupCreationInfo, it) - } - - // Reset the store backup status for keys - (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store.resetBackupMarkers() - - // - Make alice back up all her keys again - val latch2 = CountDownLatch(1) - keysBackup.backupAllGroupSessions(null, TestMatrixCallback(latch2, false)) - mTestHelper.await(latch2) - - // -> That must fail and her backup state must be WrongBackUpVersion - assertEquals(KeysBackupState.WrongBackUpVersion, keysBackup.state) - assertFalse(keysBackup.isEnabled) - - stateObserver.stopAndCheckStates(null) - cryptoTestData.cleanUp(mTestHelper) - } +// @Test +// fun testBackupWhenAnotherBackupWasCreated() { +// // - Create a backup version +// val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() +// +// val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() +// +// val stateObserver = StateObserver(keysBackup) +// +// assertFalse(keysBackup.isEnabled) +// +// // Wait for keys backup to be finished +// val latch0 = CountDownLatch(1) +// var count = 0 +// keysBackup.addListener(object : KeysBackupStateListener { +// override fun onStateChange(newState: KeysBackupState) { +// // Check the backup completes +// if (newState == KeysBackupState.ReadyToBackUp) { +// count++ +// +// if (count == 2) { +// // Remove itself from the list of listeners +// keysBackup.removeListener(this) +// +// latch0.countDown() +// } +// } +// } +// }) +// +// // - Make alice back up her keys to her homeserver +// mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) +// +// assertTrue(keysBackup.isEnabled) +// +// mTestHelper.await(latch0) +// +// // - Create a new backup with fake data on the homeserver, directly using the rest client +// val megolmBackupCreationInfo = mCryptoTestHelper.createFakeMegolmBackupCreationInfo() +// mTestHelper.doSync { +// (keysBackup as DefaultKeysBackupService).createFakeKeysBackupVersion(megolmBackupCreationInfo, it) +// } +// +// // Reset the store backup status for keys +// (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store.resetBackupMarkers() +// +// // - Make alice back up all her keys again +// val latch2 = CountDownLatch(1) +// keysBackup.backupAllGroupSessions(null, TestMatrixCallback(latch2, false)) +// mTestHelper.await(latch2) +// +// // -> That must fail and her backup state must be WrongBackUpVersion +// assertEquals(KeysBackupState.WrongBackUpVersion, keysBackup.state) +// assertFalse(keysBackup.isEnabled) +// +// stateObserver.stopAndCheckStates(null) +// cryptoTestData.cleanUp(mTestHelper) +// } /** * - Do an e2e backup to the homeserver @@ -992,9 +987,18 @@ class KeysBackupTest : InstrumentedTest { mKeysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) // Wait for keys backup to finish by asking again to backup keys. - mTestHelper.doSync { - keysBackup.backupAllGroupSessions(null, it) + mTestHelper.runBlockingTest { + keysBackup.checkAndStartKeysBackup() + delay(1000) } + mTestHelper.waitWithLatch { + mTestHelper.retryPeriodicallyWithLatch(it) { + keysBackup.state == KeysBackupState.ReadyToBackUp + } + } +// mTestHelper.doSync { +// keysBackup.backupAllGroupSessions(null, it) +// } val oldDeviceId = cryptoTestData.firstSession.sessionParams.deviceId!! val oldKeyBackupVersion = keysBackup.currentBackupVersion @@ -1016,16 +1020,26 @@ class KeysBackupTest : InstrumentedTest { val stateObserver2 = StateObserver(keysBackup2) var isSuccessful = false - val latch2 = CountDownLatch(1) - keysBackup2.backupAllGroupSessions( - null, - object : TestMatrixCallback(latch2, false) { - override fun onSuccess(data: Unit) { - isSuccessful = true - super.onSuccess(data) - } - }) - mTestHelper.await(latch2) +// val latch2 = CountDownLatch(1) + mTestHelper.runBlockingTest { + keysBackup2.checkAndStartKeysBackup() + delay(1000) + } + mTestHelper.waitWithLatch { + mTestHelper.retryPeriodicallyWithLatch(it) { + keysBackup2.state == KeysBackupState.ReadyToBackUp + } + } + +// keysBackup2.backupAllGroupSessions( +// null, +// object : TestMatrixCallback(latch2, false) { +// override fun onSuccess(data: Unit) { +// isSuccessful = true +// super.onSuccess(data) +// } +// }) +// mTestHelper.await(latch2) assertFalse(isSuccessful) @@ -1054,8 +1068,17 @@ class KeysBackupTest : InstrumentedTest { // -> It must use the same backup version assertEquals(oldKeyBackupVersion, aliceSession2.cryptoService().keysBackupService().currentBackupVersion) - mTestHelper.doSync { - aliceSession2.cryptoService().keysBackupService().backupAllGroupSessions(null, it) +// mTestHelper.doSync { +// aliceSession2.cryptoService().keysBackupService().backupAllGroupSessions(null, it) +// } + mTestHelper.runBlockingTest { + aliceSession2.cryptoService().keysBackupService().checkAndStartKeysBackup() + delay(1000) + } + mTestHelper.waitWithLatch { + mTestHelper.retryPeriodicallyWithLatch(it) { + aliceSession2.cryptoService().keysBackupService().state == KeysBackupState.ReadyToBackUp + } } // -> It must success @@ -1087,7 +1110,7 @@ class KeysBackupTest : InstrumentedTest { assertTrue(keysBackup.isEnabled) // Delete the backup - mTestHelper.doSync { keysBackup.deleteBackup(keyBackupCreationInfo.version, it) } + mTestHelper.runBlockingTest { keysBackup.deleteBackup(keyBackupCreationInfo.version) } // Backup is now disabled assertFalse(keysBackup.isEnabled) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt index a625ffc0e9..7aca9c4274 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto.keysbackup +import kotlinx.coroutines.delay import org.junit.Assert import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.Session @@ -45,29 +46,38 @@ class KeysBackupTestHelper( fun createKeysBackupScenarioWithPassword(password: String?): KeysBackupScenarioData { val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoomWithEncryptedMessages() - val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store +// val cryptoStore = (cryptoTestData.firstSession.cryptoService().keysBackupService() as DefaultKeysBackupService).store val keysBackup = cryptoTestData.firstSession.cryptoService().keysBackupService() val stateObserver = StateObserver(keysBackup) - val aliceKeys = cryptoStore.inboundGroupSessionsToBackup(100) +// val aliceKeys = cryptoStore.inboundGroupSessionsToBackup(100) // - Do an e2e backup to the homeserver val prepareKeysBackupDataResult = prepareAndCreateKeysBackupData(keysBackup, password) - var lastProgress = 0 - var lastTotal = 0 - mTestHelper.doSync { - keysBackup.backupAllGroupSessions(object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - lastProgress = progress - lastTotal = total - } - }, it) +// var lastProgress = 0 +// var lastTotal = 0 +// mTestHelper.doSync { +// keysBackup.backupAllGroupSessions(object : ProgressListener { +// override fun onProgress(progress: Int, total: Int) { +// lastProgress = progress +// lastTotal = total +// } +// }, it) +// } + + mTestHelper.runBlockingTest { + keysBackup.checkAndStartKeysBackup() + delay(1000) + } + mTestHelper.waitWithLatch { + mTestHelper.retryPeriodicallyWithLatch(it) { + keysBackup.state == KeysBackupState.ReadyToBackUp + } } - Assert.assertEquals(2, lastProgress) - Assert.assertEquals(2, lastTotal) + Assert.assertEquals(2, cryptoTestData.firstSession.cryptoService().keysBackupService().getTotalNumbersOfBackedUpKeys()) val aliceUserId = cryptoTestData.firstSession.myUserId @@ -83,7 +93,7 @@ class KeysBackupTestHelper( stateObserver.stopAndCheckStates(null) return KeysBackupScenarioData(cryptoTestData, - aliceKeys, + aliceSession2.cryptoService().keysBackupService().getTotalNumbersOfBackedUpKeys(), prepareKeysBackupDataResult, aliceSession2) } @@ -92,8 +102,8 @@ class KeysBackupTestHelper( password: String? = null): PrepareKeysBackupDataResult { val stateObserver = StateObserver(keysBackup) - val megolmBackupCreationInfo = mTestHelper.doSync { - keysBackup.prepareKeysBackupVersion(password, null, it) + val megolmBackupCreationInfo = mTestHelper.runBlockingTest { + keysBackup.prepareKeysBackupVersion(password) } Assert.assertNotNull(megolmBackupCreationInfo) @@ -101,8 +111,8 @@ class KeysBackupTestHelper( Assert.assertFalse(keysBackup.isEnabled) // Create the version - val keysVersion = mTestHelper.doSync { - keysBackup.createKeysBackupVersion(megolmBackupCreationInfo, it) + val keysVersion = mTestHelper.runBlockingTest { + keysBackup.createKeysBackupVersion(megolmBackupCreationInfo) } Assert.assertNotNull(keysVersion.version) @@ -165,18 +175,19 @@ class KeysBackupTestHelper( total: Int, imported: Int) { // - Imported keys number must be correct - Assert.assertEquals(testData.aliceKeys.size, total) + Assert.assertEquals(testData.aliceKeys, total) Assert.assertEquals(total, imported) // - The new device must have the same count of megolm keys - Assert.assertEquals(testData.aliceKeys.size, testData.aliceSession2.cryptoService().inboundGroupSessionsCount(false)) + Assert.assertEquals(testData.aliceKeys, testData.aliceSession2.cryptoService().inboundGroupSessionsCount(false)) // - Alice must have the same keys on both devices - for (aliceKey1 in testData.aliceKeys) { - val aliceKey2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store - .getInboundGroupSession(aliceKey1.olmInboundGroupSession!!.sessionIdentifier(), aliceKey1.senderKey!!) - Assert.assertNotNull(aliceKey2) - assertKeysEquals(aliceKey1.exportKeys(), aliceKey2!!.exportKeys()) - } +// +// for (aliceKey1 in testData.aliceKeys) { +// val aliceKey2 = (testData.aliceSession2.cryptoService().keysBackupService() as DefaultKeysBackupService).store +// .getInboundGroupSession(aliceKey1.olmInboundGroupSession!!.sessionIdentifier(), aliceKey1.senderKey!!) +// Assert.assertNotNull(aliceKey2) +// assertKeysEquals(aliceKey1.exportKeys(), aliceKey2!!.exportKeys()) +// } } } From 1635c9730a31a428d08c6e5a0be3d3bbe017a89a Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 26 Nov 2021 11:47:16 +0100 Subject: [PATCH 196/252] Chunk key import to avoid ram allocation peak --- .../android/sdk/internal/crypto/OlmMachine.kt | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index dfb76401e0..cfe12901f5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -75,13 +75,9 @@ class CryptoLogger : Logger { } } -private class CryptoProgressListener(listener: ProgressListener?) : RustProgressListener { - private val inner: ProgressListener? = listener - +private class CryptoProgressListener(private val listener: ProgressListener?) : RustProgressListener { override fun onProgress(progress: Int, total: Int) { - if (this.inner != null) { - this.inner.onProgress(progress, total) - } + listener?.onProgress(progress, total) } } @@ -524,14 +520,29 @@ internal class OlmMachine( listener: ProgressListener? ): ImportRoomKeysResult = withContext(Dispatchers.IO) { + val adapter = MoshiProvider.providesMoshi().adapter(List::class.java) - val encodedKeys = adapter.toJson(keys) - val rustListener = CryptoProgressListener(listener) + // If the key backup is too big we take the risk of causing OOM + // so let's chunk to avoid it + var totalImported = 0L + var accTotal = 0L + keys.chunked(500) + .forEach { keysSlice -> + val encodedKeys = adapter.toJson(keysSlice) + val rustListener = object : RustProgressListener { + override fun onProgress(progress: Int, total: Int) { + val accProgress = (accTotal + progress).toInt() + listener?.onProgress(accProgress, keys.size) + } + } - val result = inner.importDecryptedKeys(encodedKeys, rustListener) - - ImportRoomKeysResult(result.total.toInt(), result.imported.toInt()) + inner.importDecryptedKeys(encodedKeys, rustListener).let { + totalImported += it.imported + accTotal += it.total + } + } + ImportRoomKeysResult(totalImported.toInt(), accTotal.toInt()) } @Throws(CryptoStoreException::class) From 69e4b6e8a4fa9bcf08abefb4cbe53cc096f4f8e6 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 26 Nov 2021 13:56:36 +0100 Subject: [PATCH 197/252] Improve key decryption perf --- .../crypto/keysbackup/RustKeyBackupService.kt | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 40d27c926d..3320ec089a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -23,6 +23,8 @@ import androidx.annotation.WorkerThread import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -486,42 +488,42 @@ internal class RustKeyBackupService @Inject constructor( val data = getKeys(sessionId, roomId, keysVersionResult.version) return withContext(coroutineDispatchers.computation) { - val sessionsData = ArrayList() - // Restore that data - var sessionsFromHsCount = 0 - cryptoCoroutineScope.launch(Dispatchers.Main) { + withContext(Dispatchers.Main) { stepProgressListener?.onStepProgress(StepProgressListener.Step.DecryptingKey(0, data.roomIdToRoomKeysBackupData.size)) } - var progressDecryptIndex = 0 - - // TODO this is quite long, could we add some concurrency here? - for ((roomIdLoop, backupData) in data.roomIdToRoomKeysBackupData) { - val roomIndex = progressDecryptIndex - progressDecryptIndex++ - cryptoCoroutineScope.launch(Dispatchers.Main) { - stepProgressListener?.onStepProgress(StepProgressListener.Step.DecryptingKey(roomIndex, data.roomIdToRoomKeysBackupData.size)) - } - for ((sessionIdLoop, keyBackupData) in backupData.sessionIdToKeyBackupData) { - sessionsFromHsCount++ - - val sessionData = decryptKeyBackupData(keyBackupData, sessionIdLoop, roomIdLoop, recoveryKey) - - // rust is not very lax and will throw if field are missing, - // add a check - // TODO maybe could be done on rust side? - sessionData?.takeIf { - it.isValid().also { - if (!it) { - Timber.w("restoreKeysWithRecoveryKey: malformed sessionData $sessionData") + // Decrypting by chunk of 500 keys in parallel + // we loose proper progress report but tested 3x faster on big backup + val sessionsData = data.roomIdToRoomKeysBackupData + .mapValues { + it.value.sessionIdToKeyBackupData + } + .flatMap { flat -> + flat.value.entries.map { flat.key to it } + } + .chunked(500) + .map { slice -> + async { + slice.mapNotNull { pair -> + decryptKeyBackupData(pair.second.value, pair.second.key, pair.first, recoveryKey) + ?.takeIf { sessionData -> + sessionData.isValid().also { + if (!it) { + Timber.w("restoreKeysWithRecoveryKey: malformed sessionData $sessionData") + } + } + } } } - }?.let { - sessionsData.add(it) } - } + .awaitAll() + .flatten() + + withContext(Dispatchers.Main) { + stepProgressListener?.onStepProgress(StepProgressListener.Step.DecryptingKey(data.roomIdToRoomKeysBackupData.size, data.roomIdToRoomKeysBackupData.size)) } + Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" + - " of $sessionsFromHsCount from the backup store on the homeserver") + " of ${data.roomIdToRoomKeysBackupData.size} rooms from the backup store on the homeserver") // Do not trigger a backup for them if they come from the backup version we are using val backUp = keysVersionResult.version != keysBackupVersion?.version @@ -534,7 +536,6 @@ internal class RustKeyBackupService @Inject constructor( val progressListener = if (stepProgressListener != null) { object : ProgressListener { override fun onProgress(progress: Int, total: Int) { - // Note: no need to post to UI thread, importMegolmSessionsData() will do it cryptoCoroutineScope.launch(Dispatchers.Main) { stepProgressListener.onStepProgress(StepProgressListener.Step.ImportingKey(progress, total)) } From ee6eec041a3099316c7bba52a521a8ea23d6f4ea Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 26 Nov 2021 16:47:17 +0100 Subject: [PATCH 198/252] Fix / unlock keybackup from 4S --- .../keysbackup/restore/KeysBackupRestoreSharedViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt index 079828dc52..62c13e3a00 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt @@ -195,7 +195,7 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { try { - recoverUsingBackupRecoveryKey(secret) + recoverUsingBackupRecoveryKey(computeRecoveryKey(secret.fromBase64())) } catch (failure: Throwable) { _navigateEvent.postValue( LiveEvent(NAVIGATE_FAILED_TO_LOAD_4S) From 24dc52e4f62c53e82cde9c12ce0b6e861ff34239 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 29 Nov 2021 14:41:37 +0100 Subject: [PATCH 199/252] Use ImportKeysResult to notify sessions listeners --- .../internal/crypto/DefaultCryptoService.kt | 24 ++---- .../crypto/IncomingGossipingRequestManager.kt | 1 + .../crypto/MegolmSessionImportManager.kt | 77 +++++++++++++++++++ .../sdk/internal/crypto/NewSessionListener.kt | 2 +- .../android/sdk/internal/crypto/OlmMachine.kt | 9 ++- .../internal/crypto/RoomDecryptorProvider.kt | 4 +- .../actions/MegolmSessionDataImporter.kt | 2 +- .../algorithms/megolm/MXMegolmDecryption.kt | 2 +- .../crypto/keysbackup/RustKeyBackupService.kt | 6 +- .../crypto/model/ImportRoomKeysResult.kt | 18 ++++- .../room/timeline/TimelineEventDecryptor.kt | 2 +- 11 files changed, 118 insertions(+), 29 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionImportManager.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 1a006c51c5..dffc100e7a 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -134,6 +134,7 @@ internal class DefaultCryptoService @Inject constructor( private val crossSigningService: CrossSigningService, private val verificationService: RustVerificationService, private val keysBackupService: RustKeyBackupService, + private val megolmSessionImportManager: MegolmSessionImportManager, private val olmMachineProvider: OlmMachineProvider ) : CryptoService { @@ -152,9 +153,6 @@ internal class DefaultCryptoService @Inject constructor( private val outgoingRequestsLock: Mutex = Mutex() private val roomKeyShareLocks: ConcurrentHashMap = ConcurrentHashMap() - // TODO does this need to be concurrent? - private val newSessionListeners = ArrayList() - fun onStateEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) @@ -675,17 +673,7 @@ internal class DefaultCryptoService @Inject constructor( roomId: String, sessionId: String, ) { - // The sender key is actually unused since it's unimportant for megolm - // Our events don't contain the info so pass an empty string until we - // change the listener definition - val senderKey = "" - - newSessionListeners.forEach { - try { - it.onNewSession(roomId, senderKey, sessionId) - } catch (e: Throwable) { - } - } + megolmSessionImportManager.dispatchNewSession(roomId, sessionId) } suspend fun receiveSyncChanges( @@ -886,7 +874,9 @@ internal class DefaultCryptoService @Inject constructor( override suspend fun importRoomKeys(roomKeysAsArray: ByteArray, password: String, progressListener: ProgressListener?): ImportRoomKeysResult { - val result = olmMachine.importKeys(roomKeysAsArray, password, progressListener) + val result = olmMachine.importKeys(roomKeysAsArray, password, progressListener).also { + megolmSessionImportManager.dispatchKeyImportResults(it) + } keysBackupService.maybeBackupKeys() return result @@ -1030,11 +1020,11 @@ internal class DefaultCryptoService @Inject constructor( } override fun addNewSessionListener(newSessionListener: NewSessionListener) { - if (!newSessionListeners.contains(newSessionListener)) newSessionListeners.add(newSessionListener) + megolmSessionImportManager.addListener(newSessionListener) } override fun removeSessionListener(listener: NewSessionListener) { - newSessionListeners.remove(listener) + megolmSessionImportManager.removeListener(listener) } /* ========================================================================================== * DEBUG INFO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt index 220f25ec80..cf7a373258 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt @@ -44,6 +44,7 @@ import timber.log.Timber import java.util.concurrent.Executors import javax.inject.Inject +@Deprecated("rust") @SessionScope internal class IncomingGossipingRequestManager @Inject constructor( @SessionId private val sessionId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionImportManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionImportManager.kt new file mode 100644 index 0000000000..93f0c12caf --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionImportManager.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2021 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult +import org.matrix.android.sdk.internal.session.SessionScope +import javax.inject.Inject + +/** + * Helper that allows listeners to be notified when a new megolm session + * has been added to the crypto layer (could be via room keys or forward keys via sync + * or after importing keys from key backup or manual import). + * Can be used to refresh display when the keys are received after the message + */ +@SessionScope +internal class MegolmSessionImportManager @Inject constructor( + private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val cryptoCoroutineScope: CoroutineScope +) { + + private val newSessionsListeners = mutableListOf() + + fun addListener(listener: NewSessionListener) { + synchronized(newSessionsListeners) { + if (!newSessionsListeners.contains(listener)) { + newSessionsListeners.add(listener) + } + } + } + + fun removeListener(listener: NewSessionListener) { + synchronized(newSessionsListeners) { + newSessionsListeners.remove(listener) + } + } + + fun dispatchNewSession(roomId: String?, sessionId: String) { + val copy = synchronized(newSessionsListeners) { + newSessionsListeners.toList() + } + cryptoCoroutineScope.launch(coroutineDispatchers.computation) { + copy.forEach { + tryOrNull("Failed to dispatch new session import") { + it.onNewSession(roomId, sessionId) + } + } + } + } + + fun dispatchKeyImportResults(result: ImportRoomKeysResult) { + result.importedSessionInfo.forEach { (roomId, senderToSessionIdMap) -> + senderToSessionIdMap.values.forEach { sessionList -> + sessionList.forEach { sessionId -> + dispatchNewSession(roomId, sessionId) + } + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/NewSessionListener.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/NewSessionListener.kt index 301729680c..19f89b2f1e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/NewSessionListener.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/NewSessionListener.kt @@ -16,5 +16,5 @@ package org.matrix.android.sdk.internal.crypto interface NewSessionListener { - fun onNewSession(roomId: String?, senderKey: String, sessionId: String) + fun onNewSession(roomId: String?, sessionId: String) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index cfe12901f5..2d09d000a9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -510,8 +510,7 @@ internal class OlmMachine( val result = inner.importKeys(decodedKeys, passphrase, rustListener) - // TODO do we want to remove the cast here? - ImportRoomKeysResult(result.total.toInt(), result.imported.toInt()) + ImportRoomKeysResult.fromOlm(result) } @Throws(CryptoStoreException::class) @@ -520,13 +519,14 @@ internal class OlmMachine( listener: ProgressListener? ): ImportRoomKeysResult = withContext(Dispatchers.IO) { - val adapter = MoshiProvider.providesMoshi().adapter(List::class.java) // If the key backup is too big we take the risk of causing OOM + // when serializing to json // so let's chunk to avoid it var totalImported = 0L var accTotal = 0L + val details = mutableMapOf>>() keys.chunked(500) .forEach { keysSlice -> val encodedKeys = adapter.toJson(keysSlice) @@ -540,9 +540,10 @@ internal class OlmMachine( inner.importDecryptedKeys(encodedKeys, rustListener).let { totalImported += it.imported accTotal += it.total + details.putAll(it.keys) } } - ImportRoomKeysResult(totalImported.toInt(), accTotal.toInt()) + ImportRoomKeysResult(totalImported.toInt(), accTotal.toInt(), details) } @Throws(CryptoStoreException::class) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt index 89fb43ef2e..dd81eae99a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt @@ -72,11 +72,11 @@ internal class RoomDecryptorProvider @Inject constructor( val alg = when (algorithm) { MXCRYPTO_ALGORITHM_MEGOLM -> megolmDecryptionFactory.create().apply { this.newSessionListener = object : NewSessionListener { - override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) { + override fun onNewSession(roomId: String?, sessionId: String) { // PR reviewer: the parameter has been renamed so is now in conflict with the parameter of getOrCreateRoomDecryptor newSessionListeners.forEach { try { - it.onNewSession(roomId, senderKey, sessionId) + it.onNewSession(roomId, sessionId) } catch (e: Throwable) { } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt index e0748a0d1f..6c8c1c4637 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt @@ -103,6 +103,6 @@ internal class MegolmSessionDataImporter @Inject constructor(private val olmDevi Timber.v("## importMegolmSessionsData : sessions import " + (t1 - t0) + " ms (" + megolmSessionsData.size + " sessions)") - return ImportRoomKeysResult(totalNumbersOfKeys, totalNumbersOfImportedKeys) + return ImportRoomKeysResult(totalNumbersOfKeys, totalNumbersOfImportedKeys, emptyMap()) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index ea239dad53..20658f7db4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -317,7 +317,7 @@ internal class MXMegolmDecryption(private val userId: String, */ override fun onNewSession(senderKey: String, sessionId: String) { Timber.tag(loggerTag.value).v("ON NEW SESSION $sessionId - $senderKey") - newSessionListener?.onNewSession(null, senderKey, sessionId) + newSessionListener?.onNewSession(null, sessionId) } override fun hasKeysForKeyRequest(request: IncomingRoomKeyRequest): Boolean { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 3320ec089a..5410ab07df 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -39,6 +39,7 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP import org.matrix.android.sdk.internal.crypto.MegolmSessionData +import org.matrix.android.sdk.internal.crypto.MegolmSessionImportManager import org.matrix.android.sdk.internal.crypto.OlmMachineProvider import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust @@ -74,6 +75,7 @@ internal class RustKeyBackupService @Inject constructor( olmMachineProvider: OlmMachineProvider, private val sender: RequestSender, private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val megolmSessionImportManager: MegolmSessionImportManager, private val cryptoCoroutineScope: CoroutineScope, ) : KeysBackupService { companion object { @@ -545,7 +547,9 @@ internal class RustKeyBackupService @Inject constructor( null } - val result = olmMachine.importDecryptedKeys(sessionsData, progressListener) + val result = olmMachine.importDecryptedKeys(sessionsData, progressListener).also { + megolmSessionImportManager.dispatchKeyImportResults(it) + } // Do not back up the key if it comes from a backup recovery if (backUp) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/ImportRoomKeysResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/ImportRoomKeysResult.kt index e9d2a1bcd8..d04936bdde 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/ImportRoomKeysResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/ImportRoomKeysResult.kt @@ -16,5 +16,21 @@ package org.matrix.android.sdk.internal.crypto.model +import uniffi.olm.KeysImportResult + data class ImportRoomKeysResult(val totalNumberOfKeys: Int, - val successfullyNumberOfImportedKeys: Int) + val successfullyNumberOfImportedKeys: Int, + /**It's a map from room id to a map of the sender key to a list of session*/ + val importedSessionInfo: Map>> +) { + + companion object { + fun fromOlm(result: KeysImportResult): ImportRoomKeysResult { + return ImportRoomKeysResult( + result.total.toInt(), + result.imported.toInt(), + result.keys + ) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt index 75d02dfd98..f93f72d312 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt @@ -40,7 +40,7 @@ internal class TimelineEventDecryptor @Inject constructor( ) { private val newSessionListener = object : NewSessionListener { - override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) { + override fun onNewSession(roomId: String?, sessionId: String) { synchronized(unknownSessionsFailure) { unknownSessionsFailure[sessionId] ?.toList() From 8bb2f0584e34045fd312e0823ee17ad9d26f9a07 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 29 Nov 2021 14:41:52 +0100 Subject: [PATCH 200/252] ktlint clean --- .../sdk/internal/crypto/crosssigning/XSigningTest.kt | 2 -- .../sdk/internal/crypto/gossiping/KeyShareTests.kt | 4 ---- .../crypto/keysbackup/KeysBackupScenarioData.kt | 1 - .../sdk/internal/crypto/keysbackup/KeysBackupTest.kt | 11 +---------- .../crypto/keysbackup/KeysBackupTestHelper.kt | 3 --- 5 files changed, 1 insertion(+), 20 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt index 65b1e38f0b..d48317b56b 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt @@ -36,8 +36,6 @@ import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import kotlin.coroutines.Continuation import kotlin.coroutines.resume diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 6c118dfc00..2474ba5c36 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -50,10 +50,6 @@ import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.internal.crypto.GossipingRequestState import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestState import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import java.util.concurrent.CountDownLatch import kotlin.coroutines.Continuation diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt index c5b9da235c..b18c920f6a 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt @@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestData -import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 /** * Data class to store result of [KeysBackupTestHelper.createKeysBackupScenarioWithPassword] diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index f6e1348fb5..8d2941922c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -29,23 +29,16 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.TestConstants -import org.matrix.android.sdk.common.TestMatrixCallback import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import java.util.ArrayList -import java.util.Collections import java.util.concurrent.CountDownLatch @RunWith(AndroidJUnit4::class) @@ -452,7 +445,7 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = mTestHelper.runBlockingTest{ + val keysVersionResult = mTestHelper.runBlockingTest { testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion() } @@ -501,7 +494,6 @@ class KeysBackupTest : InstrumentedTest { ) fail("Should have failed to trust") } catch (failure: Throwable) { - } } @@ -608,7 +600,6 @@ class KeysBackupTest : InstrumentedTest { ) fail("Should have fail to trust") } catch (failure: Throwable) { - } } mTestHelper.await(latch) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt index 7aca9c4274..d2742bbec3 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import kotlinx.coroutines.delay import org.junit.Assert -import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState @@ -28,8 +27,6 @@ import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.assertDictEquals import org.matrix.android.sdk.common.assertListEquals import org.matrix.android.sdk.internal.crypto.MegolmSessionData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import java.util.concurrent.CountDownLatch class KeysBackupTestHelper( From 71cc38fa78e3c7f31ffa782998a8102537ba9b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 30 Nov 2021 16:11:16 +0100 Subject: [PATCH 201/252] rust: Bump the rust-sdk version --- rust-sdk/Cargo.toml | 6 +-- rust-sdk/src/machine.rs | 94 +++++++++++++++++++++------------------ rust-sdk/src/responses.rs | 4 +- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index a8ceb9cd7f..203ceec70f 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -29,11 +29,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "a628e84b63f6b761af383655e00f544ef6a09082" +rev = "8494f105837af824f4637c05e9e01b0854d7109b" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "a628e84b63f6b761af383655e00f544ef6a09082" +rev = "8494f105837af824f4637c05e9e01b0854d7109b" features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] @@ -43,7 +43,7 @@ features = ["rt-multi-thread"] [dependencies.ruma] git = "https://github.com/ruma/ruma" -rev = "ac6ecc3e5" +rev = "6c4892664" features = ["client-api-c"] [build-dependencies] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 1ffc30c764..0c0947fe9e 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -2,6 +2,7 @@ use std::{ collections::{BTreeMap, HashMap}, convert::{TryFrom, TryInto}, io::Cursor, + ops::Deref, }; use base64::{decode_config, encode, STANDARD_NO_PAD}; @@ -77,7 +78,7 @@ impl OlmMachine { /// /// * `path` - The path where the state of the machine should be persisted. pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; let device_id = device_id.into(); let runtime = Runtime::new().expect("Couldn't create a tokio runtime"); @@ -106,7 +107,7 @@ impl OlmMachine { /// Get a cross signing user identity for the given user ID. pub fn get_identity(&self, user_id: &str) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; Ok( if let Some(identity) = self.runtime.block_on(self.inner.get_identity(&user_id))? { @@ -119,7 +120,7 @@ impl OlmMachine { /// Check if a user identity is considered to be verified by us. pub fn is_identity_verified(&self, user_id: &str) -> Result { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; Ok( if let Some(identity) = self.runtime.block_on(self.inner.get_identity(&user_id))? { @@ -145,7 +146,7 @@ impl OlmMachine { /// Returns a request that needs to be sent out for the user identity to be /// marked as verified. pub fn verify_identity(&self, user_id: &str) -> Result { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; let user_identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; @@ -172,7 +173,7 @@ impl OlmMachine { user_id: &str, device_id: &str, ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; Ok(self .runtime @@ -198,7 +199,7 @@ impl OlmMachine { user_id: &str, device_id: &str, ) -> Result { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; let device = self .runtime .block_on(self.inner.get_device(&user_id, device_id.into()))?; @@ -219,7 +220,7 @@ impl OlmMachine { user_id: &str, device_id: &str, ) -> Result<(), CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; let device = self .runtime @@ -239,7 +240,7 @@ impl OlmMachine { /// /// * `user_id` - The id of the device owner. pub fn get_user_devices(&self, user_id: &str) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; Ok(self .runtime @@ -378,13 +379,15 @@ impl OlmMachine { /// /// `users` - The users that should be queued up for a key query. pub fn update_tracked_users(&self, users: Vec) { - let users: Vec = users + let users: Vec> = users .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) + .filter_map(|u| Box::::try_from(u).ok()) .collect(); - self.runtime - .block_on(self.inner.update_tracked_users(users.iter())); + self.runtime.block_on( + self.inner + .update_tracked_users(users.iter().map(Deref::deref)), + ); } /// Check if the given user is considered to be tracked. @@ -392,7 +395,7 @@ impl OlmMachine { /// A user can be marked for tracking using the /// [`OlmMachine::update_tracked_users()`] method. pub fn is_user_tracked(&self, user_id: &str) -> Result { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; Ok(self.inner.tracked_users().contains(&user_id)) } @@ -414,14 +417,17 @@ impl OlmMachine { &self, users: Vec, ) -> Result, CryptoStoreError> { - let users: Vec = users + let users: Vec> = users .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) + .filter_map(|u| Box::::try_from(u).ok()) .collect(); Ok(self .runtime - .block_on(self.inner.get_missing_sessions(users.iter()))? + .block_on( + self.inner + .get_missing_sessions(users.iter().map(Deref::deref)), + )? .map(|r| r.into())) } @@ -447,15 +453,15 @@ impl OlmMachine { room_id: &str, users: Vec, ) -> Result, CryptoStoreError> { - let users: Vec = users + let users: Vec> = users .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) + .filter_map(|u| Box::::try_from(u).ok()) .collect(); - let room_id = RoomId::try_from(room_id)?; + let room_id = Box::::try_from(room_id)?; let requests = self.runtime.block_on(self.inner.share_group_session( &room_id, - users.iter(), + users.iter().map(Deref::deref), EncryptionSettings::default(), ))?; @@ -501,7 +507,7 @@ impl OlmMachine { event_type: &str, content: &str, ) -> Result { - let room_id = RoomId::try_from(room_id)?; + let room_id = Box::::try_from(room_id)?; let content: Box = serde_json::from_str(content)?; let content = AnyMessageEventContent::from_parts(event_type, &content)?; @@ -537,7 +543,7 @@ impl OlmMachine { } let event: SyncMessageEvent = serde_json::from_str(event)?; - let room_id = RoomId::try_from(room_id)?; + let room_id = Box::::try_from(room_id)?; let decrypted = self .runtime @@ -580,7 +586,7 @@ impl OlmMachine { room_id: &str, ) -> Result { let event: SyncMessageEvent = serde_json::from_str(event)?; - let room_id = RoomId::try_from(room_id)?; + let room_id = Box::::try_from(room_id)?; let (cancel, request) = self .runtime @@ -698,7 +704,7 @@ impl OlmMachine { /// Discard the currently active room key for the given room if there is /// one. pub fn discard_room_key(&self, room_id: &str) -> Result<(), CryptoStoreError> { - let room_id = RoomId::try_from(room_id)?; + let room_id = Box::::try_from(room_id)?; self.runtime .block_on(self.inner.invalidate_group_session(&room_id))?; @@ -713,7 +719,7 @@ impl OlmMachine { /// * `user_id` - The ID of the user for which we would like to fetch the /// verification requests. pub fn get_verification_requests(&self, user_id: &str) -> Vec { - let user_id = if let Ok(user_id) = UserId::try_from(user_id) { + let user_id = if let Ok(user_id) = Box::::try_from(user_id) { user_id } else { return vec![]; @@ -740,7 +746,7 @@ impl OlmMachine { user_id: &str, flow_id: &str, ) -> Option { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::try_from(user_id).ok()?; self.inner .get_verification_request(&user_id, flow_id) @@ -767,7 +773,7 @@ impl OlmMachine { flow_id: &str, methods: Vec, ) -> Option { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::try_from(user_id).ok()?; let methods = methods.into_iter().map(VerificationMethod::from).collect(); if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { @@ -791,7 +797,7 @@ impl OlmMachine { user_id: &str, methods: Vec, ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; @@ -834,9 +840,9 @@ impl OlmMachine { event_id: &str, methods: Vec, ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; - let event_id = EventId::try_from(event_id)?; - let room_id = RoomId::try_from(room_id)?; + let user_id = Box::::try_from(user_id)?; + let event_id = Box::::try_from(event_id)?; + let room_id = Box::::try_from(room_id)?; let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; @@ -872,7 +878,7 @@ impl OlmMachine { device_id: &str, methods: Vec, ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; let methods = methods.into_iter().map(VerificationMethod::from).collect(); @@ -933,7 +939,8 @@ impl OlmMachine { /// /// * `flow_id` - The ID that uniquely identifies the verification flow. pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::try_from(user_id).ok()?; + self.inner .get_verification(&user_id, flow_id) .map(|v| match v { @@ -963,7 +970,7 @@ impl OlmMachine { flow_id: &str, cancel_code: &str, ) -> Option { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::try_from(user_id).ok()?; if let Some(request) = self.inner.get_verification_request(&user_id, flow_id) { request.cancel().map(|r| r.into()) @@ -998,7 +1005,7 @@ impl OlmMachine { user_id: &str, flow_id: &str, ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; Ok( if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { @@ -1041,7 +1048,7 @@ impl OlmMachine { user_id: &str, flow_id: &str, ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { Ok(self @@ -1072,7 +1079,7 @@ impl OlmMachine { /// /// [start_qr_verification()]: #method.start_qr_verification pub fn generate_qr_code(&self, user_id: &str, flow_id: &str) -> Option { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::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(encode).ok())) @@ -1095,7 +1102,7 @@ impl OlmMachine { /// * `data` - The data that was extracted from the scanned QR code as an /// base64 encoded string, without padding. pub fn scan_qr_code(&self, user_id: &str, flow_id: &str, data: &str) -> Option { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::try_from(user_id).ok()?; let data = decode_config(data, STANDARD_NO_PAD).ok()?; let data = QrVerificationData::from_bytes(data).ok()?; @@ -1134,7 +1141,7 @@ impl OlmMachine { user_id: &str, flow_id: &str, ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; Ok( if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { @@ -1169,7 +1176,7 @@ impl OlmMachine { user_id: &str, device_id: &str, ) -> Result, CryptoStoreError> { - let user_id = UserId::try_from(user_id)?; + let user_id = Box::::try_from(user_id)?; Ok( if let Some(device) = self @@ -1201,7 +1208,8 @@ impl OlmMachine { user_id: &str, flow_id: &str, ) -> Option { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::try_from(user_id).ok()?; + self.inner .get_verification(&user_id, flow_id) .and_then(|s| s.sas_v1()) @@ -1222,7 +1230,7 @@ impl OlmMachine { /// /// * `flow_id` - The ID that uniquely identifies the verification flow. pub fn get_emoji_index(&self, user_id: &str, flow_id: &str) -> Option> { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::try_from(user_id).ok()?; self.inner .get_verification(&user_id, flow_id) @@ -1247,7 +1255,7 @@ impl OlmMachine { /// /// * `flow_id` - The ID that uniquely identifies the verification flow. pub fn get_decimals(&self, user_id: &str, flow_id: &str) -> Option> { - let user_id = UserId::try_from(user_id).ok()?; + let user_id = Box::::try_from(user_id).ok()?; self.inner .get_verification(&user_id, flow_id) diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs index 23ea870ec7..9901c7114f 100644 --- a/rust-sdk/src/responses.rs +++ b/rust-sdk/src/responses.rs @@ -283,12 +283,12 @@ impl From for RumaDeviceLists { changed: d .changed .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) + .filter_map(|u| Box::::try_from(u).ok()) .collect(), left: d .left .into_iter() - .filter_map(|u| UserId::try_from(u).ok()) + .filter_map(|u| Box::::try_from(u).ok()) .collect(), }) } From 2e71f38f00b245b2c5ff7cf4edf28e291cfffe4f Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 30 Nov 2021 16:52:11 +0100 Subject: [PATCH 202/252] quick log improvents --- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 7 ++++++- .../android/sdk/internal/crypto/tasks/SendEventTask.kt | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index dffc100e7a..d970517c9a 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -90,6 +90,7 @@ import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import kotlin.math.max +import kotlin.system.measureTimeMillis /** * A `CryptoService` class instance manages the end-to-end crypto for a session. @@ -542,7 +543,11 @@ internal class DefaultCryptoService @Inject constructor( val t0 = System.currentTimeMillis() Timber.tag(loggerTag.value).v("encryptEventContent() starts") runCatching { - preshareRoomKey(roomId, userIds) + measureTimeMillis { + preshareRoomKey(roomId, userIds) + }.also { + Timber.d("Shared room key in room $roomId took $it ms") + } val content = encrypt(roomId, eventType, eventContent) Timber.tag(loggerTag.value).v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms") MXEncryptEventContentResult(content, EventType.ENCRYPTED) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt index bdfe818c62..6620c1c6cc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt @@ -60,6 +60,7 @@ internal class DefaultSendEventTask @Inject constructor( eventType = event.type ?: "" ) } + Timber.d("Event sent to ${event.roomId} with event id ${response.eventId}") localEchoRepository.updateSendState(localId, params.event.roomId, SendState.SENT) return response.eventId.also { Timber.d("Event: $it just sent in ${params.event.roomId}") From dc9f6b866b11bf33729431e24ae55093d0989199 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 30 Nov 2021 17:50:41 +0100 Subject: [PATCH 203/252] Remove unneeded lax check --- .../sdk/internal/crypto/MegolmSessionData.kt | 13 +------------ .../crypto/keysbackup/RustKeyBackupService.kt | 7 ------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt index d3100ede7d..caff2d76f1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt @@ -70,15 +70,4 @@ data class MegolmSessionData( */ @Json(name = "forwarding_curve25519_key_chain") val forwardingCurve25519KeyChain: List? = null -) { - - fun isValid(): Boolean { - return roomId != null && - forwardingCurve25519KeyChain != null && - algorithm != null && - senderKey != null && - senderClaimedKeys != null && - sessionId != null && - sessionKey != null - } -} +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 5410ab07df..071e1995c2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -507,13 +507,6 @@ internal class RustKeyBackupService @Inject constructor( async { slice.mapNotNull { pair -> decryptKeyBackupData(pair.second.value, pair.second.key, pair.first, recoveryKey) - ?.takeIf { sessionData -> - sessionData.isValid().also { - if (!it) { - Timber.w("restoreKeysWithRecoveryKey: malformed sessionData $sessionData") - } - } - } } } } From 59b2cfa52c52f770b188e6bf4bdfcf9e31052c04 Mon Sep 17 00:00:00 2001 From: Valere Date: Tue, 30 Nov 2021 18:00:26 +0100 Subject: [PATCH 204/252] Removed useless code --- .../java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 2d09d000a9..16ca58a8fa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -574,9 +574,7 @@ internal class OlmMachine( val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { trustLevel = DeviceTrustLevel(verified, verified) } - val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel().apply { - trustLevel = DeviceTrustLevel(verified, verified) - } + val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel() OwnUserIdentity( identity.userId, From 14f974f07f0fac1f421b0c1b2d843bb1b3a3b3a0 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 1 Dec 2021 09:12:57 +0100 Subject: [PATCH 205/252] Delete old key backup code --- .../keysbackup/DefaultKeysBackupService.kt | 1438 ----------------- 1 file changed, 1438 deletions(-) delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt deleted file mode 100644 index c70a01f54e..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ /dev/null @@ -1,1438 +0,0 @@ -///* -// * Copyright 2020 The Matrix.org Foundation C.I.C. -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ -// -//package org.matrix.android.sdk.internal.crypto.keysbackup -// -//import android.os.Handler -//import android.os.Looper -//import androidx.annotation.UiThread -//import androidx.annotation.VisibleForTesting -//import androidx.annotation.WorkerThread -//import kotlinx.coroutines.CoroutineScope -//import kotlinx.coroutines.delay -//import kotlinx.coroutines.launch -//import kotlinx.coroutines.withContext -//import org.matrix.android.sdk.api.MatrixCallback -//import org.matrix.android.sdk.api.MatrixCoroutineDispatchers -//import org.matrix.android.sdk.api.auth.data.Credentials -//import org.matrix.android.sdk.api.failure.Failure -//import org.matrix.android.sdk.api.failure.MatrixError -//import org.matrix.android.sdk.api.listeners.ProgressListener -//import org.matrix.android.sdk.api.listeners.StepProgressListener -//import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService -//import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState -//import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener -//import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP -//import org.matrix.android.sdk.internal.crypto.MXOlmDevice -//import org.matrix.android.sdk.internal.crypto.MegolmSessionData -//import org.matrix.android.sdk.internal.crypto.ObjectSigner -//import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter -//import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrustSignature -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData -//import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteBackupTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteRoomSessionDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteRoomSessionsDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.DeleteSessionsDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupLastVersionTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetKeysBackupVersionTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetRoomSessionsDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.GetSessionsDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionsDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask -//import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey -//import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey -//import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -//import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 -//import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -//import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo -//import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity -//import org.matrix.android.sdk.internal.di.MoshiProvider -//import org.matrix.android.sdk.internal.di.UserId -//import org.matrix.android.sdk.internal.extensions.foldToCallback -//import org.matrix.android.sdk.internal.session.SessionScope -//import org.matrix.android.sdk.internal.task.Task -//import org.matrix.android.sdk.internal.task.TaskExecutor -//import org.matrix.android.sdk.internal.task.TaskThread -//import org.matrix.android.sdk.internal.task.configureWith -//import org.matrix.android.sdk.internal.util.JsonCanonicalizer -//import org.matrix.android.sdk.internal.util.awaitCallback -//import org.matrix.olm.OlmException -//import org.matrix.olm.OlmPkDecryption -//import org.matrix.olm.OlmPkEncryption -//import org.matrix.olm.OlmPkMessage -//import timber.log.Timber -//import java.security.InvalidParameterException -//import javax.inject.Inject -//import kotlin.random.Random -// -///** -// * A DefaultKeysBackupService class instance manage incremental backup of e2e keys (megolm keys) -// * to the user's homeserver. -// */ -//@SessionScope -//@Deprecated("use rust") -//internal class DefaultKeysBackupService @Inject constructor( -// @UserId private val userId: String, -// private val credentials: Credentials, -// private val cryptoStore: IMXCryptoStore, -// private val olmDevice: MXOlmDevice, -// private val objectSigner: ObjectSigner, -// // Actions -// private val megolmSessionDataImporter: MegolmSessionDataImporter, -// // Tasks -// private val createKeysBackupVersionTask: CreateKeysBackupVersionTask, -// private val deleteBackupTask: DeleteBackupTask, -// private val deleteRoomSessionDataTask: DeleteRoomSessionDataTask, -// private val deleteRoomSessionsDataTask: DeleteRoomSessionsDataTask, -// private val deleteSessionDataTask: DeleteSessionsDataTask, -// private val getKeysBackupLastVersionTask: GetKeysBackupLastVersionTask, -// private val getKeysBackupVersionTask: GetKeysBackupVersionTask, -// private val getRoomSessionDataTask: GetRoomSessionDataTask, -// private val getRoomSessionsDataTask: GetRoomSessionsDataTask, -// private val getSessionsDataTask: GetSessionsDataTask, -// private val storeRoomSessionDataTask: StoreRoomSessionDataTask, -// private val storeSessionsDataTask: StoreRoomSessionsDataTask, -// private val storeSessionDataTask: StoreSessionsDataTask, -// private val updateKeysBackupVersionTask: UpdateKeysBackupVersionTask, -// // Task executor -// private val taskExecutor: TaskExecutor, -// private val coroutineDispatchers: MatrixCoroutineDispatchers, -// private val cryptoCoroutineScope: CoroutineScope -//) : KeysBackupService { -// -// private val uiHandler = Handler(Looper.getMainLooper()) -// -// private val keysBackupStateManager = KeysBackupStateManager(uiHandler) -// -// // The backup version -// override var keysBackupVersion: KeysVersionResult? = null -// private set -// -// // The backup key being used. -// private var backupOlmPkEncryption: OlmPkEncryption? = null -// -// private var backupAllGroupSessionsCallback: MatrixCallback? = null -// -// private var keysBackupStateListener: KeysBackupStateListener? = null -// -// override val isEnabled: Boolean -// get() = keysBackupStateManager.isEnabled -// -// override val isStucked: Boolean -// get() = keysBackupStateManager.isStucked -// -// override val state: KeysBackupState -// get() = keysBackupStateManager.state -// -// override val currentBackupVersion: String? -// get() = keysBackupVersion?.version -// -// override fun addListener(listener: KeysBackupStateListener) { -// keysBackupStateManager.addListener(listener) -// } -// -// override fun removeListener(listener: KeysBackupStateListener) { -// keysBackupStateManager.removeListener(listener) -// } -// -// override fun prepareKeysBackupVersion(password: String?, -// progressListener: ProgressListener?, -// callback: MatrixCallback) { -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// runCatching { -// withContext(coroutineDispatchers.crypto) { -// val olmPkDecryption = OlmPkDecryption() -// val signalableMegolmBackupAuthData = if (password != null) { -// // Generate a private key from the password -// val backgroundProgressListener = if (progressListener == null) { -// null -// } else { -// object : ProgressListener { -// override fun onProgress(progress: Int, total: Int) { -// uiHandler.post { -// try { -// progressListener.onProgress(progress, total) -// } catch (e: Exception) { -// Timber.e(e, "prepareKeysBackupVersion: onProgress failure") -// } -// } -// } -// } -// } -// -// val generatePrivateKeyResult = generatePrivateKeyWithPassword(password, backgroundProgressListener) -// SignalableMegolmBackupAuthData( -// publicKey = olmPkDecryption.setPrivateKey(generatePrivateKeyResult.privateKey), -// privateKeySalt = generatePrivateKeyResult.salt, -// privateKeyIterations = generatePrivateKeyResult.iterations -// ) -// } else { -// val publicKey = olmPkDecryption.generateKey() -// -// SignalableMegolmBackupAuthData( -// publicKey = publicKey -// ) -// } -// -// val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableMegolmBackupAuthData.signalableJSONDictionary()) -// -// val signedMegolmBackupAuthData = MegolmBackupAuthData( -// publicKey = signalableMegolmBackupAuthData.publicKey, -// privateKeySalt = signalableMegolmBackupAuthData.privateKeySalt, -// privateKeyIterations = signalableMegolmBackupAuthData.privateKeyIterations, -// signatures = objectSigner.signObject(canonicalJson) -// ) -// -// MegolmBackupCreationInfo( -// algorithm = MXCRYPTO_ALGORITHM_MEGOLM_BACKUP, -// authData = signedMegolmBackupAuthData, -// recoveryKey = computeRecoveryKey(olmPkDecryption.privateKey()) -// ) -// } -// }.foldToCallback(callback) -// } -// } -// -// override fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, -// callback: MatrixCallback) { -// @Suppress("UNCHECKED_CAST") -// val createKeysBackupVersionBody = CreateKeysBackupVersionBody( -// algorithm = keysBackupCreationInfo.algorithm, -// authData = keysBackupCreationInfo.authData.toJsonDict() -// ) -// -// keysBackupStateManager.state = KeysBackupState.Enabling -// -// createKeysBackupVersionTask -// .configureWith(createKeysBackupVersionBody) { -// this.callback = object : MatrixCallback { -// override fun onSuccess(data: KeysVersion) { -// // Reset backup markers. -// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// // move tx out of UI thread -// cryptoStore.resetBackupMarkers() -// } -// -// val keyBackupVersion = KeysVersionResult( -// algorithm = createKeysBackupVersionBody.algorithm, -// authData = createKeysBackupVersionBody.authData, -// version = data.version, -// // We can consider that the server does not have keys yet -// count = 0, -// hash = "" -// ) -// -// enableKeysBackup(keyBackupVersion) -// -// callback.onSuccess(data) -// } -// -// override fun onFailure(failure: Throwable) { -// keysBackupStateManager.state = KeysBackupState.Disabled -// callback.onFailure(failure) -// } -// } -// } -// .executeBy(taskExecutor) -// } -// -// override fun deleteBackup(version: String, callback: MatrixCallback?) { -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// withContext(coroutineDispatchers.crypto) { -// // If we're currently backing up to this backup... stop. -// // (We start using it automatically in createKeysBackupVersion so this is symmetrical). -// if (keysBackupVersion != null && version == keysBackupVersion?.version) { -// resetKeysBackupData() -// keysBackupVersion = null -// keysBackupStateManager.state = KeysBackupState.Unknown -// } -// -// deleteBackupTask -// .configureWith(DeleteBackupTask.Params(version)) { -// this.callback = object : MatrixCallback { -// private fun eventuallyRestartBackup() { -// // Do not stay in KeysBackupState.Unknown but check what is available on the homeserver -// if (state == KeysBackupState.Unknown) { -// checkAndStartKeysBackup() -// } -// } -// -// override fun onSuccess(data: Unit) { -// eventuallyRestartBackup() -// -// uiHandler.post { callback?.onSuccess(Unit) } -// } -// -// override fun onFailure(failure: Throwable) { -// eventuallyRestartBackup() -// -// uiHandler.post { callback?.onFailure(failure) } -// } -// } -// } -// .executeBy(taskExecutor) -// } -// } -// } -// -// override fun canRestoreKeys(): Boolean { -// // Server contains more keys than locally -// val totalNumberOfKeysLocally = getTotalNumbersOfKeys() -// -// val keysBackupData = cryptoStore.getKeysBackupData() -// -// val totalNumberOfKeysServer = keysBackupData?.backupLastServerNumberOfKeys ?: -1 -// // Not used for the moment -// // val hashServer = keysBackupData?.backupLastServerHash -// -// return when { -// totalNumberOfKeysLocally < totalNumberOfKeysServer -> { -// // Server contains more keys than this device -// true -// } -// totalNumberOfKeysLocally == totalNumberOfKeysServer -> { -// // Same number, compare hash? -// // TODO We have not found any algorithm to determine if a restore is recommended here. Return false for the moment -// false -// } -// else -> false -// } -// } -// -// override fun getTotalNumbersOfKeys(): Int { -// return cryptoStore.inboundGroupSessionsCount(false) -// } -// -// override fun getTotalNumbersOfBackedUpKeys(): Int { -// return cryptoStore.inboundGroupSessionsCount(true) -// } -// -// override fun backupAllGroupSessions(progressListener: ProgressListener?, -// callback: MatrixCallback?) { -// // Get a status right now -// getBackupProgress(object : ProgressListener { -// override fun onProgress(progress: Int, total: Int) { -// // Reset previous listeners if any -// resetBackupAllGroupSessionsListeners() -// Timber.v("backupAllGroupSessions: backupProgress: $progress/$total") -// try { -// progressListener?.onProgress(progress, total) -// } catch (e: Exception) { -// Timber.e(e, "backupAllGroupSessions: onProgress failure") -// } -// -// if (progress == total) { -// Timber.v("backupAllGroupSessions: complete") -// callback?.onSuccess(Unit) -// return -// } -// -// backupAllGroupSessionsCallback = callback -// -// // Listen to `state` change to determine when to call onBackupProgress and onComplete -// keysBackupStateListener = object : KeysBackupStateListener { -// override fun onStateChange(newState: KeysBackupState) { -// getBackupProgress(object : ProgressListener { -// override fun onProgress(progress: Int, total: Int) { -// try { -// progressListener?.onProgress(progress, total) -// } catch (e: Exception) { -// Timber.e(e, "backupAllGroupSessions: onProgress failure 2") -// } -// -// // If backup is finished, notify the main listener -// if (state === KeysBackupState.ReadyToBackUp) { -// backupAllGroupSessionsCallback?.onSuccess(Unit) -// resetBackupAllGroupSessionsListeners() -// } -// } -// }) -// } -// }.also { keysBackupStateManager.addListener(it) } -// -// backupKeys() -// } -// }) -// } -// -// override fun getKeysBackupTrust(keysBackupVersion: KeysVersionResult, -// callback: MatrixCallback) { -// // TODO Validate with François that this is correct -// object : Task { -// override suspend fun execute(params: KeysVersionResult): KeysBackupVersionTrust { -// return getKeysBackupTrustBg(params) -// } -// } -// .configureWith(keysBackupVersion) { -// this.callback = callback -// this.executionThread = TaskThread.COMPUTATION -// } -// .executeBy(taskExecutor) -// } -// -// /** -// * Check trust on a key backup version. -// * This has to be called on background thread. -// * -// * @param keysBackupVersion the backup version to check. -// * @return a KeysBackupVersionTrust object -// */ -// @WorkerThread -// private fun getKeysBackupTrustBg(keysBackupVersion: KeysVersionResult): KeysBackupVersionTrust { -// val keysBackupVersionTrust = KeysBackupVersionTrust() -// val authData = keysBackupVersion.getAuthDataAsMegolmBackupAuthData() -// -// if (authData == null || authData.publicKey.isEmpty() || authData.signatures.isNullOrEmpty()) { -// Timber.v("getKeysBackupTrust: Key backup is absent or missing required data") -// return keysBackupVersionTrust -// } -// -// val mySigs = authData.signatures[userId] -// if (mySigs.isNullOrEmpty()) { -// Timber.v("getKeysBackupTrust: Ignoring key backup because it lacks any signatures from this user") -// return keysBackupVersionTrust -// } -// -// for ((keyId, mySignature) in mySigs) { -// // XXX: is this how we're supposed to get the device id? -// var deviceId: String? = null -// val components = keyId.split(":") -// if (components.size == 2) { -// deviceId = components[1] -// } -// -// if (deviceId != null) { -// val device = cryptoStore.getUserDevice(userId, deviceId) -// var isSignatureValid = false -// -// if (device == null) { -// Timber.v("getKeysBackupTrust: Signature from unknown device $deviceId") -// } else { -// val fingerprint = device.fingerprint() -// if (fingerprint != null) { -// try { -// olmDevice.verifySignature(fingerprint, authData.signalableJSONDictionary(), mySignature) -// isSignatureValid = true -// } catch (e: OlmException) { -// Timber.w(e, "getKeysBackupTrust: Bad signature from device ${device.deviceId}") -// } -// } -// -// if (isSignatureValid && device.isVerified) { -// keysBackupVersionTrust.usable = true -// } -// } -// -// val signature = KeysBackupVersionTrustSignature() -// signature.device = device -// signature.valid = isSignatureValid -// signature.deviceId = deviceId -// keysBackupVersionTrust.signatures.add(signature) -// } -// } -// -// return keysBackupVersionTrust -// } -// -// override fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, -// trust: Boolean, -// callback: MatrixCallback) { -// Timber.v("trustKeyBackupVersion: $trust, version ${keysBackupVersion.version}") -// -// // Get auth data to update it -// val authData = getMegolmBackupAuthData(keysBackupVersion) -// -// if (authData == null) { -// Timber.w("trustKeyBackupVersion:trust: Key backup is missing required data") -// -// callback.onFailure(IllegalArgumentException("Missing element")) -// } else { -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// val updateKeysBackupVersionBody = withContext(coroutineDispatchers.crypto) { -// // Get current signatures, or create an empty set -// val myUserSignatures = authData.signatures?.get(userId).orEmpty().toMutableMap() -// -// if (trust) { -// // Add current device signature -// val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, authData.signalableJSONDictionary()) -// -// val deviceSignatures = objectSigner.signObject(canonicalJson) -// -// deviceSignatures[userId]?.forEach { entry -> -// myUserSignatures[entry.key] = entry.value -// } -// } else { -// // Remove current device signature -// myUserSignatures.remove("ed25519:${credentials.deviceId}") -// } -// -// // Create an updated version of KeysVersionResult -// val newMegolmBackupAuthData = authData.copy() -// -// val newSignatures = newMegolmBackupAuthData.signatures.orEmpty().toMutableMap() -// newSignatures[userId] = myUserSignatures -// -// val newMegolmBackupAuthDataWithNewSignature = newMegolmBackupAuthData.copy( -// signatures = newSignatures -// ) -// -// @Suppress("UNCHECKED_CAST") -// UpdateKeysBackupVersionBody( -// algorithm = keysBackupVersion.algorithm, -// authData = newMegolmBackupAuthDataWithNewSignature.toJsonDict(), -// version = keysBackupVersion.version) -// } -// -// // And send it to the homeserver -// updateKeysBackupVersionTask -// .configureWith(UpdateKeysBackupVersionTask.Params(keysBackupVersion.version, updateKeysBackupVersionBody)) { -// this.callback = object : MatrixCallback { -// override fun onSuccess(data: Unit) { -// // Relaunch the state machine on this updated backup version -// val newKeysBackupVersion = KeysVersionResult( -// algorithm = keysBackupVersion.algorithm, -// authData = updateKeysBackupVersionBody.authData, -// version = keysBackupVersion.version, -// hash = keysBackupVersion.hash, -// count = keysBackupVersion.count -// ) -// -// checkAndStartWithKeysBackupVersion(newKeysBackupVersion) -// -// callback.onSuccess(data) -// } -// -// override fun onFailure(failure: Throwable) { -// callback.onFailure(failure) -// } -// } -// } -// .executeBy(taskExecutor) -// } -// } -// } -// -// override fun trustKeysBackupVersionWithRecoveryKey(keysBackupVersion: KeysVersionResult, -// recoveryKey: String, -// callback: MatrixCallback) { -// Timber.v("trustKeysBackupVersionWithRecoveryKey: version ${keysBackupVersion.version}") -// -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// val isValid = withContext(coroutineDispatchers.crypto) { -// isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion) -// } -// -// if (!isValid) { -// Timber.w("trustKeyBackupVersionWithRecoveryKey: Invalid recovery key.") -// -// callback.onFailure(IllegalArgumentException("Invalid recovery key or password")) -// } else { -// trustKeysBackupVersion(keysBackupVersion, true, callback) -// } -// } -// } -// -// override fun trustKeysBackupVersionWithPassphrase(keysBackupVersion: KeysVersionResult, -// password: String, -// callback: MatrixCallback) { -// Timber.v("trustKeysBackupVersionWithPassphrase: version ${keysBackupVersion.version}") -// -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// val recoveryKey = withContext(coroutineDispatchers.crypto) { -// recoveryKeyFromPassword(password, keysBackupVersion, null) -// } -// -// if (recoveryKey == null) { -// Timber.w("trustKeysBackupVersionWithPassphrase: Key backup is missing required data") -// -// callback.onFailure(IllegalArgumentException("Missing element")) -// } else { -// // Check trust using the recovery key -// trustKeysBackupVersionWithRecoveryKey(keysBackupVersion, recoveryKey, callback) -// } -// } -// } -// -// override fun onSecretKeyGossip(secret: String) { -// Timber.i("## CrossSigning - onSecretKeyGossip") -// -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// try { -// val keysBackupVersion = getKeysBackupLastVersionTask.execute(Unit) -// val recoveryKey = computeRecoveryKey(secret.fromBase64()) -// if (isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)) { -// awaitCallback { -// trustKeysBackupVersion(keysBackupVersion, true, it) -// } -// val importResult = awaitCallback { -// restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, null, null, null, it) -// } -// withContext(coroutineDispatchers.crypto) { -// cryptoStore.saveBackupRecoveryKey(recoveryKey, keysBackupVersion.version) -// } -// Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") -// } else { -// Timber.e("onSecretKeyGossip: Recovery key is not valid ${keysBackupVersion.version}") -// } -// } catch (failure: Throwable) { -// Timber.e("onSecretKeyGossip: failed to trust key backup version ${keysBackupVersion?.version}") -// } -// } -// } -// -// /** -// * Get public key from a Recovery key -// * -// * @param recoveryKey the recovery key -// * @return the corresponding public key, from Olm -// */ -// @WorkerThread -// private fun pkPublicKeyFromRecoveryKey(recoveryKey: String): String? { -// // Extract the primary key -// val privateKey = extractCurveKeyFromRecoveryKey(recoveryKey) -// -// if (privateKey == null) { -// Timber.w("pkPublicKeyFromRecoveryKey: private key is null") -// -// return null -// } -// -// // Built the PK decryption with it -// val pkPublicKey: String -// -// try { -// val decryption = OlmPkDecryption() -// pkPublicKey = decryption.setPrivateKey(privateKey) -// } catch (e: OlmException) { -// return null -// } -// -// return pkPublicKey -// } -// -// private fun resetBackupAllGroupSessionsListeners() { -// backupAllGroupSessionsCallback = null -// -// keysBackupStateListener?.let { -// keysBackupStateManager.removeListener(it) -// } -// -// keysBackupStateListener = null -// } -// -// override fun getBackupProgress(progressListener: ProgressListener) { -// val backedUpKeys = cryptoStore.inboundGroupSessionsCount(true) -// val total = cryptoStore.inboundGroupSessionsCount(false) -// -// progressListener.onProgress(backedUpKeys, total) -// } -// -// override fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, -// recoveryKey: String, -// roomId: String?, -// sessionId: String?, -// stepProgressListener: StepProgressListener?, -// callback: MatrixCallback) { -// Timber.v("restoreKeysWithRecoveryKey: From backup version: ${keysVersionResult.version}") -// -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// runCatching { -// val decryption = withContext(coroutineDispatchers.crypto) { -// // Check if the recovery is valid before going any further -// if (!isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysVersionResult)) { -// Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key for this keys version") -// throw InvalidParameterException("Invalid recovery key") -// } -// -// // Get a PK decryption instance -// pkDecryptionFromRecoveryKey(recoveryKey) -// } -// if (decryption == null) { -// // This should not happen anymore -// Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key. Error") -// throw InvalidParameterException("Invalid recovery key") -// } -// -// stepProgressListener?.onStepProgress(StepProgressListener.Step.DownloadingKey) -// -// // Get backed up keys from the homeserver -// val data = getKeys(sessionId, roomId, keysVersionResult.version) -// -// withContext(coroutineDispatchers.computation) { -// val sessionsData = ArrayList() -// // Restore that data -// var sessionsFromHsCount = 0 -// for ((roomIdLoop, backupData) in data.roomIdToRoomKeysBackupData) { -// for ((sessionIdLoop, keyBackupData) in backupData.sessionIdToKeyBackupData) { -// sessionsFromHsCount++ -// -// val sessionData = decryptKeyBackupData(keyBackupData, sessionIdLoop, roomIdLoop, decryption) -// -// sessionData?.let { -// sessionsData.add(it) -// } -// } -// } -// Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" + -// " of $sessionsFromHsCount from the backup store on the homeserver") -// -// // Do not trigger a backup for them if they come from the backup version we are using -// val backUp = keysVersionResult.version != keysBackupVersion?.version -// if (backUp) { -// Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up" + -// " to backup version: ${keysBackupVersion?.version}") -// } -// -// // Import them into the crypto store -// val progressListener = if (stepProgressListener != null) { -// object : ProgressListener { -// override fun onProgress(progress: Int, total: Int) { -// // Note: no need to post to UI thread, importMegolmSessionsData() will do it -// stepProgressListener.onStepProgress(StepProgressListener.Step.ImportingKey(progress, total)) -// } -// } -// } else { -// null -// } -// -// val result = megolmSessionDataImporter.handle(sessionsData, !backUp, progressListener) -// -// // Do not back up the key if it comes from a backup recovery -// if (backUp) { -// maybeBackupKeys() -// } -// // Save for next time and for gossiping -// saveBackupRecoveryKey(recoveryKey, keysVersionResult.version) -// result -// } -// }.foldToCallback(callback) -// } -// } -// -// override fun restoreKeyBackupWithPassword(keysBackupVersion: KeysVersionResult, -// password: String, -// roomId: String?, -// sessionId: String?, -// stepProgressListener: StepProgressListener?, -// callback: MatrixCallback) { -// Timber.v("[MXKeyBackup] restoreKeyBackup with password: From backup version: ${keysBackupVersion.version}") -// -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// runCatching { -// val progressListener = if (stepProgressListener != null) { -// object : ProgressListener { -// override fun onProgress(progress: Int, total: Int) { -// uiHandler.post { -// stepProgressListener.onStepProgress(StepProgressListener.Step.ComputingKey(progress, total)) -// } -// } -// } -// } else { -// null -// } -// -// val recoveryKey = withContext(coroutineDispatchers.crypto) { -// recoveryKeyFromPassword(password, keysBackupVersion, progressListener) -// } -// if (recoveryKey == null) { -// Timber.v("backupKeys: Invalid configuration") -// throw IllegalStateException("Invalid configuration") -// } else { -// awaitCallback { -// restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, roomId, sessionId, stepProgressListener, it) -// } -// } -// }.foldToCallback(callback) -// } -// } -// -// /** -// * Same method as [RoomKeysRestClient.getRoomKey] except that it accepts nullable -// * parameters and always returns a KeysBackupData object through the Callback -// */ -// private suspend fun getKeys(sessionId: String?, -// roomId: String?, -// version: String): KeysBackupData { -// return if (roomId != null && sessionId != null) { -// // Get key for the room and for the session -// val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version)) -// // Convert to KeysBackupData -// KeysBackupData(mutableMapOf( -// roomId to RoomKeysBackupData(mutableMapOf( -// sessionId to data -// )) -// )) -// } else if (roomId != null) { -// // Get all keys for the room -// val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version)) -// // Convert to KeysBackupData -// KeysBackupData(mutableMapOf(roomId to data)) -// } else { -// // Get all keys -// getSessionsDataTask.execute(GetSessionsDataTask.Params(version)) -// } -// } -// -// @VisibleForTesting -// @WorkerThread -// fun pkDecryptionFromRecoveryKey(recoveryKey: String): OlmPkDecryption? { -// // Extract the primary key -// val privateKey = extractCurveKeyFromRecoveryKey(recoveryKey) -// -// // Built the PK decryption with it -// var decryption: OlmPkDecryption? = null -// if (privateKey != null) { -// try { -// decryption = OlmPkDecryption() -// decryption.setPrivateKey(privateKey) -// } catch (e: OlmException) { -// Timber.e(e, "OlmException") -// } -// } -// -// return decryption -// } -// -// /** -// * Do a backup if there are new keys, with a delay -// */ -// fun maybeBackupKeys() { -// when { -// isStucked -> { -// // If not already done, or in error case, check for a valid backup version on the homeserver. -// // If there is one, maybeBackupKeys will be called again. -// checkAndStartKeysBackup() -// } -// state == KeysBackupState.ReadyToBackUp -> { -// keysBackupStateManager.state = KeysBackupState.WillBackUp -// -// // Wait between 0 and 10 seconds, to avoid backup requests from -// // different clients hitting the server all at the same time when a -// // new key is sent -// val delayInMs = Random.nextLong(KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS) -// -// cryptoCoroutineScope.launch { -// delay(delayInMs) -// uiHandler.post { backupKeys() } -// } -// } -// else -> { -// Timber.v("maybeBackupKeys: Skip it because state: $state") -// } -// } -// } -// -// override fun getVersion(version: String, -// callback: MatrixCallback) { -// getKeysBackupVersionTask -// .configureWith(version) { -// this.callback = object : MatrixCallback { -// override fun onSuccess(data: KeysVersionResult) { -// callback.onSuccess(data) -// } -// -// override fun onFailure(failure: Throwable) { -// if (failure is Failure.ServerError && -// failure.error.code == MatrixError.M_NOT_FOUND) { -// // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup -// callback.onSuccess(null) -// } else { -// // Transmit the error -// callback.onFailure(failure) -// } -// } -// } -// } -// .executeBy(taskExecutor) -// } -// -// override fun getCurrentVersion(callback: MatrixCallback) { -// getKeysBackupLastVersionTask -// .configureWith { -// this.callback = object : MatrixCallback { -// override fun onSuccess(data: KeysVersionResult) { -// callback.onSuccess(data) -// } -// -// override fun onFailure(failure: Throwable) { -// if (failure is Failure.ServerError && -// failure.error.code == MatrixError.M_NOT_FOUND) { -// // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup -// callback.onSuccess(null) -// } else { -// // Transmit the error -// callback.onFailure(failure) -// } -// } -// } -// } -// .executeBy(taskExecutor) -// } -// -// override fun forceUsingLastVersion(callback: MatrixCallback) { -// getCurrentVersion(object : MatrixCallback { -// override fun onSuccess(data: KeysVersionResult?) { -// val localBackupVersion = keysBackupVersion?.version -// val serverBackupVersion = data?.version -// -// if (serverBackupVersion == null) { -// if (localBackupVersion == null) { -// // No backup on the server, and backup is not active -// callback.onSuccess(true) -// } else { -// // No backup on the server, and we are currently backing up, so stop backing up -// callback.onSuccess(false) -// resetKeysBackupData() -// keysBackupVersion = null -// keysBackupStateManager.state = KeysBackupState.Disabled -// } -// } else { -// if (localBackupVersion == null) { -// // backup on the server, and backup is not active -// callback.onSuccess(false) -// // Do a check -// checkAndStartWithKeysBackupVersion(data) -// } else { -// // Backup on the server, and we are currently backing up, compare version -// if (localBackupVersion == serverBackupVersion) { -// // We are already using the last version of the backup -// callback.onSuccess(true) -// } else { -// // We are not using the last version, so delete the current version we are using on the server -// callback.onSuccess(false) -// -// // This will automatically check for the last version then -// deleteBackup(localBackupVersion, null) -// } -// } -// } -// } -// -// override fun onFailure(failure: Throwable) { -// callback.onFailure(failure) -// } -// }) -// } -// -// override fun checkAndStartKeysBackup() { -// if (!isStucked) { -// // Try to start or restart the backup only if it is in unknown or bad state -// Timber.w("checkAndStartKeysBackup: invalid state: $state") -// -// return -// } -// -// keysBackupVersion = null -// keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver -// -// getCurrentVersion(object : MatrixCallback { -// override fun onSuccess(data: KeysVersionResult?) { -// checkAndStartWithKeysBackupVersion(data) -// } -// -// override fun onFailure(failure: Throwable) { -// Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version") -// keysBackupStateManager.state = KeysBackupState.Unknown -// } -// }) -// } -// -// private fun checkAndStartWithKeysBackupVersion(keyBackupVersion: KeysVersionResult?) { -// Timber.v("checkAndStartWithKeyBackupVersion: ${keyBackupVersion?.version}") -// -// keysBackupVersion = keyBackupVersion -// -// if (keyBackupVersion == null) { -// Timber.v("checkAndStartWithKeysBackupVersion: Found no key backup version on the homeserver") -// resetKeysBackupData() -// keysBackupStateManager.state = KeysBackupState.Disabled -// } else { -// getKeysBackupTrust(keyBackupVersion, object : MatrixCallback { -// override fun onSuccess(data: KeysBackupVersionTrust) { -// val versionInStore = cryptoStore.getKeyBackupVersion() -// -// if (data.usable) { -// Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: ${keyBackupVersion.version}") -// // Check the version we used at the previous app run -// if (versionInStore != null && versionInStore != keyBackupVersion.version) { -// Timber.v(" -> clean the previously used version $versionInStore") -// resetKeysBackupData() -// } -// -// Timber.v(" -> enabling key backups") -// enableKeysBackup(keyBackupVersion) -// } else { -// Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: ${keyBackupVersion.version}") -// if (versionInStore != null) { -// Timber.v(" -> disabling key backup") -// resetKeysBackupData() -// } -// -// keysBackupStateManager.state = KeysBackupState.NotTrusted -// } -// } -// -// override fun onFailure(failure: Throwable) { -// // Cannot happen -// } -// }) -// } -// } -// -///* ========================================================================================== -// * Private -// * ========================================================================================== */ -// -// /** -// * Extract MegolmBackupAuthData data from a backup version. -// * -// * @param keysBackupData the key backup data -// * -// * @return the authentication if found and valid, null in other case -// */ -// private fun getMegolmBackupAuthData(keysBackupData: KeysVersionResult): MegolmBackupAuthData? { -// return keysBackupData -// .takeIf { it.version.isNotEmpty() && it.algorithm == MXCRYPTO_ALGORITHM_MEGOLM_BACKUP } -// ?.getAuthDataAsMegolmBackupAuthData() -// ?.takeIf { it.publicKey.isNotEmpty() } -// } -// -// /** -// * Compute the recovery key from a password and key backup version. -// * -// * @param password the password. -// * @param keysBackupData the backup and its auth data. -// * -// * @return the recovery key if successful, null in other cases -// */ -// @WorkerThread -// private fun recoveryKeyFromPassword(password: String, keysBackupData: KeysVersionResult, progressListener: ProgressListener?): String? { -// val authData = getMegolmBackupAuthData(keysBackupData) -// -// if (authData == null) { -// Timber.w("recoveryKeyFromPassword: invalid parameter") -// return null -// } -// -// if (authData.privateKeySalt.isNullOrBlank() || -// authData.privateKeyIterations == null) { -// Timber.w("recoveryKeyFromPassword: Salt and/or iterations not found in key backup auth data") -// -// return null -// } -// -// // Extract the recovery key from the passphrase -// val data = retrievePrivateKeyWithPassword(password, authData.privateKeySalt, authData.privateKeyIterations, progressListener) -// -// return computeRecoveryKey(data) -// } -// -// /** -// * Check if a recovery key matches key backup authentication data. -// * -// * @param recoveryKey the recovery key to challenge. -// * @param keysBackupData the backup and its auth data. -// * -// * @return true if successful. -// */ -// @WorkerThread -// private fun isValidRecoveryKeyForKeysBackupVersion(recoveryKey: String, keysBackupData: KeysVersionResult): Boolean { -// // Build PK decryption instance with the recovery key -// val publicKey = pkPublicKeyFromRecoveryKey(recoveryKey) -// -// if (publicKey == null) { -// Timber.w("isValidRecoveryKeyForKeysBackupVersion: public key is null") -// -// return false -// } -// -// val authData = getMegolmBackupAuthData(keysBackupData) -// -// if (authData == null) { -// Timber.w("isValidRecoveryKeyForKeysBackupVersion: Key backup is missing required data") -// -// return false -// } -// -// // Compare both -// if (publicKey != authData.publicKey) { -// Timber.w("isValidRecoveryKeyForKeysBackupVersion: Public keys mismatch") -// -// return false -// } -// -// // Public keys match! -// return true -// } -// -// override fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback) { -// val safeKeysBackupVersion = keysBackupVersion ?: return Unit.also { callback.onSuccess(false) } -// -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// isValidRecoveryKeyForKeysBackupVersion(recoveryKey, safeKeysBackupVersion).let { -// callback.onSuccess(it) -// } -// } -// } -// -// /** -// * Enable backing up of keys. -// * This method will update the state and will start sending keys in nominal case -// * -// * @param keysVersionResult backup information object as returned by [getCurrentVersion]. -// */ -// private fun enableKeysBackup(keysVersionResult: KeysVersionResult) { -// val retrievedMegolmBackupAuthData = keysVersionResult.getAuthDataAsMegolmBackupAuthData() -// -// if (retrievedMegolmBackupAuthData != null) { -// keysBackupVersion = keysVersionResult -// cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { -// cryptoStore.setKeyBackupVersion(keysVersionResult.version) -// } -// -// onServerDataRetrieved(keysVersionResult.count, keysVersionResult.hash) -// -// try { -// backupOlmPkEncryption = OlmPkEncryption().apply { -// setRecipientKey(retrievedMegolmBackupAuthData.publicKey) -// } -// } catch (e: OlmException) { -// Timber.e(e, "OlmException") -// keysBackupStateManager.state = KeysBackupState.Disabled -// return -// } -// -// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp -// -// maybeBackupKeys() -// } else { -// Timber.e("Invalid authentication data") -// keysBackupStateManager.state = KeysBackupState.Disabled -// } -// } -// -// /** -// * Update the DB with data fetch from the server -// */ -// private fun onServerDataRetrieved(count: Int?, etag: String?) { -// cryptoStore.setKeysBackupData(KeysBackupDataEntity() -// .apply { -// backupLastServerNumberOfKeys = count -// backupLastServerHash = etag -// } -// ) -// } -// -// /** -// * Reset all local key backup data. -// * -// * Note: This method does not update the state -// */ -// private fun resetKeysBackupData() { -// resetBackupAllGroupSessionsListeners() -// -// cryptoStore.setKeyBackupVersion(null) -// cryptoStore.setKeysBackupData(null) -// backupOlmPkEncryption?.releaseEncryption() -// backupOlmPkEncryption = null -// -// // Reset backup markers -// cryptoStore.resetBackupMarkers() -// } -// -// /** -// * Send a chunk of keys to backup -// */ -// @UiThread -// private fun backupKeys() { -// Timber.v("backupKeys") -// -// // Sanity check, as this method can be called after a delay, the state may have change during the delay -// if (!isEnabled || backupOlmPkEncryption == null || keysBackupVersion == null) { -// Timber.v("backupKeys: Invalid configuration") -// backupAllGroupSessionsCallback?.onFailure(IllegalStateException("Invalid configuration")) -// resetBackupAllGroupSessionsListeners() -// -// return -// } -// -// if (state === KeysBackupState.BackingUp) { -// // Do nothing if we are already backing up -// Timber.v("backupKeys: Invalid state: $state") -// return -// } -// -// // Get a chunk of keys to backup -// val olmInboundGroupSessionWrappers = cryptoStore.inboundGroupSessionsToBackup(KEY_BACKUP_SEND_KEYS_MAX_COUNT) -// -// Timber.v("backupKeys: 1 - ${olmInboundGroupSessionWrappers.size} sessions to back up") -// -// if (olmInboundGroupSessionWrappers.isEmpty()) { -// // Backup is up to date -// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp -// -// backupAllGroupSessionsCallback?.onSuccess(Unit) -// resetBackupAllGroupSessionsListeners() -// return -// } -// -// keysBackupStateManager.state = KeysBackupState.BackingUp -// -// cryptoCoroutineScope.launch(coroutineDispatchers.main) { -// withContext(coroutineDispatchers.crypto) { -// Timber.v("backupKeys: 2 - Encrypting keys") -// -// // Gather data to send to the homeserver -// // roomId -> sessionId -> MXKeyBackupData -// val keysBackupData = KeysBackupData() -// -// olmInboundGroupSessionWrappers.forEach { olmInboundGroupSessionWrapper -> -// val roomId = olmInboundGroupSessionWrapper.roomId ?: return@forEach -// val olmInboundGroupSession = olmInboundGroupSessionWrapper.olmInboundGroupSession ?: return@forEach -// -// try { -// encryptGroupSession(olmInboundGroupSessionWrapper) -// ?.let { -// keysBackupData.roomIdToRoomKeysBackupData -// .getOrPut(roomId) { RoomKeysBackupData() } -// .sessionIdToKeyBackupData[olmInboundGroupSession.sessionIdentifier()] = it -// } -// } catch (e: OlmException) { -// Timber.e(e, "OlmException") -// } -// } -// -// Timber.v("backupKeys: 4 - Sending request") -// -// // Make the request -// val version = keysBackupVersion?.version ?: return@withContext -// -// storeSessionDataTask -// .configureWith(StoreSessionsDataTask.Params(version, keysBackupData)) { -// this.callback = object : MatrixCallback { -// override fun onSuccess(data: BackupKeysResult) { -// uiHandler.post { -// Timber.v("backupKeys: 5a - Request complete") -// -// // Mark keys as backed up -// cryptoStore.markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers) -// -// if (olmInboundGroupSessionWrappers.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) { -// Timber.v("backupKeys: All keys have been backed up") -// onServerDataRetrieved(data.count, data.hash) -// -// // Note: Changing state will trigger the call to backupAllGroupSessionsCallback.onSuccess() -// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp -// } else { -// Timber.v("backupKeys: Continue to back up keys") -// keysBackupStateManager.state = KeysBackupState.WillBackUp -// -// backupKeys() -// } -// } -// } -// -// override fun onFailure(failure: Throwable) { -// if (failure is Failure.ServerError) { -// uiHandler.post { -// Timber.e(failure, "backupKeys: backupKeys failed.") -// -// when (failure.error.code) { -// MatrixError.M_NOT_FOUND, -// MatrixError.M_WRONG_ROOM_KEYS_VERSION -> { -// // Backup has been deleted on the server, or we are not using the last backup version -// keysBackupStateManager.state = KeysBackupState.WrongBackUpVersion -// backupAllGroupSessionsCallback?.onFailure(failure) -// resetBackupAllGroupSessionsListeners() -// resetKeysBackupData() -// keysBackupVersion = null -// -// // Do not stay in KeysBackupState.WrongBackUpVersion but check what is available on the homeserver -// checkAndStartKeysBackup() -// } -// else -> -// // Come back to the ready state so that we will retry on the next received key -// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp -// } -// } -// } else { -// uiHandler.post { -// backupAllGroupSessionsCallback?.onFailure(failure) -// resetBackupAllGroupSessionsListeners() -// -// Timber.e("backupKeys: backupKeys failed.") -// -// // Retry a bit later -// keysBackupStateManager.state = KeysBackupState.ReadyToBackUp -// maybeBackupKeys() -// } -// } -// } -// } -// } -// .executeBy(taskExecutor) -// } -// } -// } -// -// @VisibleForTesting -// @WorkerThread -// fun encryptGroupSession(olmInboundGroupSessionWrapper: OlmInboundGroupSessionWrapper2): KeyBackupData? { -// // Gather information for each key -// val device = olmInboundGroupSessionWrapper.senderKey?.let { cryptoStore.deviceWithIdentityKey(it) } -// -// // Build the m.megolm_backup.v1.curve25519-aes-sha2 data as defined at -// // https://github.com/uhoreg/matrix-doc/blob/e2e_backup/proposals/1219-storing-megolm-keys-serverside.md#mmegolm_backupv1curve25519-aes-sha2-key-format -// val sessionData = olmInboundGroupSessionWrapper.exportKeys() ?: return null -// val sessionBackupData = mapOf( -// "algorithm" to sessionData.algorithm, -// "sender_key" to sessionData.senderKey, -// "sender_claimed_keys" to sessionData.senderClaimedKeys, -// "forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()), -// "session_key" to sessionData.sessionKey) -// -// val json = MoshiProvider.providesMoshi() -// .adapter(Map::class.java) -// .toJson(sessionBackupData) -// -// val encryptedSessionBackupData = try { -// backupOlmPkEncryption?.encrypt(json) -// } catch (e: OlmException) { -// Timber.e(e, "OlmException") -// null -// } -// ?: return null -// -// // Build backup data for that key -// return KeyBackupData( -// firstMessageIndex = try { -// olmInboundGroupSessionWrapper.olmInboundGroupSession?.firstKnownIndex ?: 0 -// } catch (e: OlmException) { -// Timber.e(e, "OlmException") -// 0L -// }, -// forwardedCount = olmInboundGroupSessionWrapper.forwardingCurve25519KeyChain.orEmpty().size, -// isVerified = device?.isVerified == true, -// -// sessionData = mapOf( -// "ciphertext" to encryptedSessionBackupData.mCipherText, -// "mac" to encryptedSessionBackupData.mMac, -// "ephemeral" to encryptedSessionBackupData.mEphemeralKey) -// ) -// } -// -// @VisibleForTesting -// @WorkerThread -// fun decryptKeyBackupData(keyBackupData: KeyBackupData, sessionId: String, roomId: String, decryption: OlmPkDecryption): MegolmSessionData? { -// var sessionBackupData: MegolmSessionData? = null -// -// val jsonObject = keyBackupData.sessionData -// -// val ciphertext = jsonObject["ciphertext"]?.toString() -// val mac = jsonObject["mac"]?.toString() -// val ephemeralKey = jsonObject["ephemeral"]?.toString() -// -// if (ciphertext != null && mac != null && ephemeralKey != null) { -// val encrypted = OlmPkMessage() -// encrypted.mCipherText = ciphertext -// encrypted.mMac = mac -// encrypted.mEphemeralKey = ephemeralKey -// -// try { -// val decrypted = decryption.decrypt(encrypted) -// -// val moshi = MoshiProvider.providesMoshi() -// val adapter = moshi.adapter(MegolmSessionData::class.java) -// -// sessionBackupData = adapter.fromJson(decrypted) -// } catch (e: OlmException) { -// Timber.e(e, "OlmException") -// } -// -// if (sessionBackupData != null) { -// sessionBackupData = sessionBackupData.copy( -// sessionId = sessionId, -// roomId = roomId -// ) -// } -// } -// -// return sessionBackupData -// } -// -// /* ========================================================================================== -// * For test only -// * ========================================================================================== */ -// -// // Direct access for test only -// @VisibleForTesting -// val store -// get() = cryptoStore -// -// @VisibleForTesting -// fun createFakeKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, -// callback: MatrixCallback) { -// @Suppress("UNCHECKED_CAST") -// val createKeysBackupVersionBody = CreateKeysBackupVersionBody( -// algorithm = keysBackupCreationInfo.algorithm, -// authData = keysBackupCreationInfo.authData.toJsonDict() -// ) -// -// createKeysBackupVersionTask -// .configureWith(createKeysBackupVersionBody) { -// this.callback = callback -// } -// .executeBy(taskExecutor) -// } -// -// override fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? { -// return cryptoStore.getKeyBackupRecoveryKeyInfo() -// } -// -// override fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) { -// cryptoStore.saveBackupRecoveryKey(recoveryKey, version) -// } -// -// companion object { -// // Maximum delay in ms in {@link maybeBackupKeys} -// private const val KEY_BACKUP_WAITING_TIME_TO_SEND_KEY_BACKUP_MILLIS = 10_000L -// -// // Maximum number of keys to send at a time to the homeserver. -// private const val KEY_BACKUP_SEND_KEYS_MAX_COUNT = 100 -// } -// -///* ========================================================================================== -// * DEBUG INFO -// * ========================================================================================== */ -// -// override fun toString() = "KeysBackup for $userId" -//} From ee017b7302da804034c891c1dbf4a82689fae48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 9 Dec 2021 13:15:54 +0100 Subject: [PATCH 206/252] rust: Bump the sdk version This updates the rust-sdk to support fallback keys, note that fallback keys are not yet uploaded, they just can be used when downloaded and info about the fallback keys coming from a sync can be passed to the rust side. --- .../org/matrix/android/sdk/internal/crypto/OlmMachine.kt | 4 +++- rust-sdk/Cargo.toml | 6 +++--- rust-sdk/src/machine.rs | 5 +++++ rust-sdk/src/olm.udl | 3 ++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 16ca58a8fa..b3cb03d657 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -309,7 +309,9 @@ internal class OlmMachine( MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! - adapter.fromJson(inner.receiveSyncChanges(events, devices, counts)) ?: ToDeviceSyncResponse() + // TODO once our sync response type parses the unused fallback key + // field pass in the list of unused fallback keys here + adapter.fromJson(inner.receiveSyncChanges(events, devices, counts, unusedFallbackKeys = null)) ?: ToDeviceSyncResponse() } // We may get cross signing keys over a to-device event, update our listeners. diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml index 203ceec70f..11c5d47ccd 100644 --- a/rust-sdk/Cargo.toml +++ b/rust-sdk/Cargo.toml @@ -29,11 +29,11 @@ features = ["lax_deserialize"] [dependencies.matrix-sdk-common] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "8494f105837af824f4637c05e9e01b0854d7109b" +rev = "009ead2eeaf365e1fb0f790557f20d4eaf6874ae" [dependencies.matrix-sdk-crypto] git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "8494f105837af824f4637c05e9e01b0854d7109b" +rev = "009ead2eeaf365e1fb0f790557f20d4eaf6874ae" features = ["sled_cryptostore", "qrcode", "backups_v1"] [dependencies.tokio] @@ -43,7 +43,7 @@ features = ["rt-multi-thread"] [dependencies.ruma] git = "https://github.com/ruma/ruma" -rev = "6c4892664" +rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d" features = ["client-api-c"] [build-dependencies] diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 0c0947fe9e..441322dca2 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -344,6 +344,7 @@ impl OlmMachine { events: &str, device_changes: DeviceLists, key_counts: HashMap, + unused_fallback_keys: Option>, ) -> Result { let events: ToDevice = serde_json::from_str(events)?; let device_changes: RumaDeviceLists = device_changes.into(); @@ -359,10 +360,14 @@ impl OlmMachine { }) .collect(); + let unused_fallback_keys: Option> = + unused_fallback_keys.map(|u| u.into_iter().map(DeviceKeyAlgorithm::from).collect()); + let events = self.runtime.block_on(self.inner.receive_sync_changes( events, &device_changes, &key_counts, + unused_fallback_keys.as_deref(), ))?; Ok(serde_json::to_string(&events)?) diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 675dc466e6..4adbdd98b9 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -244,7 +244,8 @@ interface OlmMachine { [Throws=CryptoStoreError] string receive_sync_changes([ByRef] string events, DeviceLists device_changes, - record key_counts); + record key_counts, + sequence? unused_fallback_keys); [Throws=CryptoStoreError] sequence outgoing_requests(); [Throws=CryptoStoreError] From a194213978ef84d7ccffc77461bdecd8a7016a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Tue, 8 Feb 2022 09:43:06 +0100 Subject: [PATCH 207/252] rust: Add the string that failed to be parsed as an user id to the error If there's an invalid user id that gets passed to the Rust side we're going to throw an error, this error doesn't tell us what is invalid nor what the string contained. Add the string that is being parsed to the error so that the log line becomes actionable. --- rust-sdk/src/error.rs | 2 ++ rust-sdk/src/lib.rs | 7 +++++++ rust-sdk/src/machine.rs | 30 +++++++++++++++--------------- rust-sdk/src/olm.udl | 1 + 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs index caa7c44983..1a79c5f6b9 100644 --- a/rust-sdk/src/error.rs +++ b/rust-sdk/src/error.rs @@ -46,6 +46,8 @@ pub enum CryptoStoreError { OlmError(#[from] OlmError), #[error(transparent)] Serialization(#[from] serde_json::Error), + #[error("The given string is not a valid user ID: source {0}, error {1}")] + InvalidUserId(String, RumaIdentifierError), #[error(transparent)] Identifier(#[from] RumaIdentifierError), } diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs index 35f62fca4e..533636d0b5 100644 --- a/rust-sdk/src/lib.rs +++ b/rust-sdk/src/lib.rs @@ -17,6 +17,8 @@ mod responses; mod users; mod verification; +use std::convert::TryFrom; + pub use backup_recovery_key::{ BackupRecoveryKey, DecodeError, MegolmV1BackupKey, PassphraseInfo, PkDecryptionError, }; @@ -153,4 +155,9 @@ impl From for CrossSigningStatus { } } +fn parse_user_id(user_id: &str) -> Result, CryptoStoreError> { + Box::::try_from(user_id) + .map_err(|e| CryptoStoreError::InvalidUserId(user_id.to_owned(), e)) +} + include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 441322dca2..3de5800aae 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -48,7 +48,7 @@ use crate::{ CrossSigningStatus, DecodeError, DecryptedEvent, Device, DeviceLists, KeyImportError, KeysImportResult, MegolmV1BackupKey, ProgressListener, QrCode, Request, RequestType, RequestVerificationResult, RoomKeyCounts, ScanResult, SignatureUploadRequest, StartSasResult, - UserIdentity, Verification, VerificationRequest, + UserIdentity, Verification, VerificationRequest, parse_user_id, }; /// A high level state machine that handles E2EE for Matrix. @@ -78,7 +78,7 @@ impl OlmMachine { /// /// * `path` - The path where the state of the machine should be persisted. pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; let device_id = device_id.into(); let runtime = Runtime::new().expect("Couldn't create a tokio runtime"); @@ -107,7 +107,7 @@ impl OlmMachine { /// Get a cross signing user identity for the given user ID. pub fn get_identity(&self, user_id: &str) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; Ok( if let Some(identity) = self.runtime.block_on(self.inner.get_identity(&user_id))? { @@ -120,7 +120,7 @@ impl OlmMachine { /// Check if a user identity is considered to be verified by us. pub fn is_identity_verified(&self, user_id: &str) -> Result { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; Ok( if let Some(identity) = self.runtime.block_on(self.inner.get_identity(&user_id))? { @@ -173,7 +173,7 @@ impl OlmMachine { user_id: &str, device_id: &str, ) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; Ok(self .runtime @@ -220,7 +220,7 @@ impl OlmMachine { user_id: &str, device_id: &str, ) -> Result<(), CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; let device = self .runtime @@ -240,7 +240,7 @@ impl OlmMachine { /// /// * `user_id` - The id of the device owner. pub fn get_user_devices(&self, user_id: &str) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; Ok(self .runtime @@ -400,7 +400,7 @@ impl OlmMachine { /// A user can be marked for tracking using the /// [`OlmMachine::update_tracked_users()`] method. pub fn is_user_tracked(&self, user_id: &str) -> Result { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; Ok(self.inner.tracked_users().contains(&user_id)) } @@ -802,7 +802,7 @@ impl OlmMachine { user_id: &str, methods: Vec, ) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; @@ -845,7 +845,7 @@ impl OlmMachine { event_id: &str, methods: Vec, ) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; let event_id = Box::::try_from(event_id)?; let room_id = Box::::try_from(room_id)?; @@ -883,7 +883,7 @@ impl OlmMachine { device_id: &str, methods: Vec, ) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; let methods = methods.into_iter().map(VerificationMethod::from).collect(); @@ -1010,7 +1010,7 @@ impl OlmMachine { user_id: &str, flow_id: &str, ) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; Ok( if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { @@ -1053,7 +1053,7 @@ impl OlmMachine { user_id: &str, flow_id: &str, ) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { Ok(self @@ -1146,7 +1146,7 @@ impl OlmMachine { user_id: &str, flow_id: &str, ) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; Ok( if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { @@ -1181,7 +1181,7 @@ impl OlmMachine { user_id: &str, device_id: &str, ) -> Result, CryptoStoreError> { - let user_id = Box::::try_from(user_id)?; + let user_id = parse_user_id(user_id)?; Ok( if let Some(device) = self diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 4adbdd98b9..b93a398233 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -44,6 +44,7 @@ enum CryptoStoreError { "OlmError", "Serialization", "Identifier", + "InvalidUserId", }; [Error] From 2f16a2ebd7e4f5fb6e60f1bafc655cd9f5a820c7 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 4 Mar 2022 12:36:31 +0100 Subject: [PATCH 208/252] Clean up some code --- .../sdk/internal/crypto/DefaultCryptoService.kt | 3 +-- .../crypto/keysbackup/RustKeyBackupService.kt | 14 ++++++++------ .../session/room/summary/RoomSummaryUpdater.kt | 3 +-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 60e0764c9f..98f65dc34b 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -146,7 +146,6 @@ internal class DefaultCryptoService @Inject constructor( private val olmMachine by lazy { olmMachineProvider.olmMachine } - // The verification service. // private var verificationService: RustVerificationService? = null @@ -166,7 +165,7 @@ internal class DefaultCryptoService @Inject constructor( } fun onLiveEvent(roomId: String, event: Event) { - if(event.isStateEvent()){ + if (event.isStateEvent()) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 071e1995c2..d4864c8234 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -372,22 +372,22 @@ internal class RustKeyBackupService @Inject constructor( } } - override suspend fun onSecretKeyGossip(curveKeyBase64: String) { + override suspend fun onSecretKeyGossip(secret: String) { Timber.i("## CrossSigning - onSecretKeyGossip") withContext(coroutineDispatchers.crypto) { try { val version = sender.getKeyBackupVersion() if (version != null) { - val key = BackupRecoveryKey.fromBase64(curveKeyBase64) + val key = BackupRecoveryKey.fromBase64(secret) if (isValidRecoveryKey(key, version)) { trustKeysBackupVersion(version, true) // we don't want to wait for that importScope.launch { try { val importResult = restoreBackup(version, key, null, null, null) - - Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") + val recoveredKeys = importResult.successfullyNumberOfImportedKeys + Timber.i("onSecretKeyGossip: Recovered keys $recoveredKeys out of ${importResult.totalNumberOfKeys}") } catch (failure: Throwable) { // fail silently.. Timber.e(failure, "onSecretKeyGossip: Failed to import keys from backup") @@ -514,7 +514,8 @@ internal class RustKeyBackupService @Inject constructor( .flatten() withContext(Dispatchers.Main) { - stepProgressListener?.onStepProgress(StepProgressListener.Step.DecryptingKey(data.roomIdToRoomKeysBackupData.size, data.roomIdToRoomKeysBackupData.size)) + val stepProgress = StepProgressListener.Step.DecryptingKey(data.roomIdToRoomKeysBackupData.size, data.roomIdToRoomKeysBackupData.size) + stepProgressListener?.onStepProgress(stepProgress) } Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" + @@ -532,7 +533,8 @@ internal class RustKeyBackupService @Inject constructor( object : ProgressListener { override fun onProgress(progress: Int, total: Int) { cryptoCoroutineScope.launch(Dispatchers.Main) { - stepProgressListener.onStepProgress(StepProgressListener.Step.ImportingKey(progress, total)) + val stepProgress = StepProgressListener.Step.ImportingKey(progress, total) + stepProgressListener.onStepProgress(stepProgress) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index cf8a712e71..374b923b34 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -18,9 +18,8 @@ package org.matrix.android.sdk.internal.session.room.summary import io.realm.Realm import io.realm.kotlin.createObject -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes From dc4569db5a3edb5f101d76230e252cd75a508190 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 4 Mar 2022 15:51:07 +0100 Subject: [PATCH 209/252] Remove warnings as error for now --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 013d3bfa5b..0055fa5c8f 100644 --- a/build.gradle +++ b/build.gradle @@ -77,7 +77,7 @@ allprojects { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { // Warnings are potential errors, so stop ignoring them // You can override by passing `-PallWarningsAsErrors=false` in the command line - kotlinOptions.allWarningsAsErrors = project.getProperties().getOrDefault("allWarningsAsErrors", "true").toBoolean() + kotlinOptions.allWarningsAsErrors = false//project.getProperties().getOrDefault("allWarningsAsErrors", "true").toBoolean() } // Fix "Java heap space" issue From e121007d2002da016c099a6d0096fe8d455659f4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 28 Mar 2022 18:15:46 +0200 Subject: [PATCH 210/252] Remove rust dependencies and use published aar --- build.gradle | 9 + dependencies_groups.gradle | 17 +- matrix-sdk-android/build.gradle | 19 +- rust-sdk/Cargo.toml | 50 - rust-sdk/Makefile | 21 - rust-sdk/README.md | 96 -- rust-sdk/build.rs | 3 - rust-sdk/src/backup_recovery_key.rs | 162 --- rust-sdk/src/device.rs | 46 - rust-sdk/src/error.rs | 63 -- rust-sdk/src/lib.rs | 163 --- rust-sdk/src/logger.rs | 59 -- rust-sdk/src/machine.rs | 1430 --------------------------- rust-sdk/src/olm.udl | 426 -------- rust-sdk/src/responses.rs | 365 ------- rust-sdk/src/users.rs | 61 -- rust-sdk/src/verification.rs | 232 ----- 17 files changed, 26 insertions(+), 3196 deletions(-) delete mode 100644 rust-sdk/Cargo.toml delete mode 100644 rust-sdk/Makefile delete mode 100644 rust-sdk/README.md delete mode 100644 rust-sdk/build.rs delete mode 100644 rust-sdk/src/backup_recovery_key.rs delete mode 100644 rust-sdk/src/device.rs delete mode 100644 rust-sdk/src/error.rs delete mode 100644 rust-sdk/src/lib.rs delete mode 100644 rust-sdk/src/logger.rs delete mode 100644 rust-sdk/src/machine.rs delete mode 100644 rust-sdk/src/olm.udl delete mode 100644 rust-sdk/src/responses.rs delete mode 100644 rust-sdk/src/users.rs delete mode 100644 rust-sdk/src/verification.rs diff --git a/build.gradle b/build.gradle index 0055fa5c8f..89a2eed0bf 100644 --- a/build.gradle +++ b/build.gradle @@ -72,6 +72,15 @@ allprojects { groups.jcenter.group.each { includeGroup it } } } + + maven { + url 'https://s01.oss.sonatype.org/content/repositories/snapshots' + content { + groups.mavenSnapshots.regex.each { includeGroupByRegex it } + groups.mavenSnapshots.group.each { includeGroup it } + } + } + } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle index 723941157d..89e7ed7169 100644 --- a/dependencies_groups.gradle +++ b/dependencies_groups.gradle @@ -1,5 +1,5 @@ ext.groups = [ - jitpack : [ + jitpack : [ regex: [ ], group: [ @@ -13,7 +13,7 @@ ext.groups = [ 'com.github.Zhuinden', ] ], - jitsi : [ + jitsi : [ regex: [ ], group: [ @@ -22,7 +22,7 @@ ext.groups = [ 'org.webkit', ] ], - google : [ + google : [ regex: [ 'androidx\\..*', 'com\\.android\\.tools\\..*', @@ -35,7 +35,14 @@ ext.groups = [ 'com.google.testing.platform', ] ], - mavenCentral: [ + mavenSnapshots: [ + regex: [ + ], + group: [ + 'org.matrix.rustcomponents' + ] + ], + mavenCentral : [ regex: [ ], group: [ @@ -187,7 +194,7 @@ ext.groups = [ 'xml-apis', ] ], - jcenter : [ + jcenter : [ regex: [ ], group: [ diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index b2b08646b4..b1b7986bf5 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -86,20 +86,6 @@ android { } } -android.libraryVariants.all { variant -> - def t = tasks.register("generate${variant.name.capitalize()}UniffiBindings", Exec) { - // Runs the bindings generation, note that you must have uniffi-bindgen installed - // and in your PATH environment variable - commandLine 'uniffi-bindgen', 'generate', '../rust-sdk/src/olm.udl', - '--language', 'kotlin', - '--out-dir', "${buildDir}/generated/source/uniffi/${variant.name}/java" - } - - variant.javaCompileProvider.get().dependsOn(t) - def sourceSet = variant.sourceSets.find { it.name == variant.name } - sourceSet.java.srcDir new File(buildDir, "generated/source/uniffi/${variant.name}/java") -} - static def gitRevision() { def cmd = "git rev-parse --short=8 HEAD" return cmd.execute().text.trim() @@ -115,10 +101,15 @@ static def gitRevisionDate() { return cmd.execute().text.trim() } +configurations.all { + resolutionStrategy.cacheChangingModulesFor 0, 'seconds' +} + dependencies { implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid + implementation 'org.matrix.rustcomponents:crypto-android:0.1.1-SNAPSHOT' implementation 'net.java.dev.jna:jna:5.10.0@aar' implementation libs.androidx.appCompat diff --git a/rust-sdk/Cargo.toml b/rust-sdk/Cargo.toml deleted file mode 100644 index 11c5d47ccd..0000000000 --- a/rust-sdk/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -name = "matrix-crypto-bindings" -version = "0.1.0" -authors = ["Damir Jelić "] -edition = "2018" - -[lib] -crate-type = ["cdylib", "lib"] -name = "matrix_crypto" - -[dependencies] -serde = "1.0.126" -serde_json = "1.0.64" -http = "0.2.4" -base64 = "0.13.0" - -thiserror = "1.0.25" -tracing = "0.1.26" -tracing-subscriber = "0.2.18" -uniffi = "0.15.1" -pbkdf2 = "0.8.0" -sha2 = "0.9.5" -rand = "0.8.4" -hmac = "0.11.0" - -[dependencies.js_int] -version = "0.2.1" -features = ["lax_deserialize"] - -[dependencies.matrix-sdk-common] -git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "009ead2eeaf365e1fb0f790557f20d4eaf6874ae" - -[dependencies.matrix-sdk-crypto] -git = "https://github.com/matrix-org/matrix-rust-sdk/" -rev = "009ead2eeaf365e1fb0f790557f20d4eaf6874ae" -features = ["sled_cryptostore", "qrcode", "backups_v1"] - -[dependencies.tokio] -version = "1.7.1" -default_features = false -features = ["rt-multi-thread"] - -[dependencies.ruma] -git = "https://github.com/ruma/ruma" -rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d" -features = ["client-api-c"] - -[build-dependencies] -uniffi_build = "0.15.1" diff --git a/rust-sdk/Makefile b/rust-sdk/Makefile deleted file mode 100644 index beeab61b22..0000000000 --- a/rust-sdk/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -all: x86 aarch64 armv7-linux-androideabi - -# x86_64: -# cargo build --release --target x86_64-linux-android -# mkdir -p ../matrix-sdk-android/src/main/jniLibs/x86_64/ -# cp target/x86_64-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86_64/libuniffi_olm.so - -x86: - cargo build --release --target i686-linux-android - mkdir -p ../matrix-sdk-android/src/main/jniLibs/x86/ - cp target/i686-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/x86/libuniffi_olm.so - -aarch64: - cargo build --release --target aarch64-linux-android - mkdir -p ../matrix-sdk-android/src/main/jniLibs/arm64-v8a/ - cp target/aarch64-linux-android/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/arm64-v8a/libuniffi_olm.so - -armv7-linux-androideabi: - cargo build --release --target armv7-linux-androideabi - mkdir -p ../matrix-sdk-android/src/main/jniLibs/armeabi-v7a/ - cp target/armv7-linux-androideabi/release/libmatrix_crypto.so ../matrix-sdk-android/src/main/jniLibs/armeabi-v7a/libuniffi_olm.so \ No newline at end of file diff --git a/rust-sdk/README.md b/rust-sdk/README.md deleted file mode 100644 index 57fecd4c92..0000000000 --- a/rust-sdk/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# Kotlin bindings for the Rust SDK crypto layer. - -## Prerequisites - -### Rust - -To build the bindings [Rust] will be needed it can be either installed using an -OS specific package manager or directly with the provided [installer](https://rustup.rs/). - - -### Android NDK - -The Android NDK will be required as well, it can be installed either through -Android Studio or directly using an [installer](https://developer.android.com/ndk/downloads). - -### Uniffi - -The bindings are using [uniffi] to generate the C translation layer between Rust -and Kotlin. Uniffi is a Rust project and can be installed with our freshly -installed Rust setup using: - -``` -$ cargo install uniffi_bindgen -``` - -### Configuring Rust for cross compilation - -First we'll need to install the Rust target for our desired Android architecture, -for example: - -``` -# rustup target add aarch64-linux-android -``` - -This will add support to cross-compile for the aarch64-linux-android target, -Rust supports many different [targets], you'll have to make sure to pick the -right one for your device or emulator. - -After this is done, we'll have to configure [Cargo] to use the correct linker -for our target. Cargo is configured using a TOML file that will be found in -`%USERPROFILE%\.cargo\config.toml` on Windows or `$HOME/.cargo/config` on Unix -platforms. More details and configuration options for Cargo can be found in the -official docs over [here](https://doc.rust-lang.org/cargo/reference/config.html). - -``` -[target.aarch64-linux-android] -ar = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/ar" -linker = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang" -``` - -## Building - -A `Makefile` is provided that builds and installs the dynamic library into the -appropriate target specific `jniLibs` directory. But before we can get started -we'll need to tweak our Rust setup to allow cross compilation. - -To enable cross compilation fro `olm-sys` which builds our libolm C library -we'll need to set the `ANDROID_NDK` environment variable to the location of our -Android NDK installation. - -``` -$ export ANDROID_NDK=$HOME/Android/Sdk/ndk/22.0.7026061/ -``` - -### Makefile build - -After the prerequisites have been installed and the environment variable has -been set a build for the `aarch64` target can be build using: - -``` -make aarch64 -``` - -### Manual build - -If the `Makefile` doesn't work on your system, the bindings can built for the `aarch64` -target with: - -``` -$ cargo build --target aarch64-linux-android -``` - -After that, a dynamic library can be found in the `target/aarch64-linux-android/debug` directory. -The library will be called `libmatrix_crypto.so` and needs to be renamed and -copied into the `jniLibs` directory: - -``` -$ cp target/aarch64-linux-android/debug/libmatrix_crypto.so \ - ../matrix-sdk-android/src/main/jniLibs/aarch64/libuniffi_olm.so -``` - -[Rust]: https://www.rust-lang.org/ -[installer]: https://rustup.rs/ -[targets]: https://doc.rust-lang.org/nightly/rustc/platform-support.html -[Cargo]: https://doc.rust-lang.org/cargo/ -[uniffi]: https://github.com/mozilla/uniffi-rs/ diff --git a/rust-sdk/build.rs b/rust-sdk/build.rs deleted file mode 100644 index bfce95467f..0000000000 --- a/rust-sdk/build.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - uniffi_build::generate_scaffolding("./src/olm.udl").unwrap(); -} diff --git a/rust-sdk/src/backup_recovery_key.rs b/rust-sdk/src/backup_recovery_key.rs deleted file mode 100644 index 4a867294cf..0000000000 --- a/rust-sdk/src/backup_recovery_key.rs +++ /dev/null @@ -1,162 +0,0 @@ -use hmac::Hmac; -use pbkdf2::pbkdf2; -use rand::{distributions::Alphanumeric, thread_rng, Rng}; -use sha2::Sha512; -use std::{collections::HashMap, iter}; -use thiserror::Error; - -use matrix_sdk_crypto::{ - backups::{OlmPkDecryptionError, RecoveryKey}, - store::CryptoStoreError as InnerStoreError, -}; - -/// The private part of the backup key, the one used for recovery. -pub struct BackupRecoveryKey { - pub(crate) inner: RecoveryKey, - passphrase_info: Option, -} - -/// Error type for the decryption of backed up room keys. -#[derive(Debug, Error)] -pub enum PkDecryptionError { - /// An internal libolm error happened during decryption. - #[error("Error decryption a PkMessage {0}")] - Olm(#[from] OlmPkDecryptionError), -} - -#[derive(Debug, Error)] -pub enum DecodeError { - /// An error happened while decoding the recovery key. - #[error(transparent)] - Decode(#[from] matrix_sdk_crypto::backups::DecodeError), - /// An error happened in the storage layer, - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), -} - -/// Struct containing info about the way the backup key got derived from a -/// passphrase. -#[derive(Debug, Clone)] -pub struct PassphraseInfo { - /// The salt that was used during key derivation. - pub private_key_salt: String, - /// The number of PBKDF rounds that were used for key derivation. - pub private_key_iterations: i32, -} - -/// The public part of the backup key. -pub struct MegolmV1BackupKey { - /// The actuall base64 encoded public key. - pub public_key: String, - /// Signatures that have signed our backup key. - pub signatures: HashMap>, - /// The passphrase info, if the key was derived from one. - pub passphrase_info: Option, - /// Get the full name of the backup algorithm this backup key supports. - pub backup_algorithm: String, -} - -impl BackupRecoveryKey { - const KEY_SIZE: usize = 32; - const SALT_SIZE: usize = 32; - const PBKDF_ROUNDS: i32 = 500_000; - - /// Create a new random [`BackupRecoveryKey`]. - pub fn new() -> Self { - Self { - inner: RecoveryKey::new() - .expect("Can't gather enough randomness to create a recovery key"), - passphrase_info: None, - } - } - - /// Try to create a [`BackupRecoveryKey`] from a base 64 encoded string. - pub fn from_base64(key: String) -> Result { - Ok(Self { - inner: RecoveryKey::from_base64(&key)?, - passphrase_info: None, - }) - } - - /// Try to create a [`BackupRecoveryKey`] from a base 58 encoded string. - pub fn from_base58(key: String) -> Result { - Ok(Self { - inner: RecoveryKey::from_base58(&key)?, - passphrase_info: None, - }) - } - - /// Create a new [`BackupRecoveryKey`] from the given passphrase. - pub fn new_from_passphrase(passphrase: String) -> Self { - let mut rng = thread_rng(); - let salt: String = iter::repeat(()) - .map(|()| rng.sample(Alphanumeric)) - .map(char::from) - .take(Self::SALT_SIZE) - .collect(); - - Self::from_passphrase(passphrase, salt, Self::PBKDF_ROUNDS) - } - - /// Restore a [`BackupRecoveryKey`] from the given passphrase. - pub fn from_passphrase(passphrase: String, salt: String, rounds: i32) -> Self { - let mut key = [0u8; Self::KEY_SIZE]; - let rounds = rounds as u32; - - pbkdf2::>(passphrase.as_bytes(), salt.as_bytes(), rounds, &mut key); - - Self { - inner: RecoveryKey::from_bytes(key), - passphrase_info: Some(PassphraseInfo { - private_key_salt: salt, - private_key_iterations: rounds as i32, - }), - } - } - - /// Get the public part of the backup key. - pub fn megolm_v1_public_key(&self) -> MegolmV1BackupKey { - let public_key = self.inner.megolm_v1_public_key(); - - let signatures: HashMap> = public_key - .signatures() - .into_iter() - .map(|(k, v)| { - ( - k.to_string(), - v.into_iter().map(|(k, v)| (k.to_string(), v)).collect(), - ) - }) - .collect(); - - MegolmV1BackupKey { - public_key: public_key.to_base64(), - signatures, - passphrase_info: self.passphrase_info.clone(), - backup_algorithm: public_key.backup_algorithm().to_owned(), - } - } - - /// Convert the recovery key to a base 58 encoded string. - pub fn to_base58(&self) -> String { - self.inner.to_base58() - } - - /// Convert the recovery key to a base 64 encoded string. - pub fn to_base64(&self) -> String { - self.inner.to_base64() - } - - /// Try to decrypt a message that was encrypted using the public part of the - /// backup key. - pub fn decrypt_v1( - &self, - ephemeral_key: String, - mac: String, - ciphertext: String, - ) -> Result { - self.inner - .decrypt_v1(ephemeral_key, mac, ciphertext) - .map_err(|e| e.into()) - } -} diff --git a/rust-sdk/src/device.rs b/rust-sdk/src/device.rs deleted file mode 100644 index ecd571c118..0000000000 --- a/rust-sdk/src/device.rs +++ /dev/null @@ -1,46 +0,0 @@ -use std::collections::HashMap; - -use matrix_sdk_crypto::Device as InnerDevice; - -/// An E2EE capable Matrix device. -pub struct Device { - /// The device owner. - pub user_id: String, - /// The unique ID of the device. - pub device_id: String, - /// The published public identity keys of the devices - /// - /// A map from the key type (e.g. curve25519) to the base64 encoded key. - pub keys: HashMap, - /// The supported algorithms of the device. - pub algorithms: Vec, - /// The human readable name of the device. - pub display_name: Option, - /// A flag indicating if the device has been blocked, blocked devices don't - /// receive any room keys from us. - pub is_blocked: bool, - /// Is the device locally trusted - pub locally_trusted: bool, - /// Is our cross signing identity trusted and does the identity trust the - /// device. - pub cross_signing_trusted: bool, -} - -impl From for Device { - fn from(d: InnerDevice) -> Self { - Device { - user_id: d.user_id().to_string(), - device_id: d.device_id().to_string(), - keys: d - .keys() - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - algorithms: d.algorithms().iter().map(|a| a.to_string()).collect(), - display_name: d.display_name().map(|d| d.to_owned()), - is_blocked: d.is_blacklisted(), - locally_trusted: d.is_locally_trusted(), - cross_signing_trusted: d.is_cross_signing_trusted(), - } - } -} diff --git a/rust-sdk/src/error.rs b/rust-sdk/src/error.rs deleted file mode 100644 index 1a79c5f6b9..0000000000 --- a/rust-sdk/src/error.rs +++ /dev/null @@ -1,63 +0,0 @@ -#![allow(missing_docs)] - -use matrix_sdk_crypto::{ - store::CryptoStoreError as InnerStoreError, KeyExportError, MegolmError, OlmError, - SecretImportError as RustSecretImportError, SignatureError as InnerSignatureError, -}; -use ruma::identifiers::Error as RumaIdentifierError; - -#[derive(Debug, thiserror::Error)] -pub enum KeyImportError { - #[error(transparent)] - Export(#[from] KeyExportError), - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), - #[error(transparent)] - Json(#[from] serde_json::Error), -} - -#[derive(Debug, thiserror::Error)] -pub enum SecretImportError { - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), - #[error(transparent)] - Import(#[from] RustSecretImportError), -} - -#[derive(Debug, thiserror::Error)] -pub enum SignatureError { - #[error(transparent)] - Signature(#[from] InnerSignatureError), - #[error(transparent)] - Identifier(#[from] RumaIdentifierError), - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), - #[error("Unknown device {0} {1}")] - UnknownDevice(String, String), - #[error("Unknown user identity {0}")] - UnknownUserIdentity(String), -} - -#[derive(Debug, thiserror::Error)] -pub enum CryptoStoreError { - #[error(transparent)] - CryptoStore(#[from] InnerStoreError), - #[error(transparent)] - OlmError(#[from] OlmError), - #[error(transparent)] - Serialization(#[from] serde_json::Error), - #[error("The given string is not a valid user ID: source {0}, error {1}")] - InvalidUserId(String, RumaIdentifierError), - #[error(transparent)] - Identifier(#[from] RumaIdentifierError), -} - -#[derive(Debug, thiserror::Error)] -pub enum DecryptionError { - #[error(transparent)] - Serialization(#[from] serde_json::Error), - #[error(transparent)] - Identifier(#[from] RumaIdentifierError), - #[error(transparent)] - Megolm(#[from] MegolmError), -} diff --git a/rust-sdk/src/lib.rs b/rust-sdk/src/lib.rs deleted file mode 100644 index 533636d0b5..0000000000 --- a/rust-sdk/src/lib.rs +++ /dev/null @@ -1,163 +0,0 @@ -#![deny( - dead_code, - trivial_casts, - trivial_numeric_casts, - unused_extern_crates, - unused_import_braces -)] - -//! TODO - -mod backup_recovery_key; -mod device; -mod error; -mod logger; -mod machine; -mod responses; -mod users; -mod verification; - -use std::convert::TryFrom; - -pub use backup_recovery_key::{ - BackupRecoveryKey, DecodeError, MegolmV1BackupKey, PassphraseInfo, PkDecryptionError, -}; -pub use device::Device; -pub use error::{ - CryptoStoreError, DecryptionError, KeyImportError, SecretImportError, SignatureError, -}; -pub use logger::{set_logger, Logger}; -pub use machine::{KeyRequestPair, OlmMachine}; -pub use responses::{ - BootstrapCrossSigningResult, DeviceLists, KeysImportResult, OutgoingVerificationRequest, - Request, RequestType, SignatureUploadRequest, UploadSigningKeysRequest, -}; -pub use users::UserIdentity; -pub use verification::{ - CancelInfo, ConfirmVerificationResult, QrCode, RequestVerificationResult, Sas, ScanResult, - StartSasResult, Verification, VerificationRequest, -}; - -/// Callback that will be passed over the FFI to report progress -pub trait ProgressListener { - /// The callback that should be called on the Rust side - /// - /// # Arguments - /// - /// * `progress` - The current number of items that have been handled - /// - /// * `total` - The total number of items that will be handled - fn on_progress(&self, progress: i32, total: i32); -} - -/// An event that was successfully decrypted. -pub struct DecryptedEvent { - /// The decrypted version of the event. - pub clear_event: String, - /// The claimed curve25519 key of the sender. - pub sender_curve25519_key: String, - /// The claimed ed25519 key of the sender. - pub claimed_ed25519_key: Option, - /// The curve25519 chain of the senders that forwarded the Megolm decryption - /// key to us. Is empty if the key came directly from the sender of the - /// event. - pub forwarding_curve25519_chain: Vec, -} - -/// Struct representing the state of our private cross signing keys, it shows -/// which private cross signing keys we have locally stored. -#[derive(Debug, Clone)] -pub struct CrossSigningStatus { - /// Do we have the master key. - pub has_master: bool, - /// Do we have the self signing key, this one is necessary to sign our own - /// devices. - pub has_self_signing: bool, - /// Do we have the user signing key, this one is necessary to sign other - /// users. - pub has_user_signing: bool, -} - -/// A struct containing private cross signing keys that can be backed up or -/// uploaded to the secret store. -pub struct CrossSigningKeyExport { - /// The seed of the master key encoded as unpadded base64. - pub master_key: Option, - /// The seed of the self signing key encoded as unpadded base64. - pub self_signing_key: Option, - /// The seed of the user signing key encoded as unpadded base64. - pub user_signing_key: Option, -} - -/// Struct holding the number of room keys we have. -pub struct RoomKeyCounts { - /// The total number of room keys. - pub total: i64, - /// The number of backed up room keys. - pub backed_up: i64, -} - -/// Backup keys and information we load from the store. -pub struct BackupKeys { - /// The recovery key as a base64 encoded string. - pub recovery_key: String, - /// The version that is used with the recovery key. - pub backup_version: String, -} - -impl std::convert::TryFrom for BackupKeys { - type Error = (); - - fn try_from(keys: matrix_sdk_crypto::store::BackupKeys) -> Result { - Ok(Self { - recovery_key: keys.recovery_key.ok_or(())?.to_base64(), - backup_version: keys.backup_version.ok_or(())?, - }) - } -} - -impl From for RoomKeyCounts { - fn from(count: matrix_sdk_crypto::store::RoomKeyCounts) -> Self { - Self { - total: count.total as i64, - backed_up: count.backed_up as i64, - } - } -} - -impl From for CrossSigningKeyExport { - fn from(e: matrix_sdk_crypto::CrossSigningKeyExport) -> Self { - Self { - master_key: e.master_key.clone(), - self_signing_key: e.self_signing_key.clone(), - user_signing_key: e.user_signing_key.clone(), - } - } -} - -impl From for matrix_sdk_crypto::CrossSigningKeyExport { - fn from(e: CrossSigningKeyExport) -> Self { - matrix_sdk_crypto::CrossSigningKeyExport { - master_key: e.master_key, - self_signing_key: e.self_signing_key, - user_signing_key: e.user_signing_key, - } - } -} - -impl From for CrossSigningStatus { - fn from(s: matrix_sdk_crypto::CrossSigningStatus) -> Self { - Self { - has_master: s.has_master, - has_self_signing: s.has_self_signing, - has_user_signing: s.has_user_signing, - } - } -} - -fn parse_user_id(user_id: &str) -> Result, CryptoStoreError> { - Box::::try_from(user_id) - .map_err(|e| CryptoStoreError::InvalidUserId(user_id.to_owned(), e)) -} - -include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs")); diff --git a/rust-sdk/src/logger.rs b/rust-sdk/src/logger.rs deleted file mode 100644 index a29b040572..0000000000 --- a/rust-sdk/src/logger.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::{ - io::{Result, Write}, - sync::{Arc, Mutex}, -}; -use tracing_subscriber::{fmt::MakeWriter, EnvFilter}; - -/// Trait that can be used to forward Rust logs over FFI to a language specific -/// logger. -pub trait Logger: Send { - /// Called every time the Rust side wants to post a log line. - fn log(&self, log_line: String); - // TODO add support for different log levels, do this by adding more methods - // to the trait. -} - -impl Write for LoggerWrapper { - fn write(&mut self, buf: &[u8]) -> Result { - let data = String::from_utf8_lossy(buf).to_string(); - self.inner.lock().unwrap().log(data); - - Ok(buf.len()) - } - - fn flush(&mut self) -> Result<()> { - Ok(()) - } -} - -impl MakeWriter for LoggerWrapper { - type Writer = LoggerWrapper; - - fn make_writer(&self) -> Self::Writer { - self.clone() - } -} - -#[derive(Clone)] -pub struct LoggerWrapper { - inner: Arc>>, -} - -/// Set the logger that should be used to forward Rust logs over FFI. -pub fn set_logger(logger: Box) { - let logger = LoggerWrapper { - inner: Arc::new(Mutex::new(logger)), - }; - - let filter = EnvFilter::from_default_env().add_directive( - "matrix_sdk_crypto=trace" - .parse() - .expect("Can't parse logging filter directive"), - ); - - let _ = tracing_subscriber::fmt() - .with_writer(logger) - .with_env_filter(filter) - .without_time() - .try_init(); -} diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs deleted file mode 100644 index 3de5800aae..0000000000 --- a/rust-sdk/src/machine.rs +++ /dev/null @@ -1,1430 +0,0 @@ -use std::{ - collections::{BTreeMap, HashMap}, - convert::{TryFrom, TryInto}, - io::Cursor, - ops::Deref, -}; - -use base64::{decode_config, encode, STANDARD_NO_PAD}; -use js_int::UInt; -use ruma::{ - api::{ - client::r0::{ - backup::add_backup_keys::Response as KeysBackupResponse, - keys::{ - claim_keys::Response as KeysClaimResponse, get_keys::Response as KeysQueryResponse, - upload_keys::Response as KeysUploadResponse, - upload_signatures::Response as SignatureUploadResponse, - }, - sync::sync_events::{DeviceLists as RumaDeviceLists, ToDevice}, - to_device::send_event_to_device::Response as ToDeviceResponse, - }, - IncomingResponse, - }, - events::{ - key::verification::VerificationMethod, room::encrypted::RoomEncryptedEventContent, - AnyMessageEventContent, EventContent, SyncMessageEvent, - }, - DeviceKeyAlgorithm, EventId, RoomId, UserId, -}; -use serde::{Deserialize, Serialize}; -use serde_json::{value::RawValue, Value}; -use tokio::runtime::Runtime; - -use matrix_sdk_common::{deserialized_responses::AlgorithmInfo, uuid::Uuid}; -use matrix_sdk_crypto::{ - backups::{MegolmV1BackupKey as RustBackupKey, RecoveryKey}, - decrypt_key_export, encrypt_key_export, - matrix_qrcode::QrVerificationData, - olm::ExportedRoomKey, - EncryptionSettings, LocalTrust, OlmMachine as InnerMachine, UserIdentities, - Verification as RustVerification, -}; - -use crate::{ - error::{CryptoStoreError, DecryptionError, SecretImportError, SignatureError}, - responses::{response_from_string, OutgoingVerificationRequest, OwnedResponse}, - BackupKeys, BootstrapCrossSigningResult, ConfirmVerificationResult, CrossSigningKeyExport, - CrossSigningStatus, DecodeError, DecryptedEvent, Device, DeviceLists, KeyImportError, - KeysImportResult, MegolmV1BackupKey, ProgressListener, QrCode, Request, RequestType, - RequestVerificationResult, RoomKeyCounts, ScanResult, SignatureUploadRequest, StartSasResult, - UserIdentity, Verification, VerificationRequest, parse_user_id, -}; - -/// A high level state machine that handles E2EE for Matrix. -pub struct OlmMachine { - inner: InnerMachine, - runtime: Runtime, -} - -/// A pair of outgoing room key requests, both of those are sendToDevice -/// requests. -pub struct KeyRequestPair { - /// The optional cancellation, this is None if no previous key request was - /// sent out for this key, thus it doesn't need to be cancelled. - pub cancellation: Option, - /// The actual key request. - pub key_request: Request, -} - -impl OlmMachine { - /// Create a new `OlmMachine` - /// - /// # Arguments - /// - /// * `user_id` - The unique ID of the user that owns this machine. - /// - /// * `device_id` - The unique ID of the device that owns this machine. - /// - /// * `path` - The path where the state of the machine should be persisted. - pub fn new(user_id: &str, device_id: &str, path: &str) -> Result { - let user_id = parse_user_id(user_id)?; - let device_id = device_id.into(); - let runtime = Runtime::new().expect("Couldn't create a tokio runtime"); - - Ok(OlmMachine { - inner: runtime.block_on(InnerMachine::new_with_default_store( - &user_id, device_id, path, None, - ))?, - runtime, - }) - } - - /// Get the user ID of the owner of this `OlmMachine`. - pub fn user_id(&self) -> String { - self.inner.user_id().to_string() - } - - /// Get the device ID of the device of this `OlmMachine`. - pub fn device_id(&self) -> String { - self.inner.device_id().to_string() - } - - /// Get the display name of our own device. - pub fn display_name(&self) -> Result, CryptoStoreError> { - Ok(self.runtime.block_on(self.inner.display_name())?) - } - - /// Get a cross signing user identity for the given user ID. - pub fn get_identity(&self, user_id: &str) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - Ok( - if let Some(identity) = self.runtime.block_on(self.inner.get_identity(&user_id))? { - Some(self.runtime.block_on(UserIdentity::from_rust(identity))?) - } else { - None - }, - ) - } - - /// Check if a user identity is considered to be verified by us. - pub fn is_identity_verified(&self, user_id: &str) -> Result { - let user_id = parse_user_id(user_id)?; - - Ok( - if let Some(identity) = self.runtime.block_on(self.inner.get_identity(&user_id))? { - match identity { - UserIdentities::Own(i) => i.is_verified(), - UserIdentities::Other(i) => i.verified(), - } - } else { - false - }, - ) - } - - /// Manually the user with the given user ID. - /// - /// This method will attempt to sign the user identity using either our - /// private cross signing key, for other user identities, or our device keys - /// for our own user identity. - /// - /// This methid can fail if we don't have the private part of our user-signing - /// key. - /// - /// Returns a request that needs to be sent out for the user identity to be - /// marked as verified. - pub fn verify_identity(&self, user_id: &str) -> Result { - let user_id = Box::::try_from(user_id)?; - - let user_identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; - - if let Some(user_identity) = user_identity { - Ok(match user_identity { - UserIdentities::Own(i) => self.runtime.block_on(i.verify())?, - UserIdentities::Other(i) => self.runtime.block_on(i.verify())?, - } - .into()) - } else { - Err(SignatureError::UnknownUserIdentity(user_id.to_string())) - } - } - - /// Get a `Device` from the store. - /// - /// # Arguments - /// - /// * `user_id` - The id of the device owner. - /// - /// * `device_id` - The id of the device itself. - pub fn get_device( - &self, - user_id: &str, - device_id: &str, - ) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - Ok(self - .runtime - .block_on(self.inner.get_device(&user_id, device_id.into()))? - .map(|d| d.into())) - } - - /// Manually the device of the given user with the given device ID. - /// - /// This method will attempt to sign the device using our private cross - /// signing key. - /// - /// This method will always fail if the device belongs to someone else, we - /// can only sign our own devices. - /// - /// It can also fail if we don't have the private part of our self-signing - /// key. - /// - /// Returns a request that needs to be sent out for the device to be marked - /// as verified. - pub fn verify_device( - &self, - user_id: &str, - device_id: &str, - ) -> Result { - let user_id = Box::::try_from(user_id)?; - let device = self - .runtime - .block_on(self.inner.get_device(&user_id, device_id.into()))?; - - if let Some(device) = device { - Ok(self.runtime.block_on(device.verify())?.into()) - } else { - Err(SignatureError::UnknownDevice( - user_id.to_string(), - device_id.to_string(), - )) - } - } - - /// Mark the device of the given user with the given device id as trusted. - pub fn mark_device_as_trusted( - &self, - user_id: &str, - device_id: &str, - ) -> Result<(), CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - let device = self - .runtime - .block_on(self.inner.get_device(&user_id, device_id.into()))?; - - if let Some(device) = device { - self.runtime - .block_on(device.set_local_trust(LocalTrust::Verified))?; - } - - Ok(()) - } - - /// Get all devices of an user. - /// - /// # Arguments - /// - /// * `user_id` - The id of the device owner. - pub fn get_user_devices(&self, user_id: &str) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - Ok(self - .runtime - .block_on(self.inner.get_user_devices(&user_id))? - .devices() - .map(|d| d.into()) - .collect()) - } - - /// Get our own identity keys. - pub fn identity_keys(&self) -> HashMap { - self.inner - .identity_keys() - .iter() - .map(|(k, v)| (k.to_owned(), v.to_owned())) - .collect() - } - - /// Get the list of outgoing requests that need to be sent to the - /// homeserver. - /// - /// After the request was sent out and a successful response was received - /// the response body should be passed back to the state machine using the - /// [mark_request_as_sent()](#method.mark_request_as_sent) method. - /// - /// **Note**: This method call should be locked per call. - pub fn outgoing_requests(&self) -> Result, CryptoStoreError> { - Ok(self - .runtime - .block_on(self.inner.outgoing_requests())? - .into_iter() - .map(|r| r.into()) - .collect()) - } - - /// Mark a request that was sent to the server as sent. - /// - /// # Arguments - /// - /// * `request_id` - The unique ID of the request that was sent out. This - /// needs to be an UUID. - /// - /// * `request_type` - The type of the request that was sent out. - /// - /// * `response_body` - The body of the response that was received. - pub fn mark_request_as_sent( - &self, - request_id: &str, - request_type: RequestType, - response_body: &str, - ) -> Result<(), CryptoStoreError> { - let id = Uuid::parse_str(request_id).expect("Can't parse request id"); - - let response = response_from_string(response_body); - - let response: OwnedResponse = match request_type { - RequestType::KeysUpload => { - KeysUploadResponse::try_from_http_response(response).map(Into::into) - } - RequestType::KeysQuery => { - KeysQueryResponse::try_from_http_response(response).map(Into::into) - } - RequestType::ToDevice => { - ToDeviceResponse::try_from_http_response(response).map(Into::into) - } - RequestType::KeysClaim => { - KeysClaimResponse::try_from_http_response(response).map(Into::into) - } - RequestType::SignatureUpload => { - SignatureUploadResponse::try_from_http_response(response).map(Into::into) - } - RequestType::KeysBackup => { - KeysBackupResponse::try_from_http_response(response).map(Into::into) - } - } - .expect("Can't convert json string to response"); - - self.runtime - .block_on(self.inner.mark_request_as_sent(&id, &response))?; - - Ok(()) - } - - /// Let the state machine know about E2EE related sync changes that we - /// received from the server. - /// - /// This needs to be called after every sync, ideally before processing - /// any other sync changes. - /// - /// # Arguments - /// - /// * `events` - A serialized array of to-device events we received in the - /// current sync response. - /// - /// * `device_changes` - The list of devices that have changed in some way - /// since the previous sync. - /// - /// * `key_counts` - The map of uploaded one-time key types and counts. - pub fn receive_sync_changes( - &self, - events: &str, - device_changes: DeviceLists, - key_counts: HashMap, - unused_fallback_keys: Option>, - ) -> Result { - let events: ToDevice = serde_json::from_str(events)?; - let device_changes: RumaDeviceLists = device_changes.into(); - let key_counts: BTreeMap = key_counts - .into_iter() - .map(|(k, v)| { - ( - DeviceKeyAlgorithm::from(k), - v.clamp(0, i32::MAX) - .try_into() - .expect("Couldn't convert key counts into an UInt"), - ) - }) - .collect(); - - let unused_fallback_keys: Option> = - unused_fallback_keys.map(|u| u.into_iter().map(DeviceKeyAlgorithm::from).collect()); - - let events = self.runtime.block_on(self.inner.receive_sync_changes( - events, - &device_changes, - &key_counts, - unused_fallback_keys.as_deref(), - ))?; - - Ok(serde_json::to_string(&events)?) - } - - /// Add the given list of users to be tracked, triggering a key query request - /// for them. - /// - /// *Note*: Only users that aren't already tracked will be considered for an - /// update. It's safe to call this with already tracked users, it won't - /// result in excessive keys query requests. - /// - /// # Arguments - /// - /// `users` - The users that should be queued up for a key query. - pub fn update_tracked_users(&self, users: Vec) { - let users: Vec> = users - .into_iter() - .filter_map(|u| Box::::try_from(u).ok()) - .collect(); - - self.runtime.block_on( - self.inner - .update_tracked_users(users.iter().map(Deref::deref)), - ); - } - - /// Check if the given user is considered to be tracked. - /// - /// A user can be marked for tracking using the - /// [`OlmMachine::update_tracked_users()`] method. - pub fn is_user_tracked(&self, user_id: &str) -> Result { - let user_id = parse_user_id(user_id)?; - Ok(self.inner.tracked_users().contains(&user_id)) - } - - /// Generate one-time key claiming requests for all the users we are missing - /// sessions for. - /// - /// After the request was sent out and a successful response was received - /// the response body should be passed back to the state machine using the - /// [mark_request_as_sent()](#method.mark_request_as_sent) method. - /// - /// This method should be called every time before a call to - /// [`share_group_session()`](#method.share_group_session) is made. - /// - /// # Arguments - /// - /// * `users` - The list of users for which we would like to establish 1:1 - /// Olm sessions for. - pub fn get_missing_sessions( - &self, - users: Vec, - ) -> Result, CryptoStoreError> { - let users: Vec> = users - .into_iter() - .filter_map(|u| Box::::try_from(u).ok()) - .collect(); - - Ok(self - .runtime - .block_on( - self.inner - .get_missing_sessions(users.iter().map(Deref::deref)), - )? - .map(|r| r.into())) - } - - /// Share a room key with the given list of users for the given room. - /// - /// After the request was sent out and a successful response was received - /// the response body should be passed back to the state machine using the - /// [mark_request_as_sent()](#method.mark_request_as_sent) method. - /// - /// This method should be called every time before a call to - /// [`encrypt()`](#method.encrypt) with the given `room_id` is made. - /// - /// # Arguments - /// - /// * `room_id` - The unique id of the room, note that this doesn't strictly - /// need to be a Matrix room, it just needs to be an unique identifier for - /// the group that will participate in the conversation. - /// - /// * `users` - The list of users which are considered to be members of the - /// room and should receive the room key. - pub fn share_room_key( - &self, - room_id: &str, - users: Vec, - ) -> Result, CryptoStoreError> { - let users: Vec> = users - .into_iter() - .filter_map(|u| Box::::try_from(u).ok()) - .collect(); - - let room_id = Box::::try_from(room_id)?; - let requests = self.runtime.block_on(self.inner.share_group_session( - &room_id, - users.iter().map(Deref::deref), - EncryptionSettings::default(), - ))?; - - Ok(requests.into_iter().map(|r| (&*r).into()).collect()) - } - - /// Encrypt the given event with the given type and content for the given - /// room. - /// - /// **Note**: A room key needs to be shared with the group of users that are - /// members in the given room. If this is not done this method will panic. - /// - /// The usual flow to encrypt an event using this state machine is as - /// follows: - /// - /// 1. Get the one-time key claim request to establish 1:1 Olm sessions for - /// the room members of the room we wish to participate in. This is done - /// using the [`get_missing_sessions()`](#method.get_missing_sessions) - /// method. This method call should be locked per call. - /// - /// 2. Share a room key with all the room members using the - /// [`share_group_session()`](#method.share_group_session). This method - /// call should be locked per room. - /// - /// 3. Encrypt the event using this method. - /// - /// 4. Send the encrypted event to the server. - /// - /// After the room key is shared steps 1 and 2 will become noops, unless - /// there's some changes in the room membership or in the list of devices a - /// member has. - /// - /// # Arguments - /// - /// * `room_id` - The unique id of the room where the event will be sent to. - /// - /// * `even_type` - The type of the event. - /// - /// * `content` - The serialized content of the event. - pub fn encrypt( - &self, - room_id: &str, - event_type: &str, - content: &str, - ) -> Result { - let room_id = Box::::try_from(room_id)?; - let content: Box = serde_json::from_str(content)?; - - let content = AnyMessageEventContent::from_parts(event_type, &content)?; - let encrypted_content = self - .runtime - .block_on(self.inner.encrypt(&room_id, content)) - .expect("Encrypting an event produced an error"); - - Ok(serde_json::to_string(&encrypted_content)?) - } - - /// Decrypt the given event that was sent in the given room. - /// - /// # Arguments - /// - /// * `event` - The serialized encrypted version of the event. - /// - /// * `room_id` - The unique id of the room where the event was sent to. - pub fn decrypt_room_event( - &self, - event: &str, - room_id: &str, - ) -> Result { - // Element Android wants only the content and the type and will create a - // decrypted event with those two itself, this struct makes sure we - // throw away all the other fields. - #[derive(Deserialize, Serialize)] - struct Event<'a> { - #[serde(rename = "type")] - event_type: String, - #[serde(borrow)] - content: &'a RawValue, - } - - let event: SyncMessageEvent = serde_json::from_str(event)?; - let room_id = Box::::try_from(room_id)?; - - let decrypted = self - .runtime - .block_on(self.inner.decrypt_room_event(&event, &room_id))?; - - let encryption_info = decrypted - .encryption_info - .expect("Decrypted event didn't contain any encryption info"); - - let event_json: Event = serde_json::from_str(decrypted.event.json().get())?; - - Ok(match &encryption_info.algorithm_info { - AlgorithmInfo::MegolmV1AesSha2 { - curve25519_key, - sender_claimed_keys, - forwarding_curve25519_key_chain, - } => DecryptedEvent { - clear_event: serde_json::to_string(&event_json)?, - sender_curve25519_key: curve25519_key.to_owned(), - claimed_ed25519_key: sender_claimed_keys - .get(&DeviceKeyAlgorithm::Ed25519) - .cloned(), - forwarding_curve25519_chain: forwarding_curve25519_key_chain.to_owned(), - }, - }) - } - - /// Request or re-request a room key that was used to encrypt the given - /// event. - /// - /// # Arguments - /// - /// * `event` - The undecryptable event that we would wish to request a room - /// key for. - /// - /// * `room_id` - The id of the room the event was sent to. - pub fn request_room_key( - &self, - event: &str, - room_id: &str, - ) -> Result { - let event: SyncMessageEvent = serde_json::from_str(event)?; - let room_id = Box::::try_from(room_id)?; - - let (cancel, request) = self - .runtime - .block_on(self.inner.request_room_key(&event, &room_id))?; - - let cancellation = cancel.map(|r| r.into()); - let key_request = request.into(); - - Ok(KeyRequestPair { - cancellation, - key_request, - }) - } - - /// Export all of our room keys. - /// - /// # Arguments - /// - /// * `passphrase` - The passphrase that should be used to encrypt the key - /// export. - /// - /// * `rounds` - The number of rounds that should be used when expanding the - /// passphrase into an key. - pub fn export_keys(&self, passphrase: &str, rounds: i32) -> Result { - let keys = self.runtime.block_on(self.inner.export_keys(|_| true))?; - - let encrypted = encrypt_key_export(&keys, passphrase, rounds as u32) - .map_err(CryptoStoreError::Serialization)?; - - Ok(encrypted) - } - - fn import_keys_helper( - &self, - keys: Vec, - from_backup: bool, - progress_listener: Box, - ) -> Result { - let listener = |progress: usize, total: usize| { - progress_listener.on_progress(progress as i32, total as i32) - }; - - let result = self - .runtime - .block_on(self.inner.import_keys(keys, from_backup, listener))?; - - Ok(KeysImportResult { - imported: result.imported_count as i64, - total: result.total_count as i64, - keys: result - .keys - .into_iter() - .map(|(r, m)| { - ( - r.to_string(), - m.into_iter() - .map(|(s, k)| (s, k.into_iter().collect())) - .collect(), - ) - }) - .collect(), - }) - } - - /// Import room keys from the given serialized key export. - /// - /// # Arguments - /// - /// * `keys` - The serialized version of the key export. - /// - /// * `passphrase` - The passphrase that was used to encrypt the key export. - /// - /// * `progress_listener` - A callback that can be used to introspect the - /// progress of the key import. - pub fn import_keys( - &self, - keys: &str, - passphrase: &str, - progress_listener: Box, - ) -> Result { - let keys = Cursor::new(keys); - let keys = decrypt_key_export(keys, passphrase)?; - self.import_keys_helper(keys, false, progress_listener) - } - - /// Import room keys from the given serialized unencrypted key export. - /// - /// This method is the same as [`OlmMachine::import_keys`] but the - /// decryption step is skipped and should be performed by the caller. This - /// should be used if the room keys are comming from the server-side backup, - /// the method will mark all imported room keys as backed up. - /// - /// # Arguments - /// - /// * `keys` - The serialized version of the unencrypted key export. - /// - /// * `progress_listener` - A callback that can be used to introspect the - /// progress of the key import. - pub fn import_decrypted_keys( - &self, - keys: &str, - progress_listener: Box, - ) -> Result { - let keys: Vec = serde_json::from_str(keys)?; - - let keys = keys - .into_iter() - .map(serde_json::from_value) - .filter_map(|k| k.ok()) - .collect(); - - self.import_keys_helper(keys, true, progress_listener) - } - - /// Discard the currently active room key for the given room if there is - /// one. - pub fn discard_room_key(&self, room_id: &str) -> Result<(), CryptoStoreError> { - let room_id = Box::::try_from(room_id)?; - - self.runtime - .block_on(self.inner.invalidate_group_session(&room_id))?; - - Ok(()) - } - - /// Get all the verification requests that we share with the given user. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to fetch the - /// verification requests. - pub fn get_verification_requests(&self, user_id: &str) -> Vec { - let user_id = if let Ok(user_id) = Box::::try_from(user_id) { - user_id - } else { - return vec![]; - }; - - self.inner - .get_verification_requests(&user_id) - .into_iter() - .map(|v| v.into()) - .collect() - } - - /// Get a verification requests that we share with the given user with the - /// given flow id. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to fetch the - /// verification requests. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - pub fn get_verification_request( - &self, - user_id: &str, - flow_id: &str, - ) -> Option { - let user_id = Box::::try_from(user_id).ok()?; - - self.inner - .get_verification_request(&user_id, flow_id) - .map(|v| v.into()) - } - - /// Accept a verification requests that we share with the given user with the - /// given flow id. - /// - /// This will move the verification request into the ready state. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to accept the - /// verification requests. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - /// - /// * `methods` - A list of verification methods that we want to advertise - /// as supported. - pub fn accept_verification_request( - &self, - user_id: &str, - flow_id: &str, - methods: Vec, - ) -> Option { - let user_id = Box::::try_from(user_id).ok()?; - let methods = methods.into_iter().map(VerificationMethod::from).collect(); - - if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { - verification.accept_with_methods(methods).map(|r| r.into()) - } else { - None - } - } - - /// Get an m.key.verification.request content for the given user. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user which we would like to request to - /// verify. - /// - /// * `methods` - The list of verification methods we want to advertise to - /// support. - pub fn verification_request_content( - &self, - user_id: &str, - methods: Vec, - ) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; - - let methods = methods.into_iter().map(VerificationMethod::from).collect(); - - Ok(if let Some(identity) = identity.and_then(|i| i.other()) { - let content = self - .runtime - .block_on(identity.verification_request_content(Some(methods))); - Some(serde_json::to_string(&content)?) - } else { - None - }) - } - - /// Request a verification flow to begin with the given user in the given - /// room. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user which we would like to request to - /// verify. - /// - /// * `room_id` - The ID of the room that represents a DM with the given - /// user. - /// - /// * `event_id` - The event ID of the `m.key.verification.request` event - /// that we sent out to request the verification to begin. The content for - /// this request can be created using the [verification_request_content()] - /// method. - /// - /// * `methods` - The list of verification methods we advertised as - /// supported in the `m.key.verification.request` event. - /// - /// [verification_request_content()]: #method.verification_request_content - pub fn request_verification( - &self, - user_id: &str, - room_id: &str, - event_id: &str, - methods: Vec, - ) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - let event_id = Box::::try_from(event_id)?; - let room_id = Box::::try_from(room_id)?; - - let identity = self.runtime.block_on(self.inner.get_identity(&user_id))?; - - let methods = methods.into_iter().map(VerificationMethod::from).collect(); - - Ok(if let Some(identity) = identity.and_then(|i| i.other()) { - let request = self.runtime.block_on(identity.request_verification( - &room_id, - &event_id, - Some(methods), - )); - - Some(request.into()) - } else { - None - }) - } - - /// Request a verification flow to begin with the given user's device. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user which we would like to request to - /// verify. - /// - /// * `device_id` - The ID of the device that we wish to verify. - /// - /// * `methods` - The list of verification methods we advertised as - /// supported in the `m.key.verification.request` event. - pub fn request_verification_with_device( - &self, - user_id: &str, - device_id: &str, - methods: Vec, - ) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - let methods = methods.into_iter().map(VerificationMethod::from).collect(); - - Ok( - if let Some(device) = self - .runtime - .block_on(self.inner.get_device(&user_id, device_id.into()))? - { - let (verification, request) = self - .runtime - .block_on(device.request_verification_with_methods(methods)); - - Some(RequestVerificationResult { - verification: verification.into(), - request: request.into(), - }) - } else { - None - }, - ) - } - - /// Request a verification flow to begin with our other devices. - /// - /// # Arguments - /// - /// `methods` - The list of verification methods we want to advertise to - /// support. - pub fn request_self_verification( - &self, - methods: Vec, - ) -> Result, CryptoStoreError> { - let identity = self - .runtime - .block_on(self.inner.get_identity(self.inner.user_id()))?; - - let methods = methods.into_iter().map(VerificationMethod::from).collect(); - - Ok(if let Some(identity) = identity.and_then(|i| i.own()) { - let (verification, request) = self - .runtime - .block_on(identity.request_verification_with_methods(methods))?; - Some(RequestVerificationResult { - verification: verification.into(), - request: request.into(), - }) - } else { - None - }) - } - - /// Get a verification flow object for the given user with the given flow id. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to fetch the - /// verification. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - pub fn get_verification(&self, user_id: &str, flow_id: &str) -> Option { - let user_id = Box::::try_from(user_id).ok()?; - - self.inner - .get_verification(&user_id, flow_id) - .map(|v| match v { - RustVerification::SasV1(s) => Verification::SasV1 { sas: s.into() }, - RustVerification::QrV1(qr) => Verification::QrCodeV1 { qrcode: qr.into() }, - }) - } - - /// Cancel a verification for the given user with the given flow id using - /// the given cancel code. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to cancel the - /// verification. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - /// - /// * `cancel_code` - The error code for why the verification was cancelled, - /// manual cancellatio usually happens with `m.user` cancel code. The full - /// list of cancel codes can be found in the [spec] - /// - /// [spec]: https://spec.matrix.org/unstable/client-server-api/#mkeyverificationcancel - pub fn cancel_verification( - &self, - user_id: &str, - flow_id: &str, - cancel_code: &str, - ) -> Option { - let user_id = Box::::try_from(user_id).ok()?; - - if let Some(request) = self.inner.get_verification_request(&user_id, flow_id) { - request.cancel().map(|r| r.into()) - } else if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { - match verification { - RustVerification::SasV1(v) => { - v.cancel_with_code(cancel_code.into()).map(|r| r.into()) - } - RustVerification::QrV1(v) => { - v.cancel_with_code(cancel_code.into()).map(|r| r.into()) - } - } - } else { - None - } - } - - /// Confirm a verification was successful. - /// - /// This method should be called either if a short auth string should be - /// confirmed as matching, or if we want to confirm that the other side has - /// scanned our QR code. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to confirm the - /// verification. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - pub fn confirm_verification( - &self, - user_id: &str, - flow_id: &str, - ) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - Ok( - if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { - match verification { - RustVerification::SasV1(v) => { - let (request, signature_request) = self.runtime.block_on(v.confirm())?; - - request.map(|r| ConfirmVerificationResult { - request: r.into(), - signature_request: signature_request.map(|s| s.into()), - }) - } - RustVerification::QrV1(v) => { - v.confirm_scanning().map(|r| ConfirmVerificationResult { - request: r.into(), - signature_request: None, - }) - } - } - } else { - None - }, - ) - } - - /// Transition from a verification request into QR code verification. - /// - /// This method should be called when one wants to display a QR code so the - /// other side can scan it and move the QR code verification forward. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to start the - /// QR code verification. - /// - /// * `flow_id` - The ID of the verification request that initated the - /// verification flow. - pub fn start_qr_verification( - &self, - user_id: &str, - flow_id: &str, - ) -> Result, CryptoStoreError> { - let user_id = parse_user_id(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) - } - } - - /// Generate data that should be encoded as a QR code. - /// - /// This method should be called right before a QR code should be displayed, - /// the returned data is base64 encoded (without padding) and needs to be - /// decoded on the other side before it can be put through a QR code - /// generator. - /// - /// *Note*: You'll need to call [start_qr_verification()] before calling this - /// method, otherwise `None` will be returned. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to start the - /// QR code verification. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - /// - /// [start_qr_verification()]: #method.start_qr_verification - pub fn generate_qr_code(&self, user_id: &str, flow_id: &str) -> Option { - let user_id = Box::::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(encode).ok())) - } - - /// Pass data from a scanned QR code to an active verification request and - /// transition into QR code verification. - /// - /// This requires an active `VerificationRequest` to succeed, returns `None` - /// if no `VerificationRequest` is found or if the QR code data is invalid. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to start the - /// QR code verification. - /// - /// * `flow_id` - The ID of the verification request that initated the - /// verification flow. - /// - /// * `data` - The data that was extracted from the scanned QR code as an - /// base64 encoded string, without padding. - pub fn scan_qr_code(&self, user_id: &str, flow_id: &str, data: &str) -> Option { - let user_id = Box::::try_from(user_id).ok()?; - let data = decode_config(data, STANDARD_NO_PAD).ok()?; - let data = QrVerificationData::from_bytes(data).ok()?; - - if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { - if let Some(qr) = self - .runtime - .block_on(verification.scan_qr_code(data)) - .ok()? - { - let request = qr.reciprocate()?; - - Some(ScanResult { - qr: qr.into(), - request: request.into(), - }) - } else { - None - } - } else { - None - } - } - - /// Transition from a verification request into short auth string based - /// verification. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to start the - /// SAS verification. - /// - /// * `flow_id` - The ID of the verification request that initated the - /// verification flow. - pub fn start_sas_verification( - &self, - user_id: &str, - flow_id: &str, - ) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - Ok( - if let Some(verification) = self.inner.get_verification_request(&user_id, flow_id) { - self.runtime - .block_on(verification.start_sas())? - .map(|(sas, r)| StartSasResult { - sas: sas.into(), - request: r.into(), - }) - } else { - None - }, - ) - } - - /// Start short auth string verification with a device without going - /// through a verification request first. - /// - /// **Note**: This has been largely deprecated and the - /// [request_verification_with_device()] method should be used instead. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to start the - /// SAS verification. - /// - /// * `device_id` - The ID of device we would like to verify. - /// - /// [request_verification_with_device()]: #method.request_verification_with_device - pub fn start_sas_with_device( - &self, - user_id: &str, - device_id: &str, - ) -> Result, CryptoStoreError> { - let user_id = parse_user_id(user_id)?; - - Ok( - if let Some(device) = self - .runtime - .block_on(self.inner.get_device(&user_id, device_id.into()))? - { - let (sas, request) = self.runtime.block_on(device.start_verification())?; - - Some(StartSasResult { - sas: sas.into(), - request: request.into(), - }) - } else { - None - }, - ) - } - - /// Accept that we're going forward with the short auth string verification. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to accept the - /// SAS verification. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - pub fn accept_sas_verification( - &self, - user_id: &str, - flow_id: &str, - ) -> Option { - let user_id = Box::::try_from(user_id).ok()?; - - self.inner - .get_verification(&user_id, flow_id) - .and_then(|s| s.sas_v1()) - .and_then(|s| s.accept().map(|r| r.into())) - } - - /// Get a list of emoji indices of the emoji representation of the short - /// auth string. - /// - /// *Note*: A SAS verification needs to be started and in the presentable - /// state for this to return the list of emoji indices, otherwise returns - /// `None`. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to get the - /// short auth string. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - pub fn get_emoji_index(&self, user_id: &str, flow_id: &str) -> Option> { - let user_id = Box::::try_from(user_id).ok()?; - - self.inner - .get_verification(&user_id, flow_id) - .and_then(|s| { - s.sas_v1().and_then(|s| { - s.emoji_index() - .map(|v| v.iter().map(|i| (*i).into()).collect()) - }) - }) - } - - /// Get the decimal representation of the short auth string. - /// - /// *Note*: A SAS verification needs to be started and in the presentable - /// state for this to return the list of decimals, otherwise returns - /// `None`. - /// - /// # Arguments - /// - /// * `user_id` - The ID of the user for which we would like to get the - /// short auth string. - /// - /// * `flow_id` - The ID that uniquely identifies the verification flow. - pub fn get_decimals(&self, user_id: &str, flow_id: &str) -> Option> { - let user_id = Box::::try_from(user_id).ok()?; - - self.inner - .get_verification(&user_id, flow_id) - .and_then(|s| { - s.sas_v1().and_then(|s| { - s.decimals() - .map(|v| [v.0.into(), v.1.into(), v.2.into()].to_vec()) - }) - }) - } - - /// Create a new private cross signing identity and create a request to - /// upload the public part of it to the server. - pub fn bootstrap_cross_signing(&self) -> Result { - Ok(self - .runtime - .block_on(self.inner.bootstrap_cross_signing(true))? - .into()) - } - - /// Get the status of the private cross signing keys. - /// - /// This can be used to check which private cross signing keys we have - /// stored locally. - pub fn cross_signing_status(&self) -> CrossSigningStatus { - self.runtime - .block_on(self.inner.cross_signing_status()) - .into() - } - - /// Export all our private cross signing keys. - /// - /// The export will contain the seed for the ed25519 keys as a base64 - /// encoded string. - /// - /// This method returns `None` if we don't have any private cross signing keys. - pub fn export_cross_signing_keys(&self) -> Option { - self.runtime - .block_on(self.inner.export_cross_signing_keys()) - .map(|e| e.into()) - } - - /// Import our private cross signing keys. - /// - /// The export needs to contain the seed for the ed25519 keys as a base64 - /// encoded string. - pub fn import_cross_signing_keys( - &self, - export: CrossSigningKeyExport, - ) -> Result<(), SecretImportError> { - self.runtime - .block_on(self.inner.import_cross_signing_keys(export.into()))?; - - Ok(()) - } - - /// Activate the given backup key to be used with the given backup version. - /// - /// **Warning**: The caller needs to make sure that the given `BackupKey` is - /// trusted, otherwise we might be encrypting room keys that a malicious - /// party could decrypt. - /// - /// The [`OlmMachine::verify_backup`] method can be used to so. - pub fn enable_backup_v1( - &self, - key: MegolmV1BackupKey, - version: String, - ) -> Result<(), DecodeError> { - let backup_key = RustBackupKey::from_base64(&key.public_key)?; - backup_key.set_version(version); - - self.runtime - .block_on(self.inner.backup_machine().enable_backup_v1(backup_key))?; - - Ok(()) - } - - /// Are we able to encrypt room keys. - /// - /// This returns true if we have an active `BackupKey` and backup version - /// registered with the state machine. - pub fn backup_enabled(&self) -> bool { - self.runtime.block_on(self.inner.backup_machine().enabled()) - } - - /// Disable and reset our backup state. - /// - /// This will remove any pending backup request, remove the backup key and - /// reset the backup state of each room key we have. - pub fn disable_backup(&self) -> Result<(), CryptoStoreError> { - Ok(self - .runtime - .block_on(self.inner.backup_machine().disable_backup())?) - } - - /// Encrypt a batch of room keys and return a request that needs to be sent - /// out to backup the room keys. - pub fn backup_room_keys(&self) -> Result, CryptoStoreError> { - let request = self - .runtime - .block_on(self.inner.backup_machine().backup())?; - - let request = request.map(|r| r.into()); - - Ok(request) - } - - /// Get the number of backed up room keys and the total number of room keys. - pub fn room_key_counts(&self) -> Result { - Ok(self - .runtime - .block_on(self.inner.backup_machine().room_key_counts())? - .into()) - } - - /// Store the recovery key in the cryptostore. - /// - /// This is useful if the client wants to support gossiping of the backup - /// key. - pub fn save_recovery_key( - &self, - key: Option, - version: Option, - ) -> Result<(), CryptoStoreError> { - let key = key - .map(|k| RecoveryKey::from_base64(&k)) - .transpose() - .ok() - .flatten(); - Ok(self - .runtime - .block_on(self.inner.backup_machine().save_recovery_key(key, version))?) - } - - /// Get the backup keys we have saved in our crypto store. - pub fn get_backup_keys(&self) -> Result, CryptoStoreError> { - Ok(self - .runtime - .block_on(self.inner.backup_machine().get_backup_keys())? - .try_into() - .ok()) - } - - /// Sign the given message using our device key and if available cross - /// signing master key. - pub fn sign(&self, message: &str) -> HashMap> { - self.runtime - .block_on(self.inner.sign(message)) - .into_iter() - .map(|(k, v)| { - ( - k.to_string(), - v.into_iter().map(|(k, v)| (k.to_string(), v)).collect(), - ) - }) - .collect() - } - - /// Check if the given backup has been verified by us or by another of our - /// devices that we trust. - pub fn verify_backup(&self, auth_data: &str) -> Result { - let auth_data = serde_json::from_str(auth_data)?; - Ok(self - .runtime - .block_on(self.inner.backup_machine().verify_backup(auth_data))?) - } -} diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl deleted file mode 100644 index b93a398233..0000000000 --- a/rust-sdk/src/olm.udl +++ /dev/null @@ -1,426 +0,0 @@ -namespace olm { - void set_logger(Logger logger); -}; - -callback interface Logger { - void log(string log_line); -}; - -callback interface ProgressListener { - void on_progress(i32 progress, i32 total); -}; - -[Error] -enum PkDecryptionError { - "Olm", -}; - -[Error] -enum KeyImportError { - "Export", - "CryptoStore", - "Json", -}; - -[Error] -enum SignatureError { - "Signature", - "Identifier", - "CryptoStore", - "UnknownDevice", - "UnknownUserIdentity", -}; - -[Error] -enum SecretImportError { - "Import", - "CryptoStore", -}; - - -[Error] -enum CryptoStoreError { - "CryptoStore", - "OlmError", - "Serialization", - "Identifier", - "InvalidUserId", -}; - -[Error] -enum DecryptionError { - "Identifier", - "Serialization", - "Megolm", -}; - -dictionary DeviceLists { - sequence changed; - sequence left; -}; - -dictionary KeysImportResult { - i64 imported; - i64 total; - record>> keys; -}; - -dictionary DecryptedEvent { - string clear_event; - string sender_curve25519_key; - string? claimed_ed25519_key; - sequence forwarding_curve25519_chain; -}; - -dictionary Device { - string user_id; - string device_id; - record keys; - sequence algorithms; - string? display_name; - boolean is_blocked; - boolean locally_trusted; - boolean cross_signing_trusted; -}; - -[Enum] -interface UserIdentity { - Own( - string user_id, - boolean trusts_our_own_device, - string master_key, - string self_signing_key, - string user_signing_key - ); - Other( - string user_id, - string master_key, - string self_signing_key - ); -}; - -dictionary CrossSigningStatus { - boolean has_master; - boolean has_self_signing; - boolean has_user_signing; -}; - -dictionary CrossSigningKeyExport { - string? master_key; - string? self_signing_key; - string? user_signing_key; -}; - -dictionary UploadSigningKeysRequest { - string master_key; - string self_signing_key; - string user_signing_key; -}; - -dictionary BootstrapCrossSigningResult { - UploadSigningKeysRequest upload_signing_keys_request; - SignatureUploadRequest signature_request; -}; - -dictionary CancelInfo { - string cancel_code; - string reason; - boolean cancelled_by_us; -}; - -dictionary StartSasResult { - Sas sas; - OutgoingVerificationRequest request; -}; - -dictionary Sas { - string other_user_id; - string other_device_id; - string flow_id; - string? room_id; - boolean we_started; - boolean has_been_accepted; - boolean can_be_presented; - boolean supports_emoji; - boolean have_we_confirmed; - boolean is_done; - boolean is_cancelled; - CancelInfo? cancel_info; -}; - -dictionary ScanResult { - QrCode qr; - OutgoingVerificationRequest request; -}; - -dictionary QrCode { - string other_user_id; - string other_device_id; - string flow_id; - string? room_id; - boolean we_started; - boolean other_side_scanned; - boolean has_been_confirmed; - boolean reciprocated; - boolean is_done; - boolean is_cancelled; - CancelInfo? cancel_info; -}; - -dictionary VerificationRequest { - string other_user_id; - string? other_device_id; - string flow_id; - string? room_id; - boolean we_started; - boolean is_ready; - boolean is_passive; - boolean is_done; - boolean is_cancelled; - CancelInfo? cancel_info; - sequence? their_methods; - sequence? our_methods; - -}; - -dictionary RequestVerificationResult { - VerificationRequest verification; - OutgoingVerificationRequest request; -}; - -dictionary ConfirmVerificationResult { - OutgoingVerificationRequest request; - SignatureUploadRequest? signature_request; -}; - -[Enum] -interface Verification { - SasV1(Sas sas); - QrCodeV1(QrCode qrcode); -}; - -dictionary KeyRequestPair { - Request? cancellation; - 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); - KeysUpload(string request_id, string body); - KeysQuery(string request_id, sequence users); - KeysClaim(string request_id, record> one_time_keys); - KeysBackup(string request_id, string version, string rooms); - RoomMessage(string request_id, string room_id, string event_type, string content); - SignatureUpload(string request_id, string body); -}; - -dictionary SignatureUploadRequest { - string body; -}; - -enum RequestType { - "KeysQuery", - "KeysClaim", - "KeysUpload", - "ToDevice", - "SignatureUpload", - "KeysBackup", -}; - -interface OlmMachine { - [Throws=CryptoStoreError] - constructor([ByRef] string user_id, [ByRef] string device_id, [ByRef] string path); - - record identity_keys(); - string user_id(); - string device_id(); - - [Throws=CryptoStoreError] - string receive_sync_changes([ByRef] string events, - DeviceLists device_changes, - record key_counts, - sequence? unused_fallback_keys); - [Throws=CryptoStoreError] - sequence outgoing_requests(); - [Throws=CryptoStoreError] - void mark_request_as_sent( - [ByRef] string request_id, - RequestType request_type, - [ByRef] string response - ); - - [Throws=DecryptionError] - DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id); - [Throws=CryptoStoreError] - string encrypt([ByRef] string room_id, [ByRef] string event_type, [ByRef] string content); - - [Throws=CryptoStoreError] - UserIdentity? get_identity([ByRef] string user_id); - [Throws=SignatureError] - SignatureUploadRequest verify_identity([ByRef] string user_id); - [Throws=CryptoStoreError] - Device? get_device([ByRef] string user_id, [ByRef] string device_id); - [Throws=CryptoStoreError] - void mark_device_as_trusted([ByRef] string user_id, [ByRef] string device_id); - [Throws=SignatureError] - SignatureUploadRequest verify_device([ByRef] string user_id, [ByRef] string device_id); - [Throws=CryptoStoreError] - sequence get_user_devices([ByRef] string user_id); - - [Throws=CryptoStoreError] - boolean is_user_tracked([ByRef] string user_id); - void update_tracked_users(sequence users); - [Throws=CryptoStoreError] - Request? get_missing_sessions(sequence users); - [Throws=CryptoStoreError] - sequence share_room_key([ByRef] string room_id, sequence users); - - sequence get_verification_requests([ByRef] string user_id); - VerificationRequest? get_verification_request([ByRef] string user_id, [ByRef] string flow_id); - Verification? get_verification([ByRef] string user_id, [ByRef] string flow_id); - - [Throws=CryptoStoreError] - VerificationRequest? request_verification( - [ByRef] string user_id, - [ByRef] string room_id, - [ByRef] string event_id, - sequence methods - ); - [Throws=CryptoStoreError] - string? verification_request_content( - [ByRef] string user_id, - sequence methods - ); - [Throws=CryptoStoreError] - RequestVerificationResult? request_self_verification(sequence methods); - [Throws=CryptoStoreError] - RequestVerificationResult? request_verification_with_device( - [ByRef] string user_id, - [ByRef] string device_id, - sequence methods - ); - - OutgoingVerificationRequest? accept_verification_request( - [ByRef] string user_id, - [ByRef] string flow_id, - sequence methods - ); - - [Throws=CryptoStoreError] - ConfirmVerificationResult? confirm_verification([ByRef] string user_id, [ByRef] string flow_id); - OutgoingVerificationRequest? cancel_verification( - [ByRef] string user_id, - [ByRef] string flow_id, - [ByRef] string cancel_code - ); - - [Throws=CryptoStoreError] - StartSasResult? start_sas_with_device([ByRef] string user_id, [ByRef] string device_id); - [Throws=CryptoStoreError] - StartSasResult? start_sas_verification([ByRef] string user_id, [ByRef] string flow_id); - OutgoingVerificationRequest? accept_sas_verification([ByRef] string user_id, [ByRef] string flow_id); - sequence? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id); - sequence? get_decimals([ByRef] string user_id, [ByRef] string flow_id); - - [Throws=CryptoStoreError] - QrCode? start_qr_verification([ByRef] string user_id, [ByRef] string flow_id); - ScanResult? scan_qr_code([ByRef] string user_id, [ByRef] string flow_id, [ByRef] string data); - string? generate_qr_code([ByRef] string user_id, [ByRef] string flow_id); - - [Throws=DecryptionError] - KeyRequestPair request_room_key([ByRef] string event, [ByRef] string room_id); - - [Throws=CryptoStoreError] - string export_keys([ByRef] string passphrase, i32 rounds); - [Throws=KeyImportError] - KeysImportResult import_keys( - [ByRef] string keys, - [ByRef] string passphrase, - ProgressListener progress_listener - ); - [Throws=KeyImportError] - KeysImportResult import_decrypted_keys( - [ByRef] string keys, - ProgressListener progress_listener - ); - [Throws=CryptoStoreError] - void discard_room_key([ByRef] string room_id); - - CrossSigningStatus cross_signing_status(); - [Throws=CryptoStoreError] - BootstrapCrossSigningResult bootstrap_cross_signing(); - CrossSigningKeyExport? export_cross_signing_keys(); - [Throws=SecretImportError] - void import_cross_signing_keys(CrossSigningKeyExport export); - [Throws=CryptoStoreError] - boolean is_identity_verified([ByRef] string user_id); - - record> sign([ByRef] string message); - [Throws=DecodeError] - void enable_backup_v1(MegolmV1BackupKey key, string version); - [Throws=CryptoStoreError] - void disable_backup(); - [Throws=CryptoStoreError] - Request? backup_room_keys(); - [Throws=CryptoStoreError] - void save_recovery_key(string? key, string? version); - [Throws=CryptoStoreError] - RoomKeyCounts room_key_counts(); - [Throws=CryptoStoreError] - BackupKeys? get_backup_keys(); - boolean backup_enabled(); - [Throws=CryptoStoreError] - boolean verify_backup([ByRef] string auth_data); -}; - -dictionary PassphraseInfo { - string private_key_salt; - i32 private_key_iterations; -}; - -dictionary MegolmV1BackupKey { - string public_key; - record> signatures; - PassphraseInfo? passphrase_info; - string backup_algorithm; -}; - -dictionary BackupKeys { - string recovery_key; - string backup_version; -}; - -dictionary RoomKeyCounts { - i64 total; - i64 backed_up; -}; - -[Error] -enum DecodeError { - "Decode", - "CryptoStore", -}; - -interface BackupRecoveryKey { - constructor(); - [Name=from_passphrase] - constructor(string passphrase, string salt, i32 rounds); - [Name=new_from_passphrase] - constructor(string passphrase); - [Name=from_base64, Throws=DecodeError] - constructor(string key); - [Name=from_base58, Throws=DecodeError] - constructor(string key); - string to_base58(); - string to_base64(); - MegolmV1BackupKey megolm_v1_public_key(); - [Throws=PkDecryptionError] - string decrypt_v1(string ephemeral_key, string mac, string ciphertext); -}; diff --git a/rust-sdk/src/responses.rs b/rust-sdk/src/responses.rs deleted file mode 100644 index 9901c7114f..0000000000 --- a/rust-sdk/src/responses.rs +++ /dev/null @@ -1,365 +0,0 @@ -#![allow(missing_docs)] - -use std::{collections::HashMap, convert::TryFrom}; - -use http::Response; -use matrix_sdk_common::uuid::Uuid; -use serde_json::json; - -use ruma::{ - api::client::r0::{ - backup::add_backup_keys::Response as KeysBackupResponse, - keys::{ - claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse}, - get_keys::Response as KeysQueryResponse, - upload_keys::Response as KeysUploadResponse, - upload_signatures::{ - Request as RustSignatureUploadRequest, Response as SignatureUploadResponse, - }, - }, - sync::sync_events::DeviceLists as RumaDeviceLists, - to_device::send_event_to_device::Response as ToDeviceResponse, - }, - assign, - events::EventContent, - identifiers::UserId, -}; - -use matrix_sdk_crypto::{ - IncomingResponse, OutgoingRequest, OutgoingVerificationRequest as SdkVerificationRequest, - RoomMessageRequest, ToDeviceRequest, UploadSigningKeysRequest as RustUploadSigningKeysRequest, -}; - -pub struct SignatureUploadRequest { - pub body: String, -} - -impl From for SignatureUploadRequest { - fn from(r: RustSignatureUploadRequest) -> Self { - Self { - body: serde_json::to_string(&r.signed_keys) - .expect("Can't serialize signature upload request"), - } - } -} - -pub struct UploadSigningKeysRequest { - pub master_key: String, - pub self_signing_key: String, - pub user_signing_key: String, -} - -impl From for UploadSigningKeysRequest { - fn from(r: RustUploadSigningKeysRequest) -> Self { - Self { - master_key: serde_json::to_string( - &r.master_key.expect("Request didn't contain a master key"), - ) - .expect("Can't serialize cross signing master key"), - self_signing_key: serde_json::to_string( - &r.self_signing_key - .expect("Request didn't contain a self-signing key"), - ) - .expect("Can't serialize cross signing self-signing key"), - user_signing_key: serde_json::to_string( - &r.user_signing_key - .expect("Request didn't contain a user-signing key"), - ) - .expect("Can't serialize cross signing user-signing key"), - } - } -} - -pub struct BootstrapCrossSigningResult { - pub upload_signing_keys_request: UploadSigningKeysRequest, - pub signature_request: SignatureUploadRequest, -} - -impl From<(RustUploadSigningKeysRequest, RustSignatureUploadRequest)> - for BootstrapCrossSigningResult -{ - fn from(requests: (RustUploadSigningKeysRequest, RustSignatureUploadRequest)) -> Self { - Self { - upload_signing_keys_request: requests.0.into(), - signature_request: requests.1.into(), - } - } -} - -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 for OutgoingVerificationRequest { - fn from(r: SdkVerificationRequest) -> Self { - match r { - SdkVerificationRequest::ToDevice(r) => r.into(), - 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(), - }, - } - } -} - -impl From for OutgoingVerificationRequest { - fn from(r: ToDeviceRequest) -> Self { - 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"), - } - } -} - -#[derive(Debug)] -pub enum Request { - ToDevice { - request_id: String, - event_type: String, - body: String, - }, - KeysUpload { - request_id: String, - body: String, - }, - KeysQuery { - request_id: String, - users: Vec, - }, - KeysClaim { - request_id: String, - one_time_keys: HashMap>, - }, - RoomMessage { - request_id: String, - room_id: String, - event_type: String, - content: String, - }, - SignatureUpload { - request_id: String, - body: String, - }, - KeysBackup { - request_id: String, - version: String, - rooms: String, - }, -} - -impl From for Request { - fn from(r: OutgoingRequest) -> Self { - use matrix_sdk_crypto::OutgoingRequests::*; - - match r.request() { - KeysUpload(u) => { - let body = json!({ - "device_keys": u.device_keys, - "one_time_keys": u.one_time_keys, - }); - - Request::KeysUpload { - request_id: r.request_id().to_string(), - body: serde_json::to_string(&body) - .expect("Can't serialize keys upload request"), - } - } - KeysQuery(k) => { - let users: Vec = k.device_keys.keys().map(|u| u.to_string()).collect(); - Request::KeysQuery { - request_id: r.request_id().to_string(), - users, - } - } - ToDeviceRequest(t) => Request::from(t), - SignatureUpload(t) => Request::SignatureUpload { - request_id: r.request_id().to_string(), - body: serde_json::to_string(&t.signed_keys) - .expect("Can't serialize signature upload request"), - }, - RoomMessage(r) => Request::from(r), - KeysClaim(c) => (*r.request_id(), c.clone()).into(), - KeysBackup(b) => Request::KeysBackup { - request_id: r.request_id().to_string(), - version: b.version.to_owned(), - rooms: serde_json::to_string(&b.rooms) - .expect("Can't serialize keys backup request"), - }, - } - } -} - -impl From for Request { - fn from(r: ToDeviceRequest) -> Self { - Request::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"), - } - } -} - -impl From<(Uuid, KeysClaimRequest)> for Request { - fn from(request_tuple: (Uuid, KeysClaimRequest)) -> Self { - let (request_id, request) = request_tuple; - - Request::KeysClaim { - request_id: request_id.to_string(), - one_time_keys: request - .one_time_keys - .into_iter() - .map(|(u, d)| { - ( - u.to_string(), - d.into_iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect(), - ) - }) - .collect(), - } - } -} - -impl From<&ToDeviceRequest> for Request { - fn from(r: &ToDeviceRequest) -> Self { - Request::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"), - } - } -} - -impl From<&RoomMessageRequest> for Request { - fn from(r: &RoomMessageRequest) -> Self { - Self::RoomMessage { - request_id: r.txn_id.to_string(), - room_id: r.room_id.to_string(), - event_type: r.content.event_type().to_string(), - content: serde_json::to_string(&r.content).expect("Can't serialize message content"), - } - } -} - -pub(crate) fn response_from_string(body: &str) -> Response> { - Response::builder() - .status(200) - .body(body.as_bytes().to_vec()) - .expect("Can't create HTTP response") -} - -pub enum RequestType { - KeysQuery, - KeysClaim, - KeysUpload, - ToDevice, - SignatureUpload, - KeysBackup, -} - -pub struct DeviceLists { - pub changed: Vec, - pub left: Vec, -} - -impl From for RumaDeviceLists { - fn from(d: DeviceLists) -> Self { - assign!(RumaDeviceLists::new(), { - changed: d - .changed - .into_iter() - .filter_map(|u| Box::::try_from(u).ok()) - .collect(), - left: d - .left - .into_iter() - .filter_map(|u| Box::::try_from(u).ok()) - .collect(), - }) - } -} - -pub struct KeysImportResult { - /// The number of room keys that were imported. - pub imported: i64, - /// The total number of room keys that were found in the export. - pub total: i64, - /// The map of keys that were imported. - /// - /// It's a map from room id to a map of the sender key to a list of session - /// ids. - pub keys: HashMap>>, -} - -pub(crate) enum OwnedResponse { - KeysClaim(KeysClaimResponse), - KeysUpload(KeysUploadResponse), - KeysQuery(KeysQueryResponse), - ToDevice(ToDeviceResponse), - SignatureUpload(SignatureUploadResponse), - KeysBackup(KeysBackupResponse), -} - -impl From for OwnedResponse { - fn from(response: KeysClaimResponse) -> Self { - OwnedResponse::KeysClaim(response) - } -} - -impl From for OwnedResponse { - fn from(response: KeysQueryResponse) -> Self { - OwnedResponse::KeysQuery(response) - } -} - -impl From for OwnedResponse { - fn from(response: KeysUploadResponse) -> Self { - OwnedResponse::KeysUpload(response) - } -} - -impl From for OwnedResponse { - fn from(response: ToDeviceResponse) -> Self { - OwnedResponse::ToDevice(response) - } -} - -impl From for OwnedResponse { - fn from(response: SignatureUploadResponse) -> Self { - Self::SignatureUpload(response) - } -} - -impl From for OwnedResponse { - fn from(r: KeysBackupResponse) -> Self { - Self::KeysBackup(r) - } -} - -impl<'a> From<&'a OwnedResponse> for IncomingResponse<'a> { - fn from(r: &'a OwnedResponse) -> Self { - match r { - OwnedResponse::KeysClaim(r) => IncomingResponse::KeysClaim(r), - OwnedResponse::KeysQuery(r) => IncomingResponse::KeysQuery(r), - OwnedResponse::KeysUpload(r) => IncomingResponse::KeysUpload(r), - OwnedResponse::ToDevice(r) => IncomingResponse::ToDevice(r), - OwnedResponse::SignatureUpload(r) => IncomingResponse::SignatureUpload(r), - OwnedResponse::KeysBackup(r) => IncomingResponse::KeysBackup(r), - } - } -} diff --git a/rust-sdk/src/users.rs b/rust-sdk/src/users.rs deleted file mode 100644 index 4c1a05a55a..0000000000 --- a/rust-sdk/src/users.rs +++ /dev/null @@ -1,61 +0,0 @@ -use matrix_sdk_crypto::UserIdentities; -use ruma::encryption::CrossSigningKey; - -use crate::CryptoStoreError; - -/// Enum representing cross signing identities of our own user or some other -/// user. -pub enum UserIdentity { - /// Our own user identity. - Own { - /// The unique id of our own user. - user_id: String, - /// Does our own user identity trust our own device. - trusts_our_own_device: bool, - /// The public master key of our identity. - master_key: String, - /// The public user-signing key of our identity. - user_signing_key: String, - /// The public self-signing key of our identity. - self_signing_key: String, - }, - /// The user identity of other users. - Other { - /// The unique id of the user. - user_id: String, - /// The public master key of the identity. - master_key: String, - /// The public self-signing key of our identity. - self_signing_key: String, - }, -} - -impl UserIdentity { - pub(crate) async fn from_rust(i: UserIdentities) -> Result { - Ok(match i { - UserIdentities::Own(i) => { - let master: CrossSigningKey = i.master_key().to_owned().into(); - let user_signing: CrossSigningKey = i.user_signing_key().to_owned().into(); - let self_signing: CrossSigningKey = i.self_signing_key().to_owned().into(); - - UserIdentity::Own { - user_id: i.user_id().to_string(), - trusts_our_own_device: i.trusts_our_own_device().await?, - master_key: serde_json::to_string(&master)?, - user_signing_key: serde_json::to_string(&user_signing)?, - self_signing_key: serde_json::to_string(&self_signing)?, - } - } - UserIdentities::Other(i) => { - let master: CrossSigningKey = i.master_key().to_owned().into(); - let self_signing: CrossSigningKey = i.self_signing_key().to_owned().into(); - - UserIdentity::Other { - user_id: i.user_id().to_string(), - master_key: serde_json::to_string(&master)?, - self_signing_key: serde_json::to_string(&self_signing)?, - } - } - }) - } -} diff --git a/rust-sdk/src/verification.rs b/rust-sdk/src/verification.rs deleted file mode 100644 index 13d7204d92..0000000000 --- a/rust-sdk/src/verification.rs +++ /dev/null @@ -1,232 +0,0 @@ -use matrix_sdk_crypto::{ - CancelInfo as RustCancelInfo, QrVerification as InnerQr, Sas as InnerSas, - VerificationRequest as InnerVerificationRequest, -}; - -use crate::{OutgoingVerificationRequest, SignatureUploadRequest}; - -/// Enum representing the different verification flows we support. -pub enum Verification { - /// The `m.sas.v1` verification flow. - SasV1 { - #[allow(missing_docs)] - sas: Sas, - }, - /// The `m.qr_code.scan.v1`, `m.qr_code.show.v1`, and `m.reciprocate.v1` - /// verification flow. - QrCodeV1 { - #[allow(missing_docs)] - qrcode: QrCode, - }, -} - -/// The `m.sas.v1` verification flow. -pub struct Sas { - /// The other user that is participating in the verification flow - pub other_user_id: String, - /// The other user's device that is participating in the verification flow - pub other_device_id: String, - /// The unique ID of this verification flow, will be a random string for - /// to-device events or a event ID for in-room events. - pub flow_id: String, - /// The room ID where this verification is happening, will be `None` if the - /// verification is going through to-device messages - pub room_id: Option, - /// Did we initiate the verification flow - pub we_started: bool, - /// Has the non-initiating side accepted the verification flow - pub has_been_accepted: bool, - /// Can the short auth string be presented - pub can_be_presented: bool, - /// Does the flow support the emoji representation of the short auth string - pub supports_emoji: bool, - /// Have we confirmed that the short auth strings match - pub have_we_confirmed: bool, - /// Has the verification completed successfully - pub is_done: bool, - /// Has the flow been cancelled - pub is_cancelled: bool, - /// Information about the cancellation of the flow, will be `None` if the - /// flow hasn't been cancelled - pub cancel_info: Option, -} - -/// The `m.qr_code.scan.v1`, `m.qr_code.show.v1`, and `m.reciprocate.v1` -/// verification flow. -pub struct QrCode { - /// The other user that is participating in the verification flow - pub other_user_id: String, - /// The other user's device that is participating in the verification flow - pub other_device_id: String, - /// The unique ID of this verification flow, will be a random string for - /// to-device events or a event ID for in-room events. - pub flow_id: String, - /// The room ID where this verification is happening, will be `None` if the - /// verification is going through to-device messages - pub room_id: Option, - /// Did we initiate the verification flow - pub we_started: bool, - /// Has the QR code been scanned by the other side - pub other_side_scanned: bool, - /// Has the scanning of the QR code been confirmed by us - pub has_been_confirmed: bool, - /// Did we scan the QR code and sent out a reciprocation - pub reciprocated: bool, - /// Has the verification completed successfully - pub is_done: bool, - /// Has the flow been cancelled - pub is_cancelled: bool, - /// Information about the cancellation of the flow, will be `None` if the - /// flow hasn't been cancelled - pub cancel_info: Option, -} - -impl From 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_info: qr.cancel_info().map(|c| c.into()), - reciprocated: qr.reciprocated(), - we_started: qr.we_started(), - other_side_scanned: qr.has_been_scanned(), - has_been_confirmed: qr.has_been_confirmed(), - other_device_id: qr.other_device_id().to_string(), - room_id: qr.room_id().map(|r| r.to_string()), - } - } -} - -/// Information on why a verification flow has been cancelled and by whom. -pub struct CancelInfo { - /// The textual representation of the cancel reason - pub reason: String, - /// The code describing the cancel reason - pub cancel_code: String, - /// Was the verification flow cancelled by us - pub cancelled_by_us: bool, -} - -impl From for CancelInfo { - fn from(c: RustCancelInfo) -> Self { - Self { - reason: c.reason().to_owned(), - cancel_code: c.cancel_code().to_string(), - cancelled_by_us: c.cancelled_by_us(), - } - } -} - -/// A result type for starting SAS verifications. -pub struct StartSasResult { - /// The SAS verification object that got created. - pub sas: Sas, - /// The request that needs to be sent out to notify the other side that a - /// SAS verification should start. - pub request: OutgoingVerificationRequest, -} - -/// A result type for scanning QR codes. -pub struct ScanResult { - /// The QR code verification object that got created. - pub qr: QrCode, - /// The request that needs to be sent out to notify the other side that a - /// QR code verification should start. - pub request: OutgoingVerificationRequest, -} - -impl From for Sas { - fn from(sas: InnerSas) -> Self { - Self { - other_user_id: sas.other_user_id().to_string(), - other_device_id: sas.other_device_id().to_string(), - flow_id: sas.flow_id().as_str().to_owned(), - is_cancelled: sas.is_cancelled(), - is_done: sas.is_done(), - can_be_presented: sas.can_be_presented(), - supports_emoji: sas.supports_emoji(), - have_we_confirmed: sas.have_we_confirmed(), - we_started: sas.we_started(), - room_id: sas.room_id().map(|r| r.to_string()), - has_been_accepted: sas.has_been_accepted(), - cancel_info: sas.cancel_info().map(|c| c.into()), - } - } -} - -/// A result type for requesting verifications. -pub struct RequestVerificationResult { - /// The verification request object that got created. - pub verification: VerificationRequest, - /// The request that needs to be sent out to notify the other side that - /// we're requesting verification to begin. - pub request: OutgoingVerificationRequest, -} - -/// A result type for confirming verifications. -pub struct ConfirmVerificationResult { - /// The request that needs to be sent out to notify the other side that we - /// confirmed the verification. - pub request: OutgoingVerificationRequest, - /// A request that will upload signatures of the verified device or user, if - /// the verification is completed and we're able to sign devices or users - pub signature_request: Option, -} - -/// The verificatoin request object which then can transition into some concrete -/// verification method -pub struct VerificationRequest { - /// The other user that is participating in the verification flow - pub other_user_id: String, - /// The other user's device that is participating in the verification flow - pub other_device_id: Option, - /// The unique ID of this verification flow, will be a random string for - /// to-device events or a event ID for in-room events. - pub flow_id: String, - /// The room ID where this verification is happening, will be `None` if the - /// verification is going through to-device messages - pub room_id: Option, - /// Did we initiate the verification flow - pub we_started: bool, - /// Did both parties aggree to verification - pub is_ready: bool, - /// Did another device respond to the verification request - pub is_passive: bool, - /// Has the verification completed successfully - pub is_done: bool, - /// Has the flow been cancelled - pub is_cancelled: bool, - /// The list of verification methods that the other side advertised as - /// supported - pub their_methods: Option>, - /// The list of verification methods that we advertised as supported - pub our_methods: Option>, - /// Information about the cancellation of the flow, will be `None` if the - /// flow hasn't been cancelled - pub cancel_info: Option, -} - -impl From for VerificationRequest { - fn from(v: InnerVerificationRequest) -> Self { - Self { - other_user_id: v.other_user().to_string(), - other_device_id: v.other_device_id().map(|d| d.to_string()), - flow_id: v.flow_id().as_str().to_owned(), - is_cancelled: v.is_cancelled(), - is_done: v.is_done(), - is_ready: v.is_ready(), - room_id: v.room_id().map(|r| r.to_string()), - we_started: v.we_started(), - is_passive: v.is_passive(), - cancel_info: v.cancel_info().map(|c| c.into()), - their_methods: v - .their_supported_methods() - .map(|v| v.into_iter().map(|m| m.to_string()).collect()), - our_methods: v - .our_supported_methods() - .map(|v| v.into_iter().map(|m| m.to_string()).collect()), - } - } -} From 0590258d541bc0fc1e4c3b07900898860a5b35df Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 29 Mar 2022 17:51:05 +0200 Subject: [PATCH 211/252] Suspend API: handle verification service --- .../verification/VerificationService.kt | 18 +- .../verification/RustVerificationService.kt | 67 +++---- .../quads/SharedSecureStorageViewModel.kt | 8 +- .../IncomingVerificationRequestHandler.kt | 17 +- .../VerificationBottomSheetViewModel.kt | 173 +++++++++--------- .../home/room/detail/TimelineViewModel.kt | 28 +-- .../features/navigation/DefaultNavigator.kt | 65 ++++--- .../devices/DeviceListBottomSheetViewModel.kt | 11 +- .../settings/devices/DevicesViewModel.kt | 16 +- 9 files changed, 214 insertions(+), 189 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt index b9d0c0ad2c..41ba0b8b4e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt @@ -36,7 +36,7 @@ interface VerificationService { /** * Mark this device as verified manually */ - fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) + suspend fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) fun getExistingTransaction(otherUserId: String, tid: String): VerificationTransaction? @@ -46,7 +46,7 @@ interface VerificationService { fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest? - fun beginKeyVerification(method: VerificationMethod, + suspend fun beginKeyVerification(method: VerificationMethod, otherUserId: String, otherDeviceId: String, transactionId: String?): String? @@ -54,27 +54,27 @@ interface VerificationService { /** * Request key verification with another user via room events (instead of the to-device API) */ - fun requestKeyVerificationInDMs(methods: List, + suspend fun requestKeyVerificationInDMs(methods: List, otherUserId: String, roomId: String, localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest - fun cancelVerificationRequest(request: PendingVerificationRequest) + suspend fun cancelVerificationRequest(request: PendingVerificationRequest) /** * Request a key verification from another user using toDevice events. */ - fun requestKeyVerification(methods: List, + suspend fun requestKeyVerification(methods: List, otherUserId: String, otherDevices: List?): PendingVerificationRequest - fun declineVerificationRequestInDMs(otherUserId: String, + suspend fun declineVerificationRequestInDMs(otherUserId: String, transactionId: String, roomId: String) // Only SAS method is supported for the moment // TODO Parameter otherDeviceId should be removed in this case - fun beginKeyVerificationInDMs(method: VerificationMethod, + suspend fun beginKeyVerificationInDMs(method: VerificationMethod, transactionId: String, roomId: String, otherUserId: String, @@ -83,7 +83,7 @@ interface VerificationService { /** * Returns false if the request is unknown */ - fun readyPendingVerificationInDMs(methods: List, + suspend fun readyPendingVerificationInDMs(methods: List, otherUserId: String, roomId: String, transactionId: String): Boolean @@ -91,7 +91,7 @@ interface VerificationService { /** * Returns false if the request is unknown */ - fun readyPendingVerification(methods: List, + suspend fun readyPendingVerification(methods: List, otherUserId: String, transactionId: String): Boolean diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 262342b054..01087dfaed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.crypto.verification import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService @@ -162,12 +161,10 @@ internal class RustVerificationService @Inject constructor(private val olmMachin this.dispatcher.removeListener(listener) } - override fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { + override suspend fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { // TODO this doesn't seem to be used anymore? - runBlocking { - val device = olmMachine.getDevice(userId, deviceID) - device?.markAsTrusted() - } + val device = olmMachine.getDevice(userId, deviceID) + device?.markAsTrusted() } override fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event) { @@ -224,13 +221,13 @@ internal class RustVerificationService @Inject constructor(private val olmMachin return null } - override fun requestKeyVerification( + override suspend fun requestKeyVerification( methods: List, otherUserId: String, otherDevices: List? ): PendingVerificationRequest { - val verification = when (val identity = runBlocking { olmMachine.getIdentity(otherUserId) }) { - is OwnUserIdentity -> runBlocking { identity.requestVerification(methods) } + val verification = when (val identity = olmMachine.getIdentity(otherUserId)) { + is OwnUserIdentity -> identity.requestVerification(methods) is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices") null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user") } @@ -238,15 +235,15 @@ internal class RustVerificationService @Inject constructor(private val olmMachin return verification.toPendingVerificationRequest() } - override fun requestKeyVerificationInDMs( + override suspend fun requestKeyVerificationInDMs( methods: List, otherUserId: String, roomId: String, localId: String? ): PendingVerificationRequest { Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") - val verification = when (val identity = runBlocking { olmMachine.getIdentity(otherUserId) }) { - is UserIdentity -> runBlocking { identity.requestVerification(methods, roomId, localId!!) } + val verification = when (val identity = olmMachine.getIdentity(otherUserId)) { + is UserIdentity -> identity.requestVerification(methods, roomId, localId!!) is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user") null -> throw IllegalArgumentException("The user that we wish to verify doesn't support cross signing") } @@ -254,7 +251,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin return verification.toPendingVerificationRequest() } - override fun readyPendingVerification( + override suspend fun readyPendingVerification( methods: List, otherUserId: String, transactionId: String @@ -262,7 +259,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) return if (request != null) { - runBlocking { request.acceptWithMethods(methods) } + request.acceptWithMethods(methods) if (request.isReady()) { val qrcode = request.startQrVerification() @@ -280,7 +277,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin } } - override fun readyPendingVerificationInDMs( + override suspend fun readyPendingVerificationInDMs( methods: List, otherUserId: String, roomId: String, @@ -289,7 +286,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin return readyPendingVerification(methods, otherUserId, transactionId) } - override fun beginKeyVerification( + override suspend fun beginKeyVerification( method: VerificationMethod, otherUserId: String, otherDeviceId: String, @@ -299,15 +296,13 @@ internal class RustVerificationService @Inject constructor(private val olmMachin if (transactionId != null) { val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) - runBlocking { - val sas = request?.startSasVerification() + val sas = request?.startSasVerification() - if (sas != null) { - dispatcher.dispatchTxAdded(sas) - sas.transactionId - } else { - null - } + if (sas != null) { + dispatcher.dispatchTxAdded(sas) + sas.transactionId + } else { + null } } else { // This starts the short SAS flow, the one that doesn't start with @@ -315,14 +310,12 @@ internal class RustVerificationService @Inject constructor(private val olmMachin // be wise do do so as well // DeviceListBottomSheetViewModel triggers this, interestingly the method that // triggers this is called `manuallyVerify()` - runBlocking { - val verification = olmMachine.getDevice(otherUserId, otherDeviceId)?.startVerification() - if (verification != null) { - dispatcher.dispatchTxAdded(verification) - verification.transactionId - } else { - null - } + val verification = olmMachine.getDevice(otherUserId, otherDeviceId)?.startVerification() + if (verification != null) { + dispatcher.dispatchTxAdded(verification) + verification.transactionId + } else { + null } } } else { @@ -330,7 +323,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin } } - override fun beginKeyVerificationInDMs( + override suspend fun beginKeyVerificationInDMs( method: VerificationMethod, transactionId: String, roomId: String, @@ -343,19 +336,19 @@ internal class RustVerificationService @Inject constructor(private val olmMachin return transactionId } - override fun cancelVerificationRequest(request: PendingVerificationRequest) { + override suspend fun cancelVerificationRequest(request: PendingVerificationRequest) { val verificationRequest = request.transactionId?.let { this.olmMachine.getVerificationRequest(request.otherUserId, it) } - runBlocking { verificationRequest?.cancel() } + verificationRequest?.cancel() } - override fun declineVerificationRequestInDMs( + override suspend fun declineVerificationRequestInDMs( otherUserId: String, transactionId: String, roomId: String ) { val verificationRequest = this.olmMachine.getVerificationRequest(otherUserId, transactionId) - runBlocking { verificationRequest?.cancel() } + verificationRequest?.cancel() } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt index 8994ad901b..7197385deb 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt @@ -149,10 +149,12 @@ class SharedSecureStorageViewModel @AssistedInject constructor( // as we are going to reset, we'd better cancel all outgoing requests // if not they could be accepted in the middle of the reset process // and cause strange use cases - session.cryptoService().verificationService().getExistingVerificationRequests(session.myUserId).forEach { - session.cryptoService().verificationService().cancelVerificationRequest(it) + viewModelScope.launch { + session.cryptoService().verificationService().getExistingVerificationRequests(session.myUserId).forEach { + session.cryptoService().verificationService().cancelVerificationRequest(it) + } + _viewEvents.post(SharedSecureStorageViewEvent.ShowResetBottomSheet) } - _viewEvents.post(SharedSecureStorageViewEvent.ShowResetBottomSheet) } private fun handleResetAll() { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt index 3a3f1054f1..aa97d5e078 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt @@ -24,6 +24,8 @@ import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.arguments.TimelineArgs import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.popup.VerificationVectorAlert +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationService @@ -42,7 +44,8 @@ import javax.inject.Singleton class IncomingVerificationRequestHandler @Inject constructor( private val context: Context, private var avatarRenderer: Provider, - private val popupAlertManager: PopupAlertManager) : VerificationService.Listener { + private val popupAlertManager: PopupAlertManager, + private val coroutineScope: CoroutineScope) : VerificationService.Listener { private var session: Session? = null @@ -61,7 +64,7 @@ class IncomingVerificationRequestHandler @Inject constructor( // TODO maybe check also if val uid = "kvr_${tx.transactionId}" when (tx.state) { - is VerificationTxState.OnStarted -> { + is VerificationTxState.OnStarted -> { // Add a notification for every incoming request val user = session?.getUser(tx.otherUserId) val name = user?.toMatrixItem()?.getBestName() ?: tx.otherUserId @@ -161,10 +164,12 @@ class IncomingVerificationRequestHandler @Inject constructor( } } dismissedAction = Runnable { - session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId, - pr.transactionId ?: "", - pr.roomId ?: "" - ) + coroutineScope.launch { + session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId, + pr.transactionId ?: "", + pr.roomId ?: "" + ) + } } colorAttribute = R.attr.vctr_notice_secondary // 5mn expiration diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index ee3bbe8f31..f38fd53950 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -152,13 +152,15 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } if (autoReady) { - // TODO, can I be here in DM mode? in this case should test if roomID is null? - session.cryptoService().verificationService() - .readyPendingVerification( - supportedVerificationMethodsProvider.provide(), - pr!!.otherUserId, - pr.transactionId ?: "" - ) + viewModelScope.launch { + // TODO, can I be here in DM mode? in this case should test if roomID is null? + session.cryptoService().verificationService() + .readyPendingVerification( + supportedVerificationMethodsProvider.provide(), + pr!!.otherUserId, + pr.transactionId ?: "" + ) + } } } @@ -192,14 +194,16 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } private fun cancelAllPendingVerifications(state: VerificationBottomSheetViewState) { - session.cryptoService() - .verificationService().getExistingVerificationRequest(state.otherUserMxItem?.id ?: "", state.transactionId)?.let { - session.cryptoService().verificationService().cancelVerificationRequest(it) - } - session.cryptoService() - .verificationService() - .getExistingTransaction(state.otherUserMxItem?.id ?: "", state.transactionId ?: "") - ?.cancel(CancelCode.User) + viewModelScope.launch { + session.cryptoService() + .verificationService().getExistingVerificationRequest(state.otherUserMxItem?.id ?: "", state.transactionId)?.let { + session.cryptoService().verificationService().cancelVerificationRequest(it) + } + session.cryptoService() + .verificationService() + .getExistingTransaction(state.otherUserMxItem?.id ?: "", state.transactionId ?: "") + ?.cancel(CancelCode.User) + } } fun continueFromCancel() { @@ -232,74 +236,29 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( when (action) { is VerificationAction.RequestVerificationByDM -> { - if (roomId == null) { - val localId = LocalEcho.createLocalEchoId() - setState { - copy( - pendingLocalId = localId, - pendingRequest = Loading() - ) - } - viewModelScope.launch { - val result = runCatching { session.createDirectRoom(otherUserId) } - result.fold( - { data -> - setState { - copy( - roomId = data, - pendingRequest = Success( - session - .cryptoService() - .verificationService() - .requestKeyVerificationInDMs( - supportedVerificationMethodsProvider.provide(), - otherUserId, - data, - pendingLocalId - ) - ) - ) - } - }, - { failure -> - setState { - copy(pendingRequest = Fail(failure)) - } - } - ) - } - } else { - setState { - copy( - pendingRequest = Success(session - .cryptoService() - .verificationService() - .requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), otherUserId, roomId) - ) - ) - } - } - Unit + handleRequestVerificationByDM(roomId, otherUserId) } is VerificationAction.StartSASVerification -> { val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId) ?: return@withState val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice - if (roomId == null) { - session.cryptoService().verificationService().beginKeyVerification( - VerificationMethod.SAS, - otherUserId = request.otherUserId, - otherDeviceId = otherDevice ?: "", - transactionId = action.pendingRequestTransactionId - ) - } else { - session.cryptoService().verificationService().beginKeyVerificationInDMs( - VerificationMethod.SAS, - transactionId = action.pendingRequestTransactionId, - roomId = roomId, - otherUserId = request.otherUserId, - otherDeviceId = otherDevice ?: "" - ) + viewModelScope.launch { + if (roomId == null) { + session.cryptoService().verificationService().beginKeyVerification( + VerificationMethod.SAS, + otherUserId = request.otherUserId, + otherDeviceId = otherDevice ?: "", + transactionId = action.pendingRequestTransactionId + ) + } else { + session.cryptoService().verificationService().beginKeyVerificationInDMs( + VerificationMethod.SAS, + transactionId = action.pendingRequestTransactionId, + roomId = roomId, + otherUserId = request.otherUserId, + otherDeviceId = otherDevice ?: "" + ) + } } Unit } @@ -365,6 +324,50 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( }.exhaustive } + private fun handleRequestVerificationByDM(roomId: String?, otherUserId: String) { + viewModelScope.launch { + if (roomId == null) { + val localId = LocalEcho.createLocalEchoId() + setState { + copy( + pendingLocalId = localId, + pendingRequest = Loading() + ) + } + try { + val dmRoomId = session.createDirectRoom(otherUserId) + val pendingRequest = session + .cryptoService() + .verificationService() + .requestKeyVerificationInDMs( + supportedVerificationMethodsProvider.provide(), + otherUserId, + dmRoomId, + localId + ) + setState { + copy( + roomId = dmRoomId, + pendingRequest = Success(pendingRequest) + ) + } + } catch (failure: Throwable) { + setState { + copy(pendingRequest = Fail(failure)) + } + } + } else { + val pendingRequest = session + .cryptoService() + .verificationService() + .requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), otherUserId, roomId) + setState { + copy(pendingRequest = Success(pendingRequest)) + } + } + } + } + private fun handleSecretBackFromSSSS(action: VerificationAction.GotResultFromSsss) { viewModelScope.launch(Dispatchers.IO) { try { @@ -514,12 +517,14 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( if (!pr.isReady) { // auto ready in this case, as we are waiting // TODO, can I be here in DM mode? in this case should test if roomID is null? - session.cryptoService().verificationService() - .readyPendingVerification( - supportedVerificationMethodsProvider.provide(), - pr.otherUserId, - pr.transactionId ?: "" - ) + viewModelScope.launch { + session.cryptoService().verificationService() + .readyPendingVerification( + supportedVerificationMethodsProvider.provide(), + pr.otherUserId, + pr.transactionId ?: "" + ) + } } // Use this one! diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index 3bdcbc6529..1efed66aa5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -994,22 +994,26 @@ class TimelineViewModel @AssistedInject constructor( private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) { Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}") - if (session.cryptoService().verificationService().readyPendingVerificationInDMs( - supportedVerificationMethodsProvider.provide(), - action.otherUserId, - room.roomId, - action.transactionId)) { - _viewEvents.post(RoomDetailViewEvents.ActionSuccess(action)) - } else { - // TODO + viewModelScope.launch { + if (session.cryptoService().verificationService().readyPendingVerificationInDMs( + supportedVerificationMethodsProvider.provide(), + action.otherUserId, + room.roomId, + action.transactionId)) { + _viewEvents.post(RoomDetailViewEvents.ActionSuccess(action)) + } else { + // TODO + } } } private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) { - session.cryptoService().verificationService().declineVerificationRequestInDMs( - action.otherUserId, - action.transactionId, - room.roomId) + viewModelScope.launch { + session.cryptoService().verificationService().declineVerificationRequestInDMs( + action.otherUserId, + action.transactionId, + room.roomId) + } } private fun handleRequestVerification(action: RoomDetailAction.RequestVerification) { diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index fb2f3b8301..2e5ac0cb01 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -100,6 +100,8 @@ import im.vector.app.features.terms.ReviewTermsActivity import im.vector.app.features.widgets.WidgetActivity import im.vector.app.features.widgets.WidgetArgsBuilder import im.vector.app.space +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom @@ -116,7 +118,8 @@ class DefaultNavigator @Inject constructor( private val widgetArgsBuilder: WidgetArgsBuilder, private val appStateHandler: AppStateHandler, private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider, - private val features: VectorFeatures + private val features: VectorFeatures, + private val coroutineScope: CoroutineScope ) : Navigator { override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) { @@ -210,38 +213,42 @@ class DefaultNavigator @Inject constructor( } override fun requestSessionVerification(context: Context, otherSessionId: String) { - val session = sessionHolder.getSafeActiveSession() ?: return - val pr = session.cryptoService().verificationService().requestKeyVerification( - supportedVerificationMethodsProvider.provide(), - session.myUserId, - listOf(otherSessionId) - ) - if (context is AppCompatActivity) { - VerificationBottomSheet.withArgs( - roomId = null, - otherUserId = session.myUserId, - transactionId = pr.transactionId - ).show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) + coroutineScope.launch { + val session = sessionHolder.getSafeActiveSession() ?: return@launch + val pr = session.cryptoService().verificationService().requestKeyVerification( + supportedVerificationMethodsProvider.provide(), + session.myUserId, + listOf(otherSessionId) + ) + if (context is AppCompatActivity) { + VerificationBottomSheet.withArgs( + roomId = null, + otherUserId = session.myUserId, + transactionId = pr.transactionId + ).show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) + } } } override fun requestSelfSessionVerification(context: Context) { - val session = sessionHolder.getSafeActiveSession() ?: return - val otherSessions = session.cryptoService() - .getCryptoDeviceInfo(session.myUserId) - .filter { it.deviceId != session.sessionParams.deviceId } - .map { it.deviceId } - if (context is AppCompatActivity) { - if (otherSessions.isNotEmpty()) { - val pr = session.cryptoService().verificationService().requestKeyVerification( - supportedVerificationMethodsProvider.provide(), - session.myUserId, - otherSessions) - VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId) - .show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) - } else { - VerificationBottomSheet.forSelfVerification(session) - .show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) + coroutineScope.launch { + val session = sessionHolder.getSafeActiveSession() ?: return@launch + val otherSessions = session.cryptoService() + .getCryptoDeviceInfo(session.myUserId) + .filter { it.deviceId != session.sessionParams.deviceId } + .map { it.deviceId } + if (context is AppCompatActivity) { + if (otherSessions.isNotEmpty()) { + val pr = session.cryptoService().verificationService().requestKeyVerification( + supportedVerificationMethodsProvider.provide(), + session.myUserId, + otherSessions) + VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId) + .show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) + } else { + VerificationBottomSheet.forSelfVerification(session) + .show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt index d2491237ca..f7370ec439 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt @@ -30,6 +30,7 @@ import im.vector.app.core.di.SingletonEntryPoint import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod @@ -124,8 +125,14 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) { if (!initialState.allowDeviceAction) return - session.cryptoService().verificationService().beginKeyVerification(VerificationMethod.SAS, initialState.userId, action.deviceId, null)?.let { txID -> - _viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID)) + viewModelScope.launch { + session.cryptoService().verificationService().beginKeyVerification( + method = VerificationMethod.SAS, + otherUserId = initialState.userId, + otherDeviceId = action.deviceId, + transactionId = null)?.let { txID -> + _viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID)) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index ab871e8b18..f12060421b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -240,13 +240,15 @@ class DevicesViewModel @AssistedInject constructor( } private fun handleInteractiveVerification(action: DevicesAction.VerifyMyDevice) { - val txID = session.cryptoService() - .verificationService() - .beginKeyVerification(VerificationMethod.SAS, session.myUserId, action.deviceId, null) - _viewEvents.post(DevicesViewEvents.ShowVerifyDevice( - session.myUserId, - txID - )) + viewModelScope.launch { + val txID = session.cryptoService() + .verificationService() + .beginKeyVerification(VerificationMethod.SAS, session.myUserId, action.deviceId, null) + _viewEvents.post(DevicesViewEvents.ShowVerifyDevice( + session.myUserId, + txID + )) + } } private fun handleShowDeviceCryptoInfo(action: DevicesAction.VerifyMyDeviceManually) = withState { state -> From 046699bc84dc1b3c16262bd60282fe70e26ef9ba Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 30 Mar 2022 17:35:33 +0200 Subject: [PATCH 212/252] Suspend API: handle cross signing service --- .../matrix/android/sdk/flow/FlowSession.kt | 6 +- .../sdk/api/session/crypto/CryptoService.kt | 5 +- .../crosssigning/CrossSigningService.kt | 28 ++-- .../internal/crypto/DefaultCryptoService.kt | 9 +- .../android/sdk/internal/crypto/OlmMachine.kt | 158 ++++++------------ .../sdk/internal/crypto/OlmMachineProvider.kt | 4 +- .../crypto/RustCrossSigningService.kt | 54 +++--- .../recover/BootstrapCrossSigningTask.kt | 8 +- .../features/home/HomeActivityViewModel.kt | 44 +++-- .../helper/MessageInformationDataFactory.kt | 87 +++++----- .../features/navigation/DefaultNavigator.kt | 14 +- .../members/RoomMemberListViewModel.kt | 1 - .../VectorSettingsSecurityPrivacyFragment.kt | 45 ++--- .../CrossSigningSettingsViewModel.kt | 86 +++++----- ...iceVerificationInfoBottomSheetViewModel.kt | 30 ++-- .../settings/devices/DevicesViewModel.kt | 25 ++- 16 files changed, 275 insertions(+), 329 deletions(-) diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt index 669e27edfd..4dc1d04599 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt @@ -125,21 +125,21 @@ class FlowSession(private val session: Session) { } fun liveUserCryptoDevices(userId: String): Flow> { - return session.cryptoService().getLiveCryptoDeviceInfo(userId).asFlow() + return session.cryptoService().getLiveCryptoDeviceInfo(userId) .startWith(session.coroutineDispatchers.io) { session.cryptoService().getCryptoDeviceInfo(userId) } } fun liveCrossSigningInfo(userId: String): Flow> { - return session.cryptoService().crossSigningService().getLiveCrossSigningKeys(userId).asFlow() + return session.cryptoService().crossSigningService().getLiveCrossSigningKeys(userId) .startWith(session.coroutineDispatchers.io) { session.cryptoService().crossSigningService().getUserCrossSigningKeys(userId).toOptional() } } fun liveCrossSigningPrivateKeys(): Flow> { - return session.cryptoService().crossSigningService().getLiveCrossSigningPrivateKeys().asFlow() + return session.cryptoService().crossSigningService().getLiveCrossSigningPrivateKeys() .startWith(session.coroutineDispatchers.io) { session.cryptoService().crossSigningService().getCrossSigningPrivateKeys().toOptional() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 699dbf1d92..4244df2614 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.session.crypto import android.content.Context import androidx.lifecycle.LiveData import androidx.paging.PagedList +import kotlinx.coroutines.flow.Flow import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.listeners.ProgressListener @@ -123,9 +124,9 @@ interface CryptoService { fun getCryptoDeviceInfo(userId: String): List - fun getLiveCryptoDeviceInfo(userId: String): LiveData> + fun getLiveCryptoDeviceInfo(userId: String): Flow> - fun getLiveCryptoDeviceInfo(userIds: List): LiveData> + fun getLiveCryptoDeviceInfo(userIds: List): Flow> fun addNewSessionListener(newSessionListener: NewSessionListener) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index 1d97488ebc..70330171c5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.api.session.crypto.crosssigning import androidx.lifecycle.LiveData +import kotlinx.coroutines.flow.Flow import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel @@ -29,31 +30,30 @@ interface CrossSigningService { /** * Is our own device signed by our own cross signing identity */ - fun isCrossSigningVerified(): Boolean + suspend fun isCrossSigningVerified(): Boolean // TODO this isn't used anywhere besides in tests? // Is this the local trust concept that we have for devices? - fun isUserTrusted(otherUserId: String): Boolean + suspend fun isUserTrusted(otherUserId: String): Boolean /** * Will not force a download of the key, but will verify signatures trust chain. * Checks that my trusted user key has signed the other user UserKey */ - fun checkUserTrust(otherUserId: String): UserTrustResult + suspend fun checkUserTrust(otherUserId: String): UserTrustResult /** * Initialize cross signing for this user. * Users needs to enter credentials */ - fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?, - callback: MatrixCallback) + suspend fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?) /** * Does our own user have a valid cross signing identity uploaded. * * In other words has any of our devices uploaded public cross signing keys to the server. */ - fun isCrossSigningInitialized(): Boolean = getMyCrossSigningKeys() != null + suspend fun isCrossSigningInitialized(): Boolean = getMyCrossSigningKeys() != null /** * Inject the private cross signing keys, likely from backup, into our store. @@ -70,17 +70,17 @@ interface CrossSigningService { * * @param otherUserId The ID of the user for which we would like to fetch the cross signing keys. */ - fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? + suspend fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? - fun getLiveCrossSigningKeys(userId: String): LiveData> + fun getLiveCrossSigningKeys(userId: String): Flow> /** Get our own public cross signing keys */ - fun getMyCrossSigningKeys(): MXCrossSigningInfo? + suspend fun getMyCrossSigningKeys(): MXCrossSigningInfo? /** Get our own private cross signing keys */ - fun getCrossSigningPrivateKeys(): PrivateKeysInfo? + suspend fun getCrossSigningPrivateKeys(): PrivateKeysInfo? - fun getLiveCrossSigningPrivateKeys(): LiveData> + fun getLiveCrossSigningPrivateKeys(): Flow> /** * Can we sign our other devices or other users? @@ -93,11 +93,11 @@ interface CrossSigningService { fun allPrivateKeysKnown(): Boolean /** Mark a user identity as trusted and sign and upload signatures of our user-signing key to the server */ - fun trustUser(otherUserId: String, + suspend fun trustUser(otherUserId: String, callback: MatrixCallback) /** Mark our own master key as trusted */ - fun markMyMasterKeyAsTrusted() + suspend fun markMyMasterKeyAsTrusted() /** * Sign one of your devices and upload the signature @@ -114,7 +114,7 @@ interface CrossSigningService { * using the self-signing key for our own devices or using the user-signing key and the master * key of another user. */ - fun checkDeviceTrust(otherUserId: String, + suspend fun checkDeviceTrust(otherUserId: String, otherDeviceId: String, // TODO what is locallyTrusted used for? locallyTrusted: Boolean?): DeviceTrustResult diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 98f65dc34b..4b085c7b79 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -25,6 +25,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -426,14 +427,12 @@ internal class DefaultCryptoService @Inject constructor( } } - override fun getLiveCryptoDeviceInfo(userId: String): LiveData> { + override fun getLiveCryptoDeviceInfo(userId: String): Flow> { return getLiveCryptoDeviceInfo(listOf(userId)) } - override fun getLiveCryptoDeviceInfo(userIds: List): LiveData> { - return runBlocking { - this@DefaultCryptoService.olmMachine.getLiveDevices(userIds) // ?: LiveDevice(userIds, deviceObserver) - } + override fun getLiveCryptoDeviceInfo(userIds: List): Flow> { + return olmMachine.getLiveDevices(userIds) } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index b3cb03d657..1555f8a04a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -16,9 +16,11 @@ package org.matrix.android.sdk.internal.crypto -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.SendChannel +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor @@ -64,7 +66,7 @@ import uniffi.olm.setLogger import java.io.File import java.nio.charset.Charset import java.util.UUID -import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CopyOnWriteArrayList import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.UserIdentity as RustUserIdentity @@ -81,98 +83,29 @@ private class CryptoProgressListener(private val listener: ProgressListener?) : } } -internal class LiveDevice( - internal var userIds: List, - private var observer: DeviceUpdateObserver -) : MutableLiveData>() { +private data class UserIdentityCollector(val userId: String, val collector: SendChannel>) : SendChannel> by collector +private data class DevicesCollector(val userIds: List, val collector: SendChannel>) : SendChannel> by collector +private typealias PrivateKeysCollector = SendChannel> - override fun onActive() { - observer.addDeviceUpdateListener(this) - } - - override fun onInactive() { - observer.removeDeviceUpdateListener(this) - } -} - -internal class LiveUserIdentity( - internal var userId: String, - private var observer: UserIdentityUpdateObserver -) : MutableLiveData>() { - override fun onActive() { - observer.addUserIdentityUpdateListener(this) - } - - override fun onInactive() { - observer.removeUserIdentityUpdateListener(this) - } -} - -internal class LivePrivateCrossSigningKeys( - private var observer: PrivateCrossSigningKeysUpdateObserver, -) : MutableLiveData>() { - - override fun onActive() { - observer.addUserIdentityUpdateListener(this) - } - - override fun onInactive() { - observer.removeUserIdentityUpdateListener(this) - } +private class FlowCollectors { + val userIdentityCollectors = CopyOnWriteArrayList() + val privateKeyCollectors = CopyOnWriteArrayList() + val deviceCollectors = CopyOnWriteArrayList() } fun setRustLogger() { setLogger(CryptoLogger() as Logger) } -internal class DeviceUpdateObserver { - internal val listeners = ConcurrentHashMap>() - - fun addDeviceUpdateListener(device: LiveDevice) { - listeners[device] = device.userIds - } - - fun removeDeviceUpdateListener(device: LiveDevice) { - listeners.remove(device) - } -} - -internal class UserIdentityUpdateObserver { - internal val listeners = ConcurrentHashMap() - - fun addUserIdentityUpdateListener(userIdentity: LiveUserIdentity) { - listeners[userIdentity] = userIdentity.userId - } - - fun removeUserIdentityUpdateListener(userIdentity: LiveUserIdentity) { - listeners.remove(userIdentity) - } -} - -internal class PrivateCrossSigningKeysUpdateObserver { - internal val listeners = ConcurrentHashMap() - - fun addUserIdentityUpdateListener(liveKeys: LivePrivateCrossSigningKeys) { - listeners[liveKeys] = Unit - } - - fun removeUserIdentityUpdateListener(liveKeys: LivePrivateCrossSigningKeys) { - listeners.remove(liveKeys) - } -} - internal class OlmMachine( user_id: String, device_id: String, path: File, - deviceObserver: DeviceUpdateObserver, private val requestSender: RequestSender, ) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) - private val deviceUpdateObserver = deviceObserver - private val userIdentityUpdateObserver = UserIdentityUpdateObserver() - private val privateKeysUpdateObserver = PrivateCrossSigningKeysUpdateObserver() internal val verificationListeners = ArrayList() + private val flowCollectors = FlowCollectors() /** Get our own user ID. */ fun userId(): String { @@ -193,26 +126,24 @@ internal class OlmMachine( return this.inner } - /** Update all of our live device listeners. */ private suspend fun updateLiveDevices() { - for ((liveDevice, users) in deviceUpdateObserver.listeners) { - val devices = getCryptoDeviceInfo(users) - liveDevice.postValue(devices) + for (deviceCollector in flowCollectors.deviceCollectors) { + val devices = getCryptoDeviceInfo(deviceCollector.userIds) + deviceCollector.send(devices) } } private suspend fun updateLiveUserIdentities() { - for ((liveIdentity, userId) in userIdentityUpdateObserver.listeners) { - val identity = getIdentity(userId)?.toMxCrossSigningInfo().toOptional() - liveIdentity.postValue(identity) + for (userIdentityCollector in flowCollectors.userIdentityCollectors) { + val identity = getIdentity(userIdentityCollector.userId)?.toMxCrossSigningInfo() + userIdentityCollector.send(identity.toOptional()) } } private suspend fun updateLivePrivateKeys() { val keys = this.exportCrossSigningKeys().toOptional() - - for (liveKeys in privateKeysUpdateObserver.listeners.keys()) { - liveKeys.postValue(keys) + for (privateKeyCollector in flowCollectors.privateKeyCollectors) { + privateKeyCollector.send(keys) } } @@ -712,20 +643,27 @@ internal class OlmMachine( return getUserDevicesMap(userIds) } - suspend fun getLiveUserIdentity(userId: String): LiveData> { - val identity = this.getIdentity(userId)?.toMxCrossSigningInfo().toOptional() - val liveIdentity = LiveUserIdentity(userId, this.userIdentityUpdateObserver) - liveIdentity.value = identity - - return liveIdentity + fun getLiveUserIdentity(userId: String): Flow> { + return channelFlow { + val userIdentityCollector = UserIdentityCollector(userId, this) + flowCollectors.userIdentityCollectors.add(userIdentityCollector) + val identity = getIdentity(userId)?.toMxCrossSigningInfo().toOptional() + send(identity) + awaitClose { + flowCollectors.userIdentityCollectors.remove(userIdentityCollector) + } + } } - suspend fun getLivePrivateCrossSigningKeys(): LiveData> { - val keys = this.exportCrossSigningKeys().toOptional() - val liveKeys = LivePrivateCrossSigningKeys(this.privateKeysUpdateObserver) - liveKeys.value = keys - - return liveKeys + fun getLivePrivateCrossSigningKeys(): Flow> { + return channelFlow { + flowCollectors.privateKeyCollectors.add(this) + val keys = this@OlmMachine.exportCrossSigningKeys().toOptional() + send(keys) + awaitClose { + flowCollectors.privateKeyCollectors.remove(this) + } + } } /** @@ -738,12 +676,16 @@ internal class OlmMachine( * * @return The list of Devices or an empty list if there aren't any. */ - suspend fun getLiveDevices(userIds: List): LiveData> { - val plainDevices = getCryptoDeviceInfo(userIds) - val devices = LiveDevice(userIds, deviceUpdateObserver) - devices.value = plainDevices - - return devices + fun getLiveDevices(userIds: List): Flow> { + return channelFlow { + val devicesCollector = DevicesCollector(userIds, this) + flowCollectors.deviceCollectors.add(devicesCollector) + val devices = getCryptoDeviceInfo(userIds) + send(devices) + awaitClose { + flowCollectors.deviceCollectors.remove(devicesCollector) + } + } } /** Discard the currently active room key for the given room if there is one. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt index 441fe5acd0..6aa59afc69 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt @@ -31,7 +31,5 @@ internal class OlmMachineProvider @Inject constructor( requestSender: RequestSender ) { - private val deviceObserver: DeviceUpdateObserver = DeviceUpdateObserver() - - var olmMachine: OlmMachine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver, requestSender) + var olmMachine: OlmMachine = OlmMachine(userId, deviceId!!, dataDir, requestSender) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index 07918870d3..a1b0fc35e6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.internal.crypto import androidx.lifecycle.LiveData -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.flow.Flow import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor @@ -45,14 +45,14 @@ internal class RustCrossSigningService @Inject constructor( /** * Is our own device signed by our own cross signing identity */ - override fun isCrossSigningVerified(): Boolean { - return when (val identity = runBlocking { olmMachine.getIdentity(olmMachine.userId()) }) { + override suspend fun isCrossSigningVerified(): Boolean { + return when (val identity = olmMachine.getIdentity(olmMachine.userId()) ) { is OwnUserIdentity -> identity.trustsOurOwnDevice() else -> false } } - override fun isUserTrusted(otherUserId: String): Boolean { + override suspend fun isUserTrusted(otherUserId: String): Boolean { // This seems to be used only in tests. return this.checkUserTrust(otherUserId).isVerified() } @@ -61,14 +61,14 @@ internal class RustCrossSigningService @Inject constructor( * Will not force a download of the key, but will verify signatures trust chain. * Checks that my trusted user key has signed the other user UserKey */ - override fun checkUserTrust(otherUserId: String): UserTrustResult { - val identity = runBlocking { olmMachine.getIdentity(olmMachine.userId()) } + override suspend fun checkUserTrust(otherUserId: String): UserTrustResult { + val identity = olmMachine.getIdentity(olmMachine.userId()) // While UserTrustResult has many different states, they are by the callers // converted to a boolean value immediately, thus we don't need to support // all the values. return if (identity != null) { - val verified = runBlocking { identity.verified() } + val verified = identity.verified() if (verified) { UserTrustResult.Success @@ -84,8 +84,8 @@ internal class RustCrossSigningService @Inject constructor( * Initialize cross signing for this user. * Users needs to enter credentials */ - override fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?, callback: MatrixCallback) { - runBlocking { runCatching { olmMachine.bootstrapCrossSigning(uiaInterceptor) }.foldToCallback(callback) } + override suspend fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?) { + olmMachine.bootstrapCrossSigning(uiaInterceptor) } /** @@ -108,26 +108,26 @@ internal class RustCrossSigningService @Inject constructor( * * @param otherUserId The ID of the user for which we would like to fetch the cross signing keys. */ - override fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? { - return runBlocking { olmMachine.getIdentity(otherUserId)?.toMxCrossSigningInfo() } + override suspend fun getUserCrossSigningKeys(otherUserId: String): MXCrossSigningInfo? { + return olmMachine.getIdentity(otherUserId)?.toMxCrossSigningInfo() } - override fun getLiveCrossSigningKeys(userId: String): LiveData> { - return runBlocking { olmMachine.getLiveUserIdentity(userId) } + override fun getLiveCrossSigningKeys(userId: String): Flow> { + return olmMachine.getLiveUserIdentity(userId) } /** Get our own public cross signing keys */ - override fun getMyCrossSigningKeys(): MXCrossSigningInfo? { + override suspend fun getMyCrossSigningKeys(): MXCrossSigningInfo? { return getUserCrossSigningKeys(olmMachine.userId()) } /** Get our own private cross signing keys */ - override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? { - return runBlocking { olmMachine.exportCrossSigningKeys() } + override suspend fun getCrossSigningPrivateKeys(): PrivateKeysInfo? { + return olmMachine.exportCrossSigningKeys() } - override fun getLiveCrossSigningPrivateKeys(): LiveData> { - return runBlocking { olmMachine.getLivePrivateCrossSigningKeys() } + override fun getLiveCrossSigningPrivateKeys(): Flow> { + return olmMachine.getLivePrivateCrossSigningKeys() } /** @@ -148,12 +148,12 @@ internal class RustCrossSigningService @Inject constructor( } /** Mark a user identity as trusted and sign and upload signatures of our user-signing key to the server */ - override fun trustUser(otherUserId: String, callback: MatrixCallback) { + override suspend fun trustUser(otherUserId: String, callback: MatrixCallback) { // This is only used in a test - val userIdentity = runBlocking { olmMachine.getIdentity(otherUserId) } + val userIdentity = olmMachine.getIdentity(otherUserId) if (userIdentity != null) { - runBlocking { userIdentity.verify() } + userIdentity.verify() callback.onSuccess(Unit) } else { callback.onFailure(Throwable("## CrossSigning - CrossSigning is not setup for this account")) @@ -161,7 +161,7 @@ internal class RustCrossSigningService @Inject constructor( } /** Mark our own master key as trusted */ - override fun markMyMasterKeyAsTrusted() { + override suspend fun markMyMasterKeyAsTrusted() { // This doesn't seem to be used? this.trustUser(this.olmMachine.userId(), NoOpMatrixCallback()) } @@ -171,10 +171,8 @@ internal class RustCrossSigningService @Inject constructor( */ override suspend fun trustDevice(deviceId: String) { val device = olmMachine.getDevice(olmMachine.userId(), deviceId) - - return if (device != null) { + if (device != null) { val verified = device.verify() - if (verified) { return } else { @@ -192,15 +190,15 @@ internal class RustCrossSigningService @Inject constructor( * using the self-signing key for our own devices or using the user-signing key and the master * key of another user. */ - override fun checkDeviceTrust(otherUserId: String, otherDeviceId: String, locallyTrusted: Boolean?): DeviceTrustResult { - val device = runBlocking { olmMachine.getDevice(otherUserId, otherDeviceId) } + override suspend fun checkDeviceTrust(otherUserId: String, otherDeviceId: String, locallyTrusted: Boolean?): DeviceTrustResult { + val device = olmMachine.getDevice(otherUserId, otherDeviceId) return if (device != null) { // TODO i don't quite understand the semantics here and there are no docs for // DeviceTrustResult, what do the different result types mean exactly, // do you return success only if the Device is cross signing verified? // what about the local trust if it isn't? why is the local trust passed as an argument here? - DeviceTrustResult.Success(runBlocking { device.trustLevel() }) + DeviceTrustResult.Success(device.trustLevel()) } else { DeviceTrustResult.UnknownDevice(otherDeviceId) } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt index de627e1f78..23cd54ed99 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt @@ -34,7 +34,6 @@ import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import java.util.UUID import javax.inject.Inject @@ -91,12 +90,7 @@ class BootstrapCrossSigningTask @Inject constructor( ) try { - awaitCallback { - crossSigningService.initializeCrossSigning( - params.userInteractiveAuthInterceptor, - it - ) - } + crossSigningService.initializeCrossSigning(params.userInteractiveAuthInterceptor) if (params.setupMode == SetupMode.CROSS_SIGNING_ONLY) { return BootstrapResult.SuccessCrossSigningOnly } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index ca8aeaba85..9d93e2261f 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -49,7 +49,6 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -220,30 +219,27 @@ class HomeActivityViewModel @AssistedInject constructor( // Try to initialize cross signing in background if possible Timber.d("Initialize cross signing...") try { - awaitCallback { - session.cryptoService().crossSigningService().initializeCrossSigning( - object : UserInteractiveAuthInterceptor { - override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { - // We missed server grace period or it's not setup, see if we remember locally password - if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD && - errCode == null && - reAuthHelper.data != null) { - promise.resume( - UserPasswordAuth( - session = flowResponse.session, - user = session.myUserId, - password = reAuthHelper.data - ) - ) - } else { - promise.resumeWithException(Exception("Cannot silently initialize cross signing, UIA missing")) - } + session.cryptoService().crossSigningService().initializeCrossSigning( + object : UserInteractiveAuthInterceptor { + override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { + // We missed server grace period or it's not setup, see if we remember locally password + if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD && + errCode == null && + reAuthHelper.data != null) { + promise.resume( + UserPasswordAuth( + session = flowResponse.session, + user = session.myUserId, + password = reAuthHelper.data + ) + ) + } else { + promise.resumeWithException(Exception("Cannot silently initialize cross signing, UIA missing")) } - }, - callback = it - ) - Timber.d("Initialize cross signing SUCCESS") - } + } + }, + ) + Timber.d("Initialize cross signing SUCCESS") } catch (failure: Throwable) { Timber.e(failure, "Failed to initialize cross signing") } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index 59b39d17ef..bd0ba075a5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -27,6 +27,7 @@ import im.vector.app.features.home.room.detail.timeline.item.PollVoteSummaryData import im.vector.app.features.home.room.detail.timeline.item.ReferencesInfoData import im.vector.app.features.home.room.detail.timeline.item.SendStateDecoration import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayoutFactory +import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.crypto.VerificationState import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session @@ -139,52 +140,54 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses } private fun getE2EDecoration(roomSummary: RoomSummary?, event: TimelineEvent): E2EDecoration { - return if ( - event.root.sendState == SendState.SYNCED && - roomSummary?.isEncrypted.orFalse() && - // is user verified - session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted() == true) { - val ts = roomSummary?.encryptionEventTs ?: 0 - val eventTs = event.root.originServerTs ?: 0 - if (event.isEncrypted()) { - // Do not decorate failed to decrypt, or redaction (we lost sender device info) - if (event.root.getClearType() == EventType.ENCRYPTED || event.root.isRedacted()) { - E2EDecoration.NONE - } else { - val sendingDevice = event.root.content - .toModel() - ?.deviceId - ?.let { deviceId -> - session.cryptoService().getDeviceInfo(event.root.senderId ?: "", deviceId) - } - when { - sendingDevice == null -> { - // For now do not decorate this with warning - // maybe it's a deleted session - E2EDecoration.NONE - } - sendingDevice.trustLevel == null -> { - E2EDecoration.WARN_SENT_BY_UNKNOWN - } - sendingDevice.trustLevel?.isVerified().orFalse() -> { - E2EDecoration.NONE - } - else -> { - E2EDecoration.WARN_SENT_BY_UNVERIFIED - } - } - } + if (event.root.sendState != SendState.SYNCED) + return E2EDecoration.NONE + if (!roomSummary?.isEncrypted.orFalse()) + return E2EDecoration.NONE + val isUserVerified = runBlocking { + session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted().orFalse() + } + if (!isUserVerified) { + return E2EDecoration.NONE + } + val ts = roomSummary?.encryptionEventTs ?: 0 + val eventTs = event.root.originServerTs ?: 0 + return if (event.isEncrypted()) { + // Do not decorate failed to decrypt, or redaction (we lost sender device info) + if (event.root.getClearType() == EventType.ENCRYPTED || event.root.isRedacted()) { + E2EDecoration.NONE } else { - if (event.root.isStateEvent()) { - // Do not warn for state event, they are always in clear - E2EDecoration.NONE - } else { - // If event is in clear after the room enabled encryption we should warn - if (eventTs > ts) E2EDecoration.WARN_IN_CLEAR else E2EDecoration.NONE + val sendingDevice = event.root.content + .toModel() + ?.deviceId + ?.let { deviceId -> + session.cryptoService().getDeviceInfo(event.root.senderId ?: "", deviceId) + } + when { + sendingDevice == null -> { + // For now do not decorate this with warning + // maybe it's a deleted session + E2EDecoration.NONE + } + sendingDevice.trustLevel == null -> { + E2EDecoration.WARN_SENT_BY_UNKNOWN + } + sendingDevice.trustLevel?.isVerified().orFalse() -> { + E2EDecoration.NONE + } + else -> { + E2EDecoration.WARN_SENT_BY_UNVERIFIED + } } } } else { - E2EDecoration.NONE + if (event.root.isStateEvent()) { + // Do not warn for state event, they are always in clear + E2EDecoration.NONE + } else { + // If event is in clear after the room enabled encryption we should warn + if (eventTs > ts) E2EDecoration.WARN_IN_CLEAR else E2EDecoration.NONE + } } } diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 2e5ac0cb01..2c1e373075 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -411,13 +411,15 @@ class DefaultNavigator @Inject constructor( override fun openKeysBackupSetup(context: Context, showManualExport: Boolean) { // if cross signing is enabled and trusted or not set up at all we should propose full 4S sessionHolder.getSafeActiveSession()?.let { session -> - if (session.cryptoService().crossSigningService().getMyCrossSigningKeys() == null || - session.cryptoService().crossSigningService().canCrossSign()) { - (context as? AppCompatActivity)?.let { - BootstrapBottomSheet.show(it.supportFragmentManager, SetupMode.NORMAL) + coroutineScope.launch { + if (session.cryptoService().crossSigningService().getMyCrossSigningKeys() == null || + session.cryptoService().crossSigningService().canCrossSign()) { + (context as? AppCompatActivity)?.let { + BootstrapBottomSheet.show(it.supportFragmentManager, SetupMode.NORMAL) + } + } else { + context.startActivity(KeysBackupSetupActivity.intent(context, showManualExport)) } - } else { - context.startActivity(KeysBackupSetupActivity.intent(context, showManualExport)) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt index 0bbdd87f3e..af57f3de99 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt @@ -95,7 +95,6 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState room.flow().liveRoomMembers(roomMemberQueryParams) .flatMapLatest { membersSummary -> session.cryptoService().getLiveCryptoDeviceInfo(membersSummary.map { it.userId }) - .asFlow() .catch { Timber.e(it) } .map { deviceList -> // If any key change, emit the userIds list diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index ef87d908ea..95a7213b35 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -317,31 +317,32 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( // Todo this should be refactored and use same state as 4S section private fun refreshXSigningStatus() { - val crossSigningKeys = session.cryptoService().crossSigningService().getMyCrossSigningKeys() - val xSigningIsEnableInAccount = crossSigningKeys != null - val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified() - val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign() + lifecycleScope.launchWhenResumed { + val crossSigningKeys = session.cryptoService().crossSigningService().getMyCrossSigningKeys() + val xSigningIsEnableInAccount = crossSigningKeys != null + val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified() + val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign() - when { - xSigningKeyCanSign -> { - mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_trusted) - mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_complete) - } - xSigningKeysAreTrusted -> { - mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_custom) - mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_trusted) - } - xSigningIsEnableInAccount -> { - mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_black) - mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_not_trusted) - } - else -> { - mCrossSigningStatePreference.setIcon(android.R.color.transparent) - mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_disabled) + when { + xSigningKeyCanSign -> { + mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_trusted) + mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_complete) + } + xSigningKeysAreTrusted -> { + mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_custom) + mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_trusted) + } + xSigningIsEnableInAccount -> { + mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_black) + mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_not_trusted) + } + else -> { + mCrossSigningStatePreference.setIcon(android.R.color.transparent) + mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_disabled) + } } + mCrossSigningStatePreference.isVisible = true } - - mCrossSigningStatePreference.isVisible = true } private val saveMegolmStartForActivityResult = registerStartForActivityResult { diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt index 644b7f33dd..744a6eedd4 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt @@ -29,6 +29,7 @@ import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.login.ReAuthHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor @@ -41,7 +42,6 @@ import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -55,25 +55,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { init { - combine( - session.flow().liveMyDevicesInfo(), - session.flow().liveCrossSigningInfo(session.myUserId) - ) { myDevicesInfo, mxCrossSigningInfo -> - myDevicesInfo to mxCrossSigningInfo - } - .execute { data -> - val crossSigningKeys = data.invoke()?.second?.getOrNull() - val xSigningIsEnableInAccount = crossSigningKeys != null - val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified() - val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign() - - copy( - crossSigningInfo = crossSigningKeys, - xSigningIsEnableInAccount = xSigningIsEnableInAccount, - xSigningKeysAreTrusted = xSigningKeysAreTrusted, - xSigningKeyCanSign = xSigningKeyCanSign - ) - } + observeCrossSigning() } var uiaContinuation: Continuation? = null @@ -90,29 +72,27 @@ class CrossSigningSettingsViewModel @AssistedInject constructor( _viewEvents.post(CrossSigningSettingsViewEvents.ShowModalWaitingView(null)) viewModelScope.launch(Dispatchers.IO) { try { - awaitCallback { - session.cryptoService().crossSigningService().initializeCrossSigning( - object : UserInteractiveAuthInterceptor { - override fun performStage(flowResponse: RegistrationFlowResponse, - errCode: String?, - promise: Continuation) { - Timber.d("## UIA : initializeCrossSigning UIA") - if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD && - reAuthHelper.data != null && errCode == null) { - UserPasswordAuth( - session = null, - user = session.myUserId, - password = reAuthHelper.data - ).let { promise.resume(it) } - } else { - Timber.d("## UIA : initializeCrossSigning UIA > start reauth activity") - _viewEvents.post(CrossSigningSettingsViewEvents.RequestReAuth(flowResponse, errCode)) - pendingAuth = DefaultBaseAuth(session = flowResponse.session) - uiaContinuation = promise - } + session.cryptoService().crossSigningService().initializeCrossSigning( + object : UserInteractiveAuthInterceptor { + override fun performStage(flowResponse: RegistrationFlowResponse, + errCode: String?, + promise: Continuation) { + Timber.d("## UIA : initializeCrossSigning UIA") + if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD && + reAuthHelper.data != null && errCode == null) { + UserPasswordAuth( + session = null, + user = session.myUserId, + password = reAuthHelper.data + ).let { promise.resume(it) } + } else { + Timber.d("## UIA : initializeCrossSigning UIA > start reauth activity") + _viewEvents.post(CrossSigningSettingsViewEvents.RequestReAuth(flowResponse, errCode)) + pendingAuth = DefaultBaseAuth(session = flowResponse.session) + uiaContinuation = promise } - }, it) - } + } + }) } catch (failure: Throwable) { handleInitializeXSigningError(failure) } finally { @@ -149,6 +129,28 @@ class CrossSigningSettingsViewModel @AssistedInject constructor( }.exhaustive } + private fun observeCrossSigning() { + combine( + session.flow().liveMyDevicesInfo(), + session.flow().liveCrossSigningInfo(session.myUserId) + ) { myDevicesInfo, mxCrossSigningInfo -> + myDevicesInfo to mxCrossSigningInfo + }.onEach { data -> + val crossSigningKeys = data.second.getOrNull() + val xSigningIsEnableInAccount = crossSigningKeys != null + val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified() + val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign() + setState { + copy( + crossSigningInfo = crossSigningKeys, + xSigningIsEnableInAccount = xSigningIsEnableInAccount, + xSigningKeysAreTrusted = xSigningKeysAreTrusted, + xSigningKeyCanSign = xSigningKeyCanSign + ) + } + } + } + private fun handleInitializeXSigningError(failure: Throwable) { Timber.e(failure, "## CrossSigning - Failed to initialize cross signing") _viewEvents.post(CrossSigningSettingsViewEvents.Failure(Exception(stringProvider.getString(R.string.failed_to_initialize_cross_signing)))) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index 3a944b5a71..937445e815 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -15,7 +15,6 @@ */ package im.vector.app.features.settings.devices -import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -26,6 +25,7 @@ import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo @@ -43,14 +43,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As by hiltMavericksViewModelFactory() init { - - setState { - copy( - hasAccountCrossSigning = session.cryptoService().crossSigningService().isCrossSigningInitialized(), - accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified(), - isRecoverySetup = session.sharedSecretStorageService.isRecoverySetup() - ) - } + initState() session.flow().liveCrossSigningInfo(session.myUserId) .execute { copy( @@ -78,10 +71,6 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As ) } - setState { - copy(deviceInfo = Loading()) - } - session.flow().liveMyDevicesInfo() .map { devices -> devices.firstOrNull { it.deviceId == initialState.deviceId } ?: DeviceInfo(deviceId = initialState.deviceId) @@ -91,6 +80,21 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As } } + private fun initState() { + viewModelScope.launch { + val hasAccountCrossSigning = session.cryptoService().crossSigningService().isCrossSigningInitialized() + val accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified() + val isRecoverySetup = session.sharedSecretStorageService.isRecoverySetup() + setState { + copy( + hasAccountCrossSigning = hasAccountCrossSigning, + accountCrossSigningIsTrusted = accountCrossSigningIsTrusted, + isRecoverySetup = isRecoverySetup + ) + } + } + } + override fun handle(action: EmptyAction) { } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index f12060421b..10cda3ad44 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -106,15 +106,7 @@ class DevicesViewModel @AssistedInject constructor( private val refreshSource = PublishDataSource() init { - - setState { - copy( - hasAccountCrossSigning = session.cryptoService().crossSigningService().isCrossSigningInitialized(), - accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified(), - myDeviceId = session.sessionParams.deviceId ?: "" - ) - } - + initState() combine( session.flow().liveUserCryptoDevices(session.myUserId), session.flow().liveMyDevicesInfo() @@ -176,6 +168,21 @@ class DevicesViewModel @AssistedInject constructor( queryRefreshDevicesList() } + private fun initState() { + viewModelScope.launch { + val hasAccountCrossSigning = session.cryptoService().crossSigningService().isCrossSigningInitialized() + val accountCrossSigningIsTrusted = session.cryptoService().crossSigningService().isCrossSigningVerified() + val myDeviceId = session.sessionParams.deviceId ?: "" + setState { + copy( + hasAccountCrossSigning = hasAccountCrossSigning, + accountCrossSigningIsTrusted = accountCrossSigningIsTrusted, + myDeviceId = myDeviceId + ) + } + } + } + override fun onCleared() { session.cryptoService().verificationService().removeListener(this) super.onCleared() From 950c7f4a2364289159c3c016d7ae00523f8de8a9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 1 Apr 2022 17:49:08 +0200 Subject: [PATCH 213/252] Fix verification not working --- .../sdk/internal/crypto/DefaultCryptoService.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 4b085c7b79..611f657010 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -167,14 +167,15 @@ internal class DefaultCryptoService @Inject constructor( fun onLiveEvent(roomId: String, event: Event) { if (event.isStateEvent()) { - when (event.getClearType()) { - EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) - EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) - EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) - else -> cryptoCoroutineScope.launch { - this@DefaultCryptoService.verificationService.onEvent(event) + when (event.getClearType()) { + EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) + EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) + EventType.STATE_ROOM_HISTORY_VISIBILITY -> onRoomHistoryVisibilityEvent(roomId, event) + } + } else { + cryptoCoroutineScope.launch { + verificationService.onEvent(event) } - } } } From 9c6fccab1d33a7df356cd629d856b4bc4fbdd675 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 1 Apr 2022 17:49:44 +0200 Subject: [PATCH 214/252] Suspend API: continue moving verifications --- .../QrCodeVerificationTransaction.kt | 6 +- .../SasVerificationTransaction.kt | 6 +- .../verification/VerificationTransaction.kt | 4 +- .../sdk/internal/crypto/QrCodeVerification.kt | 19 +- .../sdk/internal/crypto/SasVerification.kt | 19 +- .../sdk/internal/crypto/UserIdentities.kt | 10 +- .../IncomingVerificationRequestHandler.kt | 26 +- .../VerificationBottomSheetViewModel.kt | 225 ++++++++++-------- .../features/navigation/DefaultNavigator.kt | 26 +- 9 files changed, 192 insertions(+), 149 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/QrCodeVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/QrCodeVerificationTransaction.kt index 37855099be..3e3dac633f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/QrCodeVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/QrCodeVerificationTransaction.kt @@ -26,15 +26,15 @@ interface QrCodeVerificationTransaction : VerificationTransaction { /** * Call when you have scan the other user QR code */ - fun userHasScannedOtherQrCode(otherQrCodeText: String) + suspend fun userHasScannedOtherQrCode(otherQrCodeText: String) /** * Call when you confirm that other user has scanned your QR code */ - fun otherUserScannedMyQrCode() + suspend fun otherUserScannedMyQrCode() /** * Call when you do not confirm that other user has scanned your QR code */ - fun otherUserDidNotScannedMyQrCode() + suspend fun otherUserDidNotScannedMyQrCode() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/SasVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/SasVerificationTransaction.kt index 2922d98a62..0b84025351 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/SasVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/SasVerificationTransaction.kt @@ -30,9 +30,9 @@ interface SasVerificationTransaction : VerificationTransaction { * To be called by the client when the user has verified that * both short codes do match */ - fun userHasVerifiedShortCode() + suspend fun userHasVerifiedShortCode() - fun acceptVerification() + suspend fun acceptVerification() - fun shortCodeDoesNotMatch() + suspend fun shortCodeDoesNotMatch() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTransaction.kt index 4d35bc44ac..389309d915 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationTransaction.kt @@ -30,9 +30,9 @@ interface VerificationTransaction { /** * User wants to cancel the transaction */ - fun cancel() + suspend fun cancel() - fun cancel(code: CancelCode) + suspend fun cancel(code: CancelCode) fun isToDeviceTransport(): Boolean } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index e61c5c8f8f..8afa9d7ef9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.crypto import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction @@ -67,20 +66,18 @@ internal class QrCodeVerification( } /** Pass the data from a scanned QR code into the QR code verification object */ - override fun userHasScannedOtherQrCode(otherQrCodeText: String) { - runBlocking { + override suspend fun userHasScannedOtherQrCode(otherQrCodeText: String) { request.scanQrCode(otherQrCodeText) - } dispatchTxUpdated() } /** Confirm that the other side has indeed scanned the QR code we presented */ - override fun otherUserScannedMyQrCode() { - runBlocking { confirm() } + override suspend fun otherUserScannedMyQrCode() { + confirm() } /** Cancel the QR code verification, denying that the other side has scanned the QR code */ - override fun otherUserDidNotScannedMyQrCode() { + override suspend fun otherUserDidNotScannedMyQrCode() { // TODO Is this code correct here? The old code seems to do this cancelHelper(CancelCode.MismatchedKeys) } @@ -140,7 +137,7 @@ internal class QrCodeVerification( * * The method turns into a noop, if the verification flow has already been cancelled. * */ - override fun cancel() { + override suspend fun cancel() { cancelHelper(CancelCode.User) } @@ -155,7 +152,7 @@ internal class QrCodeVerification( * * @param code The cancel code that should be given as the reason for the cancellation. * */ - override fun cancel(code: CancelCode) { + override suspend fun cancel(code: CancelCode) { cancelHelper(code) } @@ -190,11 +187,11 @@ internal class QrCodeVerification( } } - private fun cancelHelper(code: CancelCode) { + private suspend fun cancelHelper(code: CancelCode) { val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value) if (request != null) { - runBlocking { sender.sendVerificationRequest(request) } + sender.sendVerificationRequest(request) dispatchTxUpdated() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index 11a00c3b64..ac775af10e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.crypto import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation @@ -95,7 +94,7 @@ internal class SasVerification( * * The method turns into a noop, if the verification flow has already been cancelled. * */ - override fun cancel() { + override suspend fun cancel() { this.cancelHelper(CancelCode.User) } @@ -110,7 +109,7 @@ internal class SasVerification( * * @param code The cancel code that should be given as the reason for the cancellation. * */ - override fun cancel(code: CancelCode) { + override suspend fun cancel(code: CancelCode) { this.cancelHelper(code) } @@ -123,7 +122,7 @@ internal class SasVerification( * * The method turns into a noop, if the verification flow has already been cancelled. */ - override fun shortCodeDoesNotMatch() { + override suspend fun shortCodeDoesNotMatch() { this.cancelHelper(CancelCode.MismatchedSas) } @@ -153,8 +152,8 @@ internal class SasVerification( * This method is a noop if we're not yet in a presentable state, i.e. we didn't receive * a m.key.verification.key event from the other side or we're cancelled. */ - override fun userHasVerifiedShortCode() { - runBlocking { confirm() } + override suspend fun userHasVerifiedShortCode() { + confirm() } /** Accept the verification flow, signaling the other side that we do want to verify @@ -165,8 +164,8 @@ internal class SasVerification( * This method is a noop if we send the start event out or if the verification has already * been accepted. */ - override fun acceptVerification() { - runBlocking { accept() } + override suspend fun acceptVerification() { + accept() } /** Get the decimal representation of the short auth string @@ -220,11 +219,11 @@ internal class SasVerification( } } - private fun cancelHelper(code: CancelCode) { + private suspend fun cancelHelper(code: CancelCode) { val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value) if (request != null) { - runBlocking { sender.sendVerificationRequest(request) } + sender.sendVerificationRequest(request) dispatchTxUpdated() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt index 733d4a5e1f..00c18abe0e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt @@ -65,7 +65,7 @@ sealed class UserIdentities { /** * Convert the identity into a MxCrossSigningInfo class. */ - abstract fun toMxCrossSigningInfo(): MXCrossSigningInfo + abstract suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo } /** @@ -147,11 +147,11 @@ internal class OwnUserIdentity( /** * Convert the identity into a MxCrossSigningInfo class. */ - override fun toMxCrossSigningInfo(): MXCrossSigningInfo { + override suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo { val masterKey = this.masterKey val selfSigningKey = this.selfSigningKey val userSigningKey = this.userSigningKey - val trustLevel = DeviceTrustLevel(runBlocking { verified() }, false) + val trustLevel = DeviceTrustLevel(verified(), false) // TODO remove this, this is silly, we have way too many methods to check if a user is verified masterKey.trustLevel = trustLevel selfSigningKey.trustLevel = trustLevel @@ -249,9 +249,9 @@ internal class UserIdentity( /** * Convert the identity into a MxCrossSigningInfo class. */ - override fun toMxCrossSigningInfo(): MXCrossSigningInfo { + override suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo { // val crossSigningKeys = listOf(this.masterKey, this.selfSigningKey) - val trustLevel = DeviceTrustLevel(runBlocking { verified() }, false) + val trustLevel = DeviceTrustLevel(verified(), false) // TODO remove this, this is silly, we have way too many methods to check if a user is verified masterKey.trustLevel = trustLevel selfSigningKey.trustLevel = trustLevel diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt index aa97d5e078..14d4b9c5d9 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt @@ -91,12 +91,14 @@ class IncomingVerificationRequestHandler @Inject constructor( it.navigator.performDeviceVerification(it, tx.otherUserId, tx.transactionId) } } - dismissedAction = Runnable { + dismissedAction = LaunchCoroutineRunnable(coroutineScope) { tx.cancel() } addButton( context.getString(R.string.action_ignore), - { tx.cancel() } + LaunchCoroutineRunnable(coroutineScope) { + tx.cancel() + } ) addButton( context.getString(R.string.action_open), @@ -163,13 +165,11 @@ class IncomingVerificationRequestHandler @Inject constructor( } } } - dismissedAction = Runnable { - coroutineScope.launch { - session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId, - pr.transactionId ?: "", - pr.roomId ?: "" - ) - } + dismissedAction = LaunchCoroutineRunnable(coroutineScope) { + session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId, + pr.transactionId ?: "", + pr.roomId ?: "" + ) } colorAttribute = R.attr.vctr_notice_secondary // 5mn expiration @@ -186,6 +186,14 @@ class IncomingVerificationRequestHandler @Inject constructor( } } + private class LaunchCoroutineRunnable(private val coroutineScope: CoroutineScope, private val block: suspend () -> Unit) : Runnable { + override fun run() { + coroutineScope.launch { + block() + } + } + } + private fun uniqueIdForVerificationRequest(pr: PendingVerificationRequest) = "verificationRequest_${pr.transactionId}" } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index f38fd53950..03c87bbaff 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -239,61 +239,22 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( handleRequestVerificationByDM(roomId, otherUserId) } is VerificationAction.StartSASVerification -> { - val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId) - ?: return@withState - val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice - viewModelScope.launch { - if (roomId == null) { - session.cryptoService().verificationService().beginKeyVerification( - VerificationMethod.SAS, - otherUserId = request.otherUserId, - otherDeviceId = otherDevice ?: "", - transactionId = action.pendingRequestTransactionId - ) - } else { - session.cryptoService().verificationService().beginKeyVerificationInDMs( - VerificationMethod.SAS, - transactionId = action.pendingRequestTransactionId, - roomId = roomId, - otherUserId = request.otherUserId, - otherDeviceId = otherDevice ?: "" - ) - } - } - Unit + handleStartSASVerification(roomId, otherUserId, action) } is VerificationAction.RemoteQrCodeScanned -> { - val existingTransaction = session.cryptoService().verificationService() - .getExistingTransaction(action.otherUserId, action.transactionId) as? QrCodeVerificationTransaction - existingTransaction - ?.userHasScannedOtherQrCode(action.scannedData) + handleRemoteQrCodeScanned(action) } is VerificationAction.OtherUserScannedSuccessfully -> { - val transactionId = state.transactionId ?: return@withState - - val existingTransaction = session.cryptoService().verificationService() - .getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction - existingTransaction - ?.otherUserScannedMyQrCode() + handleOtherUserScannedSuccessfully(state.transactionId, otherUserId) } is VerificationAction.OtherUserDidNotScanned -> { - val transactionId = state.transactionId ?: return@withState - - val existingTransaction = session.cryptoService().verificationService() - .getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction - existingTransaction - ?.otherUserDidNotScannedMyQrCode() + handleOtherUserDidNotScanned(state.transactionId, otherUserId) } is VerificationAction.SASMatchAction -> { - (session.cryptoService().verificationService() - .getExistingTransaction(action.otherUserId, action.sasTransactionId) - as? SasVerificationTransaction)?.userHasVerifiedShortCode() + handleSASMatchAction(action) } is VerificationAction.SASDoNotMatchAction -> { - (session.cryptoService().verificationService() - .getExistingTransaction(action.otherUserId, action.sasTransactionId) - as? SasVerificationTransaction) - ?.shortCodeDoesNotMatch() + handleSASDoNotMatchAction(action) } is VerificationAction.GotItConclusion -> { _viewEvents.post(VerificationBottomSheetViewEvents.Dismiss) @@ -324,6 +285,76 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( }.exhaustive } + private fun handleStartSASVerification(roomId: String?, otherUserId: String, action: VerificationAction.StartSASVerification) { + val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId) + ?: return + val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice + viewModelScope.launch { + if (roomId == null) { + session.cryptoService().verificationService().beginKeyVerification( + VerificationMethod.SAS, + otherUserId = request.otherUserId, + otherDeviceId = otherDevice ?: "", + transactionId = action.pendingRequestTransactionId + ) + } else { + session.cryptoService().verificationService().beginKeyVerificationInDMs( + VerificationMethod.SAS, + transactionId = action.pendingRequestTransactionId, + roomId = roomId, + otherUserId = request.otherUserId, + otherDeviceId = otherDevice ?: "" + ) + } + } + } + + private fun handleSASDoNotMatchAction(action: VerificationAction.SASDoNotMatchAction) { + viewModelScope.launch { + (session.cryptoService().verificationService() + .getExistingTransaction(action.otherUserId, action.sasTransactionId) + as? SasVerificationTransaction) + ?.shortCodeDoesNotMatch() + } + } + + private fun handleSASMatchAction(action: VerificationAction.SASMatchAction) { + viewModelScope.launch { + (session.cryptoService().verificationService() + .getExistingTransaction(action.otherUserId, action.sasTransactionId) + as? SasVerificationTransaction)?.userHasVerifiedShortCode() + } + } + + private fun handleOtherUserDidNotScanned(transactionId: String?, otherUserId: String) { + transactionId ?: return + viewModelScope.launch { + val existingTransaction = session.cryptoService().verificationService() + .getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction + existingTransaction + ?.otherUserDidNotScannedMyQrCode() + } + } + + private fun handleOtherUserScannedSuccessfully(transactionId: String?, otherUserId: String) { + transactionId ?: return + viewModelScope.launch { + val existingTransaction = session.cryptoService().verificationService() + .getExistingTransaction(otherUserId, transactionId) as? QrCodeVerificationTransaction + existingTransaction + ?.otherUserScannedMyQrCode() + } + } + + private fun handleRemoteQrCodeScanned(action: VerificationAction.RemoteQrCodeScanned) { + viewModelScope.launch { + val existingTransaction = session.cryptoService().verificationService() + .getExistingTransaction(action.otherUserId, action.transactionId) as? QrCodeVerificationTransaction + existingTransaction + ?.userHasScannedOtherQrCode(action.scannedData) + } + } + private fun handleRequestVerificationByDM(roomId: String?, otherUserId: String) { viewModelScope.launch { if (roomId == null) { @@ -449,60 +480,66 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } } + private fun handleTransactionUpdate(state: VerificationBottomSheetViewState, tx: VerificationTransaction){ + viewModelScope.launch { + if (state.selfVerificationMode && state.transactionId == null) { + // is this an incoming with that user + if (tx.isIncoming && tx.otherUserId == state.otherUserMxItem?.id) { + // Also auto accept incoming if needed! + // TODO is state.transactionId ever null for self verifications, doesn't seem + // like this will ever trigger + if (tx is SasVerificationTransaction && tx.state == VerificationTxState.OnStarted) { + tx.acceptVerification() + } + /* + if (tx is IncomingSasVerificationTransaction) { + if (tx.uxState == IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { + tx.performAccept() + } + } + */ + // Use this one! + setState { + copy( + transactionId = tx.transactionId, + sasTransactionState = tx.state.takeIf { tx is SasVerificationTransaction }, + qrTransactionState = tx.state.takeIf { tx is QrCodeVerificationTransaction } + ) + } + } + } + + when (tx) { + is SasVerificationTransaction -> { + if (tx.transactionId == (state.pendingRequest.invoke()?.transactionId ?: state.transactionId)) { + // A SAS tx has been started following this request + setState { + copy( + sasTransactionState = tx.state + ) + } + } + } + is QrCodeVerificationTransaction -> { + if (tx.transactionId == (state.pendingRequest.invoke()?.transactionId ?: state.transactionId)) { + // A QR tx has been started following this request + setState { + copy( + qrTransactionState = tx.state + ) + } + } + } + } + } + } + override fun transactionCreated(tx: VerificationTransaction) { transactionUpdated(tx) } override fun transactionUpdated(tx: VerificationTransaction) = withState { state -> - if (state.selfVerificationMode && state.transactionId == null) { - // is this an incoming with that user - if (tx.isIncoming && tx.otherUserId == state.otherUserMxItem?.id) { - // Also auto accept incoming if needed! - // TODO is state.transactionId ever null for self verifications, doesn't seem - // like this will ever trigger - if (tx is SasVerificationTransaction && tx.state == VerificationTxState.OnStarted) { - tx.acceptVerification() - } - /* - if (tx is IncomingSasVerificationTransaction) { - if (tx.uxState == IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { - tx.performAccept() - } - } - */ - // Use this one! - setState { - copy( - transactionId = tx.transactionId, - sasTransactionState = tx.state.takeIf { tx is SasVerificationTransaction }, - qrTransactionState = tx.state.takeIf { tx is QrCodeVerificationTransaction } - ) - } - } - } - - when (tx) { - is SasVerificationTransaction -> { - if (tx.transactionId == (state.pendingRequest.invoke()?.transactionId ?: state.transactionId)) { - // A SAS tx has been started following this request - setState { - copy( - sasTransactionState = tx.state - ) - } - } - } - is QrCodeVerificationTransaction -> { - if (tx.transactionId == (state.pendingRequest.invoke()?.transactionId ?: state.transactionId)) { - // A QR tx has been started following this request - setState { - copy( - qrTransactionState = tx.state - ) - } - } - } - } + handleTransactionUpdate(state, tx) } override fun verificationRequestCreated(pr: PendingVerificationRequest) { diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 2c1e373075..ee101be732 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -196,19 +196,21 @@ class DefaultNavigator @Inject constructor( } override fun performDeviceVerification(context: Context, otherUserId: String, sasTransactionId: String) { - val session = sessionHolder.getSafeActiveSession() ?: return - val tx = session.cryptoService().verificationService().getExistingTransaction(otherUserId, sasTransactionId) - ?: return - if (tx is SasVerificationTransaction && tx.isIncoming) { - tx.acceptVerification() - } + coroutineScope.launch { + val session = sessionHolder.getSafeActiveSession() ?: return@launch + val tx = session.cryptoService().verificationService().getExistingTransaction(otherUserId, sasTransactionId) + ?: return@launch + if (tx is SasVerificationTransaction && tx.isIncoming) { + tx.acceptVerification() + } - if (context is AppCompatActivity) { - VerificationBottomSheet.withArgs( - roomId = null, - otherUserId = otherUserId, - transactionId = sasTransactionId - ).show(context.supportFragmentManager, "REQPOP") + if (context is AppCompatActivity) { + VerificationBottomSheet.withArgs( + roomId = null, + otherUserId = otherUserId, + transactionId = sasTransactionId + ).show(context.supportFragmentManager, "REQPOP") + } } } From ed84e38a9b40613920af89df9894e4369a289fbf Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 6 Apr 2022 19:02:45 +0200 Subject: [PATCH 215/252] Suspend api: continue moving away from callback --- .../sdk/api/session/crypto/CryptoService.kt | 10 ++-- .../internal/crypto/DefaultCryptoService.kt | 54 ++++++------------- .../android/sdk/internal/crypto/OlmMachine.kt | 2 +- .../threads/FetchThreadTimelineTask.kt | 2 +- .../room/timeline/SendingEventsDataSource.kt | 1 + .../room/timeline/TimelineEventDecryptor.kt | 5 +- .../sync/handler/room/RoomSyncHandler.kt | 7 ++- .../VerificationBottomSheetViewModel.kt | 43 +++++++-------- .../UnknownDeviceDetectorSharedViewModel.kt | 34 +++++++----- .../action/MessageActionsViewModel.kt | 7 +-- .../helper/MessageInformationDataFactory.kt | 14 +++-- .../notifications/NotifiableEventResolver.kt | 2 +- .../VectorSettingsSecurityPrivacyFragment.kt | 39 +++++--------- .../settings/devices/DevicesViewModel.kt | 4 +- 14 files changed, 103 insertions(+), 121 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 4244df2614..d41e2aa11f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -64,7 +64,7 @@ interface CryptoService { fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) - fun getUserDevices(userId: String): MutableList + suspend fun getUserDevices(userId: String): MutableList fun getMyDevice(): CryptoDeviceInfo @@ -84,7 +84,7 @@ interface CryptoService { fun setRoomBlacklistUnverifiedDevices(roomId: String) - fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? + suspend fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? fun reRequestRoomKeyForEvent(event: Event) @@ -92,7 +92,7 @@ interface CryptoService { fun removeRoomKeysRequestListener(listener: GossipingRequestListener) - fun fetchDevicesList(callback: MatrixCallback) + suspend fun fetchDevicesList(): List fun getMyDevicesInfo(): List @@ -112,7 +112,7 @@ interface CryptoService { fun discardOutboundSession(roomId: String) @Throws(MXCryptoError::class) - fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult + suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback) @@ -122,7 +122,7 @@ interface CryptoService { suspend fun downloadKeys(userIds: List, forceDownload: Boolean = false): MXUsersDevicesMap - fun getCryptoDeviceInfo(userId: String): List + suspend fun getCryptoDeviceInfo(userId: String): List fun getLiveCryptoDeviceInfo(userId: String): Flow> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 611f657010..e4c0e90f6d 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -66,7 +66,6 @@ import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore @@ -224,23 +223,12 @@ internal class DefaultCryptoService @Inject constructor( return runBlocking { olmMachine.ownDevice() } } - override fun fetchDevicesList(callback: MatrixCallback) { - getDevicesTask - .configureWith { - // this.executionThread = TaskThread.CRYPTO - this.callback = object : MatrixCallback { - override fun onFailure(failure: Throwable) { - callback.onFailure(failure) - } - - override fun onSuccess(data: DevicesListResponse) { - // Save in local DB - cryptoStore.saveMyDevicesInfo(data.devices.orEmpty()) - callback.onSuccess(data) - } - } - } - .executeBy(taskExecutor) + override suspend fun fetchDevicesList(): List { + val devicesList = tryOrNull { + getDevicesTask.execute(Unit).devices + }.orEmpty() + cryptoStore.saveMyDevicesInfo(devicesList) + return devicesList } override fun getLiveMyDevicesInfo(): LiveData> { @@ -301,10 +289,9 @@ internal class DefaultCryptoService @Inject constructor( */ fun start() { internalStart() - // Just update - fetchDevicesList(NoOpMatrixCallback()) - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { + // Just update + fetchDevicesList() cryptoStore.tidyUpDataBase() } } @@ -412,20 +399,13 @@ internal class DefaultCryptoService @Inject constructor( * @param userId the user id * @param deviceId the device id */ - override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { - return if (userId.isNotEmpty() && !deviceId.isNullOrEmpty()) { - runBlocking { - this@DefaultCryptoService.olmMachine.getCryptoDeviceInfo(userId, deviceId) - } - } else { - null - } + override suspend fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { + if (userId.isEmpty() || deviceId.isNullOrEmpty()) return null + return olmMachine.getCryptoDeviceInfo(userId, deviceId) } - override fun getCryptoDeviceInfo(userId: String): List { - return runBlocking { - this@DefaultCryptoService.olmMachine.getCryptoDeviceInfo(userId) - } + override suspend fun getCryptoDeviceInfo(userId: String): List { + return olmMachine.getCryptoDeviceInfo(userId) } override fun getLiveCryptoDeviceInfo(userId: String): Flow> { @@ -503,7 +483,7 @@ internal class DefaultCryptoService @Inject constructor( /** * @return the stored device keys for a user. */ - override fun getUserDevices(userId: String): MutableList { + override suspend fun getUserDevices(userId: String): MutableList { return this.getCryptoDeviceInfo(userId).toMutableList() } @@ -577,10 +557,8 @@ internal class DefaultCryptoService @Inject constructor( * @return the MXEventDecryptionResult data, or throw in case of error */ @Throws(MXCryptoError::class) - override fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { - return runBlocking { - olmMachine.decryptRoomEvent(event) - } + override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { + return olmMachine.decryptRoomEvent(event) } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 1555f8a04a..42aed8e38f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -362,11 +362,11 @@ internal class OlmMachine( suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(Dispatchers.IO) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) - val serializedEvent = adapter.toJson(event) try { if (event.roomId.isNullOrBlank()) { throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON) } + val serializedEvent = adapter.toJson(event) val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId) val deserializationAdapter = diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/threads/FetchThreadTimelineTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/threads/FetchThreadTimelineTask.kt index e0d501c515..cd06d47f05 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/threads/FetchThreadTimelineTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/threads/FetchThreadTimelineTask.kt @@ -156,7 +156,7 @@ internal class DefaultFetchThreadTimelineTask @Inject constructor( * Invoke the event decryption mechanism for a specific event */ - private fun decryptIfNeeded(event: Event, roomId: String) { + private suspend fun decryptIfNeeded(event: Event, roomId: String) { try { // Event from sync does not have roomId, so add it to the event first val result = cryptoService.decryptEvent(event.copy(roomId = roomId), "") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/SendingEventsDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/SendingEventsDataSource.kt index b7a2cf2fce..9e1b33037f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/SendingEventsDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/SendingEventsDataSource.kt @@ -43,6 +43,7 @@ internal class RealmSendingEventsDataSource( private var roomEntity: RoomEntity? = null private var sendingTimelineEvents: RealmList? = null private var frozenSendingTimelineEvents: RealmList? = null + private val builtEvents = ArrayList() private val sendingTimelineEventsListener = RealmChangeListener> { events -> uiEchoManager.onSentEventsInDatabase(events.map { it.eventId }) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt index 8d62c6e8ec..7c52aa1b9b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.timeline import io.realm.Realm import io.realm.RealmConfiguration +import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.Event @@ -126,7 +127,9 @@ internal class TimelineEventDecryptor @Inject constructor( return } try { - val result = cryptoService.decryptEvent(request.event, timelineId) + val result = runBlocking { + cryptoService.decryptEvent(request.event, timelineId) + } Timber.v("Successfully decrypted event ${event.eventId}") realm.executeTransaction { val eventId = event.eventId ?: return@executeTransaction diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 8be342c6d1..7b5c08ebd6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync.handler.room import dagger.Lazy import io.realm.Realm import io.realm.kotlin.createObject +import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType @@ -343,7 +344,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle return roomEntity } - private suspend fun handleTimelineEvents(realm: Realm, + private fun handleTimelineEvents(realm: Realm, roomId: String, roomEntity: RoomEntity, eventList: List, @@ -458,7 +459,9 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle private fun decryptIfNeeded(event: Event, roomId: String) { try { // Event from sync does not have roomId, so add it to the event first - val result = cryptoService.decryptEvent(event.copy(roomId = roomId), "") + val result = runBlocking { + cryptoService.decryptEvent(event.copy(roomId = roomId), "") + } event.mxDecryptionResult = OlmDecryptionResult( payload = result.clearEvent, senderKey = result.senderCurve25519Key, diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 03c87bbaff..f3a272c3e8 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -131,28 +131,29 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( session.cryptoService().verificationService().getExistingTransaction(initialState.otherUserId, it) as? QrCodeVerificationTransaction } - val hasAnyOtherSession = session.cryptoService() - .getCryptoDeviceInfo(session.myUserId) - .any { - it.deviceId != session.sessionParams.deviceId - } + viewModelScope.launch { - setState { - copy( - otherUserMxItem = userItem?.toMatrixItem(), - sasTransactionState = sasTx?.state, - qrTransactionState = qrTx?.state, - transactionId = pr?.transactionId ?: initialState.verificationId, - pendingRequest = if (pr != null) Success(pr) else Uninitialized, - isMe = initialState.otherUserId == session.myUserId, - currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign(), - quadSContainsSecrets = session.sharedSecretStorageService.isRecoverySetup(), - hasAnyOtherSession = hasAnyOtherSession - ) - } + val hasAnyOtherSession = session.cryptoService() + .getCryptoDeviceInfo(session.myUserId) + .any { + it.deviceId != session.sessionParams.deviceId + } - if (autoReady) { - viewModelScope.launch { + setState { + copy( + otherUserMxItem = userItem?.toMatrixItem(), + sasTransactionState = sasTx?.state, + qrTransactionState = qrTx?.state, + transactionId = pr?.transactionId ?: initialState.verificationId, + pendingRequest = if (pr != null) Success(pr) else Uninitialized, + isMe = initialState.otherUserId == session.myUserId, + currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign(), + quadSContainsSecrets = session.sharedSecretStorageService.isRecoverySetup(), + hasAnyOtherSession = hasAnyOtherSession + ) + } + + if (autoReady) { // TODO, can I be here in DM mode? in this case should test if roomID is null? session.cryptoService().verificationService() .readyPendingVerification( @@ -480,7 +481,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( } } - private fun handleTransactionUpdate(state: VerificationBottomSheetViewState, tx: VerificationTransaction){ + private fun handleTransactionUpdate(state: VerificationBottomSheetViewState, tx: VerificationTransaction) { viewModelScope.launch { if (state.selfVerificationMode && state.transactionId == null) { // is this an incoming with that user diff --git a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt index 8a36a4c19e..537adcf00d 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt @@ -32,10 +32,11 @@ import im.vector.app.core.platform.VectorViewModelAction import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.sample -import org.matrix.android.sdk.api.NoOpMatrixCallback +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.util.MatrixItem @@ -58,7 +59,7 @@ data class DeviceDetectionInfo( class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted initialState: UnknownDevicesState, session: Session, private val vectorPreferences: VectorPreferences) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { sealed class Action : VectorViewModelAction { data class IgnoreDevice(val deviceIds: List) : Action() @@ -75,12 +76,6 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted init { - val currentSessionTs = session.cryptoService().getCryptoDeviceInfo(session.myUserId) - .firstOrNull { it.deviceId == session.sessionParams.deviceId } - ?.firstTimeSeenLocalTs - ?: System.currentTimeMillis() - Timber.v("## Detector - Current Session first time seen $currentSessionTs") - ignoredDeviceList.addAll( vectorPreferences.getUnknownDeviceDismissedList().also { Timber.v("## Detector - Remembered ignored list $it") @@ -90,10 +85,12 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted combine( session.flow().liveUserCryptoDevices(session.myUserId), session.flow().liveMyDevicesInfo(), - session.flow().liveCrossSigningPrivateKeys() - ) { cryptoList, infoList, pInfo -> + session.flow().liveCrossSigningPrivateKeys(), + session.firstTimeDeviceSeen(), + ) { cryptoList, infoList, pInfo, firstTimeDeviceSeen -> // Timber.v("## Detector trigger ${cryptoList.map { "${it.deviceId} ${it.trustLevel}" }}") // Timber.v("## Detector trigger canCrossSign ${pInfo.get().selfSigned != null}") + Timber.v("## Detector - Current Session first time seen $firstTimeDeviceSeen") infoList .filter { info -> // filter verified session, by checking the crypto device info @@ -106,7 +103,7 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted val deviceKnownSince = cryptoList.firstOrNull { it.deviceId == deviceInfo.deviceId }?.firstTimeSeenLocalTs ?: 0 DeviceDetectionInfo( deviceInfo, - deviceKnownSince > currentSessionTs + 60_000, // short window to avoid false positive, + deviceKnownSince > firstTimeDeviceSeen + 60_000, // short window to avoid false positive, pInfo.getOrNull()?.selfSigned != null // adding this to pass distinct when cross sign change ) } @@ -125,12 +122,14 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted .sample(5_000) .onEach { // If we have a new crypto device change, we might want to trigger refresh of device info - session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) + session.cryptoService().fetchDevicesList() } .launchIn(viewModelScope) // trigger a refresh of lastSeen / last Ip - session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) + viewModelScope.launch { + session.cryptoService().fetchDevicesList() + } } override fun handle(action: Action) { @@ -154,4 +153,13 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted vectorPreferences.storeUnknownDeviceDismissedList(ignoredDeviceList) super.onCleared() } + + private fun Session.firstTimeDeviceSeen() = flow { + val value = cryptoService().getCryptoDeviceInfo(myUserId) + .firstOrNull { it.deviceId == sessionParams.deviceId } + ?.firstTimeSeenLocalTs + ?: System.currentTimeMillis() + emit(value) + } + } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index 5575d9b7f6..db8629defb 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -164,11 +164,12 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted onEach(MessageActionState::timelineEvent, MessageActionState::actionPermissions) { timelineEvent, permissions -> val nonNullTimelineEvent = timelineEvent() ?: return@onEach eventIdFlow.tryEmit(nonNullTimelineEvent.eventId) + val events = actionsForEvent(nonNullTimelineEvent, permissions) setState { copy( eventId = nonNullTimelineEvent.eventId, messageBody = computeMessageBody(nonNullTimelineEvent), - actions = actionsForEvent(nonNullTimelineEvent, permissions) + actions = events ) } } @@ -246,7 +247,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } } - private fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List { + private suspend fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List { val messageContent = timelineEvent.getLastMessageContent() val msgType = messageContent?.msgType @@ -317,7 +318,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted // TODO sent by me or sufficient power level } - private fun ArrayList.addActionsForSyncedState(timelineEvent: TimelineEvent, + private suspend fun ArrayList.addActionsForSyncedState(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions, messageContent: MessageContent?, msgType: String?) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index bd0ba075a5..e2283fef81 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -139,20 +139,18 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses } } - private fun getE2EDecoration(roomSummary: RoomSummary?, event: TimelineEvent): E2EDecoration { + private fun getE2EDecoration(roomSummary: RoomSummary?, event: TimelineEvent): E2EDecoration = runBlocking{ if (event.root.sendState != SendState.SYNCED) - return E2EDecoration.NONE + return@runBlocking E2EDecoration.NONE if (!roomSummary?.isEncrypted.orFalse()) - return E2EDecoration.NONE - val isUserVerified = runBlocking { - session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted().orFalse() - } + return@runBlocking E2EDecoration.NONE + val isUserVerified = session.cryptoService().crossSigningService().getUserCrossSigningKeys(event.root.senderId ?: "")?.isTrusted().orFalse() if (!isUserVerified) { - return E2EDecoration.NONE + return@runBlocking E2EDecoration.NONE } val ts = roomSummary?.encryptionEventTs ?: 0 val eventTs = event.root.originServerTs ?: 0 - return if (event.isEncrypted()) { + return@runBlocking if (event.isEncrypted()) { // Do not decorate failed to decrypt, or redaction (we lost sender device info) if (event.root.getClearType() == EventType.ENCRYPTED || event.root.isRedacted()) { E2EDecoration.NONE diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index ec034173fc..3cdc9e8c76 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -190,7 +190,7 @@ class NotifiableEventResolver @Inject constructor( } } - private fun TimelineEvent.attemptToDecryptIfNeeded(session: Session) { + private suspend fun TimelineEvent.attemptToDecryptIfNeeded(session: Session) { if (root.isEncrypted() && root.mxDecryptionResult == null) { // TODO use a global event decryptor? attache to session and that listen to new sessionId? // for now decrypt sync diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 95a7213b35..67cca1a083 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -70,12 +70,10 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import me.gujun.android.span.span -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.extensions.getFingerprintHumanReadable import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import javax.inject.Inject class VectorSettingsSecurityPrivacyFragment @Inject constructor( @@ -524,7 +522,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( /** * Build the cryptography preference section. */ - private fun refreshCryptographyPreference(devices: List) { + private suspend fun refreshCryptographyPreference(devices: List) { showDeviceListPref.isEnabled = devices.isNotEmpty() showDeviceListPref.summary = resources.getQuantityString(R.plurals.settings_active_sessions_count, devices.size, devices.size) @@ -580,28 +578,19 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( // ============================================================================================================== private fun refreshMyDevice() { - session.cryptoService().getUserDevices(session.myUserId).map { - DeviceInfo( - userId = session.myUserId, - deviceId = it.deviceId, - displayName = it.displayName() - ) - }.let { - refreshCryptographyPreference(it) + viewLifecycleOwner.lifecycleScope.launchWhenResumed { + session.cryptoService().getUserDevices(session.myUserId).map { + DeviceInfo( + userId = session.myUserId, + deviceId = it.deviceId, + displayName = it.displayName() + ) + }.let { + refreshCryptographyPreference(it) + } + // TODO Move to a ViewModel... + val devicesList = session.cryptoService().fetchDevicesList() + refreshCryptographyPreference(devicesList) } - // TODO Move to a ViewModel... - session.cryptoService().fetchDevicesList(object : MatrixCallback { - override fun onSuccess(data: DevicesListResponse) { - if (isAdded) { - refreshCryptographyPreference(data.devices.orEmpty()) - } - } - - override fun onFailure(failure: Throwable) { - if (isAdded) { - refreshCryptographyPreference(emptyList()) - } - } - }) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index 10cda3ad44..871109210a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -147,7 +147,7 @@ class DevicesViewModel @AssistedInject constructor( .sample(5_000) .onEach { // If we have a new crypto device change, we might want to trigger refresh of device info - session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) + session.cryptoService().fetchDevicesList() } .launchIn(viewModelScope) @@ -160,7 +160,7 @@ class DevicesViewModel @AssistedInject constructor( refreshSource.stream().throttleFirst(4_000) .onEach { - session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) + session.cryptoService().fetchDevicesList() session.cryptoService().downloadKeys(listOf(session.myUserId), true) } .launchIn(viewModelScope) From 91daa1ab90b5b27ed3f868470d669a043e844e6b Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Apr 2022 15:36:03 +0200 Subject: [PATCH 216/252] Suspend: continue cleaning --- .../sdk/api/session/crypto/CryptoService.kt | 2 +- .../crypto/keysbackup/KeysBackupService.kt | 11 ++-- .../internal/crypto/DefaultCryptoService.kt | 51 ++++++++++++++----- .../android/sdk/internal/crypto/OlmMachine.kt | 21 ++++---- .../sdk/internal/crypto/RequestSender.kt | 19 +++---- .../crypto/keysbackup/RustKeyBackupService.kt | 10 ++-- .../im/vector/app/core/extensions/Session.kt | 4 +- .../settings/KeysBackupSettingViewState.kt | 3 ++ ...eysBackupSettingsRecyclerViewController.kt | 5 +- .../settings/KeysBackupSettingsViewModel.kt | 51 ++++++++----------- .../app/features/home/HomeDrawerFragment.kt | 5 ++ .../signout/soft/SoftLogoutActivity.kt | 2 +- .../signout/soft/SoftLogoutController.kt | 4 +- .../signout/soft/SoftLogoutFragment.kt | 3 +- .../signout/soft/SoftLogoutViewModel.kt | 11 +++- .../signout/soft/SoftLogoutViewState.kt | 7 ++- .../signout/ServerBackupStatusViewModel.kt | 6 +-- .../workers/signout/SignOutUiWorker.kt | 8 +++ 18 files changed, 132 insertions(+), 91 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index d41e2aa11f..76e691d1be 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -100,7 +100,7 @@ interface CryptoService { fun getDeviceInfo(deviceId: String, callback: MatrixCallback) - fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int + suspend fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int fun isRoomEncrypted(roomId: String): Boolean diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index 6bb4dbc620..5a0ce933de 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -26,6 +26,7 @@ import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo interface KeysBackupService { + /** * Retrieve the current version of the backup from the homeserver * @@ -45,12 +46,12 @@ interface KeysBackupService { /** * Facility method to get the total number of locally stored keys */ - fun getTotalNumbersOfKeys(): Int + suspend fun getTotalNumbersOfKeys(): Int /** * Facility method to get the number of backed up keys */ - fun getTotalNumbersOfBackedUpKeys(): Int + suspend fun getTotalNumbersOfBackedUpKeys(): Int // /** // * Start to back up keys immediately. @@ -71,7 +72,7 @@ interface KeysBackupService { /** * Return the current progress of the backup */ - fun getBackupProgress(progressListener: ProgressListener) + suspend fun getBackupProgress(progressListener: ProgressListener) /** * Get information about a backup version defined on the homeserver. @@ -128,7 +129,7 @@ interface KeysBackupService { * Ask if the backup on the server contains keys that we may do not have locally. * This should be called when entering in the state READY_TO_BACKUP */ - fun canRestoreKeys(): Boolean + suspend fun canRestoreKeys(): Boolean /** * Set trust on a keys backup version. @@ -199,7 +200,7 @@ interface KeysBackupService { // For gossiping fun saveBackupRecoveryKey(recoveryKey: String?, version: String?) - fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? + suspend fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? suspend fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String): Boolean } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index e4c0e90f6d..6523839cdd 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -132,7 +132,7 @@ internal class DefaultCryptoService @Inject constructor( private val coroutineDispatchers: MatrixCoroutineDispatchers, private val taskExecutor: TaskExecutor, private val cryptoCoroutineScope: CoroutineScope, - private val sender: RequestSender, + private val requestSender: RequestSender, private val crossSigningService: CrossSigningService, private val verificationService: RustVerificationService, private val keysBackupService: RustKeyBackupService, @@ -248,7 +248,7 @@ internal class DefaultCryptoService @Inject constructor( .executeBy(taskExecutor) } - override fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int { + override suspend fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int { return if (onlyBackedUp) { keysBackupService.getTotalNumbersOfBackedUpKeys() } else { @@ -594,7 +594,6 @@ internal class DefaultCryptoService @Inject constructor( // Timber.e(throwable, "## CRYPTO | onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ") // } finally { val userIds = getRoomUserIds(roomId) - olmMachine.updateTrackedUsers(userIds) setEncryptionInRoom(roomId, event.content?.get("algorithm")?.toString(), userIds) // } } @@ -758,14 +757,18 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun uploadKeys(request: Request.KeysUpload) { - val response = this.sender.uploadKeys(request) - this.olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_UPLOAD, response) + try { + val response = requestSender.uploadKeys(request) + olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_UPLOAD, response) + } catch (throwable: Throwable) { + Timber.tag(loggerTag.value).e(throwable, "## CRYPTO uploadKeys(): error") + } } private suspend fun queryKeys(request: Request.KeysQuery) { try { - val response = this.sender.queryKeys(request) - this.olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_QUERY, response) + val response = requestSender.queryKeys(request) + olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_QUERY, response) // Update the shields! cryptoCoroutineScope.launch { @@ -781,18 +784,38 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun sendToDevice(request: Request.ToDevice) { - this.sender.sendToDevice(request) - olmMachine.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}") + try { + requestSender.sendToDevice(request) + olmMachine.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}") + } catch (throwable: Throwable) { + Timber.tag(loggerTag.value).e(throwable, "## CRYPTO sendToDevice(): error") + } } private suspend fun claimKeys(request: Request.KeysClaim) { - val response = this.sender.claimKeys(request) - olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, response) + try { + val response = requestSender.claimKeys(request) + olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, response) + } catch (throwable: Throwable) { + Timber.tag(loggerTag.value).e(throwable, "## CRYPTO claimKeys(): error") + } } private suspend fun signatureUpload(request: Request.SignatureUpload) { - this.sender.sendSignatureUpload(request) - olmMachine.markRequestAsSent(request.requestId, RequestType.SIGNATURE_UPLOAD, "{}") + try { + requestSender.sendSignatureUpload(request) + olmMachine.markRequestAsSent(request.requestId, RequestType.SIGNATURE_UPLOAD, "{}") + } catch (throwable: Throwable) { + Timber.tag(loggerTag.value).e(throwable, "## CRYPTO signatureUpload(): error") + } + } + + private suspend fun sendRoomMessage(request: Request.RoomMessage){ + try { + requestSender.sendRoomMessage(request) + } catch (throwable: Throwable) { + Timber.tag(loggerTag.value).e(throwable, "## CRYPTO sendRoomMessage(): error") + } } private suspend fun sendOutgoingRequests() { @@ -822,7 +845,7 @@ internal class DefaultCryptoService @Inject constructor( } is Request.RoomMessage -> { async { - sender.sendRoomMessage(it) + sendRoomMessage(it) } } is Request.SignatureUpload -> { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 42aed8e38f..6dfdc3cfcb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -833,21 +833,24 @@ internal class OlmMachine( } @Throws(CryptoStoreException::class) - fun roomKeyCounts(): RoomKeyCounts { - // TODO convert this to a suspendable method - return inner.roomKeyCounts() + suspend fun roomKeyCounts(): RoomKeyCounts { + return withContext(Dispatchers.Default) { + inner.roomKeyCounts() + } } @Throws(CryptoStoreException::class) - fun getBackupKeys(): BackupKeys? { - // TODO this needs to be suspendable - return inner.getBackupKeys() + suspend fun getBackupKeys(): BackupKeys? { + return withContext(Dispatchers.Default) { + inner.getBackupKeys() + } } @Throws(CryptoStoreException::class) - fun saveRecoveryKey(key: String?, version: String?) { - // TODO convert this to a suspendable method - inner.saveRecoveryKey(key, version) + suspend fun saveRecoveryKey(key: String?, version: String?) { + withContext(Dispatchers.Default) { + inner.saveRecoveryKey(key, version) + } } @Throws(CryptoStoreException::class) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt index 45644d951f..942afd336e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RequestSender.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto +import com.squareup.moshi.Moshi import com.squareup.moshi.Types import dagger.Lazy import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor @@ -80,6 +81,7 @@ internal class RequestSender @Inject constructor( private val getSessionsDataTask: GetSessionsDataTask, private val getRoomSessionsDataTask: GetRoomSessionsDataTask, private val getRoomSessionDataTask: GetRoomSessionDataTask, + private val moshi: Moshi ) { companion object { const val REQUEST_RETRY_COUNT = 3 @@ -97,16 +99,16 @@ internal class RequestSender @Inject constructor( suspend fun queryKeys(request: Request.KeysQuery): String { val params = DownloadKeysForUsersTask.Params(request.users, null) val response = downloadKeysForUsersTask.executeRetry(params, REQUEST_RETRY_COUNT) - val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) + val adapter = moshi.adapter(KeysQueryResponse::class.java) return adapter.toJson(response)!! } suspend fun uploadKeys(request: Request.KeysUpload): String { - val body = MoshiProvider.providesMoshi().adapter(Map::class.java).fromJson(request.body)!! + val body = moshi.adapter(Map::class.java).fromJson(request.body)!! val params = UploadKeysTask.Params(body) val response = uploadKeysTask.executeRetry(params, REQUEST_RETRY_COUNT) - val adapter = MoshiProvider.providesMoshi().adapter(KeysUploadResponse::class.java) + val adapter = moshi.adapter(KeysUploadResponse::class.java) return adapter.toJson(response)!! } @@ -127,7 +129,7 @@ internal class RequestSender @Inject constructor( } suspend fun sendRoomMessage(eventType: String, roomId: String, content: String, transactionId: String): String { - val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val adapter = moshi.adapter(Map::class.java) val jsonContent = adapter.fromJson(content) val event = Event(eventType, transactionId, jsonContent, roomId = roomId) val params = SendVerificationMessageTask.Params(event) @@ -143,7 +145,7 @@ internal class RequestSender @Inject constructor( } private suspend fun sendSignatureUpload(body: String) { - val adapter = MoshiProvider.providesMoshi().adapter>>(Map::class.java) + val adapter = moshi.adapter>>(Map::class.java) val signatures = adapter.fromJson(body)!! val params = UploadSignaturesTask.Params(signatures) this.signaturesUploadTask.executeRetry(params, REQUEST_RETRY_COUNT) @@ -153,7 +155,7 @@ internal class RequestSender @Inject constructor( request: UploadSigningKeysRequest, interactiveAuthInterceptor: UserInteractiveAuthInterceptor? ) { - val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) + val adapter = moshi.adapter(RestKeyInfo::class.java) val masterKey = adapter.fromJson(request.masterKey)!!.toCryptoModel() val selfSigningKey = adapter.fromJson(request.selfSigningKey)!!.toCryptoModel() val userSigningKey = adapter.fromJson(request.userSigningKey)!!.toCryptoModel() @@ -195,8 +197,7 @@ internal class RequestSender @Inject constructor( } suspend fun sendToDevice(eventType: String, body: String, transactionId: String) { - val adapter = MoshiProvider - .providesMoshi() + val adapter = moshi .newBuilder() .add(CheckNumberType.JSON_ADAPTER_FACTORY) .build() @@ -252,7 +253,7 @@ internal class RequestSender @Inject constructor( val keys = adapter.fromJson(request.rooms)!! val params = StoreSessionsDataTask.Params(request.version, KeysBackupData(keys)) val response = backupRoomKeysTask.executeRetry(params, REQUEST_RETRY_COUNT) - val responseAdapter = MoshiProvider.providesMoshi().adapter(BackupKeysResult::class.java) + val responseAdapter = moshi.adapter(BackupKeysResult::class.java) return responseAdapter.toJson(response)!! } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index d4864c8234..11c1117761 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -237,7 +237,7 @@ internal class RustKeyBackupService @Inject constructor( } } - override fun canRestoreKeys(): Boolean { + override suspend fun canRestoreKeys(): Boolean { val keyCountOnServer = keysBackupVersion?.count ?: return false val keyCountLocally = getTotalNumbersOfKeys() @@ -246,11 +246,11 @@ internal class RustKeyBackupService @Inject constructor( return keyCountLocally < keyCountOnServer } - override fun getTotalNumbersOfKeys(): Int { + override suspend fun getTotalNumbersOfKeys(): Int { return olmMachine.roomKeyCounts().total.toInt() } - override fun getTotalNumbersOfBackedUpKeys(): Int { + override suspend fun getTotalNumbersOfBackedUpKeys(): Int { return olmMachine.roomKeyCounts().backedUp.toInt() } @@ -405,7 +405,7 @@ internal class RustKeyBackupService @Inject constructor( } } - override fun getBackupProgress(progressListener: ProgressListener) { + override suspend fun getBackupProgress(progressListener: ProgressListener) { val backedUpKeys = getTotalNumbersOfBackedUpKeys() val total = getTotalNumbersOfKeys() @@ -725,7 +725,7 @@ internal class RustKeyBackupService @Inject constructor( } } - override fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? { + override suspend fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? { val info = olmMachine.getBackupKeys() ?: return null return SavedKeyBackupKeyInfo(info.recoveryKey, info.backupVersion) } diff --git a/vector/src/main/java/im/vector/app/core/extensions/Session.kt b/vector/src/main/java/im/vector/app/core/extensions/Session.kt index 87ed51522f..17e2949cda 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Session.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Session.kt @@ -64,12 +64,12 @@ fun Session.startSyncing(context: Context) { /** * Tell is the session has unsaved e2e keys in the backup */ -fun Session.hasUnsavedKeys(): Boolean { +suspend fun Session.hasUnsavedKeys(): Boolean { return cryptoService().inboundGroupSessionsCount(false) > 0 && cryptoService().keysBackupService().state != KeysBackupState.ReadyToBackUp } -fun Session.cannotLogoutSafely(): Boolean { +suspend fun Session.cannotLogoutSafely(): Boolean { // has some encrypted chat return hasUnsavedKeys() || // has local cross signing keys diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt index 438b502b42..9e2fa10bd3 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt @@ -26,5 +26,8 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionR data class KeysBackupSettingViewState(val keysBackupVersionTrust: Async = Uninitialized, val keysBackupState: KeysBackupState? = null, val keysBackupVersion: KeysVersionResult? = null, + val remainingKeysToBackup: Int = 0, val deleteBackupRequest: Async = Uninitialized) : MavericksState + + diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt index 577572ef14..c177cf5da8 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt @@ -124,10 +124,7 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor( style(ItemStyle.BIG_TEXT) hasIndeterminateProcess(true) - val totalKeys = host.session.cryptoService().inboundGroupSessionsCount(false) - val backedUpKeys = host.session.cryptoService().inboundGroupSessionsCount(true) - - val remainingKeysToBackup = totalKeys - backedUpKeys + val remainingKeysToBackup = data.remainingKeysToBackup if (data.keysBackupVersionTrust()?.usable == false) { description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup).toEpoxyCharSequence()) diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index 51213fcd38..8ca14e562a 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -18,7 +18,6 @@ package im.vector.app.features.crypto.keysbackup.settings import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -32,7 +31,6 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener -import timber.log.Timber class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState, session: Session @@ -46,6 +44,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + private val cryptoService = session.cryptoService() private val keysBackupService: KeysBackupService = session.cryptoService().keysBackupService() init { @@ -75,34 +74,12 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS private fun getKeysBackupTrust() = withState { state -> val versionResult = keysBackupService.keysBackupVersion - Timber.d("BACKUP: HEEEEEEE $versionResult ${state.keysBackupVersionTrust}") - if (state.keysBackupVersionTrust is Uninitialized && versionResult != null) { - setState { - copy( - keysBackupVersionTrust = Loading(), - deleteBackupRequest = Uninitialized - ) - } - Timber.d("BACKUP: HEEEEEEE TWO") - - viewModelScope.launch { - try { - val data = keysBackupService.getKeysBackupTrust(versionResult) - Timber.d("BACKUP: HEEEE suceeeded $data") - setState { - copy( - keysBackupVersionTrust = Success(data) - ) - } - } catch (failure: Throwable) { - Timber.d("BACKUP: HEEEE FAILED $failure") - setState { - copy( - keysBackupVersionTrust = Fail(failure) - ) - } - } + setState { copy(deleteBackupRequest = Uninitialized) } + suspend { + keysBackupService.getKeysBackupTrust(versionResult) + }.execute { + copy(keysBackupVersionTrust = it) } } } @@ -119,10 +96,24 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS keysBackupVersion = keysBackupService.keysBackupVersion ) } - + when (newState) { + KeysBackupState.BackingUp, KeysBackupState.WillBackUp -> updateKeysCount() + else -> Unit + } getKeysBackupTrust() } + private fun updateKeysCount() { + viewModelScope.launch { + val totalKeys = cryptoService.inboundGroupSessionsCount(false) + val backedUpKeys = cryptoService.inboundGroupSessionsCount(true) + val remainingKeysToBackup = totalKeys - backedUpKeys + setState { + copy(remainingKeysToBackup = remainingKeysToBackup) + } + } + } + private fun deleteCurrentBackup() { val keysBackupService = keysBackupService diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt index 1aee0257f4..174bd94706 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt @@ -80,6 +80,7 @@ class HomeDrawerFragment @Inject constructor( } // Sign out views.homeDrawerHeaderSignoutView.debouncedClicks { + signout() sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer) SignOutUiWorker(requireActivity()).perform() } @@ -118,4 +119,8 @@ class HomeDrawerFragment @Inject constructor( navigator.openDebug(requireActivity()) } } + + private fun signout() { + + } } diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt index 9acc81d0c2..bf445a7c34 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt @@ -95,7 +95,7 @@ class SoftLogoutActivity : LoginActivity() { MainActivity.restartApp(this, MainActivityArgs()) } - views.loginLoading.isVisible = softLogoutViewState.isLoading() + views.loginLoading.isVisible = softLogoutViewState.isLoading } companion object { diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt index 0cd9cde547..74ce1ef615 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt @@ -34,6 +34,7 @@ import im.vector.app.features.signout.soft.epoxy.loginRedButtonItem import im.vector.app.features.signout.soft.epoxy.loginTextItem import im.vector.app.features.signout.soft.epoxy.loginTitleItem import im.vector.app.features.signout.soft.epoxy.loginTitleSmallItem +import org.matrix.android.sdk.api.extensions.orFalse import javax.inject.Inject class SoftLogoutController @Inject constructor( @@ -52,6 +53,7 @@ class SoftLogoutController @Inject constructor( override fun buildModels() { val safeViewState = viewState ?: return + if (safeViewState.hasUnsavedKeys is Incomplete) return buildHeader(safeViewState) buildForm(safeViewState) @@ -78,7 +80,7 @@ class SoftLogoutController @Inject constructor( state.userDisplayName, state.userId)) } - if (state.hasUnsavedKeys) { + if (state.hasUnsavedKeys().orFalse()) { loginTextItem { id("signText2") text(host.stringProvider.getString(R.string.soft_logout_signin_e2e_warning_notice)) diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt index f40f35a6e2..44696f9505 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt @@ -32,6 +32,7 @@ import im.vector.app.features.login.AbstractLoginFragment import im.vector.app.features.login.LoginAction import im.vector.app.features.login.LoginMode import im.vector.app.features.login.LoginViewEvents +import org.matrix.android.sdk.api.extensions.orFalse import javax.inject.Inject /** @@ -118,7 +119,7 @@ class SoftLogoutFragment @Inject constructor( withState(softLogoutViewModel) { state -> cleanupUi() - val messageResId = if (state.hasUnsavedKeys) { + val messageResId = if (state.hasUnsavedKeys().orFalse()) { R.string.soft_logout_clear_data_dialog_e2e_warning_content } else { R.string.soft_logout_clear_data_dialog_content diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt index 00422d8872..7bc88c2b7e 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt @@ -69,7 +69,6 @@ class SoftLogoutViewModel @AssistedInject constructor( userId = userId, deviceId = session.sessionParams.deviceId.orEmpty(), userDisplayName = session.getUser(userId)?.displayName ?: userId, - hasUnsavedKeys = session.hasUnsavedKeys() ) } else { SoftLogoutViewState( @@ -77,17 +76,25 @@ class SoftLogoutViewModel @AssistedInject constructor( userId = "", deviceId = "", userDisplayName = "", - hasUnsavedKeys = false ) } } } init { + checkHasUnsavedKeys() // Get the supported login flow getSupportedLoginFlow() } + private fun checkHasUnsavedKeys() { + suspend { + session.hasUnsavedKeys() + }.execute { + copy(hasUnsavedKeys = it) + } + } + private fun getSupportedLoginFlow() { viewModelScope.launch { authenticationService.cancelPendingLoginOrRegistration() diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt index 511711ab2f..2bed442fe8 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewState.kt @@ -30,13 +30,12 @@ data class SoftLogoutViewState( val userId: String, val deviceId: String, val userDisplayName: String, - val hasUnsavedKeys: Boolean, + val hasUnsavedKeys: Async = Uninitialized, val enteredPassword: String = "" ) : MavericksState { - fun isLoading(): Boolean { - return asyncLoginAction is Loading || + val isLoading: Boolean = + asyncLoginAction is Loading || // Keep loading when it is success because of the delay to switch to the next Activity asyncLoginAction is Success - } } diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt index ded42e23e0..c35363d66f 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt @@ -130,14 +130,14 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS /** * Safe way to get the number of keys to backup */ - fun getNumberOfKeysToBackup(): Int { + private suspend fun getNumberOfKeysToBackup(): Int { return session.cryptoService().inboundGroupSessionsCount(false) } /** * Safe way to tell if there are more keys on the server */ - fun canRestoreKeys(): Boolean { + private suspend fun canRestoreKeys(): Boolean { return session.cryptoService().keysBackupService().canRestoreKeys() } @@ -161,5 +161,5 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS } } - override fun handle(action: EmptyAction) {} + override fun handle(action: EmptyAction) = Unit } diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutUiWorker.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutUiWorker.kt index 29c094bff4..66b69fd53c 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutUiWorker.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutUiWorker.kt @@ -17,17 +17,25 @@ package im.vector.app.features.workers.signout import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.core.extensions.cannotLogoutSafely import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.session.Session class SignOutUiWorker(private val activity: FragmentActivity) { fun perform() { val session = activity.singletonEntryPoint().activeSessionHolder().getSafeActiveSession() ?: return + activity.lifecycleScope.perform(session) + } + + private fun CoroutineScope.perform(session: Session) = launch { if (session.cannotLogoutSafely()) { // The backup check on logout flow has to be displayed if there are keys in the store, and the keys backup state is not Ready val signOutDialog = SignOutBottomSheetDialogFragment.newInstance() From d020d1f6e09e48d0d5966b6569d0ee794d65cb62 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Apr 2022 16:33:48 +0200 Subject: [PATCH 217/252] Use MatrixCoroutineDispatchers in OlmMachine --- .../android/sdk/internal/crypto/OlmMachine.kt | 57 ++++++++++--------- .../sdk/internal/crypto/OlmMachineProvider.kt | 6 +- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 6dfdc3cfcb..aa6a1abc7d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -16,13 +16,13 @@ package org.matrix.android.sdk.internal.crypto -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.listeners.ProgressListener @@ -102,6 +102,7 @@ internal class OlmMachine( device_id: String, path: File, private val requestSender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers ) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) internal val verificationListeners = ArrayList() @@ -182,7 +183,7 @@ internal class OlmMachine( * @return the list of requests that needs to be sent to the homeserver */ suspend fun outgoingRequests(): List = - withContext(Dispatchers.IO) { inner.outgoingRequests() } + withContext(coroutineDispatchers.io) { inner.outgoingRequests() } /** * Mark a request that was sent to the server as sent. @@ -199,7 +200,7 @@ internal class OlmMachine( requestType: RequestType, responseBody: String ) = - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { inner.markRequestAsSent(requestId, requestType, responseBody) if (requestType == RequestType.KEYS_QUERY) { @@ -227,7 +228,7 @@ internal class OlmMachine( deviceChanges: DeviceListResponse?, keyCounts: DeviceOneTimeKeysCountSyncResponse? ): ToDeviceSyncResponse { - val response = withContext(Dispatchers.IO) { + val response = withContext(coroutineDispatchers.io) { val counts: MutableMap = mutableMapOf() if (keyCounts?.signedCurve25519 != null) { @@ -260,7 +261,7 @@ internal class OlmMachine( * @param users The users that should be queued up for a key query. */ suspend fun updateTrackedUsers(users: List) = - withContext(Dispatchers.IO) { inner.updateTrackedUsers(users) } + withContext(coroutineDispatchers.io) { inner.updateTrackedUsers(users) } /** * Check if the given user is considered to be tracked. @@ -286,7 +287,7 @@ internal class OlmMachine( */ @Throws(CryptoStoreException::class) suspend fun getMissingSessions(users: List): Request? = - withContext(Dispatchers.IO) { inner.getMissingSessions(users) } + withContext(coroutineDispatchers.io) { inner.getMissingSessions(users) } /** * Share a room key with the given list of users for the given room. @@ -308,7 +309,7 @@ internal class OlmMachine( */ @Throws(CryptoStoreException::class) suspend fun shareRoomKey(roomId: String, users: List): List = - withContext(Dispatchers.IO) { inner.shareRoomKey(roomId, users) } + withContext(coroutineDispatchers.io) { inner.shareRoomKey(roomId, users) } /** * Encrypt the given event with the given type and content for the given room. @@ -342,7 +343,7 @@ internal class OlmMachine( */ @Throws(CryptoStoreException::class) suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) val contentString = adapter.toJson(content) val encrypted = inner.encrypt(roomId, eventType, contentString) @@ -360,7 +361,7 @@ internal class OlmMachine( */ @Throws(MXCryptoError::class) suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) try { if (event.roomId.isNullOrBlank()) { @@ -400,7 +401,7 @@ internal class OlmMachine( */ @Throws(DecryptionException::class) suspend fun requestRoomKey(event: Event): KeyRequestPair = - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) val serializedEvent = adapter.toJson(event) @@ -419,7 +420,7 @@ internal class OlmMachine( */ @Throws(CryptoStoreException::class) suspend fun exportKeys(passphrase: String, rounds: Int): ByteArray = - withContext(Dispatchers.IO) { inner.exportKeys(passphrase, rounds).toByteArray() } + withContext(coroutineDispatchers.io) { inner.exportKeys(passphrase, rounds).toByteArray() } /** * Import room keys from the given serialized key export. @@ -436,7 +437,7 @@ internal class OlmMachine( passphrase: String, listener: ProgressListener? ): ImportRoomKeysResult = - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { val decodedKeys = String(keys, Charset.defaultCharset()) val rustListener = CryptoProgressListener(listener) @@ -451,7 +452,7 @@ internal class OlmMachine( keys: List, listener: ProgressListener? ): ImportRoomKeysResult = - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { val adapter = MoshiProvider.providesMoshi().adapter(List::class.java) // If the key backup is too big we take the risk of causing OOM @@ -481,7 +482,7 @@ internal class OlmMachine( @Throws(CryptoStoreException::class) suspend fun getIdentity(userId: String): UserIdentities? { - val identity = withContext(Dispatchers.IO) { + val identity = withContext(coroutineDispatchers.io) { inner.getIdentity(userId) } val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) @@ -547,7 +548,7 @@ internal class OlmMachine( @Throws(CryptoStoreException::class) suspend fun getDevice(userId: String, deviceId: String): Device? { - val device = withContext(Dispatchers.IO) { + val device = withContext(coroutineDispatchers.io) { inner.getDevice(userId, deviceId) } ?: return null @@ -555,7 +556,7 @@ internal class OlmMachine( } suspend fun getUserDevices(userId: String): List { - return withContext(Dispatchers.IO) { + return withContext(coroutineDispatchers.io) { inner.getUserDevices(userId).map { Device(inner, it, requestSender, verificationListeners) } } } @@ -600,7 +601,7 @@ internal class OlmMachine( @Throws suspend fun forceKeyDownload(userIds: List) { - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { val requestId = UUID.randomUUID().toString() val response = requestSender.queryKeys(Request.KeysQuery(requestId, userIds)) markRequestAsSent(requestId, RequestType.KEYS_QUERY, response) @@ -759,7 +760,7 @@ internal class OlmMachine( } suspend fun bootstrapCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?) { - val requests = withContext(Dispatchers.IO) { + val requests = withContext(coroutineDispatchers.io) { inner.bootstrapCrossSigning() } @@ -775,7 +776,7 @@ internal class OlmMachine( } suspend fun exportCrossSigningKeys(): PrivateKeysInfo? { - val export = withContext(Dispatchers.IO) { + val export = withContext(coroutineDispatchers.io) { inner.exportCrossSigningKeys() } ?: return null @@ -786,7 +787,7 @@ internal class OlmMachine( val rustExport = CrossSigningKeyExport(export.master, export.selfSigned, export.user) var result: UserTrustResult - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { result = try { inner.importCrossSigningKeys(rustExport) @@ -803,21 +804,21 @@ internal class OlmMachine( UserTrustResult.Failure(failure.localizedMessage) } } - withContext(Dispatchers.Main) { + withContext(coroutineDispatchers.main) { this@OlmMachine.updateLivePrivateKeys() } return result } suspend fun sign(message: String): Map> { - return withContext(Dispatchers.Default) { + return withContext(coroutineDispatchers.computation) { inner.sign(message) } } @Throws(CryptoStoreException::class) suspend fun enableBackupV1(key: String, version: String) { - return withContext(Dispatchers.Default) { + return withContext(coroutineDispatchers.computation) { val backupKey = MegolmV1BackupKey(key, mapOf(), null, MXCRYPTO_ALGORITHM_MEGOLM_BACKUP) inner.enableBackupV1(backupKey, version) } @@ -834,28 +835,28 @@ internal class OlmMachine( @Throws(CryptoStoreException::class) suspend fun roomKeyCounts(): RoomKeyCounts { - return withContext(Dispatchers.Default) { + return withContext(coroutineDispatchers.computation) { inner.roomKeyCounts() } } @Throws(CryptoStoreException::class) suspend fun getBackupKeys(): BackupKeys? { - return withContext(Dispatchers.Default) { + return withContext(coroutineDispatchers.computation) { inner.getBackupKeys() } } @Throws(CryptoStoreException::class) suspend fun saveRecoveryKey(key: String?, version: String?) { - withContext(Dispatchers.Default) { + withContext(coroutineDispatchers.computation) { inner.saveRecoveryKey(key, version) } } @Throws(CryptoStoreException::class) suspend fun backupRoomKeys(): Request? { - return withContext(Dispatchers.Default) { + return withContext(coroutineDispatchers.computation) { Timber.d("BACKUP CREATING REQUEST") val request = inner.backupRoomKeys() Timber.d("BACKUP CREATED REQUEST: $request") @@ -865,7 +866,7 @@ internal class OlmMachine( @Throws(CryptoStoreException::class) suspend fun checkAuthDataSignature(authData: MegolmBackupAuthData): Boolean { - return withContext(Dispatchers.Default) { + return withContext(coroutineDispatchers.computation) { val adapter = MoshiProvider .providesMoshi() .newBuilder() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt index 6aa59afc69..513a9297d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.UserId @@ -28,8 +29,9 @@ internal class OlmMachineProvider @Inject constructor( @UserId private val userId: String, @DeviceId private val deviceId: String?, @SessionFilesDirectory private val dataDir: File, - requestSender: RequestSender + requestSender: RequestSender, + coroutineDispatchers: MatrixCoroutineDispatchers ) { - var olmMachine: OlmMachine = OlmMachine(userId, deviceId!!, dataDir, requestSender) + var olmMachine: OlmMachine = OlmMachine(userId, deviceId!!, dataDir, requestSender, coroutineDispatchers) } From ba540eb861bdaf85816a1fa7436950e12cb9165e Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 15 Apr 2022 11:17:06 +0200 Subject: [PATCH 218/252] Continue removing runBlocking + some cleanup --- .../sdk/api/session/crypto/CryptoService.kt | 9 +- .../internal/crypto/DefaultCryptoService.kt | 104 ++++++++---------- .../internal/crypto/tasks/EncryptEventTask.kt | 75 ++++++------- .../sdk/internal/session/room/DefaultRoom.kt | 5 +- .../VerificationBottomSheetViewModel.kt | 51 +++------ 5 files changed, 99 insertions(+), 145 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 76e691d1be..671128f268 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -66,7 +66,7 @@ interface CryptoService { suspend fun getUserDevices(userId: String): MutableList - fun getMyDevice(): CryptoDeviceInfo + suspend fun getMyDevice(): CryptoDeviceInfo fun getGlobalBlacklistUnverifiedDevices(): Boolean @@ -104,10 +104,9 @@ interface CryptoService { fun isRoomEncrypted(roomId: String): Boolean - fun encryptEventContent(eventContent: Content, + suspend fun encryptEventContent(eventContent: Content, eventType: String, - roomId: String, - callback: MatrixCallback) + roomId: String): MXEncryptEventContentResult fun discardOutboundSession(roomId: String) @@ -151,7 +150,7 @@ interface CryptoService { * Perform any background tasks that can be done before a message is ready to * send, in order to speed up sending of the message. */ - fun prepareToEncrypt(roomId: String, callback: MatrixCallback) + suspend fun prepareToEncrypt(roomId: String) /** * When LL all room members might not be loaded when setting up encryption. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 6523839cdd..6abcd0f8a5 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -22,13 +22,13 @@ import androidx.lifecycle.LiveData import androidx.paging.PagedList import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.async import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext @@ -76,7 +76,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.StreamEventsManager import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask @@ -219,8 +218,8 @@ internal class DefaultCryptoService @Inject constructor( return if (longFormat) "Rust SDK 0.3" else "0.3" } - override fun getMyDevice(): CryptoDeviceInfo { - return runBlocking { olmMachine.ownDevice() } + override suspend fun getMyDevice(): CryptoDeviceInfo { + return olmMachine.ownDevice() } override suspend fun fetchDevicesList(): List { @@ -344,9 +343,13 @@ internal class DefaultCryptoService @Inject constructor( /** * Close the crypto */ - fun close() = runBlocking(coroutineDispatchers.crypto) { + fun close() { cryptoCoroutineScope.coroutineContext.cancelChildren(CancellationException("Closing crypto module")) - cryptoStore.close() + cryptoCoroutineScope.launch { + withContext(coroutineDispatchers.crypto + NonCancellable) { + cryptoStore.close() + } + } } // Always enabled on Matrix Android SDK2 @@ -513,34 +516,29 @@ internal class DefaultCryptoService @Inject constructor( * @param eventContent the content of the event. * @param eventType the type of the event. * @param roomId the room identifier the event will be sent. - * @param callback the asynchronous callback */ - override fun encryptEventContent(eventContent: Content, - eventType: String, - roomId: String, - callback: MatrixCallback) { + override suspend fun encryptEventContent(eventContent: Content, + eventType: String, + roomId: String): MXEncryptEventContentResult { // moved to crypto scope to have up to date values - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { + return withContext(coroutineDispatchers.crypto) { val algorithm = getEncryptionAlgorithm(roomId) - if (algorithm != null) { val userIds = getRoomUserIds(roomId) val t0 = System.currentTimeMillis() Timber.tag(loggerTag.value).v("encryptEventContent() starts") - runCatching { - measureTimeMillis { - preshareRoomKey(roomId, userIds) - }.also { - Timber.d("Shared room key in room $roomId took $it ms") - } - val content = encrypt(roomId, eventType, eventContent) - Timber.tag(loggerTag.value).v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms") - MXEncryptEventContentResult(content, EventType.ENCRYPTED) - }.foldToCallback(callback) + measureTimeMillis { + preshareRoomKey(roomId, userIds) + }.also { + Timber.d("Shared room key in room $roomId took $it ms") + } + val content = encrypt(roomId, eventType, eventContent) + Timber.tag(loggerTag.value).v("## CRYPTO | encryptEventContent() : succeeds after ${System.currentTimeMillis() - t0} ms") + MXEncryptEventContentResult(content, EventType.ENCRYPTED) } else { val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, MXCryptoError.NO_MORE_ALGORITHM_REASON) Timber.tag(loggerTag.value).e("encryptEventContent() : failed $reason") - callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason))) + throw Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason)) } } } @@ -707,26 +705,12 @@ internal class DefaultCryptoService @Inject constructor( } private suspend fun preshareRoomKey(roomId: String, roomMembers: List) { - keyClaimLock.withLock { - val request = this.olmMachine.getMissingSessions(roomMembers) - // This request can only be a keys claim request. - if (request != null) { - when (request) { - is Request.KeysClaim -> { - claimKeys(request) - } - else -> { - } - } - } - } - - val keyShareLock = roomKeyShareLocks.getOrPut(roomId, { Mutex() }) + claimMissingKeys(roomMembers) + val keyShareLock = roomKeyShareLocks.getOrPut(roomId) { Mutex() } var sharedKey = false - keyShareLock.withLock { coroutineScope { - this@DefaultCryptoService.olmMachine.shareRoomKey(roomId, roomMembers).map { + olmMachine.shareRoomKey(roomId, roomMembers).map { when (it) { is Request.ToDevice -> { sharedKey = true @@ -752,6 +736,18 @@ internal class DefaultCryptoService @Inject constructor( } } + private suspend fun claimMissingKeys(roomMembers: List) = keyClaimLock.withLock { + val request = this.olmMachine.getMissingSessions(roomMembers) + // This request can only be a keys claim request. + when (request) { + is Request.KeysClaim -> { + claimKeys(request) + } + else -> { + } + } + } + private suspend fun encrypt(roomId: String, eventType: String, content: Content): Content { return olmMachine.encrypt(roomId, eventType, content) } @@ -810,7 +806,7 @@ internal class DefaultCryptoService @Inject constructor( } } - private suspend fun sendRoomMessage(request: Request.RoomMessage){ + private suspend fun sendRoomMessage(request: Request.RoomMessage) { try { requestSender.sendRoomMessage(request) } catch (throwable: Throwable) { @@ -1083,18 +1079,16 @@ internal class DefaultCryptoService @Inject constructor( cryptoStore.logDbUsageInfo() } - override fun prepareToEncrypt(roomId: String, callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { + override suspend fun prepareToEncrypt(roomId: String) { + withContext(coroutineDispatchers.crypto) { Timber.tag(loggerTag.value).d("prepareToEncrypt() roomId:$roomId Check room members up to date") // Ensure to load all room members try { loadRoomMembersTask.execute(LoadRoomMembersTask.Params(roomId)) } catch (failure: Throwable) { Timber.tag(loggerTag.value).e("prepareToEncrypt() : Failed to load room members") - callback.onFailure(failure) - return@launch + throw failure } - val userIds = getRoomUserIds(roomId) val algorithm = getEncryptionAlgorithm(roomId) @@ -1102,19 +1096,13 @@ internal class DefaultCryptoService @Inject constructor( if (algorithm == null) { val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON, MXCryptoError.NO_MORE_ALGORITHM_REASON) Timber.tag(loggerTag.value).e("prepareToEncrypt() : $reason") - callback.onFailure(IllegalArgumentException("Missing algorithm")) - return@launch + throw IllegalArgumentException("Missing algorithm") } - - runCatching { + try { preshareRoomKey(roomId, userIds) - }.fold( - { callback.onSuccess(Unit) }, - { - Timber.tag(loggerTag.value).e(it, "prepareToEncrypt() failed.") - callback.onFailure(it) - } - ) + }catch (failure: Throwable){ + Timber.tag(loggerTag.value).e("prepareToEncrypt() : Failed to PreshareRoomKey") + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt index 627352f568..ac49102a07 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt @@ -22,11 +22,9 @@ import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult -import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository import org.matrix.android.sdk.internal.task.Task -import org.matrix.android.sdk.internal.util.awaitCallback import javax.inject.Inject internal interface EncryptEventTask : Task { @@ -56,47 +54,44 @@ internal class DefaultEncryptEventTask @Inject constructor( localMutableContent.remove(it) } -// try { // let it throws - awaitCallback { - cryptoService.encryptEventContent(localMutableContent, localEvent.type, params.roomId, it) - }.let { result -> - val modifiedContent = HashMap(result.eventContent) - params.keepKeys?.forEach { toKeep -> - localEvent.content?.get(toKeep)?.let { - // put it back in the encrypted thing - modifiedContent[toKeep] = it - } - } - val safeResult = result.copy(eventContent = modifiedContent) - // Better handling of local echo, to avoid decrypting transition on remote echo - // Should I only do it for text messages? - val decryptionLocalEcho = if (result.eventContent["algorithm"] == MXCRYPTO_ALGORITHM_MEGOLM) { - MXEventDecryptionResult( - clearEvent = Event( - type = localEvent.type, - content = localEvent.content, - roomId = localEvent.roomId - ).toContent(), - forwardingCurve25519KeyChain = emptyList(), - senderCurve25519Key = result.eventContent["sender_key"] as? String, - claimedEd25519Key = cryptoService.getMyDevice().fingerprint() - ) - } else { - null - } + val result = cryptoService.encryptEventContent(localMutableContent, localEvent.type, params.roomId) - localEchoRepository.updateEcho(localEvent.eventId) { _, localEcho -> - localEcho.type = EventType.ENCRYPTED - localEcho.content = ContentMapper.map(modifiedContent) - decryptionLocalEcho?.also { - localEcho.setDecryptionResult(it) - } + val modifiedContent = HashMap(result.eventContent) + params.keepKeys?.forEach { toKeep -> + localEvent.content?.get(toKeep)?.let { + // put it back in the encrypted thing + modifiedContent[toKeep] = it } - return localEvent.copy( - type = safeResult.eventType, - content = safeResult.eventContent - ) } + val safeResult = result.copy(eventContent = modifiedContent) + // Better handling of local echo, to avoid decrypting transition on remote echo + // Should I only do it for text messages? + val decryptionLocalEcho = if (result.eventContent["algorithm"] == MXCRYPTO_ALGORITHM_MEGOLM) { + MXEventDecryptionResult( + clearEvent = Event( + type = localEvent.type, + content = localEvent.content, + roomId = localEvent.roomId + ).toContent(), + forwardingCurve25519KeyChain = emptyList(), + senderCurve25519Key = result.eventContent["sender_key"] as? String, + claimedEd25519Key = cryptoService.getMyDevice().fingerprint() + ) + } else { + null + } + + localEchoRepository.updateEcho(localEvent.eventId) { _, localEcho -> + localEcho.type = EventType.ENCRYPTED + localEcho.content = ContentMapper.map(modifiedContent) + decryptionLocalEcho?.also { + localEcho.setDecryptionResult(it) + } + } + return localEvent.copy( + type = safeResult.eventType, + content = safeResult.eventContent + ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt index 2d8c3e9c78..a0c3ac23b3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt @@ -49,7 +49,6 @@ import org.matrix.android.sdk.internal.session.room.state.SendStateTask import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.session.search.SearchTask import org.matrix.android.sdk.internal.session.space.DefaultSpace -import org.matrix.android.sdk.internal.util.awaitCallback import java.security.InvalidParameterException internal class DefaultRoom(override val roomId: String, @@ -117,9 +116,7 @@ internal class DefaultRoom(override val roomId: String, } override suspend fun prepareToEncrypt() { - awaitCallback { - cryptoService.prepareToEncrypt(roomId, it) - } + cryptoService.prepareToEncrypt(roomId) } override suspend fun enableEncryption(algorithm: String, force: Boolean) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index f3a272c3e8..5fc752028f 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -16,8 +16,6 @@ package im.vector.app.features.crypto.verification import com.airbnb.mvrx.Async -import com.airbnb.mvrx.Fail -import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Success @@ -358,44 +356,21 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( private fun handleRequestVerificationByDM(roomId: String?, otherUserId: String) { viewModelScope.launch { - if (roomId == null) { - val localId = LocalEcho.createLocalEchoId() - setState { - copy( - pendingLocalId = localId, - pendingRequest = Loading() - ) - } - try { - val dmRoomId = session.createDirectRoom(otherUserId) - val pendingRequest = session - .cryptoService() - .verificationService() - .requestKeyVerificationInDMs( - supportedVerificationMethodsProvider.provide(), - otherUserId, - dmRoomId, - localId - ) - setState { - copy( - roomId = dmRoomId, - pendingRequest = Success(pendingRequest) - ) - } - } catch (failure: Throwable) { - setState { - copy(pendingRequest = Fail(failure)) - } - } - } else { - val pendingRequest = session + val localId = LocalEcho.createLocalEchoId() + val dmRoomId = roomId ?: session.createDirectRoom(otherUserId) + setState { copy(pendingLocalId = localId, roomId = dmRoomId) } + suspend { + session .cryptoService() .verificationService() - .requestKeyVerificationInDMs(supportedVerificationMethodsProvider.provide(), otherUserId, roomId) - setState { - copy(pendingRequest = Success(pendingRequest)) - } + .requestKeyVerificationInDMs( + supportedVerificationMethodsProvider.provide(), + otherUserId, + dmRoomId, + localId + ) + }.execute { + copy(pendingRequest = it, roomId = dmRoomId) } } } From 9cb43ce4c8ee3372cf3f0624654896031efc1f57 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 15 Apr 2022 18:52:35 +0200 Subject: [PATCH 219/252] Continue cleaning mostly on coroutine --- .../crosssigning/CrossSigningService.kt | 13 +- .../internal/crypto/DefaultCryptoService.kt | 13 +- .../android/sdk/internal/crypto/Device.kt | 47 ++--- .../android/sdk/internal/crypto/OlmMachine.kt | 162 +++++++++++------- .../sdk/internal/crypto/OlmMachineProvider.kt | 12 +- .../sdk/internal/crypto/QrCodeVerification.kt | 32 ++-- .../crypto/RustCrossSigningService.kt | 12 +- .../sdk/internal/crypto/SasVerification.kt | 45 ++--- .../sdk/internal/crypto/UserIdentities.kt | 69 ++++---- .../internal/crypto/VerificationRequest.kt | 133 +++++++------- .../crypto/keysbackup/RustKeyBackupService.kt | 11 +- 11 files changed, 304 insertions(+), 245 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index 70330171c5..df8265a051 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.api.session.crypto.crosssigning -import androidx.lifecycle.LiveData import kotlinx.coroutines.flow.Flow import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor @@ -62,8 +61,8 @@ interface CrossSigningService { * by the server and if they do so */ suspend fun checkTrustFromPrivateKeys(masterKeyPrivateKey: String?, - uskKeyPrivateKey: String?, - sskPrivateKey: String?): UserTrustResult + uskKeyPrivateKey: String?, + sskPrivateKey: String?): UserTrustResult /** * Get the public cross signing keys for the given user @@ -94,7 +93,7 @@ interface CrossSigningService { /** Mark a user identity as trusted and sign and upload signatures of our user-signing key to the server */ suspend fun trustUser(otherUserId: String, - callback: MatrixCallback) + callback: MatrixCallback) /** Mark our own master key as trusted */ suspend fun markMyMasterKeyAsTrusted() @@ -115,9 +114,9 @@ interface CrossSigningService { * key of another user. */ suspend fun checkDeviceTrust(otherUserId: String, - otherDeviceId: String, - // TODO what is locallyTrusted used for? - locallyTrusted: Boolean?): DeviceTrustResult + otherDeviceId: String, + // TODO what is locallyTrusted used for? + locallyTrusted: Boolean?): DeviceTrustResult // FIXME Those method do not have to be in the service // TODO those three methods doesn't seem to be used anywhere? diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 6abcd0f8a5..c33885b925 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -988,18 +988,17 @@ internal class DefaultCryptoService @Inject constructor( val cancellation = requestPair.cancellation val request = requestPair.keyRequest - if (cancellation != null) { - when (cancellation) { - is Request.ToDevice -> { - sendToDevice(cancellation) - } + when (cancellation) { + is Request.ToDevice -> { + sendToDevice(cancellation) } + else -> Unit } - when (request) { is Request.ToDevice -> { sendToDevice(request) } + else -> Unit } } } @@ -1100,7 +1099,7 @@ internal class DefaultCryptoService @Inject constructor( } try { preshareRoomKey(roomId, userIds) - }catch (failure: Throwable){ + } catch (failure: Throwable) { Timber.tag(loggerTag.value).e("prepareToEncrypt() : Failed to PreshareRoomKey") } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index 9ef3cb200a..e07ab4db2a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel @@ -39,16 +39,17 @@ internal class Device( private val machine: OlmMachine, private var inner: InnerDevice, private val sender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers, private val listeners: ArrayList ) { @Throws(CryptoStoreException::class) private suspend fun refreshData() { - val device = withContext(Dispatchers.IO) { + val device = withContext(coroutineDispatchers.io) { machine.getDevice(inner.userId, inner.deviceId) } if (device != null) { - this.inner = device + inner = device } } @@ -66,12 +67,12 @@ internal class Device( @Throws(CryptoStoreException::class) suspend fun requestVerification(methods: List): VerificationRequest? { val stringMethods = prepareMethods(methods) - val result = withContext(Dispatchers.IO) { + val result = withContext(coroutineDispatchers.io) { machine.requestVerificationWithDevice(inner.userId, inner.deviceId, stringMethods) } return if (result != null) { - this.sender.sendVerificationRequest(result.request) + sender.sendVerificationRequest(result.request) result.verification } else { null @@ -89,14 +90,18 @@ internal class Device( */ @Throws(CryptoStoreException::class) suspend fun startVerification(): SasVerification? { - val result = withContext(Dispatchers.IO) { + val result = withContext(coroutineDispatchers.io) { machine.startSasWithDevice(inner.userId, inner.deviceId) } return if (result != null) { - this.sender.sendVerificationRequest(result.request) + sender.sendVerificationRequest(result.request) SasVerification( - this.machine, result.sas, this.sender, this.listeners, + machine = machine, + inner = result.sas, + sender = sender, + coroutineDispatchers = coroutineDispatchers, + listeners = listeners ) } else { null @@ -111,7 +116,7 @@ internal class Device( */ @Throws(CryptoStoreException::class) suspend fun markAsTrusted() { - withContext(Dispatchers.IO) { + withContext(coroutineDispatchers.io) { machine.markDeviceAsTrusted(inner.userId, inner.deviceId) } } @@ -127,11 +132,11 @@ internal class Device( */ @Throws(SignatureException::class) suspend fun verify(): Boolean { - val request = withContext(Dispatchers.IO) { + val request = withContext(coroutineDispatchers.io) { machine.verifyDevice(inner.userId, inner.deviceId) } - this.sender.sendSignatureUpload(request) + sender.sendSignatureUpload(request) return true } @@ -151,20 +156,20 @@ internal class Device( * This will not fetch out fresh data from the Rust side. **/ internal fun toCryptoDeviceInfo(): CryptoDeviceInfo { - val keys = this.inner.keys.map { (keyId, key) -> "$keyId:$this.inner.deviceId" to key }.toMap() + val keys = inner.keys.map { (keyId, key) -> "$keyId:$inner.deviceId" to key }.toMap() return CryptoDeviceInfo( - this.inner.deviceId, - this.inner.userId, - this.inner.algorithms, - keys, + deviceId = inner.deviceId, + userId = inner.userId, + algorithms = inner.algorithms, + keys = keys, // The Kotlin side doesn't need to care about signatures, // so we're not filling this out - mapOf(), - UnsignedDeviceInfo(this.inner.displayName), - DeviceTrustLevel(crossSigningVerified = this.inner.crossSigningTrusted, locallyVerified = this.inner.locallyTrusted), - this.inner.isBlocked, + signatures = mapOf(), + unsigned = UnsignedDeviceInfo(inner.displayName), + trustLevel = DeviceTrustLevel(crossSigningVerified = inner.crossSigningTrusted, locallyVerified = inner.locallyTrusted), + isBlocked = inner.isBlocked, // TODO - null) + firstTimeSeenLocalTs = null) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index aa6a1abc7d..581a3425d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto +import com.squareup.moshi.Moshi import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow @@ -102,7 +103,8 @@ internal class OlmMachine( device_id: String, path: File, private val requestSender: RequestSender, - private val coroutineDispatchers: MatrixCoroutineDispatchers + private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val moshi: Moshi ) { private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString()) internal val verificationListeners = ArrayList() @@ -110,21 +112,21 @@ internal class OlmMachine( /** Get our own user ID. */ fun userId(): String { - return this.inner.userId() + return inner.userId() } /** Get our own device ID. */ fun deviceId(): String { - return this.inner.deviceId() + return inner.deviceId() } /** Get our own public identity keys ID. */ fun identityKeys(): Map { - return this.inner.identityKeys() + return inner.identityKeys() } fun inner(): InnerMachine { - return this.inner + return inner } private suspend fun updateLiveDevices() { @@ -142,7 +144,7 @@ internal class OlmMachine( } private suspend fun updateLivePrivateKeys() { - val keys = this.exportCrossSigningKeys().toOptional() + val keys = exportCrossSigningKeys().toOptional() for (privateKeyCollector in flowCollectors.privateKeyCollectors) { privateKeyCollector.send(keys) } @@ -152,18 +154,18 @@ internal class OlmMachine( * Get our own device info as [CryptoDeviceInfo]. */ suspend fun ownDevice(): CryptoDeviceInfo { - val deviceId = this.deviceId() + val deviceId = deviceId() - val keys = this.identityKeys().map { (keyId, key) -> "$keyId:$deviceId" to key }.toMap() + val keys = identityKeys().map { (keyId, key) -> "$keyId:$deviceId" to key }.toMap() - val crossSigningVerified = when (val ownIdentity = this.getIdentity(this.userId())) { + val crossSigningVerified = when (val ownIdentity = getIdentity(userId())) { is OwnUserIdentity -> ownIdentity.trustsOurOwnDevice() else -> false } return CryptoDeviceInfo( - this.deviceId(), - this.userId(), + deviceId(), + userId(), // TODO pass the algorithms here. listOf(), keys, @@ -238,7 +240,7 @@ internal class OlmMachine( val devices = DeviceLists(deviceChanges?.changed.orEmpty(), deviceChanges?.left.orEmpty()) val adapter = - MoshiProvider.providesMoshi().adapter(ToDeviceSyncResponse::class.java) + moshi.adapter(ToDeviceSyncResponse::class.java) val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!! // TODO once our sync response type parses the unused fallback key @@ -247,7 +249,7 @@ internal class OlmMachine( } // We may get cross signing keys over a to-device event, update our listeners. - this.updateLivePrivateKeys() + updateLivePrivateKeys() return response } @@ -270,7 +272,7 @@ internal class OlmMachine( */ @Throws(CryptoStoreException::class) fun isUserTracked(userId: String): Boolean { - return this.inner.isUserTracked(userId) + return inner.isUserTracked(userId) } /** @@ -344,7 +346,7 @@ internal class OlmMachine( @Throws(CryptoStoreException::class) suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = withContext(coroutineDispatchers.io) { - val adapter = MoshiProvider.providesMoshi().adapter(Map::class.java) + val adapter = moshi.adapter(Map::class.java) val contentString = adapter.toJson(content) val encrypted = inner.encrypt(roomId, eventType, contentString) adapter.fromJson(encrypted)!! @@ -362,7 +364,7 @@ internal class OlmMachine( @Throws(MXCryptoError::class) suspend fun decryptRoomEvent(event: Event): MXEventDecryptionResult = withContext(coroutineDispatchers.io) { - val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val adapter = moshi.adapter(Event::class.java) try { if (event.roomId.isNullOrBlank()) { throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON) @@ -371,7 +373,7 @@ internal class OlmMachine( val decrypted = inner.decryptRoomEvent(serializedEvent, event.roomId) val deserializationAdapter = - MoshiProvider.providesMoshi().adapter(Map::class.java) + moshi.adapter(Map::class.java) val clearEvent = deserializationAdapter.fromJson(decrypted.clearEvent) ?: throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_FIELDS, MXCryptoError.MISSING_FIELDS_REASON) @@ -402,7 +404,7 @@ internal class OlmMachine( @Throws(DecryptionException::class) suspend fun requestRoomKey(event: Event): KeyRequestPair = withContext(coroutineDispatchers.io) { - val adapter = MoshiProvider.providesMoshi().adapter(Event::class.java) + val adapter = moshi.adapter(Event::class.java) val serializedEvent = adapter.toJson(event) inner.requestRoomKey(serializedEvent, event.roomId!!) @@ -453,7 +455,7 @@ internal class OlmMachine( listener: ProgressListener? ): ImportRoomKeysResult = withContext(coroutineDispatchers.io) { - val adapter = MoshiProvider.providesMoshi().adapter(List::class.java) + val adapter = moshi.adapter(List::class.java) // If the key backup is too big we take the risk of causing OOM // when serializing to json @@ -485,22 +487,28 @@ internal class OlmMachine( val identity = withContext(coroutineDispatchers.io) { inner.getIdentity(userId) } - val adapter = MoshiProvider.providesMoshi().adapter(RestKeyInfo::class.java) + val adapter = moshi.adapter(RestKeyInfo::class.java) return when (identity) { is RustUserIdentity.Other -> { - val verified = this.inner().isIdentityVerified(userId) + val verified = inner().isIdentityVerified(userId) val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { trustLevel = DeviceTrustLevel(verified, verified) } val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { trustLevel = DeviceTrustLevel(verified, verified) } - - UserIdentity(identity.userId, masterKey, selfSigningKey, this, this.requestSender) + UserIdentity( + userId = identity.userId, + masterKey = masterKey, + selfSigningKey = selfSigningKey, + olmMachine = this, + requestSender = requestSender, + coroutineDispatchers = coroutineDispatchers + ) } is RustUserIdentity.Own -> { - val verified = this.inner().isIdentityVerified(userId) + val verified = inner().isIdentityVerified(userId) val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { trustLevel = DeviceTrustLevel(verified, verified) @@ -511,13 +519,14 @@ internal class OlmMachine( val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel() OwnUserIdentity( - identity.userId, - masterKey, - selfSigningKey, - userSigningKey, - identity.trustsOurOwnDevice, - this, - this.requestSender + userId = identity.userId, + masterKey = masterKey, + selfSigningKey = selfSigningKey, + userSigningKey = userSigningKey, + trustsOurOwnDevice = identity.trustsOurOwnDevice, + olmMachine = this, + requestSender = requestSender, + coroutineDispatchers = coroutineDispatchers ) } null -> null @@ -552,12 +561,26 @@ internal class OlmMachine( inner.getDevice(userId, deviceId) } ?: return null - return Device(this.inner, device, this.requestSender, this.verificationListeners) + return Device( + machine = inner, + inner = device, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = verificationListeners + ) } suspend fun getUserDevices(userId: String): List { return withContext(coroutineDispatchers.io) { - inner.getUserDevices(userId).map { Device(inner, it, requestSender, verificationListeners) } + inner.getUserDevices(userId).map { + Device( + machine = inner, + inner = it, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = verificationListeners + ) + } } } @@ -570,12 +593,12 @@ internal class OlmMachine( */ @Throws(CryptoStoreException::class) suspend fun getCryptoDeviceInfo(userId: String): List { - val devices = this.getUserDevices(userId).map { it.toCryptoDeviceInfo() }.toMutableList() + val devices = getUserDevices(userId).map { it.toCryptoDeviceInfo() }.toMutableList() // EA doesn't differentiate much between our own and other devices of // while the rust-sdk does, append our own device here. - if (userId == this.userId()) { - devices.add(this.ownDevice()) + if (userId == userId()) { + devices.add(ownDevice()) } return devices @@ -592,7 +615,7 @@ internal class OlmMachine( val plainDevices: ArrayList = arrayListOf() for (user in userIds) { - val devices = this.getCryptoDeviceInfo(user) + val devices = getCryptoDeviceInfo(user) plainDevices.addAll(devices) } @@ -612,7 +635,7 @@ internal class OlmMachine( val userMap = MXUsersDevicesMap() for (user in userIds) { - val devices = this.getCryptoDeviceInfo(user) + val devices = getCryptoDeviceInfo(user) for (device in devices) { userMap.setObject(user, device.deviceId, device) @@ -703,26 +726,27 @@ internal class OlmMachine( * @return The list of [VerificationRequest] that we share with the given user */ fun getVerificationRequests(userId: String): List { - return this.inner.getVerificationRequests(userId).map { + return inner.getVerificationRequests(userId).map { VerificationRequest( - this.inner, - it, - this.requestSender, - this.verificationListeners, + machine = inner, + inner = it, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = verificationListeners, ) } } /** Get a verification request for the given user with the given flow ID */ fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? { - val request = this.inner.getVerificationRequest(userId, flowId) - + val request = inner.getVerificationRequest(userId, flowId) return if (request != null) { VerificationRequest( - this.inner, - request, - requestSender, - this.verificationListeners, + machine = inner, + inner = request, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = verificationListeners, ) } else { null @@ -735,13 +759,26 @@ internal class OlmMachine( * verification. */ fun getVerification(userId: String, flowId: String): VerificationTransaction? { - return when (val verification = this.inner.getVerification(userId, flowId)) { + return when (val verification = inner.getVerification(userId, flowId)) { is uniffi.olm.Verification.QrCodeV1 -> { - val request = this.getVerificationRequest(userId, flowId) ?: return null - QrCodeVerification(inner, request, verification.qrcode, requestSender, verificationListeners) + val request = getVerificationRequest(userId, flowId) ?: return null + QrCodeVerification( + machine = inner, + request = request, + inner = verification.qrcode, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = verificationListeners + ) } is uniffi.olm.Verification.SasV1 -> { - SasVerification(inner, verification.sas, requestSender, verificationListeners) + SasVerification( + machine = inner, + inner = verification.sas, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = verificationListeners + ) } null -> { // This branch exists because scanning a QR code is tied to the QrCodeVerification, @@ -751,7 +788,14 @@ internal class OlmMachine( val request = getVerificationRequest(userId, flowId) ?: return null if (request.canScanQrCodes()) { - QrCodeVerification(inner, request, null, requestSender, verificationListeners) + QrCodeVerification( + machine = inner, + request = request, + inner = null, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = verificationListeners + ) } else { null } @@ -763,16 +807,15 @@ internal class OlmMachine( val requests = withContext(coroutineDispatchers.io) { inner.bootstrapCrossSigning() } - - this.requestSender.uploadCrossSigningKeys(requests.uploadSigningKeysRequest, uiaInterceptor) - this.requestSender.sendSignatureUpload(requests.signatureRequest) + requestSender.uploadCrossSigningKeys(requests.uploadSigningKeysRequest, uiaInterceptor) + requestSender.sendSignatureUpload(requests.signatureRequest) } /** * Get the status of our private cross signing keys, i.e. which private keys do we have stored locally. */ fun crossSigningStatus(): CrossSigningStatus { - return this.inner.crossSigningStatus() + return inner.crossSigningStatus() } suspend fun exportCrossSigningKeys(): PrivateKeysInfo? { @@ -867,8 +910,7 @@ internal class OlmMachine( @Throws(CryptoStoreException::class) suspend fun checkAuthDataSignature(authData: MegolmBackupAuthData): Boolean { return withContext(coroutineDispatchers.computation) { - val adapter = MoshiProvider - .providesMoshi() + val adapter = moshi .newBuilder() .add(CheckNumberType.JSON_ADAPTER_FACTORY) .build() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt index 513a9297d8..95a117d676 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto +import com.squareup.moshi.Moshi import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.SessionFilesDirectory @@ -30,8 +31,15 @@ internal class OlmMachineProvider @Inject constructor( @DeviceId private val deviceId: String?, @SessionFilesDirectory private val dataDir: File, requestSender: RequestSender, - coroutineDispatchers: MatrixCoroutineDispatchers + coroutineDispatchers: MatrixCoroutineDispatchers, + moshi: Moshi ) { - var olmMachine: OlmMachine = OlmMachine(userId, deviceId!!, dataDir, requestSender, coroutineDispatchers) + var olmMachine: OlmMachine = OlmMachine( + user_id = userId, + device_id = deviceId!!, + path = dataDir, + requestSender = requestSender, + coroutineDispatchers = coroutineDispatchers, + moshi = moshi) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt index 8afa9d7ef9..e19b66977a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationService @@ -36,13 +36,15 @@ internal class QrCodeVerification( private var request: VerificationRequest, private var inner: QrCode?, private val sender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers, listeners: ArrayList ) : QrCodeVerificationTransaction { + private val dispatcher = UpdateDispatcher(listeners) private fun dispatchTxUpdated() { refreshData() - this.dispatcher.dispatchTxUpdated(this) + dispatcher.dispatchTxUpdated(this) } /** Generate, if possible, data that should be encoded as a QR code for QR code verification. @@ -59,7 +61,7 @@ internal class QrCodeVerification( */ override val qrCodeText: String? get() { - val data = this.inner?.let { this.machine.generateQrCode(it.otherUserId, it.flowId) } + val data = inner?.let { machine.generateQrCode(it.otherUserId, it.flowId) } // TODO Why are we encoding this to ISO_8859_1? If we're going to encode, why not base64? return data?.fromBase64()?.toString(Charsets.ISO_8859_1) @@ -85,7 +87,7 @@ internal class QrCodeVerification( override var state: VerificationTxState get() { refreshData() - val inner = this.inner + val inner = inner val cancelInfo = inner?.cancelInfo return if (inner != null) { @@ -111,22 +113,22 @@ internal class QrCodeVerification( /** Get the unique id of this verification */ override val transactionId: String - get() = this.request.flowId() + get() = request.flowId() /** Get the user id of the other user participating in this verification flow */ override val otherUserId: String - get() = this.request.otherUser() + get() = request.otherUser() /** Get the device id of the other user's device participating in this verification flow */ override var otherDeviceId: String? - get() = this.request.otherDeviceId() + get() = request.otherDeviceId() @Suppress("UNUSED_PARAMETER") set(value) { } /** Did the other side initiate this verification flow */ override val isIncoming: Boolean - get() = !this.request.weStarted() + get() = !request.weStarted() /** Cancel the verification flow * @@ -158,7 +160,7 @@ internal class QrCodeVerification( /** Is this verification happening over to-device messages */ override fun isToDeviceTransport(): Boolean { - return this.request.roomId() == null + return request.roomId() == null } /** Confirm the QR code verification @@ -171,24 +173,24 @@ internal class QrCodeVerification( */ @Throws(CryptoStoreException::class) private suspend fun confirm() { - val result = withContext(Dispatchers.IO) { + val result = withContext(coroutineDispatchers.io) { machine.confirmVerification(request.otherUser(), request.flowId()) } if (result != null) { - this.sender.sendVerificationRequest(result.request) + sender.sendVerificationRequest(result.request) dispatchTxUpdated() val signatureRequest = result.signatureRequest if (signatureRequest != null) { - this.sender.sendSignatureUpload(signatureRequest) + sender.sendSignatureUpload(signatureRequest) } } } private suspend fun cancelHelper(code: CancelCode) { - val request = this.machine.cancelVerification(this.request.otherUser(), this.request.flowId(), code.value) + val request = machine.cancelVerification(request.otherUser(), request.flowId(), code.value) if (request != null) { sender.sendVerificationRequest(request) @@ -198,9 +200,9 @@ internal class QrCodeVerification( /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { - when (val verification = this.machine.getVerification(this.request.otherUser(), this.request.flowId())) { + when (val verification = machine.getVerification(request.otherUser(), request.flowId())) { is Verification.QrCodeV1 -> { - this.inner = verification.qrcode + inner = verification.qrcode } else -> { } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index a1b0fc35e6..07b34ca1c2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.internal.crypto -import androidx.lifecycle.LiveData import kotlinx.coroutines.flow.Flow import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback @@ -31,7 +30,6 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo import org.matrix.android.sdk.internal.di.UserId -import org.matrix.android.sdk.internal.extensions.foldToCallback import javax.inject.Inject internal class RustCrossSigningService @Inject constructor( @@ -54,7 +52,7 @@ internal class RustCrossSigningService @Inject constructor( override suspend fun isUserTrusted(otherUserId: String): Boolean { // This seems to be used only in tests. - return this.checkUserTrust(otherUserId).isVerified() + return checkUserTrust(otherUserId).isVerified() } /** @@ -136,13 +134,13 @@ internal class RustCrossSigningService @Inject constructor( * Returning true means that we have the private self-signing and user-signing keys at hand. */ override fun canCrossSign(): Boolean { - val status = this.olmMachine.crossSigningStatus() + val status = olmMachine.crossSigningStatus() return status.hasSelfSigning && status.hasUserSigning } override fun allPrivateKeysKnown(): Boolean { - val status = this.olmMachine.crossSigningStatus() + val status = olmMachine.crossSigningStatus() return status.hasMaster && status.hasSelfSigning && status.hasUserSigning } @@ -163,7 +161,7 @@ internal class RustCrossSigningService @Inject constructor( /** Mark our own master key as trusted */ override suspend fun markMyMasterKeyAsTrusted() { // This doesn't seem to be used? - this.trustUser(this.olmMachine.userId(), NoOpMatrixCallback()) + trustUser(olmMachine.userId(), NoOpMatrixCallback()) } /** @@ -213,7 +211,7 @@ internal class RustCrossSigningService @Inject constructor( } override fun onSecretUSKGossip(uskPrivateKey: String) { - // And this. + // And } override suspend fun shieldForGroup(userIds: List): RoomEncryptionTrustLevel { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt index ac775af10e..3637edf157 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction @@ -36,6 +36,7 @@ internal class SasVerification( private val machine: OlmMachine, private var inner: Sas, private val sender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers, listeners: ArrayList ) : SasVerificationTransaction { @@ -43,27 +44,27 @@ internal class SasVerification( private fun dispatchTxUpdated() { refreshData() - this.dispatcher.dispatchTxUpdated(this) + dispatcher.dispatchTxUpdated(this) } /** The user ID of the other user that is participating in this verification flow */ - override val otherUserId: String = this.inner.otherUserId + override val otherUserId: String = inner.otherUserId /** Get the device id of the other user's device participating in this verification flow */ override var otherDeviceId: String? - get() = this.inner.otherDeviceId + get() = inner.otherDeviceId @Suppress("UNUSED_PARAMETER") set(value) { } /** Did the other side initiate this verification flow */ override val isIncoming: Boolean - get() = !this.inner.weStarted + get() = !inner.weStarted override var state: VerificationTxState get() { refreshData() - val cancelInfo = this.inner.cancelInfo + val cancelInfo = inner.cancelInfo return when { cancelInfo != null -> { @@ -83,7 +84,7 @@ internal class SasVerification( /** Get the unique id of this verification */ override val transactionId: String - get() = this.inner.flowId + get() = inner.flowId /** Cancel the verification flow * @@ -95,7 +96,7 @@ internal class SasVerification( * The method turns into a noop, if the verification flow has already been cancelled. * */ override suspend fun cancel() { - this.cancelHelper(CancelCode.User) + cancelHelper(CancelCode.User) } /** Cancel the verification flow @@ -110,7 +111,7 @@ internal class SasVerification( * @param code The cancel code that should be given as the reason for the cancellation. * */ override suspend fun cancel(code: CancelCode) { - this.cancelHelper(code) + cancelHelper(code) } /** Cancel the verification flow @@ -123,11 +124,11 @@ internal class SasVerification( * The method turns into a noop, if the verification flow has already been cancelled. */ override suspend fun shortCodeDoesNotMatch() { - this.cancelHelper(CancelCode.MismatchedSas) + cancelHelper(CancelCode.MismatchedSas) } /** Is this verification happening over to-device messages */ - override fun isToDeviceTransport(): Boolean = this.inner.roomId == null + override fun isToDeviceTransport(): Boolean = inner.roomId == null /** Does the verification flow support showing decimals as the short auth string */ override fun supportsDecimal(): Boolean { @@ -140,7 +141,7 @@ internal class SasVerification( /** Does the verification flow support showing emojis as the short auth string */ override fun supportsEmoji(): Boolean { refreshData() - return this.inner.supportsEmoji + return inner.supportsEmoji } /** Confirm that the short authentication code matches on both sides @@ -175,7 +176,7 @@ internal class SasVerification( * in a presentable state. */ override fun getDecimalCodeRepresentation(): String { - val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId) + val decimals = machine.getDecimals(inner.otherUserId, inner.flowId) return decimals?.joinToString(" ") ?: "" } @@ -187,40 +188,40 @@ internal class SasVerification( * state. */ override fun getEmojiCodeRepresentation(): List { - val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId) + val emojiIndex = machine.getEmojiIndex(inner.otherUserId, inner.flowId) return emojiIndex?.map { getEmojiForCode(it) } ?: listOf() } internal suspend fun accept() { - val request = this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId) + val request = machine.acceptSasVerification(inner.otherUserId, inner.flowId) if (request != null) { - this.sender.sendVerificationRequest(request) + sender.sendVerificationRequest(request) dispatchTxUpdated() } } @Throws(CryptoStoreException::class) private suspend fun confirm() { - val result = withContext(Dispatchers.IO) { + val result = withContext(coroutineDispatchers.io) { machine.confirmVerification(inner.otherUserId, inner.flowId) } if (result != null) { - this.sender.sendVerificationRequest(result.request) + sender.sendVerificationRequest(result.request) dispatchTxUpdated() val signatureRequest = result.signatureRequest if (signatureRequest != null) { - this.sender.sendSignatureUpload(signatureRequest) + sender.sendSignatureUpload(signatureRequest) } } } private suspend fun cancelHelper(code: CancelCode) { - val request = this.machine.cancelVerification(this.inner.otherUserId, inner.flowId, code.value) + val request = machine.cancelVerification(inner.otherUserId, inner.flowId, code.value) if (request != null) { sender.sendVerificationRequest(request) @@ -230,9 +231,9 @@ internal class SasVerification( /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { - when (val verification = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)) { + when (val verification = machine.getVerification(inner.otherUserId, inner.flowId)) { is Verification.SasV1 -> { - this.inner = verification.sas + inner = verification.sas } else -> { } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt index 00c18abe0e..3af7b10704 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt @@ -16,9 +16,8 @@ package org.matrix.android.sdk.internal.crypto -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.events.model.EventType @@ -80,11 +79,12 @@ internal class OwnUserIdentity( private val userSigningKey: CryptoCrossSigningKey, private val trustsOurOwnDevice: Boolean, private val olmMachine: OlmMachine, - private val requestSender: RequestSender) : UserIdentities() { + private val requestSender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers) : UserIdentities() { /** * Our own user id. */ - override fun userId() = this.userId + override fun userId() = userId /** * Manually verify our user identity. @@ -95,8 +95,8 @@ internal class OwnUserIdentity( */ @Throws(SignatureException::class) override suspend fun verify() { - val request = withContext(Dispatchers.Default) { olmMachine.inner().verifyIdentity(userId) } - this.requestSender.sendSignatureUpload(request) + val request = withContext(coroutineDispatchers.computation) { olmMachine.inner().verifyIdentity(userId) } + requestSender.sendSignatureUpload(request) } /** @@ -106,13 +106,13 @@ internal class OwnUserIdentity( */ @Throws(CryptoStoreException::class) override suspend fun verified(): Boolean { - return withContext(Dispatchers.IO) { olmMachine.inner().isIdentityVerified(userId) } + return withContext(coroutineDispatchers.io) { olmMachine.inner().isIdentityVerified(userId) } } /** * Does the identity trust our own device. */ - fun trustsOurOwnDevice() = this.trustsOurOwnDevice + fun trustsOurOwnDevice() = trustsOurOwnDevice /** * Request an interactive verification to begin @@ -133,14 +133,15 @@ internal class OwnUserIdentity( @Throws(CryptoStoreException::class) suspend fun requestVerification(methods: List): VerificationRequest { val stringMethods = prepareMethods(methods) - val result = this.olmMachine.inner().requestSelfVerification(stringMethods) - this.requestSender.sendVerificationRequest(result!!.request) + val result = olmMachine.inner().requestSelfVerification(stringMethods) + requestSender.sendVerificationRequest(result!!.request) return VerificationRequest( - this.olmMachine.inner(), - result.verification, - this.requestSender, - this.olmMachine.verificationListeners + machine = olmMachine.inner(), + inner = result.verification, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = olmMachine.verificationListeners ) } @@ -148,9 +149,9 @@ internal class OwnUserIdentity( * Convert the identity into a MxCrossSigningInfo class. */ override suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo { - val masterKey = this.masterKey - val selfSigningKey = this.selfSigningKey - val userSigningKey = this.userSigningKey + val masterKey = masterKey + val selfSigningKey = selfSigningKey + val userSigningKey = userSigningKey val trustLevel = DeviceTrustLevel(verified(), false) // TODO remove this, this is silly, we have way too many methods to check if a user is verified masterKey.trustLevel = trustLevel @@ -158,7 +159,7 @@ internal class OwnUserIdentity( userSigningKey.trustLevel = trustLevel val crossSigningKeys = listOf(masterKey, selfSigningKey, userSigningKey) - return MXCrossSigningInfo(this.userId, crossSigningKeys) + return MXCrossSigningInfo(userId, crossSigningKeys) } } @@ -172,11 +173,12 @@ internal class UserIdentity( private val masterKey: CryptoCrossSigningKey, private val selfSigningKey: CryptoCrossSigningKey, private val olmMachine: OlmMachine, - private val requestSender: RequestSender) : UserIdentities() { + private val requestSender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers) : UserIdentities() { /** * The unique ID of the user that this identity belongs to. */ - override fun userId() = this.userId + override fun userId() = userId /** * Manually verify this user identity. @@ -189,8 +191,8 @@ internal class UserIdentity( */ @Throws(SignatureException::class) override suspend fun verify() { - val request = withContext(Dispatchers.Default) { olmMachine.inner().verifyIdentity(userId) } - this.requestSender.sendSignatureUpload(request) + val request = withContext(coroutineDispatchers.computation) { olmMachine.inner().verifyIdentity(userId) } + requestSender.sendSignatureUpload(request) } /** @@ -199,7 +201,7 @@ internal class UserIdentity( * @return True if the identity is considered to be verified and trusted, false otherwise. */ override suspend fun verified(): Boolean { - return withContext(Dispatchers.IO) { olmMachine.inner().isIdentityVerified(userId) } + return withContext(coroutineDispatchers.io) { olmMachine.inner().isIdentityVerified(userId) } } /** @@ -232,17 +234,18 @@ internal class UserIdentity( transactionId: String ): VerificationRequest { val stringMethods = prepareMethods(methods) - val content = this.olmMachine.inner().verificationRequestContent(this.userId, stringMethods)!! + val content = olmMachine.inner().verificationRequestContent(userId, stringMethods)!! val eventID = requestSender.sendRoomMessage(EventType.MESSAGE, roomId, content, transactionId) - val innerRequest = this.olmMachine.inner().requestVerification(this.userId, roomId, eventID, stringMethods)!! + val innerRequest = olmMachine.inner().requestVerification(userId, roomId, eventID, stringMethods)!! return VerificationRequest( - this.olmMachine.inner(), - innerRequest, - this.requestSender, - this.olmMachine.verificationListeners + machine = olmMachine.inner(), + inner = innerRequest, + sender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = olmMachine.verificationListeners ) } @@ -250,14 +253,14 @@ internal class UserIdentity( * Convert the identity into a MxCrossSigningInfo class. */ override suspend fun toMxCrossSigningInfo(): MXCrossSigningInfo { -// val crossSigningKeys = listOf(this.masterKey, this.selfSigningKey) +// val crossSigningKeys = listOf(masterKey, selfSigningKey) val trustLevel = DeviceTrustLevel(verified(), false) // TODO remove this, this is silly, we have way too many methods to check if a user is verified masterKey.trustLevel = trustLevel selfSigningKey.trustLevel = trustLevel - return MXCrossSigningInfo(this.userId, listOf( - this.masterKey.also { it.trustLevel = trustLevel }, - this.selfSigningKey.also { it.trustLevel = trustLevel } + return MXCrossSigningInfo(userId, listOf( + masterKey.also { it.trustLevel = trustLevel }, + selfSigningKey.also { it.trustLevel = trustLevel } )) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index ebd17307d1..9075423f9d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -20,6 +20,7 @@ import android.os.Handler import android.os.Looper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady @@ -45,6 +46,7 @@ internal class VerificationRequest( private val machine: OlmMachine, private var inner: VerificationRequest, private val sender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers, private val listeners: ArrayList ) { private val uiHandler = Handler(Looper.getMainLooper()) @@ -53,7 +55,7 @@ internal class VerificationRequest( uiHandler.post { listeners.forEach { try { - it.verificationRequestUpdated(this.toPendingVerificationRequest()) + it.verificationRequestUpdated(toPendingVerificationRequest()) } catch (e: Throwable) { Timber.e(e, "## Error while notifying listeners") } @@ -68,12 +70,12 @@ internal class VerificationRequest( * event that initiated the flow. */ internal fun flowId(): String { - return this.inner.flowId + return inner.flowId } /** The user ID of the other user that is participating in this verification flow */ internal fun otherUser(): String { - return this.inner.otherUserId + return inner.otherUserId } /** The device ID of the other user's device that is participating in this verification flow @@ -83,12 +85,12 @@ internal class VerificationRequest( * */ internal fun otherDeviceId(): String? { refreshData() - return this.inner.otherDeviceId + return inner.otherDeviceId } /** Did we initiate this verification flow */ internal fun weStarted(): Boolean { - return this.inner.weStarted + return inner.weStarted } /** Get the id of the room where this verification is happening @@ -96,7 +98,7 @@ internal class VerificationRequest( * Will be null if the verification is not happening inside a room. */ internal fun roomId(): String? { - return this.inner.roomId + return inner.roomId } /** Did the non-initiating side respond with a m.key.verification.read event @@ -107,13 +109,13 @@ internal class VerificationRequest( */ internal fun isReady(): Boolean { refreshData() - return this.inner.isReady + return inner.isReady } /** Did we advertise that we're able to scan QR codes */ internal fun canScanQrCodes(): Boolean { refreshData() - return this.inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false + return inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false } /** Accept the verification request advertising the given methods as supported @@ -132,15 +134,15 @@ internal class VerificationRequest( suspend fun acceptWithMethods(methods: List) { val stringMethods = prepareMethods(methods) - val request = this.machine.acceptVerificationRequest( - this.inner.otherUserId, - this.inner.flowId, + val request = machine.acceptVerificationRequest( + inner.otherUserId, + inner.flowId, stringMethods ) if (request != null) { - this.sender.sendVerificationRequest(request) - this.dispatchRequestUpdated() + sender.sendVerificationRequest(request) + dispatchRequestUpdated() } } @@ -158,12 +160,12 @@ internal class VerificationRequest( * emoji verification, or null if we can't yet transition into emoji verification. */ internal suspend fun startSasVerification(): SasVerification? { - return withContext(Dispatchers.IO) { + return withContext(coroutineDispatchers.io) { val result = machine.startSasVerification(inner.otherUserId, inner.flowId) if (result != null) { sender.sendVerificationRequest(result.request) - SasVerification(machine, result.sas, sender, listeners) + SasVerification(machine, result.sas, sender, coroutineDispatchers, listeners) } else { null } @@ -187,10 +189,10 @@ internal class VerificationRequest( // TODO again, what's the deal with ISO_8859_1? val byteArray = data.toByteArray(Charsets.ISO_8859_1) val encodedData = byteArray.toBase64NoPadding() - val result = this.machine.scanQrCode(this.otherUser(), this.flowId(), encodedData) ?: return null + val result = machine.scanQrCode(otherUser(), flowId(), encodedData) ?: return null - this.sender.sendVerificationRequest(result.request) - return QrCodeVerification(this.machine, this, result.qr, this.sender, this.listeners) + sender.sendVerificationRequest(result.request) + return QrCodeVerification(machine, this, result.qr, sender, coroutineDispatchers, listeners) } /** Transition into a QR code verification to display a QR code @@ -211,15 +213,16 @@ internal class VerificationRequest( * QR code verification, or null if we can't yet transition into QR code verification. */ internal fun startQrVerification(): QrCodeVerification? { - val qrcode = this.machine.startQrVerification(this.inner.otherUserId, this.inner.flowId) + val qrcode = machine.startQrVerification(inner.otherUserId, inner.flowId) return if (qrcode != null) { QrCodeVerification( - this.machine, - this, - qrcode, - this.sender, - this.listeners, + machine = machine, + request = this, + inner = qrcode, + sender = sender, + coroutineDispatchers = coroutineDispatchers, + listeners = listeners, ) } else { null @@ -237,24 +240,24 @@ internal class VerificationRequest( * The method turns into a noop, if the verification flow has already been cancelled. */ internal suspend fun cancel() { - val request = this.machine.cancelVerification( - this.inner.otherUserId, - this.inner.flowId, + val request = machine.cancelVerification( + inner.otherUserId, + inner.flowId, CancelCode.User.value ) if (request != null) { - this.sender.sendVerificationRequest(request) - this.dispatchRequestUpdated() + sender.sendVerificationRequest(request) + dispatchRequestUpdated() } } /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { - val request = this.machine.getVerificationRequest(this.inner.otherUserId, this.inner.flowId) + val request = machine.getVerificationRequest(inner.otherUserId, inner.flowId) if (request != null) { - this.inner = request + inner = request } } @@ -269,7 +272,7 @@ internal class VerificationRequest( */ internal fun toPendingVerificationRequest(): PendingVerificationRequest { refreshData() - val cancelInfo = this.inner.cancelInfo + val cancelInfo = inner.cancelInfo val cancelCode = if (cancelInfo != null) { safeValueOf(cancelInfo.cancelCode) @@ -277,72 +280,72 @@ internal class VerificationRequest( null } - val ourMethods = this.inner.ourMethods - val theirMethods = this.inner.theirMethods - val otherDeviceId = this.inner.otherDeviceId + val ourMethods = inner.ourMethods + val theirMethods = inner.theirMethods + val otherDeviceId = inner.otherDeviceId var requestInfo: ValidVerificationInfoRequest? = null var readyInfo: ValidVerificationInfoReady? = null - if (this.inner.weStarted && ourMethods != null) { + if (inner.weStarted && ourMethods != null) { requestInfo = ValidVerificationInfoRequest( - this.inner.flowId, - this.machine.deviceId(), - ourMethods, - null, + transactionId = inner.flowId, + fromDevice = machine.deviceId(), + methods = ourMethods, + timestamp = null, ) - } else if (!this.inner.weStarted && ourMethods != null) { + } else if (!inner.weStarted && ourMethods != null) { readyInfo = ValidVerificationInfoReady( - this.inner.flowId, - this.machine.deviceId(), - ourMethods, + transactionId = inner.flowId, + fromDevice = machine.deviceId(), + methods = ourMethods, ) } - if (this.inner.weStarted && theirMethods != null && otherDeviceId != null) { + if (inner.weStarted && theirMethods != null && otherDeviceId != null) { readyInfo = ValidVerificationInfoReady( - this.inner.flowId, - otherDeviceId, - theirMethods, + transactionId = inner.flowId, + fromDevice = otherDeviceId, + methods = theirMethods, ) - } else if (!this.inner.weStarted && theirMethods != null && otherDeviceId != null) { + } else if (!inner.weStarted && theirMethods != null && otherDeviceId != null) { requestInfo = ValidVerificationInfoRequest( - this.inner.flowId, - otherDeviceId, - theirMethods, - System.currentTimeMillis(), + transactionId = inner.flowId, + fromDevice = otherDeviceId, + methods = theirMethods, + timestamp = System.currentTimeMillis(), ) } return PendingVerificationRequest( // Creation time - System.currentTimeMillis(), + ageLocalTs = System.currentTimeMillis(), // Who initiated the request - !this.inner.weStarted, + isIncoming = !inner.weStarted, // Local echo id, what to do here? - this.inner.flowId, + localId = inner.flowId, // other user - this.inner.otherUserId, + otherUserId = inner.otherUserId, // room id - this.inner.roomId, + roomId = inner.roomId, // transaction id - this.inner.flowId, + transactionId = inner.flowId, // val requestInfo: ValidVerificationInfoRequest? = null, - requestInfo, + requestInfo = requestInfo, // val readyInfo: ValidVerificationInfoReady? = null, - readyInfo, + readyInfo = readyInfo, // cancel code if there is one - cancelCode, + cancelConclusion = cancelCode, // are we done/successful - this.inner.isDone, + isSuccessful = inner.isDone, // did another device answer the request - this.inner.isPassive, + handledByOtherSession = inner.isPassive, // devices that should receive the events we send out - null, + targetDevices = null ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt index 11c1117761..0c1d6946e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/RustKeyBackupService.kt @@ -21,7 +21,6 @@ import android.os.Looper import androidx.annotation.VisibleForTesting import androidx.annotation.WorkerThread import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -95,7 +94,7 @@ internal class RustKeyBackupService @Inject constructor( // private var backupAllGroupSessionsCallback: MatrixCallback? = null - private val importScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + private val importScope = CoroutineScope(SupervisorJob() + coroutineDispatchers.main) private var keysBackupStateListener: KeysBackupStateListener? = null @@ -490,7 +489,7 @@ internal class RustKeyBackupService @Inject constructor( val data = getKeys(sessionId, roomId, keysVersionResult.version) return withContext(coroutineDispatchers.computation) { - withContext(Dispatchers.Main) { + withContext(coroutineDispatchers.main) { stepProgressListener?.onStepProgress(StepProgressListener.Step.DecryptingKey(0, data.roomIdToRoomKeysBackupData.size)) } // Decrypting by chunk of 500 keys in parallel @@ -513,7 +512,7 @@ internal class RustKeyBackupService @Inject constructor( .awaitAll() .flatten() - withContext(Dispatchers.Main) { + withContext(coroutineDispatchers.main) { val stepProgress = StepProgressListener.Step.DecryptingKey(data.roomIdToRoomKeysBackupData.size, data.roomIdToRoomKeysBackupData.size) stepProgressListener?.onStepProgress(stepProgress) } @@ -532,7 +531,7 @@ internal class RustKeyBackupService @Inject constructor( val progressListener = if (stepProgressListener != null) { object : ProgressListener { override fun onProgress(progress: Int, total: Int) { - cryptoCoroutineScope.launch(Dispatchers.Main) { + cryptoCoroutineScope.launch(coroutineDispatchers.main) { val stepProgress = StepProgressListener.Step.ImportingKey(progress, total) stepProgressListener.onStepProgress(stepProgress) } @@ -878,7 +877,7 @@ internal class RustKeyBackupService @Inject constructor( } } catch (failure: Throwable) { if (failure is Failure.ServerError) { - withContext(Dispatchers.Main) { + withContext(coroutineDispatchers.main) { Timber.e(failure, "backupKeys: backupKeys failed.") when (failure.error.code) { From 48793f531c5be6aa1c51d5067def9b6976769f73 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 15 Apr 2022 20:05:06 +0200 Subject: [PATCH 220/252] Start fixing crypto tests compilation --- .../android/sdk/common/CommonTestHelper.kt | 2 +- .../android/sdk/common/CryptoTestHelper.kt | 25 +++++---- .../sdk/internal/crypto/PreShareKeysTest.kt | 4 +- .../sdk/internal/crypto/UnwedgingTest.kt | 16 ++++-- .../crypto/gossiping/KeyShareTests.kt | 55 +++++++++++++------ .../crypto/gossiping/WithHeldTests.kt | 15 +++-- .../crypto/keysbackup/KeysBackupTest.kt | 21 +++++-- .../crypto/keysbackup/KeysBackupTestHelper.kt | 20 +++++-- 8 files changed, 108 insertions(+), 50 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt index 031d0a8bcf..ab6fadb52b 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt @@ -378,7 +378,7 @@ class CommonTestHelper(context: Context) { assertTrue(latch.await(timeout ?: TestConstants.timeOutMillis, TimeUnit.MILLISECONDS)) } - suspend fun retryPeriodicallyWithLatch(latch: CountDownLatch, condition: (() -> Boolean)) { + suspend fun retryPeriodicallyWithLatch(latch: CountDownLatch, condition: suspend (() -> Boolean)) { while (true) { delay(1000) if (condition()) { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index 71796192a8..d8546b4d8d 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.common import android.os.SystemClock import android.util.Log import androidx.lifecycle.Observer +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull @@ -275,7 +276,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) { } fun initializeCrossSigning(session: Session) { - testHelper.doSync { + testHelper.runBlockingTest { session.cryptoService().crossSigningService() .initializeCrossSigning( object : UserInteractiveAuthInterceptor { @@ -288,7 +289,7 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) { ) ) } - }, it) + }) } } @@ -300,12 +301,14 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) { val aliceVerificationService = alice.cryptoService().verificationService() val bobVerificationService = bob.cryptoService().verificationService() - aliceVerificationService.beginKeyVerificationInDMs( - VerificationMethod.SAS, - requestID, - roomId, - bob.myUserId, - bob.sessionParams.credentials.deviceId!!) + runBlocking { + aliceVerificationService.beginKeyVerificationInDMs( + VerificationMethod.SAS, + requestID, + roomId, + bob.myUserId, + bob.sessionParams.credentials.deviceId!!) + } // we should reach SHOW SAS on both var alicePovTx: OutgoingSasVerificationTransaction? = null @@ -346,8 +349,10 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) { assertEquals("SAS code do not match", alicePovTx!!.getDecimalCodeRepresentation(), bobPovTx!!.getDecimalCodeRepresentation()) - bobPovTx!!.userHasVerifiedShortCode() - alicePovTx!!.userHasVerifiedShortCode() + runBlocking { + bobPovTx!!.userHasVerifiedShortCode() + alicePovTx!!.userHasVerifiedShortCode() + } testHelper.waitWithLatch { testHelper.retryPeriodicallyWithLatch(it) { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt index a7a81bacf5..d48881e1b0 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt @@ -60,8 +60,8 @@ class PreShareKeysTest : InstrumentedTest { Log.d("#Test", "Room Key Received from alice $preShareCount") // Force presharing of new outbound key - testHelper.doSync { - aliceSession.cryptoService().prepareToEncrypt(e2eRoomID, it) + testHelper.runBlockingTest { + aliceSession.cryptoService().prepareToEncrypt(e2eRoomID) } testHelper.waitWithLatch { latch -> diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/UnwedgingTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/UnwedgingTest.kt index 0a8ce67680..dba5ad4a4f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/UnwedgingTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/UnwedgingTest.kt @@ -144,9 +144,12 @@ class UnwedgingTest : InstrumentedTest { // - Store the olm session between A&B devices // Let us pickle our session with bob here so we can later unpickle it // and wedge our session. - val sessionIdsForBob = aliceCryptoStore.getDeviceSessionIds(bobSession.cryptoService().getMyDevice().identityKey()!!) + var myDevice = testHelper.runBlockingTest { + bobSession.cryptoService().getMyDevice() + } + val sessionIdsForBob = aliceCryptoStore.getDeviceSessionIds(myDevice.identityKey()!!) sessionIdsForBob!!.size shouldBe 1 - val olmSession = aliceCryptoStore.getDeviceSession(sessionIdsForBob.first(), bobSession.cryptoService().getMyDevice().identityKey()!!)!! + val olmSession = aliceCryptoStore.getDeviceSession(sessionIdsForBob.first(),myDevice.identityKey()!!)!! val oldSession = serializeForRealm(olmSession.olmSession) @@ -174,7 +177,10 @@ class UnwedgingTest : InstrumentedTest { // Let us wedge the session now. Set crypto state like after the first message Timber.i("## CRYPTO | testUnwedging: wedge the session now. Set crypto state like after the first message") - aliceCryptoStore.storeSession(OlmSessionWrapper(deserializeFromRealm(oldSession)!!), bobSession.cryptoService().getMyDevice().identityKey()!!) + myDevice = testHelper.runBlockingTest { + bobSession.cryptoService().getMyDevice() + } + aliceCryptoStore.storeSession(OlmSessionWrapper(deserializeFromRealm(oldSession)!!), myDevice.identityKey()!!) Thread.sleep(6_000) // Force new session, and key share @@ -207,7 +213,7 @@ class UnwedgingTest : InstrumentedTest { bobTimeline.removeListener(bobHasThreeDecryptedEventsListener) // It's a trick to force key request on fail to decrypt - testHelper.doSync { + testHelper.runBlockingTest { bobSession.cryptoService().crossSigningService() .initializeCrossSigning( object : UserInteractiveAuthInterceptor { @@ -220,7 +226,7 @@ class UnwedgingTest : InstrumentedTest { ) ) } - }, it) + }) } // Wait until we received back the key diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 7b24f28e06..8ec650a122 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -23,6 +23,8 @@ import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.assertTrue import junit.framework.TestCase.fail +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking import org.junit.Assert import org.junit.FixMethodOrder import org.junit.Ignore @@ -93,7 +95,9 @@ class KeyShareTests : InstrumentedTest { assert(receivedEvent!!.isEncrypted()) try { - aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") + commonTestHelper.runBlockingTest { + aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") + } fail("should fail") } catch (failure: Throwable) { } @@ -106,7 +110,7 @@ class KeyShareTests : InstrumentedTest { var outGoingRequestId: String? = null - commonTestHelper.waitWithLatch { latch -> + commonTestHelper.waitWithLatch { latch -> commonTestHelper.retryPeriodicallyWithLatch(latch) { aliceSession2.cryptoService().getOutgoingRoomKeyRequests() .filter { req -> @@ -148,7 +152,9 @@ class KeyShareTests : InstrumentedTest { } try { - aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") + commonTestHelper.runBlockingTest { + aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") + } fail("should fail") } catch (failure: Throwable) { } @@ -185,7 +191,9 @@ class KeyShareTests : InstrumentedTest { } try { - aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") + commonTestHelper.runBlockingTest { + aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") + } } catch (failure: Throwable) { fail("should have been able to decrypt") } @@ -199,7 +207,7 @@ class KeyShareTests : InstrumentedTest { fun test_ShareSSSSSecret() { val aliceSession1 = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true)) - commonTestHelper.doSync { + commonTestHelper.runBlockingTest { aliceSession1.cryptoService().crossSigningService() .initializeCrossSigning( object : UserInteractiveAuthInterceptor { @@ -211,7 +219,7 @@ class KeyShareTests : InstrumentedTest { ) ) } - }, it) + }) } // Also bootstrap keybackup on first session @@ -249,8 +257,10 @@ class KeyShareTests : InstrumentedTest { } if (tx.state == VerificationTxState.ShortCodeReady) { session1ShortCode = tx.getDecimalCodeRepresentation() - Thread.sleep(500) - tx.userHasVerifiedShortCode() + commonTestHelper.runBlockingTest { + delay(500) + tx.userHasVerifiedShortCode() + } } } } @@ -262,16 +272,20 @@ class KeyShareTests : InstrumentedTest { if (tx is SasVerificationTransaction) { if (tx.state == VerificationTxState.ShortCodeReady) { session2ShortCode = tx.getDecimalCodeRepresentation() - Thread.sleep(500) - tx.userHasVerifiedShortCode() + commonTestHelper.runBlockingTest { + delay(500) + tx.userHasVerifiedShortCode() + } } } } }) val txId = "m.testVerif12" - aliceVerificationService2.beginKeyVerification(VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.deviceId - ?: "", txId) + commonTestHelper.runBlockingTest { + aliceVerificationService2.beginKeyVerification(VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.deviceId + ?: "", txId) + } commonTestHelper.waitWithLatch { latch -> commonTestHelper.retryPeriodicallyWithLatch(latch) { @@ -312,7 +326,7 @@ class KeyShareTests : InstrumentedTest { fun test_ImproperKeyShareBug() { val aliceSession = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true)) - commonTestHelper.doSync { + commonTestHelper.runBlockingTest { aliceSession.cryptoService().crossSigningService() .initializeCrossSigning( object : UserInteractiveAuthInterceptor { @@ -325,7 +339,7 @@ class KeyShareTests : InstrumentedTest { ) ) } - }, it) + }) } // Create an encrypted room and send a couple of messages @@ -346,7 +360,7 @@ class KeyShareTests : InstrumentedTest { // Create bob session val bobSession = commonTestHelper.createAccount(TestConstants.USER_BOB, SessionTestParams(true)) - commonTestHelper.doSync { + commonTestHelper.runBlockingTest { bobSession.cryptoService().crossSigningService() .initializeCrossSigning( object : UserInteractiveAuthInterceptor { @@ -359,7 +373,7 @@ class KeyShareTests : InstrumentedTest { ) ) } - }, it) + }) } // Let alice invite bob @@ -380,7 +394,10 @@ class KeyShareTests : InstrumentedTest { val roomRoomBobPov = aliceSession.getRoom(roomId) val beforeJoin = roomRoomBobPov!!.getTimelineEvent(secondEventId) - var dRes = tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin!!.root, "") } + var dRes = + commonTestHelper.runBlockingTest { + tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin!!.root, "") } + } assert(dRes == null) @@ -391,7 +408,9 @@ class KeyShareTests : InstrumentedTest { Thread.sleep(3_000) // With the bug the first session would have improperly reshare that key :/ - dRes = tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin.root, "") } + dRes = commonTestHelper.runBlockingTest { + tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin.root, "") } + } Log.d("#TEST", "KS: sgould not decrypt that ${beforeJoin.root.getClearContent().toModel()?.body}") assert(dRes?.clearEvent == null) } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt index 2e24373526..4ff556895b 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.crypto.gossiping import android.util.Log import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest +import kotlinx.coroutines.runBlocking import org.junit.Assert import org.junit.FixMethodOrder import org.junit.Ignore @@ -92,7 +93,9 @@ class WithHeldTests : InstrumentedTest { // Bob should not be able to decrypt because the keys is withheld try { // .. might need to wait a bit for stability? - bobUnverifiedSession.cryptoService().decryptEvent(eventBobPOV.root, "") + runBlocking { + bobUnverifiedSession.cryptoService().decryptEvent(eventBobPOV.root, "") + } Assert.fail("This session should not be able to decrypt") } catch (failure: Throwable) { val type = (failure as MXCryptoError.Base).errorType @@ -117,7 +120,9 @@ class WithHeldTests : InstrumentedTest { // Previous message should still be undecryptable (partially withheld session) try { // .. might need to wait a bit for stability? - bobUnverifiedSession.cryptoService().decryptEvent(eventBobPOV.root, "") + runBlocking { + bobUnverifiedSession.cryptoService().decryptEvent(eventBobPOV.root, "") + } Assert.fail("This session should not be able to decrypt") } catch (failure: Throwable) { val type = (failure as MXCryptoError.Base).errorType @@ -164,7 +169,9 @@ class WithHeldTests : InstrumentedTest { val eventBobPOV = bobSession.getRoom(testData.roomId)?.getTimelineEvent(eventId) try { // .. might need to wait a bit for stability? - bobSession.cryptoService().decryptEvent(eventBobPOV!!.root, "") + runBlocking { + bobSession.cryptoService().decryptEvent(eventBobPOV!!.root, "") + } Assert.fail("This session should not be able to decrypt") } catch (failure: Throwable) { val type = (failure as MXCryptoError.Base).errorType @@ -222,7 +229,7 @@ class WithHeldTests : InstrumentedTest { cryptoTestHelper.initializeCrossSigning(bobSecondSession) // Trust bob second device from Alice POV - mTestHelper.runBlockingTest { + testHelper.runBlockingTest { aliceSession.cryptoService().crossSigningService().trustDevice(bobSecondSession.sessionParams.deviceId!!) bobSecondSession.cryptoService().crossSigningService().trustDevice(aliceSession.sessionParams.deviceId!!) } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index c9e319ad6a..524046c416 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.crypto.keysbackup import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull @@ -164,17 +165,22 @@ class KeysBackupTest : InstrumentedTest { val latch = CountDownLatch(1) - assertEquals(2, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)) - assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)) - + runBlocking { + assertEquals(2, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false)) + assertEquals(0, cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true)) + } val stateObserver = StateObserver(keysBackup, latch, 5) keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) testHelper.await(latch) - val nbOfKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false) - val backedUpKeys = cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true) + val nbOfKeys = runBlocking { + cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(false) + } + val backedUpKeys = runBlocking { + cryptoTestData.firstSession.cryptoService().inboundGroupSessionsCount(true) + } assertEquals(2, nbOfKeys) assertEquals("All keys must have been marked as backed up", nbOfKeys, backedUpKeys) @@ -833,9 +839,12 @@ class KeysBackupTest : InstrumentedTest { assertEquals(1, keysBackupVersionTrust.signatures.size) val signature = keysBackupVersionTrust.signatures[0] + val device = runBlocking { + cryptoTestData.firstSession.cryptoService().getMyDevice() + } assertTrue(signature.valid) assertNotNull(signature.device) - assertEquals(cryptoTestData.firstSession.cryptoService().getMyDevice().deviceId, signature.deviceId) + assertEquals(device.deviceId, signature.deviceId) assertEquals(signature.device!!.deviceId, cryptoTestData.firstSession.sessionParams.deviceId) stateObserver.stopAndCheckStates(null) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt index c5666ca2db..453de38d89 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt @@ -80,7 +80,10 @@ class KeysBackupTestHelper( } } - Assert.assertEquals(2, cryptoTestData.firstSession.cryptoService().keysBackupService().getTotalNumbersOfBackedUpKeys()) + val totalNumbersOfBackedUpKeys = testHelper.runBlockingTest { + cryptoTestData.firstSession.cryptoService().keysBackupService().getTotalNumbersOfBackedUpKeys() + } + Assert.assertEquals(2, totalNumbersOfBackedUpKeys) val aliceUserId = cryptoTestData.firstSession.myUserId @@ -88,15 +91,21 @@ class KeysBackupTestHelper( val aliceSession2 = testHelper.logIntoAccount(aliceUserId, KeysBackupTestConstants.defaultSessionParamsWithInitialSync) // Test check: aliceSession2 has no keys at login - Assert.assertEquals(0, aliceSession2.cryptoService().inboundGroupSessionsCount(false)) + val inboundGroupSessionCount = testHelper.runBlockingTest { + aliceSession2.cryptoService().inboundGroupSessionsCount(false) + } + Assert.assertEquals(0, inboundGroupSessionCount) // Wait for backup state to be NotTrusted waitForKeysBackupToBeInState(aliceSession2, KeysBackupState.NotTrusted) stateObserver.stopAndCheckStates(null) + val totalNumbersOfBackedUpKeysFromNewSession = testHelper.runBlockingTest { + aliceSession2.cryptoService().keysBackupService().getTotalNumbersOfBackedUpKeys() + } return KeysBackupScenarioData(cryptoTestData, - aliceSession2.cryptoService().keysBackupService().getTotalNumbersOfBackedUpKeys(), + totalNumbersOfBackedUpKeysFromNewSession, prepareKeysBackupDataResult, aliceSession2) } @@ -182,7 +191,10 @@ class KeysBackupTestHelper( Assert.assertEquals(total, imported) // - The new device must have the same count of megolm keys - Assert.assertEquals(testData.aliceKeys, testData.aliceSession2.cryptoService().inboundGroupSessionsCount(false)) + val inboundGroupSessionCount = testHelper.runBlockingTest { + testData.aliceSession2.cryptoService().inboundGroupSessionsCount(false) + } + Assert.assertEquals(testData.aliceKeys, inboundGroupSessionCount) // - Alice must have the same keys on both devices // From 39755b08ee3bd2bcf85b51b8d6458f2e82aaaa4f Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 21 Apr 2022 20:09:08 +0200 Subject: [PATCH 221/252] Continue cleaning up code and fix some verification code --- .../crosssigning/CrossSigningService.kt | 4 +- .../sdk/api/session/events/model/EventType.kt | 1 + .../session/room/model/message/MessageType.kt | 4 +- .../crypto/RustCrossSigningService.kt | 8 +- .../tasks/SendVerificationMessageTask.kt | 1 - .../verification/RustVerificationService.kt | 74 ++++++++++--------- 6 files changed, 49 insertions(+), 43 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index df8265a051..edc9c3b2dc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.api.session.crypto.crosssigning import kotlinx.coroutines.flow.Flow -import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.util.Optional @@ -92,8 +91,7 @@ interface CrossSigningService { fun allPrivateKeysKnown(): Boolean /** Mark a user identity as trusted and sign and upload signatures of our user-signing key to the server */ - suspend fun trustUser(otherUserId: String, - callback: MatrixCallback) + suspend fun trustUser(otherUserId: String) /** Mark our own master key as trusted */ suspend fun markMyMasterKeyAsTrusted() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt index 0c77b574e7..d33e318cc3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt @@ -91,6 +91,7 @@ object EventType { const val SEND_SECRET = "m.secret.send" // Interactive key verification + const val KEY_VERIFICATION_REQUEST = "m.key.verification.request" const val KEY_VERIFICATION_START = "m.key.verification.start" const val KEY_VERIFICATION_ACCEPT = "m.key.verification.accept" const val KEY_VERIFICATION_KEY = "m.key.verification.key" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt index 2a6138ae60..f4eb4b21a6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.api.session.room.model.message +import org.matrix.android.sdk.api.session.events.model.EventType + object MessageType { const val MSGTYPE_TEXT = "m.text" const val MSGTYPE_EMOTE = "m.emote" @@ -26,7 +28,7 @@ object MessageType { const val MSGTYPE_LOCATION = "m.location" const val MSGTYPE_FILE = "m.file" - const val MSGTYPE_VERIFICATION_REQUEST = "m.key.verification.request" + const val MSGTYPE_VERIFICATION_REQUEST = EventType.KEY_VERIFICATION_REQUEST // Add, in local, a fake message type in order to StickerMessage can inherit Message class // Because sticker isn't a message type but a event type without msgtype field diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index 07b34ca1c2..992782f3a7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -146,22 +146,20 @@ internal class RustCrossSigningService @Inject constructor( } /** Mark a user identity as trusted and sign and upload signatures of our user-signing key to the server */ - override suspend fun trustUser(otherUserId: String, callback: MatrixCallback) { + override suspend fun trustUser(otherUserId: String) { // This is only used in a test val userIdentity = olmMachine.getIdentity(otherUserId) - if (userIdentity != null) { userIdentity.verify() - callback.onSuccess(Unit) } else { - callback.onFailure(Throwable("## CrossSigning - CrossSigning is not setup for this account")) + throw Throwable("## CrossSigning - CrossSigning is not setup for this account") } } /** Mark our own master key as trusted */ override suspend fun markMyMasterKeyAsTrusted() { // This doesn't seem to be used? - trustUser(olmMachine.userId(), NoOpMatrixCallback()) + trustUser(olmMachine.userId()) } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt index c4a6ba27d6..7f782818c0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt @@ -67,7 +67,6 @@ internal class DefaultSendVerificationMessageTask @Inject constructor( return encryptEventTask.execute(EncryptEventTask.Params( params.event.roomId ?: "", params.event, - listOf("m.relates_to") )) } catch (throwable: Throwable) { // We said it's ok to send verification request in clear diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 01087dfaed..8ef383f193 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransa import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent import org.matrix.android.sdk.api.session.room.model.message.MessageType import org.matrix.android.sdk.internal.crypto.OlmMachineProvider @@ -76,7 +77,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin olmMachineProvider.olmMachine } - private val dispatcher = UpdateDispatcher(this.olmMachine.verificationListeners) + private val dispatcher = UpdateDispatcher(olmMachine.verificationListeners) /** The main entry point for the verification service * @@ -89,18 +90,22 @@ internal class RustVerificationService @Inject constructor(private val olmMachin * dispatches updates to our listeners. */ internal suspend fun onEvent(event: Event) = when (event.getClearType()) { - // I'm not entirely sure why getClearType() returns a msgtype in one case - // and a event type in the other case, but this is how the old verification - // service did things and it does seem to work. - MessageType.MSGTYPE_VERIFICATION_REQUEST -> onRequest(event) - EventType.KEY_VERIFICATION_START -> onStart(event) + EventType.KEY_VERIFICATION_REQUEST -> onRequest(event, fromRoomMessage = false) + EventType.KEY_VERIFICATION_START -> onStart(event) EventType.KEY_VERIFICATION_READY, EventType.KEY_VERIFICATION_ACCEPT, EventType.KEY_VERIFICATION_KEY, EventType.KEY_VERIFICATION_MAC, EventType.KEY_VERIFICATION_CANCEL, - EventType.KEY_VERIFICATION_DONE -> onUpdate(event) - else -> { + EventType.KEY_VERIFICATION_DONE -> onUpdate(event) + EventType.MESSAGE -> onRoomMessage(event) + else -> Unit + } + + private fun onRoomMessage(event: Event) { + val messageContent = event.getClearContent()?.toModel() ?: return + if (messageContent.msgType == MessageType.MSGTYPE_VERIFICATION_REQUEST) { + onRequest(event, fromRoomMessage = true) } } @@ -109,9 +114,9 @@ internal class RustVerificationService @Inject constructor(private val olmMachin val sender = event.senderId ?: return val flowId = getFlowId(event) ?: return - this.olmMachine.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() - val verification = this.getExistingTransaction(sender, flowId) ?: return - this.dispatcher.dispatchTxUpdated(verification) + olmMachine.getVerificationRequest(sender, flowId)?.dispatchRequestUpdated() + val verification = getExistingTransaction(sender, flowId) ?: return + dispatcher.dispatchTxUpdated(verification) } /** Check if the start event created new verification objects and dispatch updates */ @@ -119,8 +124,8 @@ internal class RustVerificationService @Inject constructor(private val olmMachin val sender = event.senderId ?: return val flowId = getFlowId(event) ?: return - val verification = this.getExistingTransaction(sender, flowId) ?: return - val request = this.olmMachine.getVerificationRequest(sender, flowId) + val verification = getExistingTransaction(sender, flowId) ?: return + val request = olmMachine.getVerificationRequest(sender, flowId) if (request != null && request.isReady()) { // If this is a SAS verification originating from a `m.key.verification.request` @@ -131,34 +136,37 @@ internal class RustVerificationService @Inject constructor(private val olmMachin Timber.d("## Verification: Auto accepting SAS verification with $sender") verification.accept() } else { - this.dispatcher.dispatchTxUpdated(verification) + dispatcher.dispatchTxUpdated(verification) } } else { // This didn't originate from a request, so tell our listeners that // this is a new verification. - this.dispatcher.dispatchTxAdded(verification) + dispatcher.dispatchTxAdded(verification) // The IncomingVerificationRequestHandler seems to only listen to updates // so let's trigger an update after the addition as well. - this.dispatcher.dispatchTxUpdated(verification) + dispatcher.dispatchTxUpdated(verification) } } /** Check if the request event created a nev verification request object and dispatch that it dis so */ - private fun onRequest(event: Event) { - val flowId = getFlowId(event) ?: return + private fun onRequest(event: Event, fromRoomMessage: Boolean) { + val flowId = if (fromRoomMessage) { + event.eventId + } else { + event.getClearContent().toModel()?.transactionId + } ?: return val sender = event.senderId ?: return + val request = getExistingVerificationRequest(sender, flowId) ?: return - val request = this.getExistingVerificationRequest(sender, flowId) ?: return - - this.dispatcher.dispatchRequestAdded(request) + dispatcher.dispatchRequestAdded(request) } override fun addListener(listener: VerificationService.Listener) { - this.dispatcher.addListener(listener) + dispatcher.addListener(listener) } override fun removeListener(listener: VerificationService.Listener) { - this.dispatcher.removeListener(listener) + dispatcher.removeListener(listener) } override suspend fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) { @@ -175,13 +183,13 @@ internal class RustVerificationService @Inject constructor(private val olmMachin otherUserId: String, tid: String, ): VerificationTransaction? { - return this.olmMachine.getVerification(otherUserId, tid) + return olmMachine.getVerification(otherUserId, tid) } override fun getExistingVerificationRequests( otherUserId: String ): List { - return this.olmMachine.getVerificationRequests(otherUserId).map { + return olmMachine.getVerificationRequests(otherUserId).map { it.toPendingVerificationRequest() } } @@ -191,7 +199,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin tid: String? ): PendingVerificationRequest? { return if (tid != null) { - this.olmMachine.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest() + olmMachine.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest() } else { null } @@ -256,8 +264,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin otherUserId: String, transactionId: String ): Boolean { - val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) - + val request = olmMachine.getVerificationRequest(otherUserId, transactionId) return if (request != null) { request.acceptWithMethods(methods) @@ -265,7 +272,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin val qrcode = request.startQrVerification() if (qrcode != null) { - this.dispatcher.dispatchTxAdded(qrcode) + dispatcher.dispatchTxAdded(qrcode) } true @@ -294,7 +301,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin ): String? { return if (method == VerificationMethod.SAS) { if (transactionId != null) { - val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId) + val request = olmMachine.getVerificationRequest(otherUserId, transactionId) val sas = request?.startSasVerification() @@ -310,7 +317,8 @@ internal class RustVerificationService @Inject constructor(private val olmMachin // be wise do do so as well // DeviceListBottomSheetViewModel triggers this, interestingly the method that // triggers this is called `manuallyVerify()` - val verification = olmMachine.getDevice(otherUserId, otherDeviceId)?.startVerification() + val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId) + val verification = otherDevice?.startVerification() if (verification != null) { dispatcher.dispatchTxAdded(verification) verification.transactionId @@ -338,7 +346,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin override suspend fun cancelVerificationRequest(request: PendingVerificationRequest) { val verificationRequest = request.transactionId?.let { - this.olmMachine.getVerificationRequest(request.otherUserId, it) + olmMachine.getVerificationRequest(request.otherUserId, it) } verificationRequest?.cancel() } @@ -348,7 +356,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin transactionId: String, roomId: String ) { - val verificationRequest = this.olmMachine.getVerificationRequest(otherUserId, transactionId) + val verificationRequest = olmMachine.getVerificationRequest(otherUserId, transactionId) verificationRequest?.cancel() } } From 5581b82ab47446e218909b67ca7984ab59e9f0aa Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Apr 2022 12:14:04 +0200 Subject: [PATCH 222/252] Let rust encrypt method handle unencrypted content ( like relates_to) --- .../internal/crypto/tasks/EncryptEventTask.kt | 27 ++++--------------- .../internal/crypto/tasks/SendEventTask.kt | 3 +-- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt index ac49102a07..b582930ab4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt @@ -29,9 +29,7 @@ import javax.inject.Inject internal interface EncryptEventTask : Task { data class Params(val roomId: String, - val event: Event, - /**Do not encrypt these keys, keep them as is in encrypted content (e.g. m.relates_to)*/ - val keepKeys: List? = null + val event: Event ) } @@ -49,22 +47,8 @@ internal class DefaultEncryptEventTask @Inject constructor( localEchoRepository.updateSendState(localEvent.eventId, localEvent.roomId, SendState.ENCRYPTING) - val localMutableContent = localEvent.content?.toMutableMap() ?: mutableMapOf() - params.keepKeys?.forEach { - localMutableContent.remove(it) - } - // let it throws - val result = cryptoService.encryptEventContent(localMutableContent, localEvent.type, params.roomId) - - val modifiedContent = HashMap(result.eventContent) - params.keepKeys?.forEach { toKeep -> - localEvent.content?.get(toKeep)?.let { - // put it back in the encrypted thing - modifiedContent[toKeep] = it - } - } - val safeResult = result.copy(eventContent = modifiedContent) + val result = cryptoService.encryptEventContent(localEvent.content ?: emptyMap(), localEvent.type, params.roomId) // Better handling of local echo, to avoid decrypting transition on remote echo // Should I only do it for text messages? val decryptionLocalEcho = if (result.eventContent["algorithm"] == MXCRYPTO_ALGORITHM_MEGOLM) { @@ -81,17 +65,16 @@ internal class DefaultEncryptEventTask @Inject constructor( } else { null } - localEchoRepository.updateEcho(localEvent.eventId) { _, localEcho -> localEcho.type = EventType.ENCRYPTED - localEcho.content = ContentMapper.map(modifiedContent) + localEcho.content = ContentMapper.map(result.eventContent) decryptionLocalEcho?.also { localEcho.setDecryptionResult(it) } } return localEvent.copy( - type = safeResult.eventType, - content = safeResult.eventContent + type = result.eventType, + content = result.eventContent ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt index 6620c1c6cc..33d5e5ab79 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt @@ -76,8 +76,7 @@ internal class DefaultSendEventTask @Inject constructor( if (params.encrypt && !params.event.isEncrypted()) { return encryptEventTask.execute(EncryptEventTask.Params( params.event.roomId ?: "", - params.event, - listOf("m.relates_to") + params.event )) } return params.event From 309a290cb86e6b560fdc3a2646c06301e1eb68ea Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 25 Apr 2022 17:55:17 +0200 Subject: [PATCH 223/252] Suspend: fix flow builders --- .../coroutines/builder/FlowBuilders.kt | 44 ++++++++++++++ .../android/sdk/internal/crypto/OlmMachine.kt | 58 +++++++++++-------- 2 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/coroutines/builder/FlowBuilders.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/coroutines/builder/FlowBuilders.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/coroutines/builder/FlowBuilders.kt new file mode 100644 index 0000000000..282b1b2cf3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/coroutines/builder/FlowBuilders.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.coroutines.builder + +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.channels.ProducerScope + +/** + * Use this with a flow builder like [kotlinx.coroutines.flow.channelFlow] to replace [kotlinx.coroutines.channels.awaitClose]. + * As awaitClose is at the end of the builder block, it can lead to the block being cancelled before it reaches the awaitClose. + * Example of usage: + * + * return channelFlow { + * val onClose = safeInvokeOnClose { + * // Do stuff on close + * } + * val data = getData() + * send(data) + * onClose.await() + * } + * + */ +fun ProducerScope.safeInvokeOnClose(handler: (cause: Throwable?) -> Unit): CompletableDeferred { + val onClose = CompletableDeferred() + invokeOnClose { + handler(it) + onClose.complete(Unit) + } + return onClose +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index 581a3425d6..46fab21f0b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.crypto import com.squareup.moshi.Moshi import kotlinx.coroutines.channels.SendChannel -import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.runBlocking @@ -39,6 +38,7 @@ import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional +import org.matrix.android.sdk.internal.coroutines.builder.safeInvokeOnClose import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData @@ -48,7 +48,6 @@ import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo -import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.network.parsing.CheckNumberType import timber.log.Timber import uniffi.olm.BackupKeys @@ -67,7 +66,6 @@ import uniffi.olm.setLogger import java.io.File import java.nio.charset.Charset import java.util.UUID -import java.util.concurrent.CopyOnWriteArrayList import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener import uniffi.olm.UserIdentity as RustUserIdentity @@ -89,9 +87,9 @@ private data class DevicesCollector(val userIds: List, val collector: Se private typealias PrivateKeysCollector = SendChannel> private class FlowCollectors { - val userIdentityCollectors = CopyOnWriteArrayList() - val privateKeyCollectors = CopyOnWriteArrayList() - val deviceCollectors = CopyOnWriteArrayList() + val userIdentityCollectors = ArrayList() + val privateKeyCollectors = ArrayList() + val deviceCollectors = ArrayList() } fun setRustLogger() { @@ -132,21 +130,21 @@ internal class OlmMachine( private suspend fun updateLiveDevices() { for (deviceCollector in flowCollectors.deviceCollectors) { val devices = getCryptoDeviceInfo(deviceCollector.userIds) - deviceCollector.send(devices) + deviceCollector.trySend(devices) } } private suspend fun updateLiveUserIdentities() { for (userIdentityCollector in flowCollectors.userIdentityCollectors) { val identity = getIdentity(userIdentityCollector.userId)?.toMxCrossSigningInfo() - userIdentityCollector.send(identity.toOptional()) + userIdentityCollector.trySend(identity.toOptional()) } } private suspend fun updateLivePrivateKeys() { val keys = exportCrossSigningKeys().toOptional() for (privateKeyCollector in flowCollectors.privateKeyCollectors) { - privateKeyCollector.send(keys) + privateKeyCollector.trySend(keys) } } @@ -204,7 +202,6 @@ internal class OlmMachine( ) = withContext(coroutineDispatchers.io) { inner.markRequestAsSent(requestId, requestType, responseBody) - if (requestType == RequestType.KEYS_QUERY) { updateLiveDevices() updateLiveUserIdentities() @@ -652,7 +649,18 @@ internal class OlmMachine( * The key query request will be retried a few time in case of shaky connection, but could fail. */ suspend fun ensureUserDevicesMap(userIds: List, forceDownload: Boolean = false): MXUsersDevicesMap { - val toDownload = if (forceDownload) { + ensureUsersKeys(userIds, forceDownload) + return getUserDevicesMap(userIds) + } + + /** + * If the user is untracked or forceDownload is set to true, a key query request will be made. + * It will suspend until query response. + * + * The key query request will be retried a few time in case of shaky connection, but could fail. + */ + suspend fun ensureUsersKeys(userIds: List, forceDownload: Boolean = false) { + val userIdsToFetchKeys = if (forceDownload) { userIds } else { userIds.mapNotNull { userId -> @@ -661,32 +669,33 @@ internal class OlmMachine( updateTrackedUsers(it) } } - tryOrNull("Failed to download keys for $toDownload") { - forceKeyDownload(toDownload) + tryOrNull("Failed to download keys for $userIdsToFetchKeys") { + forceKeyDownload(userIdsToFetchKeys) } - return getUserDevicesMap(userIds) } fun getLiveUserIdentity(userId: String): Flow> { return channelFlow { val userIdentityCollector = UserIdentityCollector(userId, this) + val onClose = safeInvokeOnClose { + flowCollectors.userIdentityCollectors.remove(userIdentityCollector) + } flowCollectors.userIdentityCollectors.add(userIdentityCollector) val identity = getIdentity(userId)?.toMxCrossSigningInfo().toOptional() send(identity) - awaitClose { - flowCollectors.userIdentityCollectors.remove(userIdentityCollector) - } + onClose.await() } } fun getLivePrivateCrossSigningKeys(): Flow> { return channelFlow { + val onClose = safeInvokeOnClose { + flowCollectors.privateKeyCollectors.remove(this) + } flowCollectors.privateKeyCollectors.add(this) val keys = this@OlmMachine.exportCrossSigningKeys().toOptional() send(keys) - awaitClose { - flowCollectors.privateKeyCollectors.remove(this) - } + onClose.await() } } @@ -698,17 +707,18 @@ internal class OlmMachine( * * @param userIds The ids of the device owners. * - * @return The list of Devices or an empty list if there aren't any. + * @return The list of Devices or an empty list if there aren't any as a Flow. */ fun getLiveDevices(userIds: List): Flow> { return channelFlow { val devicesCollector = DevicesCollector(userIds, this) + val onClose = safeInvokeOnClose { + flowCollectors.deviceCollectors.remove(devicesCollector) + } flowCollectors.deviceCollectors.add(devicesCollector) val devices = getCryptoDeviceInfo(userIds) send(devices) - awaitClose { - flowCollectors.deviceCollectors.remove(devicesCollector) - } + onClose.await() } } From 8bd094fa66bffd9de8f7daf7270ea9c36d68918d Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 25 Apr 2022 17:55:37 +0200 Subject: [PATCH 224/252] Do some cleanup on verification APIs --- .../android/sdk/common/CryptoTestHelper.kt | 23 +- .../crypto/crosssigning/XSigningTest.kt | 82 ++++-- .../crypto/gossiping/KeyShareTests.kt | 37 ++- .../internal/crypto/verification/SASTest.kt | 275 ++++++++++-------- .../{qrcode => }/VerificationTest.kt | 71 ++--- .../verification/qrcode/SharedSecretTest.kt | 46 --- .../IncomingSasVerificationTransaction.kt | 34 --- .../OutgoingSasVerificationTransaction.kt | 32 -- .../verification/VerificationService.kt | 63 ++-- .../internal/crypto/DefaultCryptoService.kt | 2 +- .../verification/RustVerificationService.kt | 88 ++---- .../verification/qrcode/SharedSecret.kt | 29 -- .../app/VerifySessionInteractiveTest.kt | 7 +- .../IncomingVerificationRequestHandler.kt | 5 +- .../VerificationBottomSheetViewModel.kt | 16 +- .../home/room/detail/TimelineViewModel.kt | 8 +- .../features/navigation/DefaultNavigator.kt | 12 +- .../devices/DeviceListBottomSheetViewModel.kt | 5 +- .../settings/devices/DevicesViewModel.kt | 2 +- 19 files changed, 323 insertions(+), 514 deletions(-) rename matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/{qrcode => }/VerificationTest.kt (71%) delete mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecretTest.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/IncomingSasVerificationTransaction.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/OutgoingSasVerificationTransaction.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecret.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index d8546b4d8d..ba0b467122 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -30,8 +30,7 @@ import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction +import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import org.matrix.android.sdk.api.session.events.model.Event @@ -311,16 +310,16 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) { } // we should reach SHOW SAS on both - var alicePovTx: OutgoingSasVerificationTransaction? = null - var bobPovTx: IncomingSasVerificationTransaction? = null + var alicePovTx: SasVerificationTransaction? = null + var bobPovTx: SasVerificationTransaction? = null // wait for alice to get the ready testHelper.waitWithLatch { testHelper.retryPeriodicallyWithLatch(it) { - bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? IncomingSasVerificationTransaction - Log.v("TEST", "== bobPovTx is ${alicePovTx?.uxState}") + bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? SasVerificationTransaction + Log.v("TEST", "== bobPovTx is ${bobPovTx?.state}") if (bobPovTx?.state == VerificationTxState.OnStarted) { - bobPovTx?.performAccept() + bobPovTx?.acceptVerification() true } else { false @@ -330,18 +329,18 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) { testHelper.waitWithLatch { testHelper.retryPeriodicallyWithLatch(it) { - alicePovTx = aliceVerificationService.getExistingTransaction(bob.myUserId, requestID) as? OutgoingSasVerificationTransaction - Log.v("TEST", "== alicePovTx is ${alicePovTx?.uxState}") + alicePovTx = aliceVerificationService.getExistingTransaction(bob.myUserId, requestID) as? SasVerificationTransaction + Log.v("TEST", "== alicePovTx is ${alicePovTx?.state}") alicePovTx?.state == VerificationTxState.ShortCodeReady } } // wait for alice to get the ready testHelper.waitWithLatch { testHelper.retryPeriodicallyWithLatch(it) { - bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? IncomingSasVerificationTransaction - Log.v("TEST", "== bobPovTx is ${alicePovTx?.uxState}") + bobPovTx = bobVerificationService.getExistingTransaction(alice.myUserId, requestID) as? SasVerificationTransaction + Log.v("TEST", "== bobPovTx is ${bobPovTx?.state}") if (bobPovTx?.state == VerificationTxState.OnStarted) { - bobPovTx?.performAccept() + bobPovTx?.acceptVerification() } bobPovTx?.state == VerificationTxState.ShortCodeReady } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt index b4c8f1a22a..fc8aa57de0 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto.crosssigning import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull @@ -53,7 +54,7 @@ class XSigningTest : InstrumentedTest { fun test_InitializeAndStoreKeys() { val aliceSession = testHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true)) - testHelper.doSync { + testHelper.runBlockingTest { aliceSession.cryptoService().crossSigningService() .initializeCrossSigning(object : UserInteractiveAuthInterceptor { override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { @@ -65,10 +66,12 @@ class XSigningTest : InstrumentedTest { ) ) } - }, it) + }) } - val myCrossSigningKeys = aliceSession.cryptoService().crossSigningService().getMyCrossSigningKeys() + val myCrossSigningKeys = testHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().getMyCrossSigningKeys() + } val masterPubKey = myCrossSigningKeys?.masterKey() assertNotNull("Master key should be stored", masterPubKey?.unpaddedBase64PublicKey) val selfSigningKey = myCrossSigningKeys?.selfSigningKey() @@ -78,7 +81,10 @@ class XSigningTest : InstrumentedTest { assertTrue("Signing Keys should be trusted", myCrossSigningKeys?.isTrusted() == true) - assertTrue("Signing Keys should be trusted", aliceSession.cryptoService().crossSigningService().checkUserTrust(aliceSession.myUserId).isVerified()) + val userTrustResult = testHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().checkUserTrust(aliceSession.myUserId) + } + assertTrue("Signing Keys should be trusted", userTrustResult.isVerified()) testHelper.signOutAndClose(aliceSession) } @@ -99,29 +105,37 @@ class XSigningTest : InstrumentedTest { password = TestConstants.PASSWORD ) - testHelper.doSync { + testHelper.runBlockingTest { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor { override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { promise.resume(aliceAuthParams) } - }, it) + }) + } + testHelper.runBlockingTest { + bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor { + override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { + promise.resume(bobAuthParams) + } + }) } - testHelper.doSync { bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor { - override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { - promise.resume(bobAuthParams) - } - }, it) } // Check that alice can see bob keys testHelper.runBlockingTest { aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), true) } - val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobSession.myUserId) + val bobKeysFromAlicePOV = testHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobSession.myUserId) + } assertNotNull("Alice can see bob Master key", bobKeysFromAlicePOV!!.masterKey()) assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey()) assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey()) - assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey) - assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey) + val myKeys = testHelper.runBlockingTest { + bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys() + } + + assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, myKeys?.masterKey()?.unpaddedBase64PublicKey) + assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, myKeys?.selfSigningKey()?.unpaddedBase64PublicKey) assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted()) @@ -145,25 +159,33 @@ class XSigningTest : InstrumentedTest { password = TestConstants.PASSWORD ) - testHelper.doSync { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor { - override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { - promise.resume(aliceAuthParams) - } - }, it) } - testHelper.doSync { bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor { - override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { - promise.resume(bobAuthParams) - } - }, it) } + testHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor { + override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { + promise.resume(aliceAuthParams) + } + }) + } + testHelper.runBlockingTest { + bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor { + override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { + promise.resume(bobAuthParams) + } + }) + } // Check that alice can see bob keys val bobUserId = bobSession.myUserId testHelper.runBlockingTest { aliceSession.cryptoService().downloadKeys(listOf(bobUserId), true) } - val bobKeysFromAlicePOV = aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobUserId) + val bobKeysFromAlicePOV = testHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().getUserCrossSigningKeys(bobUserId) + } assertTrue("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV?.isTrusted() == false) - testHelper.doSync { aliceSession.cryptoService().crossSigningService().trustUser(bobUserId, it) } + testHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().trustUser(bobUserId) + } // Now bobs logs in on a new device and verifies it // We will want to test that in alice POV, this new device would be trusted by cross signing @@ -180,7 +202,9 @@ class XSigningTest : InstrumentedTest { fail("Bob should see the new device") } - val bobSecondDevicePOVFirstDevice = bobSession.cryptoService().getDeviceInfo(bobUserId, bobSecondDeviceId) + val bobSecondDevicePOVFirstDevice = runBlocking { + bobSession.cryptoService().getDeviceInfo(bobUserId, bobSecondDeviceId) + } assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice) // Manually mark it as trusted from first session @@ -198,7 +222,9 @@ class XSigningTest : InstrumentedTest { fail("Alice should see the new device") } - val result = aliceSession.cryptoService().crossSigningService().checkDeviceTrust(bobUserId, bobSecondDeviceId, null) + val result = testHelper.runBlockingTest { + aliceSession.cryptoService().crossSigningService().checkDeviceTrust(bobUserId, bobSecondDeviceId, null) + } assertTrue("Bob second device should be trusted from alice POV", result.isCrossSignedVerified()) testHelper.signOutAndClose(aliceSession) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 8ec650a122..613a54a6b9 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -24,7 +24,6 @@ import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.assertTrue import junit.framework.TestCase.fail import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking import org.junit.Assert import org.junit.FixMethodOrder import org.junit.Ignore @@ -37,7 +36,6 @@ import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService @@ -250,32 +248,31 @@ class KeyShareTests : InstrumentedTest { aliceVerificationService1.addListener(object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { + if (tx !is SasVerificationTransaction) return Log.d("#TEST", "AA: tx incoming?:${tx.isIncoming} state ${tx.state}") - if (tx is SasVerificationTransaction) { - if (tx.state == VerificationTxState.OnStarted) { - (tx as IncomingSasVerificationTransaction).performAccept() + when (tx.state) { + VerificationTxState.OnStarted -> commonTestHelper.runBlockingTest { + tx.acceptVerification() } - if (tx.state == VerificationTxState.ShortCodeReady) { + VerificationTxState.ShortCodeReady -> commonTestHelper.runBlockingTest { session1ShortCode = tx.getDecimalCodeRepresentation() - commonTestHelper.runBlockingTest { - delay(500) - tx.userHasVerifiedShortCode() - } + delay(500) + tx.userHasVerifiedShortCode() } } } - }) + } + ) aliceVerificationService2.addListener(object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { + if (tx !is SasVerificationTransaction) return Log.d("#TEST", "BB: tx incoming?:${tx.isIncoming} state ${tx.state}") - if (tx is SasVerificationTransaction) { - if (tx.state == VerificationTxState.ShortCodeReady) { + when (tx.state) { + VerificationTxState.ShortCodeReady -> commonTestHelper.runBlockingTest { session2ShortCode = tx.getDecimalCodeRepresentation() - commonTestHelper.runBlockingTest { - delay(500) - tx.userHasVerifiedShortCode() - } + delay(500) + tx.userHasVerifiedShortCode() } } } @@ -301,7 +298,8 @@ class KeyShareTests : InstrumentedTest { // SSK and USK private keys should have been shared - commonTestHelper.waitWithLatch(60_000) { latch -> + commonTestHelper.waitWithLatch(60_000) + { latch -> commonTestHelper.retryPeriodicallyWithLatch(latch) { Log.d("#TEST", "CAN XS :${aliceSession2.cryptoService().crossSigningService().getMyCrossSigningKeys()}") aliceSession2.cryptoService().crossSigningService().canCrossSign() @@ -309,7 +307,8 @@ class KeyShareTests : InstrumentedTest { } // Test that key backup key has been shared to - commonTestHelper.waitWithLatch(60_000) { latch -> + commonTestHelper.waitWithLatch(60_000) + { latch -> val keysBackupService = aliceSession2.cryptoService().keysBackupService() commonTestHelper.retryPeriodicallyWithLatch(latch) { Log.d("#TEST", "Recovery :${keysBackupService.getKeyBackupRecoveryKeyInfo()?.recoveryKey}") diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt index 8cd725504d..395e86ac92 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto.verification import android.util.Log import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull @@ -32,9 +33,7 @@ import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.verification.CancelCode -import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction -import org.matrix.android.sdk.api.session.crypto.verification.SasMode +import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService @@ -49,6 +48,8 @@ import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart import org.matrix.android.sdk.internal.crypto.model.rest.toValue +import timber.log.Timber +import java.util.UUID import java.util.concurrent.CountDownLatch @RunWith(AndroidJUnit4::class) @@ -75,10 +76,15 @@ class SASTest : InstrumentedTest { } bobVerificationService.addListener(bobListener) - val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, - bobSession.myUserId, - bobSession.cryptoService().getMyDevice().deviceId, - null) + val myDevice = testHelper.runBlockingTest { + bobSession.cryptoService().getMyDevice() + } + val txID = testHelper.runBlockingTest { + aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, + bobSession.myUserId, + myDevice.deviceId, + null) + } assertNotNull("Alice should have a started transaction", txID) val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!) @@ -90,16 +96,14 @@ class SASTest : InstrumentedTest { val bobKeyTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, txID) assertNotNull("Bob should have started verif transaction", bobKeyTx) - assertTrue(bobKeyTx is SASDefaultVerificationTransaction) + assertTrue(bobKeyTx is SasVerificationTransaction) assertNotNull("Bob should have starting a SAS transaction", bobKeyTx) - assertTrue(aliceKeyTx is SASDefaultVerificationTransaction) + assertTrue(aliceKeyTx is SasVerificationTransaction) assertEquals("Alice and Bob have same transaction id", aliceKeyTx!!.transactionId, bobKeyTx!!.transactionId) - val aliceSasTx = aliceKeyTx as SASDefaultVerificationTransaction? - val bobSasTx = bobKeyTx as SASDefaultVerificationTransaction? - assertEquals("Alice state should be started", VerificationTxState.Started, aliceSasTx!!.state) - assertEquals("Bob state should be started by alice", VerificationTxState.OnStarted, bobSasTx!!.state) + assertEquals("Alice state should be started", VerificationTxState.Started, aliceKeyTx.state) + assertEquals("Bob state should be started by alice", VerificationTxState.OnStarted, bobKeyTx.state) // Let's cancel from alice side val cancelLatch = CountDownLatch(1) @@ -107,7 +111,7 @@ class SASTest : InstrumentedTest { val bobListener2 = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { if (tx.transactionId == txID) { - val immutableState = (tx as SASDefaultVerificationTransaction).state + val immutableState = (tx as SasVerificationTransaction).state if (immutableState is VerificationTxState.Cancelled && !immutableState.byMe) { cancelLatch.countDown() } @@ -116,14 +120,16 @@ class SASTest : InstrumentedTest { } bobVerificationService.addListener(bobListener2) - aliceSasTx.cancel(CancelCode.User) + testHelper.runBlockingTest { + aliceKeyTx.cancel(CancelCode.User) + } testHelper.await(cancelLatch) - assertTrue("Should be cancelled on alice side", aliceSasTx.state is VerificationTxState.Cancelled) - assertTrue("Should be cancelled on bob side", bobSasTx.state is VerificationTxState.Cancelled) + assertTrue("Should be cancelled on alice side", aliceKeyTx.state is VerificationTxState.Cancelled) + assertTrue("Should be cancelled on bob side", bobKeyTx.state is VerificationTxState.Cancelled) - val aliceCancelState = aliceSasTx.state as VerificationTxState.Cancelled - val bobCancelState = bobSasTx.state as VerificationTxState.Cancelled + val aliceCancelState = aliceKeyTx.state as VerificationTxState.Cancelled + val bobCancelState = bobKeyTx.state as VerificationTxState.Cancelled assertTrue("Should be cancelled by me on alice side", aliceCancelState.byMe) assertFalse("Should be cancelled by other on bob side", bobCancelState.byMe) @@ -177,12 +183,16 @@ class SASTest : InstrumentedTest { val aliceSession = cryptoTestData.firstSession val aliceUserID = aliceSession.myUserId - val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId + val aliceDevice = testHelper.runBlockingTest { + aliceSession.cryptoService().getMyDevice().deviceId + } val aliceListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { - if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { - (tx as IncomingSasVerificationTransaction).performAccept() + if (tx.state is VerificationTxState.OnStarted && tx is SasVerificationTransaction) { + testHelper.runBlockingTest { + tx.acceptVerification() + } } } } @@ -226,7 +236,9 @@ class SASTest : InstrumentedTest { val aliceSession = cryptoTestData.firstSession val aliceUserID = aliceSession.myUserId - val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId + val aliceDevice = testHelper.runBlockingTest { + aliceSession.cryptoService().getMyDevice().deviceId + } fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, mac = mac) @@ -267,7 +279,9 @@ class SASTest : InstrumentedTest { val aliceSession = cryptoTestData.firstSession val aliceUserID = aliceSession.myUserId - val aliceDevice = aliceSession.cryptoService().getMyDevice().deviceId + val aliceDevice = testHelper.runBlockingTest { + aliceSession.cryptoService().getMyDevice().deviceId + } fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, codes = codes) @@ -283,12 +297,15 @@ class SASTest : InstrumentedTest { aliceUserID: String?, aliceDevice: String?, tid: String, - protocols: List = SASDefaultVerificationTransaction.KNOWN_AGREEMENT_PROTOCOLS, - hashes: List = SASDefaultVerificationTransaction.KNOWN_HASHES, - mac: List = SASDefaultVerificationTransaction.KNOWN_MACS, - codes: List = SASDefaultVerificationTransaction.KNOWN_SHORT_CODES) { + protocols: List = emptyList(), + hashes: List = emptyList(), + mac: List = emptyList(), + codes: List = emptyList()) { + val deviceId = runBlocking { + bobSession.cryptoService().getMyDevice().deviceId + } val startMessage = KeyVerificationStart( - fromDevice = bobSession.cryptoService().getMyDevice().deviceId, + fromDevice = deviceId, method = VerificationMethod.SAS.toValue(), transactionId = tid, keyAgreementProtocols = protocols, @@ -324,15 +341,15 @@ class SASTest : InstrumentedTest { val aliceCreatedLatch = CountDownLatch(2) val aliceCancelledLatch = CountDownLatch(2) - val createdTx = mutableListOf() + val createdTx = mutableListOf() val aliceListener = object : VerificationService.Listener { override fun transactionCreated(tx: VerificationTransaction) { - createdTx.add(tx as SASDefaultVerificationTransaction) + createdTx.add(tx) aliceCreatedLatch.countDown() } override fun transactionUpdated(tx: VerificationTransaction) { - if ((tx as SASDefaultVerificationTransaction).state is VerificationTxState.Cancelled && !(tx.state as VerificationTxState.Cancelled).byMe) { + if (tx.state is VerificationTxState.Cancelled && !(tx.state as VerificationTxState.Cancelled).byMe) { aliceCancelledLatch.countDown() } } @@ -340,10 +357,13 @@ class SASTest : InstrumentedTest { aliceVerificationService.addListener(aliceListener) val bobUserId = bobSession!!.myUserId - val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId - aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) - aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) - + val bobDeviceId = testHelper.runBlockingTest { + bobSession.cryptoService().getMyDevice().deviceId + } + testHelper.runBlockingTest { + aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) + aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) + } testHelper.await(aliceCreatedLatch) testHelper.await(aliceCancelledLatch) @@ -366,17 +386,10 @@ class SASTest : InstrumentedTest { val aliceVerificationService = aliceSession.cryptoService().verificationService() val bobVerificationService = bobSession!!.cryptoService().verificationService() - var accepted: ValidVerificationInfoAccept? = null - var startReq: ValidVerificationInfoStart.SasVerificationInfoStart? = null - val aliceAcceptedLatch = CountDownLatch(1) val aliceListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { - Log.v("TEST", "== aliceTx state ${tx.state} => ${(tx as? OutgoingSasVerificationTransaction)?.uxState}") - if ((tx as SASDefaultVerificationTransaction).state === VerificationTxState.OnAccepted) { - val at = tx as SASDefaultVerificationTransaction - accepted = at.accepted - startReq = at.startReq + if (tx.state is VerificationTxState.OnAccepted) { aliceAcceptedLatch.countDown() } } @@ -385,32 +398,24 @@ class SASTest : InstrumentedTest { val bobListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { - Log.v("TEST", "== bobTx state ${tx.state} => ${(tx as? IncomingSasVerificationTransaction)?.uxState}") - if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { + if (tx.state is VerificationTxState.OnStarted && tx is SasVerificationTransaction) { bobVerificationService.removeListener(this) - val at = tx as IncomingSasVerificationTransaction - at.performAccept() + testHelper.runBlockingTest { + tx.acceptVerification() + } } } } bobVerificationService.addListener(bobListener) val bobUserId = bobSession.myUserId - val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId - aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) - testHelper.await(aliceAcceptedLatch) - - assertTrue("Should have receive a commitment", accepted!!.commitment?.trim()?.isEmpty() == false) - - // check that agreement is valid - assertTrue("Agreed Protocol should be Valid", accepted != null) - assertTrue("Agreed Protocol should be known by alice", startReq!!.keyAgreementProtocols.contains(accepted!!.keyAgreementProtocol)) - assertTrue("Hash should be known by alice", startReq!!.hashes.contains(accepted!!.hash)) - assertTrue("Hash should be known by alice", startReq!!.messageAuthenticationCodes.contains(accepted!!.messageAuthenticationCode)) - - accepted!!.shortAuthenticationStrings.forEach { - assertTrue("all agreed Short Code should be known by alice", startReq!!.shortAuthenticationStrings.contains(it)) + val bobDeviceId = runBlocking { + bobSession.cryptoService().getMyDevice().deviceId } + testHelper.runBlockingTest { + aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) + } + testHelper.await(aliceAcceptedLatch) cryptoTestData.cleanUp(testHelper) } @@ -422,20 +427,22 @@ class SASTest : InstrumentedTest { val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom() val aliceSession = cryptoTestData.firstSession - val bobSession = cryptoTestData.secondSession + val bobSession = cryptoTestData.secondSession!! + + cryptoTestHelper.initializeCrossSigning(aliceSession) + cryptoTestHelper.initializeCrossSigning(bobSession) val aliceVerificationService = aliceSession.cryptoService().verificationService() - val bobVerificationService = bobSession!!.cryptoService().verificationService() + val bobVerificationService = bobSession.cryptoService().verificationService() val aliceSASLatch = CountDownLatch(1) val aliceListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { - val uxState = (tx as OutgoingSasVerificationTransaction).uxState - when (uxState) { - OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> { + when (tx.state) { + VerificationTxState.ShortCodeReady -> { aliceSASLatch.countDown() } - else -> Unit + else -> Unit } } } @@ -443,32 +450,42 @@ class SASTest : InstrumentedTest { val bobSASLatch = CountDownLatch(1) val bobListener = object : VerificationService.Listener { + + override fun verificationRequestCreated(pr: PendingVerificationRequest) { + + } + override fun transactionUpdated(tx: VerificationTransaction) { - val uxState = (tx as IncomingSasVerificationTransaction).uxState - when (uxState) { - IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> { - tx.performAccept() + val sasVerification = tx as SasVerificationTransaction + when (tx.state) { + VerificationTxState.OnStarted -> testHelper.runBlockingTest { + sasVerification.acceptVerification() } - else -> Unit - } - if (uxState === IncomingSasVerificationTransaction.UxState.SHOW_SAS) { - bobSASLatch.countDown() + VerificationTxState.ShortCodeReady -> { + bobSASLatch.countDown() + } + else -> Unit } } } bobVerificationService.addListener(bobListener) val bobUserId = bobSession.myUserId - val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId - val verificationSAS = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) + testHelper.runBlockingTest { + aliceSession.cryptoService().downloadKeys(listOf(bobUserId), forceDownload = true) + aliceVerificationService.requestKeyVerificationInDMs(listOf(VerificationMethod.SAS),bobUserId, cryptoTestData.roomId) + } testHelper.await(aliceSASLatch) testHelper.await(bobSASLatch) - val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SASDefaultVerificationTransaction - val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SASDefaultVerificationTransaction + /* + val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SasVerificationTransaction + val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SasVerificationTransaction - assertEquals("Should have same SAS", aliceTx.getShortCodeRepresentation(SasMode.DECIMAL), - bobTx.getShortCodeRepresentation(SasMode.DECIMAL)) + + assertEquals("Should have same SAS", aliceTx.getDecimalCodeRepresentation(), bobTx.getDecimalCodeRepresentation()) + + */ cryptoTestData.cleanUp(testHelper) } @@ -489,19 +506,18 @@ class SASTest : InstrumentedTest { val aliceListener = object : VerificationService.Listener { var matchOnce = true override fun transactionUpdated(tx: VerificationTransaction) { - val uxState = (tx as OutgoingSasVerificationTransaction).uxState - Log.v("TEST", "== aliceState ${uxState.name}") - when (uxState) { - OutgoingSasVerificationTransaction.UxState.SHOW_SAS -> { + if (tx !is SasVerificationTransaction) return + when (tx.state) { + VerificationTxState.ShortCodeReady -> testHelper.runBlockingTest { tx.userHasVerifiedShortCode() } - OutgoingSasVerificationTransaction.UxState.VERIFIED -> { + VerificationTxState.Verified -> { if (matchOnce) { matchOnce = false aliceSASLatch.countDown() } } - else -> Unit + else -> Unit } } } @@ -512,40 +528,46 @@ class SASTest : InstrumentedTest { var acceptOnce = true var matchOnce = true override fun transactionUpdated(tx: VerificationTransaction) { - val uxState = (tx as IncomingSasVerificationTransaction).uxState - Log.v("TEST", "== bobState ${uxState.name}") - when (uxState) { - IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT -> { + if (tx !is SasVerificationTransaction) return + when (tx.state) { + VerificationTxState.OnStarted -> testHelper.runBlockingTest { if (acceptOnce) { acceptOnce = false - tx.performAccept() + tx.acceptVerification() } } - IncomingSasVerificationTransaction.UxState.SHOW_SAS -> { + VerificationTxState.ShortCodeReady -> testHelper.runBlockingTest { if (matchOnce) { matchOnce = false tx.userHasVerifiedShortCode() } } - IncomingSasVerificationTransaction.UxState.VERIFIED -> { + VerificationTxState.Verified -> { bobSASLatch.countDown() } - else -> Unit + else -> Unit } } } bobVerificationService.addListener(bobListener) val bobUserId = bobSession.myUserId - val bobDeviceId = bobSession.cryptoService().getMyDevice().deviceId - aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) + val bobDeviceId = runBlocking { + bobSession.cryptoService().getMyDevice().deviceId + } + testHelper.runBlockingTest { + aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null) + } testHelper.await(aliceSASLatch) testHelper.await(bobSASLatch) // Assert that devices are verified - val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId) - val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId) - + val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = testHelper.runBlockingTest { + aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId) + } + val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = testHelper.runBlockingTest { + bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId) + } assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified) assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified) cryptoTestData.cleanUp(testHelper) @@ -563,11 +585,13 @@ class SASTest : InstrumentedTest { val aliceVerificationService = aliceSession.cryptoService().verificationService() val bobVerificationService = bobSession!!.cryptoService().verificationService() - val req = aliceVerificationService.requestKeyVerificationInDMs( - listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW), - bobSession.myUserId, - cryptoTestData.roomId - ) + val req = testHelper.runBlockingTest { + aliceVerificationService.requestKeyVerificationInDMs( + listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW), + bobSession.myUserId, + cryptoTestData.roomId + ) + } var requestID: String? = null @@ -590,11 +614,13 @@ class SASTest : InstrumentedTest { } } - bobVerificationService.readyPendingVerification( - listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW), - aliceSession.myUserId, - requestID!! - ) + testHelper.runBlockingTest { + bobVerificationService.readyPendingVerification( + listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW), + aliceSession.myUserId, + requestID!! + ) + } // wait for alice to get the ready testHelper.waitWithLatch { @@ -606,19 +632,22 @@ class SASTest : InstrumentedTest { } // Start concurrent! - aliceVerificationService.beginKeyVerificationInDMs( - VerificationMethod.SAS, - requestID!!, - cryptoTestData.roomId, - bobSession.myUserId, - bobSession.sessionParams.deviceId!!) + testHelper.runBlockingTest { + aliceVerificationService.beginKeyVerificationInDMs( + VerificationMethod.SAS, + requestID!!, + cryptoTestData.roomId, + bobSession.myUserId, + bobSession.sessionParams.deviceId!!) - bobVerificationService.beginKeyVerificationInDMs( - VerificationMethod.SAS, - requestID!!, - cryptoTestData.roomId, - aliceSession.myUserId, - aliceSession.sessionParams.deviceId!!) + bobVerificationService.beginKeyVerificationInDMs( + VerificationMethod.SAS, + requestID!!, + cryptoTestData.roomId, + aliceSession.myUserId, + aliceSession.sessionParams.deviceId!!) + + } // we should reach SHOW SAS on both var alicePovTx: SasVerificationTransaction? diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/VerificationTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTest.kt similarity index 71% rename from matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/VerificationTest.kt rename to matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTest.kt index 35c5a4dab9..ef04372ecf 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/VerificationTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.verification.qrcode +package org.matrix.android.sdk.internal.crypto.verification import androidx.test.ext.junit.runners.AndroidJUnit4 import org.amshove.kluent.shouldBe @@ -23,19 +23,13 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.auth.UIABaseAuth -import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor -import org.matrix.android.sdk.api.auth.UserPasswordAuth -import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.common.TestConstants +import timber.log.Timber import java.util.concurrent.CountDownLatch -import kotlin.coroutines.Continuation -import kotlin.coroutines.resume @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) @@ -147,50 +141,19 @@ class VerificationTest : InstrumentedTest { ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true, otherCanScanQrCode = true) ) - // TODO Add tests without SAS - private fun doTest(aliceSupportedMethods: List, bobSupportedMethods: List, expectedResultForAlice: ExpectedResult, expectedResultForBob: ExpectedResult) { - val testHelper = CommonTestHelper(context()) - val cryptoTestHelper = CryptoTestHelper(testHelper) + val testHelper = CommonTestHelper(context()) + val cryptoTestHelper = CryptoTestHelper(testHelper) val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom() val aliceSession = cryptoTestData.firstSession val bobSession = cryptoTestData.secondSession!! - testHelper.doSync { callback -> - aliceSession.cryptoService().crossSigningService() - .initializeCrossSigning( - object : UserInteractiveAuthInterceptor { - override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { - promise.resume( - UserPasswordAuth( - user = aliceSession.myUserId, - password = TestConstants.PASSWORD, - session = flowResponse.session - ) - ) - } - }, callback) - } - - testHelper.doSync { callback -> - bobSession.cryptoService().crossSigningService() - .initializeCrossSigning( - object : UserInteractiveAuthInterceptor { - override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { - promise.resume( - UserPasswordAuth( - user = bobSession.myUserId, - password = TestConstants.PASSWORD, - session = flowResponse.session - ) - ) - } - }, callback) - } + cryptoTestHelper.initializeCrossSigning(aliceSession) + cryptoTestHelper.initializeCrossSigning(bobSession) val aliceVerificationService = aliceSession.cryptoService().verificationService() val bobVerificationService = bobSession.cryptoService().verificationService() @@ -202,6 +165,7 @@ class VerificationTest : InstrumentedTest { val aliceListener = object : VerificationService.Listener { override fun verificationRequestUpdated(pr: PendingVerificationRequest) { // Step 4: Alice receive the ready request + Timber.v("Alice is ready: ${pr.isReady}") if (pr.isReady) { aliceReadyPendingVerificationRequest = pr latch.countDown() @@ -213,16 +177,19 @@ class VerificationTest : InstrumentedTest { val bobListener = object : VerificationService.Listener { override fun verificationRequestCreated(pr: PendingVerificationRequest) { // Step 2: Bob accepts the verification request - bobVerificationService.readyPendingVerificationInDMs( - bobSupportedMethods, - aliceSession.myUserId, - cryptoTestData.roomId, - pr.transactionId!! - ) + Timber.v("Bob accepts the verification request") + testHelper.runBlockingTest { + bobVerificationService.readyPendingVerification( + bobSupportedMethods, + aliceSession.myUserId, + pr.transactionId!! + ) + } } override fun verificationRequestUpdated(pr: PendingVerificationRequest) { // Step 3: Bob is ready + Timber.v("Bob is ready: ${pr.isReady}") if (pr.isReady) { bobReadyPendingVerificationRequest = pr latch.countDown() @@ -233,7 +200,9 @@ class VerificationTest : InstrumentedTest { val bobUserId = bobSession.myUserId // Step 1: Alice starts a verification request - aliceVerificationService.requestKeyVerificationInDMs(aliceSupportedMethods, bobUserId, cryptoTestData.roomId) + testHelper.runBlockingTest { + aliceVerificationService.requestKeyVerificationInDMs(aliceSupportedMethods, bobUserId, cryptoTestData.roomId) + } testHelper.await(latch) aliceReadyPendingVerificationRequest!!.let { pr -> diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecretTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecretTest.kt deleted file mode 100644 index 9b10f9e9af..0000000000 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecretTest.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.verification.qrcode - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.amshove.kluent.shouldBe -import org.amshove.kluent.shouldNotBeEqualTo -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.matrix.android.sdk.InstrumentedTest - -@RunWith(AndroidJUnit4::class) -@FixMethodOrder(MethodSorters.JVM) -class SharedSecretTest : InstrumentedTest { - - @Test - fun testSharedSecretLengthCase() { - repeat(100) { - generateSharedSecretV2().length shouldBe 11 - } - } - - @Test - fun testSharedDiffCase() { - val sharedSecret1 = generateSharedSecretV2() - val sharedSecret2 = generateSharedSecretV2() - - sharedSecret1 shouldNotBeEqualTo sharedSecret2 - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/IncomingSasVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/IncomingSasVerificationTransaction.kt deleted file mode 100644 index db2ea72e88..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/IncomingSasVerificationTransaction.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.api.session.crypto.verification - -interface IncomingSasVerificationTransaction : SasVerificationTransaction { - val uxState: UxState - - fun performAccept() - - enum class UxState { - UNKNOWN, - SHOW_ACCEPT, - WAIT_FOR_KEY_AGREEMENT, - SHOW_SAS, - WAIT_FOR_VERIFICATION, - VERIFIED, - CANCELLED_BY_ME, - CANCELLED_BY_OTHER - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/OutgoingSasVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/OutgoingSasVerificationTransaction.kt deleted file mode 100644 index 38ee5dc7e7..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/OutgoingSasVerificationTransaction.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.api.session.crypto.verification - -interface OutgoingSasVerificationTransaction : SasVerificationTransaction { - val uxState: UxState - - enum class UxState { - UNKNOWN, - WAIT_FOR_START, - WAIT_FOR_KEY_AGREEMENT, - SHOW_SAS, - WAIT_FOR_VERIFICATION, - VERIFIED, - CANCELLED_BY_ME, - CANCELLED_BY_OTHER - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt index 41ba0b8b4e..8a8f80426b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt @@ -46,54 +46,37 @@ interface VerificationService { fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest? - suspend fun beginKeyVerification(method: VerificationMethod, - otherUserId: String, - otherDeviceId: String, - transactionId: String?): String? - /** - * Request key verification with another user via room events (instead of the to-device API) + * Request key verification with another user via room events (instead of the to-device API). */ suspend fun requestKeyVerificationInDMs(methods: List, - otherUserId: String, - roomId: String, - localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest + otherUserId: String, + roomId: String, + localId: String? = LocalEcho.createLocalEchoId()): PendingVerificationRequest + + /** + * Request a self key verification using to-device API (instead of room events). + */ + suspend fun requestSelfKeyVerification(methods: List): PendingVerificationRequest + + /** + * You should call this method after receiving a verification request. + * Accept the verification request advertising the given methods as supported + * Returns false if the request is unknown or transaction is not ready. + */ + suspend fun readyPendingVerification(methods: List, + otherUserId: String, + transactionId: String): Boolean suspend fun cancelVerificationRequest(request: PendingVerificationRequest) - /** - * Request a key verification from another user using toDevice events. - */ - suspend fun requestKeyVerification(methods: List, - otherUserId: String, - otherDevices: List?): PendingVerificationRequest + suspend fun cancelVerificationRequest(otherUserId: String, transactionId: String) - suspend fun declineVerificationRequestInDMs(otherUserId: String, - transactionId: String, - roomId: String) + suspend fun beginKeyVerification(method: VerificationMethod, + otherUserId: String, + transactionId: String): String? - // Only SAS method is supported for the moment - // TODO Parameter otherDeviceId should be removed in this case - suspend fun beginKeyVerificationInDMs(method: VerificationMethod, - transactionId: String, - roomId: String, - otherUserId: String, - otherDeviceId: String): String - - /** - * Returns false if the request is unknown - */ - suspend fun readyPendingVerificationInDMs(methods: List, - otherUserId: String, - roomId: String, - transactionId: String): Boolean - - /** - * Returns false if the request is unknown - */ - suspend fun readyPendingVerification(methods: List, - otherUserId: String, - transactionId: String): Boolean + suspend fun beginDeviceVerification(otherUserId: String, otherDeviceId: String): String? interface Listener { /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index c33885b925..caef4a23ed 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -775,7 +775,7 @@ internal class DefaultCryptoService @Inject constructor( } } } catch (throwable: Throwable) { - Timber.tag(loggerTag.value).e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") + Timber.tag(loggerTag.value).e(throwable, "## CRYPTO doKeyDownloadForUsers(): error") } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 8ef383f193..780229f038 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -229,17 +229,12 @@ internal class RustVerificationService @Inject constructor(private val olmMachin return null } - override suspend fun requestKeyVerification( - methods: List, - otherUserId: String, - otherDevices: List? - ): PendingVerificationRequest { - val verification = when (val identity = olmMachine.getIdentity(otherUserId)) { + override suspend fun requestSelfKeyVerification(methods: List): PendingVerificationRequest { + val verification = when (val identity = olmMachine.getIdentity(olmMachine.userId())) { is OwnUserIdentity -> identity.requestVerification(methods) is UserIdentity -> throw IllegalArgumentException("This method doesn't support verification of other users devices") null -> throw IllegalArgumentException("Cross signing has not been bootstrapped for our own user") } - return verification.toPendingVerificationRequest() } @@ -249,7 +244,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin roomId: String, localId: String? ): PendingVerificationRequest { - Timber.i("## SAS Requesting verification to user: $otherUserId in room $roomId") + olmMachine.ensureUsersKeys(listOf(otherUserId)) val verification = when (val identity = olmMachine.getIdentity(otherUserId)) { is UserIdentity -> identity.requestVerification(methods, roomId, localId!!) is OwnUserIdentity -> throw IllegalArgumentException("This method doesn't support verification of our own user") @@ -284,78 +279,49 @@ internal class RustVerificationService @Inject constructor(private val olmMachin } } - override suspend fun readyPendingVerificationInDMs( - methods: List, - otherUserId: String, - roomId: String, - transactionId: String - ): Boolean { - return readyPendingVerification(methods, otherUserId, transactionId) - } - override suspend fun beginKeyVerification( method: VerificationMethod, otherUserId: String, - otherDeviceId: String, - transactionId: String? + transactionId: String ): String? { return if (method == VerificationMethod.SAS) { - if (transactionId != null) { - val request = olmMachine.getVerificationRequest(otherUserId, transactionId) + val request = olmMachine.getVerificationRequest(otherUserId, transactionId) - val sas = request?.startSasVerification() + val sas = request?.startSasVerification() - if (sas != null) { - dispatcher.dispatchTxAdded(sas) - sas.transactionId - } else { - null - } + if (sas != null) { + dispatcher.dispatchTxAdded(sas) + sas.transactionId } else { - // This starts the short SAS flow, the one that doesn't start with - // a `m.key.verification.request`, Element web stopped doing this, might - // be wise do do so as well - // DeviceListBottomSheetViewModel triggers this, interestingly the method that - // triggers this is called `manuallyVerify()` - val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId) - val verification = otherDevice?.startVerification() - if (verification != null) { - dispatcher.dispatchTxAdded(verification) - verification.transactionId - } else { - null - } + null } } else { throw IllegalArgumentException("Unknown verification method") } } - override suspend fun beginKeyVerificationInDMs( - method: VerificationMethod, - transactionId: String, - roomId: String, - otherUserId: String, - otherDeviceId: String - ): String { - beginKeyVerification(method, otherUserId, otherDeviceId, transactionId) - // TODO what's the point of returning the same ID we got as an argument? - // We do this because the old verification service did so - return transactionId + override suspend fun beginDeviceVerification(otherUserId: String, otherDeviceId: String): String? { + // This starts the short SAS flow, the one that doesn't start with + // a `m.key.verification.request`, Element web stopped doing this, might + // be wise do do so as well + // DeviceListBottomSheetViewModel triggers this, interestingly the method that + // triggers this is called `manuallyVerify()` + val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId) + val verification = otherDevice?.startVerification() + return if (verification != null) { + dispatcher.dispatchTxAdded(verification) + verification.transactionId + } else { + null + } } override suspend fun cancelVerificationRequest(request: PendingVerificationRequest) { - val verificationRequest = request.transactionId?.let { - olmMachine.getVerificationRequest(request.otherUserId, it) - } - verificationRequest?.cancel() + request.transactionId ?: return + cancelVerificationRequest(request.otherUserId, request.transactionId) } - override suspend fun declineVerificationRequestInDMs( - otherUserId: String, - transactionId: String, - roomId: String - ) { + override suspend fun cancelVerificationRequest(otherUserId: String, transactionId: String) { val verificationRequest = olmMachine.getVerificationRequest(otherUserId, transactionId) verificationRequest?.cancel() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecret.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecret.kt deleted file mode 100644 index 858c0ab6af..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecret.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.verification.qrcode - -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding -import java.security.SecureRandom - -fun generateSharedSecretV2(): String { - val secureRandom = SecureRandom() - - // 8 bytes long - val secretBytes = ByteArray(8) - secureRandom.nextBytes(secretBytes) - return secretBytes.toBase64NoPadding() -} diff --git a/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt b/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt index c82b543a08..c471a59af5 100644 --- a/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt +++ b/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt @@ -51,6 +51,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState +import org.matrix.android.sdk.common.CommonTestHelper import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -134,10 +135,8 @@ class VerifySessionInteractiveTest : VerificationTestBase() { onView(withId(R.id.bottomSheetFragmentContainer)) .check(matches(not(hasDescendant(withText(R.string.verification_cannot_access_other_session))))) - val request = existingSession!!.cryptoService().verificationService().requestKeyVerification( - listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW), - existingSession!!.myUserId, - listOf(uiSession.sessionParams.deviceId!!) + val request = existingSession!!.cryptoService().verificationService().requestSelfKeyVerification( + listOf(VerificationMethod.SAS, VerificationMethod.QR_CODE_SCAN, VerificationMethod.QR_CODE_SHOW) ) val transactionId = request.transactionId!! diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt index 14d4b9c5d9..6b01403fe3 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt @@ -166,9 +166,8 @@ class IncomingVerificationRequestHandler @Inject constructor( } } dismissedAction = LaunchCoroutineRunnable(coroutineScope) { - session?.cryptoService()?.verificationService()?.declineVerificationRequestInDMs(pr.otherUserId, - pr.transactionId ?: "", - pr.roomId ?: "" + session?.cryptoService()?.verificationService()?.cancelVerificationRequest(pr.otherUserId, + pr.transactionId ?: "" ) } colorAttribute = R.attr.vctr_notice_secondary diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 5fc752028f..5a338cfb45 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -238,7 +238,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( handleRequestVerificationByDM(roomId, otherUserId) } is VerificationAction.StartSASVerification -> { - handleStartSASVerification(roomId, otherUserId, action) + handleStartSASVerification(otherUserId, action) } is VerificationAction.RemoteQrCodeScanned -> { handleRemoteQrCodeScanned(action) @@ -284,28 +284,16 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( }.exhaustive } - private fun handleStartSASVerification(roomId: String?, otherUserId: String, action: VerificationAction.StartSASVerification) { + private fun handleStartSASVerification(otherUserId: String, action: VerificationAction.StartSASVerification) { val request = session.cryptoService().verificationService().getExistingVerificationRequest(otherUserId, action.pendingRequestTransactionId) ?: return - val otherDevice = if (request.isIncoming) request.requestInfo?.fromDevice else request.readyInfo?.fromDevice viewModelScope.launch { - if (roomId == null) { session.cryptoService().verificationService().beginKeyVerification( VerificationMethod.SAS, otherUserId = request.otherUserId, - otherDeviceId = otherDevice ?: "", transactionId = action.pendingRequestTransactionId ) - } else { - session.cryptoService().verificationService().beginKeyVerificationInDMs( - VerificationMethod.SAS, - transactionId = action.pendingRequestTransactionId, - roomId = roomId, - otherUserId = request.otherUserId, - otherDeviceId = otherDevice ?: "" - ) } - } } private fun handleSASDoNotMatchAction(action: VerificationAction.SASDoNotMatchAction) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index 1efed66aa5..ea89a1c017 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -995,10 +995,9 @@ class TimelineViewModel @AssistedInject constructor( private fun handleAcceptVerification(action: RoomDetailAction.AcceptVerificationRequest) { Timber.v("## SAS handleAcceptVerification ${action.otherUserId}, roomId:${room.roomId}, txId:${action.transactionId}") viewModelScope.launch { - if (session.cryptoService().verificationService().readyPendingVerificationInDMs( + if (session.cryptoService().verificationService().readyPendingVerification( supportedVerificationMethodsProvider.provide(), action.otherUserId, - room.roomId, action.transactionId)) { _viewEvents.post(RoomDetailViewEvents.ActionSuccess(action)) } else { @@ -1009,10 +1008,9 @@ class TimelineViewModel @AssistedInject constructor( private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) { viewModelScope.launch { - session.cryptoService().verificationService().declineVerificationRequestInDMs( + session.cryptoService().verificationService().cancelVerificationRequest( action.otherUserId, - action.transactionId, - room.roomId) + action.transactionId) } } diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index ee101be732..e4ead15183 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -217,10 +217,8 @@ class DefaultNavigator @Inject constructor( override fun requestSessionVerification(context: Context, otherSessionId: String) { coroutineScope.launch { val session = sessionHolder.getSafeActiveSession() ?: return@launch - val pr = session.cryptoService().verificationService().requestKeyVerification( - supportedVerificationMethodsProvider.provide(), - session.myUserId, - listOf(otherSessionId) + val pr = session.cryptoService().verificationService().requestSelfKeyVerification( + supportedVerificationMethodsProvider.provide() ) if (context is AppCompatActivity) { VerificationBottomSheet.withArgs( @@ -241,10 +239,8 @@ class DefaultNavigator @Inject constructor( .map { it.deviceId } if (context is AppCompatActivity) { if (otherSessions.isNotEmpty()) { - val pr = session.cryptoService().verificationService().requestKeyVerification( - supportedVerificationMethodsProvider.provide(), - session.myUserId, - otherSessions) + val pr = session.cryptoService().verificationService().requestSelfKeyVerification( + supportedVerificationMethodsProvider.provide()) VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId) .show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) } else { diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt index f7370ec439..adb0fe958f 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt @@ -126,11 +126,10 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) { if (!initialState.allowDeviceAction) return viewModelScope.launch { - session.cryptoService().verificationService().beginKeyVerification( - method = VerificationMethod.SAS, + session.cryptoService().verificationService().beginDeviceVerification( otherUserId = initialState.userId, otherDeviceId = action.deviceId, - transactionId = null)?.let { txID -> + )?.let { txID -> _viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID)) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index 871109210a..768a52cfb2 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -250,7 +250,7 @@ class DevicesViewModel @AssistedInject constructor( viewModelScope.launch { val txID = session.cryptoService() .verificationService() - .beginKeyVerification(VerificationMethod.SAS, session.myUserId, action.deviceId, null) + .beginDeviceVerification(session.myUserId, action.deviceId) _viewEvents.post(DevicesViewEvents.ShowVerifyDevice( session.myUserId, txID From 859d47453cef688ca449c61542a95b948b294a7c Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 5 May 2022 11:45:38 +0200 Subject: [PATCH 225/252] Add local lib in case maven is broken --- matrix-sdk-android/build.gradle | 3 +++ .../libs/crypto-android-release.aar | Bin 0 -> 18161404 bytes 2 files changed, 3 insertions(+) create mode 100644 matrix-sdk-android/libs/crypto-android-release.aar diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index b1b7986bf5..1334b83191 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -110,6 +110,9 @@ dependencies { implementation libs.jetbrains.coroutinesAndroid implementation 'org.matrix.rustcomponents:crypto-android:0.1.1-SNAPSHOT' + //implementation files('libs/crypto-android-release.aar') + +// implementation(name: 'crypto-android-release', ext: 'aar') implementation 'net.java.dev.jna:jna:5.10.0@aar' implementation libs.androidx.appCompat diff --git a/matrix-sdk-android/libs/crypto-android-release.aar b/matrix-sdk-android/libs/crypto-android-release.aar new file mode 100644 index 0000000000000000000000000000000000000000..d2e9c800a944baa906ef5a8033de3e479fcb0454 GIT binary patch literal 18161404 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

8w8 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

c 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

V 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 E~3BO&9-L8ODnOiqrTt8Op+w##b|M_^C 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 B?B0>XmZewOo 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 z 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

b(-8jf0+$I=fs9i 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
    c6ma%sODRXFk; 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
    E2^3lIWZEz^fysK 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 AT&_; zG@wJEd`XKf3($2c6|@Mr)=+Sj1(E~xkw&561r1t@h58DVp9bQX@k zqJV}I)Q$z^0j&rS4@PJcq0pd}0u2NPsuW5CtqiCx^Lj)DM`Yj}S1dxkDYzn%fhs^C z9uN&mUa0bmPYeIw+rRq1bf^7~KmYMQ2A&kWga7`;+r!<%FVuyx(tx4%_d$3^I)O(J z7yQ`)@AIOAFTTg)AZTJZWg#dx9)^sJIUr_6CIt2UAVK%D^zdgmeBrZJT(+S0Fsy*o z*wFdq=aki9=+Bkl#3FNjwwwK6FfG{R$Xq##;0b};{?BUui#>G*{&Ry>1l#L zI65L7E|vW$Y8sovxxY<>(Q%8mOBvIw1mDtL9==@PRS~flRvQ=<*qTf+t;B zt}x}LbH#ebgy4FHEl=Kdw#NC+tRr~s!>7WsCa>=toY_q9jC)J!+Ryr)$er0i@VE=E z`(*seUe(UH6a42(CpLS}((_$2egt3owfW77iFe;eXF>^H!<;KAx_IpxeReOwk6P~a zBRRPyESZfXxQ*IPP3O7#dxo=#1h-vUdpz-=RmQg2G=ewmmk*K&|NS;}Hk;tdH3Kzg z8{QTq&*l?6ZC~i24yWRY;@L8ScbqOtJ`rSc{q}4n!F~BSZcL0(kG!3&CwP^*x`*wO z@`t}?Zxg)iK-8m_cZR2U=h_HP)>Blt&AFprWv-LpPg6s@PszxXSj_bhoc%r&`|Vo7 zjN4p4!9NRgrMgoG>i5qL6TIz^bs(*+KJnDtIKh=Xgx=W;R6o8tH$C@{T5goxKKG9X zhVw$_;NTqV0&^|9^Eu)oy0GMC94&1kVufL}I5fXRaNtZvQNpMrCEPhUZ2Va&+oAN=~$4k`w09} z7WN~!W%y{;sq_BljN$p2`UidYRYpb7zU_eb5? zt&L>V_ig-{(MTu3b=4$J_FT(-cN*y-c*fQDJ8T}mD5^sG39fHanEzt$>8VG^@O)XC z}P_`#0CJ&tQlm`70=f-Ao+Lyh_+Z(Kl?2%bD=;;5SK zmDGf45`0xnVs?(evd)*NKEaDc-dCo+5<2q(H6i$m@VB)AH!?nRVCx9}Kf7mm1$&2t z{ij=o;^HkppCPBt(AQ^Zsml}j|F`z&{~DAe-gtwyoiJeg_xFT9NAVw1|L;twK{VUd z9Kg-Wb%(6l4%vTo5abdZ8uE|Zh^Cr~%71mFWvc9s#JHXS*#Y)XoP0izP zZi;`oPx-q!kVsfgdIh`q5gP>Joo2f|=DXScFdbT$`yam86@tr@Fjxu*3{WNr z?sdTxZU-6S@8ah-Z?;AZ<}OU3`zKd~wdCKs`ojPcx3gc^4H93^VSf9_d6ON&xQ(&6 zfCkY|Mil3QE23)>A4(yN^qqh^-FXWjKW}1-N@5}cApqy?8cK|1S`N+(<%OvJ!wd)& z7309*;J|RAQ)m8geOTy%8S?+Q!&>*Bjf99EQanlX-ACRbprr75@*$E21_u9Hrp|JH z9-g5LMle2-CGSjUFmMjeJ1f!WPvXbmtIJ?S(Us^*c(jKq1o=xzFSsOpg$3bf7Hvt0QGf-z>iO#nQGm9~J zU!8gfEGVeQys0{25BSGQF!SxiLM8jNMf*Qo{KX>-``&L3k(VQ`yu{$!|^}e&9|$ls5lU%zM#UO zHC@nRVqfGC{K$E}k<&LIW){dTPT+7MMyVK!`zPx$ya|h9?|=~ec|xA>`R}GFfGu4tMo^-a)S#8+1okHc{ zlvN!W4G7dWFf=wzId0<>)_U*JU{KvNE3uvyzx|B<5SzZ#k$oEqVtpvxdriK%xukp>(ni)r`tY4rLKXw_#gp z%veEDIzMe4#ymnU&1V(B)bp_DmrE(EBoecLGx`SwW+;%s)ngd55fwo>*dQ{D8%H4| z3I(B3X$YOfg0N$pFc-p2;^E?j`49m_h)t9vMwNkmFkj>{T90%fkC9H+F4{As8+i%$ zlKPO3*dQ{(7{ewIpr|mbtlmni4asNDoQ*nqBIDeZ+V~1Gg{Eb&((e1C#~81mmbTrN z10|O(H!SbvPB@%&<_}H8713&gyT^{IY7tQimCnK|ptVA`sQCE{ns&#S{T?Qo@YcJuJ`4T;!y;7ESSWRXtD$E!$RGmWEQ85la#T$gtJTrkG=4f&P|tJ)>PDrh@slJ` z5fW^qgRLd0Vsr|PV#JWeSZP|QE=ibzu~Mupw3o3hqo`2n(Mva3$x#*fg_nx*3ec=T z1SV`k6gt_QDoYDvFC6I0DN`0YnT>DF5p${yn?*Fmj4p<*vCu}@sdVxR3O!m&h*=GDXt2ee_6%cT-afL04PU5>;PQ@-6}Ew+NfWrXX%$q8!QGX>hYkI~DNQ7()cop>1Y zC9$D23TLYG8d|76^Cvxo8pLPD%;II;LK9*pM6W>)8guZ)SxYec6q#Mhs4#{^8%c2K zlHj;r<}dkm7#%}mxlGm>FmLITVa%2!qKQPaD`D=ec68P# zhO%y@fLg@Cis^vN$Wf)NqBpbhp(K<-6GK@@WICNp1+6Oc!4i5L`QNt23+RNK?Ec-| z3V&B{_4b;7H2v4xRY0IC@z(G+@0|F{4*puJ`8RKI^HbzjGQdq^+cUk?XEx&_hI)Bq z`4U5}2@eku&r17r${m^ft@rO*?!K||+=0GJwH7~>*~aQ49c%*IkGws#ZKx+Cl2b|P z`FI-XW|d;@^W)xwYmb~3p+x>R+m)}?YE>2Y?u}o}JM)v(na9?f?0NTo$!UJ7w1~(| z@PUYOpG5zpUkvtvA7g5>8_s6zI5w{}u2W?)kT|TFI(O<0Fw`5tM z!LH7Pofij;65WI2$?4F8#AEl0ZwX3lygb9c)4aB6W^_!i^V=KGB_a*nh<|A2Z2ImC zaa-0p|5B@33m-bZa=%_@`vql3o#hSZ&#d~iyxqa_uyM!ru=tp=b>vM~`f~TQryq_! zK}&o5d31G%gs_E>@zm$M36|e?K78ioEO0)3mV46k{!gp$@ZP1uosV>4)|{+?W-6s@ z(=*E%hhy9-5*(N~P0YWtExEt?QxLi7 z{wwz_@d^(!?e6dhV59WW$*C--dr++Eh}D@5y6>yHayMtL$9XVqzKp>->Iu z^@QyvC&VOsr+h}P?pb%{(#+0az8ZJ==e49y&RZAzog0=V$tTEM4=nXnBfH*wlx){K z5!qSw^g>2_eM0Tm+gJSr!!r-(n zxZ4k$&y~AYOZmz%z`Ac{HshvKTWhduvBeh~@x^}iJsfpB*@J^iDrj223_42AmJMxA zbU9uTE|!RfvBjp}6_D{6z5XMoYe}HVlSl9O{1&@t;wu+IS{r`HC)Txn__W3_ef4jz z_f}oIO=YIw!CQuf4^RABl`VCo)9yJ2t}@LmE{X6x%tMb| z?8mq1vTO0pY?DrY(8A@bHT*yeG9IS>~es;Lf@1WDcXNj~mlZz0mU0KAtCW>pG3fDXly;mu#};;I$)# z8gi`k&eGq%=dSXd`tZ(gqoGDJ>pgzGg>i%Tsa^+O6dGKzoH{$6DQi-Z9lq*q2iL<> zVv~2(52&ZVj_u;=UTtS&v}s!O!05_-M}n95dVX3iXYQ%j?^v27da+}K1bM91cxhyr zqh)u+?Rkt3#b{+`W6Dk|sdr%;Rwf)jhYc2(gl|LMm29(l&sMDUfOPH=AK$LUaSC*0 z!hMtN+t`jXyTnhu;EuZ$pEgU6v>&YMJ>of+EN~&XXhq}tlL4;pGnI|zLLAzYxm%Sb z4d_!z2Sg7Y*g45O#gbF6>G@%A@L6e}v&f1(rq%7wH|HcotrE&i)~rsr$8f#od1X%a zyi{>FpAhfRR8g%fbaw9R+Qo5^;z|SOX2bA6slA-1t_rl@ek!?Mr;@|=f#T`S2Xb@Z zpXNT!W_dOW`=@%-HpC$}Px%{9KQIY>sj@<7kK2;f>P=LesaadDlr_u4y$+^p&ekdi&QhaLZ!vlG}dOHptAlqi;j(pn@ z*!1?^bIYp*;^v>4%u7_qkCtzlP7-r|wDhIS*OzH}Ul+%j?5Wkys0Md-e~Fg4CLr+O zT)=&I*0qVdH}5>>f9`e9z6Z3KeH{*}X~hT&jfHQs!|b}f4y%{z{eIe4FtGI4=E*ac z{e>;zJ5jf@IL`)^57o4Y(DJfZRb?%2>TF3AmGPQzU3(9G;s!TQm`ryc-)(eSti!?B z?M-i_*21_}zwr<5X}+zQw-xvFt-hZ2E$74)fvD|)E4OVQ_PhT*`=oJp$B5D?QlWaV zEVV%`uE8cYRv}`p#k#>t-EvreU|7ywX1U#siF~ccj+c1MIMPlvYW1auizLJy{CO%< zfakhlK-|_S+jnvUOGBIXzuxk(J{dD~YurX=xlmtOY~vfY zhw_DE%Kz)#_3fYg(&SpWw^|H7ZRr1*J?6aZ*p3%*?w)ZHKb1cBwmIa-!;s z<90`5e6>z!xb3TV-}URv)1vs3>L`*u=WywB!}@FSRGXsdnOG$Dz>gQ6%6YCu_r0D( z&B!#ny$yckT%T`H{Dv9pFaB%mnFni(BR;bov*CBir+x?>JJ|SQlbz?rpuz2t506Tu z`pK%Kc>R2IvT;2@mlxkmx^Qc}C2s_C90f z4~0Xn@h6h9M`D7bD)(W>g>h#xY1|%~3vjvt@j-m9YKa1B%NIqQGan@1MBPgydA+%G%%Nt@eui3pg?i$j&3L1YgEKlnQ zzbinWx{zYO3EIWEbG+@A?e(0t$d1YpPorbJF}rS@>N@dGqAXg?*2w(%y00y&&;y-U zvI6J!`dDvc&%Icq*EBy=)S?%^hY7?P# zF(034s3r00-h?kp=xc5Ad7qbPSYL7K(AS$;vJaX+nDh)(7xHm9|H!!BG~uYrSt|eL z0@o| z1CQ@u7nI`pw*9(o{=tCf;AqU0)W=sL>oc={ER37ie(rtp$a&?>tBW%`|yhd`(G4BD6Ns(q(`uC0v76Imq z$>4Jg&km))UIxPG7VOsI`;fNj(+K_QCl^7q^h~dvCulCx6cMaVBS< zyi+>*zQwx6d&VC6=A>R#;i|U0*kW_KLckoaF=OuWKK0YQ@#A*l4d1 z{I-3z=8O1j+Ug5(hdf3qtxn!rDO+4%uqUlu}ziGkl;o2DT`oz`4(_VYOuF^47ntoTdx-)`NR@d}JOFp*n zbPn6PlDM^LYrE8oSRN9J1p8+1Ws^vO;CJv zKV6oq8eRIX?x>b6{nuga@W87p=S$09eo~41)D~K1su*~0gPHH8*3_I-Zs^`o7QF{` z?*+&&_f(r`3mDY}w9^_&dU6s{whr)-#5jHE#%)!fif?V6+>)#;&21TDR(#goWApc+ z3FWK5OEY?;GEb~owCng~SARlrf5cX;QK6RIpQes(tFqO9W%YRr>YE$RJ1}|atF$jm zs?>)sw+|jl-+Jcy%P+&GNm`{&L#J)RW_}@+hj=SL3nC9*aYYwBnZAbhl?df6J$tKR z)3bA%D0|PFoa%D27&BYu|8ebw6LHEP?jJb#O4*LpC_gALX~B+U({*1C>xb(eTv;kn zNV$0OQDLDOPd>!huNo23D%0i|(<;ZB=m~Wu>Di@BDj)cHZc>9ol?fdVzVE9U`CGj5 z!S%T(y17P*8|veuyQ`Px%@*BAuxRD{`A%!R{DVe~%-MV02j+5;`YI* zbGKHNrg(LIYrbx1d@A_e{s4lfs=|_s%9f?BQ^JKpLv4YGB;ES(h*bZRXKg zxklPc=F3jKDN>}0%GZa>D}Po21RD>bAhG5sUP zenpL2jHT-Obv^U%;SDLb%mW=2zqM4z6S zx0fwToNSJyNmI5SW51}gZNGW;7VW{Z$YJx#LRW^|l%#;;*)#H&g;b*Ge zKe1?+GiNX2{@_fK$eou@MzoZVmKmx_8SFO;eiwc`p(JkNVmC*fPn+0t_U)f)(>`sg zYl|PMymgj)%~0lrp%oWoKOHENalN{xJ5$<_-ThEfMgQ3+7j<)m*bWRQ9bU=zdt~H% zY?%zEwzI=VNHJ+!b;+m1{BC8EzHxJr)1n>F`bhEv?(tM@t{W?zYz2~-k68K}k3O$^ z_bh90YnJM->pNNU)+2TOE^OJ4B2TroXI~g}l`hyF z$s5fkp+#l`8BSSo5wDVOEPK=tjBUz%v-eli1-mC9qedqF$p<}GW?an5l-=!ClwM?+ zAISrKe7*JN{tBDD+;y8A*z5(HoNX`fdXuwLqG1Q_7$Bm+w1um)cY9DmTE{1*`ZTZOFDK)3$B^~Kk+Dni zR_bLf|MBa|eYMrOJofzoG`0mhu4$V?f&n@AkDBlAJzo7d^vr%u+Ya}0j^QtJ>~}9A zbGMv{RzPPhwbD1<8F_jsA>$WG>PKwD>sZ}QdSNCHc^k7s+yunB)D={L??5ep;{_JNTo%K(ucB z&;^(Ds(qH?!yh#K9=#t@SEM+Ir6!G}o_KV2wX2H8oUTP>zLrKwcujLc=j8R-M%wni z^|u?-(mzxdACBDFsIu-wS-I}7y<#a`^q*^C?Hmq{=R0W2dt@rp6ThFi85d{6!(O@8 zm`A0rHn5!h?ShBgg9SUaPE!?=>IB2zvn4VQSmr)ow&-5LcfmXPS7X#;(RM39+&2)dT%!z zI~l+o`)R2f+bGiS-TmOkq{*@YK|CL)e z|CP&(|Ai99#ee!R>Kp&U<$Oo}!ha*_e~GPnb?u)yZuj?RuJAGL_@84NXMDK!C!VWb z?DYOm9J_H(B20=q8~1abYuw$z<)@p$!jm;0+X4MWJ4%9co?Xj$WnL$It6_}b zo$=!1huE%JpW2;4h{lAMNBy()yL>}l!iX@}_JzRAk^$kQ4MLxBPA%d_RP%T= z73Tx@^R`_ip(NRs(rP@mGX|Dlh3>9yDX-2L0Q?c@VYYwZg54(I=cJ*S{-fXfg=20w zTm`WmQDUBZ9iVn5&sBAKFUZ?PZ3au1=^Nxij)7z%1ZlQOjW0EQmcE*ubWHv-1g$!t zSP_)5E~;~*+1U4&kP(;D?$@mP91mr_EAD=N2x|42@}?iUU;~YeR-Irkh4z^4!Pq_} zE!v4PpFhhqP00^lHMZ-sr`!31)@$MqD84LMv(eA0z(}99Q09e~Q&mdJDG$oK4(qiY zkNi7U{d!+HK6lpSOEh1gdb#Grnm0IY1Pk%&W_u*xpftE%vnf8+?rbAdv}-b4gDi2 z%?Ctf`M>WOHC6;>}c4@;nqj1ldOgs1kN{#ei_+huxJPS zdhLi?QAy#t3DGGTCsW5XpV82j#rFr3wfa|#R6Ps3ZlcJYWHa;bs)<8uvHQBGANi{? zb`{mXa<NUS*b!f+w&(WaC1t&A^pdqo$q9CAsi`}5n@aTdbGSFjH^D@=-dsWw8C@ zuX%M6axV9a9Zc#@_9R_04LG8(H2AkZZy4XFh7%gX-8AJNi+0R**-k-Am+Eg-={wgE z-rQT|7aPu6u6i_Z x$w&R)oYuwX0vZwr6h7Gl|u4TSWDsyZ&ysANF%}0(q(EI%- zuWYGO8a_V!#lFwxXVYm%gSTJaYkO6B$*cN}pR$+S9)C1+BnEoY8`+SstLf6vSFcN4 zCFhystTC-W~5MaWz5DBzRt5-$IR9? zWPEyj^WnRJPT_l$pfbTTerGhKPc>cSI9UD~Yw_)Phnmj$-cUPbQy|J0Uu_oqDvp27 zY;^B|!49`9FAqU??hgS@iF}tfe2w1UN8?MmuTNc@$D) zaj`m0*)yBoC9-D@;EMmnR=k`PJdjwdSSgD0-J)^exNL7pG8j}y0#-V*c}_jb7DNeju&5YWTmh;wWw?+1QmYUp|gZsCA*>~&n)X>FMNtBSdMxJDQUeT)`_P7f@ zsc21Ja_RY%fUS%32+hL%zIb(en& z<5yNqoqRgDVXilN~qz}&_sxH6K9?@HueD6G(sWBBS zIYQmOFi*nNKz7TS%@>cHax*MQVCZM9jgR>GZgZK|0sW5TVz~!RuM7DrMSQlzon>kM z{`A|-Sl33;ymKc09;-iYjksNXCS%Ffiu?gf_p`h%K^fOP%<4xZ-msl@Fi6-M$vQ1H zx8?JvLfgmWYpli3A0)gEo8v$6?NFDo%-2HN;=Byi&qr+hzi_cetH>zGjXoWiyx?Ed zx|2VdGsjLiGAuv2KEcF$9~|)8)@0bZJN4Mrvf}jSp6GkpKDM$ej{OSi72u5;w|Q50 z&^5hgbxoF8V$yJ1M5urIiMrZ?&7Q05FJF;`PCjnkqvPZKXz0d9l~-rfo2E%or^t)* zKv0Q^hWEn~CflBrjJ#IWFKu4B`=aQeY}eO#Tc0jHmS>^mPoGP_+jYb)G|bh5boZcz zRh*Zda>7r)$J}*|Ejop-Ts+{i3AxI<2fMukCdiLB)i%Q2TFd&fuP#MQx97)%XbQNP zAx*<^&gI7Z!Rybbzz)B=kullDc_-tmDt{eAht=CNmbDrq@^ia3<%R9Sy!NkJ$!PG- zi#!|uG;XNH72!aNttprd=1 z?FnvvRy4G={HsXgj&&+qn*=w6vhuhGiH@B667n`OaO{mM*TGqrp0 z`beKjyEfUf@OrA2K)2$`bpKPeH}52fat&%@uiL7QO}6Ipo_f_;K|g*@if)venJw13 z^#He}4nF>A9i*v5dtQ z=3L+6=eBK<{pl!+m^{1mH!nU&JNSe|fpsM_gU)t_&8P{3||k=Vrb@%P5$ zezEo>&zw?c?j>5^Bie^zFFj!jIUD=#RqVd0CScqzvyGA`F~J?b{pY$X)7hKEE~#1E zldU@G^=(=2o5guU73cTCqehwh7mf^)sVb{-tl~$U)8!N%P%rPxoR>TVZan*5aQu|~Xi;yT|NSz<*8y$ioIh`TS9oeqr_Bf? zr5%~;N&7xp{(~~QZte8z7ui)3bc2cXq~Gp*oR=FcITq$AebsIh?iBXV;jumT*y*j! zr!RN>B@er_#wpoOygTh1np%0fzw(Fvj7GRm)vK6zuIjv7Vp7Wz>kaux`Ki)_UHz8J zE_^b)T*{#wTcF2ZK}u#fD*TqP{(=02bjtnhVt21_b8Z|RVyq1PsifI(r9a{=|K=sW zGR5nUFV2ff+WhNQ)!|3NjOIt@OM^2mRmfipktvJI8~lDd(T+p^rFiJM6y@%Ld%Fau z1TqeL97;Xpv1f0A>i%PIe&4$W?>`=3skZ%VHw7>5BUaN5U$l^S#gUYMRy~7lhPha`z<@19lCS+Qk z-Bn&M+t_IwzVj{fTyj+9@!Ibeu{`0sjCZRVJ_yN@)G7`VmFezedulVqKFbN0#6C@w z{zASm=*H`C?@Wo2r3R*>HE!PiZtvF0sFtorJu68qt1Dhci}VEM2~W^TX-VX^nBAVge|`fC+d5x&~vMY?+e6JR|TBp zd48}LB{g=%)aMjhKDKBOv?_dV60f}WoZ`WaIi}geXCxo9Kl?cG+EnlRrkK*c6X-SL zdjlzT_XX(XA6@xh)~t3tp(hdMW3V{StW!6F?!|qF^<4sNy3fTY<&MlzPp0CO?8~85 z89l$_Dt~@aW;*};U9r*qNu7;OL0^dXirk5i2*)e?-E1}AQ;rSxNxMgxv%GS0toMO? zEXrM9Dj8%6w;%r%=6eUW+0iq_8PR5xw`zB-yqieh)$50I=noFGVnfA?^V&=vHk_R_ zb=$n`>-|~|d5!LLql;@I1@;yrI*7MyLq=F?g@ zIs094&5L8!HoYDGpKP+1b*Ynm*s!mmqiyJ8W_HBM8qqEtrqaT^y=J?H4{r1|y%D^b zn6<;FkShAJyLj3%(xDMgaDJ;k-G;n_LRX>ja2)czpkOen{`12cS@=HJ~s$`g^ zkdm_%NiEk3(sZ_ITJLOkET3t|R?uXZ-)*!7`pt9=m}I!EoH24^BCw}6MbekaelrLX z?ThRc?@P*(mP|`gy_u$}>5>ka+)Q6%)|U?Lgfmw7NM;xXtjd^3kj#9R2xpC5UX>+X zk(V`nCHgc}zbYH*bjdDwmX`y)U3D(yo#chyk1mDKNME7a*S=y1lDg7c@b1crYUJv< zcH^skpKo1-CXh<;NvTQ*T3xx8#|?bbDpv`Ug;ilXjKL%USOSJHR(28vhG9Ec0bltB zBbJdt!3kd220ltHfR`dLSzeYM##gJvm(UQwFfkUA4oqS9gsB)6L+L02bE>g<2ujj` zcak8&!y`mtAqm1{E(JO(N+GX+Q2!im#AUYI7@nd314h(@wtO!UEzCh0W zbvz~nBLN0Nq<}PWky%if2GTWum4xEQ2nusxd>HVz7%qN=2p6OT9J9fkAn_;)f=2N4 z|6xjx!r-3_%V8jT6c&Iv@g+B4;1x#kh(#CA)A8`;uaFTKV?)^30Fy_Eb1=R*4vC)( zj<``lkUAKlP=WAZDmTKWi?2+x43Cur3xZ!B5Hh|h4$O`*U_&Y_gK?2LVVTw1z!!jskiPcIJVF(BWFAxlo2VcoQ7zexp{H|WY$!Uj>Q3&CJg-L5s778y5A1f~_o-Tw{ z6X9V8CA)gw(q95*#b^TJ2no0K*Am4H5nc^g0AWGZHDL~zx=aDV=t?jPyEZ>cmqBP0 zMFf?{S0e>-B{j*ivp^uzOTm}AFxy80Sx%H4imyt7kTEtAI0}V8Vetc8;sH=Nz!a$=rWj<1LowU zlVEKcJGTI8iYH1CMK}?Rg^b_}vEZ>P!tCTIJ_w(V06~ZkF&%*wWQeq&?S7IFw-KTx z#~Mn46J$WmVcCijz7bTK6&41iiohHQyHu3va!3qSS7or_w)o3VVh5e6=0evP%K!9Sf)mRE0tT5TmphpGGu+$ww`0yHy4600^1W)l)v#)VO(LA5c$S9b!1 z150zmQurc7s|bw(X`xeA2w?wOd+@qJqGTK66EJvDabvum)@UIVA+nSq-ZS+5JsdPBIW}?(EMxwItD|w@EQ<2Of(~`AVm~-6{tg0fTDN<2=YRKAw&ok0xjWR zzf?$~j{F66aQeD7c~n$=%U2!J7aOvk2ZQf`7b8h4C7W&DQ{Q;r!wU zXLvd>!T}xT0=0((b3s6>$in#AeUvu{#Qu+=4-|r8F$Q#;yJn(yM0 z>&ATgHf#u#w9cu|vxYicHhMhH+X%gs+ywRZ*{Joo*j{>+wm?A; z1yWvY_03t-_&8w?3ebE|O46{n$aWT88Vwf2h*p`Ti0V@n1Yw3Yu2@tI$d!(W!MeD2 zP!(t}9T5hlfHz)fIh{JloFDvjV2ZGne8y298 z6oiEc6(JOdgy38hS%Lf`7BScyFCY}ZuWSVEF)P&-MrbT#OGJby1Z{S_2_mt;GBnte zXzLI}2*FTJj13%;LBRsKqhg3S_yZb-FaE>=R2PI7hDgD?L9<5#HdNCSgwosM~EUVMiAUA38BYeX9h&}Mt}~{ z8HhCk5sN_!f!oAMM3|cmUP={WQ9;%4wYm^lcr_WXT&y5ps_-(HSf35#TLCEZ2vKn$ z7~v&UsxY|SvQtn}GZoK>04`DTyduNMXBc093)FGMmWrS8feFvB2Z}!g zfclR70Of%*PHl>8iwp46RiP|pgA5DzIZlCj{?Dl z*hc(V1rdPohXxXricrL{G!)XtG^j8;%uj+jpg-y<&{)_2gDCzK$eB3?LC$0d@}x0f zBhFsfn}DPXv;25q0*-6J-YU ziS|C}6Kn656gTS26CZomCw_NOQexMziv;wwPhxCJQgU)CSW=B1fiE+NLiBig3mu~G zrekD3@VlFikOSC4=v0aqeJ6#&<4<=6=gfE^x)~kfh0swt88rV8oyl?m997ZnfPXR_ z=na`nZ&`+rAbl%-NE~PaEJR~RA?yfUoCJ=Nfo5ZQy{V$9g;XhSHOZO@#0Ln zK0Sp_;hiGV579m8o~#g$10523kEfOo3WSLC!4yaU;`I}PG>AB9Ogf~8EBZQRP;zYe z84@?_4(_EO*(_o}EUNg?I+w`6uuyy!v=ewD_X=>DKS4aBLm+S(E1w|vU>w|hpsBX=}5vX>)M#@M(()OA9cFJ(p2VQ3?Exwc!4r(+P{9dTpKv^n4uz zVQH+;AULK1guD>Q1fU?mOn_=J0C@r01C#+61W*&;A%JNBa{+b&tO3{$@Dad4 zfP(<_PXRgjfcO9k0$c}B4d4!d<^cTwIs@DbFalsAz!ZQf0E+;Q0c-*YWdS(=zfgAub0PX}B0gwqW7honpC>!J-KM$}K;30s$xceNCPCo=v z11Jcv2%s9k34rDRgU*0-0vrSw0nqs@2p`C~24D*AFBha2pgq7QfS~}N11twP22e8( zq}Lym8$brYUVugbndg9i5Y99}XPlo0;R9652k8aa1h58N&%OW<@Y?`;0XHcC;jN%R z69Cl!1{DIigX@O?+5^6~2*@AsT!2jcdND{Jz)paV0G5}4{01OUE5Hf-dMU^^;GqB+ zx)eyX41^1~5kPZ*&H$YO#sQ1~cnDw$?jK+gz(Igb0I3&2z5%KM90RBckQxZ|3?Ktw zC_o*6nEP2Y|nAVQ13r+NJHaO}lHG zwzsaxzJf#8p$N*tibD|uha$)biZfwBSWMWNY>SEQSjO3c*kXI<;?H;9SF8$Mto(FU$aCzfRbiT)JNMVXFqwBACuPyo$KRPhYSaNr|)C#Sl@+Tr2eMWp`G)OUmbebc*5#1!nWAzP-gcN zSBGUDK7MsbzSwy`X?5u4Li6g7XIQ;Dl(_eV)uG00e07MwE8E=&bD~!MNxG=iKeLT2TK5RY7KCE(t z<4N~3x6S?ByWRcKeLGf%#LM(=r~EjzYjw!6Bjr9$p1e9tv+ES~aA~iffnKh!Pq81D zpSn6^Svpny?0DMhP-MBoK5T!+>d=VhJyXB-+wWPcLl+azksl{I^+Er;pJyK~pSC&_ zjQ737{Y<~oey_0ZYvjkigR8>;kG@?!9DeWWP-oMJt^Z2>|G0eE`5F1Me`s}>L)nSO;_c?#A{6jq)d;AHZ{Z-Cs z!wDhBsniK!oZZhkAym2a@)JV*)$V`e389OJK5#*YPXCUmi9d`-wR zcEy@7&HnP5u*{B|)`Zj>tasO%(8Ki7no!{MqiaHiLr+{AVsCWriM1ia>0N8X07sv` zHk4T0w>H!{b;jC|Jm@^%wl-wh-?ui5F#hSaVUC3_uMOc%&VOueNOSJ{YeOH$uUZ?5 z9QfVZP~-F+YeVAA$Aysx*M@H99$g!Tm^uE$P-bG&iJ`&elTQroZ?Vp^P7FDYzx2c~ z&VkpT7^>`k_lY6iuqA|E`MUc^%n~O!$60o{ zK6u``P>c3qgH^`+qwlxs<{&eyG0V|!t_uT9ov&{9r@yr>jELu1ipDRrpYeHC#GMzZ zlT$1kZ=2AcGu6oyn=f(Q_%yr3M;U*w=i*Z5BtBGB4_m&cpX}i@r8ox|*6fjyky081R<42xWd*0bN#kMx~gS30jlUdKOnKVv`DUlykIldV@dHi`na{rK&1cIE=5zW+ z^O>nQhYvW%o6TqT7Uw7L{R`?6*KhT_vv9j}=e|F9J@V)s`qF3rMd!=byY-ued-Q?1 zd-atoe^d_#kEn<352)vZ_WzT5IP_=vvGp(VV`)i#Z2PPHSpJ*+qCWp!o*(l5{BM0@ z>x%PZ`hU^u&g&zr_d3(pW7d0pd0viP@Ac#L^@R0dh<&m3q0G@It`Ezs9lt&#`sLre zK6G(%)q2mnpEhjE7Z`Y^{8E^~IR`Dc3G)>)VJ4dyew(R_y1^`Xl6*7YIw5q&yo zeMoaSwLbKHB>G%kABtQ##XN?mtoK}bF51oGfv1_r%G1r`{4>{w8oQspKEwx{|8wM_ z4?WM7uekFx`*ZpE=Ckm^^`XM?7p)Hsww=B{w13R|(5u#m9`1X!K5+2u`oN_RniqMd zc^_Bb$JU1&i=R{vt7pkG^2_%Bgua}s{sBKfe$D>krBV6vz_;wrLl>FPh3~4zy#DXG z@380Vvh^Xu*rfHj@ACDbz`h^qFKZ=vu;mKp_DS=uv_AW$)W?}0Tc2G&wLZswroW%^ zzJIlS7=CVDE?i?>*2~sq?N`=i$L#u$`n1o5U#|~YCV#6B9GP1mra5<==Z5L))tA?Y zdHb{VM*DO4Cj0Z?&Gu(%!Tz6d|E>0C~>U9~@pf3QDOciKOiw`l*ftaG>h*;}(e zyYF2eN?iD(bLPGy`t@1+->+ZX`zQV7Qr&rQ;6dlh`d>UZgX(|Cxv}eS&X<+t^!Z3tQJd*X(WbM9Ttb3Y3_z#-SWp0pv9IKFB_sIv70>kN5L zs#!@26N_5Y~2t>ICPSI zjn|oDb8r zTiC@8_AtZLmz>*Eou7D=BP_DWd1hT7Z{HBg(KxFtF>ieERCS4~jD6DQHj7`1-Ul~$ zUr=XSzuCcVW?6OpC>zW_OMb(i-)HN)>vd+tQ_rz}v>toJ`A+q-{ki(fIxEba<~+L53w#zyxjSSJ6Va=XPrX~pFSo`GX52>=l$vz_pzO$OdFqkg}OQZ zN_iQdWe*oQz;L>JTpxRt^Aazy6y5h~{TFwgA+KmXR@wO)x<30l^+)S4p7$JO<#Uer zr8npU46Cg)~6^Je`J?_(bia=>`8M;_v#x2j(}^)`KHve$FL=6CAIDA$g#cixbKDh)@%)Hq*e9-WNIX13af#zx;55@;^}I08 zWlpg4wdm&@bq_iRCRt#bGpxEE|GK&dqklJ0Hzzs7_HW2@)bqh&bp1T_Fw0~#&T2HT zpwAp(m+|yB)%iJnJm0zUD7zWHWqmd?&jbr>XNjGhV;5^Yzy^C5|9td&ch3z+*k_;e z1?uPWMV=$$`EmVX^S7)W^mz>|;Dp zR@aca%hBiZF`=6o9%lH4?*YFw&eFB|$K-FkemVAA`$X~e)?@Px&YLYad0#ru^KrAh zdGr?faq$oGwr=~K@(}M|lphOsc`n&;k30&V&zk3g`Fr(|2kuiBTkm&1O#j(=v*|(k zeKY#~hWuDvvOd%Q^8UcqhV|L;sJs~eU-Ui0`wd69?=jCSdstyxNQCeOpQlW)<#CD7 z&S7>jdrTq>u)>jO{MdxgdCy~0B2>A|@I}wt;}apt#1j%B!!moAJ1*h#-0LZp2;-b! znVnBegc>UhU-EtCc=xmUN$%$qd)U?NelByIg;nm4=C4kKyeAj3+{t zi8bzHnd3aXHWB97c48vbInUUaJs&NJkYejP^>UUu9$KFWLriT*gc2*Pa3En{wrsTT zSEBD(_GNZcB6M?!eeB)relBvH2U_)wbyk_*k_Zj9Y}NO3ydN;lj+3mzN#=MUX&ugU zocp#}hhiVkhwM?Dw z`ASi|#BOnJk9EbdQ>@En4sd#}=YwNUPWU{q-cy_t_dQj;Y-^Wibl<7+JXb%Nd<=$r`yl2Y$na+VB?HpNWjq}gaN0y!~@2^?sIr8OTr#zW_uIGWV z=Q)=s=72gTPSaO${`vaBy)UHkqnsAUU#cIRINkY-I`>yOXC}_@oG^Dl9_Al-t$fAf zuT!5m`9}MH%j^5i);B)&7JU-$d#k>Phu`KtPQG2gj8FF3kF|HGhb`~YpE2K$a`xli zce|fG@39_7->VOtJEX5%d7szM1-|Efz`krcQ@!l_y!AQtHTyC1UGpyVK2cJa{W}@H z9{szVb6_Xa%&?pLm}3|7+|L5LSz?8AT#W9sZtqX^H}YzAa`flw;o>j!?;`I*b7J#n z82g6T$GrP^nBA_28=MQ%>^8oiIUZ!5c@{Xqar3e_%0t}4xoADsILro1jGyQGD^qN} z$@9R&%yOJ_);Um-w|Idg(Y%|Tqwxw8WAxXMd77rI zG&L<1MR+EsoS95(ESFr!l^RV$azO=VGDUNtvRo2j%E={nDaDms5Eq0R7c>`AR8&v` z1OxofM?LB z5Jx?@3_x%`0~x%2b0U;05iDMl*&*OtN)h4S!(-O*FCtrP*YzbiANf7V-l^7H&TCt1 z`_Vle)3@@cJ0|XOX5Ey>ApKvfOjRu;k3W<@Zc_Y07SY)2THWj7S9H!M)iy=#Ps+QE z9-tGfBrE2iSJ*`thg^;jQ{jKVi@C=H_`#d&0n7@C6LXydwGqMW()D%9lSs z9iZV?ODTAe4Kk~2uNtAYt09D@OSCPU4~0GWH+`MG*rikT4TJ8px1Kj?hf7Zl*la1o zNvJY>8}tz{Cxk}~Japm}hcxIO1V{a#q!!GY#xFWc1h@XWQ8@J(5Qv{PU0-oBZ#~;j z250nLqG>t`1zHBfQ9xA5o?3z84g?HRVO!n-uN* z9+clSU>{zTf}OJA+$M++Tu;$=4z-(8rk_S#r%o7&evkx(wu&~(#0x*_e@rW!YDo>R zy7z1Z02j=Jz&+y&@AyuQUR?2q6OTr^o$wDk!kc0qcAdUu!ZoQWJ!NRux8}1%tFQFO zS#2C~Yh{Yo#Gy)%cspO7=fz&;D8PK=_Bpg85%ZS{q`1Haky)5}dPs~pV(~a}SIhlr zY;R}LG<6jjMs4pO@^emVq5g|P3fI60h-nPBf?McZ-x0(D)t9TaZPE?}>*ARWCTxqK^eF2aW>*ylEMuFylRIBwgLcs4al+QtH|e-oKW${U$$TiJa`V1T zEho}~E3fKvQ3V(S-%Mlw<*$aQ?uqe}ydCr;Z*d>5FGKGY8Sn+$3@Wsp@c<3*HqW#-A`f3PyvQbn!47G?N#%U+9OWi2!%(Un zL=GOnLoSE-%yWq5(g_e4My2gF%;JT-5-uLk*Pc|WYfy_{*DNmUnnvDo)|hkK7{jJ_ zftcA5d)I(SqoNYHfIcrTZvR1<1mZW#4OB;1XU&7*^U0h48;5arg@hADUt29Mu-82f zIIwmf@(;^)AgB;q80x8WjJQ;v@uUPQXuXxEth+{9*2=2z-Im?Q){BH5!bi$`L8hrm z*M*2sW!EH+p{gCB86^{ow;LsjCSf4l#Uo!gvE7{mG23W>k{t1KBqyO|2-JNAA2`& zlCUeOAB^0ffbA#9u!Y}vLt?!2N!b`vbebRh8VVqM1RBE1p?(*synj8Iuo`@j@*T3{ z6YC{1#3ZPb+2(*qhlH4`=bk{~KS!YnPqYsp_8}9%!p-YW{G=LOF!nl&)kU4R^`7L5 zBjSH0#=v}yklO34^U57tmR>mC1#7X>faFC?0am7*6LsNOYRc$QslMEt3W{iJ`~ztk zCV4R$`eLYX^d&QYZ>f8yHRnpHd!{7N5eIR+I|CS)o@fDGcWzHben-vKgv23#anL>+ zJxXu$al(D=;N1!xxuYUik7=lnH0Vzn0roF-0OpB$TKu~Tsnv`gMcmzz|6J;B;uq2d zGHB$#D|LUOV81}o0-&OMRL5QmIe@3s7N(wKsv#O0 zk?v8loh|%`E_HYHn4(>j*-3v=kxAb$$p`YVgGxbY-bKgcXW68i!oErFe>*6;u`Mbm zTr7%Fb|-iR`o?B}*=$IM)M%;Kv^*(EANB!jVLpkK;a8zPurVzsr3^C%2?DW{)@4*s z?mf+e(U*Wcd<`jkx0Ho~*iLBMR)yhPBx9&OUJnyvp{f||U`jCWc9v$q$6yFCuhgA5 zN4*!q(Ehu_f5nlzusJBG=A9a=10oklQwmp9{ALO&Bu;Wwe+5h@DYu^a=h913WgVlnaB6(=`y-;st5IW_lZ~}Z+0W6pvv93%Gsj0K=jPYd4Bk9^(QuTL>t0!=Y1$gJHhO=YRmQt~RY?fh1w>%SWJyOWVq z6YHL7hKTpl$V0_*cL_KUz2|y#Rny=bg_UKE`ivj*I%}NgFyj7^ z!XN5d-`|SN8nT?Rd_f1T5W|2v`0zE?Pq*WqAiZHt2Hd(d`^hE_kr5!emY+lSdWWYl zj#?}vzcs9!mSJTo^p>2aJV{(`PHsP{jWrhN9y7oL6$nCKqzj^+fV}Kkd-NSX zveH-DsB*J)V^*_A=NC`aqncX8lf9G9_b+eB8SCmcssH{Ya3Hl!3sQFcE%ZcGjA^Xh z{M4QhR<|H>SbaRoS=Yqjt())_HQnig>mM~^;VHui(Voh-?KITvx?;Z4&;s*h=NN1e zG6_4~u&OCqGto2c7+^iOZi8&cv&&JQhvViOm?tqA(pTHh#XLKe|MK@LFDI>|G%+(_kT-e7ik zVEYeN&=&483)}<_MBeuuocY6-a*di!+B7rn__ht+VW*~+Ss4pIm~ih53}Y}kwZn3^ zkRm{G0~)pcI3>8je)L}z*kfP>*l0vof=MyzzcJ6tS(b_>aj4WxC@dmT-Y)?=8;n+u z;Gh-W14n>GmVwZt-b{-`pvg2mWXDH2Jmk%%+t!UVQ=knbPs}Awt}uMZP?#D6e{ROL z5*$h*y|zI7g(fU~9}R%Z$di%rSFuxKkb3*M0&ow@=WQIb2>)p|p+x~6&J{6Cz*y_E zEVDz-^!+Bz^uy6XVd;AZ8l)J-MZN>mAh0A-Pvy)w>I<^S!w#YBS?yp$qd=Y)OZV^? z8^aJ#ByW(%TvgRd76DeXsv9a~;m}1=4)1Vlh_FgcQ^Q(qjj-v$ z@^WANH3&gNOxw)X5QCusU7qH(-s`YYo?w|-`VQ#qWTUxC^*^KICxNKVfVN&0uPemc zXHvJb5d&M)KSSh~v^GBgy*x*79+)T%u$*cn-w}V#P4nMwlWI-XXp*MsbuClXnU6UI zG}QbCA+-BK2xaHB-K(jO(l&E6^WGXkiGwyPr2!dRt7W#G1qo-Tkm->4^-HW}^*lW8 z-=vDTNxG^WD}3w(k41PHw7w}QnIQ;wiMxX50S&|4zg9V|b*leuCH*-WnRsm;8^4(} zl>WM7c~t4P;(%)CEK!$t22i}`gPg-K!E;7~rFxpB9gu&L2B0NtQ1vVR2Z4%Gq?#-o z(vBzDfNSxy+A1kX4UI_Xm2h3C)n0x#^? zDx2?I{)LPjDSXU*S!Q}XyOA+-?~Xq_4uuQm_J0D2$IraP`BcX4J{FVmsnBk8 zGXKm==J;5h>ahzc6l?Rk^&!LpRhSTf$xkQ&-@SYrd_X-nQTSL{(=H1vS}>3lC#R#H z=#6qe2X1JcNae!EmNWBp7QVWsux*#43wlPyc*6gmTK43s;?!W)R#L`ltGtGzPbe*(B?k}b`FIx(SF^YA#X7Ghgu)@ zH!LgMRHDz3oAAhg)t>72YJmEs$_%rFv1spAgX3STuw2O|T^XaD^{zV>Qru$b;CFYo z`vBP?@Iv+(wm&0t49hch* zcO|XcRvs#|v`PXM4IXbo>l;lMUCbvhH>_ui!!kB%$?2h9u;S0xD%yHu2eeUcCyIGs zdI>C11BiUi4T_QpLrmCfeNZsnnp~>ZZYggO-389;sL0I7#HQi&p#077ouqCaq*ha9 z)8Zkbwmh^kL{29w_wlSDgI`%hEk0QlW=P!$VNX;6QNS9&vb}z8a2)hR+xv6)#!`=x z@G(HU%sBAqD9qfSr8B5|yzo*4C_HTD;cIfTa4)FQaM?1xe26V36p5CJcS#ocz z(5z}7<>06NIvM)|dwtKRgn%sPwUjzclvGX3yKR0V*c(Vb-yioS&4HHAuwz;GH3h0W ztF;1qY{s$0t}B7+ooX+cnK1k>i8Wa(x{uC2Z$s`W&*hk^yFN@_b&7k~giYnRF*O5$ zVY1M_+&tY7(SzioZ}Q3ghk3~l&ky8t4u7g63xAdE1BU4!|4^+cjVz^IjPi#akE`&D zlOh|0f!5;hMsmv<&tETr&#Ox)3A8TjM|zX~)K^B)8zVo|47iW@LM>Ab%`6hU_!}eR z-*N#9|L5U!cQ3a#ZvJrm3O#V*7!y%)CU7Gf-1Bu{$u?fdn~~yn-JJ|AJI?O&;%8eX z1>zPW_&b(L;cS1sym8~RM--Mlc$@@3XW7P9X*s_rtzOLs1`N5X$F@0v<={8ifZ-o{PpDB8NRQhGGXsbt> z5y}qGH1lIzJ<94?XB8BGQ_~xkMbtGyPy?YM1hMe7H2bnat3PhHMf+7?5H$XYa!Pd< zWy)%@u?eXK()%xL?nfO4M%@HM*1$9}14(onu(W0C$)43lcNQH-X!cxE#pmzxyGin> z*rH1_NbBqeY~EX!DY*m6;)s4pjhpQvnsJFM;GXoU#|Is=-PCrW^O78FZ8)!>jQKZM z0ObnFnY!A2f-MxMl~Uyv@*JH1AzL;W7t_X0ON@UnodQnu4Ygxt-!u@6ZK1c_MB`5r zrjiGdp=ny!Xlf_AIBJ2U>|y(>V?+$JZW9v&R< zEs2{yz+ZemVVTiMNq!)GBfc4K?mJ05(2jZr@_OfwSM%%WU->!@xEP&SQs@agJVmPm z1v{NW!c^bd=sG+;N4eqj1bphc8Rvu}=FiBeX}kHia|wt?L&fZ`ipmpAJNjJi$`&Ar zZJ5>S^(gNSjVUmq@N(s0o;^L-7IMXW5yi|dbrIOc>LB2gNJL(?WeN~g2=3p-$fA>? ziODaTT&39{ZaJ%YEY3Ayz7H*t$yxwbb+r@S2cDq5?@I+;l~J<=W@6unGB zdC`sm7QsgbQsdWAPuYAu>FBmyM}H3CP(x$0soM3SD$giw3i)4)aLNep52^|@dag#W zvPXZ#3G#}SyO)ALmU}+6O!vN8zz^ZVV{|kv0!8NgtVa?r7J_0!Se12ja1G%zfj`|T z2|NC8@(f&nOxj94rZ`LQe^X4V*~;dUiW+nQs*Ba+GT>#{HK!TY$E1}@* zFlVk7vR7Lv?=zD#zY&RPlQ{#_a*|-Xp7+_Jp>mMI+u5Jc)c;KMP1Mw_!n&fHMP{;M zr{SZB>G%o18ap;o%6b8DLO>`2dX~75SqjsfH!=kLQ_J9nLWuu+l`Tx=sGyq%?c{&Z5V}X z6q3y^PZsV~S`ynnb}z=zx`Vm{=Ffy^TUYgbTHlZqGh1Uj>l;Kk zf&<)=K!njr$xKSpwN9o4S)}SeCZEFPy^!1*>)M1{@jcH1vNbk7#93Bi)HE$b)`;H) zX6(yv9{jZsGn`0@l!!s{);|#^ z5$A{o=VkTYncF8w*wUv*`#w!Zta1hU5vK4IxIF_A?`LoAQ1V-5f0UdQ0|~GE(LEn0 zKhgIck4V^>KCFMn`yC|J`%0#Njl8b%xVtNlNHhq@hxkAkU@Nmn;4g%TDm$=~*hq?79xOf21}6$bZ@yFV`n*oUN5tDPmy5mjVyyyEUVt<}?)In{nA`uEsd4hC!I7)`+)msbi)0`2z*^%jt%M#+J2_=2aRB6z_xI{ zgE8!>2|n#&w?OqG#TiRfwgzegm9!T9Er%3{t!L(guF zCHT^ke6v2C3eS(+r1@l%_cCp)Ip-=Wi@@PxODG*vd5QCd1_Yti`|u!Q&o z$iv2}p(v^{Bc(+1y4xQ2k|*sHLxnG2bDma+P1>+^91rNYsg z){H%R-cu{^?}WH$hBha8qvZor;3BC@`ft;jt*k)DIQ?USnf5c!K+U7*pg(2~J-xjC z%U%7sTvGFy19L^m>n)E>fNlwaClU4TAp>wy+nFDK?ND0--!VbK&`w1|+nDJaa+N z(5>wZ=?+4rW13WdgQt{HQq6f~(%{|DERU3}?6uaR^z=Bk?PO|ehKnnw?aV`6Eg!tT z@IPh>_)DzXbsE$S4;+kN?phC(p~c)CRbAh8PK(ZUrMFC`tJZK6G#3?x3JbyJbPMn5 z?;`9xOZ!10&IXUT0Cosz$@hMNjC|yb4dXm;%RLpy+L6Kr7mopt<-Qe3EnV|KO4+`` z7kyADY29%kJk>+%`cTOf>4QByL#paeM*T#*VzTChtVKo!k-SA+(lGhiG(Yp8?w`%U z{%>tvsnj!!rop7Qbt?C0ZvbSt4AAi-7BJ)-|bQwQn6i0K5j()7EJ! zOSC{Kl7pRKti*gR_@HW15I37a9`7jFEJKgHKa9ojW!^pm30j|#<~G@ z_4a{UnMsjrI>~<=B8AR$+xkM`uvZvep0rM8u$MYeVLHd??`qG48Z8LY0DFx|B)!DQ zx-O{+$z{rEZHn%@d)I|;nLp_cuB`L61IIaLYTYvX&R1Z(WN%1n;dL!idcG3lNcB)# zQ~lJlDu~oWq?!QI(Cb*@cKSN+18#zqqWd`%*HBI8{%h-n2@0u1bpZ=aQlZCf^Lfj( z*#L2vnk)|E>5dnt#ly*l-T$?nq@J|3F&xP$fITr8J0=cu_6uRjmD?{mr&I~3vpSGY z`Td>^0K{o)jAOKQzDL1UgNgx3HZko}ZTB>;%#1Td&P6A?$J_3$rZSf^LZ~_e%b^ox z`f|*Z#nQ2dIN~ zUMtJDZ%Q3B(Nf8mxN%kwNJ^aoX}r{g&JeZd{NI@TxhhPH-#AM-x{l2T$6bRK==R~~ zGvlnk-YBQja7qxeQd!b|SslDi@lXTmt4TTz9BLx;(YdVrpm^}#nxYho^>yBR-C{kV zR*@!f%}ybub3aD4Xm5LEOir^hyHmbI_V*z<(=R= zWYEplW7ZyQC&72we$Kr9{KpG}73N3j5&V3+US*+q=nI_g1b@u7-u1}p`dvMf^e}N{ zCh?)QT=;397~G!faWY=BWd5>u{gms4^k8qDbj8d=LtrC<{dCvyW3g~Auqn+G8r(eq z4~UXDj7RU-S=BZko|AhfWZ{3-xG6c2*SuRb4t>4kC6y89Nb%A+>7Bu{eEQ2 zyHmcrX>20rJ5>hcPNFhgXgH8%eKV6`RW@TLgU?Hc*TlE@HRGY3+zFz-2;y6grZ7SV zG|Q>L0zkxza>2@fkl@3#$?2p_DNWD+R>rOYq~2Cw5EoFS1MYdK`l9Kqdb0IqN*%^+ z5l|8)NKlUKCkuwwZ3AI(<`SH#VKNj`jyV#CDp2)<5)qjfxob`%enH_19sTgFTjioB zeuvV($13gy)QEZoYLTr`C7h+3V)IbB=fS)_aE+L#p-NdU4%*CB`Nk$3IzkBF*!xj9 zH>bVCNiSZqb^w1lFDDOz{feK#B;5u?kad zOG3&kEWO3B)HV^C>c4b=XR69qp&mE2rWh87jXhMo;-v>Kre6aD^RC`kcT9#BA_);? zT}8=d-J?i)q9g1yw$S-K@fCY-rSs^Nywf82ao%kU<2XE~ffrN~Sy%wLMPaDH@9!K6 zSl)9)K)kQ>LucHnuu0OaPmO$yD>*+e+Qmm?ePh$Sl)^Kb=rgFyV+Sn%GNc6ezTitw zYT~w%?#WU;wz_68fXG63zp0`!zjeAcf45%10VB_~hUA9_MZ@^IKBc!?(!dc$yaqnc zrf5$~IMqZmlI5aVVoo3?)=e~Zo(ON*xey}w{3rh|b*s}sZN)z#4BI&?wDmm80XPb_8-!|tucxLm87rrLfHsLP=!qT}h?U(02s%smcCnPq;boHpVp6Fv` zn0Q9h%cNg{(>s2wZz?rW=qODrdO&*zeJKAX^su%l!Fl#E_5k#cvT*!f4{f-)q1vyD z;kF_jtfs%q2s!|qIg~ji-EOgCKDT_EamQxh(}fHNx(;WmUd&v$?c(^hE>?fHulH^J zJBAH+^yfT@x7}>szRdvRCR;PUb~V0xR1wP~e{5e|yE3`_a5s+W+Q*6juXHZ>bqAS91Zk^=~*rLg!V|wXqe1!kUke z=_?O`YP}rursTWCO5ec2X7vRgeHX_OU#AngIj>iwC{F1){4($bz02=SdNrvk-J^0; z^*5`uW}@d~v|ywO_U2f;uQ@~Givfze@1;YU5d{$Y)EtOCsuXgGdjq{=Cmi?inyteV zI{kpCC5*}gF{cq|bJVH{k)I0La+IZ68m|JiMw&Y9N7Fs8uB>@Y5ScN8+w~FO^R831-G6yXCy`zFopOGv$<0Qx*z-1f@7! zr?g_>-{HD|nCos}aZ}k#OYs+`UGI>$&>&JqdN-Ez(ce^~yQ!Ujq`1V)*iF?_@bu0> zoopP0ieKWpy6^aGS_ury5-}qh&yd^LN&1GidKEdVA^BoIYJzsU)u^R-l}Dj~HDt8` zR2ZvxWg{#Bix|D-090cFp`i0Mq}m-{5+t0&Su-whTJt%;sr7!Muk3ekozYseMuL_7 zDWfRy2h!5eR=PMs;=Y3R?X>nz-0>j_c8b8$TX86iV~S>JX#RZ1g+H#U&vaZc@;Q>2 z@nkSRI5gj#HGA+dAgu*Ok^rDdeuMU9(+4w6Lnv0BlEIwB3>V9e#EgDkS2wI>BniQW zHCY+hB`WLfm@9r8d!DmASoC_GS3Rve)BB4?{wetAP(-5N;5~s<9J-U&aeYIBghmW4tyDZ{)k7ld`ZwZQY4U zt6^(rI^2oD!ddg*YB9-4Rg(9XNw}p(3>uL%7%zzK==)BNNlhx|GK>;&Um_dIOXiM_ z()fwEZd(r?)%8GId_+1cqw*mKdbI~2y% z|3=ZYRw|3s)0-Ok|Mb<_LQv0X%QnWT0bTZ(Q9%p@dhlOQa%orXrv`bTI2&*|qo1Ap z7wU;g#f3r~wNATYVw32#xRQPSI#D?>6l{3vqf;IiqE_v>^Ws21FUrLGMrH-^;(KQ@Oum@bv_!p;qr|LSa8d1lEuaCX$B%(bmcJQP>}- zx*K$@?aR1>LeHs0H`bSWCpNiTtmU4e=yBRgGX(9XR19^`YONB|`grtr%HDr#(cSyh zX+Oq!sV5+Huy5Q|< zMaci1v#9fVqO(I}Zhsk-?PE3PB*+^1a^>|e-L$U|V`s$6m_#!peVK7vtRohq zt$*gWuDc&_Xql9xm1;~$VSn7+LcWkvNNxrZ?5ETXclf)Y6b;F5N9m3K~R3cFRd zH`BNaJ9{dQd3N;Mj)35|-uF3kx~&+Qbr}F3b5jnPS`n7)-AB{p2hE}p>JU`6POIYq zH*_c9bZzjJ-;IHL`xWy-VXJM8AYA>Gg3{gpAbHuFsE25-k8Np+(YgL9@7t4=Kk?Bc zNRf%!ZoV(qxoZhyh|E#}+n!e#B@)8hO*ayo(~0W znUNO1_ZgKfU4E zU|rEwCkO6F4re4BtW4d7YL3LY1hHCmoPCRrMXg=<&UfJ)nL4@%WB<=mcxRptG94|P z+DM@fiT49x&i3^cbn9d}}+y>D!gs2zgsdatdti0lT`#Kplejf}!br}1o zeOhvz-`uNfXtJZZIDm((-8<0JjH4%ywp^AAEXd5feIN^}$# zuG4cK;M%9mrT(f0peiBpy4s)01!*Yl$zRAac&I-%`Sy5Q6J({+lA*0{2dQ=`nl#30 z?ibr}c`(T~QnEBAwn}K?-c*Oq=t%iBr^(1LCOU}1R0_K0)pa3yPOCRe|S$%B|7v$qCmZnLg)TH^ftzw0pSPsDrT}=W!BP0+MVB6c094E*TM$* zr%1=O`5r0>D>1LN@6)OOF&)Uzr(K?8{2Z78C^gwgtrq^2bcFZv1;&)+_9Ip_3|k&m zM550^c8pZ_9*zJaV{j0Mp|cerW~`ST{Rasl;;-YAwMX)A`ppi5DgwA)IZn}&OVK4^ zPt2J1BZpO#-lHv0Ytk#ZIa_VBj@&`|FzG)t8n z<9(aAV=RAYjr9IxEUtAD?xqPZV!c}|$EV(5ytA+zbgAs2O_ZZ>H##QT0YBneH zdLg~9Qn0&vWJ_{tGLlt2xqP2Tv_l7M$*U%p7w?FRx7>u^grO>76w8NYL^eA0!h`4a zZbvti<0B_6QWV4wqdjUFeBof~1w21v(=GJjv|k`;v|-wK-Losy`;HSc$uKp)DFt_!my1xhQW2SBfyQ&;dK4^aT?N3GWE-V^K zMY7y@I~d-4>HQZ`M0DcR{v?}oT6p*ZL&7o~`BVvuPaMqZK#Fr$(96@Imx55wCH^Vz zP#_0eqZQb(2CG+8liy(#uu4PE!im4K*)>PP4;)?vPwW zx3Ik2P_`)Fuk0j=Gpm>TD$?8Tv4(A?{S7rhu$Ge zj>R|(#omXgJ}Ppd{gRAdD@sB$QBeUA`3Jqo%<`D{LUU#leNW%Cc%?nXE5t_gK>n-e zZCKvNk2_vh_XU@z}=Use|i1*P^5ijmJYiyA-w2&JQHM0pd#h6VY}va3p0PYvwxURQOn5zl?smwoeRN(--)^IXPmzQ*{^%}}yD4g-dSrQcS z(M6-r=NeqjH@bV35b?aAHku>4tU6WSNITy0j*f{0wlNYm_}3V-4WlY5QQwn1LB7DE{|+X0c^^u5DmlR3Y;;(nn9Z2|27pGx ztB_yvUEOa|_pKB!8|cTlhO~__uO6~RTn?h>%BbyTQuJoK!}!|Y`6B`XW_z7?w&nCHkyR%mlakNAWeT?&(qg6XVHHZ zb^dx}!f%@f7c-wFG%>q1H8I(2=6PszxURmbQEn7Cg|C&pd@oYFx@RbM;Xht*dK6zUP-4~@j{(a zs0m8RPg!dn{x&tHDea~DUMF@O)3gOv(N?roN8lm1gOz2sNM~a2z&Zw9SW={!@fm(f zwQlaKJ%6Fsios7VD5(P0eDd!4O-&1oc@!vFKNS+0p*#PVXaMg&9m>dInS?(tr_Mm` zG}s-VzeO~rPXwzB`il9V-DG~L$}VMgWq=8by+kW0T9fZpi7~1XCQhJ>hikE5Vy|OQ zKr7}H0f#7q`=fJom(J%Zvyr665GLZXD%<;JC52`&W5AoUA?OCg?Ui60lpXt}3!f`% zeNtaIESg2pE*_c+&F0s}e;JcKafO6i3`~U+LL1nYzPS$chsnfKlO>VqBl+HE+Cq|Z zGpfpt6T_Z2jg0m=2LiY*^fsD-iU|v8;nZxFv&=}y+zlVgLo^Yq14dDPgNlZZ7H;?7 z7|70Vt(64I{xYk_%t;$yc#vV5yAJX-4u{7yo4<3NkMsj8uc&Oing#$xs0Rx(M0}0x z3V6h3M&QA7SlcdX;k(pf{7U`6nBO{*ADMYMue-W8EmWwdA zNX23JfEKAMDsLx1`?5WauA%{}fqM1t=G7~a*U|{@s?b-;-WC-ve#TE+OQkSTi_ZFh zaBmfWdsk>VIZ+U3-H7axwv%H{gWcrM_I* zwL>(8D?Za@CdL6#^zmw9+JnHw@+9-U=MiTihhJEe`%b3@MLDm6SpD)^-ezuCRR0mV z9T2YP;r_g`I3BDOPSW?6ekzay_6A37oUVD~1s7d8Ns8 zsFS@5vpZRgW!Ms691o7od?qDt|;C}Gg(H30<&X7;gQlYc#chn<%)1ZbnDG!&D9P*u|_L9bd zT-iszDX048;ocgCP=}TQsqflv$FVvv$>Q_%I6fF2!dEUZ_zZe>vwC^($Wq^!;GQaP z68#rnS*#&Yem0+ib3|)SH8b9w!m6qxMe~c8TcWy2pcGr0kb|>%2U`r7Z0kLtHy_)T zPm1t|Pb3r4Dn-d#!2=5)I)Y*RkDMn%qzUe%NnN@dLg;qDZ$7$PGy%lF|-Q z5}Fkt4MqWM;shP?#=PJ0B-&}cbx(RJN3_RhaTYg$Yid{CTRpbk2XTewX)wO#n8RIh z_9V$~Isu^1DVca?IQl~zJal!kI`~4js8E(iskaLGkgELsKSueErw?O|V zaiCfo@sg&$Z%AXh_^UeGEwVATv2Ke#FuVF>y2&#Agv#R;N3Vv}7ew_G8#owfqb&>@ z2mfOQ2rc8r#6L1WG{v>z}N z9^|W_x&VncmaPG|R-z~S)(X+#GQRlHPNpL65v0-zIN&!y3g^U|$M4KcvKE9Cj`N2^ z5+XgjUbXm#Lb8>#arpq2)%|7sl%iQ@@aUxhr;13^LS3SdB0r^R$6d9b25kmf2h~8p z?G^LT97wB`mNcSrQINNc6-Z35#yZFr%T!<25W0WTP#+8LD3Cjs6doGVPD$sl8iHV$ z6b>!WX0o$MBcxqN#JnMxi?`ZIHE9V!;*h=eI3dPsHC|@HdpKpg?3C>F3xe*(+Ks9Z zCU~7hos@69a2OZJ{fsZYlZIXr4(M7B&v76l4CL=O?9^0Hi!qIQPWbD$y@pAj8PqUx~Le z&kSI=DVVp)oXggi=m87g`sA}uuy!YiekhG0_g#^hVsj@VF%y5$Zo zC}^cHg2tI<#E25UV6`ZoLVmbX+T>iJuADdc4llBF!}&U z!lJ=tYh;d@t_vt^rwTid5H0yk_ypZL@4{?JcKyS|2psH28!;%D9QjYd*m^&JOb8FP zR|5Xw^IJcvPP5CCGyi{Et63(eL>{oRuV{Mthk{R)#Bd-@pONiN?$6fWpbK9K-ytl# zAuJ7KfK@lU-!F<_8*(dbOtSdRlW% z_=Bsi=h6b~S9i9vz|dk)eqDaS3^M(ZDMllh{=jtiM^&0W7L*X|Tm@Jq8iddcc`K*xpWmy^bs zn`Ma^UN%a?X#Izgi&&3ltB3SdbXFKWC+Tc`a(;DHSwOwL#)MVUvAHMXWYo>s_KspJ z`P9MRKBd-XnOMX?n8!yOy86F0nVNto9tR(l`86cLOL50n+6D?S=t7!Dk_*22V{mA& z>cGrmTk!gOM=m} zs~>eGnnwxGARL>d1<$5{q*=i)tK3+flsi7p)@}ZS>{eUuerAZJ_#*G`=yiYj)|2p(JfCnV`*- zUKCAC(jiBf!Zdb!f0NGvBeEq#xr;qREjzfMJ?N)GMD?eeqq1iR`x>+#Twck5L%eF@ zF;B6x!|Y8TCpup14_Q3Xv8dn+*c%gTmEtI!L>RyD7K~cF#OLOhF7Z3V{4k4#(Tfg( zoC0VO&-|^!|KsS)!;((d|NlMH%y=dnZL%_RJ57s~CT=Mz!kHX%8Y^pB)Ld|>{Fwx$w{=NrTe|l%eHy_HM%BVk(a|+>G7(wQg6LjIY^9fQ_r-u=>Os*%LR zVg&YX3!)?o5IP!*{roSrH1q1d*&Em*atwBFS_SNPZVdLk&-m7;3^i=qS=1*G4npN^ zDUs>dlh^)>>;fmw^;9qG{y{kFEZ66vb zN3KUpWb55{?N;78PxNQ+RMx}ZeauSo^SV_NjDSq_K4dgs$DXoYpUV)eU0D45hmKby zoC1|PzJeRpJPkl$JzX(h)4ya493+yp=8;izsYy%LHK|{Z@8ep~ymdSnBU`%=6P1{L z9VJ*6AQXE9v@%Wa$E}3knXNFg2dt#21ZK`$4+MN_Kk4VZj^IpaXY^KCge_0qRW)}O zN<9bkJ&)r6Oo@Ij1F!%$zA)e@q=lFIvw%mgB8#j+eR5GC)^!4eew%4!gDL z?Z*=5Kzp_q6s|DdPHSYFYnNAColCb58G&K9AU58xJ;%c`f{(uf|9LL=#Ce~qG^0$o zQygS3sdW3vtE4!{dB|k1>2FQu5VupS|5ce_`a&K}!F(>J4?&1&ProT=(u7A9I zv`y1^Iau&q_4lc=0Nb;<{kUs5pFOP(ShqdDhJ~EX{niLtv0dzdIld>_5Qib3$#oOL zD!2Q^mtI;+RcvM-zfHk>^s-IR1zofAsN@U{fI<ksxx_ z<@;nlwEN^97pomvr}B(D=gszqX*+#tn2S@So!n&&^k(2MuBbX6QeK3?NO^a=ar(4b zX;*DBXZLDaNA!sz4Al4>C{78V zOA36~oN4fhx<@yiGJ6q*{Y3f@8{gkOrDppa=wNJ_E|~o`_v_ks=u-BA+4}@_Gw7rKMtz?N z|I^@F%guS_T2{F}MpEZ*Wvth)6N+$!ygQ)<3|9oqZAYC?=V{yhDGd;LP0iaOk*}}6 zp*Y>g?Nxs*4s(5_?Y6S(Ksy%|ubFeA3tZXXUrF3M@;ycu!}j!W8(^A~EW4{HlDP-q zPoABriSLkZ9)k9XttPjVvm<_KQ~V`AMY0csg8qC` zK7sI~*+M~XQ}Kj4%7{rPWia>++uKTT<7w9$t4=T-%5;GGCFo}^v5ilrk+BiiQL7e% zF&U+)h0M<6h?(7fum?s?fMC$_Aoh`Bww|ED zBfE`RDJ8CR(G}i~E>K|?%WF0)4!qQj{*12CR;@^z*v4m&ifHljr#W;@lh4p*?gGta z=mx-`J3~7n=Z!hI^q%c|1#0;*qA0qtZRlKDIkqdiJPs@p{`&}+zT3Qf*=2UnTeDq3 zj4qvudsO`p*)?Ed1iukhgk+*yf-F?cTKrAhe*?w6344(?`OMb4 z0a?hDpiUbGCa;xcl!On$5k52Z5<+MJjIFzT)uX8ObHv}U;e2H7|w&lfH@ zz-7)IuA|z2pb3Gk!+D+0>Xk>bc&#(7T}|4J0}3h`ke2?7mVPKO{CN>8`wU5f zsTi@`%+EZnn<|=_j#1VNhF`EJ8wk^-UMn!>9~oPg>%8rjGkor!T;p1rof}MkQIZig zp*Z2_>|Rfm+<@tC@nP@9v+3i3+ONiV!Lyr^=C@lDgF=zYda{XOMK=xem@x+*1OmA2 zB{#{GL5g9xNcU;THl&GP7reVE+&&(CZvNHe)GpQZ@=7X4dmU})PaT-*)~u98M?f%r z>L*I_HQT@z`pEYJp%PSBYsiB?H~fWBx2Lwf-4#l^m`+l^L{96gy^sP`qmWTu1f7p6BoFeV5p zg1Ac0M!j(10#6=}^+u_9mBO5ms$BBUN=Uyy}|in0DNkhV01rd_B>qCcCm5(U&06&A8@LwOb7X%CR%f~qio$p=sk&4ZeN zCv4AW!b@S~5Um5CU|c!UZf6@u8>rpkr?N0R>nh9;(w2t?YYQ35zj`U_U|g z-3T+wI_e%~Bzb8_WZn+*BWWf>J{=F3i+vlSYd9?oPcTeBzU04JFUgyPA0ghDR5K^8WaV6OY>|Cj(bdWK;c_)84??SA zX3+JAfn*S^EC|^B^jFqGkrh{DEAu^wp3h40Cd0RQ^7FN%Vk2*d7PY%#w26NDcJ@!z{c_2DBK$=JZ@-pjozxk~ZskfJ2$}!W zrCr8A1byQ8W?1Z1+EUhd0A%RN<~}BG`^~w6ajG&x{7I&I9&{U;busLc2eL3cexb?c z8}_j2W8$!Bmks#0bnCu30H6{NG&cOl=`u%PUotMhUDlsPP0J>TLzUip3*`w4#DvVx zeJb)d?I*h>#%kdE9QD0a?}+H|?2SuMtyNi}0T$*iOx z*iD!xE;m!Q(z<0uj=2JvNUKIJ{Vu=BPC4R54qr9nw%H&nT8!sA>l(^R8g8(i?bc8s zkS&au_s^cN*rOpHW)jx{k?Hsl+V`f&&IS<%S@t@nymeq37t2L!hXk*DX@`hH{ zE52MT3dyIY|9k$|QI*k3Q{S6Z*|+w*kAW}c*EgX4-t4VY^G{NpA(IN)0d~-PG95DF z7DId3$ydXBK>hw%oHyI+t<;6;in#MMuTWlGV;lVhDQZa8&V652Un$6XB%F{=f0n(CpgW`34_Ub<-X)aT8aF~B77~0eYQ=pvkRg3OgUo|GCI8;Xg3fz^)~#^&)L^xP_U%mD z%baE7m$T~m+V$N{5OxOW5w`$M(S0RPW)KS4dO{&PxmadFo7yzbis)leUDf%R1zNfA zk;rZ^5=Mj)B?1IJF0uzLyCZ*zZAM z0Sd&hV@#?%rCjEbfny#TV$GL~Z;0YID;_1!%d@D`4*n5B3Vj&5C zHo5eeqZ9K|)#B?X$f}?%N-A>QOmuM_HEB02-uzn3Y6WCZ6O;s*zgRwbKk*~gDPNxo&7U&L;NAdoDF_ecZv}NXmJ3D?tDV!jFs>v2M@Y)o z7X|6S@4UH%9v+*l@% zN=~X$m+BjEcA0%hIF`LBsO~wf>;HVScJh01*Rjm%4+e9Md}UZeyQ;OFC=+-7%)Z5* zcjd5$LTiO>LY?*4f!_1jZ8z9(HnHb#-#cB!x1Y82*;#u*fQ-UK(jEb+QrSDMe}DU^ zvsQHb87c~DJ=4(3$!Jn#KYQx?cy;3T(G<<>V2rRwgKR5FgI!~Eqq&iNo%6Qas}@?g z7`vuT{fB779jz~UxmXvqStugU*`}}x)=cAyq%*dqU401LN(zRHRps!Bqr}QU7aJlp z26z4RDtlJy<)JUYmL*5P9DCz&N5gmNyt`#n)Z4g~@LfI(Wly4_el@*szwo#YJT_yy zUxLNZ#P7wYvT*nNLJURNu)ajx(Uj#nt#7rZhlnxeF@*2qu9*(yXKqE|-k}tG#j(7m z_4uA7tf2Fy{Ddf3tbedvfvX@-&szO6H9j%@U$4+xN~2TcgQi|Pe@ki)G@$>rd!M)J z-_MYY{yQHQ-U8aP< zc3x}1zU>Xujo)#~ey+)0`}aFnrJpW1bd0zS=DD-u$0VW~F@&Axe%iJxTSVEeYS=ERZDoD~1fQT9^}lW&>_+VNI9hF&PvAp24#R#bIHzIkIk zCilEL>rC#Y#*>jw{oETc62>Vur1t{Mot)+5M%l{NO;!8siG&f+e)d>?XDc4kKdJk)$H8}@* zC&XrE4cQCOzLOe#q?j)Qy)(QVRcYUoTR>jqT8R^TA+(kj^s1;6jiLTF9~@VTI+ywY z4(Npkp!zs|^Tr8KJPQaojxZNYtL_}q^9=zXbfjq>}bXoC&*9(xw$rW^CjO}i8wbu zuxiW986dyQVTwm}^(K?`b(<^SujBkT40%7RTEybhYG-tb_>+t3*5oG7n)V=Qf_f|1 z)Cl|8E9P^M^3Ef;HxcE7_5vwqSM+HM(gtC*^3iukJcilI_}jF4l~jR{n2utkm>=p# zWw4)BG_Qq(c}N;+!>ai_$B_U9Md^5}u=m<<oA?K64Ig!b^zMx7v5YH>xFFS`&WYZnMBCWp#gn`~88mzz8a z@X2$jTcaTl zIpa>8pvb#X$BK(i#Qhvzq4}%3weJv_KdL<=hS~HHUyblb<-;;QP-{LHXF+ISR?JzN zUFKSdU5`Ub&Lb6&?GX=2Y#lmr1a@3%zag9wN{s2|8!@`SvNu9CPt;ReT-gT>DJkD` zJuVg7B>rOGXgAWZPuMpqzYaMB6)4m<1?HyN^Hf48_W`UdX!W3wdaIY{Ck-9+y+T{9 zpEwt`NlHDDiOc+TVa5*YWV6l-_O}Vs)F@D*Yg(Iun*uFG$Vmm1VOX(|@#L(zJ2ncA zPVw!7Mp@HdMc7D(=$k`apl*?wat1`h>zQP&kjRlySL8enJ5?|p~l*lV2l9eQ<(rr*Ej10T+#uQ7HfxuEezyH7}ip_oBjdpH;V*?!(gy zR>82pED+~u*uTKQFG>2DjDo;e_t|s$Y_`2N1uyqKA!5fBwG2agsu1Kl3)rIKSUdo$ z_J~+-ko%slLij^6>g2u=koQyy;|UlVi6N&{FQ~UJ@{q_9#?<05W@LIo9y#D|1mf{H!ptLvo*ujx^I<4xZFw`k`&B zy<>B{sdC*oDgLo1;27_JDCR@7$BSGKuKnyBq?$pj)`b8XrKDx}4un{(rp6Wg~8ns|4RgGG?}q0-+b2XI`DmbSMs}VD{^MJdf;$rzoi4g)l782CWE55 z?=ii!cXnos_yFYJs^r&>O52xpA>xcbF+T|RK?U7$e=sU|pKz6B-^44}u$k1?F(sUu zKEpmaFcpFFxo;ODbf|1-UCmI-1bf&%Z@l_%N(dhN;Fmp)Sdgyk?IrfEVHvyH$&pxR zP1tjFEjG}d#@}%>oY%PPD zy$_M=+u%BMgfSI$&*wZ8mN}o?=k%ubY|A?bVMye%dK9$)X-LWY-hG<)-254=2jsR; z*K5)oJ6{(+%$^AdgEd4fbw>%J<)6zcT!BnqbKC+(zFpg&IHb=$uJP$bLTz=~x2zJW zgP12iy&T<}p8$ILEt59pomTPPGlQ^I-Hs9mCpuaX5>sp!5>;pAV;*jo;G)b_@cx;_ za>^bQ!^|9<2ly=P5zSm(rfghXD$YX;EGz_&b6$l%`lDs z);BcM{ghMDn+@8c@07suA09;wsFR9F_Ulo(x7@*@c_iCLX6L(ED2Mxd6=+KOjW}BR z8+v`id%SRQek4ZMr*Tza(N!DJwQZueGBXkDtQ#sBQ;6HsJcW*Y^__?M3fLo34TEs85TkZdpiwh1p{0UKZL?OysJ!X!k%+ zy|+ELZRDxSpBp5M-%$O%e&aM*TLREZhVXSwlhOdlOI!1#k3@UeB(Vi@KD4*HJkXNVU`26_MO_ zaQWkhnhU+hGjY*jBlBF!MeR0|+!O9L8AlIM1*x}}F1&Nm!ttl_LK|9?pL}bEPJi4C zo4c`9DrbA{{us89dUSV2imK*9lxv(%*fi>BL!0)4?}6-jc6AJgy@Up8jXpt?2j=KT z7_r{SBzJ1h8a@YqDm=@OEncdikBpJ1uQLax@ga2?QE$5e^~C?#?4D5}Ysns}J1VC9 zsKL^FYu?nB6x}3eOKL7G2aix@0*D?UZQuj4a;jvB@yITek+Okt*?OvH7uyBFuUpR; zgB~_fzU&h3#1mL{q`oN#Z;n}DXOo$$?*AOLKPY>BLiFPr+cJGZ%bc{{e$0frkP(K< z(a&Yp$}4(*)&*yj=n$*J>$*}^z#j49$IvRq`_N%_ZIUb0)fj(@0a*>G21R7m=`W_DDHzXPZ_0or4a} zL&t$hvhO;c$Z1j44Xy0`e7inS)Ozej*A4NKm2p_)|JIbfTr#Q}epe}$kP4{&oD3F* znE@}LCJkml1{^$sBgu!KQdc)8l$BRx?v_?tMXA7)RLm{yf4OH$%X?-ZGlT{L+euFo zeF^6~1N8*JA0~uF=GuiID$gah(r+ojUwl%jA2ZGZK}C;74IT$guTHs3H;<`*b`D5r z&5YZS)(*y1hH9!e?;xpSb#fv46}y!IjX5X3-7qP0#}CMCyNQoS4KRN97-_S3YvAxm z@|`$RY@xV8)S3Je^Fz>dd`UPdo@Svl#Bu)Sdhy}A48eWn(f2M%yr`@x)tuerbF%Wr z-mbyp9#fy(LwCTCFn_-Da<3W7xyKQ=N}sHhG8@y6pdVT^x)_#MveXk&=BR-iolT0) z+2*m2e5|y_+u=vKyfT$2X%+VY%&$_2*+;0>H;@Vin^dWZa>$8$0m*t1Xp z+RKwjB%WUPL>ko$=beckn6(tW0o;;gyJ_C9fv`cGSQFyx$mgoCr8kO_x+AEz7<~XK ztakuywN)baHC$Boi*acSrcY=>l#Q?=CHqc@W9xr)m&v>nSNjQu2S!=5qQ8CS0LAtV z?i%~#S|y<8)xBMOz<;}Hig)Q;O9s0=;kVFhFy}V98t65mEk596JF#l_tqJ~ThFDf@ zir>+e?r9ZI$q3R_5N%C{&u?UP&})`^H$CybL6CNF@_n6?CQQBfAX+y^KfoT!5eSb= z*6R6!#eJ4DlP1<@Lz?l?ilcH@Kyo6=2@RyLa!N=7~bW`%&koJFiILw56>kw z3pY0;i#y?RtE^%fcw-mePZqHJH+(A^?I&-3;-mc)9k%Q_6o(XD(I8{=$^V3v3dJV) zL!A*IP{+dc`5-?jyO4dN6l;Z{4rT&Ro71pW#&q5YzaZnwHc{4<4IkI_N$Q(8q$Ecv z^O{uPR}UJe@@0o^hHX-Mr>_UAQb)!0US1&W4WaIkrs_o+GWa25@`=IF51z3Db)H8S z-$*OhUfbw%;g~734T>-O2%7W|Gb!Z{UYsNDgvM~1rD|U>SR!@F*QYg}Z!(x(|08-d zxN!6Ju*>|8CsN-lh{Wc&xiNBEV3q!fqA6>nbs?Y19rqgWZhQrwi_b-!(~2_+tFLaP zcXR&s(H-XBud|>!nl|1f2VcR90Yjp=@_AAvLw4*bnCVc@@?MDlX)Z1VqViFgPfqOw zh4ZnynpzK%)~=feP4RYVX98euI5)@6sYr=sL>=}oC}ePvOxhFQcoJ5}84u8YC$P}A zWFnnE$~dX(=IOy^_*8id!$un_5^R33U8R4I$Srmi9U5^tLDJSM^2?@UUL^T&H>h|& zMqr|4S$*fVGNnx@PllU8*dVTD;akQQJoEv&slvEZB;WLryH$L;1A$Pbj^8kt#h>!+ zMVqhk^x>{GBf${9E^$NJUh!cu<1cJ&I{Pju;~@r_1GEk4{XjsfO~r#QXN}f|5AbHK zYUgD#9Q&?YUC0D9JrMX7#`f1Ew=1F~hF%aLt1oI}PZb}#3Lf~2-*SLai*2|mZ5>L6 zi~0WyC}Oval$f&ax@Vcbzk4FFD42bYSG^uws1KjW96*5Sqv4$NOB=oIq@)mOBA*b5 z3JyCL(nO&$&^)NTYX2DRCOKr6X?59m$B<>{MCldyk&i&hgO#szqF;CSjLIQ=3{^`8 zJ_*J_psi5KT@Nr94xqu%EAb>Xfp{X?Um2`PSDVrIgpl%cedZ1BO^q zO?rd-p2#h{mmx>G`W?zbKAkC@ihX3C&^)j=sB0w6%_gwrU{lzrg2nMuE|xXY%l4P~ zqSl4$%<*b5$iu|<4C!p|Z++Nh^!jn_U`0@>47TRG+rZ7Pa!7`V83Ob4Cso%TXMc~a!V=66n+CsHS{$|ty_5<3K_-4vov)9$mz;k|T& z+M)Cp-VE+C_7ksXRh#rgs=a8wcflTab-@njIJsm9MMoUL-7|eh9x_`;tmUjDKKlZ$ z82Y-Q8X{g7a{QOrZ-_%=K4D!rN@S9a$qx)q_2fSd@f%$i#JnNUP>ica4@M^={cPrt zk04m7T5%HXq)gS-Zd$H?diMfC**JktUY^z9xVoVzWw{=Rr+MLpgK5xLNSgL0_XS&s z2erOv#xBqz2r}Mc(im2+58KRBEJ&!7H((EcGW)V=qkgW}10YM3nQLjBqyPi=J>e18 zl1T8V-{zlGY%WHO7wTx`j9yEOR^u<@j#n}aQFBs%E?khgvni3#g{<$sX{#%fqak5C zIqjwkfTC9gHIG5>_4tQA@!&K&zHDCr zFw;5p`kR{3JiYCb@!Nu}!L{t4uIC|we*i5EWG4(x_-0jxh9M;QQE4jZpY*xt$FnSF ztOp-?H?F94(Am+I>254(?T4E0GZgF7gOWNbmT&BxipvAy1Q9tcS-~D=VTgyJKrGU= zCZd(#;?t1mBA{DP{l6>5Eyp&x`y^oh*WIj@lG{g4HW}xLSYNwZMU!eBQmXcxZ>8?l z(LOY8b8M#X&kBp(Y|-X_msY_$(k5wpZEbMG6*X)4E7Jcgv1=1#`v6qY-ax0cYH<-A zGUQgtLgu#ArI^_h0n5_1>ubY3((Y zLNgC%9g^envC^gy9xydAvMaFdy`$w^q*$|p`iF>h>}nM^GN;zm4K_K2Q2(U-i563! z8&CC$wgr#4xw2%}$AS6{d(0Vc2q4YyP2FKe(~*CiFhNzHNko>mSV|ba5+n0qFEd?V zk1m#U?nmk|1`lak23*nWY&}286`kydph9{*^eIe_z&aXA^HF`*62AITypRS=*vc zw)=}1i5xw0`J(83iD4Bg@#iwHLv5=6q{%qto0Y0PL}wy}u^&ae0$=rUB(R%@zkn6_ zoHx)*1>9I#MQo`Br$Tsy03ls6O>D7I;Cj1La;$B#o+!$buD^%sPH21z`7GFUHjbe0 z8=`K_Qz3pno>gUbC4rCF=SEfD-V5ypE5V1cC25BEv*;Lf7{Cr#jF_<@W8L5@56YCv zwnBQI@yj+#o#B^3HC~m&E-|u;Zy=yRAIO9@U^!Uw(Hrz2PT)CssH}W(#cxm@ zvY|USh)}nS-mgv$k?oU`tqpS-3>H%s5JqEBhrB#x@!Ge~^TqgWNvSX=rMq1BqehEF zx88m(G!-r++9X~crt^@gTYeh`ix*?}v<**-!unX<6eU*69UI8}4n~la#X$Qz~f3ANmj-A2%NcN{4wB0+qzE~lBkN;cB z#G_yjOedR)*-1*CAiWpopU*HVy1Q#~ExTWvsOBnuIqGdgn=J-#t@FgYCd`~c{-zJ{ z?qaAeJEiI10cKa0?RS1prKm&WiG@`1@-Nq0QfLQj78k8;1CJW`+q$KLO?hgJhg5sJ3hV>jKT}3~yu0R!kI3HrktTw2vZ zwllK&*5c;DiHl+Jl&hF>in|6AsWSDb=yTWfIE(r%O3?+6fIZ$egbNWj5Mo?K0~gaQ z5EpU9+mN{}v`kpfm}161Z5p3Za89_Lxf1>qB@}!fCj)YAk*ubp%^LW)8vU_&?T{T^Cw(JV{IQ zO!;?sp)}=R3%m=xUWjU17rT7v>XM=(ckTyq9?{i4QMg*7_8%e-`&Sa}Z1`cP=Yoi- zHdV)`?8n}cbM?Oa?-4@uzEH`oVv77@dBaArCZsy1^{?*ZaMVmOlc{rN-+ywGpPTJ zX1&T-3{=u9VD&VmgZTin0rk2-d9Gt%`p%@^ID6{EhO4>4_3((^kID;ibYdJAmQTQm znyvvqL1Vj#HesK+{y0wNW^~becE)3h|L$q`!beozn3b+_%aiSwHXX^6iry60Ksu9* zEzipPVbw(RE<=ieATKa5wJ68?orYOxzvuZj`d3B`;=rUK;^ESEP|MpftLwIEB9eFG zNaEqZj{aL|hCRBT3Z#{;saJ2U!|YX@TsvwEVfq2IIgFD<+GbcJG#<=uRGLjr|M2!D zCY-Wn(si1~Z8`W?zg=VJ!9V*`1^r@&HfZa?@hJr1pvTk?dkZTg;gD3i^#QD<3dsVm z9&vUz-zek2EyWTa&(atv03&d9wUme^{836D@9o7e!fH`*QiT;S#${M)ndlZxP zfaNW|I-~>4a5T31vJcN+sh>3E=#Z{jbeGSK z2vV24=mUQxeArw;oHgL)&C`SY9l7*uL!sWJKutm4QBzJvLGNkTzC=uRtJ+M9=HXb$ z+4o``3AjD64Nna4AqYesnYszzFdUo#1qN2&bMY1U&!4SphULTy2*)+2z`mj;8|(=`BDULFegYTmR7VIX?+gtBWsyW2tv1b+s&de_J?vPClM1 zE3;rr>yP%FCg#+i!Q{i*Nfh6OcwO?DX39a z_FT83P_DZz{R(GUR)ke6XhQ0;$TTg3=Duq`Z0?7>;H_fK{vhphxsBW_ybMOvzsb~i zTdoD!=t|J-AVVOj*rWQpMH3P^#`OSQQXPNlPK-J0?(x9D5#Vt0k3S_TB6&07-@1*J zvG2OD`!bKXQ7%`1hZ#K2zPnTnNuq+y){EyWE-VgCxYi6W(?UU?bpsuQQ}<-E@ZG;! zVOIQVM)Ky(b8XmGT}KbCNj%pJ2&al3F+tl2R=t8JA9x&Z&~{%(+?OX0s01+-b@AwW z|1{xL;RHEscXwEi=E+W)y#aIaT`Q`jI_i!(RJ!AwNr|^_Pe!1fhCh|Vvm61V{YlzIML@4mVTOy~KfWfWja_nkid7I`E%{;^&8@>hTh&BZ)q z@fas0iVz@aegBWnCy=J3K70ic`01IwQ^K$4^wrAQ>BxIP591PfOp<5hkViaUpR)Nq;FF>U)td+dJC3UExo2d19+nZi7Ii8SS>mPW$zD+pTILEz<8){li87} z=*OYvm0U$zmL#BR`X;uvDF)pI%>HLaJK<%qE%xEJN-q)+x`1l6ZV>8aJ;VF>!HDQ=~!aj;Ho?vTLoysLxrV z{$kXitHKxElX!2N(t_5dz)GMW;Nll!n7K08#q`y7@?*S=%p`nes9jCwejOpvzZ!t~j8&WmEu)nF zj2tIJbAokvG3DfC#E9+^wR7DoCjW0-7i>)^ep`y#Lyo$0$xv(yoZlng_9UR**#zo? zsGS`4*MX>+?1_!W3-O8U#t)I&PmLcCns<#4C?B+s8Ee};Ioo^Qe$^J}R8$!_wWJoq?=oW2D*Tdo(lo0jYJS+Vt-IL}CutcdG5 z^{e&>sv&$4Qto}jR^#1}#|L#{$453-=MWNtWm9q=W#C35^|wCCpo_L4`SxfxWO#F1 zuL0K%@zm^BjFBSC_*Ttnzs@Iuq?2pgLrB>U7Fg32Uemu&)<9o- ztU;}ZuJsgTVrHoon?>@N<>PYXUv2hoU0;0oo?Fyx8;LsoyiJ(41_)G-(LS6!ogNgt z^reoo$YQVJtKrX#vI^$kpz_WP;*PKf!sPRQ@ceb7l#nzK^>#GUMl7{3*siZi9Sdy}ot{m7G zlMcKz4+*U15vy4TmuZhCbtvvn+^dCuhojf8sm6S(_)k%vwqRA}T3>Bi_+}jj_2>6T zo&*~{rnc44$FIBhKkaSmxxx{G6>&saD1!b<`DixQH?L(jo_<05ezonuqm3=TTafg> zWMS7ko10dEc_*#BJH~yZB8Ji?++_xN^H^Py{{G&p4ALzme%txOZ3pTxMc>#UDgw?z zfUBuH>H9s%oYanriG`j}j_{25Zwa2Ub}Vpp!nlFqNDqe?m4E8*Yhd$P>xYcPqATnh znn%2}3CMSjF=p#=f3)<>fJ&+&?_FXcOZ^0taCXD+7hM%3(-hDROAp56Ov7m;kyFY>`ezhDhFa3R$v2OmSN-2$bjA<$4)Mr3Lcu8 z?*&CYG;XjYQ$DCu6mK-PYjVTEr2)|ZN0>cArTkeoNv~}}G?I(-eLqtn*a`^c3q&iJ zAyhFB&Jmj)fLxnW6RWan6=2-oY2wZoqJs+=^*W#5Y?3-15v7HQ&(rfqv)g~jwQ~qvuqSf7!&x;`Q{MN*Ck%EO1US?dSMT&++!5WmA#9YQv3~I3=;U% zs*2Z_oRw0GKJsOR)?1OTrM;evI}#l8_$JFmWvX8P+WZOjYS-IuD-#|gut$?*XOzLq z510j9rrKp-tSTOlCdK51hV=$*WS4m`rhyYsUS>FqL*`-{UCwTL^?&VM5Z8y*pTHrb z3A|#17i=WC_|jw-IJQ>i;FLa3z!bHb)Q839T%{oN5usCg>2xD z?jcu1lgA3e4ZH`!uLD@lVG=R>`vSh?dyt8zvg;YF-%-gz*)|V-?QMl1-?*ox*p^3@ zF0W`Thlq^C>=t&+NL~mj`VLd_S?b&|D`Z~e2gipP&Rh+S@&Oiw-OQ9*B@a7VBdbe49MM5*;^McV-2&-1P;wzWn8fk%K9nsTIQ&WCaj9 zSEs(NjnuY?dM7dR40L|r$gHV-U>bF%j2vx6gr4)Z4-E1cB*)PPt1~-v$!bp#gN0ho zf+;?Ipd7ixb3MBzw-UYr%OF~_CTGxETR*?d+l~_~+#h-o7BC2UR2{S%^?Fq3-DEru zY7iwg4~UE#>U3^Kyc6+`1yJG?tS%&$WL$-arfHY&qWhUZ^EU1FJYkLu8BE40qW%Cp z>p-N=ff5iBNL=7#TQ=P18!PFn4mYI03=%}`qW&FbeQX3Ch2y=XYbOEKIl|tQ?-I7;IS6vrr;7SF#PjeO zxx;;SN^$KT`Tu|!?v^t#Ne?{QtWt8e>Bf?7n;2CYwMkr*|0gtWM{S(r@b{t4wr>7s zMO!oi7y#m`|K2vrwhs=>{^J&Bir-&Z&D@6Ri<+SP4TuV^SH#yrtsomrJ;vrTC>~re z4#!q@BP+gHUG5A8<#!z=Wf|2X8~j!QFhp;FPyg&qCCHH)YJCu~VI>$YsTt z?ej_H(;<%Ilw{2HDvql)4BJkpB!tRgWVTN^r6N}=Mr_H&$ZSXCnq^~?&BkV%UH{(a z_m98axZT{|_I|yd&&T6_A6@Am1);6kc&3_}^C=6CIOX_QFuIa8iBeL=i?qM5*T16cH+rS2k72V1JfzjB0oOK=5T@{GFx_mxJ` zLu3vuy)p3E{8Pr009?W<*9J`)dUErvF0IU4R?-;ezG8T-xy9K3ZcH#)w`9)( zl$nXB)r=KpJ|{c;K*pnHqij+{46a!FAJTNNrPPd_7SuWTZJ^--j=A&xC?Y!F559Oj z0m87&+fkB+N7RvK)pa=-ZnBiO2_wQL?w-U6$x_UlbwexE&QN1Koo$fM?sB>__oVyv z!?`DHRP)?H%r9NO8F>(7GR^Ck3i`14ui|M2K=R&?Fi2XwVy|?~h=1aK&8CVCoqBP* z*Drm8*%s{iUa|A*t}OCg)b~)*y!CfnQEor%GNj$h;hxN7*80Y5=3hyOV4(f6CVntV z*FKno($5=;BDzEQ`8Sk@lOIKYYysl1(sl~Tb+|4lS;5@>6h_) zDQxiFV?tjjONf++A4JEKjG24au-H(&Gix$~mHm4VI-XKJdIA=%V-u;|esNmIJL%2SB>vW9&mEs9TpD4`fJz zw*gCH98N-B!t;M#B}P|mRa{wg22Q?t7_l>C9{X``Ov!V_Hhy1z%{Xr*n0Q;^D1)%? zDpM8RsP`+B&w(1(q1ou%LBR`&>8gM#?2BO*m{08?#}jszzbSzPT2Hml zc22huR%52oPR`Jd;$x|~qlvC;V?PMvoN;K3Hdn#Epa|#S^409@YDW*`_|ym|`af3q zm#N&7<^Uk(rTg}ffl`Xy=dTxN0i8eE1QyVem!S)gA$U}gAmF8mIU+%Oc&u#8I#W2N z99+?Tdjr;Uech}uNMpJ5Om`Fok96rEZ3n=pFWmh!L-4MK$l&Wmlv7YD0JDDLazW&l<$ff#kX*ai#gN zI>Sv+hc7ynD#Jz>=e*Zv5`7$%-G0rv)00Q4K!B;9))MjSGp{W!}o?g{Ul#-sv)B5>;hj+YO6IW#&) z#+RE1>dryox;%)7E>P&E2Q}u!j0ny&1{UA-e)4`=uDEmDJo$~?&HYL3cDQ|o;Y_pmW=(EH%LwYy1G#*FDz|GAjJWfXX+W2im@ zm=&cs3DcaL?HpQC$lg!7Sy<&A$6867-5umd!w2t!eJ=;SpIocfZUJ}?cA#tFt23ZC zc7Kp9be(D&_I@E`Ob(wyc0CdZ!-f;ICn;R+jN(q~rbo8S%D z>zf8HI=X6#y`Qj7rSG4=jweP>E}>4ACc5=BXRHDQwkuq#p`eIUD(UjO;kvHAtdnAI zDQ}x%D#{^&qwny#IG6c+Fbj&JpGG=P&xx0uNC)4^g;!cvP8uC;D6K(UcH7sito(vcm z)@rDq=X=YNg*Hmh4t-(;|EneI?w(S2@=mmwDdh>n8EUzQE$@sRmk&8K^}B|IE?A7W z_nWa>hK!9wZmoe>G1T&BcvSgLv;FV#R33~U$5@_ilLh^?i^ocs-bI4u?eRWkQ6D@t zPbCaMNs!IHyNFZrut=X`zw4Ulvcg2fwTK4T0D6R)H()P7d!4fUM8qs74p7{Fh16y+ z@1A#5tIo>5G*5++v$1oNNQf7+h4GF1mH5eI(EVl>fILMKOs!H#&0EC5w&3)9Ri@~D z;?Wk?R$F7%-K%3TcVX9yi7j5lXfkDoQJ1~~KoMeyp`^%L-i|5!2P%&tTfyW)kRmj? zLe}9C4Sg=7K*^pVd@Ab@U_(uLDf{v-ORJcw3kv>IdXNvV$l#0`sX*vii#z*jA+#Mk#)c!l5k#m_kq&0YcPV$m}9ulSQboYx6N7JAll4WwoFe*n%w`OVi;Y}+96>;womoJ zcK0_mdN0XNYhDOLdH0~Zgy#My;`@Nrom)xN_h{xt(asaabI9c7cVds8XAQ{TtNc-m zwDF~FW>3@0L;b7r!pFhcFd5K@4v3(-@0g4h1&s(ZlmFY&vm;x{v6TAzPn#IkJFEV0 zVlbgdzUJt`oGTA0|vGS-NEbw(ndi@Gw?e{N`z$l*4N+_KWk!TLDEqi{{@7qzM}aIz1qZznX^m0mJEpq55@kD`i$Gi zZ{Qv9BN7Rm-!T$>#i&MDr2TAvClifp)Dr7 z=Ti$1%}6IZ4Y8c;3W?BK329@pAAauqup^|BcYvbyV=Ntv`0@=fN$P*3pAx*HZyue2 z^xFic4wSNk+w7?1O8$40zbyc{Og{u5%j8 zjPH{NqCi@TzI+n7& z2WaiQ#&5<5^M$Zr-Nl1bXGthL!w{G|;L z(Im`Loc!F72!eE6r}M+LRlyIEQrzes-+1XnfhpH-+W%B~gO~gI#XS&6!8F zl~E2fr^PF=4-?>#Qa&FkHsddS8_W--4by&#O!kMBW=xq+tGzPX8ZvF)vIS^4y;fI{ z2N3AiYtO-e+r^*Y9)|=6$O(1(1MCy#xAyh(Gg-6IdFz^ij38ab(g*Bk`vdH?n~j0C zRMtu4r+$~AZ~PqE#gMvLDu?!0wEm3nJmA*)KvUEx36eUZ@=tY2?$&-#lhas{AEnRA z9I+2OKX2Z_O$F>{q6%eg;(47(IX#mE&^n9Je@{zEaqLa;A96(3iC!C9#Ht(fUY-fT zh+q>HvHI5cV;B*3O&2qw46nYO$xmI89#DonWUr~Q9l}1;5p?Fo4cSpeH-De>6FIvb zs885$_|iVnJesdr@fuqYNzFrVLuQaC#itaQN_Dj>J8pzd2o=)!yq}bBh zsRauF%J@w6qZnzMdH*^oRy)@E;MHUI8_4ssakq2;E(eutN_Z+M9SDKw($V+S77;@1 zK#S(ThHrwo^Ijq{MRF55&2DjEb^4KJGut|DfSUF#$!%n*L~GqXs7*Wy+Yb2YhPm{r$V1Kq}ImtU9>UO9mQU&F= zL$U&fO5BveCh>NkZ&P-}AsQ?G@Kx>B_?+qdaMHbUf=0TebU$YhFJ-l+H6RuLTlZtB z{?a=SH+OcVECos9RW8yv%9l=z=olYM5t5Dv$^=&;OXK=U@z$58zI+%}<^}v=q=97l z)7Z++sNd`SQGAOPrFNN{&vtWQ=%6OeHJBI43r!;o;t(`%*I}%`o3jXmtU;^_5GS8Lg zoWW8z4$+*|?Z%otC3GN1TJibXtl#26o6siM`i1dcdl8U_LcfvXAk z=>sy^syJqKJtK_1f@WTKq)p&LGwHe%*(jg4=GBm0*H{Z%w@THC*o%EA!AsrpDV866 zrm10b^R0qCd{Hp`+3-p-)0#VtPKz3$$|i!9+QAdhZY%fD=&$F&tC>{Pv_wBEVL){pP)@_75D=Sh#Y zpGb19#fzS||7D)BAOEgn*1^1B+LC$CoZH^?J+$xl%tgMUZ}tSU79hD2CX2^of(>88 z_-C9B(8D8!Xsl-QrM@?rg+8g&GPLVULd!G7r&r$Zblgu4 zTs#vFM;6wJT5fuwqjH-GS#wQETJ7rRq9Okqjj8)zd)eah8V$^A9GsCns_+@%JR6~j zUnu5BJ)F7*@sr%cIbQVkAphYz#&%?g9ZXoR3Rk6lDTKA7G{a>c{q@~+ZDtXGUY;OX zhLAI|s^@#MAX&GtDB=7{BwPfQ=JWsFv8Ha&+IKaq<;1vkh;h?k{1f@xk~suaB9*6p z!mMp>sb^OjRg&#oS!H1cJCpI}X$OO5%=Va|97WI%w9wfoj@8u52FP1K@5-4~E6%F$ zO9ZeM&T6P~FF^6*gnLve8$o<*i9lU5JXBdDhMC#K;2pd#>t`dJNk|(fiSlDcgl<2+ zMI-GRVgJJeL~?peJ{%Z~4}gSQU+(01*@A4HPz^iSEhJB??AFfSQpRh0G2D@MNZkc$ z3}eyX=cr5QlWI8q3{4^Ys& z;G9eoB~;gJ?hS)ybzv%B4fx{uJNf2<{rGlOC0F78m|R+K+4j-cmlGSYT6-lrelQCj zTP>K%!feoHJNpCapyO9h6*}8v`>X{0ZpXeO@`VfkLx3I=7iT5A2|W`>#c-4fS`-HvFfe~Ps7NT?H7kl>rs^_in~6ww+yd& zl9MYVb4DP<_;QRbRHPdf4iCM3C5w3(Z^Ig!GY>KtIc?j@3$CqZUuRd9>}OZrUH8xV z0Idjr8_1g`r#ixuUX>`?-5NCa8hMDH@Fe}Cb+zz>aw~%#O>a~}%Z@d;4GlJ4C7dgt zip!lkh2}o6zT5cHbZE!EMtif@ZsX-fb%}1O6PnNDg@1Pfp9PCE)3A;cZ@|O36kwT> zQO{_uTa20AQN?uw2E!CPaZZRHB%`&(K*uYQ(roEz$D!~1;D6C{8kQe1ve0*G>4GuU zN^Y5?MUn?Kd)JoaX0?$ z-Fq01hUFYmd)XVEA>>+u{Imk%Y{`Pd88b{?E$Jo?Cx8H>BDLozu;EmtVU#kdcz~@Ap#EOSU{| zIiQQEmc!j+ANnbwyB<&5Nn&)*mUWL*)JM==o_-^eQtN+h32;-yOH3-F#UHlN; z@ydyEq}snNe)L z0sd0gDa09N)RztY+_4t04=~9PDWOpQ+UK?lCdF+0Fy$pZ}9d-KF3@~ zd#GW^^W7(bqUO2NSCE7g##30thK#NFRr}>4AB*1rv$MEm?nAz_{4ahZ92gq$wiD6$ zDQkNBLoWAS{X~I&{$)qa%oVd-aF;>9ki z>Xa-+XE{Df?{;tx{c>~0gVpo_(4oZ@s*=I5a`2Y}UWj~sQm#htBaMBuE_vaFtmOT6 zE-Cd^ttZK^L8$$=4Wfuf`-+sya_>xng;?@16Hm9a=i?2&~K>(4lsaeM^ERs zt4st3=e4yHw=>0fK&+9nKir(3gKM@KwR*>b4>b24vV?yztGi#s%pC{H035PRbuQ<2 zyK^jYy=1WD*y+&LdF@WYnal9lTZ}95`KNUGlkgY!+!70GlTHd`g#yv+_y zExgM~iCuR)E4dZ{6z?0>tx1QH70EZOjVm@gIv7hmWnlxiSHnU}nrE1~&r^4%gZ;0R zyqp=%1$c!*1qw>Y1oc>z#-N_?I@-Nhxs&dlN#gp5>8gxM8Ms#m=yXsSWhU&B1c7>P zu?Amyv3PzCVijZHjj(yF+_i0uMz$X8lY#Rwjwj)W9|sYgy$zXa65nuk1N)sOO8m`4 zTNfwxTuwRqxp-;zX{!H9qd!$|I>L6FEXfqluN()6vUYRH{w;kw-Z8PRYK)Oa8@mBe zG2Yg2wlskn(*C0fz1-e?{v_#y?%*nttw9f^by6VF{TYBqA zZvLs|qdz8swqH5uBMB>^k$IL$t(q0`f)d+#VQwtUnfrF@C)OLupauzfjsrB0@e z<#scT4+Rz~+BhbSiykkMMiZ)bgkZe8<~!9x4r~7ee*2I3_GtYJ-A>lht7XmV_-=9x z;j4RS3D2+pD;Z1aq<;akHq4(Y5qu;$*Xb-hBpw$(>55zVaUvfXip`wxs1HzH-&+ zJe?4O4RFaB)L)+URsVe~Vt;+1!%Dwc#aOdzlvN1G$D4cc?>o2v$TO;{vO{%c^MAst z5#}IQC%cM_ImM`WOEIq3b2r~x zTt=>tBq-K{W!MvHeZGo1=nw<+GX`ZN8Y^I0*qe3JIt(61I80ATBF1ZlEALMR8h*w> zh7Pe)Z&}u-y%FfYSdA*)ZQ5(hl~XaI34UB*esV?L_0tod*_)XhT)XaoMvL3ftV$>F zQcy$)cP$WYxRq*XHCerIc`_;@JJCLib1*P{Qt-Q?)DT>od{%O}Mrp|^+E#qm=gIEy zj5(i!CjwlCwwXS?Z?icH>IaEDNtyRl8%`99*FDC_=f=5QQO)3LI)T#vR(s9(GcG2 zu=r4TTyFkFWuH@5V>A!Gkug0MO5E>hp1Mg8teJRoDi#%n^Xy=@OlYlu$kDNjDOVN; zg&^ZoNzL+}WzE(+AA+en#Om${8X#sw&O^;H8~u4cw}Je=bC$;)lID*Kj&qAC1FrjE zR(oJlcwA^s!6iq|tS1CF)N@0GwdT>&5J@mAR|u}I=OC!Bt<`3z4Q%y^zb(Iq#F57P zXgmwKs+j|fQqc`iSG7)iRIMuLc`^u2zY-6VDx|u%0>$LQE=_Y|!rvtJL^lS|=dC`* zV~CFecZshlSH86W37MqI7XIR?!{1oK@F6mNKPnM!!`(5;{W!OHxWUa(wJb^bX#bdu zO>((eBXO$m#oIl@asOe--RxolIQ8Q7ZJN&!(Z>!jni@z-sMT@c1@mr%o$%7#ZZfXA z2cQ=GAKH*Ftl%m%HVX86HIp*v>MIt^W)g?VXYrg*nL>ZbBYLJPTCiEVEE%Q-z6l(D zB?tumw5sbH8AxJ@f(6Amm(ZpaT3S-D>O!UQnW4mPBgaToqFGbi7`0`=bzC)>&R z$Ck{r_a9WtlFkakP<@N^rY5#*4tStVD+D)`2De2#dP6>pp3QmE;T#q;@xo9vzBB-2 z%_N;WI{l>%ZV-l5AeN&WZU#+)O6yUNPqa?)L}1N>WM1BgYyfPS zq)kOWu7eem{1h`~=D~?)HQL+`*=BN$;18wALEc4hRn@ohT5!xyIm(c(r>D=AW7-GG6>BhA z!H}r1ZNKKWa&Y0l{{?mhho7tomzA{QJDr(jajgv*Ka6=m(|&jp%KMEn0o$|3a^_6+ zsE8s`k62o5+xI+FUftW^(SQL$u9x+;O3qn2?0W>s&t}`X)mlkTuPjg#zPP)O=X*w0GQxgnz0JFLZVrbt z^|l*U+Ofk=199#>xZ_yqcF_@&+FezX+h|=F8RRcz}|_o8`TEPf#g~*S3vFP?dQM zk6|7Y_3(%z>fz3DYCk`@hHn0xHlA>Cs*&0QWxK#v!Tb8uAvQ_Xw;D}H6}8xWi&XCJ z@u;fnK(qT^E$BKu#Fu; zg>yy@Y5T(&1?w{zRb-3SE0F|-M`UF)2ZM7~y<3)4g-S9;*p>Ghi)f(i9~OHneZ-(v zDL+mgqyXmksnO|tfWV5pN)9H>C=pAlGb-tZ-_k-y5y5)hW=JUfQ`e$6&TCJ5wqC`} z2+f-^@iGa({-~?e{|+&jVd;Hn{xPhN4va5TE4$|DPRZqX5wWOF2L~>TVe*B3&>U!1 zZ-UlkZ)B4deLR3f=33XBbCjwdyC{8fkYy{23WB7YyVy+@^XUoD9Uf_IIrnt)GSUUx z%7suq9;DOcVnVxop}*9mzRbCHo;SJha=SEYK-9%Vb}4dI57c>RL!iz5z$G6oKy^s{ zm{*V)?F;?0F<-CuokxArvA;3D!uPD3I195ohA3tZ5Nbrty=z9R=7WTD0Wye;IDg#+ z*z#{1Z|^k&mPV`Z7Kc>z+S8p8mC@R0;UMZ}iMBV`!I}9uC$#$))3Y z4dm%$vJZP$m2*_eEG2Fk3QV^Sg!HK`N0f}$c4Al$+NxY6ELo8|2;P5-5;YC{!<;&J zoDE^f6JZl_B94aD4$7Ulu-CHa35sHme1w!!DQw?Jlk0*vWKX30$-2*SHb3Uk+leb= zyTEo5U@kGRN0hbU>`mco_CZT{N%rzVHGW-GU*;x0h_=~Eb&bu-nPmEY}U z&EQH;&F7pK&4adW^v~FSiq%=3g~o3~ImBe31ANzKh8a7{se|Wi5T`-D^9w|ekB)7q z_b&Yn^7i`|fZGO7@+LVwl>6KEm5MBaj5qymxDi`@N--5H^5##_Spj?L?jW_ltM-zv zB2t7En-sfhCYA-G8-}3?p2?JX9jF;91OYJ~s2FC^Nq>W#8e8q>lYcmadh#Y9`!ec(}Sf?e_*C?M~leV$!DZ0R_V?F?^(1%6B~2cV5yrQdiJDG z#C#U@e$_nuz#c=eQGCT5=K8;UCYry8mY#BAIGzsBoUGz*O`n?oHHVt|Uvc}%AHYz1 zm~kj~mgeWpA;J>4==i)5&M6mzv)ap_aMyLTKIIXb)!fJXyBf$ake_Nwl22Bd8|fp{ z%Z~kiXn*gie--?1;MqXjE}&QcZmyb{gmiz$-!t~zx7`k@J3qX(f3a_G)VtG1qjy$4 zy9`wGe>#2i_XW$n|Cy3#v~nDlg(9J#0#pF$&rwima2s8db^C&2izOf5(IMUJ^t{ms zLN#%gxTTM+V`(|}Ja>y?`f0dpmsd;5t)7jzD{|aZfUw2qLcSIOVU$biT zQh|b!Crl##gt_~%^9!Eno{jhHtpZ4`!6FoMw_QX$!eF7-KTB zM+^F?lM%3-aot0pPGtfj&?SglUobPR_mHxSCA?$WxLq(MBc6CZwX`Rje+*#uC8n)4 zuHg>Hlbi8XwKuc?LqHRfVa(aZqNAHWVhu5%DJ1v2rshM~22e`RmD%W7&(%$e))aBI zQ2<;b|L{+Dju{KT34NhyFu~VeorlL&Uu>oJJBC@oL3;gj2&So_VZ)t0xGd_{hSERgy%055F`z=heO`yDg?fv9V*1Z6?K^M3Cj@t$D``18z{t;%Z zC5xbfovfzeP(=mZf#|E_BviXY4&QJY%suY`LY_61P+)LmS*|iq2R-~)`&;KE|3P7$ zm=63_(QUC{uiJe$cC|@6xyPi=&F`XcVGjc`I7xGR8fP1dyld|;Lzep9KitsVEAlNe zZ=iIeTibh}c~+^?G)(ouWPqZyBhZzNE}x7qGiq#t#zW(=_rs3`o(CyApuyGq1;?I) zmD_kJrO$TZKY1LCzm07T4I`MxkROHI1EJ1bBQ9 zUBxa0#B}ISG?uaZ6jHv@WTL5wvDO?ABSp4~{0r$GDcIzmPHr!uM=vUgr`b9gS5Dv_ zAL*yrD6Zq*G$M7}4;h{FXS8!oftnimiMy$^WSu{y7W>{M0p?6r{8U1q-q6=%X7419-1X-K*Ma$B0$MGbaJE&&Z zD=l1{4+QEHh_gIh(T260ptNj^O5 zL*t(4kCt`_LRoYf<4@`Xi2aYVvG_NA^_i-Oy@B(Z`WHu`1CKJ9o};4xyb{YUINo6A zv6mbf-ucn&ohYqz3yEJ*sw`!k@Rn4@k}MqEfQKn_`PNF`Ya<~(m|f!gv9Pej&8e33 zs@NZpqVBhDjnJ7Fzu>)Q;%Vws-ir>Gh?5+g2Jg>Iyg*BYbD>EzZT+?AH2lpMhd?Bt zB;GFhQ=YQ&dVH`lPTo;Dq4ZiB5*J`2>;5C_oo|GdVBdFyUM(}c?gQ2rx)spRMoBpy zL`!nuQ3<+bc&SxGU7Koh(s<_$qlR=Nr$^x`qUS(%%8y-{ zYui^?KLBZ!LW}hF5B~@O^AE%Xi;+O1GjsU{rn!4hur)g7@x|7ug|So8nBNb#?tfP# zlbz$G7FgI;2vW-@qfc#U9?5z5JGZ-N_$$iQUc*h& zBo#`W(T%)ZPL#YJNA*x@{vq(-Zz~Tc(?+I(L;(>-z<>MB)qE_{*JAx3KQuNZTXLUL z^C**Wsh>SYrX*6{Kg4;7^39VI0hkf$=zQ!=q%ekf_&Jr~U}wuJ{*D-3xozBI*mhL3 zwrjLMoSLt#c=u8dd1Da0U~Mc;1tI9S-3ftIvT4S;zW1LAiNZFVAI1e72U(Rdn}Jeq zb?wYRVeSmcdS7Tkn3E~+_sYu{X)tu(LC<%$cfISlXP-EGB*zh8N|boFdUX12=KRli z8~Lz>;J0JN6{i9e^LyEp_rT|GOaGD6p;38up{bm49h32C3$w?^tAB^pxs^6l1_V}e_A^QWE)|)x4VY&f80@Rgqb34Rwr~aw<$KFXaCV27V&=T66{i`i?_@uIeC$cBn zi2)X1d#H;|2;x^r1BLN&Vj2YE+b>UBDQSjDkb?;G4(wpu&LMfT?0ssknb{|imW`mT9r%?gcoUy zg(DHsB|}!yy*1e{eCIGr-5FWdDZteNVs4-U+V}YFK;XB zwzxwhtrQ_k=4w>$ywM!qNeBJGDJf^t^S+mSx3Ul@eV3q%p|1iO1dbuF^|8n675sbK ziPSbo!@mTRsKp<7X|s zbpo5;$4_CXjhF_s4R!jI@pc5T+^AYvpz%1yjdq%Ktg5MF)zcnENzT|VnOHz`)nC`t zYw*n)jD@C3o)+yy%x1S+I-Fg9ry=5bxknk#2Db_(HG{9so*EO9+jbSTqa(Xjzi_;q z&SH}0;|{(`5jSjS)u0rh?Lj4OMsmUQocYsU?=H?f>fpz;6YaaoDms+EqvGc^`^otl z$Fn|{C2e2en50^>rzeL@uB4FadAHP|%E8Lq7q%>zKQqQc)+F`7%nfz4NTY?@q|xFF zQtma@rWmI9Blj8?2W3Oh2Y+j&mHrcwRaEc8+@n3yGP9>oh4yUsh_&49 zLAT4E<-V}a89Xy47?hql`P~HKxIr`HWZT}q!;6V3Jd#BDxZ4t1&(J$FME0M(OD$vxAjJ_Aed zD{O3rae>9WX=C`ks{m^+3Tpg8M{qnlvZXWGnKd<0nK7+7HpfxTdoY;MqDNvVTyD5AST}-$b)&g$$+Gn^Tq&C zh09WTj1|wAS>ageIsTRChjBn3xcX8n;5of$?D3^S^X<4QlI?8^W^`%^mAl(~n7@|q z*D-PH-&;O`%{VlRXuu06uyZhoT4HLF%5mDrz*gt)k_?b9{QbjfuPj8`5$!SBPoBLq zR{06^?*u>2;eQREHlK{k-IA2X+#O?bN$>>iGQ7jQ0-1ZHp#`8NLWWPr(3^`>V0ri5 ze)MABN0BTr{=oURu(opPpxN6toS?mT>}yIf78lbkFLgixmmt&^H4Wwg;@%cHYw}VW zi0@!`fKN*mdjSH*<5QvG9F3nx2w#=p5dvlFFJj+h7|d7%MOO-q*n`gnN*apB6dFXS z|8>^zra{;P4(0$~WI6A?f`iUzz8&?S6 zq4?{3%%AdjcD^e_{(~@`qYW-%uZ-5)y`g;AEwqA#SMT@s@wQpPE>%iRpniIjog4|8 zF5Fs7WxY~-LT%vxm@uE=$|+;{J(SPE**V=FkO8Y;hZgqnT0nUbKgEY+JERQkvHKL^ z#Q1z92GWmtaO`e&4Y$bYpGPYDG0yw7b;Apa`VF|j4 zN3^Tpx>8EEA?!j8F&`!_jI)F5n}=-MCKrCg26XjzEQV*l#z8P2a_S?1YYMJfz1%i5 zi5Hio&qvy%bN)1jXIJT;bT#1eL^EDJ!YLuoRS4NjYrIj-yt5evC3hik-6nS?UQTqs zQm1~sy&zvk&F0lh7D#wdtE2d&94V|>8J=H~3a(xB2AFTU`!LKiIl#(cy{#v#2fiAu zmt~g8ewf!0wS80UF!vDJt_VEq>t{7eaX|A7p)3?<*Q4GnSfxmY_)+Wj{DqB>r5^Q! zs7+H)C5}Yp{A83hdkl<4(_ftzxw3ga7&o~k29@{gI9`Zj=~y~A z;B+SehXmG+Ko@qmmuFTHC$7L>N`>X+R!_R0r>OVCZ>=jhs8xbGA2f!H_=xLLFiwSnA#!CHqB(OAL&`U15>%jkY|m!g7e$VD&tS}8kU3u zUIV_J1NE7@;*}r7ln>tJZ=9?ilw{_g827Of(?{EbLg3urPNlzTlRU*a%*$u5)$4wU zDJhrCZT_O^{=tu#Qi*8|<({s)Z~PI!B`BK$xiJp+LL@I~+}W-%pB(kPG%{(rbGlZH zB&S7`DBBzzQG3OH*YWq!(D$9Qng3gdldD}o6QD#a5%9i3F8G@@uN)i&`A^S%2-p5bfjL*-p5nxn5t5SGN z(nvuW@Mr^%H~)?vqVUv#Bzl7jY`fiSLhva;QD56&>DM+d#MGMn36>i@2mY5ZhkzB( zGJpwMa}+5B`&npjIiEbM{HHAZAldE?-rW@%__u@^U4~s0e`b9(#fqm=ppyn*$E2&1 z#;ppaOU=mxN(Aig2TS5w+)l4yZ|sIbD_Ciw5;m3h+dbhyND?rZWD^RS7R zGPe&C;nDHthp7G(CT1J}TL$Q7RJ?x}PsVRJ@LX9N zaw$(CU%)KNd~bSu%nu`GwlsPrrFa}K81m0|12(3YdbjfX?2-Vag6~{1)??-Frej{s z@-e7{BWM!jHAORWW@yarT@T-FDX(gWo zYf?_eqPwYVW3ta2Lxo!E*-c3VK}BxOy5m;GAK{QgP61?OL_cdHiF72r*U#6)7n|+~ zu_~H;H;^Tp=M-BP?}20W3rBkf&9B&*(Ejo~<7L@jnfXwj7Iy(Ri(OwhT25g*H7CU* zupX~g==uXPx6}{1=^;V~`Kx;cSyw8~e$0+aJ`FNT9x3T*`^uPWtJ`8e9|h$(q`o(` zqWnLS&NM8^w2#~GOw;(3rBjx>FioW`=2|K)@XR>nG@4FXDI>0^RGNwmDkAVSWn?al zSt_|O<&>GbRPK@~lA=(#ucRoHD1-Z-oa8Th)RK>$L1l6amWP}IEgjiasa3ASe(_ITXi z(I)TmNVp}k0GKxPHi`6jNX^1A9|Y1{JrJXqkH;ea#QQl*!}x38wX1UB`%va$6N!^{ zmy*F%P2w4t<@Bv>oc$>HNZ9WWOoCunW>-kRctIvTEnlv)(NS{{?HzfO<~(-sGdq{n zyI(M#n6<4CBG`%4Umko)Gzxm2o%Ya-L$3s^b#p&$WWIWUL)Jclt`1qz>1RU@dQb{b!KiwGuDdcjYvxM1@MnM+3`(45_2Y+Oi;A;?C~je}7xp9$0FiQBnGv~A+>I~Ob~b9(rO$9^Vgo?D`+ zM%k#JcU!mgJtX$%nRMuFb`*?JvUNwnV?6y5M$S7IG#;Sk;AmZYfqxXe~|C=NJUoU|DzDF8H`t`Kyd%oD}1dtvajH!c7` zU=QtcEnc$Lw`?5zRMjWkSK|5B05yRsJSc#izZhhFcV2yZnOguHZ2aIFJpVsz-ei;w zDh#)Zzr8u}(ABVrcHL^m-M34aUS>&$YQ`b|k$Lfm4HufgCOBf}yL7vq65Uu274Z5^ znoR4J$KI^+9ihbm!PotyxOl%oyhgEo_zK@aI0vL*lH*lEd$0TbI<$_5DSQkN1L%C zBW?$?3l>12Mr2(rkH|Z2o1D8}5uBpSdMIUnZXU2-M@ew=!mo4K)Mhi~CTEY)O!UKp zf?{>J$eGg>!v}U|`+X9dyZ!?6$pkOCfvm0kSqViyUV0Lr(-~+bFToe#m^QrYp3=d) zYF|a!(K;u#oxbPLLn2$!2twaHSuN7|RSPWY_vG!z_UVE$D zJ}>-sk?kE1&}e-vlc>l#2gOgqJ7+-|wDf_v0y8uPAmzTB%V4w_d)mW3c3hz$uwlhf zH{nkaG}Yhg;LX3JFH+%q>NA38dn+gRC7xn>%J;~Jp%Lpph$2fHDdvU{$k$(xD%raSW8gaap)lP)o4qp87=00AB$}#(EkUK0!?ukTonOo} zRIevt!p*kZSM4&wK(-k_TK%*Yqn_{jDr8|JXazhTJW{@LTj_<3KHVV^ErX&2Y4Oe- z+*Qge{Bpmvd1uq4GWP;qK31%B#_LK&TgdsEX>5_ zwGK@9t{4@pIQ5(mKq9g#;Y-E4#TI6i3Rqi0*CZ?s^}=ETg zPbTt@NG}KlV|5s5iqGRl#i)m+lqkZmLi2t;?LWKv%Sglu$mcQCSLwc&X}8`QuezgT zYtA3T9(vxO_};woON7P@|0(|&t6%52_q2UrGuf<2M)!IA^)$t8?}Jv!d7sDTsZKtR zjjJgsU_AXsO8s?rzx%m&H)a9@8f-%rPt?QMhblv`h6aM70_7Ym3~(W z;aba9fK#o@Zaeu&3oSwuBLwoHwDLJu`lYKL#OhIZVw3Z+bxlKF3b*_M*GkjQH=Fo} z=<`nk+-spEgkIJ65f@)ZBx_+RMFDNN5zh8PUVn=if~3#j4C_)DmaF# zsjALVde%>KtE&~;t(oe&%RW+f)=c!uXc*vO2pEqGce1O9%VqsIPN=IVj6$=8U3IjU z7e@{2NZw^Mi3V`<^bJXZVJ4)Au)N^W#CbBODDAV)^7mmez#+-RLa|j}7~fMj(NP+6 z8!n(Cv#c(M8xiZ-TIZpZPb?6Sd}n`pskn(25FeKVtt$5kq$41cIXDJ!bO0GPu&x?F zdOqFiphje0wI;=Sj=`gEK1eFVS`+Jl?*E%Kn>UOKa|+~4(QV%G0x;fB`YuoUlSg*Z zZCZ#U=y(mi&p2puw}u$gkyIwVr<8hC;2n#cY}ew2zu@W4O30x4`WNiH@?9wg zw2`a2M%%32>@|DU^46}}vcoRJ>w5WkhzTDN!6uNk@gQ_Qygd5GiNaQUL3n3>PUGmC;RpSGUvJC0lGZ)?m@wNHSc4`k>gNiQ%hQp?D0>hGQhrw z-8`1N{k1FgGoL!1S%Vt-32Kh4HHkD5>tk7l4m-KG-dXz-x6zrKt(r1{EbO(J`$(Yd zxJ->LgOo?*XIaopE)_?WnZ@QbcNeB*hvq^4qp{&+_m!enNF80&#jl-bqRS5!x?u}s zkB<$>xYgVkvEwmh@hv&6c9xyg(~ zMS8?Nv)E!(`RT&6ds&BRse1)`Tqh#P*A>NBFKm$PPC(-!@oZ0PgtlBT42|_c1Uyup zD0jBJE0i22HYzjmY;U#Q@WQN`?St^|2Tou9CVc*?&qN72MEj2Gmgol!?gVn!_WrQm z)|Ot;7T_27^>?6=lU9r|Q=wm<79hgYS_p!f8hNAgKk}V2r^~W7!ary?_AbmIMtfe2 zqyqT?i@yHifR1iELru}<#QaBJSng-QI2TvmX_iQ zHlh99HI+KCkY)26<~q4^oc2%G0zin=mf{A&XaRz0PZ%xAYhkkTcNiZci?eqc`j$PV z^a}NAVU;SVs5Gmjo1v@vvN0nu>8ZS9M7=;?=l?vXv25b>VOC(-s7Y64Gi09$=Q6LT zAKBee>OP)Pmm0iRXxL6`{8LSJ|7jc$JoP?OEaTR`1Gpot7*f~xtS&vzsr$)kejL{d zn^)ZNu4N|ZBuLLPS^k3(thDS5CiT&(VF4f`i^?@mwdE8|vW01nro8~C-_Y!K^aXBI z%O)zuTVhh|zuLDW8<)LSSG~FL&qn`M9CbL_VT zX#9YV{5FmB3S`%?$@!vw)rUiEl*aLRW>DepV0CF)krE7SM;d8u$OO=bONpsJu!zVh7D*lzRPgjZlIamXTS0cAT7jUO=#u=C7Zk| zR&|f${PQ5wBDhoxUIAC0Sz8zaCipe<*Q;mqqa$tiFkBDV0jZPJ7HafGhc`OWi?7xaI3EsfN<3f#S+2p0f9>}#M-wli%C473QMMUSA%RedKFya)S+I2i z0Cr7%Uys9MX{W^PjTzKv@+C#<&>p?gG}4CVx6R~xSDzO1cNoKCGIx(n?jEnLOgEA> z;)i7wg^J-7C%SIy%4<)SCuc%$B>$|-L=vy@tj4UJno*40>eYVwIJ9bS0*_uXj#3Ue za6Ns2&fJYJnCOxE?*d`s_9vU(gIT^_u*4?@s+ zYbL(tPUS-1yeEAs6~5Rt-Of3LuS>*aT-|_R*@3ASh2uC{Yl&y?xmafZO<*sf z7I6^+MCrt~#j5aJWSz6(M8sx=tLwHSVW>R}IR?6xV zYCxkBQbt|dZ?L>@$Jnb_wYfwJpYTv4tHB*nQ>@~Sgk4Kszi&&%hNkE zVAsNnfkJ(PGw|b`3A$v{HxcpYbvs6Pi|5d7bamoM@c3MG#_H4QkLQ&@-wz{@{u zl^v_c=LLW4ZNoZrn-9mYy{;Te?8tq!Inh4Qg3$em<1Lhu`ZH$Q$7E!7__+PXIgQ&i zo%2xmQ8~!k!m7|(S5>3hM@a7R!lqRdU4PHnSu>mbemroFmq>pm=xY^4os_yrWU1jf zPVqBH$K?UZ&%nztb;V$(NyVcU_fFH%Ub47S$0}uvM2#4agBRVAKp{+Ir~!AGE(NFe zMqP}YKcC%Y=O7`SICECH>NVy$leQIgU$`(6b#W&&#_@U6ml5W(ekTvGJ`Wb2qpC^j zH7aen0QGC=UVkvp;|;N`vk}P56JxC$wn~EK{tw&pEzmPr1g4Y? zTw5QoAur%JazI+AbNAQ7woa_Q*@Mu~E=0sl@06DHUAQJ@Rt#5$!+r;jSSb*o?#Tv| z7N~2B2MXcQxi*uF?jAW_zU6-CUaP*bA@+UT2d+z<8+RAQnS17){7hIG)1v0Kdg9|E zW`ufF;l@3{&Vj~Q_Dx3IeGgw|yH)qC()W+Ge$V*MIlX=j`NCFcr%6$}#};y9hJRZyd@E?2{Vt_jZ>{{I4tp6MIqyevCtO^v-xE*54L zJ#%Hn$miF9Oz!}ij~4CkB$k3h;$wf)v z8mT#$F@JZ8YtM`*&Z-WT6K6u5!*-(s z$7)oihwDtlO&Rz%J%b716fjpRYqSp*>gCEZzbGwpdNK|BDc*&x>yew8il^@V)y)6D zQvP^@Vp?>rul_PgAh#!tYy^=RaaS`^fZ;*W^OBf0+U^v917Mmui;Kv~O5L0p%Cesdie=Ji z_gpEY-@WGc6BB=gjr+utwb$h)K~&_;ZL2J39FHj~O>5?of~qJj9QOdnCj?5Z{cT18 zAop^t?Cfzu(p<|G`&gwYpz4DRPcEO>&n0xbr`>DZAC3yW4({5go&ANlK(NBj7n`k0 z<5u*CZP7O_8QgrtD;n|5i16+#j-(wQ9~hS_f_nWjE`?1QI=-66Do%+Oj4PDSrpE!t zL&OaWTg+SYfJAf3=fq$=6Ss)Wv&uwF#~y9iL(G>L^_zV~)TNIh%Y%r3IpD|X3lNMz z0m*OOF@0W|>zkn>OA@Q4H2Ut@SolVr=0jo}dt(6_vM@n;nQhoWyuJYmU-hH2y#Xi; zvJU;JYe+PRnbclUqL$b9bK7YlU>oYZr3{covx1j)0Im6w>J@aEcZw;thquFl=(1JG?Gc^1ggJepp zApNdajbB?FV2qY@e!4QEy|zL8{Qk-U0qV2rVJ`12v0QsionjbwfpI5)ZSTStRGh!y zIYl}-AX^{GJ9Eh(G15{z^MPPFqq?$B*QT7Dw#;o>;fb$Y6pXD>&TQxJll*b=Ii2PJ z4w3+H)Dm5{PsOe{!(kep;<+4WD@toZ^T1lr12pV=$(#2_SR?vF-1pgoT&jtPwRTul z3yfyNFek4)Y)1d28~vh&tLQ3m#d&h>gNpM!`Era;MLxhx@Tut48~va%2G^#SNHQ^X|JE zm2TYMDvrpzI=1Azwf-Imf8rh#7trWn1ZrH~8n>v7#CBbto6-+=gf;{Ide8Q?7z%_# zxI~zUnIiax7u0VYD#;rW-iZ*H!L#!=@yV@F=_cuw_hJm+wGPrV^Pt5;lUs(vNnp~X1QPhE?ttLo++9`=PD z`bCV6VWrKhkTKFCi<&`QHUq|Y{-?$puT9SP1uR)VyL zSWO{m+42r@9IhwS>s$I7k68TDJ};r0CLZ6K$;Jq~phgQ{kr$@8wfu^56vM&LCgoFl z4&)5u1!(m|A=9G5Z5STq&z?{T0Vufvoj>=ZcQ~q1YHbwavX=p z%TW^QkwD7(41PtjFQD;AxsHta!H&L9)i_{m5l^oRm(s@iYrSx?5yt4W+^VnsKRjW} z_sdy^$!`x-fZbAETfYA_smx5X=GyW7u_j!F{^J)47tBm-{`)Td$5Z>~)w@i7-jAkX z?aI+Vj*LOEGJQ{eDK7-^-MNfG8TQw95$pKk>q;^)swz z!B!nNJ=NvN9GPigj`*48*LrS?tXN1?IvIp-Z{w6=e(SMjYDks{Uwm>hXty^G| zpLc7_<1x8juOKUAM!@xQa5`vvh(h@HCbd(&{rsc-+A^Tt_G{R8*tCT(lb;VJ@IpY~ zap(ycXLfuGY{&@0{5TRV)e7bX+wAZ3m6G0WKfh))R|L9-cm=AfE5+X;T0$>)!9Ei{ z{Y8j$$NzY7Va;fX%MWP#ewpaB6_&LLAvUGgdgwt!C@tVVLd~gK74hm`z$K!-k26{4 zr_cZSY;XprlCEzqzYa9{q`b=CS4-yWTtG#%`UJnu*B!RDa3!jvF6=Rw6{8+pDylNn ztA9t)1c}BK>Ck!4B>4qw^p;$OR_|6dZk@qy)?nn;*!jhf(M)|^HJHU-Yl3ApPn%d% zmv*u0z$CJwdPE&69`EXPqR{({;*+UXbxmArAJ{Gi>2EP?Z6^9pucvT^p9YSrM+e70 z8>hTs=uO*mFdG$LByTuFl%XECIB=5xQo&XOx>tV?i20<#BWtdf)ieP+U8?R50h!59 z0wbpd>Sx-%+2~}CEyj+qgJGR-M8D6(mRl80ps*epAT-e}wxp2)Pi>L>Dw;3|*JXLb z{I`15+kl%z%N8{v4{i)$?WEA91z+$*eM`simYCj8Mt$lk;YlOU*C$h9*DXO?Iq2f3 z1q|naXrYYzd|P%#KYJUHJYSknt;laXmwNz&LHeBWkreq)#}bT&nL}-?m8xRIyY5 z<@?c`g+Rr#hz>v?zj(z0_JTfWP|`=+e6+2BJXpw(s%F-m;!YTDZ36r;wYcbuKAu|SyS zwxBEYD|+8yKIiCH%s6b#2s6)Tj+TU(?#>Ntnan)Dr4Oy|wafW^%Fr*=bT{Av$b4Vi zIvr-pBpPY!vea^mIgX~Zty4P_MUi_TOb^RLVs38}KyWPm(KqRa2-DHYwgR-A2T6;( z-!`Ql=(Njeo1!c84K0RE&KNO9DLYb%1vk_WX)IvX|A2Q}XVTq*KxT{n-HyzB+-RQH z`8MS7Hai9nsUt0A;}V;2bT+O}Op3fX92S}FVH+3l&kM}MbD$_PU<~QoV*~nLH(Y*v zrIn;Qu#l%5g^S+L;enO_6zNsj!#yx?6M4Cq_(I;m9sB$RU)eYRm$wTjHFBS3PFPhV zb(8+gckH%A1#b~HIxp}ui2xDI1rO9!B0nh)ZECt({E~Syndb`&Y#q9t3ThmgKsei> z2U=NvRg;5R(0yj*V1a{>;!{s)hZD!?e$HF~dE}J-%F|v0<}r2dwA{?PV$l2)o#s(*XXFymjqe;woNGU9ncQ9YCC_EuU3@UQ12x}#<`zP+90sd+TsfM#xg(2l%B?TA|ms8T@&E> zh^Id$N$kgT0et$=u#IY>pJr%NhuQ$X;X-TrjNr(iELCkc7r9m4rBzjCz>#n~hT8_; zXhs7gL@cK4rUNKjB{{>qVhhFHjJl|=lpH@}mB$_7EdT8IYsS#{CD)^8q+WbKOWk3R%w#^@i9hNL_{1r7aD*0_H1M#s} z9;T;*uTRd2KF>3caMx;r)jMMA4H=Bza(*r46a$;2itO{=h>RQ@vzGO{-Z&^I=W${% z>2he=O4gcSs#Fb38%=Czu^MrG1NWT43tC!RM=!f{9Puan?aaAXno-^p31HTT3BZ-2d9I_J~3s52!w1hz=g;5iY2z#s2j z0i6dYG`{|dZAtIjCY($xoLG{c#u1Kh!S<-oNjF51TiGKwvV^|}*>BDL51TZHw(XD&mUq0m%Dm8y8}@~`+SpB>e8a`A~UN=8|itu*UP0vd4caJZ;Be>?;`s- zx4oyH&qEt~Z(SE=9hJHi9DpX2f9Gsdj?2V0_W!9kA!y;%LMN1Y#QYVK!rC3?|bamC?Llx!Nhti9B27;=?O)`P|&I1Vg`aVv8tP-yac^@b4CUw}4n z<2q*N%ue7?_fEwIqsn&|PDDRA;o>HP;F1fy#7S?5?_W6?RccgO>OBUPY@t`paUsGn zlhw+!*G{aO#+Q)@m%5h$H5sSNYf^GkjW&s+ns~yHrVq}0;qOlh?3yC;n*7n5?PC6# zvR0%At=Ik%il}emNMETiYIimFGp$N;u5+$9VpAxH%!SmgJhKlX#aN1+5@%HPxi(Oy zar4B|RRcHIixf>5ErwuqqOE#?+N zRU&m$rpm|)QnBj`37l)#$=LEGS!-*%`a+_@N;|_y=z`FMhQ|cQwjqun)3_&hu*+JQ?7?a{u?3>C%`P zqgvjWhI+GdRUs4rb?aF4H;#hTXQfIkKjCR_z?hkOKVut1UuWQpg5BIRq zV<7vial#+y`>2A$dBIC|B85l0WZ~H!RpSs)H04B^3U{r}BT8}TeI60Be#z246CXfB zGrw@9)e${2vpY7#aLq3%FwS=(M*-#%)KA z9(}X>&mUMb{f>xYv48ASkAkw*z5B3t|NhUl?WZSxFuiZ_&FS;|Fg8d2YyxcZf0nB| z8Eg#^I@iHDDw=^%4v~`1S>DFr&sSi0Ks5GjVwAX9s8iTk()iknqZEN z%QGD}Gffal`@W$#4@vL37sq72tY$_EXV;J_g1Eg*qyAe3 zk=L&wH+uw>_^RV=0N(d4$ENmR5$w8Gi`-1!xDJu$77Jy|3+pDUhC=wqy?~YJfkph6 zeIYCKA#u@)zAGa>JfU7&e}|P{uz)tvw?t9lmx1#}^+Z(u^*l{U+WVIJ0f_;}HL&zr zNMa#Xc+7Vtsj#F5Q^Fo34e{;UXrUZB5_TcnL|FpWWemH|o!1UtldQg_RPg9v6^kkW z#X`Eju7pPxV69!2xQC_(o49+8j&3>)^%~A_53zw6vSmr>5?}%{S7Lx_;hN|0DVP!L z511ZlktmLRFbNLv5yxcf$7Axn>>N{2>Q_tXH`fJjia>0`Yjbvd^6lz;FC~2qgPUPy zFkWZ@5jqx?ORu4WLK&0VhJmFLiJ{fygjQH@>S=C}+WR)YT}l3$Y&QpfZW(j)I0A)_ zCw)RIkxKGn=&Z6u6Pcsg(*A{71uMyW12Z*|g+n&0hV1v)I?P5tK;7T(!Z6c>R%i~C zN@kKnJzge~ez}609Io?OO)RtMD{q4RBR8SG4~w~hr?tVN>(25s##I~5f3=N-Rz!qNw7O1`RahF?q z%}e5&{>Z`#&!)6=LtV`R@EM5bP-BDO0JNULb6*ec*OkE^!b>mEQVMpjCXKW?revng zJiOd2Vh24evOp}k6j*ISd$y)>QO_j_3l7}|&V!dmdW^FXk(r@mVq*g56|DwSwmYSD zASqSu&9u3c9QmvdwRWk={?%z%$az`I$B_fuOjmOI|jS1 zG>6+kJ#6Xh-qa3a#~W-4e9M1br@J0D9?*5h>OBFm^g3=-sM_aI@m`3RfBA;5Y)I4} z%ax8-kt^cOV5~n=3StaG4@1e55%*5SPR8bYflw1bVNKbCW1;O4=^%ax*v6-=HKpPu2swC+)I zc5gOc!KiA-&g*`VtvFVaY91xnHTz4%a!3!xE@h zSMv>@7x|tLJtBQXiigFurZhANb~PLx^YBz`>kyW|OuJx+f?c-)keNiDaFP2q5PuiG z`UbUHpxEU*waJAC*wLA-r_{pqf)gNA$-GQKIk;lpOlibJBssd*{4IUKa31M>mqWiL z-L}b8ZebGMOqntp19S)3h$UkWKN5UaS*Q%^jmb3QG=A?d=he6h8P`A>eZUL7)1n5Q z7?P1kIJfo5-D5_M6)_iG7fE3C>wPw^E3P4fJR4O;WSN`%oD6*fn~+Rx?~2ht2JBLu zS6sj)YwXmO5(Pkuj48~L47i#%AGJ#*@!IIGjg^h7+8IOBSuV)Lw7q_-IC|M!7K%iS zs{pnZ%RJk&`@X21^o(Xv^RrU(w)I_tZo>U)BE3KVg#2@T(j~mz1rM#W2zzcl_0Zrn zHjjAKs$!#Z9rHk%P4EX))Oo<(91uZCgVvIC;_&Jayux+uU6`mEX08ko^-FpE-XyZu z>MWy(oPrC{C^4Yo=uOz5(Mu|zzOdZ5xsgNXd{abSbXPXA&)#nQB>GX2h4I6b!|mv= zZ|LsZ1lA;*07wSr?pKpB0p(Q=X6aLS({=`K%eDWiHSx+U^}T=TDYN83`djnk@pR)* z1}FN;neowj0A^b1&67UC(ejU@w3#d^us`-6LPCU3?O1S{U#L>|YxeCI|MKPd(}~=>#o$ z0gC6H(ZF8unjh!|B~&ITd|u>Ict3)shCKXlcPKuUS@$$4q#o=*eC{R1#CsUY1b5XQ zSQ5+gYL9U0`rpMq>^x$C%wFMb`^m*~J63uU6#GDQ9RV{<(EN1y4w=D)C+90dii zL-1Mq>*&V0r~*L3igOi7jVLxLFHjQ{0YwG=gdWTh&5PIGmoJ)D56awtQBDLx{HEWb z+H3zNKwtZlN}0sJ4blBDJ@q-erbJ;nPDK_SzO4u0<-@#OOQU~M?<;`i5)H<*afUJ0 z-i6d(G}jB$mc!QG!7>s>O!U~gq>F;3)X~`sgw+C(C`UIaQZkpf;Opv-3SXU*{#34` z@@l1|9<*vuVoRyM*$%!kiwKYWRAylejxTHRsMbW#>Wd?8Tm=Y|zy5;;M9P|9L_MmC zRsG|Xe4C>38Zpg>L5}kbFkV{H8nFGK=d29#y6mhI?HVj|r|lD0J~DUd`7}8Bh@v&&A&@9 zsqDL}*zxLx66#9=9`UOim_?m0H^^CWNw+hoLQSjm7pLcAlRFhr!bM5Vv~TY?sQ!5n zJ|AMxbrCjP(*~98L=(*jq=7A!zP_T!sJ=k2xo$75q`ovCL8a zScynNPmH&p*5mi+Ee)AHB@z;T*{b#=S!v4uabK^egPC5DWgr2Xwa*6bVyBA~Z8Urm zLCRfQy7%_@ELwyLkCm*T)fJ$`I+Ne)Fj>Gux(x7;m(0(XCsIGoQQ%+~fbw9(kb178 zMgMs9IIiXgy!G{9AG4YKXc@BWIEXh$XYE8%9KhM)MB)d6ZN^mFGA%~1=e_!O(VK6x zJvlo=5H8RR|GAucc%tTXpIUg^D?Ca20)vPtw=$j(9^ykptbHiAzGMH+3b7m@|Lf8+ z7*i+vroHtOp#h7JUMIMTdQLnAn-Mg=R%>uw)0Ua;Zdy(0i}E`AhPS6Lw@7%S-B(>& z2QLA!CID^js6E1UeeWiX?RsLcYR&@oeJuFGF;r`Joz$jlRm)R(4(Ed_85Lchh<5b; zKeaa`{n@SO#z__$-OGsp1?g`hzp$>6X8Q*d|6)8J{Jf-k5UuhNpnyt9QAvC{3?@yHMM&I7`tv@)2BXjWI+V40VoA}4sXBc}H<`Qz+cClcMagRJaGmHGbkzQgNs@h^zI*Zk=Hwn6X+vU&oQFJ&mxV(tc7 z@?W3$S45GNdCH%6L0dZS9#>OB;$NQf)5;G&s@Az7Db4<*gFw`FX`^#*x>br(+tSe{%G2^y zCs;redm%Je*V7vLB}3klm~FPYsy|cjb^le^Ovi5omAYd2LmrQR@7+iDkkZai_uj>7 z%M}j}_vy~V0!!aM%g(}AWmg6ZK6Wzs|M~Z$(O2%F6tpw>yZ8YwXvzW`7BzPYxyGN+ z)Ed%(AVu>+gQvKoaR6$OW3r;#w#4kcxyU?c+%n`u2HDm>qYXWyReR>|rvw`Aq3{i{ zAZ@=)Z@4t7u!;fP&f$V@t7{~CDD2YQG0nUp|8U)zaqueIY|~V@aCVK0??5j}6-#H| zD@#`O$7!Ds4zhp+&!Z}cgNVf`7#Vs~uyjW<#oDK2N*$%)Mm#AvOibC?G@z- z#6p`PE}`i8@m;rDw~diAZ;nw5$fMnxM{$_NJGfxjwQ~Bm-V4dVz6YtG;w!y4ruf@i zj}^{kL7a;<;G*&;U7}sL3%IWm{Dz(#zXluU-<#$J8d}gf$8EGsZD^{)Er_VQ$^?$8 z>zr`^GU8ifPYz$+YLGcmroWPLt7(}*&uH}ei?Gzu5pHHsHLalj63isLQY+ehyK%gl zR)Uq&RcGXwr1Kg}0$tUrJOLE$BCaqlX?7(B!Yb$Lhz9mmv^dFcFt+3ZOmt38^D@26 zt0lVds)=KBl|*aU-`cl^&tYxa19H~4-ili)$od{RX1-!s_^Yo5vDKoYhM(8%9+4iE z(>JclF<+dQg#y$lckH1GvbkN3`6E;#3}ygt(FlA>`ZlB7K}I#Lv;H}aA0DV{73kVj z5c(q`a7!Wfxi3@dNIsewRh7 z5(<}5D@Dr`RX`PNZG0J}bzNq>k9f8|%I!-W<;rF-oV*Ajb^7)=1){>u-4QvV=22)h4#}r>WJyb-rumN8xhIjA@r8ud zPVWWSB%f-gpz;UL+3()X9}E8AKRZaMp>uZEwLys(S)2qJpmrO788ngG=SW0u9=6*Z z8NQy5zxqoY7?sBiDGnz+xSG&d!yvMKy)WYzF0To{j#J?gg2jgP2|!F(#kd@BlFNG= z;K5!xVprgrFRW$qU3@*uUjQXv!H0Lz6wwSm1e=s8m94N>7nzH1pB&(BFKiVm1oOv2 zN;__*Lx?`g-Tm2S;$O3lQ@+I`qQZ1t9+Q=oX;9SNdCu}XSigH<>YgG(O7KLCCc)iw zA@!0W@VI}yIY!2EoCr4veDfgqFYIhWU!t|7y^4$#1b4N&323o!{CMUV6&SrGk8D|X zkvnoNP%8qC)$m~WKQv!kXH38*z1R`Rc*lst#J+E{k1E91i3u|-!r-b);)uXWD2XFM z(i+*-tH0{xfLnq?+w{y z*xXebu@T1)ZsPd*T_gM4>2X3;5TbqrT*s>gHCHN=r)-<{Gl5`ei}L)~aLZ9(;kCgl zPW&m<5?_NpkGNf#p5ffR$VZ^^A)Lmy%wLo-G7!uX_vfbEJ_(MGsP}x~Gx5I8Atg?> zbyK8LqRX6Dl1t`koiMeJtf~KGfD?P&Xq3H^JrnVJ#~TD~5hlPf;C)8?6$$>iXUpqbTIldh&l@Ix z*>oa-Is?{}c5dwQDGQWhf}VThzfi}rSjSbZ>Pe2Cn%fAC_Y6Xa@m*Nd%J#MLKMb@? zqJuL^GfBvID|kOH?afk!AA_ZY#WElsiDkvaCmnWsDy{7~jNijbiM5zF`QuduaY2(d zg5`1@m0006lU{)7F-in>0Gish){#wONk(z|@1cW?9&M7ceX%Dj5Ng}WNx zF#^DjJXYkd>&f2;&7!&|*~)HVjUEPZu< zd_U-f|9s=!!t3=L?}TFNwgUt_x6i+xb^eWG+Xl?7|341%;{C}S%9lqaj z`#InJ$-7wm-}}aDxxI4VM<%s_HT$9t3uWIv`726{SoO$C&AwoYTy}Z#o8Wcbg)2_P z^GE-HZ2j-TFLQ9M;fYMoW^LoX=jYW`PZ|dDsTcl}Ds{udk46XMLXX~W*??{~$mcJ7 za*#f_@XJcFxc+FSCE5SM8{0tL`JE^1ScbQu!o7Ols=7KGL)Bn4XTAG36cpp|qE+?x z%>%@)4iMTQ8lFDW{oDMf0>j%e0^W`^51`7m!W$ecH0nafE*+O zJafA0eb1vmj;PYxR8-)Z8oYH&?!Hgc#hP#6Xl)G1b}T5t?N-lw3Et9RM;+@ryQ z*v(Sgq;A!mlB1E{p~~bi#&s+BYH^Vf?~Gb8v z{M5Bbd0XIt6tEC;W@`_#b^!$ z0&8Bcz(;Rx`1oa-Q((!*7IOpq?^JlnC#o7aFFVkx0IwertDymR`h58zJo?Mim;RvIE4_fPqG#vSXGh%~dZT;bHp#Utpo@Wt*`6aP$OldzNf zpNj)Jeuny80t7Eb{+S?=eGvt1fyIWcblCONWRkr)r}2`&1I#C>AvT=Oacton3Ti-% zI5v2O_zN)~T)wlqbmP;-PYztD(uvsH8hvRi+P8D+;Gh%pYiC3XVG+5UH??w&+mwDt zrOm1H7$Nk-HxvwYfs6OZxIYgb6tgAVbndSMg8RyKD@*|0r+hA>YB+* z_IvIg5AX{}4#_m4?W(S*wJn=<EOHzl*FDD&DMI`5i# z?Mbz*gLap?zfe@>wLAhM7K^5UjdZ=@n?OTFM`>Vv%2xhzG?{KmxbNQj#@Ka2(C?Go zLoiy#JynkSVR*EESJ=@Wcfwa?5-61=p zfMjri?f)g|&Et|v`}gtBOw%}RI%Q?%!qaM{NowVWFq1X5m_Fr{nG2aIl?y7Vs4UYs zX=+MlZmIB;m6Z#rDQ-aKLT-?nJBoseii(KJ&iS4B{{G>Gi09xrH`o1MuJ?6C=2scV zRjO-KJB@`7vdYe*iKt=X;ar{&7nyHg?sN|JmU5q7_veGKJ@GFZ?OJs87phw1Rdh6J zez=Eo#oMKgQtqc)(e)G94{W*s3f{VXXCnPLb%dcif2$7nw_gad$0s-5Ks`#e@TRq2 zDl1ywDjE^!loqY~mH#2DX!csS=g6PbzY?{H9S)-xBN9sor_H-N6{ru+!0lH1++=vM zy^fE-!hjqIUy84ZN?#(TV?NUtB2p@ZBT0FkXPy~#g=gAZI(fp%!?VExcaZ-8p#n^b zw{oPo)}Opx5m2S(PHemM`xY+e`LInP@wVXd9xL>KF9GL7sSIUT8Tc z!IylS|FTDRXi9d5qvLvFeRtG6V(of_SLjzyVy1n0)z{0{Z^Y#{BKP36(P6dS*Mg|0 z^>PgJF^t?PhhV)l26G>zoYA?)l-94prIi46Ai?Y=zhe2Gv;hsl6a++ADiwNC7s=46 za^=Q|YWK?am(Y%c_+0J*c0G#{&A&8{&k*i9eB<^D&@G%&g}h=bDo7hKE2J5m1Hs5t zx^PwoG^_>5Kd>aJbin_`%f&`a-nsIs9o5Vr#0_P=be%sd`?v_*!V4eI9sj5c&EVM< z+P<}K3!NEOW;gon(5Mp|YvrM_lApW_M2}g?;>WBWaYxAq!rNRq8Oyyz?#u^cd2lrK zk5fwgfvCv!y-}5H_$6P_+Ew9l(t3hNSA^PSh404(jkYoAodt@D#-X7dNo$nHQfsMA z_b}xqG^}E|a#r(njXw)rFq3_3{|+rQIPLyk4EkG}cvExYVZcRv!3@n!LM0$c!cetblmv z^BEmVA?crkF68iocWUXf^Is!oA?g2ol3?7e^%~s$9~ACNEbhqP5E4lSWtLSRW<|9w zXWrQ-0TytZbCS9anAF{IM@RLnjM6eG?`xd|YnLJw=^tHLCFkhCR0Qs-3AJY2H6k^@ zxc00M_+J{b|5&_4`lqd=h{A#Gxaot+?>r=0ou3ua1}0CDS-S0+`CZ{_AEPEd2QJx& zTQJ|LW4YUH_X4m8`_|nhAyT{e9?cW_fQDm`)7%xFV9(~Hur^+|Q~Z74CEL)_MdKs< zwx!H0#>(O>5i)iD{E4n%h$$*N%OIHrR`4s^<_uD4ztWddSnVIwcFm0XAU{japuMMb z1ytGK-bydNF*RY{GW|=iE2D#8)qHJcC|McIXIRE*KDm3^i$Pl~mfrzR$t#|_!;a0y zab+4I2wD{p*H%?7{D>@*be}_}Ifg`f6p@bYvg(9wc``W7f{O~`67ZAdwkge*6YHb! znGSWqU~^#qmbF>gBQB)cOE6BmVH;M_-QitkL^C8N$S!S*J)t=*YT13Mi|*@mC4bxL z^6Ppo*$W4RhU0gUB7lb2!9BtrUCSXfp2OI|yvVJH@~wm3f@I4R@%9!I|Q3d~*%l?(+ussMfkb>H$P zk6{+VC3<|xPl8MHcTzki?|!vB$CP1C?i@xvY89DoiyF{LPYkrg6p9uiSCuZ#Y7??8 z2fnv=p|!<-;b#};efL3(rPy;8&9@kg&viorSm4f_snXeLU2?skl7W+(fykb39 zG5=f9r*U3H^LMWhz@G}{g%%C4sFI?60}pu1Jx@daKp=0M%65g}Pd+(S#I(VjoXYRv zW!dk&2+M-){ou-*xqJ5``3JGQ!$j)HtTK1VdQ5?stCaQ6zTaEhETvMr z=6D#zrfE`2O594b3`ZD#2i_jAt^;44hclE|QqZUDcwAEdz@l(n^%E+@q z!+zN~_&D9PF{oC?7+9qDh+DxoRDC%}ZU*P*4a-Zj4&Mv$uJ0 zr}i{AKhZanhKt_PTdk8I{$sBsA=cTM2ykeX1(!MX*2OVd`W{^Ak%-~jU*)!JE2Ic7~eD+*Z8GBbovXj%dm&2vo6#4K!KySLurxtXC`8ON^=1&!2d zd0=mDLb4L{FLPW!E&lJuJe5u?)JS$#7E%2l%NVB%-04~I>en0(_X@VL5*0CYq{C*O zSlz93svy06ulM8|K)8DSBzVuhZ;8Qr$Or3zf zm5FxqG9z=&YVG7i6_=x|Dk}lg!ImC&Rp+5LZNC=g2`>$Qa%yJyPI5^>peA~+`zWB!$;i-ZxWYo+t!m_9@5n>n-yK=M`Ty62S+t2 zzK!30*k95zeLC1UmJX{+Dk+=Ae}dV!6U>zw++gb*y~%;#3PkKpYkVY` z_JMM=4IAVH;pYs{yiyR3;X9M_Vz(YTJm!_jD7oorf@(e z=;38nA|WJ(9*TJ*mWIoXCD~E_tD|qh@HF0?p4!}^no=asiUnWI?}Kse0w#~HHx$#B zz34a!`6M=90iNPf3kTTlQ!a(*-CnmJRb6Q~1TC*@)gAQ#v#kP6Etc|N95D%t%nrB` z->N+un(d`{tx?=rjRyuO@$f+65GrZ1Z#~J}71v=O@S-?(TK)lBfXcg68u=*gF3dXw z_Xj9}UaHR36lheR)^4W+rbozLV7n^29DB(Z-7xT^Ex(q^-APu*?VY|A7oMb_;=REK@TLlGr)JSW>Z zO<$PZY;Eo%+|dwXRXWUTiadX!>7J!|cDD?TGN3k~bIfKPG}( zD5jqVto$8$B=W_s@=EQSS$t(91DsiS+L(LmI)1Ui3$ngsS*}$-;uD5NuuPv@iT;0% zJ*jH(XIpnWu*8rqw;q8sJ(wXLIT{y9F3jvvMM<>XwW?9Hsc=t2m(4nD zK1lfkNN0P<4?k&6C8iR@Ulo(&BnJc#M$EmP46eFDJL8~#fhZ{ogaEavi1lNGg*C2U zWSzNS)f_s**h{B)nz?``<)_${?HkKi>>PdkDaCux-bqQFnF8a0?AX&c?z>R7ObKz% zhi<2uq{DjSGzrq?;po-a&y4#r)4;}Pbp(tsB@)RR;ISdb&m0xlO_| z@u?fzKtA2Fpucs>FDgO{`QAEBe6DBX{-@_j?S*+TQE71Z&2Tr!F;^8r%YFCjn(MTj z;@xbwPhEi@aj$vXzebwJC#us*A`35roU7$+qE%N_6U^qxH8AzgjRtm07o0k^vk*d! zBKOYmdeUWfc-G};YyrO9iZQwN{3v;9=#N!=P}Jkm7Zq@$9)%OE&m~EYO;Or3|K~2JNjs&S267Q$Ma5dU$h4euI1&z_t3|j9euns0u<>3F3E1_ z2q6B0Xx2f9ST^T}&%MUq&X6vFc61FD4o!n0-zA*g-T-$PaX5DW9yDCU{WQJ8$hV!#vO3* zCp;?)a+XKj$!Qc2C-h!1Gw&3BLN!l=F7ETCozCu##4*s#Dmu?s7b#wOie0%i#DG(` z%ebA*d*UUX&g6J>WbBcM{3@S4_1wLkl+MAkMBz=?>EY?mm!WzugH6zure?W8553-^ zBVvzWo`Xz=CSC6*V=F7)W=_O|3xF`I$heT5JGm2MQT5gS`i=khIrnM`h2P37 z^&}8`p=(4z0JjrXe1mTcvK^G9SIqp^VPw98i}ohj)oML}Ljnblt;$aT0x%v)VbKew zPgV`!l{EtgR@V66`d8g8t>LT9JSxMv zVM@_AD|T$p1YIQr^X^4V;c<{h$Jy0J41$1TfaNPwKW+)B?AmpGI4Hq8M6z>~8$_DK zsroVFxl_N|be&*X?Y3uct}2bt%P*J!*(Y=7h-e>jLBJS+{bpK)A?dvxn%I+*2gI(% zyq@ZGDDeqQ5QS7UpKbuhxQ3up@iB_XTtiE1j;}!qYio%yD#0E!*UM)Or?!z&WS0i> zrhc;FvbfM9+3@-`lh*hfI*XfCBL@scFP*yg28XQJfoo!l(e#u~i%RBKabSYt@0^`F zO94(dZjmo_)uH7CwqdGX_|mF7CfnrnD^**!AWqse-^&i{ZfPj8b`U&*@J z5F4TywRmfyHD;vBV&x}u?wvI6kjVTJW9|WX<^sk*z+9IHyzmXGYyD9M>w?~XTSiE$$%cZv`eJI0s{#oC(H(U16|-z#D>bO*BG zirUoS$0rh#G*woTF$4vcUHCZj|@6GhFG@_J&QtR$FeJ0 znquq_t_%+!-Ns8kGcRTYvklWkyr}u7oZKLghSumZ4ys>mDYer2iJE>I%nQ0sP{@)? z=pErTcr3FP)MIGTc@psGUjxnkB|Ubhv404mjVw%2sK{5UtJa{E=&WOFyJ;cGl7g#6n(u%gjph4=P=v@17i$BMhv8JY14w5w_iywM{wd!z<6;dnm6a%5H4>i-QWV= z{Yh#;z~NkFPQc59eru0b_~izMoa52Mr5`$L^<7gm!9>tc?+yQ?VAby62>a2HK&C3b-+lQ#U0 zn3XF2UE93I78OWZp|qb;%<)>iK)Y91jv>$}YAfW|udf)iq$-(5IMM~P%z|5q@p%IH zZu{=dNrQ`9QZx8jpnBnm2XHv-q~*%9S=F8OOAT!&rhIIgd`26~sWxRMzzYYc$<`92 zXVUtFZ5P#P{jxMtJ<2Z8(k(D4*EDOo)wJP>&oSTMGc~@V_hbI~zUy`?PEq6E>pz-w z)86B6ov={N0oS6oT z!$^VKi7P1tCL10+X#bWj^qdzgAyYdoo4XeT=&9zdHWt>LW0$yhvMLxbuI)d3T}BTf2xt^E27QBINeX1qfBje<$0AcD-bO-&X!hXK7XUP@U&b(6jq6 z&N9rCfYPzAQPOl4^_PkSIC^|4<>}0d=b)FT8}1&E;@kp9uMMD|GeQkJpDqnpBb@6G$T+NEnNDp z{V4IdpR8X!9IzfR08r^{JhyIQ$ZV>0+wR)B{m^p4ML+J^y;!U6wY#u}E-Q7~+MU0* zy^Ve5weEE*`Wg&uaheVePpzP+zmypJVBmIN%9YXhYrZ+L^jk<^GwV|(GE-JI-Mup( zWD3vNFCSO6?Jp?^N(ikP3UJ)ZG2O!34Sk=Ujx7-E@$RZx!N+2hdn0Psw#YDY+j&M> zqjKerR>syx(Lh~!k$ci+RzTm&wlCeq&Bub9`(ARIrXHN<4#aVz9iBvRe2bkkf(=}g zywZK_O!ji|Jr8c6RNAG~5u&3BpH@Y7jgb7%x35#*B0M#)jaBTN)g1D%8YA}l|+G2;jJc)-jp42{gYlW!PQHD8G~gY1W-FXidl zYo?PfC+!g0b;b@D66Fu>Mm!6>K9tJ0iq;V>Z|7qY4RxpAI+L3%tlGVn0tydVVw4#x zX}C`~d*vR*c+XlR*21QFGo}Cq3Vw%AiTgRp#9ZCWapNJuk;8{4^xZE7JGJOn}cUv7ksct z#WOc`6dMSCRIU6F8$Rc}By8Ih`w`eK{AUBCng^;T0eC2W-fv{`NBTyG)VMeB-xRCE2cE{JDYo;N#{DNNO|Ry$mWvWa_!Z zFQF18SA=rmK=LEx4YL{Iy~13lL%M@rfeW51{t0EXN@{CBjuTt^2VQmpjl_poH9Ik{ zK^iO~XJSkZLc%~&yS6!YW&yHbW~=omG=_^hzM&)zo{92vGxVjbeXYA$L;tFH>?w~4 zd>5I!%@PT8eB*B(<;JgPy=2uH`54}oePaGwowm&jkQqzt;Ml<2z=u)f+Q}^cykus* zbt&c;A#k=57a*}V^$dwO^$Q|t-T{wg!L}Jt8YdHKP>!o>ZY08I~hl>=LV(4{u_CpTOabTU(ocIJ%PFq0ZGTlj+w<)CRfFFoJSphLjju! z5;xDp1uMmv*H}Sas@kp--t4=EoRsdU>Vw--(C}#JQ%)A#^X+u=wi(LH^ad~YbWHZf zfxO0sT3Gv(4V~b7#8l|TKRQrrf1hq2r6=+-{4_Z5NF;lX0EKu|@Oe}yO}b(sA|j=j zLD1mtQADh@^f%E;h~h-2;q_eXQ_b`*U~wI>(!?Ia;M`{RbXr&`IscUlh-`=Tci{u8 zyn?8bCU1bJo&4HB*8lknpmP6?*sIagG#p@|cM=s*<$E71WpdP6pyi%MrS|wnu{+LQ zr6}D=He!mQX1Gt8qsI6U=Raw)W+^sPb(54CL#4X{^*hmi{_FU=Wn{$9oX!5Kt%@hJ z?qs6dW6Ew6P1|CqG+SkHz9HTtq7$`-nn`tG)bUv;*xR3oUYU%@Xxp=Ma{sc+WunIvCg~}%)G-V&#Pa{I*##{uFZJtn69_l`o!5Xyi zCGd~7)n+R8Dv+(M=v(3TA|5oc?KTWn%M2E}FgJ*Rx=E(bp#KK}05M@q}BE;qi*yN=eLR)UotU?YxZvtQHk<|ax?IQzd}TS$7}GiYnE@) zD7HkCGcRcRP>*ezvusL%zti7p)%POOMPlENQc30RjpxNrnC&5PLIK{Jct9gmAXNo1 z^k3(d!9-&UP7yVu;|IE;+y=4+--(hN7E9wvTKQNsyULw-fw=SuSG;D+K0)v!E-X2! za#jsE-mgDSYEaniK+DTQk?&I!T=;B%{^ zfT}*q9=aD5I_vJ!Xrn!&7P8g z5}W?BAM)vzl48jQ+htfZfcdfjVaeD^WE*KOQ~ej_%YfHlI#i?AOf_M0A|u~E7cxfb)3J|sL;oqU9$?W0iL=b^m$MiZ*LxAGEg z#GddUWgoOzxQOMt5cx2KS{VCB6los02QIDmQORSRG=t#pAP$C_dri#YVMGy=Ad*Hi zv@X(voKXoZ-Uk>TU06W&G2=!HMRY?=`=ik%W2UB9+cy|Ln>a%sV@n#e-K{F^!Ji;j=u4|D*Utmrw)X{c` zre@hv+fw3h#OY6xB4xbNyLe69gKS_?NTijqVua6waU>3DEdbB)vTp|Y4H4VJUb8Pp zfLv?xn!$Vw-mXd-QS*lA9wZb5eAYkb2bA}T1`+Rx%b&DY{zWSgJ|aN)P*$O4DFaN^ zR*h8I_b+_>3o5%b$u_I#SxDCc&Y04R#D9q$B$!MvnYvrYhlFp6gpbyV@%YCB_s;?Y zW(CrBME)OjeMn;YUZtRp8^E18p7>=M!iiU|$_{0gb9hllzT>qk6YtdS)P}(&ro^no z*^xaRp(*I4xB30TcXaOl$WE-Zv>?q9dp%A3s(m7>Yl$~hMqNi5d z>H@V!!mQ%|RLwz6-bnUtgkGLqJ5ZA^THXORP zS~&mGgi7_$o{CswOEB7NcFw>n;$=U&lw0t4<>tsRv6nf+{>Gd}25R(+%cP$#m(3Zr z>G4*(Bra4xkRg$xU3ZLb%Nt;>q!)^8sKiARXGaRKDjToD;IFTu z0Z7}@|FJV3xT>*k+c?=&jJSTQ%5=iF+%vmtHhUlh>aY66F}mtx zWO3Q8UstzxZ7<0QPpdWhDZsWNE~Y9v-8kV^K|y{4aj9#2@UJx)0wBJmmwv&?J&Hqs z4-gofQ8XRh?~SHkL-!kTV>NgA<`)c2#l+|r`31?ZWa`(rbC;DVrJg@R#}1BS z_M&+QrJTv`{5$rkSpM!e8o{LZw3aGJrL`~CEMsWxk9y*>h=0Z?n9^GZ1do zxOS~>?4T**(p%0%YVm8KM12(eLza8HxMh4QH=4b{{vYBd=%D)d zFL3H>l0X2=8w`&A$!V49;pX#uw_sQDttpY5b1D{{x1JgituN-EONwz-FalEi<~J2f5)a@_5h`(|@AG9PQ!i}rIW2`$uvQ|t zQ=)BY5KcwaC+PJVvK!QeL`T62<>(@WqjvQp1z>MpptJ}Hhh?5`g?t499!YaWT2CwL z7R*ZIJrwgr-gBXWHE^1&eALBjNYF0Z(%1WFlpp2aoe1vzfrxX-G;xL|>_Ql~4T8D#FgvI^;SepobYpi55%IxUMR%PkIO-g+HQs6$NmZ z*@>qc#s?4mIAfUEWgDtp`>T81j%o{Eg1Ag=m@)hsGz?5yQC9DN<~CnKPdMv68%67M z(KSI)1p&T5bfn*onDmk}@(P{y#j}#+)YoRwFXk_}=c{*dCe4xpV^bZw=^(|eR7$~4 z?92D0WOhm^wX&D_t(ss|v0-ZGq9VFN9KJ{xcL0(}P9arTQ={etZ8y0#k{2)rELjH> zb+5}Kj%&3qjc|0OJ`_A#Op5$({w`QC)`ZerD2yo)vR8d!WwpTVwwEbMl7IMCxU0iq zS0jS88;~P4!vxcBGz5J4FC*N5RF8jP)OJ*Mxzl{OtBYu~#E0g(Uie;^~B*i5f zT|;S>E%JVbe~PI(r6pv?*Q9i|PFAtENw>}g6HUW$?QN3y~> zSTT;@=w$@>-XTt$ zgQP{kxAztv@NEj?*|4>izrz%9GHjxJZcsG+kxk_HdC9Pkth@sJy9F_Ti<~@k*jj}zD>Zd%|VlRv4{s+D?lO~;eR;~_` z#cf;fTlv3X$mi{lu_ z9Ac|<7Dqx+xpH*_7l6ApN-gn-n*t<%IHq%DW_hLoT<6#aO-{^Xl99i!5@D;d-cjt5 zc(9EYJStf#LICmf@c}tS-WC5dHGe=3ai6^B$V~26?~u34O8bEA6f7FeHAR{bxebsl zEtf|x!-`w^qZil?r<&N?s+3PvE*(~h&+Hrm}BunABJWcAr&11Cz)|B033oEy1tn9D6 zn5T1^nf;1QdBiR zO|Fd>8vn~%$onKf6-q26^UO#@k(z!qX5wl}bwDbX3H{q;xm-9NDMPqi_!XiXvYlhq zm-7PU){Bwbx29s9C7T(gSQDuE_!p8u8XY^hWZsbTVsq$rX{^>I7FMJ~EA`_T01rZ$ zu!-i9dzV#@pOw4Tzu5wk_A=qCL&sm42$!pBs{jlBWuGo0e;fF)zOtPIEVr^kGo%#x z7r~Tvh17F8La4sDhl6mNfi#mq3QW)i_48-&1lwi94H_8`FhhTIoL~3nCUiR01kp2o zzojT?dOcshvb|2D>xbAcOA_}K=($X3f0?{=5q_odZyghIc)QtHC#w#LkzY6j?DzBN z^;}N8s*Quv?*j5ohk!6@0b8xnS=1azM~wdoOQcC2KV(R*?0}?ntQz9ZN?`C0*i8^p zhw{2_ukErRr&IH-4U^NkI_|uhnWD4&jK94xvd+StdkDYT-Tgd=@71~mOE_anwI<+B z;Q<*`zJuWaRM!Lf;I0ek5=;$v%<%s!*80roe<2+;ZOs9E$gEAc*-h5KNx14KaEr#I z7<5Nd{v)MMpeXNF0j#fNw<-2nS8=M4T)Ijm`4=eec=1j!R_}oCHOs<1!vG%0B6c47#xs7Yi}}!9^Jc+i6nl`-8b#=n-B`iB=mjR%j@D`Jati14g_OzH^ z1kF~+Sx5UiYp|fAI(|{TO;C~3xx$JYM=9V)sxQ{(Z&1HBHNvVKgi#Ei9lWN*WIuSI5y*O~$yQY@SdGy$TS9z{0{+#3y?d$r}**Y8i zUd~Z+vv4Prf3MYC{-koOK9v?{IRh;J!`B`-8PM8{{Zq0B{x-z+eeIgYnPaw~N{nJM zPb|JUt4yYaN-T1vcW*Z6RSVUk*WPig-R^;f4+f;@-gD#CtxE0U83uGyUb=$*Tt+Y| zww*rzlpvSy7CH87RRavxAJ^+G=3bp!s#-eGH}*}mTB>yEj(r-f-L<4ij2V%a7OlZH%eVIN^R^tcJqzk>r)m3C95RG}=S#S$R|GnONZU<$I zpB(zM{P+4I$|%2mm?e1UU2i!zpLLu(y{-3=DaTH9$p}KSo8z0=hH(sg3mNwWf-47o z=VsFS`p?^Xj@9Bqd%L-ntyQ(ZE7ba?oIGks0rL5S&Q7D^OBrEvHEDg*7ii(Cwz*@k z^BV$ESyjK+AD(-A-$;xQQ=~vlWZ`u-Py4{XccXZu7PqN)Tj9uUB9!I^UZ2C-H?~?Y zDsaGeDOiLaTMCXucQeXJXT>A3 ztC8u*eI}}AT;X2dqZ8sAQxN6^>>KM%sL^c%g6O~_9q7osJv^M!Mv=|LceIcYSke84 z7ZEi%4iQXZiPEWZP0ebdt@1C%OE345LPkHZJ8w#X7MGZiYT>!(SX^&oe&aP?O4D9o z2WewXIl;x&4%s`JF(Bn!km^niJd}w`m4Yp#k^2aeCU?z8#VG z4H#Ey3$b#0??nQ*`8~{tmpM1Tri>q(Ssao7LjH3`zf6cEUU(ryR|}6i$z}|`*g%Kw z^H}Q$pp{cxGs3Y_jmNuAkaI$^q>#hF^HpQQACmokU=2k*IJ0;Rn+wVn>X`nw@sY|n zteeR9UE##Sf*0>is9433g_Gjj>9Q*ai8zHOc+m$&wFKQO!^0g1)Cj*;_Xf3ZCRXVT z9#Wu7zRHz7NM|M8sdJVuB;9c;l3zJQ`N@?2yFDQ3F{_I4LYpG+PFR*+L=AYxy<;+U9eeB3|zBI|m|Dz=~ zx7BPXbiy#ndk}%U*PpdG*u9S4yImAm9S(FK;Hy4a!qZ4HTohCF{Yc^N(*(j-UTaw?-tLRP!DD& ztsLM?6$~wDW&8LH^O|9S&Y}v%-vS*yECiM0WJJg=JupQ)Q0p$S8`l`k9c?Vb?nWQ;`z*r#k5jfzqVv)Cr^L0M=9HQ+ zWhx|YJ55>5h#qh4lt0D$6c3C5RkQJab(h(|#8?TfU4i7r{Q1_MFAPTkxlJ7Y?@7Y= zxkAPBasn&4(eE^3! z|Hk*&t(>4~ts6hXHcVeox)rYaBM;8Q2;(;#YAkzA<@XJmvmlW8KJXCt1y|IibjXxS zk28&(2_)>}l8Q~HQ}|UEl|M1mZqstXC2{t2$7EIv)pu}8&Iuv<=hvEEmt1J1xlND2 z@Ea({j;ygTkny(+1OG9=CVY=C_iefCjtP-3P3@4d`cf+?m-z3`4RZqH<_cA2BzN8s z5@r)Z))N}3PNlGXS(1X z{&Dd8ReqGo*S_`=o{h7+H*hY)w3%~^++vi1TJ}g0O6EPYq)cJoIssl^qun&FxlcuY zf(AzeB+^*FBcSZ1J?!$erpq?^Fd4rS!yziWvM}4fC_{ALCkFfF{FP`GT`51eMMewz zMLX5(OlMyDm4uIPkS{roNuRL}kdZez#AFCCx!$k%%!o!ID982Dr^WQ{1lJu#XE{(Xa#f4abuSV_`;>p;V zoF$31B za)~I}#I+w!p73vE0+s0q(-w2f>C5`mBctt;hu-+Kns?We9a}J>&5Vgk6Ol6JjUuR@ zZfwFglXWaA{LYTY2hz{TcMy65-_zuYu+^hT;fl$Z{ z-oaVq?JKu2!G$qlx(ox4bWMV)^#g+Z#pCDaYm(b7IX?Wu)SVK6PW0oozDn$d7&!IF zL~*m@lnTJwG&(&Qa-N!KwrKN(b+YaF=+!M)UxUvFb>9ot0NQ|56w2qGO9RZ!jKv*-9R*^8mZZTB2ZmRrb5a zLL9L^rRyXV#9Wo8>qp?~4yt^BYd-pIf%q?S1?vLIH;~}@+kjcJN>_Y?&eI=l-$C8Z zS?g!*1q1;(i{W_FYx@}I8-e&uB6+@gCwfx2yeTP0GI^j9uJw|JeS)$5VY|onk)f?Y z-Hyx-3FQBJD?h8Q8Rk+*E@vbhO{ge2{7`oq{CO8{1mHY7=<^lZVCax@+~dN4mz zD32EohmF&H|4DXt{mM+$q$xCiRg0ctq5ID@I>SWI(CPACeK35W#DB0LZsZ^?FNy0f zP_bJemlmFaoK$IFC1j2H1ot*j8O|xxoLdN-QJHvY5Bj-w;H;rGvg?j5nk%LxpHo<^ zOk7-<%=8(cChF`$^UWd8$D6z%&)1ge+|mR8^8uDW@_Taf6@Sca!quFt^$k{|dx>F5 z$_BH;B$$MoGe$iyQl@~F!IT^92_=Hg%V4ruOgM>c zEK>@`fuV{xge80Qv-uw0ukPlu_yLKTpNeSBYcYonyh_dNAkan-k}M!&x=U~zwy=B^ zO2=v+c>?Y=RX@Wcfxm8siIgrl#ScGlN-xpX)H}w%U+e({1RpTjo%Bzb>n55>rn`S| z?)5>`N?4uei|WV?CE~SI&9(h-?c>j%Wx3Y@5(NKGywi&o_rxDp6x5@hNB+YQ zuljZq+6pyiX75+AeSZ5SJL1Q(u^e^ZfuMOVv9^v6o6|B`LfHlAoi73Y5YfRG#JRwwdpnt zn!DhZtYfu1k%5dfZv?SK`+Cb+=>N1-YhGEWV2Yk7nVODN{m_V0v?O zrd7hUq7VZxpquUP4XB00jK>_3NNja}9>}UmM-X<#z>!}C-L!Vmwf5)2#mI(hT&Zr| z*w2KT|Hx2AdX4TgV*DxAo|tsUALSLY&gi{OTWUFhPIc#gaO`uZu!(!yi4m z7x?ezH9Td$q+98ipzsnva8qr6iNsr?A48Z|vYTall}$!jQsC4~3}Pw@nxaA+mRN__}$=5y3|tut=wHJ1ku!;NR1Ara6(7MLFHTHFo_^U@r!+{lm3WbzL+zQ*p7k*|(0>mC9xTzO<0ChFIxOknk< za-iN7^4a~EX;W}i9l)30YrOSaUW}VQLVKC+1QyLB#B-nL;~iEM29iAy%p%w+4|3l{ z0Ns%Qb(|k<5;Asu6j!OZG6!WE8tj8m)HNZrE4VL{0~$SedN9*Hu$!ol82F`@L)53@ zZ2!k5=EFan;i{ZE&{{%56wOt+drqIHH^l4q`7A!AM7k@8*vYwo*HBw%Bh0XOkp1(5 z?1C>7@rinI0Q89kAk-}3!XFCT^Ay#E&sDdI2M1^-YRx5w+&9RL3$guM&O`QT7SKPg z$H0u#&QulCEPo%LQZ@V~d|oI{WHx)9G6|sB`d#$<)Yzj84(%lY z$ltnjVu5V6);)d0k4`afNfW=f3TlzzA_bOIRJc4^|fCrUxo2v3isA(w?mW(rnGtY#?w`p zTVwwpOYa_+ zHOoZlxk4op=YU|w%W!0Q6m0-++XS7!UJwiS@p>;XIO!uyIjq+ox)Myc}gRffyw$P@CDDh24Al}NqnAZy-H30awv!e6<{ zdqKQ-KABb-t@B+8g%^WST~mETs6bu|lfa%I-&d&1*zU_)aiQQSPq&*${&!lRw?R@z zVJnxmi-;3ttQNwrHrIABf!C7IZYw4A>%RWCe5E02$Bg;b!M2aN*vA~a~v| zrVXe5Rh#%d@WMECm*N@5O%Cy^Fc)0t82Rt33^&RuI8JSu(VmH{5N7cB>>jKocoo>Mh{Ts zk(*fGGgHWHcoeqo;N3^=iHm@tJ0atfpCTIFpK|VdeG|%9OSAnmH4DifmQECxz}eym z_pw3W#y74m+BpO6k|xtm&AaF%vZVqQQR456%I|$+vOO~RVN+VE;@_%ueP-hDHf45R z!ui~&aoQ2OtBP|(B3_$QYOc_AgzC@*`u^&1=pd{XDkf%*N;#0H`cZ+7nn<6isWm_G z*VM;P7rL;v(Z*BTgGq0=Ei@rlTuvIgx}8%>Cz0cGi=wf@y!dI6V|f8%G#-@Pf>|RG zLep4Wg`SZbtApc|bXMOMjiBi*kW$18)It`@V7qCUDoP^na_$XU2EU%V4o#MJl5JbW zik6IAX>8X|bDNb|0|q&sFlJ(SU^b4J`d;qf1@#%jyY=?(i;nK6q8)2{akoYb4X@C4 zLwd1+CqIqZ=H{EmSc9*3!Oh7~x;tX7SM!V7f1&GhHwi0@J`H?wd1LC-H^}{%%VtN0 zvTfN9;Cl8#>+pwpH$0;;-!~+`jHE)(w@dWTzmm&${rbVyp9NGDvbKcwfrjjZZNXA1 zWdlb|M@QBrWKSLAnSRLgyBe|>C+MJ-ulG%5<<0F8&oQ%LMS4{8lq<&8`jGTKw1FXa zu#e+)P{&?4(|J$1`iOCf@F3W$!lBuMiyqr5mWy&(j;}?!6w&%CMCOXuET_|I>_S#@ zX}b-2H2RPvd^EX1Tk@m1Zpe5%)i9#H{6gYIwmIO?L(^3Cv*L_2X^bH9CbGdH1Fhl8 zM~V4yk+-!d##(S6xLUKJxw?(xu_0}qeR!&;6azSph^<#~H z>D(SI+G>Tt(*p_5z_mRjO{v>_PEBI=4cIPxz_VV$W}(ni?L4!=a?+kfztURtSG(}H zXY2tNe~=&}P@}j}82Q6uFtVOd>Z&p~WrRXp7a! zQ^FtzhH%$uSiLdfw@L4i`VPajAg_PxgMm)5Me`*(k`_aqOx$iZubME+^at-s+$D6L zEg9$lZzL@ft2AqA?<27%ui4r54d;riV2njG+XC5ge8X~*J}&jV%?YdLlwqMCTQ~21 z3X96)Zs;-xmQwp-Y@9!tLru2T5x->!>u3)@WZlN z9NuH>V*_rWhxqV_RTjm3`cCU{8K=ArA^e__=3=4YhrX;%A~OX19;GuP^mp0{$oEcWYBEaY}P$A;jbK~%d@I@ss>GD-vrVAAm~%D{6Y%* zXMf(bZ=@wHM2OZ$KUKar4|>xA17u$-6Q~~>#H=|P`fn_#lQQeC!>Gm%cy)(J(Z^KJ&`WG7sO2Y4kPvsPEbEw!hfgZoRW> zwurXqwFI|cpx&1c)W83>cMMei&^N9dHcJf8t5c_`dsrcmQOgJ2e|(E)(QHntp^*hF z^WhJ)eNS5%hS8BAp?!}y^3M5P*BG*nOg$E^UGBb}f`86_;70vQ+)lB|1m{mdH%lpA z8TBXV=RExH81k_8!_h0~)c6k9$J7{1vMlKLWObTRW_@DkcUBN`*Z8}p`_Xnzwy;V0 zZ7%n&=U$6pMkLJ(Gx;#6p5`t`Z@4w;PNE)-6=t(2*UZzs^Lvqe3Np&TE6 zBg|hUhOb3c;ExOGk6#xpf$rQ48Ykn1)WP*m6@)TVf2G0f4E_4n7yq;1wRTapRpfDB z$iDLyA6HW!U0>vptWt{1HrwOAKAK2*rj9n&{{b_iY_o*ohiIoZPGD+mC;cNewJglKp~(_)$zbTL zZlElQq#8{9FUEe)OzuplNMH9R3MLD^Ki70tvP9LXcl+J9ygp%G^@RG!1h#yP;pFI{aBPSMA>e9hZGkKx zQFB!;VBD7l-$k1K;YSqtW6v<##(z}LM{9C2im+#LJAk-TTvuX4=~u`ms$x%c-X2r% zlb#gkbgU9gruUz>q_IN!^czjMh8>2`hC;*A1_#6Gh7N;ULxQ19zSHtV?r8a2o=6RV zeiZyeastnqH?tN+*0#|R7TXFxHc&r-LRWE6oUJ(PL~`VM)JciqmBJ@{=yzTujDMIW21c9>#k zr1>2?-dkAd|-nLgbR9rVoOhO|C+v3g);LkjC8UCvkj9Iaq3pjA8xhy70Hih!~Z z+Jv?SP+;dol07SUI%**+k-NpV+1OV`(Gi7q(ig9?vC!L+GO)nUCQ3oG)1B7XJCd|- zXv1C7ZN*|2Qg8rD#7K$cP~oMF_39tB%1})Cx|ZO#N@ytsTjI-hS9JG&q5V5J+I!Ll z0L?Nh$B|x=L3eFMJ7m z8%AolSYbm!l|DnZ=ZY4hJP@*yJ;u zqYT$9R01~*b<+@b%g{}AN`0~bb^pO@v=Wbsr6AuwI&Grzj}Z3 zpSH1*d2U?2hQ`~#*zp}MCAfn9KR?~xJe)njP_c(lua(`L;2f_ougDW*v#i<0#Ch0h z-%3`M;UntZl#O22Zxn1_;$iu9*ujj}O5b3l0evvw;UdqWq*&IUeE7P@K&QIpPkN9)v!KdGZs%7A;MG_JO~ZHZs9KK7M;+#*6%n2P-a zO&&`Q*OGLxp^Qbyuj4<;wjZLXrhPB9AoHpXttetOjp1ZiC+Xfx z2^SV#U!*7Luh}+U;-FrNbY%Kf0J%*pRJ33Oh5_G6vp?^;PYaV zX*;xtwg+0vJj}albFHT3D}@+CvGfp7Lqrc#lQq#Fcrdp+ghG zunVQ=rK_ceR;0PQSpZRfV8B|W*+^ueq3Lwr7wY_C-#GDr2+I-ah^=!8zr;`(XvNZ2 z_H_iE_Mt>6BQ3*5E76U(_42`Hq|suB0Q3H_*K~UwmjEqM1!IgmJ1U+;X;jLmN+?_Y z)Z>1IJKwak+*Ua?OL~ZB-I)-(TTe?D?0~+(2V*8(6I1~Vu!;s7$bHLDIvG6h+~b}0 zAB}5y%xGjV(<6vIhz81HWP=Z3lNz;KUvRQFBTaK6!yhV^&$0Xig7&9i+8^Ov6FIWM zt&%|3Kr!MFv;n!l4~~4lxuK350xc1oKZuXY;VN6&H-mM|C`~HB*ZMDJ%eOZyCsd4$ zO>Omi#?`Mj`8Le(>^66gE~Fj=CY-0FudB@lZ(mA|v0(k^OzIJ6a&J=g`Q-Vmjvg$t ztA`#}{n#qo)7#ktwQBFq-Y~?K+rs`5{U0#-Dy)?#Y0n`YgnsZVBq4Eb z_}VB(Hn>B_d3rP8)$HQvQ4C+POz-nev{qQZe7>FwA9-I>K$*~&ywPK?F(!J(n!Flu z@jMcQXUN75h?-8z^ZLQBZ&2W)V)`B$WjaH)9lsuz&W%&!&6M)zf@!Ha`{gbS^&}hp zWfLu~{|xO#GCOLThJ>n%x(u*8u+4lP^BV0`tdu*HQzF!e22ryF6i4DV3qxFe|4v)Xkkit_ z^e|WQiKDii_|v*vuDr(be25{g={qG2kw(KRPK9kVbj7pD8Y(K!;Alb{s!6}a!xOKG z0H!$#V4BCIMf$bO8Zp5`ABDueAkD#+kaS5}0q1O5R&U#~Z#ShZ_i$73>x#X8^1TTB zniJ^DV!(u5h*x})7%i)>C>_PpV*-9I{%u;qdEp&sgYl>=ddfHM`5@FuH4Q({C*IS4 zinOf&8=5TS#PUGX0@^|7uQn>h!}k)aG1VTYh&o>eH+8mpYAFrglARdcsXY4AQ(fX< zFdh%J|9@w^tGg85r`;>qgKCVDtp_nKG&9eSTx8rD*yWk(?X3cE12@i6F`Txmfw??6KoF-!qu%QW<2D)`CKk}-^ww^$`*{| zhV?gR{UMMq5CGnc;tahFiZ26W@W?RfmsR#lgeUGwd<-(l6Jd(tVUJ8HUI5JHf-mk?9OIevD*3 zHDpR-Rfc-OxIBsrcy0&$8zC_h6hn&~8H4Fzk=22=Orz~M`<`9Xz)sf`P%ruSHJz$* zFI#a0GP1`VwTSr`4o{-f&+@L%A&$RMFE>qUQ?e%d9s$kYFjmGpUz?t zIy4QFZ1RtnjHH~^sbEjFe*NkV?`+>|=P!v+%DmwKB?{=nEMH;;!yZ}R-!-b2oDNYG zCYeX*Fv26dCAm@am6g@3XK7BJJ;YPz)i4@Q`jIi#lcTQGNw-2d>Co7zl)n$e7eo(0 zMeimmpuD1Y7CwB27Pfa7WeCxRok|_u%UnpErSH)$U2dZVWK1!g0R9PWW;@>z3pM2= znD@rmJ1M;XX2f4&jR*wte?GPIA1?C^bS1=12hWNbSvLBuWopYLcb8@;`im_?0p62> zWxqrpa0j)uO`G6a&sJj7Ce|jur%%{}4u-FZ#}gy+Rx_K6>C8|a{4BIL6x@(^iGfyV zWrG6HD2tKR`#@d#DHt1=B`Z_<+;ShP2-!c^Q^qhVkEoBT-A0wm>4 zANBx7=beZ9&f`=h{dQwQT<&NB2sC$6O)J0`flp3bhwJ~MwI}<%(I`lLgZ&++<}b>V z!t0xFqa4*)e?!6KQ08Y&>mM@$VTO6`rW8Q$+nm&b|00S3OsqOq54F9vmXtVnNIhyMmIcfaxkAb!=leH$hSx3-3 zeGD|1yqq%3o49=CmrW_!-r-Q;l)b7l^fW9R^iy>m*eLyBuqiB(a!sDe$<8pd>xr%E zukS1!B*TVKTe!Hv;Dj}r*+i3({J~R2M<$w26s|FmgBC=)*4!$ zrA$+^rvX-9NUy^2l%E@Y1SzFzSEE2Qy`cx49X(r(*^|6j9ebDgHmzbecuX?4yg;eJ zsQNs1@*aK(uJNx3VCPS$deB|OxWQKu=dnppu#-Ai63xkm_0Lb7V;KtW&-T-5z#q+W zy(UQ)Pc@i(w_hdE^nUTOJW&eeBtOtFTQL4lh$Ep?%NnH?jH^b9ImN#(N_xShd1}SA`@xS{dFY&uUd>=1L+JyZ@Soj(jj@BC53-$Ah z^~X$xMJgYzm?qYK*Od@+gEsWRFVPqK!uE`JGv#Yaw;U&p z%`sz!1j6Mc+YZZ!gT7lrk4&j~(3DHsX{5ZcIuP>uqQuLm`2+wv;rh``_Wv~ZjwvFP?^XlxN@RquC?yUiTP@);cFV zPmE{p?55o@JP#RPepKA>FL>}{r+IuVfRNI|RUbBgN~9DkWKT*6Mu}^WIRVf zaKcT8^We|_)2FvpGT8d3S6f9bd|Fxlk$Uv<1$6bK;VIl%TfM^E&w(+&55v5Nz>o%x#<4&VixFN|A0q33;nujb!0m9Ql zt}IaA!7YEV6!R)zm?g66yFDcIT3`Lm(HC3+=!MQ##}B^ zRTKJ@jqz-va7<4-Eia^(5u~ub&sY$-5aB-R?n|6@PsA9D%n=e%jDsH0G(ifRQjlQG zqb;_Y1a2=c;uL4@AnS1J61 zG`PKNMH2Keb2`&}5~e2zuq5!o7Z=Kd5OHlq75|y5xy?Hx(27K1ko9#A1g@*-g~%NMAN}$Np^i9JvYJ zCgp{9d0t^1#AGT+-RU(=c z{Wa*g8|D_h@YH(uZu{SSoj|=;KC2StKyoJL6WZ<>ZmkPJ;?_+#X-i!#Be%e=Fo{*? zj$!XvgfC?YJ@F5Excbayof_>d%-3fs7k-N&mxF*MDqhKT%f|ITeoe<@_$W`5^QS<1 zae~u46`3QRXpbgoDd(%(SoabUL-Avldd%3(UY+&!q$Pi90X}+ykV1PkZCRN?w1o|` z-iqCsjVG{o6;GU*@TkIeMkYZiYjlwhoW_JGuQlfiOu zw*>=#h==8Z&|)Pf{A>&Ng5zc4|ET%Ou%+-I-Zf=Tob6z;qx!;a8;VV_e+QwMRpM{E z!4rm!S2ArvB{*4N7u<%dR)Zfx8~Y?->IPu+ipS` z6D@Oz(xi`kt2fi-nIC7!{VJ||o>O|y*urzn89HO@voO=A?4?;v$>#UH8-{`W-Vy1O zAr~>@e{J2dS~L9#l-%F7lFMz6T0IyNrW=DW2V|3JApnxpML+Nq?uh^OdRng`JqmTM zAZ^Ne`GVN%r{R@5gue*kb8l_PUB>DqkfWR?lDR@BLY&VP2wN8s?%&j{AIRKXhL5zg z-f1>6>47S&RH+!jzw7};l5m3+H z*v%T=QZfw(X~UZA!X<~-EI>pduEifV<_`16XOwDl0Sy;-$NWeaq|M*bYy|&rIkMd< ze0)D6jUGws-Qfk(BfGYT0Qh#qcT>tN0*wJi>7l`k_k`;PGiT=E96g-A(9T$zi+9q0 zEs(sH!Y(Q-?QNo!L>Cp8tk=$06lISo89GZU=?lu9`=0VFJ<2wCF&tiqOF5^pyfV>w zy6vIrxiowLL48k;v%f}e{}FHa@a;ydq@fyh%bEd8!izG%%9@sWzIr3IVvSg_3goe~ zSR0ycKQqwhII^}44sj`li({D6{kPRFcHzo^-e(xpO(kFNS&?aE$nL#4`_x|(07A(_ z&|<%5q#qG(__zMI&)=nNkkUmd8J_VB`3hb_>IIoEQv6@-UVC-MajADt!UXZ-p5A~( zEMupOFJz{K)Ac>~;Z^MW{QmD_V!p}cTQwE<- zCoj$Bx)l+xY&DMfmss)RJ^C6?U@8&_OjiRW(*F%tA)_A{zOa!cw)Z*dMd`WTj0#EJ zVF9t#fn{tfw4-643E?&DdnvZRDs3oW-*M2pOE;pr+*IcEI&;?40)Tgq#O>|PVZOzI zO)2xgELh7mfPw|_2}cUoFaWuU6G5*VvBE9lNJIwh-z+rh-2U4wW}hTav zSUpaCAW7Tims#!W0T7QJeO0t61`HWyATqT4YaysLEnzje$Tb{-$Q^+h@fJkqPnhj9 z$i8azX)NNF?uUUWphU$qC=3~Lw?4|vb#XtU1n>B~o$~I?+a^W1QH&ei~dtvQ|9}3JiOye(h0*a8-Rszfs+>IQ|ql*zY@|MkgPY%K-@7GT|)RC zx?7aRz#O_OGt(_t6;C#IAcsqW=dku;vKb((5FyvLuo?<8oHV5enPpANV|I4T>O5gd z-g)`*wxEgt&+%MQr`c{glW-a)?G8X0Q$r?VAosMdwdLtF>sQQW|Lm5q!B?UCe#=5_R?#En=B7#zyc;bdGOHuwU z`9Uyg7BN4qc_DVijiL4OC}JRc;CaO4wog!F!=xp8Frg;(IITRBb6F*M@%GtXW^k_a zVtwL5fN(pbXoi|g#=S3WhHbR=|A-7Mh|_5_{dS1=<}zjao#L>lnsQPosV%1<>|2BW z(23kBh^kW55-viNaA?@6M!D8*fkOF8YK*dHuu*uGs-Z>GQ0P zpZqNEQjg=yv(iv*90gy!8aIBRjQK6kvW9HUxHpw{8<39nO^RE!QH#ZLov4{6xJW^w z&73l*t}I2OdDL=}-dEvrLXl}< zV!CEBr%zn{9ppe?*%Hwh#ahWf)sBAR881sfWayH73||r=lV#SepmT-{wEWy zNmsT|+exaxQ7`IXV5B9}4!?>omnZhY2S?XiJ{@kaHWwB&A-~8CVpwhqTH;id@ z9>JMKYk8Po^-MGD(=S55kPQw6gd|G_Y#ZT-TBo^oo)6R|Iq%C!`!R$wd8T#ENuMX4 zVxxZz_1vf_%EttuLKXfC-el(70Q=w8`Dujf4q7#X?qizAyMBH6`gE{k5s~&hb;Yn+MZ?oPa{_&l8-wX zQY!S9URPt+=&^=zR3!OlLppY?9wzA+=Y>x-7nL_Kwo}z$N{*U$dnoYgm1JvO8h=xY zgIXGrY==$r85`2ZOkQ_0{;jzf@{A$BV_vbydgwcx<#{VQiv!t=u0SNm%?De!0Rl0| zOtBl@(}>mF_$y>R=1Y#bB>HQnPj3;t-LNyQp1iQp0ddz@uUXmvEFd*y50>_AUe}?F zXUScuCk;2aw8QZpQaGaRtw~m|OwUvcA#Ip_lTnyCf~aVoNYlu#75gt{oXrJ3!g^4@ zsZzeDo+m9qc=N8Yct?i`HPuc)ropBa{V)aUu=%;px5iM4H)$=_uk>G(o}fDM{X+RA zYZ(nsna zO5SB3S=}}Hyqi1ZzSqC^n?718>>!Q2oN~s~pJCqbw6t!H^l~TZLeuK4#1$UslPO__ z`tl*#m^@f~BpcqbL?+kHdac0m3}?ys1_(Uplod4C!qxJ#*5T=bV#2pKO?dL9 zb~xWcIJX;v{_DPleM4H4AF{>@@2JGxyJ_C?H<9q{0gTw9N0eFSP`@JzoNhHbaHlDb zT^0mjg`Cf)#68)=(*=TL#TbHIq*iW$T01wT*kKdi^a%xN8{hN(=t58Z;=|VpR%L{g zdc7V@Ugy@{MsVlkHbk>QaE+(G0X9n9DTjJrNTXi$2w60R z+P+c-FBJ2(t0dd}7-9N3)(I3Ng1(!lXEk(45EVOeqP|7&M{lGEIq$XOYe(Pn1MU`H za+*9(=RhViA{{CxZq^5&wtewNIQ-1?qV4ASJ2Z5lZj0P5nf)$+qnt*u;*MZqif)&W z#v3#%CHmvd&zv*U>WNRc@C0l0I~=fzb7KYtfRVl=3kPInO`A<_M&dEdsRv zZ$mVf%LpZU)U~2GpD!i>?iR_o6--~0u!P7n3F)4rak&a;5mK-NsbA}tUF{neyNJNu zF)XRk65majD?Y0GA6=)%RkW#n-H1p{x6csNsz9p_ffcOtCgU)j zce%QR^I;Xu@&d$_X+qjNo$t?Zk_tPP_DO$j4}PH>Elhcb7khuC5Qe1oJ;|%0+Fb)Y zb%akH0&uB(_;?n)+o{*_Ch*%RxFlOQz#_eoN7^~bsy(uX)C@E6T(~1bu_Ms-is{pV zhE)4Tms$XR%6kel@qsU=(IV*A7D!H)Nmjdg4_<_ zj(=N?$i+8`eZ!HAWwayEY7jBK-?v$|rk|4u3CsEy;16IjJk~PbYBP!;uZ9FtAoMe+ z?#u*)lgQsOZjjbc&GnCm8&1(el9zz<{ekVqtOv1HO(yszpZc~3f%4p1P+gyabC)(2 zIqGMP(!ptf5)?4L#P@mrxKJ2!t9A@`os@kayBmMuh>?Hml5XAH)hU05_px&!MRntl z6@@>@OK0uprQ+2cnxFjM1lUqw%U```qlB1!(go&u2%pLM z1LbDQ1gSu#$h;YAyGY>&*Sj1GRju>8#JQc!zT2A&=UwQ?&8D0Qv>mag6FnlZC?FvF z7}tc_t7Ci2g~=1OL+ZU%zl=7YSf1;-y(-5}H~Gf|i!^xyV^8KSUh1STaJ3xz{TW*> zLb~veO_Co>ZKeGduSS~YH_QM)gbT3vZv$WUVriq(3SF~2FP@Ba)R4og)vrxh`3iYg z%1&5Iz$ABbond|Wbr{;{pPXQC(D%?*TK^6}xmYzf=iyi@t>kup0BxpE^^b7T$C>k7 zJ7wlS%rl~GIa5p#qgP1JyDj95w#s}0DG#`s$=`RY(<6@3&t}JDOeNq(pAtv?_Xx=C zWQAf{Kf`H%_S(@RX40UUzt{Ath|xR7iul#^*00C7*eaVjP7D@r8x5mxiIp*`rxdFr zu3l&n_iT%}d7+`6Yvsih=oXxL;$uF`hyQ33n`}2P6frl)VnYs_4#;Sw61s0Jo&IVc zcG=1ZJ)5G8k{K6^luXZ925iDyVbSqwi&|S809)eCl_@NzJvLI)V5H?}8PQjzT}Jx@ zTJ1M^Io|A}^ivNsIlY?_%$Um0o_e<8Z;gY8vwqcvKQU2YhRe9e`)n(^pG@{M6x6nx zwBhD>@vC_lg8LJ!@$tMC*;jZsDoEFJKvs1t!eR(&^o{a(`C#xDMcRwT3H9x*Yl^nm zTvB3^`e@RAv*-*=GOkxlt4k^^$d{l%-Jhohx6`R#&l6lOqW@2o_qx}7i0)G%po3LQ zn5?)fF!ZQp3&l2uS!PBx>6B6bbsrIsI7m-j&;r!hb;`ct&CHif`i;`5>Ngi=7?0}E zDr24Dt=bl<6Y)uHw(6w^=<=GIb<>#A3L6>Cvguyw6;#&kq+#2ayG$=V9i!@99KYFOV&x(D{2toLK z{uKqYtIx@M+!PTG@N88b^T3eLb^xoU>A9ky`psthUfK3-lb*`REQ6&GLHT2vTsdfX zxFcD80znzxFo3D}ifv3B$xHK{8ENhUoi8d!>zJQXX6cEG*uLtQMXyeO*leIqzO-1~ za~N`0%bE>Ly8QW*^A^ahPmQsW!sFG2UZ`7>)Y$_H`~NJmi#fw#cVwbH3kY1mU4rf~ z&VDaQ3vp}kHR#eCL;osHaC?cDV&tOI{a@+la?r#pprc74>3f_T68l%KB#%Cqb+A1O z@m06R`SsYbHqP|$QnNU1E|f4(-VstIvZifA5uS*^T8!gOy}ZX^D4KGS zKWa5@812DILYblV@TB2K&G_Lm)CL9m9AuftUMt0%l$!5KYnEr2f4=U*zNMQxh>jW} zFKxiJHd7ao4nzN=ojFpG>MSsLp05T~%(A*kvj@gHSvP6bGc%P!!&FNoxoS1N!OD0f zJb<|#1ubPn4UqSPb$K+$Fq+#keWOPF43Q~I1-pGnbMl=%y5SJ zErTBz%gOQ(1m5j1A8kCr_Qq(Wxm(~&&v=gh=g0ME_D#|HOSr)Re{u)uTh=*}JsV#* zMK>%$o+CBf)-MZXc!SdGkNE0c71gQ}ZDyZIk_iQF#Vyb+Zbv#13?!E?fUw5W%!ZZn(eW~kSPfes?8r5gqB z&3iYtua6v>zD06#*T>DmPB+%ceMd1gRaP0*mG_9`h^6pBPmCz(YJOIT?AdF$ZYn4) z$7rXSOZy~)Dxtn6RFY;;dDmata5`aij+Oc*#I(60rW<<0=sSYi!f0`~BY{C~`(1eF++Ade}#si)u8>a^9$5 z&3CG4X8cW3^nttV%jh`gaY6~u1#Kh8%#_tJ)*13ahMSUpJ2}PjlEm=5=#O2=LDitK zkFLX-cphwglL)7xA#(2dp=%-7joYNJhT(V^jd-EX{6mR_a#%+|P&3*wS@o&0g@r5z zdJ}x!#1^0J6JH6C7|>q!8G}0dt)bm=G#pUT@dFYxlZ8|LvF>`}9G0b+7kdP9#0+V! zHo*yLcG9~4kt_BZv2;?Meyx?>NDeswiek^tA1#HmLe`e~1@xJBRuVQDMsg9E>R%_h z>eYGlIf%YhEx`>ZJV6t!U{818BNF`E2V$3<{nf{3g?{_DJqJ)IfNTT zgZEbXmWFwT(XcPJb&8_cn-kBw5~8YO?^9#@xe*jJR|sdU^Z!P_!CmKx5ZsM4ZBvCI zo!OyEtRIj1S(j4o42{I3MMz54E)>h2^}z})=xcOc9z#76uV!^%-H>mK7BdDm0&#{b zcf%9|*$Y^|0iq0ws?j83Xhr5JvAH8mFEo%7!XucTM%LRzJ6QsNLT1g0vf&1*EOz2zOQ1 ze>oxYtqTaB;{Si8?h)xn22kn%@}p zV@HNk17slRy4;bv5Ap`U)D@V#-AiqNlKP4`5hgLy7wUN`r z&w-dA>JVQA{S0aB`V@!d5TZ(yU(cYu^Od?X|G2=gW7d+-DI%F<4rqr)mv5rrkG{Y{ zwQafNj94Ao&vK__e5}9)gv219miEHUnCDA{p)%o(4f@U&%q4Rl#o5g1*kq)(@tIQL z6QOA^a@vwW)fo@UEKZQYV?(*jV}Do7^@R*uyDz*L8elmu@V0!jUkPHK3--%*dflk^BQtT{5t7~JTZvIyAE6*qrC9>BndwEdM+i;zcn z8H}~kw>!8AypBd|24(3z3J8V^>{i?q!hH!!+BHSgovG&_4TyrOA1?=*z6D&4qfT_EV3UjVtfXO~5v2$PGFF_fIoW+;*yZ zJr?MFN$0Tlh3@*k3H8_dBILT3kF{td=BWJ(&>;|Tmorlr)KAm7#nc?{Okx&<#tA>FYv^u{4u^naO-)Xg+gIF6eUoa84r zv)rm59JjW(Rb%8$> zuOcc~rQNDCe%3L9&2i|^Yb~m7Ipb2k^>w;GH%bDpvqmGUU6|q1RG+O&Ev+ zm|Nr@3(9=ALhtr<3oj(A`cQ(XkJ(AhNegO=l2*i9Blt_8N131(hR5knlsJ4{%bl7I zd(Yk`#q&%CmzEnryBjK-yhg(EuCmui>u1!s$SdRR7&C`#`i(c*2tVtCW`q6|8Bxd$ zy~n--d03ZER+OVyHyK|_I9T5jXuI>bQMK!?kok*D-((3hSX{ouPuxF$HJeKV74WSR zw(ohLh18LQp{3iT%}3m zgb}suC(d#J@-gJfgg`irn2@UE2jn#JJ-NU)uiosmI|SXoYs`8$z>{#-T=+3T3B@YN zz%kHG6+i8}<8nNrYJuP6OrUuf+Ri_?{gxqf(^Hm-2jzN?J$`%h1lPo#cARKFoT=Pv znny)F+-cGQ8N3R#rB8V7F&&U=Y41P?HZ`m&pyahd$|OEBEqzw%lWF0gWU5&|j;h2h$Dh2`4LGJaZP` z9Eu%?VlKa<#tzn;4n?Wwb=xi+3ip^{Xb$Qhb8w}Z;vOF_DEuBz4*jIl*KVpW>No&Z z|4FuNQ-L0UQ00qAuV_PMbYbb(qBqx^N^{I$H1m#B!E+m*vvZJ*3^!!mybLt-e(WSg zyo8=|s82EkB^?-hk@z?M%_PJnO7Vp^ITI z{+EZv^KSnnpr(9EjCgpRyim0lpiC+qKk1_kZo8*@7Fqeiuu3pqjHLljE$s!}N}zfd zeS!m<^K+CT-(d4{l;rQRm#RyubAIxJ?*2oCLATAi{8`$T!A#NPX?<_A-qBTFB&+Dk zUfnfJ*VwD3rN8GGx;g$sYQkU^r)BJcdS^wZOjwI^8!ZIJRouW~;1-wzB#wY4;b)-I z%mpSfZ)OPCBz^j-;JVFm>ImT-H4orY7_GgYbeoh%lGH2sz>G}exCdB{NT`w(}_j=lF zM+$;ANssWZ5*NqGBN}}8=e_&&iy9*{(#{F%N)!w`%^XFuCHfZWlPicmNC&$KGXZJ4 z33-6`U-y9NuP!PWavUNV@MqLS$YKZZ%Ecb=5hf>{>0{RaPw<3f@8LE13RGh&;mqWN z(|U2L?2QijJ;((6TLmo*X79bhEPuS8#`>g*lWNzvfnc?DB=XbV9(ES`6I6Nqe@0|2 z8GVK#R`TGw6M($l2*~SSp+&&pt6Qt(jZR+DB^7H?IBaa2(sLnbj>#K(C%O+my<7yj z`SAY|tt_9>=mEpm3sR_IA!I{b#GCJ*-T7wOyq~UePP?34w&cUEHGy*Pz~kr)!ttkD zO6E#G9Buq`%rIy6!}&XAZaK7g$IK=FR?IpyyCiVFgX_eh*@rILttI6@-0)A`#U;la z@=tI17gXew_g-T1*tlIs%ixcU^~jq!rj#EjS5mU-#5F~W z2bbwkWH?iQMtK(c1m~u*g`cf-*Duu`{n3KBxFCX~AZZkT8Xnv-Gp;Uo@V#lo96juE z?v-t(M@@q@ZUZJZK8jW}kg546$aMbQi(HkX?ZeM~+FShN4~|??Um~g`;{vcRUKV?k z<}rUzZ~5=ppWK=S9xR$}Ij^;5-M3pGix7Q=zrocwB|cn|=6Zv3W4Ts;tUvpxo;5N! zznL^NrI{5;@u)4bi!`m(K-)w85)Cgea|Tl9sv^I8<6kpFb7>zYMz`h%#9Go1f-vy8 z7cWN*STm^a>a5^n)dw|e`-%qU8}{uKywS}mylgJ5v90-fV1eM-z|H8^>6JagdAQK< z&v0~WlFNH+UC> zsWw!#)bRSUa_|7S>-se$N91Rjk96Z#ER}PaGq`=GzU_n55i=W+__f?>b;?|B`_oiz z&!}_x*Ay3j04`Bym~m097t&1#eO+)isq54p^UJ|&Q4WHQTuwRtlCb1 zG`IzF?!(K~ zpEK9;$U}HZ!jZjSs^ydj>lLYl@UY-|Ski}6Y2RtKVV++r`e?h!+9fESE%^**QY~Nk zzGJg}^)eowuC6arWKh@qBr}%r<<_oEnE4*vHc0|piDc)hw@A9r8YP$6g7EijUfh6B zhf*0-pw)kCa3h_`ADh?+dH}`hHdm-u4<;HOD5{qlNXOYE$x1|AgbR6&z}&gXvX*M- zycgFy>*M+Ei zLkL_AF5lE|q%BpE+wdLY*m*^>P_(Qciss;i&pe&$U}%@z*uyVKF^oAabJWQ5iAUji zKcPs44~S`l>7LEWi&K>{Zb(||8}}xsG)h{TWuB+g@ZxGW$X!)gI*%T2LDk-Mh4j__J|9l30bZ3z<<7cB*)h$(BaU+^9GT5*q%SikJSwv-UCv14f1j*1!N zs^@ohHeS<;*J4zwlbJ$MwzOPFOdZ*x?)F}>aq7LaT1V^{Daqy7V!!2gnk($t8Pawo zCz~*j-|F--Kg_H(hV(31jh{fbR~)%@RkwUGA)KZCzD zIltfkImbc0&NzA4w4M=^(uH=uUt%jHSWLsl!nFKf)!}z6-Mh>kx`YwCBO?fpty50s zioe)*LajUvUW-4Nn{c}d@4)|>Iui3SmKqm{nJ$QVO`rNs_7wHG-nL`{#qUl7=k}wo zSYM$+1dbG#rCqX;LMLNQS2B~ck@eTv0_ji5&rvb`$m1jHt>&#J?9?W#^bht$>8Hw= zDf-Av`tfe#-tqW(eB&^F$l8)5ybAZsd;JBcPwJBG#G-cjSqNbw_e)Gz*g14YsP@Wa zRtOSFu2W~m!g6=4;1@8?u3)BJ+M~D`^O-*NFJluRZs;dQ$n;lPlm2lr%adnL1uoAQ z;W*0=PfZG6%Q^p#q%Vz2YVF>xJZ5Q0re>x>YGq|bYH2D$lUb*MV`d&R<&=3mHi$z8 zC_*_=nNyQZLS<#8MWs0;f=Z5=RGOLtLk>8?7F1^TyPyC2MfT4RZ1%nHdkxoht+lc! z>@3QgnpuSbJ`%3#>AK{2J?yW(iU{I{nKF~P`-(02A6w+31!H|)EaSvqCW`yIU;oa* zYV540`r=r>lZ96zu%$B|mn0n{n*NRpZPd5nY}xJP6JJD4lS-GAW*$0$G2z4U9~u_$i&#!U`A&H- z)CC4q3bRRO$T<bf*~2BmlEW+#3kTj5VDa%OUONTi|h^YbsEcl&5_BwDMmsY z$D1@!R$j79Ys4a*XOO|(-}RsgF5O#4CK00!$(Cz3^;a=#jG0+2fX!XD+aq_@YayF3 zra#`23M^y^>KuU=zpG>OV~!r*aat!1{R9S$TL}}=Dc0;IR$|;6s1@2n;QDSse9e9Q z5eY4_F=B_kvaPZ+2P!#2#n!NqC+`NW3j1qREPQTSAq6i7S*R_2^w)`9q9=>*Gd3%Q zX;1Z$?>WZs%e+IA=F-#*QE5yNWK(*doi}<_A_>Z$Zmkzvu;%d^&g_U#&J4STZCBpU zmrN-0({PpPRH^f*{bH()c*%kv}yCIBgg3L!P#2p2OmO>pu zYEFU$SAswaV~mk`O(DARR`3!W&5AtZ^YZWhvB!kl}`-TJjtiVQC|lVN#<%?cc+ZMrPl9HQq~r@N4VmL2XQBZbI2h&83xslR zs@XQkZz$+<7f}t)U5h80DIb^P_*7$jZGm|FC}3wbNtj~9HDev5gtVYECKq}qeKE0m zGx$UwvK{epCPsaRTyyAT`)rGJVcZM$I}j*$c(jttb>toxH!p;g$8)*gxm85Yxuo^0 z6_Y)JQcCm;2y~i5V;_z#rTlP~7e>WKdZ8dyZ8}@<`-pBC`FLF+P?F*#yaO%9Qk*|v z%X%yHRo1ubWO}Tw+BmFxuqxn1aYXEQF!}P#M&dlmQRs<(2Pn=J-z}J=gPP0wuy2(3 z4BFJ2vV zK|>k`KI(NNUIm*en?pfGiFEyMv1YZdUn=$Bh5wqu^lOZ2MAlOX$~a8%P*L=YXiJg& zI*KvO@$nmv6y3p$j~rC6UoJq|^$UWfX5!q9&E~uTCaH}Q-~S8mo(qFbdT1`B>6D-+DndSnOpq@!xVrg0 zpWXoy#wc=ra){nS)Q~^vp|dRqHpU3}(Wt#zn`W$Z;tjr0#WYODdn}M{kEWJ#aIH{;mq<%s zIo{%H)@s3cxA>*($(Z z!T(GY2Jh+ZO@BbdwCu;orZKjzO?lUoRunc{(S6QH9RKRfUnBFOZW|g$v^gO4)47-0 z59QyJTIM0q)R*z?!Ahgz=7-3YuDV;0hvjzTc0AkcO$>oav9z)c1$}eZ)Uuwhm{N9l z2dsWiQbwC*{RPxhTnuR}*A}ex2t%z=fVB^e=|4Fp3QywvFq*gSd<4-F8dUUC7-_*; zj9gzS{&$=KMbS})usZBUq6Itv_=EgcT?geEL z0on+L`}PnMMby;h_H^G(W!l=hY9JA=X`>n@`^TcHs=Z>yJ7m)7zsC$)8&}=JSP^cy znw|4c)8L+7)+^5Fuicmwed8C}Crze%2W0L>o5Ebq%n`0DhU1z)a%^1{)4lBpD@0F% zOcT`IW9^ks7BF z5CA4J+6ZgI+Y{FHX_`hOaGWZ-2;9xoXV`bomVbaBIWd43mwCyCE0#i z4iS#JYdx+Mf07ob3$Ii-Ph!YLDNg7Y0@{mr;Bh5nGS3-@Y41_6>Cj~+QatpbCrdx2JE^AM|L| zd(6ij9W8nT6zCt@lHEOq5)pqMfJt?Gexq-1WGy6k3%>1zD=$wnP>g?A&xMrApt?OV zhao%KrLoi@wEdb0b`kXIG4&J1VQEZgqlWndUfLT_#_nsVaQ)}+W57I=SlFnwLK`vf z50|Z%V0OXv!dy?m(Kf4&W-M|^f_8N%)z6eY!Ig;a<_6*8^1E|+d`QuR#M?7AE=iEQ zm$V~l7|+5iGrTmr8$8Qb%f25bVp~Tb)-Z>A%b1?R_>{cA#5_Xu{WP9)R!J2` zO5>#Bjm`0l=VS{xwdTV1+`hwZBj64Cu#4n>KCf!brXef^$&@IU9&@^h@Dd;$L;eKqv%=Bw4VQ z;=t@19Oi#L8E?~B%L|jd`sw6Zm4fL(fYO%DWCX*&sLFav1}ZT2Pt zub>lK8DI02T4bFaPu;Z$ZA1uRUbV+>_ZQi>0`~Z>fef7COG-Ib|7K$DV9*1Y!ya`g1*0Ww5g3Ao_V8OiSEfk~1uP zkEjNjX{?z+`}f#FV;uP2LAQdCjq3yK#EBiRr~-o3pfX-EY_pq=E?NoJirWu>2Np=G zwL671X=c1?5%>z5#%NdH=`p* zGF=ecMmWHgR|Y3Y55+}CNAsDef9Qk&<*E4QZl;&e3-4^N2%Xx(v=_)-KlZ-^o83B$ zK7V?m=$J8yiG=Ex-*B9$J9}tbSpR0qh|A8_ms9eI8l=lGLpI zArdyKB8kiB{6_sLA5)hZY|RLC(-otl7vF8jQ}a8(55AS3C}z6n-F90Q!{_&Kvi0>7 z6-=pa({()RaeDcwrkRTw-xaK1#)9Divq5b~Ehx`QO zWNV13oss>>$&+>}Kn%M#!M_#Di}YNA&f;;FS;cgP9-D86xKxv5LPEG6dPB zH}A6JS$S6&x~FA(NW@XS!3gSW<3V6j=ZX#_j!=H_R{=9R$yB%8vys_cARf~J?ocYR z2RQ3nUa_7GdA!Iq!U@a!>@xkp^)eezhwQm?72W+4b6kIkrP5ox*MU~Y$fpt zkBdw+h>?D{L0!qNBNR;7xF~Bs+`ukJmn^~UQ2e{0nWpBqRDKZH7a$vjP}9KLd)pvYqqqke@`WEalF99<#k$?(}af*GYDyjM$t zHgXGdTH;>SDNyU=MNzTu^(3j`389N8ds=XA+`DP5y)uT@H&X~~@Kr8WRyCbTKEizn z7QX~nNC|)gWDzZiZ;%f4OzuY$M;{e_61*an?LEXv$8W26hmZvvT@jzB++S|74)!1c7h8~Dkma-8OnrGId4nU z62TLp%YfOltJvlIe*0NBAOqUhvv#hJmXoa|CHaBM*A9>N{n}*ZgbxwzsFI@9j)t&$ z-g>r86;#@#O#YXg1{#FLcAAHSM&w*_sZ=cW1k+KnKZ2zjfnNOHz11(d6ETt0?iUF393CCsYp`}`^ghnk%UvM5X75jCM z^aG0hVVxXrgp1hCJ?u(_I6^y-_=#_0rpPWA8b~w$JLmp3|Bhmlu0`W`B2b*25UilXuHG9wpPu~H9>Lt3hWJE0&atvTon29w|7f;HyS`DK z0|$|QZMuMhg!#_@6l(J{?6W^HA;~hbKO%B(o4oS6+F~br;+)y$0r5)^xEOc}6mBrY z)q3|$qSDlZd!_=~$%AwHr%9f!DuTm}0h3f@>XwPhS z=<@7PJe>Xfm3PmNozd^P#knpdFsi#aW@^4Qb0O>1Mk-Mwq(>$m~Lv2XZUb#vJjp@fmyM+PQfrnj$g2BDKeB`$k9D7Y5 zr=dWUCiG3GbpAfAH9;l^+znsFFY#?79GleRl`VMRex0B>pR<;O`$*)ZdI+5bM{iI! zC5u4NSf##jU$UC4ue-W~W_HC2ep?-@{E_OawIEOLvgU2lmN`6HzkS4JD=)a#7t-?*f|N2sgd#{gT@V<`P<f@oVt3dik@ zBwOs_BRtnDs9dq|e{o*SDNuAR)yNkUe3@4}pl&gidBqhazu|VnTBT*e3x*0x0eQ#8 zzgR_-sTll+NB#ytUna`?I+9$j35XvRXSV{G zKttgNbfED4%T6Y@sPHJq5SatFm{9YL{woSM3YEGoa$wMNht1ws#*>%R&fRhi+feEB z0^0ip#$lI{M_SbW8H@~XMM1YPKB!f>P4vCk)EN4KHn;l%C9|u6r8@TI)YCOSOK|KH z<(ie+$)6D7LJWMuxDxdC?(l6IGIVoaP>VXc847nYepfFgilB1bUf}naXEoEww^ZCO zopX)%KnEBLsuHR(aT(Hcaz*QAV{jrmFLdd)G~vQ(Qf93+4LIG%SJ^Y;>xN@{vZlC!Ep6O^US=}$V*m0ALqLwH6x^%;LIM>iA}aKAj{etr7GCUY9ZXbu1jguTMZ?lN$=$Cw?{oX znv3xHq7mV+_ok#*O59@A3IE1YW8T0kXo(uUE$0yQbjHPN91ypXncNx*-$y@j^vhBW zjirr>LIwaIdFv+;WL@;HBPKvrwdE{AqI%THtgA8Rr)khmeb2?X4NW{m=iI%qdo{Ip zMU83?8K5)z8vi)t5dz|c)b|4-rd0~D(O2CYW72^f zDH8TT3|Pok$)4k?shnA+I+3?49(=W1GRR#!1tsGF&3l?Vl4))60%Ot=QgeK>kFFVu zdv6AT&n2!*QWtDIvS*77$;3hVrj)yRVW29sPXa zVMAs;m$ze0d)_u-DKA%WfqRRWD^kMG*ebkt-mE;x9^tDaQJysOq{HbIK}Yj zdn5{mJ>%1{k#ojq@~cCHt{;TCe8c~XKjL0J)rtnM$2?eJHOP^UO7jjRgM=BvFN2n4U&1QHDXuRl76=*|3OF2+%;@%Ce*|xkZ2(}NyU@>IGiKj^`eHs zn;Q1P8q}7l=w)c?$ws#YJm;A~z_#C$dZ6yht?P3z+@%_C!WV z3hxLaE*Zzl=m*8LHr<`_WW?7`Y|LElgk}eycA&}Gw2F=}alqE>hD@E4CCW61v%5=h zyP-j61jHJ7v?AbFj4p`pCu(tOaQX4-4;*kYBjsGS#_j}A$3d-Whe+zI=|-I0a`ChQ z_(EFjHS|f~m4cGn5l9PEV^VnB0QT0du$PE&)|VdwPsD9n5coxnYjfXHVYke+kvdwS zlkPbY8X(3Rs9v>j<8%h>W!{@)eF~ou->WS*}OU2xQb3q7&2+@@QSG-K&iyJ8%5vZdk&XZ;_r zy234E*X$YW-7lOLGpcvn;R^MRNL=jSWtj`ei}}HX@iOS$sgF8SEu=?&&MI+H!_}v8 z1RGW7opI$#xj-5KbI+r3n1a4n?M7UEGLD+_MF&O=>4K`n;d;#{&XE!781&KZgE-f0 z64W9)U!M=feHx=Sh0xka!QB(|B@zCivJ{tDUkE%(b)r1hOq|&fm6vb2ZZpZ2N1T=ku&@ajj7OC9lS$-Aih3sP)@ zu-C@);b3?O`6ke8a|Y!G_~3KLT0{CLdYDI3jId9bJ(%z|Fwcm8u?GdS{y6vQgc%ev z%c{z>^a}f`Q=oT$1n0;fDj+0+7;8mOp)q|nN$kG5&m>uzW+wTW0F4Q>hMK|%+a$LlX#VE2*oqLt*eP8|hl zk$fbnF;x>vvmlFegxaSPz;=2P*4J6S~{k&)#TuABPT$T>4U3jH=;ixEqU$Vo#$ZI+tp&Ai#W5gPwud;vq)b!g>!>}-) zP5ioI?nl})iU~X=Wbln7DUlyPB<0qOZPPMV;I`=)57mPgbt~0!@KVo=wBdr@#|jKx zsOwUgKBUNAZf`IBRlFb$RKQHAA=YdI^grbwo$_r5m`d)3!SEA4o`YH*c0DtmR-vQp zU#SDAaK2h+HFL?`qq~E{@MT`%UlMF^F2qz)h!YClw}(k*lEz#m7&S~S06j|r+sGlm zUTYmjn<$4dQAnc@%>AA8#L0Io&;YHu_f*Hl`n(tgMJ-Jh5WFmN@zsDZ9V+Fi4x~{i zyD|oKSaoDNWga}mTiURg8=f=Ub;?P(2j9rr0Ht7REX~>NO&CTm#E8Q?!V10iu+Mc-A?1%;1&+Nzo=zHbcm%?^b zzSqxJ)J@6ZNtk21(ZdcNKXOn^WtcfVFouUke*0l8p*dNOE!G|5Fi1VDoUTjw0~Y9b z(Yp!u%o?`%w8en2Lqi26$jvM|mYc)maU{{02LLI^W2tMs8e? zlXOPk03NiXv>HeD)|CRm#9Dv62{7r)9bpq}klZ39d71@}6bW-fz2sQ^%$kI=}*Pm!maeV^sH@-T97lFlui3+csRZ$^6N`*;s)Ydsa7SH zQd7@ykYA90;Pqkn>aF7#)XdFO?{iAr1V^_d z2e>r(1HDW5M#nu(=}k*Air7JCmiPq=+q4qWZ^(a% z+NL}a!loI@QkP=+L+y~N7`a7a*%;O}6za4uXCVZr#l3AWb z78Y|063)cpb3n6^`+`;OO;1KX#{H|}-V&^mRAE{mCZ@IG3^ngEgjg*_)?q#CTk4Vp zcUgg6yPK|2@fed`KC&3{LtKG*3@ls{l+v{K&SsDSznAL zy0yb4!uiVO{lBugD+qH)mr6yf<5R=|{f|w^BFaL_@h1$LwAY@r7;R9Yz%{CxaO2`f ze*IF;UV7rwr&?-yO{(`)CK&XB(lTAJj2tE2FJ_CN483tb$ec<3%TcCvL_HB&6HnI3 zW2QFT%oo}i>o$@@>ui8W4v*YX#X>eN952$jLtHrZ!Z`k(%DyY~X|p-nI&1+v2-t>N zn6rauik_Izu_19&d`u)J;7XAN%M?mXG!-kf7X5tuNfLshOg= z?2D2wzdEsJ9)bHXZ0cT3E6e48yEm3nPGO{f0KpxEe+pZR>! zsCQptYR-3@?W*q?75Di&)Kwz0&E#cu_B!OqdE zD$~#ITBvPNLv#+FLoOWEWaBaVs2PuSW70#q(vWuQcSI$5@0SPaiIB1G@4O>f_w=F* zpPMvPb)xj@7fs}L?agYrujsppV|9Af|6IB6d!5!}REMHg%t*q8rJN*%b` zwN>DDSL7D$@*{^||FFX9?RPLL`Gi{P=cTZ?sPmproY@>&-R+}Tkzo|+=Otb9wNEjy zY7jRxT`{NUtpw}2_z6A!g+_0NN|@Tus|>^X&1WxR42;y6ZJ#033~cmkJZQ&HlupC1pE(EsPHUL;ksE^LJ zUBh&*aGhrNI4JgOOP+UKo@X|64tiwq_B6!WEB*54W@BJR1$)Pj;0kX@av=2|wGvg^ z_4j~(2xiv?Wy0D6W zH0@R@v#vm&;Xs~sjVN3#z6SfxiOSg!bup6cY7 z!{lKl+dVk{E~@#63(<`$*OngP5SOU50Xg@ioz9b4l()42^=Z+R*J-xN;D1!Rq{uev zce&5h)hcNGG;9O65AZ!4&`ua{?!aOkB;TXzXpGps{e^?cwsU+cbYXru2m%nXn1BpK zDh$l-#MXNVPwV_(;$YWDEcg-7EEfOQV)g`KEwdit?F{H9wq|;@I~gvyw55?_kfbw$ z*7}sY#v+AT-=O!)TCw&txMd-O+Du(1D}Ec^zmwW1>j%`=c_PDL0bJ40(1+{YhKYE7O| z7ShvAG(}W}p{#nXt{PGh*wK@&v@tRoBEKpxPDI%7kH-k`Gf~&9;AT?yKSZTS6pmex z+-gQ70avS#Xa97`d9S^CU`DpbuT8PU9PNKyFIVMZL?f=m|idb3pSWg`v8qeXCeLIoNbY zIiENc{vkA7G*NK?UJAuXDLK@qef%Lke&`@0cdBL{?9tsZXD*@MDB&Mx=_)dBj309Y zBJ7t*E}=U#d)YbtRneB0#pn$jLgL~edw`Z0Lbd(eQShPMXfaK5m3qadTR=+3&Y-Tk3dqZ{!Y8OqC{8{eo8AtWgU?%S#nWzm=tV}=OGJRCJVT912_JG2I zsr}2t&e@qMo<|CcHwW`%fU)+5G&w*Yc+w&_m;S};$V>FI>~#LNKWqkmF4K8 z_+~u}!^oYZu)9|vL#E0@^Z+qr+-VbpS40t?Nnh>|o7w02)4GlxXXMBael|RwE zaZO7WM6Fn1&a#sp6Z6qotmK5CEnQ#a%@11&JIxOFe>pV+HWU8MexNr9A)f`l_2ta5 zZ2o~nIGg&vnv$pwm8%J*w{{KPA=p|{t}bE`2mFUoz3-^aL3~o@Pj*DE5kH~xBrot6 zW+-Z?J)UewGE|MPlP#2eo0Y`D4D=)`DD}+s$n)0SKBe3V6%DUMEwNHyYMV+w*qsqp z*<>4Q9?+x@^3`jVjjR%Bpz??2Of|li$HF$2E@iH-ltv}@o;;Fao>me61HM-XNr6ps z*tqh13zU}fijgkO=$rZk38e4Avom#XM@7khmCL=f+xk5v|J8M)*UNdDi)tsxlo<(& z&}-z5OBlM`L%1b$^}9nj*_c|rA72B7?kw^xsHqkzl#yd+IjC|a+oC6A952~()(xBq zo#Wfc(=2JV3yT{Hng_28?BZ=jk&Bl&EfgddPj=q~zP%a0I4;{HyW^X{iG*HlUQV+# zPg}SWwlzR71`7f#}8r6dE>?ANRi*y>FO_4 zmW8^)pkU1FVPt2bcHUZL%*0C-s?R ziC!YOaOYrAa^t4t3e^c?61?i;+ix{R?k0k1^engpM94{9?VM(}SJ$rc4 z2hckIk?Vv%_6z~1^@*GIsYMMo9tSY81YcsX@__?u0eQ6;9%e`~t{UzhSG!CA|8Chh zGPs#&7d=_}*9`@kQJ1yEm{er{n%P@G z!^5Y)eUwXBmu_jJ`M>8b+UOW?9=S8&(O(^$Thfn(5DOx$^xW7uOy9{Ep?NnsQt9@r_5hZZQda%@|TBp zPs<0(+R>V=vLQ!*`J;h#;{4^KmK6AQ-a}_e=GWCQ{q74?Nb4K6i!Y6X`T6GKo7Kl? zL3aJ`s6cPVC;qBIL1X}oI)>&ivd3r+1~UtRpSadbkKR=VU?6?P^Aec(00iK2uk^Pva+0 z)QA83$zphwAAG0e5+9ibW#eOh?GUMv>&Uqd#K)Y&kQMzG4ACpSx_&9Pj6>)oG|wOa zy}1{RZ)ReA*73l4LOnJ?{^cwPSf^7g-i9U~x{G1Oz3Rkri<5F%G%(Tort@m|*riUwnfz#fes6z02HADKt5IrPGL2?Mj5)b_hw=_I;#b;z3N8h1!d z72dykgSwdRO+3VhAXm>dTzoCo?xv_>mI%Ko(&+DzcdX&U>cztLSpPrhSG;w)SY>UD zlrXElmjdJNxt`<<$yeA(Gxuh|dR?I_$9aVnY;wFY}Y5N+&-3 zy{P8at>gM0HDf)>utJUh&Rdtqpx>TutMzz`>hiR56IA7_fnjW#vS(*U&K(dJC4M=a zbI_8lk!A-=7bh{ImTG0~NmeIDRUm!tbP4t_ul~VVhl~=+G5*}V@uU<@2+M+mFI^8~9HwSzY?xT>d zoP)8oqVSQbMBhXoUW4htP;`+&GgrlrbAu#WtEGC5GJZC8)a5;A-R#L^+r&d{2R{Hy zXR1dHs{xiKJPTBvS zp0qJ*7NMN9PDqCKragjFWW%$p(7j$7Dh+ei{@0!JW7a5#4+AkB#FYi{XOpy;YdQ z%3Wuhxmd*1q+r?L+zOe@ZQn<`)7lPj?o^vsx6N#)QYau6po;L zW0C3N^c%3btV`|Qi%9cSGX3{#PH?kh^B~RdYl49A386IJf9R`=s^AYuX!5AL zNOW+pa74AbK^+5E^?!a@g~7%mLakN6w7=XoFFd&iQW1HamWV3yn2%O&7vFiUK^!9IV6D9vxo6f!6SFUjCMv=Jj7 zQm`0o>7t6f!!W%a4C_G-rlb4&0p=Jo=uy1u)CChCLH)~>m_*!Xgvcx(B(!f%3wy>e zvDwah9xaRBt@Zr`9%*zl#9d*ARgzHhL^65{h)c|4BXbkqAMk>VCNIAGWgI2Cj5@@w zK9e*%WiPDW*Pui%Qt-Erd$DsI5Ug{@O7^VT6peG*3W={`8x-+LGqZc{OB~2B6uaTm zsiieTKVEund6(XoR)iTi*L_0;X5Q!2DgK_8s6k;VxOL;)xpd($Z!RueZ-6nW&}^8R z+o(D{fcF?rgcvRIV$}x~Sl5nvJWmkIdwI9pt@SIi^vhk!OcMsPQQLT!xbm$Ggaq*i zHD#f=+)K{$6dR#`B|oWnv_u1qDxn-xdfx;_#Lpop>PVd&XcYT3unPacrB}b9b>?cW z<;Np%=8}NV-SXulT+`?tPX4{Iay3luZH3#`Z|#wh=fQp)4Qo`wRN2U^2jUy<@6D}e zUgK^KK0%T7djEJbyG8jvC5+|J5khO)_<<7@e6j>gAH!Oz=VwYUJ}O$uHR3olZHHt> zLH!dXW7UtKeGRIYo5V9vNQ+{bRqWS zv6pErP_Ne$AOggs**SZL&}g|~h>IiSi*r3fhyDk=sxEITdfiYk+Yy2LCrg|P zPlt{7(FQavFDDWYE>eAh(@&!#pCL#Sm`)I)*+{=J5vWq&6?l8Lavo00^A|ZGL&#mj z-U&k|;>*N7e-`Sw1owy}xui+I-2;!`2j=jr7|{c72S=YnJ)n~y(C^pFzooo-O#~!G>yA0Z(;`Tc#otwS zR}t*N1L04#yJHv*kJk4WE^?ZW6Kt66fDXBig3yI{D&h6Nq6VZf@8ccFrB%|x8)0BT zb9O+T&z@)U4Xy>0O6dkyAA90#6vSwLF{WR(qWb0O?FTrkNv8C4Z^e8I zQ6$x`vFLO2xWx;~#QERgGZAtU0`IvP)NG73)AlCyb!5y^=l-2f+@LZufiaP?E zi7H+jMD4F&J)RvG&r0?BdysHD03en6Tub_VwpoF~zNlUdTVF|A%sWyUkH|srVT2Im z5(t&W^)~7@?o)rqa&~rcmY`-AKteV~ns?K=wZz|sANa={)rn6_nwBbmn?!u-14>dS z#$$3v_H;=p{!{(V}_%j4M=|eZ%dW_cOw7Ggk z^_eM$qzpcpg4t(MQ)eD-2XOX&&S_$a zgEE)y*{p4Gg4-nu&*aCD3Wz8-hQd+^C|yjAu%joB-6O%W#&vE(bm!+aK-NDnk^Ka9 zKrVnJ@qWTz#b?-`MPtQ{pOs#Q*t(i6gJN6RnDTF)PrQ$U;V6ioy*DQKD~p;7W1m0N z_T>Q}3d&BH6U~$bgi3sNgK6ZR@7c5Cg<}6@szzMaeQ}2S`*@d`G7fyApBbyyVpwzC zP#bQcJ}4_e+bY&EfVtwP+tPC@2N6TnI7ba_73vYBiV{A#UFJkDT=&0(G}SJ-PtVUa z$@v7NHE6!d#wCM)ay2;Q1kRMLPW08$g2M1WZ8VyEsC4reqEkevjK}RZK_{O*r2NS8 z9~u5XN%piyR*QxzYVp_rZOhJwXFlBoetEQLd4Ko6V$dQjS%1LT!5IM`E8WmbiKAby z>tX2JyZwY4iO+?*h}08}P75#|-s>baSzH1;F#Fum7+y$(wiHtBDvbYEP7uqlTTdOj zUy*fRzo0MqY=W}(WB6}WoC&<@c)5*q{iVSZ!O{iL^3p`&x7@IMB7&x6C3$WjynxXC zne3KMhWL+yV4}6;lK$OQ^60k8yBJ}zo#Bsun(_2ZY{M%#T8F_Tn|^13SFKH8eW3oYD%CdHmWwjnBUb= zz5dJ3rg{fHYj&L50*{a2izFE=aKI?1^ znK~8J7{7Qw#FhK$0FHMJ>{%D;KEf`1IFvRp2-xKrG^Adx)V^IwUxe+_u8 zU&9L@(XagpWq(4Pr5piqN67j<&_QQusqE!M^Khp+sWT4+H>cW@NQ^G^aVgQC8984` z$K$62SD#v)ydzpCd=ltsdYB8b_wm55Ku_uBdMxwL>c1eR;7yh(53^<}(F6`k?veNd zbiMPt$a6P{+v!~$n&5$ z=#Fh5KKJ~W4XbED-$EsR$K_%}+A5q!3wm>Pd+aF7>DzdDm2(QZ^Q$0E`S`>-&HU7$ z@ri)&w^Eb6dAu@9Jym%zBpcHKJlc&h!jVcQkQ3^{Oke=??y8CmnhbjFkfRseoA?xO zuKH~_c$y-qx=yLWpL`3}rUDcr7*t?URCBHVV9a;04(nWhfGbAYT1`0`F;byc0GmS3 zM58LJN~Mp}Sl9Y5_%JhAStm=V!JxSw+@YIFhZ=hhS193r+TFm?%D(C%m!T_}jiD0< zj3MMAJ``!fNH3mDi4MwaKGEgZLGLhL2#RbO(8O5(? z{MZh3k8JH9Qt)f69I_ip#s0+co6~Uct_V!ePmp{7(Wxxm=h*JVkezhCC;z^HApqwI zbkAaA8RwUVrFkn3ZWB#A%F&~CL?KEh_0r#Dd!HoDF4rhD;!`SlM+ z5$8)DF~q`5?48;7qxDcOI!IOiDr!~pQ>;X(FDL|*IGMyao?2bgWW87NYx|Zi7YAUV zx^s2_GHXS-)l=22t8;t~_tH=({kC7(2Z7O!Gw5TRB}V8kseU~xb@W{|K1HGi;g0eneM3H6`2@{(MvPlO6=8@r z!hIOV^Hi9j!6&iZ35$4)0LhcsSRMyKPs)RIpmO9*72;#19De-|@^FK(28K(1U&8Pt z4mS+OX$O}dX)tbTnE*aoeTh2{A=bRAp?oP)UH1H7lehTckSb_s0+}bs)TguCcWjx< zTO;(wp`+VxmH+MJK8JaXc({)8I=-Qtbiul&v$)Y)5u3m}+%5dr-K^X$n(c1Z0<4tS zRsCp6nb>chN|NVKTo1^GgKG?^N5j{vp3QF{DUctkW%NaRkaznndx?l=y-aWEgU4?+SVV zkOI$6$)A;OBrc^ShGp{}s0m`rK?Y~C)Sw})_GRfC#yaM5$R1~ucQ-@ zltQ-#6_>xA9nhbe`;$XuZelE8fnllwSF)m}MwcI}hZt)7hAx*ZHM6OZbwCF?tDk=; z!R#VF*`#4CLg9`pGNC{ibx}}xy!#CKh903(C%bZFKrO8CtH#W70v$2*3z40fz*fr$a6GTgpX4c4s)y%y!G#nXkGG3(v*1cbm*FYW5txGYgqHKJ+c9`X{&=kX9Cr% zCUZuo7)wDXGOWL%h4phK_}Hpv^o>&@r!&JzlvFe=5pEa1Mnl^u$yh3PMnLHrq0heIpX^Xp6 zf7+?41oxK7@2u#bD2ORwXl}N7=Xz^?t|s?8cbH!ZqNAQXw-s+01oVOjf4vp|uMy4Y zEAzKh6snOr#^Q*&^8g5?I_+N5LXk5N zZwjy4$51rK{03qI##6>mQ0()9oA_KttDDToVRV|_~6eGoTv z1Iy&NlI+46x2kW0Yxn~&( zP#sqlk8qj^C%x} z?|0+wP+z`Lfj}E|pPWm`h@46K`&q%&F)#plrniG~l1K{_3|m_;_+~kZ(&>Xc+kDI4 zR}D>Zf2NbMGU9CR%=N(V8)o*b5DW^xcaMtiM|iFi7B@MaS1g(>&tD?Dav(tmp{lC| z_by`bhNRK78t8#YiII1hPVyAcl8!reW8HZmsSjZ-_w*l*Snac zU&_AtW)o)_i~Qyg&VsGK6bv&5rafCaRuI(P@c=LzhYEy*2gs>VL&|t!Fax65CIq#3YL! zr=!$vges}URFXMq5eYDZ3fZX5@|*OE2M$Bk?=di$7wv& z#;M)^kECx8XnFttKXiz~P)WKBAqhK0l2+q%=(r?=q}o2DlThoTw%RS-MyVtUX+wyE zc8aXaF4fdZX^5iME>>33wys;dy?-y?-#;!frERa*^ZB@%lYbn>)k_GD6Vra5M>_y^ z9RLab;v>HF^Bpo7knoP+%eR75x;FDF1~frrx(lkm*4hz=t*hwkn?h)^lfJNd_1v!{ z+d6VszFfvEXY?FamMjkni)X#$ils153UqKDd!SSH(byOWybPNZli?4gIjZ1dVy9yd z?P91#x=*#xXkBIO@rJbP458oSDmy==(g|*3z26DPI38Uh$_QRif3!to%9&v1t6AX@ z8k9s@ZttOFW+&;ej;r=)3t%Wi4HBA%8HaoDGpEO?bV7F=$myZ$No_9JZh^@@H033k zd}w?b(%f1Obv@?PK&zs&z#jkjou=cK`cR^JKVRZS_pQ@*j@TMec#5Xxqwz;v$7=Y_ zm{H}4$%_lmDGj8xle2YsB@@Xyuj=mlKis`JzEuv}rXc(6n+*_!&(huNa6%Ddf0=Lo zl^oXG08*`j!?!6>8izT8#&lp`RlDHl(CEm`+S^+3uzHgNu0Qhg9<-lgvUtWwGg{CR zR4b9o3a7Tu&R>tWb2y^11pbxa8pJwTV5;({%1!u8;;vZ)^yl7Yie&TA(fFuHy{fuB zf;7MJS#i78Dl;GRbUj6*KXwH06Wo12a@&^GXO#<*6%Sh>WSiyv90tK+X!mc9kB^T^u5 zaf7X9g|PPEwO2KXodFe;)d5*fVTN0~2R^GF>h$oL7SUey3~F3TDm;yPEI(Q3#H_(N zUPdRyR*mEths?o&fn z1@zsDQ2x_~o{Ae&|AAO&=ZUh2v0Yp4PRO~UgPxu>K%b!Cp8J?sx;72Df^IpoF-~(p z$o6?$P>k8;+=&>JxZ|6FE$(Y^K(^X(gX&{@#Ey~8tidL>@{eS0t}P%szxx-K;+`=> zopSGU<3}Ij5u4|$Bi0BS%H0Z2`xH=tsC7QsZHx1Ce~{EwQ#D-PcM)~F(wIY@7%lvs zJQF=+$|ytC#T@Z^r1tA78NzJ+*)t^@QnF}CAZ3UcuFo+_2$hsr#b~(VX8qLUL!HjA^?Z2*YDrd*q(V(`gpsQH=r~zHn%pbYi$TvM#L$0gBIx zr_UhMYsGIWP*|&}O&pJL> zG>_@LuTBLFh72Ypu6T3KX5E8_qmfNfM#EcF_?(pY7HbBi)$(RZI zp+lcZX;*2cT&0mOf?1C>w8KzAam)>Avh|YykGFdBjYGz{02&8*p}MEbk(9CvxV`x9 z##}>yYAfrUHv0HxVH3LOy?BZY)+uk0kid|y!6Jr~l6?x@;=!MiEXWj{Cb%HeSAH;l zz>@y>M;rKa0;6f5hCinBTVAR%Sr_DU@awRj12a*t$5$CjU))-*#sNmYHtFT7@@Q{z zavKT$kMVlYD+=EKKKv4R%i5ujt1OAmh!MYO-ak9uXsl`P+Eb1j|GSOpj6J9F+`Zi& zzwf@X_R1JsNX`Rx#fE^U7gJ`W(%SP67U(F2w<$5>+sD6_^bbZ2h(d&e$phvkt?jKQ z%)0iG*5Yji%mS))|DX{$Sa$_^w@2(0*bX>3&h(PtMb7vs$0|~UG}7l|wMhxbsZ4DX zVbH;IZckKgY6+f>j~?S1|LmCJEEd1}L{EDFx`pO=D)LVNh=*s99eV@>UI?0S00u>z z&|kF?D|D9!OA;xknBvjif)%X9lAqRhmf`xLB=hMBnHzeRMjKrvhVlBCwQ615fC;=< zR%MCQ#5HU9U}Z3YQ9@mfmz3ZJ?lu`|4WwVbt=zStJG!?u@*w|})dXQnXq+(xc$IksxRmf5cPOPbpkUZMMPy|oMXCe&~}c;KDa=_bs{RDL#aTt>`cG@9Vv z#$hZtBL@@pSI04L&_ZXPc>|8LZ~PA;c;cr}n%aO`iqj)Vx%n6DFMI?XL&qB1Ro|~a zXSjz^_D);-}ym>2L%mG1<1dga0w&j7r5zcr^RFR$sco}vcNJjGj*3|3q zTzl3l-#Rl0cpELQxAt&t62f4etKp%CzfiytZ3?{3?!fDe1zu-`GZ0f-31J|>XC7zF zzpYI5-Q$JvON)i-*zUTI%WxGggOYZacw}E&`E{cK%YWq@7Sl%$&QvD`W&)mi`?uS`$sv6x z4Gci8QgZ(Titp-5Xi%mlOD!r4kybOEPNjbc+WW+)EP>C=UvkmJF1fyK0>DESIKbi~ z^zpWfZ#KouSl1;1cP6jYuxlAQ!(3;IN%d;4ea_$Cc%J@V8M))bSWsf0 zp9SZ^d-dJNY-i30wb)X7zw005Zpf730`$dq(#oaBG&daY+6i?bP6IP=jRf058eA+LCY6Ienj{zhgakapUt?bHt;q z^6kQj12g@WMERD8`qn02!Ow*l=GQs+Y6UZ=b7MVlQX=z?Vi2Tw&_)Et2 zFJtZqTJk4qTT+t{QM1tSyLQ6D2}BQsbOa_Eg!Wo52d4wv58D*A&+c(YvMSi2uLQi@ z30P~nD4_|-t!~yfw003i3BsQYj)Qd1>noLJww3N^L2 zTKEKNonW@7g#22J%bqCVo~yp!kJc;@)&}r!PDwDuPjQ+m4bWwt_|^sGUf5h7_%=I( z*#G*kUQ;u&`IV^h-^3&;fg7}o6Z=cp2V@C}#PT^9t}j`vbMD2AW!&i1Sxs z*1uJKQ>7d(Amcxe*@M*Bm)Wsqv4T=JO1sMF^@zNXRuh;d&IoX>k#BCn;@)bdRG15X z9?dX0KQ6|}j6TybzmmIp7Ts|5ReF@S{`yaOyz1iKZrN)6nY~%S*y8&cXmc3X7D#Q4P2&#s$CK z_ydhDsyA#my%u0Q4QsHCU21Sh7)?e;(7`B^W!6)0TAG&{%a?qvT7a65CGF~#FF?i? zjb#9ne`M#|vGen3GuJ(Ag!E4_|?s&2~L*1fWOB^#$G74~%qJ1!>8NtdjC5nQ#vc0t;C5K}E#z5K6*{^y@R zaX##u{`B#V&#&yGi=IACJfC6eD&C*&Q7?Ehpvh50Cw z-<0AxE!)Rr=FNsuGQdkLr(ksM;TGFWgz(97NOF4$O)}_%y12uC`aySQk5Bto-F>^R z$8h|)S{yZ8H}fZ-RJm-td(?V|A}5(~x-^k`TA%JG(QO)7zFaGpE?_N$h18IZwa@!0O!2KCM|sColvP47MU9IX$lWsCZV1rSrFlq?&B0O9 zXJDHZD399zAW6jT?MpOEfua_)_TpEN$2Zy>Tm&3gtBEEt4C-5tSGs|RWP@!lJMKC# zV{NNYLX^U!u_uNWQglJWvghi~5d(aNw#x>+Tya>nT6-3@YnR_sBLwdJ|rB!s~=_sZ4p6zWEsJ4f6XlX*`trW7Qg|1 zAT)>d;myb!H*}S{Cr5^Tc!wg|lZ7Y5IAsZf$DdXf%izdL%m<^tfxWCkNh!K5kb0U@ z&VgLcONLU?^9uUWc{KYzgdBxG2y(YsAa{FCO+RBhjNu?u?l`4VsPSv@7l_PQYgHPGtdfL(=shCxTwO5)e+n@3o8{zB&}t(Bc; zB)%4IG?od%Q?-Fe-Z!4rHmWO)#xLUtu474%{N(pX!-k5YO6VaArgCeqbG=Filxb#| zLpt?Wrh+ACu>2YWf<%vu&lZ+RBJjh`Dug?OrN$0hP$qORF^b_F`UZ&YU|oJhG%TTRSQ3j*0Z3?5Yy7oypuan0mJ&e2Uy z0UZinF;!*vCs6YC;T~)fH?R2+z&^!2K{+G2;-Ro6^OH4t+d=)|G&rH`K;-97O!>3> zkHpLJjE3?ejHV+-2^qFc7)z#erp_(r#2;v}O%I9=6+K;&bZbaNiXj%)>&ZSf(B5kLdWQU0*Zv1g zeB1Q!XEg;1nlKlOlZy{(wiI2icnf^`v88XtUr5fj1?vY9a zca(sWE;34Ul!{W^q>}DMw3ek86>Zc`C|#%Q6}tCaO2t{VVbnt}!o~S~*oi9a#}c{R zl8Jn!TLru4f}q|L+KHOr^pBLk#~2#OGV;@~A?x>It%NM|sj+WyHt5X_)pmn5?aJQ% zo(~jMm3X^{SZc(OjJ_0!hAbm}3Cp1Gqzs4aa&=)z_vyZ<$+7;Cpo%Vie&qmR z{lO`&Zkw8c&4{EX{RD3PG(xCjnQRWC?;p-TdT?8^rl*-cFQK`X0GB$6{K&8PA6H%CBfNS)ZOj=U-RfyhV1fD=u)S5Sf2FQhme^s)5Bfg zbC#tz8L88!giO{bsq!$;kuO;!|u91;F_-3#ZcL_*!Qv3_B!V)M9D;z zedK}7S_oFHezO+Q$nx))Rw(yI`-^Nn@DL$?2eJ}N&Lc^iZMC`{b~&MC0ZZd@TZsg5V;7a7HZ$Kx zP2aE++-u6?8pgcRmyLh$I^#9|=?R3{ukfht?=)*H0h1H>H|NI)y}aiPWNC#AP%@PwLLO&zveR zohaCa__kt;Rt?;UANr7_3x4%gS?KYrmG)gddk`t#Z#|<>ReDq;XB6J|!6)yY-1~gT zS--xaNALUoLe%H>KVwoRr;+goG~Pw8Cco6gKuvz|rw7Xu>C8;gHQWIa<@G@?(Ux^R zT$K&}s7X;m+hU~g#8Y@CL(`Ih*}0Un$QqQsR>zU_TX?SA_AfhlWMe*YAaqMuk?Ndk z0Vv7*oFSmQ$Z+Be_7jPZ=4Y)NWfxxeHT-nx^4h%w=y+CPs)rSlRG0);+=>%F$&^bB zt8N=t3oWjLsjuQ1n88+gZ=z1($)_IjI}KoE`v2o+-lG+)ej_Cxlc74FscvNHd1fc_7gTKcL^UVI)NdByN>`FNpe z1kxElanDX!rIJ$MBVTG)vsRD)q+Fd3-7;gT;NOXnTI!GvrP90bLywgcUa-F#1&ClO z>r}^f!Rz5*HP2)y^J93H{nm4(g4~IUdE*wvS8F$96UHy<0J|Q2qc|OzgGBXIn`E#q z6DLrmJjQAPhc~14-()Dx_vDnwYHv=DUvUj;dlGQUbnZ24W`SSKXT|NrBBz3$*9DOU zf>7y3#A+C-F;pYt_8(6-lL z9dGyUj`Z>riYN&LhzKVjH&H`Am!98|FoDgmrEb5?fC;^b+s-4!mMh=4pR7Y|>IzC1kWPLtfBHz*RmBo=ABf2* z2ZV$l=?ETfM7(4dS9{wv94@X>(o$ii%M4!$NB{P2yAo<%@h>Qirj1`4yRFexx!-*B|($()PqQf}x zH^IsH`5D+KFgoq6^KYJl@{LeME(QZN*{ZCjdvd)p#TBfP!*Ihz{6||F$C- zZl!q+BJ@G>i)K?{&Xh8&0~TA4qQN;e8+fqB9PsM{mZCcH0R;p^;fTJ7JzdbH1Cb66 z#`|Dj$=`stLL2V`nNfTt1Pc(ati=_^Dd*nq{EhhCDSHY=ytgiSfg%uqjfX%G$-Ojd z2@j+K`dPB(B8(RfXdK<8x%B+n>@0fgYh}amgqU#~8hOmFH8;%Dz6j}_2^%`-1f8HahdqVhv9scSidNErc<~7p%{(KCG zhTMg?sP0VJJz1sx`8>#%Arb~Na?uix$E26JG{~WQklP=ONJF1KAIY{%Nl=3aaQz5= z36X5G6k1_;i=n@7$i14VKSl6nLmt(*I@q+vYiIGqWMs}QSEo^m^~)r`aomL%dW9bY&80!qpgPf&Wj*rvI- zHy7ex=x4Y3i74*}J-WL-!WuSG*QZEfw+72EJ7p3jzCZ96p`d{>K5T_C(JXoXObfqs z(0voU*nTS~|4?g4YjFkg>?ABR?7LxM(mClp7a1^(?FoVGw(93tjjtc?Er)IB@k%ik zaau$ufqLi@-@rQ)+5yPg5#lk4|V*QKP zXwUUx3YF35cR{+A{Okp4(S}h1$=LHvC)`zQyo7C1_u}Vs^fTxRus;q@`sS$*dsO4K zi>}}jgdqS+=moAO~`5bxbWk z2yDHc%2l#b-rwbv6AIK{4ur{7yo3K`6lYqi?cDVAO{{xkd^@+!T>pyZz$^sJA)W&* zt<|-is|D}6NIKzfA#d1F+BmA)HVZ#Dh6xgxf@{7&mz<sffFXDPPskIUrySv5u)*wN^T4 zeg;$p{R<*aCr;TMobNL}yX~1O9C1y$Rq~`BZQ%J~lK%clO;$P?5QU@2-%!(T zHss~BOR&DC{Kg*4WGmF0W=-Y&Ta$akC zCgtQJ;RGQ)$AHje{fYWrV0U9CyQv-I@$A)Hi32o8aZ3c~OtpsXN2kG28+lKg`u!GN z(YdSuDSH3NqBX)LHhJnbvJ?7ip%Bma*8}q3M0j0k3|a@9U%xRTzFg-V-)h1@4h$)e z{Yl;kCbPYx1fSr5gMQ306CC?hgLEu{f6Jk?qc!4L3M9dK{3K}UnZz=X3IC7Ad%HFy+4vV1DgZZ!Imp2QIx92OW69nc zsQh}QL{YLK1s(0#v9nbTh(V-n7M0>W z6}}E$IcABR+HZqh=2HeXxSz#th6w!8B>?O^Jmdk=`f*U^*hIH)6Q;!!o{C+etDT-$ zT1mIvMM?CnNMEYT#kAqOREa=a(nDS=7e9Cke>G;tiU3bkzU;He^?2UgsEEM!US~X8|#c9#kJwQhL^ZD?fwQ}VqX~0zjpMK z9Wt&MgpJeL`&&XT3509g*)dt+J=n%@Gll01fz`1L88v^yq_1iTNL{5`N!LhMWs>JQ z9K8|X;4_b@3%uD8`xoRPvoeSWN(}`d4R9f2DtAA`?9zoE!|%04ya3a7WT&0Sv{MHP zoO&AHmRx1%3*(2<8F+FTMTo~XkJoQSrgYbgqYw8(vy$i3_WWnjOxh4J&+h?hf@x&0w%^#6N6W6n8G|J?k`71oSJ&W-Fsy>yyhS(e^7d_43 zH{<$B6QYzhpTuPZUQZv2H8~U)C%&+pywoRB=87i@Y9>K>w7OOGQne94c~Qf_nzM-) zWGU@=b+NbUg8&8KFPRPzd88u0fIGo6QQh-R&ID4Y*J_-022LER^y(qZWf$;AL$SLj zzxhnz?=vX_=UdbFc#e+#EZipXrzddwVZ#X#o%XogTe2`Y&POvYisMh6m{$v7&p?-( z)J>y0uf3XUf1*ra4b3y$wq~vPY7d9}91KC%eN#$W^Sw`nilDDz`39d|S@LuQ>Qsr| zQH_cNA2iSRi3|Oivqt*WDX$$I9C3KzW%(xqS9KSYg-I))3xYZ|cEURG(;gJ-kF&3B zZ$dr6q|M606kgXT7~R@r^&GkLgG`HSgC(i?zn@9zQau4^YTO*eIVtMcwAzdXJ&hMW z;RS4HifZf+xH&lLSue0k{!v4O>>SdS-LOBhjXzQA!3le?af>RGa&1^p0-nM-v|~d- z(x}~0xfdSt4Wl9R#yfC88+?2H1%>>uX_eVdk18}GZ=Iy{-b%sQDhWjjooCIiVXxA zh3Tde2dd6#AFy%lKLs_I($>nbx3tsvUe%|UpJgRJMuXMhI6{^u=dT)&o(lFkT%$_{ zdA2q39r2HLILF5){^abtDr zDzb()|0z682U;-TM^tM76KJDp&3H~n673a3(DUXko|~t=&-W_V@tZl37CywI(_U)c zS*#y{A5GFz`O^Ai4__=a6lo#LqU6?c-YZdQi~v`Jjk4eZL7YK`3LZmsaY2g7(aBuV z3mtS1p2Djcd3Xx-uJn}q`^_&k&^>u_S4}0>Bc=1Cy8n8+fYTA~3{(C#G3M$?{{27< zozevQZ}^e~z$CA;20PUaFpmO=FN+W6QTQ>{I^+VT&b=1ixjiKcXYbrH3l-nf_bKTn z$GDqD=&Sjt{8J6>RFv8(Sz>2{xWHQeu)mZlm%hv^r&cL0yX~A%O;>heNpK3O1xg{2wxkPWy~WN+DxjAu&L9WXRLn0 z4y}ethCKK{P#sb`1madPoD^Y=_`J3HSuOmlychSbX3R&hc`|*dp1Ygy^$~ftA>5_D zt7jAi{3(h&$FTbQPaaKp$yz+GHiN3ufa5J;w%OzFN8rhl9b3qOF<~CHY*NJ|Wv;Dw z(}`~rjm+Z_JJM9|)r7A5`4rVx_}{=+_^;dDSIdmBN908cs9-g8l7+Idmj7v`S%5qz zOWY))w~le>KIRMrCo(Tc^?kQxNrVVg{p_`pJn+sE-}_O33&Ta zhre(ibKC(NV#;Ws=Bm`aBehppmxM;q9Ua42X&a&U0h=ezQ5% zKo!HY9r;M>Y&<{mk>k?zELJz;+q}R}!)+KDiHHC9XmG?jTT9tGqs=@3T#1~$;{dE% zW^>RIL_Pd)s#aMc%Q7)R&nc2CA%o;y^BuUyI-ecG&unWp!dVwfF8D>)s5gH-$R@03 z5+XRWRo?2{9A!99C4pN`pol7%8^#$A!3k4SAf!pR>m}K0lzEvr^z#HC3##CQE-4Ab z1Kr%B3a93Q8Aj3Onklc7FD@YSPu(S-?D*o8OMCgH{J*lv>3or-D}uNLKWuZ|3B<}6 zLcOEMv*+%qA4?Qq##{XaIaf%{ONleAThA$`qF9jPzhOB#@G|v##h9DFv9s7GbXd|H)7O*ZtQaMY+BXLpalw_^}M}}As{m8A8AQ8-dvTa zdA>>SMjW~~;I3h<7Om5N*>#)D%ufzkk_Y4b`ySR5vhrf!pZoJ^cfve?;gkbA8XOKSl^~)@hk{3H%zCHEg zOF-UgdQRJT0LVK7(&4+87|my9S zDjnU7D~W#r2@4E<_!CO6St1{QyArz^bh4>7?MANEJO-)gw!Z{4@ZlFY5|GWL7jKf| zz2%tva?Ur`%6tnV>$P%K^6x&T)fE0l@OmkW1*zW~|rEaWwfEjVxYIwLBy2Ak%!ms)Q>UB4^6;K~dviF$G z43!MvKV;=MbS>ge7#5B~w+{F%rlpR^Ie$Ig0?Ti(czv-*!Uw^)VDJ;A5;ostEyQ6q$fkS>$VpKL?wbEDAxL-Gg3OEJ zxAB)7O@SU>jXsxG*sac&?%kbYrUF24RwOtAF^Ast5g)u3SXmg?#BlE;I20=AVOh+1 zI1e>jfZ5O&FdJN7<%T_+H(Hoaxa_1uj>=V&BrXMWDOTAxpe#{cVn#y*e}RtKVO{^; z{62F#lTG75>7ouw%WDe!Ykb}(7`zLHQRIGE8 z^LZ&{=Le`d)@S8t;X2{eE>BpU>2MJIs6Y+&W_~_+d}C9q+~;vCilvIXooC6aS#BW@ z3)awFPJd%P`wh!0Rph={iP0RzdVT7lsJ>shCG$LCJHrt;w?Iyn4yk>D#@VWB#NUQL zKzWrbc!8EnULgJ^Y&93B)!X+5FG(KF$)168#&-WoG}9NK&XY$*Z?eZ^Pu(pXo)#DC zLMzu+hdl&nLnOy8LGQ3Kn>g&^%2&=h(i(V3mZ^zsX-F+MPoM#7!-zw14*CmL|L3*W&eYnN&G(dwogFn%+I+|#TuzO>N+^{ ziJQ6;#Dz2pKH}X*_=pCUFSJakw(G?$OV$?MI^Qx~KN~sLeu5v6{H2ckd6WXwV&N^i zqh`q_GaJUQ16eZa<}_zjkH3#*D9f%qeG&3>ycAjhv=b{h0bmnL1?D$`6>B!&2kb=* z$tJw+c$+u0vp#b~Zn6wIiXvW)ot%gZPd?QFsov~)E-U`>Iln33%jA@nir9L(h5efu z#NHUMwtvjVenqWs@RLp}z3Qg&k;L+-pfBBHDF#PzO`tu)2Qrj>SC8rmsPPxk1E&VQ z`bUCjZVBUaJR5Rk=<7lh<;a4u!mWS$s4B7|3ej{ID&zuUeeWv|w9IJ|G9Z)U`H(wAG%Mq^1L-qyi=+@(dZZT#I9n0bA-ZflFo=~vJaUx5oy2LK5^=rc4A=+bY4Zwg+SI}2Wl^OYs^B4&@9aHp&lu?o>(;zEhE)&g042D_-*_|N$6duDF~WA zT0hcBS)|nKU>G+_Ny+R{k+}%U% znShDYN~UAfy1co>$u_E&^6N$Mk{DjUwcWO#3qKphTmB2W*2gWG-_&RQYrY;ywNQ|)-EaU8}Scpe7X2$0St+G-LnE|WVo@`A)z#0#jP=8$t^!``QeH(s=b(R zwlaVpVFX>x$e$|vz287ZX~^r6t*k#*^~Eg$-`L%o00G_*x$X?5f@fh-WvG@Mu8E4g zoZP58;K=@_hbivdKrRp;8RCO*S6UiCS(b6!?k|U=Yct6+xA)9^9ZkP;n_RB1zSd(U zO`iV1wHh3x7CUv2AN)se(!H86lWUf?`mKvFJd~c=o%~(03tS}u2j30lse5P2fG9~otQc->FBq{iTtx`ucVG*0lB#-rPLW%Hk6()iJ#C@8~8 zdQiU2e_$kAC4@Tk&jGcv3>lMwdkdL!u=@ZACw2acvQVu8@-$L*Y`p5%r%VSFH;gx` z>rKQTy)RDVm!IJv1uc0cJ2ooP$9T5clT^w1z>f#7HhEZTLC-}2t>dLT^gkO=dQe&< zy&B%*Z{|=^VI8gbzF6_qt39?q5^~?Qs!Y~_d`qOO<7n}6q^DyS9kf6n$tuk3 zK|A*)&f?6XZ~5rln>c4C_DCl#@tsubPPJD@_qCQV3Jje(yB|7tH`FEhaxJ*`-}Ssr zb_LzdrFEzuMpSG6Q(m6#-{gVYHx6Lt(+;*>JSz3Y-WZN)P_qvohE!i3Q3=x_Q+iY} z{v~i(gHG~4ko23wR~r+|43@;h0ET`5#{PD2=LP+`^V%I0oS?2SsL5Li+}VGm6bS6MDMtSr30A=UAK>&8)LermdNO|Ka}G6E>2E(d zsW0oP+x579E(ZD_?ezM$Ta1YTC{HeWDl)$R8_8kxSL-`qxTGUy4(UCV$0wkMpdOg5 z@nv?x6}#~ke=}Xs{vQ7-;|A4Re>Y>@vV7p5IktN{ZK4u|y)L6dL`SHnppm}DQp?xexxA>1jsz6{z3dcYqwDvmq|8r zAnXLsJ*b&)_(d=%163=8Q+$zO5m+ph$70poBL^!S;~^LgDZ3n}IL(G&3e?19B=kpe zFOZ`qXOep_$?fnTE(KYJGNA*a*ju>1)}B1ib`s*A&qu$jgjtq4?W%#sTE`X~F57T> z`M8FfS987SQYZtU-(`NG&t8*$ZbXh%I#%p1Aiw^-B8*LkHTj@ zKG?`8Y8#!%iTvH`AV_IQ27Q-6mY2!58e8Wd(<5kbG^0_$7rqpj9FA#H(>x@j0e_3K zut4{pxu>=lWGOt5oWdV&3|Gm(aRcBzb3okB2F+g)nt4J_z>##NF5{=bAHTD)A8|VL zP=+iW3$SU<{drE~tILELkTvVU`vB0gr}fm#&m=FQ1q}sBf`P)P3zYdfSxE`#1G=L_ zI%yfe4#5R%>GM$1X8o+)(**us90{^kq%qF#9P3BVH1C;7j^;jV+#g$>7`cBx|G~)$ zCNyvGN~qZMwU+zWR>%%Oy7ki2#&qU<{*HXG_6pOd$k%@AyXp6a6hPK+TuQra_n_HFK0s0f9l84Fuq9Da=*A8Pr=hv3 zF>N3MVD0Bsr+~!R(M(}v`t;lavZnc9fs8bF<1WD;xK9UFM6x|IrCOr}=jb6Y8))V? z>#=~KVmyNOR~bG_%P`jm#cqK4V1_Hed?kjxt|v?7Eo&Bgrn8 zaY@UPr)}Aze}$MX1HgNG4eV50xsrE&2#$cq39(VD7@-Mo;<(MaDxYHY$zY#ZfOvzk zFyOhJcE4VZemq09Uo!GwBWo5s=>)|R^O%Gqzd6AT?!Ik>Ck|eYgJ=u!%+Qj#5; zt*QgEFakODFQPn@YE1@zKxIl4^tQN8i)PWGSQN_;XoH={nFD{B3D1Nr>HN#@NwAi>d68PD6N{%3(UHWzg2c75~SA;^4KAM<)k4s;*x zkm1FqTI?a~iyT`>bFyPCfU#hJbu&xu@jU6)jB!3uvMtJKnY5xWWhxQ!z?&&9=Ko`o zEZZg@PgFW_`XY7^RUM;dIymi!Y912231(rqVZF>K&5zL^7e_`=1G*J%+_m^h>0R-P zc(Hw_^!2q!w}W52Q&GFWXumc!2~hz+ zc0dy}MQ*d2f-!g=?iH%yD7*LiIfKZ4pL;Xb`xN$N-oj0C{Xe3dYX84^2F~L>lP#=^y@oYHD7DE*g?X>!wek93t?`>1!<-`OLB6FC4T^fCg>L%SZKER> zuve$Pr^km`q{6(P028M^J$nkg8vLHp(-4NeS@cYV3w{=7+{yFc4e4i;XTC+^fMZ3@ zLtqyG)QyI++-rs6mB?(Rn2@CpTkeqR^@6#yHNVuktDu{#Ufh#JT7Z}Z<24(c*5OW;4;Bb$qypKF z7gvdMerZ!5y+m9$3IO~^x1Op!2u5R|?OVwjJ7hzCGjJNR_$7jTyOn6q5&YwkG+yjS z+b&;S3oWFp-(EZ>jjGWYZD>b^n9?m~irg)mU7F@Ml*Q_5|F;}Xc@A=IF@Wf1&4#}o z+sK+ZVS}9oD%`4U7%IviwIq9h*}8m`(f((5I73WQaQ@!B_T$I))SG(!ISVTZi8Y5?0+e}>k44L|<4%jes>t#k1 z<_r;jW|;1SxA!@BHK0Yed>LwLaeTngYMGaHAO6W`@teGJYS5HDLYVV%2!X_^wGory z)<4nQD@Mr#j-lLtNCDLm07>uSSl<&+MkjqxOyvya?@nT1{7{;yoU6L9)AHx*rxzmB zD}K~*BC{tMVV{zf5q*U9i8`3!XEa-O)o5@5LF*UugUx2f`p$R>nyh0A4UFFe!gady zHlhpbzoRsJe5Z5Pv3jpf6cX+v_J>(d38|0sDP6twYqH0%Cke%Wxf*XvFOR{%tQ-Z7 zvIJEj?(M~8(h}glVb8`2p8^&32<~lsOke9e(GRwC)v~?UUJx!c2Qz8r^i5- z@V6o2tvU!nxL)iF^z#>yh##6ZS{*dsAsYQ@jA`>)SzHsjoPY36QfV}_Qw;s-^D-BC zm6fKym5#h5RGZ4hk=NjTd(b=43D-uZ@>#}vuMi{Pbq9Y{z%;IxyDPcssFng5ZerI! zc=Xprj=f6b!~cM@rG`{`GfS`@qy+>AJ`{2#01?$HfFwb;c@xV}StLoo69}RvNjj zNh`qX$9qMVwPdC%C3%4l{v^oC`L%OoB4`f9BPh-M8gG#sawso{9Gc$KA9t7m06jV~ygTAGQtyJ^JZ_NVSZ zH{$~2dBE$z6qK`}wW3d>@PUL@CaJh7o^jB^aM!N@3UcM9oYDK>-^xO1s|G?^M~!n1 zYd!*k@Ve?Vbt?YFRZs$`IjCM?^}#j;&mutQ)OwghGCuStwp&_BPJxk=oa1K*=Nq2^8$LTpocFVstXaysKdW84{`Y{w zgIyI~iN=K(eG)e1m8;i$Oe$jqdE>uRLr*XD=(|QSWF~WI5KTF(0j8?7~@6E09_K>=G(9W5b5>^Va zV7Gi?!}Ug@;)DE)66SFd%k0V@sIp#!ZuMF-pTX;?&S>ro?u+uK`=MSsSgT`iNM@!) z_-fTN>_j-5OIzY@ci7Y7`Nu>DJc zD<}MevKEEPM9%~bebs-gQhgg;7pY(V-zalgfqX?ApD_2|)*jm`kuA8Kzi7hL^~KY! z(a=UwE$pcd{ZRex3mx}nA@_U;vd)ms8eQ1~ULC^+Z|AK+l8b>;eV{@#wi5%ff(e-I zF~s~c6MY|gP_3pOvWkC)^UI$oV+=#1(7Rsmz<6OCH*;(#rdbbzvqK(x%!9N1rj?gX z0&WQ%uqzZ?zdS$BLa$QY&1>a~g27{%0+9@v=U#yAcjUXOL*_G_yX5JDZG(8Lt+gap zc7yy*6>F*L%ob6C_&&e@SziH(+ZVA2eW9gZZr!iON*+D#z|G-&y66D2Z4I&tz@sxaA}dZo}WDVd+QK1yoX zEJ{YK7R_gvVd?|A!%fiafX=|^O?P!?QrN|ZXupID-$?NeU`hiUa-_0QXXcF8`pDxp zQi+2;3GDyPXUv0D4-ij$_=debvUN8IL*uFW%`?Ha4)vJFeFSIO2SXKWwn_zlYy#j& zej`b({_ZP)9`$<1#|4E-<uCN$uIYY_yJm>~jx_7D z8qumY?hZqr)QgxOHeXX7euE`3xBowqzCEtR{{O#&O2;9Dv>}Al$RTNMH+=}n9B#VP zVG?(U&b8In)=4=wL`k(dC()8arL{xpBpRaQ+QG`I)wWJMZ`b#_f4_h7k4KNKU3Qu$WNM%SZjmQ^m_SwkNSbcePuCJ+h94R z_nsk_dJC5go>kxdhBBxud%n1L@&7_?-634Il~3hLm;WsTVq^(sRFCf|{0c49-w3(* zer##tDB)ebA*KF<%p;s0_3wGeX4RLjwg1g><~7=eNFj*ZUXHr-%80|B)z@FrppRdd zQP+mJB!7=i)H>)Jn(SNZu^(hBX7qgQExx#X_@kao5EA-OkHM7~-6$4pcI2>J<+V4( zLW=d;Pl&%W!C;bEr~b5L`_qURRvXUdk}HTpI0vFMn-9g>)pJ;G9#6+b7?g1;H9M=EgDM)lO_inGPjf1McA< zjeoU~Onx9LRa5ST0rJa*=q3F5|LFX;$Q7<@cTWE**J6b4NB$?SZ*qs9AEn3cR-uo- z#|f|J5S5fBbArrZDXL$2Ic{3P6}?#+JWPiVVS`bF@pxr+0yZsYo`oN9tdT9TbUcQ0ci4c zYV6XJZdurQcSN*BIt_i)U#CCahqepbv9aUHT+H9#B5w^Y)ZpCMaj>uy|0jsdih96G z1w6T)ZrZrHJd~RjWQ}6qoYr;CEJB!K!SDs*9XWXbcRs8>_f-vlbQUC$O1s?xh7z3W zX7wFdW!>j3&l|#nEYt$w(ElR!K8Y8Qn;BZml}hI4lEQ_OuS?>4D!`mX`s{{2UbURv z6R^ba@V2zRt`Mt4-GVTQyVZx@@PONaVW^dzUCTg7LpiT-O6Ol6h*6S=5Xn>jwRe>* z5(88AorftJ;RdhPq|HegyJTOAHLBMmjX7UuKiIp4jw;W|t{q$=n~6?<1sFG6+*=T_ z6j^v%|I{2Ec}5!zc2r9ZG2`>ilx*jv=f&p2h^2k7Rr3Ej$gTrxwEO#q6iH!+{5jq( zpFWm@dYk&2Q?Ny1pshppU_@nq9ZM;0i<-7?`55){v}af}-E*}4v>($?;fg{egErs# zx;^;X@S$g}_j?X`4oMF+x^Ee>9Ku^Y*I&#B{b?zpWA-g|rO%d6$={$m;$6MuFHK|C zflB!zM5S>vPKbw3m#m_%puYxZ{PRJ15m%KLWd8do;1Gwugoqp)7&vmopHqENwg@zn zN#vK$Hme}iW3e3VeTRiy2$mG_xRrJg29_4a?9;D9n0sa{2L;}pdnn5CdIi31uU z!!pUlV<6`B7+fD26=!!`!Z9=Pe2(hX6;C5R*pR(Fr8Aj|wh43XFqCGJ!<+|v7b71F z%)n^5LOu;F@e{W$BdC`xjj@N)PgHUSt$TCj^CzH&Hwguu^Xxx4yHB5-$+GVE9{S?a z(xAV-oBzRZ@SzM-x`_drkhEzayQ;q}aj`*RwD>s%*olr2HSybfUx(MSrZEugIso>F z7l-r$u!q2gS{QNn{6lR+-7?ASEDDiks{c;l5bI~_q`(!TuGPNMHbM7}Ofwt8N6nx* zlzY14US<-cWv|fVeDK+ixuf{Ynqfz)o0$rY-GJd+yb+Cs;tzDR4wrs-GJt~plvWgv zaJ6oo_=q+K()!lig@lW~1qq9xeIqT{F;JH`5*W%jh4wR3AB|}2<^MfFA|Cdp6>Z`@ zdGo2q@GzPGV0jN6_835{Xr&o(mH0gXRRSkdYYBd8(QKw5q*>zW#Z{8k`3V#4@VAS@G(ey{wytTW0F{)@MVRUAH6DMHSU@*x3=#S&0B z-fFn;W7`?}lj`qVI*Vjr%^H8C*=ez7l z`x$_|FvP5feanQHuf3_YT9`~%I)9O%OB3CCKYJO)=$f9!(OzB#(PUtqh+ITJRbS(7 zhSqgG6*VMz4JDwd3&kKP0gaCFTco0cvhek)s;}_6XP52oj?NPP{;FT=Ai=2UyHOYZ z(?p`zx-%A}<9eNiKEoP(6aP35 zs$b)Yy}O~rzNeGOXKSbw@@5Qs!myW!Qw-;yF0o?Q*tJhOTY;vVsfd0&uNt|<4k2Ut z+tJ5Zj#ia4(m`or^tcu_PH(CXH5cyLgP0HMP=gLxsy3@AUHFufqPU<#Uf}G0U5*QB z3Eo_%UtSN&3Hxp1b$*N&%@K}NI!u;e+YtRDj_P~`F{RnxMB_go;h>Bj24D<-dgf!7 zRV9^F9I_2LWc14^%pE-9>Hdx6ru<}Yelk48u0iANf>$`t>Y570E;sRnjdT+l-S0Wg4$k!JpYNvP zDbd&PwLXP!qjSl<(-3OVEn&7GgS-!VS&Q`OQ@cOKciztSyQtA!zMHQC5VgVSaAfdJ$w328r0 z?|N;LpCJy2#?;&u+@@`4A?05O1rQ);+vJNm-pjl`6H%)tY&Rk|Hf)FHfG&cI-}jMA z%LLAtdlPG|`DNfa^)RzghzA)OS+0b5vs(!fuD{ICT4_9W*^l_4GIixQUeP_xE}W<$ zo^XxTvvBs#CN=#l7{Qy%Y}v^gte|GOFw4Q+Xfo!2_p8%W6XWYZ6uaSdMS%C`nb)z)}6Bri4WOAF}pzW$WIrT9Yqnr`%vc zL%%*hoorBmb5vR~e#(Oe#<6s~4p=5R^A_=*A1ExA2Q>kSPdGan4-91=0gF^$&qE)V zl}RRFNH^2zUH{Hb%JP3I(O;A9Ud|OTsOaR*h>sH+tx%H*eUv-$G|4qXOg#B3@^h0Z z^Zr)dc{lpg=3weLoz!E?v_b_@?ZHGAyB>h^#LoeQX*ea#Y+#23ZeZo#=dU(r1=&ulTdpwC>Q1{Thy zX^!}zeyo`KAODEZZy6};cic`%FXY}S6DCA1pJ2dyL7Vi*mnSXCWovuDsQk*@2GRR7FiGcqGc(`uuJtrT?y{?3~&&)M(J&P^3w} zcVgQIYoYpaxX_tW8@+*N^AU)-!NzaTdKNM zM+!$_Upb@xc=b=__EmTKX~6S2zsSf#=!uQ zr^RY(3oYHICi;S_(#uj?5}^JQ3H|h^({|Yycd6vo$)p#r0Pj| zMER8`IVApwSFj?X-)KsJfo&V#;7<=%twKb)<}T6oJ|SP5+<7+M4~QHZ_Uo8h*I0Nd z1RMxJk<+i3#(2A*e^H1xUXiyWX74{a&6pzc1l?1=K5sT6H#rZez%a0@j|)>?^|>z+ z1z4p>;|8btcYM`_E=CHxUzT9APJ*70Rj{;c{z~5@*>CMGA3zuV$IS2Mw2ed=1BO4~ zuiq$it{yZK;QbcrVNyr04LbAFa^qS<>A_FEHE;9q=Z7lV(Cdc4!vLw-y%b{!O?mW+ zvjL&o-3MQGk{Gs58|p~8Y;ki++Hb~#pNeF)ZVag*fnSjDEM-Y9Xr7ufI5nHI>epBlo^bJX?y^)R)5cgyGtc1RgWpj#>*s15~|d7qt2*${Nxz^I`|pon;|h z6fn;_QuxK`kMKbOBd{&@f!tmmk;9*9Nfv+8=zuld{tgc`5!Yl%m&Cv4&nRy?O=!-_ z77~}~`+T1p?*9(qE?|TKBh)LK4NGL6oRebwAh0xL;_;KpZxJ)99u4*i^QNKY&6CoE zv1W$TjH!R`aLlt1*hK%YI+BeZOcoe>Iq{oEY%qL>q^Vx)z-(aUB6s`rg3b*2_a`md zY>nz(LR4CvIe&+p%yUe5q<)FZ`Fk-(|jd%f|W?9|qeVC$Wd>b~HTt0DO# z+RuKrK=Sp$dl`^>82mZ>NUZc7LO6ow9 zurWrLaWU|c8}rwbmNfn!>UO(SX1{oudZp;qcTU0IqKDw$=Ibk`r1zaarr*9hMnV&h z2Xo%K?~K4|QfBlu50VG$G^yZwAM7qAeI%~1#o0hVOezB3EdWh zeFk&+Hl4*@PLU*U;6uW|&eSdc^eONQPRdtvqcOP3v8F%!6BYMzCKP*&)bt5#s^Py` zXtKVNy2}PkdsDZT-Husd>k4A5eo~~{_i~yP8EDCXM90(|#|gF;G0ee0WF1j-S8q*b zPlzrnC25r}R_Rzh?`5jhpcF6mjY0qM_Mu6=xaU3odr8NdT*T;#o@p{+bZZdlI1U=N zb=*Tp`}Onpgn#XZ7X9+zLL8p2g^xE<$qNbO2Dyk zUI-WkHgkOycurqmcKBV{hN%Y5zAO5l=7e!XAEsZvi90jxSe@wLgW&)Agr&Svt{?~z zeU+=$*0en7dtwQS!sJT#!9(26&JQ_-V(j}S5BdUvnE{A|{Y4`YYmn5~o9CwAG^L%_ z7_dS3m=gIV$&F4deAiGG>|kxbo#fWKc%|QhoWbfWW**P*UFqaPy{2Cu%8ycz+(Kay z3xE86Pa!pVPFV)FCm%WrkCLGd@G@m}9>SBdSB_uQpA&3{r`xk#ahh_4GF)PCnfg<< zphbx8=!;z7jWKZ5bFUx|TMvWa=_}C&%&pgc5UC?`lCK9Jvk7OOr5Ad0A$M(LF9H43^VZ zE$7r!#Rw#OQ$?i&jnEl$V2L>PTAa%b!brz+rwB{9Ihp-6p+rhNYz0+ayMeOiPv6V# zMZ2^7n5#OTT#OF~8hx$w&)X;Xu=>D%3fWoPrCDO;xY~k*CjcN7~M|-XS*F*iYs52>xgx7o8 z5<%#qXGdY6sd_T%i@I-ZPYXr~ESnsij{cb-Ex$R@DScQ3TG2zIJ|qP1&=?%1=1pMIp_|2$4Wi$3sW=O!X-Q zdu2!akEiGv{i{=5YF^~FdYAb#fjJGDrspA1FXMH+UMUhr75LDiQG}OeKIbNX376LL zX!W9pGuH8#R@`+;AeH})m^Ox=qc_+OIg(4_*FfJVq=E3?2%ft2EU)LgBLxYp~JLB+UT& zNGu&8jjpj;ghPgs>bXX9cDIOAvOpBFOxowU1{@4szB?G;@;_V3hV-)MjM5(AD5+rd zBKw&9h8u=*d`wL}yHhWB1NGs#g14N4$-N+%nzsDFgOCzZ)00Q#Qm->ggP+QS%QysQ z_Xv(S(i(j@w}<=EssAH2Kj(wJ$9~;3W$NdpV6Uq%$+3q?$_b=y8CLoDo2ajf4=pv= zbt_@QXToxdY;Z=C8^fNE{8>eq&g3a7IDq`zna{ngCmMju+}Q;|=u5TYH4PKTF+dts zp|>3Xaw`yYzdH@a zKz70J%}yA0frR3-YDSuTxbU-Kc{YvycQ<-YSW5XtzU7wX_>^Zt7eSnV>g(Bpo<_%e zqZ>e!GVHR0pfv6NA;U8H?UBF5^bdG+oFhZlxL(xY-N7iTIpF1V-$S>2qxiS6>c{;r zm?dGL_C{}kvcvpLzW_kgl&oVv0Nei>PgHMwk2R7jO(10SRc(vpfuZ)5Y%$%#U7ID& zO{>hfzZ|ZY6G31z^bHROM!7(56pj9^>U(~xEbm|v1F#>y*{qkUL#%X?4>yDk=@wQs`RxW?FQEb8mPWC}Nz*E+58<-f&K%JUIUAi#2p;p`a zuBqn1XpKs&5)7yGMQ6#sj^C}Ntu`SyU=O_Vw3ok8epVFakm-Tl5z^Lvr59K#M00D4 zuVe+H9)e1NS;&6gj~~FwAUK6O&yah@d!|X7;88LU@gRSc+~^7`(CkhG(Xm0T%A0N;6S{eg&g{WSdf)-6Vf}>az-7G!DE*oTr629~pTnSS z`lY8l)aqRje~&mhBx*T7F^36}FWaZv(1dHc(#nFu+wioO6y9rR4(0F+Ni}JI%>Zoa zZ;E`zfKd#u#sgR4PJosmSS}~A>nsB>fvM=ADh#AEAYdBT0>sI?)BjtV09HA zB~PR~j^{Wqk!SI!z9qRcde{&n=Fn2Uag0bg5f;g)>)(j}rL~asYu%280#~K_LU~ct zQ=es*$!zq_?84nhFrlCJsvs}wD{kY&b0c(!tAu8Q4z0KkyiZ);7;|CtXsj~eOH7gBUy#QgJR?{0%Vx&zN@I&lg47cGo&V{7{u zO?HTXR%p^?x znSaPz6SMbrJV=gnG^OKzphYN#a7B{5W= ziLoB(^}Hl~wi5^6G{OlLa4`$od^nyWa+`v(3%Uy#!9gJa9ghGivgJSg%kbl_QQFrl zG0@WOiuHfXm@7Dpi~UL57qTF&Ax~+ik-4T$cXff$vdWJ5JQm2Zw4iY3n9Jc^YaK)| z@MFIo3lRI@8{`KGCkeTjT*%t8W*@bi3W;lZK@P_o=vYNvH^#?JNfJiUD2tN=mPqk8 z!Gy#H+U?N*w#C0?&4{AQvZ8xJ2f@{#K3<1>Nb;0u%h2r%LIvQald56$vQoOuFApQEUPsBAQ&Xn)yP>jSLVV?awM|?7me;``Ii!cy7A{#-@KpW75=Z89nKKC zZ?~_dG;2Vg`%->j?}sNj?Y{pa24y5c@zNkD55EoqhHHZ^gxr8=4%P7G>~!5FS6S@B|nWq?~L_%HwV$Kn|+_uU&bZ1V)Q1Fa@&ZWn&IoePGE z^afG>3ghpk>_TeiN2WX~FKyk?;o3&_Zrg@`o`HxZ^s5fxa+S3+8UXdDnB1Ofw?kgl zz6Xr0Sfp8x6Nsuo#&B1y9>FkzfICQ74tafJIr|B$aB_P9v?slp)1r4A-*}n9`A>~U zIWC`zcrCERO^K=rKbV_;!2h6dzeNobfq=mRX^Q>mS9XoyRF^`2SQYi4Eppm}D&;TZ zhUFn~9<(+TqM%THmF2fk=yEWc7})2g+)A*ER^mUi!L*x;^tpU&(LuBs5(oZtk~X}; z8bB9qErc;vF#MthaBJys9ojK}Q{6H3-dnAefB!@w9t+OnMh*nIdx6>5m~5BIyXsdg zKiXYUk`priSqVB=&T=VhCO#5}eOBgIJE??h^k<@dW*KU|#QUW{qvWsk zwGI7gsXr>=McfNLpj}ee3*HS>(-`kqnasvr0sJRs2LD@`d5M-GWyC*03vNrI;D9B~HR)^NfBGTwTf@LRhNYyv&^PBk8g_5>;Q;pc?Zpxh5 z&k=0{ZEx+SwoVmYJ6Q>CYbW>g%huo;R&~@{VP3BrgCT*?KI*_)YQhzMPa{%OIUcx6 z)q;KIvnZpURxIUS?`eo!VN7Kn`r~YisjaN1VlMy|3_@v%!!`Nmqt)N?Ukim))$W9_Ecr>Q81|C?^fEC1p} z*L1z7SaLv=ur0!n8xw*W^zxe+^As9n{%K0nFJO0#lpE;PQ|I}`f}b6Tt(9%K5%yu{ zC2qn)oQqoq{loT4T<-;#zPUF>&HgGhTUKp(lQhCs& z^GNf-Yj!ERIin}QeG0%&7!L0-pgoY?HSMUWA-DMDmc_d4VecL&xaqwP9+v%B%m4dR znU;BOwC_|1GN6<)wSQvykxtWXs^6FXlNob#7y4Dmpxa?G*pk9!R$6{WZa~WnGzATy>#p~_~j}*ZSYiIa~tGYjMA{}iuvhf z+e<}PS15s#;lNJ$yY|<^PsA{W3A`USAKDPyjUC=KL0RNasusi4e+J_T=bIdgyDC?T z23_MwwaGD=(SZJToRD{3S#nBBw(~AK zc_l&bWt726lHc2+XtimE4J%;U{5s-$UFEB15>D4=?SdIF<&A@RelsE2f9J_%*idef zvR;_dpH|5&beI0jB>?l)x*yFx#Q7&u=A?{tIJi!%^Z`z)+9sxB%^7pC)mc_;PcU`= zloa0;wlYt*L<+$Tx^@tGzHtkt;h)}>QdBsa-K>Vw%|S2o3PQ~O99RaKF!8$*b-Krp zK~8(^sn@71U=0UCc^~z;^bEo$Mg1K`{qS|~YAKai8JPEF*WXXRPTx^e4*$F`^YkZ;MQ%!1T&YE|^^mafTK98NO#I>QC(5lg6-MNx zqRCe~0AGr_t2t*dW&)7UP|u>!tUy6~*H7WuTY-m)Z;N5_zOKmsXO0<9v!%`bhBZv(5yBMw#5>IjMz(n-^=h6 zR@jZYui%t=iT)uk8oHYMr4394T1V(CU@Rs)Cq38toa+JJkf*#V0x^6b2bKlj@d>t< zah1@!IP9Rc>|zi|AUjEu}i>eQWKVEp{XbEef<-vRF7MUDd`B#R~p2n@0?AOhEw(st)--kl0kFNRa z-rTe8?t6Y8U9&s%<&6c8cBgMRB6$${(!TIx_u0GaWXckJd_n@pD}aZD9Hek$_)Z@H z;3pJOf&mk_Rc-T`qXl!g#uWS5n*FveHHPLLN`onGFDpV|F_7~UZ>rg+Kisw6lES?< zwLxunY;kg{(02^GEm1^6;C_eFNo(Ykyp^-~uFUC~f`D__yfe}{vhQBukmcL{R#!G` zkDf}W^$!beSV#k}KlXq~FrC)1*-qBzgFsx&|X{SS~j#r(sqfU*BLk z!QP%i=T>2%o=yRx z{j9WzxGVSW<2W6JBK@VC@OkO3H|K883euq;~k!WQ`A`(hYOMF{&jn%97gYl9jXCZJ=D3GJRn- zYZ`7{59HHHDN`j0DPgNP>YukXgZ`oPfZSEP0QJdP=)7GT?^8>#C(t;FM^2Qp_+*TskAm7xe_I%H;&3t=cD5D+ktutXduzn6fcn8;LfIBx}M)S(n8 zK^H8V;KU=CmD~%;BJEjFIV{=izNp8yD||_$&P7Ib;=YS- z`0@5lK|RaKVjd&lJ=dD|Cbi*5xWKp(umNlh|6^O&O&MHRt$apUgZMBBFjfip>Y0-( zgot=@mHzRhi+!_qRYlId^ERx#`M7&C5r9q zjf0v)YLzeaZ}M8%rDd`sS}(mCCC~B>QYDIWtB2|$$B%Ti%k_>s4H<*7`2*+mxq}T+ z=(A3>CxO>%*Qnn3=nO8Z^o%Y8jBDy1%(P-LR>|R36bJbn6=Db0071-7`fStQeW$m; zn8~)vO;l|1w1Jl4(12ITU^S0JNO#0`#$|e#C} zC>ZW(4%2owFOvL+ z8NN2@E~p*ZeIhz>x@ithBK7$(TWd4EtM{hz^$<%b`*(CL2tJQzII0r2y?;Xen8C5| zR%NHxvs%r#*3boVBh{^RKemM#!Wg+ia9&O{#u&-$O$3 zDB@!sJHn&^f=D&R$T9^fu_8^Z4Sn5Q^aAeY&S@JFcm~L&afZ4*vDzIN)aNg-2;9Z( z`3o53+ZkuvS}l>PES^iAm> z)cACjBM1NLHV$!YAn%8oBfO8!=;$Qx2v>fIng~kL`EkEab0)J~%n&w=O&qb`a)c-N z(+V+d8b&qa7*0WIcn@3*b8(jR6@us3M`;>kO!TBnUnnb1bTMV&9hm4FAbN$Id6-?1>J-$CM=wr2`L#VTv`qU+*N? zZ0;44np!=uNUNY#L>W-BO8i`Cls& zd~g)&-kL+_pczetSxay_r%;@&@BmwSG^cLbJE&!FwNpr8?d}Zd;#huI4 zAH(m*0IRucgkhGDeYk~m?w9E~q7c0WY|}Ksm}?5YRHn{U$i14 zPH>J|kCN+6q^2Az+&n^eBg(U-c5}&o`O{q>AG|4S^xhHgi< zH$g9ox|nm2bEC)04z@m|nxS7zzNiGRW6N4=ZV&RyYZQ*H?Qa%7){?5=P42~<=5QH* z1D2YTcD4c$8ehff&-pd|I8%MbQt?w554g2H_DSoh`bb$*}+MZ30hK87I57KOJiMX z2U!V%ib$IT<^4rhQ81?yJ?uofjnue@kJ;5qlC`R44!)+yMX26jpG*UJGAxT^EQdlQ zBwMZ5J6*oGbWIHB=qLVL^;E&xkmSyKBkhmAcv44IZt~=0)um(Vqs^FZ$PRYBHYchj zIMHCi_~Bw_F#&{A^-Exeb)stdnsAx6_8|}vvRH-~e=Tm)hi0YyS-uP4KZ}o`I|+Ql zki2MlC%R2Ek()MbuS;mW;mE&!CCdfn6*3(*=POChNXV^=i&#vz2-%KuXEBo90o}Hi zo1%X^;?}MiM18qg>?AOtZT(xnLVG8~lbp#doeh971IOD0Vh^|(LJHwW>+Q5agO|0* zp$?SD=T2I^$GG0Xrb7HV$()!p{u{bUIkF*oaEr9IH(y zEWelO6Eb`_?8cN$7mJ?qwyd;@~?38@Rr!2p?Qe^$N0_Z!&AxHqSCoZ7fFXDglv zRvE;9C_>4X;7-IxuQtVtpEZruEf`FQ7hLU7;T)D0zD5_7wAHY~X9*8ZF$ayc+~Leg zIQY94p~j=C9DDp51(mLUrqO9Hv_>gba<%SIRNz{UZfqdi{)&i^S-KXWoTLUJ@U!9ndp!$UnW{xSjtRg zks5a^g=nSd3-1lSB6hpJjnD2*0iMV_waqSRQ+vLHrsT6cI4YtdiSlNz~$)K zN8x+s|MdT8Fvic!{~6q_M7SCjK9b;d>z;q*@&^;+gz4ULS#iLskG+piARg~N$3 zL-Z>*I5M^al5_8PQ{A-{-%;LQN*!)yl!3P(ZM8~eojHlZsmvIJVU`6(AlW~ktIfpm z_KQfX{$SweCjLn>SXa{9l!5N@Uk<&RtW%6XSw7RJUy~9I)L$5|s-L4$H%zR4R}7yVmCR8xKZ)}#5bEkvx+Yv%MlSo9Nm@zV z6QmghtZ-tUW%sbkl13kKa!tmCx=qT4``hHaz??c+$3KVmG8m6e;@u zNv;L2Zfi&i%3rig{&N91nNNzv7oCn_?N(ccg)BWmxRVgvm*2iqRh1g^NXT;pUs#!) zd|J3oK4VNYoQr!@YUWv4TfSU$HUfYkXB@&X1+fF`H+bgtlnP2oPJa{wJ_4fr z;Th6OBkh-gCa%8ti2PTLTH$F7-8e1Tc3z&H4o{Elc!iYkNv2c_%&i-ejN$6Z=} z#L)tvQ|Wvtw$=N6>N1ji6g#9pYNR-EW5Z2J;Sr7Tw|Rj~dqIV)t>^rfD%oZ4zMZj9 zFhY0tnBgglVUAyxTm*bLwz+a}MNR!F_^Svd8_HX9M85~^L&i(F>eten|li%43FN+ zY~XB!C{4x_{zdv&!B)zq+dK9bA(V&XYR_w#rqe&a(wXjZ)xU3;@AO%NHJ8z?D^$N1 zryxXC%9BHr2W2a?XI4fNKNv+LZ_xbAzW08!RSuWa zgf=|pr=>#;0X*i+(jonaTN=Y-7IXRd=oWRNn@99=P66ALGOxyPQM<0+R(`f!^VVAN zt#9Ql!)7pnE~tBJHUSg0Oxc@}WxqSnCfqI;IBIFH8%#vakKo>q-V^JfN?$#AF!D5A zAIC_m%F1PlZH37h*b@8Se=5S{bqOlsj@Y$*f!6!Q6`Ol4=$Q)gB(Z7dNpr$f{z>iM zX~2ALLgflz4Sl0Lht6AnYn^e#1Al(qo4Qw2%8ri42Sy)5Aea6yfi zBFnjv_x*OVkBKK!A)?Y8m73iJmH;Tn9!K6*UR7ycHB+-iCOp0kZZ6{KM-e0Nc5a$s zcendkV~`1k_cfQFxSi8}pWTW3%LfyQOT z-u!p>Z)bF}kVD`L%63>o|57^{^6`>G|Fr+^ZQ>v2)fR#7w(Uyb6z1dKhYe<6+O8;i zzj|LIGHK6?DFd#pH~MTi8nftk_wbZpOW-8Obu;D2LSgEoXOQX63UG)88Rll`IYX1Q zVK0(t%?hLMHE@@Vi+oqkF25$#4(*qhuVkwri0z-qQ3(Rmo~hYqbHPvc?t1{{yOX%~ z(}ZI$yA0`!73VbIoT#11mfY3S#wx7Mw2++TouihQu}TH{%!C7pI!HZg;mh$YiWA+f z)&l!Sx8%A7OPveDG1;X&r68sVBSW6n789@0*K zIQxB6lJvZbX5)-D#%BGfxgNetR=55s4|Bv1tpySeOJnSQ5o*#wW?{70SEu%qpO0le za(Y#gVAU8_yXGm+^#|=b%p=!`aYlmp91b z(2iQ$>kh-?o%3oKBSy->c1{gfVDMHeI$eajTEv#$Xh2pm;}f~;j-VVqDJr+Y{q~=l z{2Q9g3H|Tsdhs;uBr-#H-TDt|fz%uhMC@yK)NF&PxKCFY1bK5%@VpG{YE`nkW%L30 z#8GpCpkk%4&ibRl5^ti|l~LMBI>l*)W;V7O;a>f0%*<6N*_(16iCRf273$ z{sL>0hH{vwSep`U0kN*NMqo*=fp>aSS?XVooI}e73RjF%V&oJ1Y`9w6U1|%N8r=8b zLN9qn%+zefKAnTy11Iw|69MRQLN^YuR{h9YnM4IK8V4MwX7@dO{@R+6!mQWfM}KVz6R=L^FyGADeb-~ekGMXI zkII0>y@OR2(4ODTK72^M`s(3f#tULZ+Ra8NC;J`#()(G6yb-&btN;6aEGK^@2)1RA zyn4lARpQ3XU`E;H{0>-`dhJ=o`jnmCr)o%;4t`Ly&Yuf{46qea@vt=FlOFOe@eh+^ zS`P$m@0|a1+GO0-dP?jNuGH`Ah;$!3h*SZh!(Ww~&Ka^G8QO)Hqxk0yO%xrNtxmZK zQ!uDD4yT}ZM6I@VEqla0=d}ROAgoS@+VV# zQ}L|au-~mQ#MtQ$oyyIID1Vmp8>0Qv@t)%%Qf?I``h4Mg1Si-X-b94|#RL{HFhQoA zxwU6KTT*D*wP`UHxFf7VK`3o%c))@;xq$}B)MAFaoXw?aNu_#p?_1huagTMCHY}f3 zxG=m1J}KOo6SvaJ{y7yZ96LfSzDazp$DYM290%a^2_eVkE_{Iko zV3~7|^S0QXmrw;l%+I`IqdE)3jI}!9K$Vi-NsbAiw(L+Ou??_VZ4#rTmQ^1n25Up( zo}i3D7=@fkcG%7J@wJrylQCPInZ&jk|AV>wQ+9An*O8$mE&9!K*pO*qMz?|L7r{^i zdtPvuR&nB{5{Gib%#ub)-4$-kyrY~!tCk7l(|~O-VE-lXbd~nn%29RE!tpMkSvK%5 z+l4>(xODJG_suDX+xUThQYA_f+fCqW-Y|Ol>3|gmH7?*SLQ+F-a4HOcgMeGliQQbR zy@}u||Mgn~q+YDlX`=2-vXir#yQr7pD0qaJ9rJj}iKWty1gT^ml;SH-X%=aOg zihlz(0g+rB?3E({p!$v}=Os=~X0#e06HiiQAI5LQ~k`!8rXsyX3Q7SLBEtuYoEw%l)M1lS$@s(W?Mw?#KJ4 zberhqp0#X9rejYtL7;d(U-)s!P1JZ;uf-bSJ{FYrv8VC2ImSpV1{{;r7T!fNN15;32!=XYKuDfFhAvvf)`mhOW!r;?*v&WgY4s$7s8l%7`g(+3#{mnEKgzCQ$O zVnsX77$b(~=VmE@DhtkU>al-IW`SR`KvY{AkIq{!NHjFnUPRcZH%v!3e7Y zGv?rXgt2r-A&Gdh(P4?_^FU)d&Yc<-C1@w6r1s@}gAxzSBUvi<)q*4uf|9!i;VxWn z$vJ=vYxG|b{qe*wR}Gi{NFnGGGvK9VH*?>~qEgxUVsfmu%vgSTTCLb@g|s-Nd`tK> z>1#rmPoTuIk%8ulTjZF?co5dn7vFu5)V8Wtzv=|UGkYZcP9=~P$u_-!sExa(-y#>B zep3p*8N7R?t;KoYG(m&lNK$E~RM{QztrfmhC~ZHO$q75^L_7Y&#gt(#J)Q#Sb2RyY zO$v%4gZK*$#fo-b8Qp3B$Af^60;e(9ksj-R>b}({H1V)r7$iYZ*%9P*O87(z2n-#= zqf2wsmL*FKp7Qbz^;EtY8Pf@tSE<5`;Tf%SxY_3CcC#h~-#gTCRBOasUZfyQ{`4={ z+?T?wV^0J@a!XTmx_6~OzdvhW4u}#ano0PHlAUI9V`Gdd8p9SB52wcSE@W#D-7qC= z+SK^ErjEVE_!6S>YZpP#T(S3Ol7A_3E)P4qZ&>f`hIk`s_c6Z6ec9#0uCH8L&Mhn- z-7-|yBNvgEtERR&b2TUC)A3h&3fX$!_o+uCFXC?@1<6gCX8lK#eOl7Ub6S_ifd~?2 z2Ekk`eD@N>IzgPgVHc79z=S$ScCs4pgTUH4>BAaxeyI``@h`9f?M+*ie)QF{P z#l?qXk|cLEsvY4F@*Cob!aQhf;C*-@G1d>49qebDh0Wl+7(FovSWvB}hds;8uo-=yJ@krepr{qld|1M~w9smL}IW&t0 z30tg!{mWg#-|>GWU3)y!?fb8UBrT~_4(qHQp;9TvDwRs{R1XrfN)mFWIqXnW>M2x` z3Y)VEQ>3x6k)kMbp4dslFgDEWywCUZ{C@vzukm?(cJKb&*L7dl`~AMITlViJ+yySn z?#VwLJ~6?3c%w4xkNSrZ))vm$c~{EWy&ib-p83k=c0~FS(KY5<5a(h3lvdt7e*osR zuJR1|L{l#5ABM%JSxDRp=FvfDmkP4bKxh^la2UVtx>!6l*YR5lRj3{+a(9^7B-=2Z zF4T!!c%S#a$a>Z97Q)nHi|-o>6KUo%$*3p2Xi*j(w-kld6Z=NNQ)pxOYpg@3&LKdc z2NTaZHOky6rQ$Z;rhA>d$I&YkBj@TVF84Sa3gr;xR5H45&;2gpvRX5=<|vlRyOvW7 zL4vU9*;$FjGWKGp5boZY-)qX?_?I2a-ILs5`@gV|8H?RvU$c~^J=M`)`@~3Y&k|f4 zcf(@RiL-6kyFkao_xv&V6BCK%p~9C}yKjZLF30r_mw9~2!rcu`3P^3>NfWPNwQ@;Z z#K{jD%i)mKVRc7Gb9ID^Ao^c;I?y#To)!{68viuX-@#PN=4V=jlyA}G1LZUB+H!Y9 zbTzC8Q}+h`5QwWr`cnePhLW)%^kI^%bvCr_D&+JO=>F*F#CxD7MTd^dwlR*JiI4bw zShRnt%pG*!^~Q~%uMH<0Gfxa?Z3xZrvI4fDH&F3|EnT$bwMMW^!xy*+F-^Y>E*k`k z%h%}G-~x-r9FYkc6Q+8*^pi7$rKK(aBk_+_;tSv_8hgDd^MsRWd<16; zoNaU0!f#zUj`QTUIN<1ikd14TLbq0wr8?BEFO(Nw0rX)OGZxF8EIL7-`@q5gzi!-k zJwtGsY}{DdWYMdMnp>s*dISpi{7r<+OoZsVn{!)5)-w}Yw_wC{cx~BNffm!^oZuE3MPqa6!|vnzhIp2JjRsydDa z%1y?)-n&V$&12^>CA}HYXq6(K zc&X*pn5sVd>>i^YQw>XiDDJzhC+j2`TV#Kp70!YBwoc7Z27J{Qbi7 z>~m*+IX#@Mzp&mu#s8m2q3;cFrs%mt>)g!T?;58Ej=I=keDr%gz=vBCP+bw4=rw%kK zW5DMGANrMoTMW~~|J_pxP6s=33(~EBy)>zThwok3)S^tkTg7su7YteFq@TDSjy zw!*(5=2{nNIT*jINY88xT#+LLTApewQqOS8q8f#;M|7xNobDk6zlVTZjLO;n7dre- z3v}V`zYYlb!(`pYWRSumXrU(Y&O8X-;gN_i$CY1{CtTX1xTq}w^kpXuTJA}r%p#W+w|iVp_RW&5v8TZ_fPO~_|I)fumn}7P@;xzQzSt%i zrKkFcF%&;dpP9X#gj%key+Zja-r7|XWA zJz3POdXR>@ipuRsu{2;?arF~_pbF#t7Kv8R9EfP0K-Ya_K8mv8u8ioJ0GTMXWWS$C z3%Rc7;wl(!BeL?^+3x!|BdTJ!AF@Xt2ya(sZLkh>;) zlKISx+gSSLsa{nebKHGBIwCMM(Un1K)NOpcblI3*(7<#<(k!I5E-N!UyoPDq=#U_f ztK8f0v4OOhNBVV(Wl-mTi(+M-2 z*(PhUmCe0g?4EGak{?r}>bPqRL(6w3+33e@sNc!`Y*UEFTfGAAO7&}X>y6Q!Ps6Y? z4T0&N3%hEfPh6du`h5#qDz;cjocbf#HPh!lH@ZvTZwaFk&R_zNL}^`(+?kHUyv{*A zr?-XzH!nQs;PZKIGx1OkExys#X;$`N0rz3Z<|#w4ek#{^`5d%fi}_8}*8=Af^=srO zVgU#( zsbik_m{A7{hjjYv*c;BS_=S3he_^Iu%kNpAa;Cr1 zlCxpvm|fgnOS`1RcS#?z)rFIF>(x?vQ!=(mmJ;cI2!vB{p@)Jr$ud-Xv}Y;zkbzanBHHmi8ZElt7m|rz#85FBw&aNkW1^7joVC0kXjEsV1&b;@{yfux z+)3FkJu!NP1WEH0^2P>}S5LWSF&?B70Zm4mm)_HIpj(N{%cfrYXX5w!PG$7j*nUe@ zXK7exw?}r$gC5-8P(}N{0}w%nOev^Tz_EZOKM>^ z#$kx{md`6>D(&26?#`YUG9T%}oI3c0Q1rE&aGNjO;mCuPMqqb}g?EuoPC+vRhXi)> zAb}4Y;-sx@^*j$Xv~r3~ufcz!r3d^t-6DGrW6SYD16Vok}VTeBGDzgMps5 zrmnHUs2pj?0#+#J?dkf>emUIsi>5Fe?yi~pj|OKg%s>P_ECXJ;NZA<*(qoTAp=gD- zaPKbakW6BtTN{|mkGsOrSMFP^P(mA(aAbRsT31wy`A4m(zCwU6rW`)lmTPhf^kK3k zafCa@jb8p}hbkSvhe3jgJ`v$;K2E-*5_Lz4%eS|#kco8C_2!*sI*nzL2b*MHjhBuR zBEwX=P8w}2_SseXC>YDk8N0}pgeC@c=Othffz@7FI6%E|VXU$A61ryACXSwqj)QUW z4qyg@+$t@ZRqT=F-Dzz~UIIqAO3|7pK$Eesw`D>lgD%Kz^uQ^oM*eBFd0APez&e9$ zvo7r`i4ZokCGPSZ8a|azStrZX#qAFsgNu$fW<&ng6usDM5t8j2KN#2$Sg_8|ISe%jXx* zOgTBJ3%SJ8)cS3Wjv45>Q^}CCpursA{>e(lC@j&cf4{Qe`F`1NDSFdt)Xa~{D)mLR z+(kA1YNH1S(kHQSQ#~yCgmDk$aFU_#Qe+Z4Kt1BS%@tw>;kBxqYj{zYfm#32&7r>K zsf>%;>LJx)odRX}6-aYf#(e3Cfs`8{VM>Hr^HKzcvvPws03v?MzL`8m1 zhNw;SQ-}>Qcj@}I#`V0t2i=QKz;!NweHY+o> zX!PS=%7EPS5{;o6gfoaZKEY>+7v6M~8Xl-9Iqi*pF6FFr+S{t+EpZPp)RYXyNRraw z4)1r@JnT8JEK%zEHaw+&?BWX8jN;}msRamu;%%P1m;RZE1KZA3{_PaQ&pc(4u@$|6 z&M8>N*ek60I7_$t5f7uHz0LoL=d}D~5&A)^o@;h7>YlPDK5rhK4N=T$_7;o&_CSj8 zRqN+72<8{*>i-bEESrry2E6I9W-rl~-Xrlula+SSPy8n)@s4> z#g$_q>KSNl!kf&6!1ThHtp-W-WD_N2eca6Q>BD`XR`9>L@|F%-zTC+iq=xo|O>x?} zhm(PA?9bs>eGS~`rymO8Ni5^_yg{T*tuFdPmY)Lqm&|I8%6+9UCthKjrmzzGE{&>8 z0d@F*@m1(`O$f-yq?NVS#ttpfvxxJIF0_U0WH+w_jC&~bB17k)mSb{>>wh(ZO zP|M;LF?Vp!M`YZwXq2v;oyf*MWE#Oss5pM8cd;N{YR3w^v0ysIVx+y}C7uU#DZphX zr;?N|8^89H=9TP3E2PGk`+E}-SwgYW^bFaB-wCyPt)t&Pq+|4b?JJ?N#o z8z+>I|42$Kb&l$9e!J(K|D@w&!R@EHb~euZhS%? z$&e<%opg?8nZ@vvB%f>kOjL}7uYEf4O;Q*<##>T9L*}nKEfaSth3hYhd{#|W6Q4!2 zv=;F!hqiuC$C+L{^FTVD%f&C9{GoHgr?gNB=YFhA+vV1j=)DcUc)+5x)4KOC(kw;D zWqeW~rh%qJnp4X(>UvY*61*!|A1Sf<@w&|MxO6x1X*ewZPt&x9xqr5jiT{VGxmIhz-30y|>G!J(6B%_7K&EUpB zZ#dgvR)OLc@mgXwL#MHHUCSrw!Y4UICQEPmONmHl!?J0d#l?2vJH zKd!0auoDR3RoKih=fWd)f@x+SVNO1wLuzPDcgEbK!943yf(B(+|Md%*s`V(m?MlB6 zF|T<|?dV!6?N<`?XL=<6`(M0wOQtklEk%NbfPsrN(;ljk_b!{yt$UEb+IHh6%%Jr^ zR#t0~66G{-jyBx0eHnI@@H+n%??X1u)-yWn4H0(-rMhu80e^e(ZJVi;{+f)qH8r#2 z<+lL{sOfYjz{`(4g?;>W4LggxS$R6iZVztu2vniI^s8>O0`yuN(Y~uWJEuyt{M+7y zQBN@7jafk8SwxoMlr-Q9sXXnpDCm2$P_-3`UoGo|w#Fz=d7!pU?@rHe`EQ-yo*_V zJG%opsBv_ox|;M)dW<%-ZIPXIy)-Qq{6q!;($E*_pZ7@pJ{kE2L82v{&GS{7{YRK) z=3_0p&PR|yQ*Uibo&I|xdKnn^FSao^9OK}0ATcwV^1I5V%(@Vgdm)Ic zYeti=_g-lq5!wsZmaJ$~8(ftr7saw$3)Rs1v`8l?=xCRiFG^1Xm1Sqvpikww-%++U zGi$AW#U1Uo9{DZ~U+GHo`n&C^-0e~#t#Kgi5;a*a|Ame-<=QS0>WI|0E>Y~t=bVZl zOfB;p)BFUfQ|Bxl^<5Kr>2U4Qce%h_$hR+(7?M30n_-Ygf$}B*yQT= z%FkX&@+;3fbgh7}3sH~Mv{hzz>(?n-f%yAgq@U#QC|k&Xuz zn`4*F+RCzYATU$Uf1lsB)lFn-l?@QRe3^h=5&Nwz7^EKsMEjq*y<`fY4_@4nOovo3$KQ;NGqsI!c-l_p(`ay zqR=urmVRN%o#AotIMPw54s?lKNAw>swe*Z71e5pqoxa;jc*z$mnR@Il z9{vjy5~uQJ56tuj%4FWuvM7IGY>^H8*Pua@I?a4Q$qnmUkDKX`?;(kdbfkAEE9j4s zAxZR%Ma!s+tOp4BW`*u^WR;ZaUG$K;2qScPOSH zC26=*hXBiREa9|W$B(v;I7A+m|8L-`1u zO|nTgq1!EOe4H6KNeA|UQktY}j`1@Q@Wp8ng~};XL*o{s{fvcg)X;&#*5kn)YkM@J zpn2!kw(UnGU`GgFa&939_NZlE31U z6b{z=d;+$}+u{si^8AP7v{G^D3O~gvsQD1&Z*y&?9$qVbgTf4~oY`d<0RJs*QT@13 z%F%PC#d#ioUG=y6TC^GFUm4Et_~`?dvC7CdKxZjDRdv4gd~T*hu{vJ3{aKszd$H7Z zK%*so)4qj?{bYoWdTL`~J~L~%g?Z>V#GIT&r|sb#)k+6+f1^_Wp;9h60$M`I@xKJ8 z)J&NO{+;?461$vRy;vg$G30p9(GyyzJ1&*irpaN*b_1u#wMZKbx2X)o#6padxY1s- zl6?!i--$zRxxW=jw~T864}Z`+5~OUd2x7M6@2v~r0KQk`~=n6X`s=kGPU>T<5P#vfy%3k z-SSEG!Gd<{r^>*slj?2HCH7)PQm)x&Jy?_H}Z0uefi8uzK zX}*n_b@0C{%?*V)G+lJ;mM^(9X)=l3!Vv7Kjqo3B={pVqEze~NXR zF~7?e`$rL9^RY8-iy_HF3nzkw@FFk|)s3s%)G)5%w~oMKj#D7s|D8zwccVVH3u8E~ zdbpsmh`X@Ly4}5#CMpYcAD7$BtdZrB@pZ!bHw(Bmx0imnzv(vJN_c&Tk(q)4cJHExik-rW<-4s*T`Ux9& z`E$q9I~@y$z62h!$kg%LH!h0Jkx>?z8%~YZFC$fk$al4TbO$Hu zba@?McH8Tvdmtn(@MT5xI7m3ps6p!KfEgqi1v5L(kYrAZd0bt>x|DPfGf~rz_eyQ% z!Q9gpIxK|R+=1M2w>Bl0jJ_}B6)FeZKwI3Q=`iFzIB&2Ef`;- z6i{%*i@@3o^K0L6p!8UK8Ynoui~7Cgqdmwp?XJ>z5ddyimMoqCs%cikq54TFe($Hf zz@nBo)%JdK5I#7~Z1_2urBNBh?VwkZMw|F^_0*+)*!%nv!c|}KWvfyia%SK;%r|Tx z1#3RMu(oX;+JlU8MVZpd;DNiWVGM}Jp+kffr%6RzaAb?mM1 z`xS%w5qnidikjX*W(SzR6x?)N9#$}&Ek~CaF?A_N+E&IG9Y>Wg!G4iR0>!y`hg)Nz zHTLR5>GfH*5VO~`?20IW*%>?iyQtidMY#Oeu>OYF5&W;T;dAqptz!(IqS=QT{9`U- z!(&-KMfB~`(X142GHjPLeab-u2`!MKUqN4{q@!_-4qsxFU+pjGo>Gp|0y3%wSFjF; zz9)9XoBXj}g!(*Ww`-j&fa(@)M`O#6{jt_VSt19Ec4zQe`E@?hob8b=3#k^sqq@Yr zNYuLdR!1bK=+pBEr{8ghPQ%%Xa|`wSjX1wG!ZGvTMb{rukRif#g1W8Z6H;FGi(P+& zX1`cu<>Xg{p743}?wnuK1}Qyv7rrGong2%ZgI3h}pnT6U<&P-PD!#V~&hN|d7N_hN z+agI74Z~3h zOjvpAg6UUQYTtahamRi=KGbg4iRacNJ9GHb^WL!UbHlvMoneB=h`t&#zdJs z=IHsDq#;)ck6G;Br3^Y;=2Yo-Xu>|hJ)`RQmw0a;-SP;$q55OuzwBOGdVP!&x(zPWUd z4!02auoviykLoC-NYvt50VV(RkI+qOLH`3m;%eb?-nq8@@$Bh06ggQ9WyU+DM139x zY&bs-KTsVvYTyr|Z}4WtjR?MR_6yh`Qrywfyx~4&D(lS}e#x7Je@N6oZrE*P#fWxk2D;`l2y`5k~>FiFbPqlkSBt^#C54Ec8qR{XIrI8UBYUIfKwU!jwn91 z51MpH_b@A95BSei6k@~h?JWinZ@ln7XxpuPp;$jSG?z+ z4^7$C)@i#l>p1QoOoOhX5!ORvd3r$~U}tpC0tpz*bqSn5E$o4rz(qZAqe%x`35+#2#0BC z{qT(ZvfZrn<8BbZlBEjY~9NNXyC|uiGLn ztj8EE93J>VzAN`*hlMy}+N=4TZ$pR=*?w0woG(L|52b!rhbd{Kl&d04rX2TiljcL^ zKU4f=ps;TwWVgy8c>1~%A%#`bdz|k4iWDN)k)eoAKkoIwS|tYE%?+nxJys^MX}9n3 zjnBmZ?E3RPzc$ADjl=Hm2uK=d_x2mEO9jL8AIO7UYFAdm_xkf$_lWbB>!|!!M5G`~ zXvYaW&%ouG_=XiIC&w)Ivp${oN+Ql=?;v+v!yeK24tb8y!@Xs~=K^Nuxpn7PJ`|pm zM{9M)s_k59mOe!j#wpedI{KWtIsT12AMc<70}{36&pXz@4Ye>erbkwG@wNJ8wE- ziI6D@_T(RccoDp85K$3XX!q)U>~bIYJn3w2B7Op~({klY>u@`~by#gSyQ6#bQb_Zx zeludS=tgm=H-mbBYkiKHJ6OJAHOeknI7y_h9kyl+m9OZEFBl6W`y~vfA2F#b^G2k{ zQD-9*Tq2)&WBVDV`rR!5+pu-Q)#`oc=7z`nAG8kZM|jQKl}WC8g)~d@SD=P1vokfG zRV$IPjDNz_g~@1TjkouQ$rih1fsUx7s`1(e@7J4!_#Wo3{^+bP=?y?{dC?<^7HIkB zB>nK2LX|;Lpo2H(9kG&#!agJ7Oi!~Hhm@!b;T8Bsyg>3C3ir-sX zUEhCJ=@6FY5Og`%fd8WM-uEgsqx?PZv7eQhJN%* z7~_Ts*H-Uy#!G+pKTzuSB>o+a3-lCpo%G=efCytiKblk)iMm?r<2e6!9}AI6ac#~O zu~PoB{K|TqO0oQs8>Gx{gZ-dYq}ajmA85w2(a`tvgQqlR?1%&f*Sd@TNBVWxAjNhi zN>>+BEH)7Pq*8q1Y~(lW6WM8~15^zJg(2CZNC$--vHRx-s zup?D@f9#x%<;`w=d~%j_(2}<;C%m3Aj7Bvh!g|&nK(K>gh%YOv4t_jwdNs<$w0JbJ zA);iMD1Bws=J!YVqHv?N&57FVDRx28LrQdd@F7RA8pi3*yw#bUS`#9>ws$gRrDvD&AqrfD+vR9kuUZvIc4? zo0wLtcBW%jEoBWe72d{d_+3j`!iPp>G2?4b{o1GR#~y#?eUR;@#z@mytc9fk7WE^Z>aCiJ_-M64Ft zC%mFqx!6rvLr~F_R}^qfR-2}%hCLX_&!O>Y+%UzN$NSuwj+J%U6%6X}VWQ>r z^W=w=t@bAP^Z+h#Yw-EyUs;*C1|-+*we7;1PPLb~FxNoplEyplWVDW)9<0e23#(#_ zRjnD6JgYMnkt80*fJD)&eGHVHIK2vms;?a8k8;CCDeD4qY7=KM2BnXK9K1;%cRGJ% zop0Tr1A0P}xE}?FR&JF?oNXRn(VWX?>;}voONQs3KcHl4m7}S#XPZZ>m!Vj?R&Dzt zN#aZ3!jcn=B&?WM&x_@Gb!86W^G&(5={?06MeUDU5Bd^$5&U@3)!k521Ag-o=KXZ| zSu>p9#Laqe-Jl`S(rY}SFSHQ{PKg=N83*X19_hcLq?n+xk|;HnuPGIxaPUe8&dz95 z2v2wmdfddeiD`C|nQJV(rF=zU4Q&(wTx&EmT6&8otb%SsrR+ml#2jFQgqk4nC#xZq z5{`jimt?|cf`ZOz$GZD$XgJk_=z7#Es%GcrD5vR-R_M+Cu&B=8 zs85|Dhu5N~N|Fv@F?rYJl_U1b9}h(nR`co`;;@ftRCh>jK%jmDqpzM9M`UVWA;1dn zQ@w7nci{X?$*K)g@jfHu6)~f>J}&|iI+AMi)q{r*h0>^t5M$-*65I>q65d}EEx8tZ z@>ipT*EEh6Qo0`N0<_0*Gee%2t%}ocfHPHh7MO3MH-Q)qY9?o$1lELjgX>cVvoJ$n zIs50??jK|;9;=J_$h>Ujb$yI`3;N@j4GN#XBDa)w!m+Z-74MV=$+yz1Xx_c=9SO>mS<#8zIqo+VlkzxcOw zB^NqyloaQ!uQq=yzjn^fhD^%s$Bk30!_U)8r`D7jR{*7XZhlQML!-)B=5;57mv@J2k^ba$Rq;ngc zT+<6y=y;!dUTUkGxh3TSUR<=RTorQCdv#xMO;Z z2GXEzpE^tnRUIxdlX0l)6lw!2v{SPzGu3%Q1yQ{Fu}|^BWyAo z8KUn-)9uWuYnZ>bU0&0=nH;x)hRmmk9B9et$E5pIX(-m)5>nj~b@4%%rmS2Y=PmX+ zq$!cUyK<%b@lmS!>6z3ShG$qixlWLNgB?@#q}CUNBzADvxALV6ub@U*(U*aI z0X1s^pDCE@eEobkoL~gc>HzXxS&V|(gOhDpw18_3(YrpW9SnH$6YBybs}N2LA@a%^ zUF`S+>hFSiXhB(EQpDH1Z1jf{826F$R;B_xYLoogeM(2lfNJ8Z72p{wupPuWe*#kc zUI*oK4)1~g{VTjnZ4{&C#}x6lTFq0gjA1T2?EUQ#uGSUa;@lWjNm|4wrZ%I%e>Fl{kOd=8 zB!~0^Q*TRL8u*72yO5d>pzRYYoKFjzwj{vke?vdUgcCm-7c69V;1Yf$Zm^oi`&E0i zy9<4zb;xqUr_RLqpRK`UJ^zNkj@acolb_Bd9*Z>#X%M^2t5aF!bcP(&z8Dj!!#&;GPc`_L_N2o@uqX=gy& z8Qxmaw(4-Yay&AXgbRFL?c`b9T$Ig#L?~x2J9Zp{!e2V_AM#AF9UGZ)c;lbQ+1bnR z52riBJ7+6(Csaqv6i#h!q3Yr>KjS}@#^iTK<@0_k#0xyj>E?oR%)?`Z$e!qb73QiERgL=HLV}876^CF3tT!!G|V@}sS zIA!k?7WKF{pK+a)*n#(H&9{RRh8z0#1N1G?d&=yA!O{tS09ZTeTzYveM~9V=Q@H~O z0Y&^ghw`@7vq0E6+RiqVJpj*s5_>65_#SF*GoMlF(>JSdl&I5J1Bn&?rrrbAor8zJ z9PjBwp?lw(!iq}j&wl^oa|bIwTV{{1C1Pb(lvCbUM$6vNz9iBfvJD#ex614x#4%CT zS?E1%l(86iqmXRXQ(q%^U_=q+*!cFNwE4YbK!v0k`GCqZeMxigb%zE*2M<(wn9+Sm zj6P+)J2vS)-(A8pNukc1F0-d&O9#y#3h70oP{mD}2c}X(>YL+ivjjR(IrK?Uwghay zy7$C{)O*6wd(3V!g`=BtI$UJ(jeqH|j}8cbgI3ifBC3k-oLN%|!1+G>GD7rl+KV zg6WIem7Vo1PwM+^@@kD4Av2S=V!p?#TIS>nhkc9wp0Gs>+*L@JV<*^t?KQkFq6b}| z{tKyj;(>4(@`9_bjwdF09)!RDtgMRwOK-+`?Y=8Js>4uzsH7#&65PH>PCNsQV=L8O12 z4cU&<=6SW({aXb@m*+TMw#urC8hhYm-}L2UxH=|(8al5}x|;Kj6FAKn^XQY{#&?91 zxQV`jw?u0g~?KvJKcY39z+9^|h^cPL95cd-M!eIPX z0)los%tfD|PabXXRA6?9wFaX@#yBx*ee#4u#iWAabdGd$1#$&hjjZZcuK0!ehu2gA z9QC3;?kn_J%1c-F&5Y*z{0{UG4N(wOj^7UQ=`yknts{O>Yw1%u^5c8KYRag+O-!PZ zXDlGMw=zG#(ajeCo!*+?XGFz)DkEll*1Zm;$2w~69N+o~BOcNdnjtvTxmI{}xVo)5 z&;i1`v#TU=D9$|ZeYCUJy)?Yn+b8Ku`T9%v&k`l&^A7jNvPL!E@*lH9ilwI61n)q= zgxp`0$&L=k{#{-OGBc~C-fK@(+A@a_a;#wmz;EX04%i|n*(Ve~VsyPjh9Qzkp(U5yc0yhnS0aV6bIDObh6 z+BcO91Q&BYcC}@3DW6tCCueEi6Ag`H7w1P^C9PVCvb|*qY5v&*&_T^n(sHvpk*A4h zdB??Vc_xIKzoL(m?&JJ)7W!L%!|quU$V!`hSIp2E8sq&h_;D%H?+ClHs$2BW8=DM< zi$zRD^sO8**_WT(p>ecScif3Dym;BVpi_cN@2j>OnRuCG?H&_D0Bg;e+9M_&KWY3? zO~o@AmZpiGHhvzy^=3AbR=CwxyJkSiWk^INiQ_xp74N&+2)}Ty0%}4-|8N2 z5%bc^I}w*u3*<>TM~qX#E_eM(j-7UUB@=JV*1bGRcRfa0mW!a7Z<+)^tm_!HE0Hy# z{#%bsP0D2Z6Mv~JtS!=>6k6vlB2r&1wP@Uy6ozFGH)GpNrRimR!U!g2FB z`QWGbd?U-*&OR3-`}e}sieOxg8!UI#{F}>t2_IcyX@z3=xcwWS3AJD>qbBlaaQ3>p zgV8tk7QkOj&?_f>v=czKlkn;Ddv$Z#bT=BbqrSG7p%MF@?XO%sVthvJEn>7nE9U*M z6^^UN(Vb?ndJhDOy=4KEEg#K-zxT)u_h_+rE(+~pPhl*VPb`7YnMiJp;t6r(Y73s-Wy|dGFP8`7qZE88|`y@EOxxa{iX-Mlrl)Wo53xMmILB<9BJVNzSy~as$-AdwW9<3y9rRlsL-|_JxA&quFX1nAeuM1> zus&sFK|o&i;W7^dBS@1M<6EVZi}5PkcZ%We^u3bsVdl54VHVZ1hJYPQu9V#Lc8`$x{+9F!$`Ry2;6zerv7=d_21+>*N`6-tuD!0qXQv59-4Dd#+d_u&1 zVSS=`AOeG(-p%Cia zR^RfVQ|v;9pW`!DI)@K&-V3$T5 z4))H@_h%II0^l)5osv~7AB)qmd&k>4yCg%5QS$zn#}<27)lmriJ<;)!#D9pE&UX4{ zW^@jstVc>n+x!#a7JQNai_`{k0mq=h7hBgdeh^F^bfC_dsEL*Gjdj*~tYhvb>a-W} zmjrN`2zbiJ_m@z^7eeZYOIh5B(D_8z82^Boo#q4L@u%NEREeHKf(iMWO^@RahBk3~ zAn%nhw9a}ZOZGZ+5>_O?9%LVw7b5xeP7oU2#yfwf1M8Vhb{D^aan2I%t|NQgCEn2J zB5=s;KLc-F1G`jEa(?t+Z{%;m+{}sm>bRj^$s_QAojc0ElSWK*{L2lVpt%o|8in4% z=A~xb6Zl>C^WCAr51piC+{ALXh56m0tyJqw#h|fSFtqu&r(&pAGj}_lyfl9Zcy~~u znuoSoqnR9e_K`OQ-?U0g8IbY$U$|o300|A zGy`2kA%hw^PaY&jC$Zxpeenf; zE*v14$Wu>GYKFvvu+#IoC2yoU84-b^V6RpQ{U5$pEDbEa?clwpSnNkh_<;YzjOyG5 ziz1L7_p`SLQYdwh&t;;Xe|l=hFdc1BGvHXbD9p>(Bxd?eRt0^W4|K-n_7aJ9@Vtpy z3F-dcsMaGCdpGPcHsnQ~nDR>KSJ$!bq{+hO5(MA0@$jWa&9tuy6R> z5o2KIpnirmHdc7LfCsHL84vLi?ONZXs`O4N7T^r4%m;~7ujthNu-%V4M!V(Ec{6YZ zsN&SVxo;IX=Rh&Z@}f!bV4?h?w!jlS&E8~2bcNDQJIb&*IAivG5i`E>rkCfz@wN

    Ek{l9<62_th3ff%!#KbVbNKKe8DmiglKv<%Y9v`0|KDx4X31GIih9qXoTIf z#QDKY`3+XIwmm$CmoeS;X9t#v=<1Sk^2F#GL}Xa6gcLiM-2xSkQCt2<9>DxgjC^T=0?B}uT1MNazN=8InZMimcctCE=Mn4h4*gOB5jaL$aP*{xcg=avv$Efamb@Gm za;4s|jd5w>>Jdl5?d=0af=U51@H7vCGJ{`}&;FxUojSrH6DFWONOvBjL2fbKb|r&| z4B6y6N`Ef;TvMjZrBx7YI_UYSagQWGY}?ufz$hUQUlT&#j|Y2S2+*mi$oKTuS;dSc z^Fjj2GEJw=2CNrT2pQh-@ddLHhr{nHku{bLHS}j=h0p|g6s4fI-{`8MTMZcx1%7;q z4d)GCzC%d^u1Q9Rb^hQiCu|0yg&N=?uyhWPmisz&9#Q4nWxmn~6^cXiqwp)ti$2g| z#qL=g$g8`m=Pqs00EVM&MJA$yA83MF1Ia9KNx}A@HHeQ^nqF7<2n7C}m74qC{L8WR zww;yrEFu-|kqbG+>9IT}QaI?-VHTnBIW`W~Ib;WhD?|T`!By1U&*2*% zU_*JHHLB^G^{V1w;gufG8t88iI9q!>daNS2-kk^yZ=c?IG26SI)R#^&Q9KDKOTdr5 zRY)9`HIVLqOZ4Z>x-}tiLttoF)t}x9Hjba-6_VdK;4YNhfB7lzbvGzuJib3zzoz2ki~^Mz+^%?@k6VL2>NEi#hEc^Bzn-y zS3O8=Dt5;NXO9m9im^Fy4;idO(`eR&R?WB?uTb|ZuU%U(jNR({jj|K}`+k~yy$(_x z_J_2taP+33w4hmSuD+)ZxYMH+*Ch=>{g8(||RJm#Z-Rhi&Y|n;zv$ ze(x;5vYf-zlG5^WrI@P}c|HKcdY_CL7yEpYCRF(5d|azGI(F)Z3H!ES9niS*W4P@< zw?75iv>9MFp*o9>64NKyH$v@b%6p&t3elaMVnxXJwE4w%RkEn%vBTdQR+V+7=Rq-4 z%_FwKpodpTdt&68#Zutv9iKEg(n<6(d*GHFQpD9=Jgq_q%lYpw?)Z8%llxZ2dv8vBo?ukX>9>^mY8b zri$)dUmyvsbs$pY8wm5PquGav=EgUrUVCyem=|ZhJYVTPSD;hJ4#%13>(UsOU6va| z#S^YL`D2JMZ)c>QVDKDjqVn(otrA&FMr7d^c3+_8{G6GX^p3~dy(~2;y6e>rZkkc$ zt?5P+^K|6 z`csSqyZS{rEy_Ly#G0S9Q6X9dDNemM7+qi3F9K>0t`>fY`+WJb&Ui*#js-PIl)==_ zZ(vWixZN6c#1Jm=3DF-Vz#$}!}eqn<7JFRNS@CSI;I=c|>k8O03hkZ_SNh7ARg zhc=NMUu?sztnaA$ZHcv7E=8w*jC>JUqIS_HjF{dn(Wf*sc9uJ?Y4_()ig-n%7$HU;{haT26GB>e-=Aeg@~sKSfy@R>HqY^)d!!MP%x%JChc=S7tRYQx{78tz`xp(T|y%TOO=4V7EX*;F&<-aQH6c=~pW- zQ+(^DcHL?wU7$``&I_sT4qI-}e-5O{jE zR{W}v5B?3sioO=_1q@Z)&WJ@CsVQZ^_uH@Eq5Q`rhpBy+8CCf=)_Qup#nGkA~!JNC*$+@r0CXmW`n`K{5 z5>lIr26N?)sPe4?L_-1^AzLTux>DxaM-h3$4rK-ubh_F%d@d+qJ=N=CdY z?%#(_sjhO`v7m0>pVM_`;02_*A=H*DqB~Od_P}yVklgu@Z^(JtWoZ3SlXVy;jq)m7 zk*tp&Z6ut7SC@W4RxK_%zYX06Ye|~$Y@+?}=&jY@9PV;_BAH)*##?vs7IpVfn-Z24 ztQmNQ5(N3RqI5rQj}qC7=`J==H@?Z8Lug3*Iw|v%ZlCk{cYHmLT0}Q_p_mgronHKp zBMGXgTD!97ks%2F!^T>x+K3KpIuqivGfuJF1qQo$l)A1f9l~&DIyrm&sbH%{HEqCf z@4?TJjuLDnv>(mY-BF|nH<~*NSc;CtS?;Jx$kN8zF-UzXnY<2H^1Hn6HGA7K41`bj zg_lZKl7un#Exh|-rM&%5(`WK0_E6Ek%Xb~Lqnr1GiyqO4ba$r5+RBRgBkONN<^4(_ zjJmanTWZdHMH_O1S6N|NemT9)5B}JsVMzE+h_tNdKdbxKE021kJ;IK5s;0p#i#EHm zG8~_?;#M15bZa-M`cY0}!U9|g6siIjpb)F&A3{D~s& zB3a!yu-0p_D!+|Yx*pn))nnq^m~vopYpoUa+V)QQTN2~uoGXa9`)r=p0c z!qKmIO?)5tx02#@O*Lfswb!Bxwy&sE33mS3Ji?0fq&X$Ai=DF;q-DSL5tlgc&eoYc zJ%4n5(k0DB^T2&&13t><=&PP07|=I2BJqd0<_kbhL{X8u1eN;N2~0HtxQ4K|MGcuH zDJ`yTy(XtUCD`*~pEE_xx|WwIyRh0y?u% z-UH4;-HU6>(oP4tKp?s!R|XHV+^JqyCOOhi-hZW#%l5I7hg~9ND$i;Ny4hE+fR^oY z@H2Ew4jyT7=<$6KAuDOll0KV1AA4;s@^0eu;u0qUc#Z9ft0H_egiH zfRl6A*JMDR5G>pjmcGC>U}9)N=)FWRU7`+~x;H(5!0n(UqNl$hjJJgRkNKHH*@MUB zU$y1}0{JaF=SY@$SANITdRi3r!5i7V~;ay7pN!4TOuX7c*~8QlMNHf z;MIU>$sWOE)$^5b3D@ZDqNOMEoxi`!+ofah^F(-Q^vzjoaZbRpe(0h8q~_GTqKBkt zXZ|(;-S?U;sn(?y$c0%(5f3yaFR<*!AQp0^0cbxcWnP-w7$W8%mq^`u()|-!=B`(N`DHgK-3B5Xt8g|0uyDsxDG9Q{h z0%Wc%v>>A1x;a$_P?0=1iE}t^8!qGOuAbMwjnPJkxe1Ok(?b8M2rD2fNp_A=J6h*m z`-tzWFCJgGkC~wLUM$uPnH?u@!@nS2lhv%CErt8$IiYVSbsKFp<4Xz7YmL^^*$VjHIivSykgHJ3g!XQfYOFCC|eJ@;yg5*9J#yV1CfdA3V)8b|Eh)Tq+hRAFK_<^xr@j@ z6(u)m&2w~c6Bqqt=Xpnu(a&Qs3chLBl3l&h;EOi;nS5veB{HXJeH`hsn|NQ_=O;-bJy6IKkF8C6k9P1GbH{AzY?TC^m9i z#MIppWsI!&C|bxdg(YF{CtWt&rAAyJj%>xnDF4u%`6!8^h(qZDdBe09qC^yOPvkTn zR!@-&ZC{2)eLyqBn=aZ!i6I4JD2>)3w)4=Kwq6iyuI)z5y8ZB`BG;ihM&Vkn zjy$?8PCC>t7yFRnjOuwzpx}a2G>aqG~uetx=gMOS&!DfTsysI96Z+iWb(2b z{~gTZZnf`py;3yTt#3y^hq4VXRczN~*3rqoX3_62vrlkf`z;pNS67_3(L_4s%0I`< z!24*kvg{v54Zszj%QPLu|WAd{&vxdgT^9A_G7^1$IEeR4cxqM@v82xul~K!%_s0RUhRuBbtmCx zjhs;Vlzw*dithQ?P)AoPnY;p{y&GZYd|pcN>hBy^2-%W*g?cN_c@m?Huu6nbq@F>fNp1}auu(YusA2CW{zrq6)jAHD-4>xMy%Yr=|p z0BiGo+GmLgx5-xofn&=~M}iC6yK3)X&U4hK3~cYs>wby+Pe+x~+&6`2k(64Tux~!s z9Uvu)wvTTKi3!S{$JBB~RxP`jpNqw>YR1PO-r} zxwd^69rVrE?0Rz4$KTXS@#A<}=+8^Zlk$LCxdx1fy2O64GVW%8fBgQs^O;3&dB4s^ z^QpY+siwl1&gRJY9F01#KT{rimC8?-w*S^tATR$fd-ziaKV6OXRBxZPZ-2z%fywBr z*0B25CYyO`dmN%9Y}(`5HWrJ1|J7 zXmf{ns|ruh!zYaT!6Uoj-Q1%fXpHfOrBfDlF7w+-YL9|VfGt3qaB^9ZbicFN+05Ko zO9-B)+AZ%K&4MZQyTwN_ejgxp-dOmq0UPCF^Agg5 zehxO~n?r^o?v3p}iNOl~x!!nH3~~8a#u^y3j;hkE6kTpnL+{K*VjeN)o88Do#bTIa z3{H)5#6sBrPi{=Z6GHX9AXrTX^J#P6gG&YCcL-zQCw%WIrxfa$k%*7FyW$N+*RzKY zO;+4!ID(_TT~h~-Jm)FG$EqP_AH z)_M_A6|NE7yEO#2B9hPo?sp2#l^HCe-_>H^Lnfc@8Q7so%dnZ$b}Zv`q~1-5zC@s$ z%Pc(2^J&TgG|6&m-bE@G*sA2`PZ?tff<&IsHe>;Ci**bkeh`TZ$76? z1TYSCsy(62>N)+XcTL22EdcE1B0KF=Zcaj8VH#1JJe!@CTwIytZ=jh)5bO^L*xh?< z|C%TxGNz>*qd4=#`oL-jf@D#rF72p0U0s3M0mAIZFMFL1q245Q0|&8Qd0-GNVWj1b zK}S?tN_;<}UaV$7KJz=vqgek7m+0?QD=Zf0;c8;693n^)%y^vp)-nAsvVM^|4k^ce0q4N)?6rhn7=X3tNs{Cb#2kH zU*5b(%)`6dKvi*mHepG^wXyX$u$eb1dR&`m+rfY^0^;keEaOSVP;BU(Z zXYJV+P*{rKt`mo+aY68c(Ydjg&uKMUbN-#Av&(IN1~MQX9{t0yLe_xzqzS*Uu~0(`9_>FEXS}_?}5miO1jBZ>Z+w>USuW5%2i-a ze)W5)hw!XE`ovPv^BibtnIlv_W#|(w4^^n)~eb) z9>k$_xSM8-=#(aKolMENz}P!a(=!16!-{%>?(~{`S3~+DPp(?f56;FB8b~i)<$f!} zsy)%L3*yRB4BQq}6lML&1)~aF>>cq9w|Rkiek(QSt@|8L-DE)oS`$=VjD8&Gv4}@BrrG3 zLxrM(4}wZ$Xa!h*R=3IL_IvWcG-ky%^E9R;(2kgeGdpNEQaK?e(PCxkW20sSv~~*u z>jLFYR5dm|%-zN9e`rQ{X}Wb$u@;nT12~^hFXIhm$5K>{S7z3eEJrf?JAOkqFHtas zr7LS!v8C1qgutTG$kGX9;{)2omTsxot2}qoB{D&K(qYc4lcl{LDqo*s;=VlRC{vop z*?KQRZ?utuH@BEAIzy=`HJ;MzyXcX=1!1#RV8TUsll=Ug?~fv)B5c%WFX{NHRo(^c z%=VcoFx*z$t^U(=Hcn&aNCfgQV4~(r4zG-^AnwUSKll)U^~^H|4gDG4Db)2qQcKsH zOY$B@LdH7mBbzFzPlnD}7Wz(Np2EF+4vTFsPsL|SqptEzy2KN#m_mF2i+pfUsbZp_R?J$212#jhV0(>VnSP{zG7&d1^ zR_l*=iocK5UT^*>!W9q{&|5Fa?Dx)#%j=HlqltFVtXhV! zk+ZF|kb})BkAp3lKZV9ObyidZjTMaFDv%X$3r2xBU5bK5o$TuNU(zRNlkY2Ay-X~q z3Mp;FO1DI5&v>b-(>gm-%+GX$Yp@^*@9ZTn@F*MT=_5T)|NpIX^EJNIhP)p4m)u@x z(-XcQeuwzGGp`cXE^uj&OIyttVeOFq%OXFEKH}Z2J0b|l)060F92cfQ>33*Hl-|Itqx_<8;Z0OgXfKQwL6pSW9l+0G zTZFEs2GKpb8w0)N8=x7NDIVAeb-(-B*bj9|S+c}_wTrK~w*gc5nCbaNqR~nG=Nq`) zu<)p-W2u$1o6bz`hL`KTh*k!LUi!rL8Hmm$n=3f?epvOcbOF>D$!`Az%9aPo?@~>0 z!=1`ud}0qTG*LSb`{4)4u{6@UcA`Qb;PQrmfG;TZL+z&gr#)PCnh8ttFp!{*%+D7* z?+1_zTy($}E)tqGZxiS8O&3rm}NedHZ3bxmzMr7q#?Z3vo)BaGc|^7Q6S?JVUq#_{4T_SV~gKg5`clc>#yM zgxfl=nC+uqdpJ?qM==*OXC&SxFx9|FMusq;Y zoX6wTuUXXshh~}oHH&%byPptzdwObqTS#xxRO$tM!O*7h$WC^L7hTIU`4aOv@RR@H zMX9bb<3oD=QswV0E&+E_I1;jJEM8>MGAJ}pw5|o8&kL--B{;ukb5~#R@yC`(B120X zyS6J@rAdxG%LhWe2IP-}C!R$e;-|K!0;=;ej+8#>-QOtREa~0dLp>Y_RzW{BTq(`# zEl`qRP1@MqkuY%net1OfoiE&|L;bNy&0=|a58`lzIbx3ld^xlxLiPe^U2A~Ojj)<; zHb*h`#dP~TU{V(LNt9(cxKM>WRsUfDRkX9qv zci!57@24fbwE$Kv06kFfh35*Y|GVvIhCcRjJ0+*|b+1zG3#AFY0*yKEh1^#sm+jH# zB=-X+GLa+^e|qJjO}u3QH!f_ z59Bh>a*E==v@bVD;6B<=d;aCe=MPG65?wJ~Pv8ldpZ|!TodNKDLiBMlB(YR0tJrCq zEVfXizY@dVwQ?x1M6laHkGiKd^2$fJ=?+x`CQ<)OQEgy}v}{KT2UKZYdu+N`$u~En zcrxsF=hP;8sqR#~>#6EI4r;ePj3O&lA^Ih<`ai&xx2qP(yM(0ttNf1lL6C*R{*(Xq zJlVa>kSN1C;;)!N#&5!}GQ0l!x9!|O?HEnu&#Qhk?)#>AHnsN(>ePe=yEUmfCG!p8 zG8m;u3$S@xEFs^DkVSZHVTx4m-@W?T6Y70CypsJ}+_DRtTfCH)6AJIpmzb(|PZX~9SW*qwSI&;0b7Ri)p#;|RK6_<+UBjtr?eK{YZ>kf(@EtxsuZy3$ zK))?UU#Ig6uasZ>YwZ^v{R56=-DSm{8WLkW4M#;rN}960VfI4F@Z;bSM@IBB6XF@T zy;axNt=GRr{W4lbC9Ezocxsza;!9Lxg5*u;vxd1-_wpYe3NCtL-VP4oXy+J?M(x}{ zo^*)%nr4y}0N+74zj#;8w?B_Iw)G7mqml3xA2V}jI`cpLxE^|HNLFfxM58dBfzgBhQ_ZDCdXPLbv~>-BA3;U$Qm>$UD3s8*Pk)|JhcRt z&1JOztwSuJ@N+YM)~qBoEC6)_s7I)V%;$umHsz#x!Yys-E)~XpGY{60d5R^qj*cVY zTOV_EidOTyTgQ48@Y1ID59M{;9Y0w0o4inY1JSLtCPo~-|*DXJ1S7 zSQt9Ky(TX!K1b(s?D+k$v&W$Zt5O?RR1&o-0?^$ie_m&6R-Ei*yt*MbKfJc^SN4e1 zxed^3KtyCBmWEL3$@p zdJMV&w@Nzw3V-i!a7y)`F|S*=^kTveZ;VYn>;M3HdgAVsh(nFFa_{KvUJsR$ukfU- z#uks+=ZdtAvWtxH`LG%o%=1lVL;`-shN%n{^RGnqPk(9g__63lbCxB{^MB3Um!1Le z`~s2f&Dpk7GDS_9K{d50z|!jn@cNLn3HGU86L;#DuFz|lm#I;NTw8}<(O#LyvdWQl zZ{t~@tirL*!=|9hxl%#qBGoG1GkGwD3uqIM^+cm=OjaR)u9io0_;Gdn+L#dCI|jka;AP=t4H8BQ9{_>{r; z2W{g1RcN%H{3geapQ)7#v{p54%PE}fv-XEORieKs!Kzaiggf&I+wj^#k04kyj3D zB7UBKyI4Bpn1ZrjK)qU|X)^uoG6VUNWN(hg%^x>2wz|=u$=!x`b8)p~ zn_Be7UgLOwE!{Ua?%iLLdJe$fyRWg-tOXp^_+TGrUS)YMFQJcy1pOT7q4Q6HQF(wT z`yV+m!-RMO4>#hma;`LdTb0w?r8!`|nch)z4UzkR;9j*>MWI~Te5UPFs8U76I@q{< z7w#CMAqc3TWybKY^ytr&fnXE%4!)ZzLifPPonOGSD{~PB2KRRHZWmPv!;ROI`C-Sh z-XrS<<9j_ErPZ~$Jg5<^Rqb?0?-`3;3#$z{sq0(nPB0NTo#d;HJA^Ub(FI_zlkAQT z+gCyhK|Y-)+oXo@0B4}~Q500q{|^}uxI|YJjLwUEWH|msyx+$cgwOnZyc!(&V=&M| zz7EQ_?CCrT_95ARB|5e1GU~3u3-gO)oJZXqYkwkXp2YvHeFH4v;{XtHKIiBpV8l+) zju9@&ZjSqxFVKm3FM=PH|*n zh7EZOj_8&jt(99S|GNRYYSYp1maMsv+>pm{M6e{CBWtrcFGT{Az0|&w zGby_2O3jF#3Qa%BfC^;WiZ&DzG2qFS((%J(&?kc$)l|fL7n)A)4C_H?{gA^)a(>#AvNI zpVGb_nzf~Wz<28-?J;}lyb?B|Nq43`^mij~y5N43uq8$JUy<2N^@#5-{BY=>7~tgI zBBjuR)UR3QBi`~c2T&$~#avX;mi~H~8g6CRUZM{3KU~o787FM;itqipm}|fKeGg$G zy8waZb<~37Hy^n5-CXhzR2e5%5hgSth1HKs1$xsNe9($;aU=P+T0<6p*NW(AvlIBD zblm+9?zoJU_sMMaSL3bpZVw3vZwvV(lmrka<7pdH|5)5A@IV7Mo3Q|M8^aPHAI6tj zon8C(I27auFEHp1Ei>yise$ZOgi2;-IING6dKMGsJ0ok&$v6&$`=op+a zV`YlUl&S*?_FGQnJCeOMUQ0?RUlxQfDUsJq2h4K-JZcyAH#4D;7+%yOe{zpNV@NM* z;B(Ep^8<2t+Py>ZEL+E@{8n++Zg?TF>za7oVNTTE_2we?%*^BDl@#vntI{OEaG=yZ zK3?ua;YO$6OWvUZHTZJ}i`w$l?-WNY#9HZ3+VRf&sMj@`oJ%!7r}wDQULAAD(|8<0 zFL>Q6*6hESFHWX(4sOKFM|;dq{_-D=IrlnR@@m@hW{SZUA;obgX{$H}2&Ho*T%laV za_=0xXWgQ!LFutzf?6`9V8;p9fAp9VeS9yC9#_B>gx^($t|T3g#3YlmNg-W|&~Jkc zvp*4@2>D41>WK_;Uq>eA;hn?xhF>YR8rQ@pwulbvW2V_1?2jB+s%TXtjiO`DOFlyxY;Fdz}T+ll6DbRIr?aR1L!7nA} zCpXnKLZ{~SGdXh!l2i23L`kC?cnhM%sfYjE{E_8DQbkNHj`pCLUNc(pjhn(p zuztx(EJ>&?DvNftaIj5iTQs_m1Yv+zEI3L!lO#$ zhw2%&arj@wI~hpgl2OHPmzGf2dQpJO434xSH6~cd2moN_8gb z2>q-#`1jsau}`~VosBOlkEmX)Lb>T#Q}41IZ)-4Jsszn;UZlmmKST)VvNr`@bz4~| zuzI5B0(>Jx6Xd%G7ISP!emEFe@S05j#}dbw;a+hXctyVkAfE_OO#cwlnu#xCH1X4*tgUlGrvc z>5P!BTxQx~4cBX~29~0ycang^fe5Ubhp3N649Hp*b2G|C>E6j@YwC6EbuUc%QJsDo zRK@G^U_{6k3JnnF-|X%;tTN6~?{k7@oBA#iuWv?p>>na8*k!J{t0L?_OzM?$0=h_Z zoagQcWqLRJu#lHjCIfM9d82|^}VCcS9|I2A}N0`vlsg9f`ci}dAVLdX( zZHcoVQ;$q=TS{nj%&Pd__EM4l6@~j0OD-!V%X3x9Ay#L)9NE_mCIKK&w@YpMtd-fUW;E`B8(nm zCpLO!RaEzg_l5pu^p^wsLnW=xa}UQJeGXazj}-gpL))N^byf zFnlQVEN$G%F{($_0dHatGm;;0)P>KC^ZkKYp*muvBfva@yusav<)$|w^^)0h!NAvk zGqTD!3iN`G>x96MRIN7v?XY!EAR%hh^@uEE$lZ+SbKp<^O$zlo@c1CB^BCx<&A+{5 zPewPth4h!hI3pywERcS&I{(`&7RS;Zp-Z4_5DC7L!f>pYKHzG=b`DMffw1VcsE8KiG2-N_Z$JEa)`FW_yCZms)1Z!1*CSjG5y zUin%?*{gn+K`Dl|H~%v)je#Usw?rE0W4^rwK-AfdRYSHThXA*aF~V|){SdI_Jl=sG zrHdmCI6{?2rJ|cPo|q=yzl+FgI7|YUJRs^BQXY*NZ!s%72#Na-PfdAL8odd!yf25~ z2ajNV8;WjFwP6}JBmJFf#?)iRu;~EyO6%-~{9U;yf^iXDG=H_6qJ)VcdS zGzFXhx)LC`x_l?}pV&34qE5c?V8kBuh2;h(Y(whT%}DX+{m9TC#-_G9)GY*I`Ta?*^5lDw+`qk#p1wea0cSiV*> ztm!TDhM~+JvE`_mSoPlHa(A4>Iv|sfSfY^*mV6DKe9n=(vpO8jjcI!Q%+Nq?-NtAA4wA+<`+fgon(`-l_LU? z*I!7d-S?TBKdn2@@Ua4F-ls^)>{a%SGSfdDqmkQ?GmCmdA;VU+IlGr53}W6+ls^xR zJ^-4a8C+Sto31b10Hjg^?Yt>xiy z-@i8co?PLC*jqr)WOTYSIe!&F*mHB^*)bwm#4jo%=DX(#uJ58gth9GO%1*_+g?%*& zXbn@~O@2&`Alh?NlK0rRS0+U*KTtpT*>@JyNc>gM_iPaKNqTvO1JRrzSn53(TGW`y z+%R9HGPT}Lk6|9rpUN`7U=vAGosGNRkOPKH#aL~_MSZZJaDDrr-Ly5s>qa|wT`H$@ z?gu`)eF=SJPCl6|i%7Ebrsq5B^QM=wYs+?}#pohy za;RbqztbkDaVC##F*&Ee7H-HO=`cB)64cEO`e1PfzRyJ7hEz?Dr{3*+LL;HZ3aTe| zT?KCv^jakv-v1nKH46h2f^>7&Cf!I}Ef`2$_#|8VQiah~Bvw6H1w{?BF%VJZ13j}P z%lm%=J8jP{$6@(j!j|_Zuy2Vm%U*=bbCAEevXJFM>!VWT+&_>llTFD35zUsiSmpHZ zm72Dm)jG;Ki!Ze`H#Un27w1M6|5UcFxWCSKEjWnUn=7^FpR4rE`k~c(MG6xoJ&`${ zUh)X~o7%)4z?%=c#)pl3wKv?OS=m2-g7{_zl&For9Mv#78j{muE_pKcWYl?-_i~%y z2k~0N_+QG>Q=ql$KenN8TwwIQH)n(a(~DnrB4;4QlfzbIFGazlGj;sVqg^eE5y-N#u~!<5yknW=NjW9>&v@_nWjI)hrGsZMjgOS!T$ z%WmmKcPG*o>&9lW%UOehubPs7b5<)Nh9R5LDAC(Q306lANkrUnpJo6_Pvr9=s5L8e zBN2UU&Uda1vH=}FxwCq*sr3kmWpzA*v`z5hp6j4s_&6vEP4`J$v(^t2A6KHDh=3>*^F+LU0m5|#y0QG$m8=LvyI+=lu&{Kfv$c8 z)_%?o!#ruC-0!ER9`@txg8;%P!fTrZYri8j%ZSEwzv9r9`kz0|;JWkg?1IHXBr#z! z9q?6)+jo}FzIyiX;ICAKp2L7==2e8=3t#L3tb%|?I$#@p;iqr>ZpdCAz9q7+@rU!x7+_b%sOwArvgR6U+iU@#xo8>uv5v+e9-4u-^%97Nmeskjslt{g(rqzNTK1RflPia{#luL ztI!%Lk9y(0kD$&rYqcb}jJ||_fLudDx2INUPrV6s{vF#MogAsED|yh)2jU(ZW_)&0 z`<`s-Fklf6IA}Z9K@H!q-Lw8O?uvchJ~L2}T|C@TReo?PW^5bomZ-_|{WF7x!IM~@ z<UHiJ528WK5XGQ~|~sBUW?D!284iw#V< zwHh2(QNz_s%n`lT>tBhRP-smVoG2aI6lcSI4fd&wBOaKaP~~s`sR?nIyW;T{52PW@ zFpp4{+S|@OhxvRAAYlG3D**18`qZYzsw2X%Z6T9qbth71>M zO42@u|Ht@=b#{yeX~%L!)sb9u>g5CM{Qa;88c(d#WAM8ZS?G7IMkX#6Fq780tZR6~ z=ShG!wtlQQ+jo#!zqvryV$^Xe{ci>9a}e(q649zs+j$S^kp#DfIL=X|G1D^jsf&bj zQ>$?=b|Bsh@h2)jg>k6g27ivnbuTL zsx<&2t8QzEY3`Hq29&Wjjx|~V)f!D zapCPbpw_13_w@&tD5_y2WxkzK6PH8x)F3$}eHrW{?uSl8-iUoK;LVRxUbMG%uRvN; z)LORMSx9ZOk0nd@N-u&0G|)fJt+H3zD=#fjS&_CWQNpa^F|;KX-TKw5AyTbQt|_4t zoreOtqzXS8Y_IZP_V7}RI)r>3qw{Dey7jlQXEUkEDCq}p1yLv0Msfu@k+Mk3m2k}Q zMLF8DjP<6GatxHvxa$0dRNG_Qdy^cUhIIc9>zD6~cKUghW$&7QV&0&H@>lmb5GXB4 zbg&G{pNkPk2QviG?{CQauCk2DDY5LS)ivWCd|l=jv1dRw&#z9dM7b0Fs$RV(nAE)n zx?uGuVvrE_NAK2n(syOQ=t3Y=>Xm8(E=a|-%bOiX*oBSfG) zqhTtY@jDy{l@dC1NjYep^TxAYCUplSfRhLu`ihgq74pm9b9$Aa z<%EU&r_O_m578ZsvxmsZhs_ULK*G2&{ruzj=-In=X=^vzl$v)@T^Qy`Cd7^KDUYw` zlSFrw%{^Zi3|)-KjC&K?va8Y1Ui`Btb6~#hsp@0y&%Ucn2O!5p0j~$2 z@O(?Gq&U*zrx=Z?tKOxzcmQ%bM?qjq*OM(x?DKjp_4@2Ybr<0sc9!#c8=ElxlcdZw zb;6?5a(?pF1XAJ$$4%=*QXdIr?-{U`J@{9*IPBnsnbbx|i~MYu?3H9XTqa#T)?#}> z=oQKrb^z%_HZ92kldvpu z^RXL zprae2v#fyM!~wrMbQ}oz_0A~p-YqgV_UkQP2eUUT6c289tRLIwf_^d9;Rhy!!1HLL z4Yk3~A6Rw+u7!?2UsX@On!KNHJSvA6^dlHwA|hwS4w+HzD!9U@l1Dg`{8=$jaB9IJZJyQNO>=eHH zqa=VkxA{@9d{1=|0*N~PD5AXkH{~4l`hSsm-D;mgx91alG}s2+TXD7_UZLOQ%23JC zW3{TORU(R^p9$?nA#tki0KByMiBc_TZ^gUN9+5KB$6hLm^6^#0(|PUXGhB`JwP;&j zLhk~vTclhYXj^S6m1cB_l5D;{mI$way$Nm(V<#-?sI5qYj#!xn%x{PAIgnJi5xztM z2K&qvfm&3EJ#$rbc!lv>75Bx`K2N{V!>_lSE2p*gUDwMxcASwW@e}ltfL%-tG`#=k z(CW_k(n){`%&^af_33V}qaS>Tiaz3LOor@N$0$h?Zxq=E;qonUm;;oqt?h=h{MwiB zVbs}5R=x`KyMcXq^xHkGkXNjm*wkjsLK~9T|4ek{wsgl7(!>?N>mq)Hw}B-xXdObD z*avT)irO=!Lt?KUpvY$SFfS%Wz_PT?TgY9GP=xJmyKon!1P7kE*$S`ADv{Oj2=VrK zR(o6IKA8ND;Qfk*)P6lnq^JTle^X%A!`r8yJHt0Jw`#^|zl(kjPs%)aKX6^5_OI}2 zUi8IPdCN1@a|)mna48w3!owGyM0_WOB<3uy!OG7kYWu$b$KrRty#{W-A+!&|Te;G1 z&8_!cLGI-8#o8_gbuZsFlI9$r&gB;%iR6t-UDgg%f&~y- zpFpEGUH4k-Gz^z0;ud7Ep^CC8-XY9!2i3>p`uNLO!wu%qy9-0N0&(e%~ZG6a2b#DPoxVJee=k5PY<&3-S)lYw?;aUr>tXq`}NmP3u12 z2-yScFR1e@r?3OyyV4j2WcmEne#h{khBc8OUW?kpgDiU;i>UthSHsAH!F0L&IXp#$ zEIjzcD=h}Ut(6CaV43hu4Tgzb5`EZj)4HIEklHl)@JM(#MrVzC9~VnCo^CqZE3T!@ z2j$jz!V^G0-Pl&|VQ)ccQV_n*FuWSKqLDixbgHc2tbN-ufs56^vGnWa8#?dl`^GIS zTt>?keE-QRt!s~2x^hcepDV|#=aS9pf_$u~%jQmLtW@9xMSs&{9G7s8SIOV~{g

    |YpsMJ4+3#WvWoo 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
  1. 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

    i!phA7r`Y6Ih;W5DGGl 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�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

    RaTTA$S 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 i_l7Yv9{1FkcRb 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 z zWk=itX!px*47`hF-K&`24A&`g-iIfigz;`nz+C$27wSLl0{z>A`uAQ$|8uba4GDUW zi|GIO^7Hqyi7_QK+>d3S!2jPT1sEb5SJ%=qMr``ayt;Il}oBT#wE_jx0b%eHt!`YO0ukfVb zzS`g?{V{+yKpZ6Z7DtOUw0eeQuS`E zKfxGfK5glrlGjf2j!=H*wlm|C@i*#K)SP)a?bLii3GCi?DPCLtu6&nbEamUt!f*9n zp)T#jU1iE0K8sM^fW5e-C+r*8bJ8CPpDzij>k)Nd!@6)j4Bwv(bibimw^G!75$nQP zHhg^G+02oY$mV2e-l>MIB!SJ@>aQtQ#(X4I^MXvAj=ApsPYd=9PGrY=QEa#8J%7!E z!S4YE2k<@6gnQuq94KEHWcwd()x2Ak{*ty5%+xwB#;Wm;(X6-n8|0bI7R~#r_&r+u z$NPMZ*e#%Y%e$F*UX1uf*f&qTM?MQ2Hi9npYOi@m1TXGZj*JEM^9xE7h;^+EkE&<4YA4EPm(cO&2_SBqJ%8|G#eyfxOj zM$|X_!GiD(<+Zc30X;GPnQ#j)1H6*cQ}~1d{+RkM-N#e|^L}2Ve2aKag7Yz+9b)=q z8@|>XqVGeRwp*h+vUn`)g7Jne{l_7=Kcd*PTPWtvyVJ*8F2Tn=%-nwD$Vp~LtX@ZP38M-*q4y;U&)nu@kVmr=-+qK z4B7s!pguPbp?Ft`HxQ?xeR(7L>4VJ2^R2^LV62u?!USmfP2!pJR||@a_MRU?`A(jE z&%Co*>a@#X9|KQxY<*DfL+64?s~_RtMX_tzkvuN%t9D2~1%;njn?(FX@Ey}{T@yJM z;T~9@D}w63e4hF{wxCa-jcs^`e08wAThRBFKqDoZ0n?@&+m`61M~iz z@B5hk3*Yvkw)Tc;tN9kI7k!X0&P3|<8jM&IX-{*suH9fu4_*gcryDeCd+X*4-+wmH zuo;?uxOHM4xJKCalQ0+i-@^Onw%=o8Sg$xO(C7F0KBg^iwV3Ow&GPOYt@)hjOWYUF zV<|Bf59f{kF6i&H8SPccO3bA2gS9Aru>a58cgIIjZ2`~hZZ?}j0x5(J3DP2<(gOri zC=nGD5fl}YpcslM3Mxg?Fa$!I5D1+lsAPkSiiz!660jhM8uj7xy{DvD0*DxD79snc zGw06E?9A+LVzGJ|yQ*FRr8d?b~*s zT+L#(N))lBB?iHaxnU)V);T4F3&6{ciN0Q@-=BH!YN4dxoqA-k>)nyIWin z`hrC}-fS+$sdFUz2v<^ls;>`G=p5{BK*@KEcLNqFVn3Q$><7S5xLhIEEW_vcOqqKy zFi7dUGYDVZqWqr|emFvRo~7j^IC=Ry1LeD~B_94NtXGeR{ht zb9wwjRg88rvwKBy3me*TQ>>WpV|U}%%2LFLq{{aKFUq1A5euH7?MzSK;{D!XiN-A2 z1$r*}a18G4D+1`==_MfBW+hlty1HhFQz$?*~%GTy9$HGLy-;1JXZPnZ9PG*dwOIcb*+SVe#cz&0KtxVuWX)JuWGnrp5l5-V65GWu}T!{ z-A!ZN24kVlDB2I8&qt#XmwklvEdeoB_#5qOm^+`o-Tj@->vqB%4?=#lClw_CYa^USfVSPydqvGrsAD)~L zF1&XR#$G`8(mT&bv!eq2?a5KCh2=jJJkNE9^?uF#yfAKh4ve!tK)`SDu6p)v?lnh+ zG-ho%)*cFQ8}rizhE;k$LZ*j1p`=(RXEcrTjb~K;rVS&dPaMEYqVUq9s85+AC_z&IJULBOyeXtN;$$x z+XvPn67Nrg^NPBxqBv35zpY|d<u>!uV-bD~#D6FVoXejGy{at`Fi)D(w9*@eJJ|x0|8x zT}`KU_d~n6SU3AkKISN#&3O~x{7rV1F%gbx-lyh!qX)b4J-i1<;(J)1ocNw>KPJ9s z5QdeTT7KUR=p}fUTKcD_6qwV%6tt~}==zL@Wj8VRE>g{6%qbD? z|A9T2+lA>-Am^n;-MAigdjGXTXdf^c&YY^&r>S!YAJFT<`ay$xr}&H&!I5;Tu}Eoasv|-q(*K`teVPMn7+V4fS)^ zI7^YfGF=91PUM=Y_6gptQv=U)6}n6=(`7IwFT8D#|d02w~JJ2um-&mo^F%2#Ik;%hdl;`+n&hBrbvlxKq#B$?j@%{a(yH}ac zCY>pz&i2DW(%F>yutwhDN!|(NP`2U({t=^7_vOtQlO_H9=s|t`{H@ zr43>!tXHx%L<-2GVEjdtu}x&l>uumFB)(Fl!&fW^iLc9>kZjh+gS!W}3=eW& zCp^IT-@gkFI<)`~dV9cwv`WH*Ngom(r2j)}hrKmfw!=!Yu$~?E?$`C{{INsC*V3GQ z>&rlBJCyS)fDfng)kh3k8A!4*x|4zWzwTKETGR^jEr187YI*P%S81-XI&gUVs8NK2 zCYOux!A0;J$T07WI22mI8;JjjcU`}Z@mrkmBfO6`)(yb-@Eo|~r%#6vKkb*Q&rdJE zrVr=(&x~SiLZyCw7M@AIV&^?0Kx6h=6nZ<>!)UL}>EVQM)D_@daLoh{`@7!hc*lx&_{96Fj#`s$(;;sjG>1YoGeLP|6#g3InGYo8Hbp6b*EYWvBxvgMc(qcEj2`NHdf z4pUv7Db9Dk?ML+-KH$)nX%usPf9~XZPuQw(rqjc|ZT-bjDD~~U@23vd1@LLl@K{=( z&%25|(2RJe|HP8aYMC(Gt6mIyu_A^YdG6P*Ds1sNW1P157n$Gr^gA@xJxAr5Fg(zQ zc&v|Vr2HFfxADCYF-IU5^P6;X1@wHdCkkDCuu}b&%Mmp8v3FeQxFq);;fdFOG(T83 zF9B;^NO=iT|HiG32&w-^?tu52XCB$p?04idXpcH6o}nSH8VeSsQtg>vdxjPyi~4QG zWSbCd>uPFjD@{fY~%plw)eJ=4})&pub3u&ek$M zBF+1sh59+T#hh!qu=TF6RG#&`D6T+?Eo!aeF#|hMZkKfKl)v5oKGj>=VWe1*$NVvN zg%=8YQT&av?Q&nzS!S?3<4vyhZ->3gbWWMCbndl?}t{~vxsS&#Q6o-5_j%(}!zaLDnS9L}{O}`i8 z?=$X=N$boF{!R3^JrrZPiRFu6{y@n?&RXZmh7Q8C&){6QO(dSwA(41emqhyp=x5IP z1pDn6uY7j-HfwBcHMQ6AJ`}1~F$?B!2Kj4Nm~itSjzZDbm~|iVgJAT3(%+f*cLMz# ziGN4Y-&H}}l*I{QqHq1sCah1MVDBA-dG2yuz{f>@9<}GOZm)sqIb*%1SAm$8E zKd)gwYZC0GnA4LZ_w#@l$CqGVToNiIg_A75-fk=?^_W){Uba0CW8V|($yo`aj)CK# zeSVq`+UI%U3g{UJ9K5W<I8k?WgSB(wxsap#h+HvB&jmiG7rY;yS-CB;9t^}R; zkgBcAeL<*@o*EiMcaf^@{{y-u%0n<8 zyt@qdPWB1WnHwPLnhb_Zsf`G~3yzB2_-qBOrT(%5=9geEzU&as-(=AjPxMHvg})}z zo}81Y@Wm%8?h;BA&+8oAhoy-vs=1o|XAta7CozvZxvss?;~d5-MhKk|{-3muF|y}f z(I0&%!A^HtJ;3&)tq_WP{lx<@=||fWoJS?fa2}V)YGx#ga7;uvPEC~IJcIo{oqity zzo&oEUflECKOBQ!knU;xeYx|FMv<=mDAU#cxK^0QcgaSP9;MF?T7v!W{mmirg_PeM zPQK6`+RlVNDb}@9%s_>|DaD5?kmAHex(KjL0oY3N%5P|Q2AEC;IN-aIuPjQ@$KB9J z4*b88J(GOL$%b~q$@fq;iVy_+&T1>{!S6%i!fR(7g_5qYo^y@!mg6cTgm-$;e(3GN z!Cvwnz_Y;!!(6s+!|^@%Uz$^v)Flx45O=I6F>|4rJxKHYreM|jHIBf~!20hMbDL&^US~?8x66YFE zL}}w|(~dd{`>6bi)9j8yz`4c~Dw_}DW(wfmoiOK4s(1P{^94XZ8&7C_W#MJ7+qE&j zKU&b&sT~8`54(&puweqHtltE*c2ETRE?NsCdTL{*CU%4V4jCIy95QP93+=;+bahxS z1ziQ0N1nm6=$@|L)l*AX@ve1=u9ouLUJj-yMQo0hZmCE=suZD z_t{!NaTuQLQ2$y(wX!6g=kwOG4_%3CIQEm*5LbC2S+tAsLRD*$y$8Oj8{;d|=EE$; z7xg%f?u%)xGGMF~>4$|67z$8_$Tg7;5^s`i#md;*tNTsjy}I#6*_WXF{XG1RcdCju z5R4lQx^a7Qu2mcNE9t!d_y^gRE?0QB1rFUnHa@iu_vwC<^Nt{Q?{-@48jFkLf7mU! zKzT2~+^)e+TjuY~X8ToztFABE6@0pb9?oplk}i&Yytv=w+~2Hrw4WbV=EBuN#_V58` zUb(d58v~sEv#_5wKCsNj$1Pb8GUQr5{h%%Ki|u8+e;Kx`0~nuyHuIp(JU%XFEwq^z z`T6#_@cYf3;_Q7FcD{G5-}Cts*fShIx)W!&!ny4ObL-O$&Q2o7Y++r?{9ult-yDl> zd>(WV|1*93;_{6klZ=LWT0sXt4P#B1llFEV%ym8=cW@8ycP5*~_}%@&7wN6+!Ck9Kdyz6{V8Z^iYL+8tBQz?x6PM_LQQd_L%R2=`a!%zy52 zgeSm!ZRGLoFxRqlXoE0MgEqfGo7_2R!{$L7OXRWb{_uPBi-3m=o_Mx+cCSt*^KIbS zyIN){NC}Z@=(G5Le5TT^|G;O_vVBgfiFvwAK95qo-_K<%Ci`#p**#aP@9V}j4K8ST zEoR9Nk=%*!^80f64v5}vXusq?X}`&H&AI8TwXyyiqz*hXft~feRBYV`kT=H%L(_h`vhFQ z@mwrmXJsxudla5w&C&yvLE^WRQ#=#fu3&AKQrqd+_K-=qP;{*j>n^>w^I9S1mWc7{ zKu`TZXX#VS37|vd@k}01`+(K70NOPH-%l_**X(EuawyEL9Or40=NZT5S$ow{@jdhR zNiyYyUQ#`7`B?+r8<1cWE?=emqT55Le!dGFVZP@MA)ogVc2~+dtfFo18M&|jU|%3- z)r)-T!MfiFIx;Zez|=R>v9Zpr)`osE4@50$3~NZe$u}HiGua<4$I~kI{TZ>TCU7Zej7#P(@!) zxrfCz)>nDZB$`(nm>1A-%s<`|We_s5IN?f^p}GUW_9FCG2)L2S>VZn@&qbJE9b<$E zt7DuE&;Af~eYTD^ay?pU?4`I5>w#Y8u>AEXZT@=tEsAxlai0tSn3dH^&u4vQY5SV5 z>}!krzNT2Qt`goYF4s&uVo>NjA#%>S6CVw{@Z{SLF*bKl2;Prm5E7#(e(N!yZ+EJ6 zpxbY8pGP?x`kA0=AM2t0bQ~AfJMt|@p_ETLT=o8@4yaceK(91t-oG34nZBy_;X~cu z8FBhuZ9MF$!S3T*GvC$fl(rD}{eS%~(kg?H-yMA_MxpgP$S;h-YWxOT)&}7UXJv|s z6Za{_Ks3qxhPoDfoE?29NoLWuzOhenKi#|-bv)CzrA#g{$#RM0uQ*<63UkWq@c&mZ zZ^<8naiNt)ZpslKu0r(7_{e^l-i*d~4d)sUqyI5M?jy?%=P`-+sQwQF2z zN-E~CA7eh*`{*Ov3}Y8X$+(Bzy-r zS}!SUNy76Yn3E5-12}Z-N$2p9gIYPpV~nYP+&hoF6Dr5V8046k+e-CgV)|84jOpzM zwfuYDo*=QW-{9M+AGRhwiv4sdmG#3dZRDD^`2Q#))Bjn&5C7a8q0|jU-ffn7w;$VU z@p*{++=$OXCa%QiOrDqI_G|lOxm{VCzboiuAOq9+KdwFhPFY`tuMPWX4q`25m_rrt zA!)4IePm-0>j|4>-Qhp%xw4-V`v~vFIOrg`?N>T&kL{y6{V9JsT-{a>>voQY1 zVkVkZrJz~SEN)YJ@BSt+4)7g6AFdkp#w;n0nbD+D6IUVTdpZby-5mP(ozg7hH^z1S zRoXRwpDXQ3+ow;vQUP{KI@=rPufTb<alse&XE$xF>4a>b8AMw&FOaY}FT@<#r+e`|7qNOST2sYA~zg ze}dIY$2$JStd4&XtK;8!AJy^CRp$9Jxh#X_`G(<`J=vI1G-fb98^E6Rr)U27EP*{6 z#p-|K-hj*#TX3x~b2|HND#MSL**>+C_DPOqyz(;PSS_ct1$BC1L;7HYPAv$a3G*+KZPNOh7AL~*qqthlJrqp7UJfvn zVu}2*ZHUfUWNjB>+e6eAq{IU8o(6?-}dXmeage8q0l~NtseVfNU?Y7Mg+DrB)EtnLiT2THkT-AkZn zXPL!1@5Q`a=N-><&P!T3DHGeLvi8l63Z>lV*Ny5MU`&x1zXWm!p4loR*0JXVW#3Og z-%ek<>dvIJmq->9pD|f%)=OGD@{E_rj*K)TEsA&Pf7(l0yu`V^)QaNzoOc~wC7(Jz zdztxX(q8@RG3{4< z_;fqcPN12i>;#+0S7rM)+5peOyGQ*M_nfo%?hvBgFCAcWG=x z3(o$!Y^_gj_fCDi>5CU-nJ$UtuAe%f<$vwindx$s>=vEi8|});huqgzcy~3l`2gC~ zY1^pdSsT}S-ybzJqf zXxID|wJlBJ^_ee9w#s<7^)7Rw6?VB0mJ8$S`HtFoFY4b>E7_M8M!UC{t$)K&sICd~ zXf)=pg50cWA6l062FU}D93*(nKk(P_-Ijs$oD+mVv|Rxo2GDuq{n{-gv|KWK`6l>ds+FrnC{n@iFkosB(19{YQIo*HMb+z-!Z%g?{T=L=Z-r{w3yvG1jE_V_YR zyc=(p55@_B90+SY5-ZDrhxclE(g%CBJn5ai#FH`=zRhxc2J5RDPPN~^=1G6Bj0V1i zaTPtj7MwDG%5VIb z4jfY%9K~l$XMGr-sqO^6ANP6!Tk}MD&6D?%p9sgS+>Y_(^tU03oAR}Z=9L!Zd0z2* z=}t)T8M_m5q|SLCs&n24;JkGFWqom833QLxktA-4XcOJcO-VFxVRK62tSC$Q0i5;b z(^+Re?R4f7%H|UvPV;%0V|`=%!&t7oehoJzc{RoUWUQfa;@8OIOl0uEvz9cL{Mw@J zTW3y9CHi#Xe2I2mXG^sE+)$#W3-u-1ef|;0G01loU3-h=UWVzP`L9c~=ks`p7Ke}M z%;_+WHH7s!T<-Jz61w*>={~L^p1~-oHJqUkhFktE$E~sw1x}-lAdxGN*+lk;4Y}6} z)$89~LU&(_&k|Vt4?deL-+zJ63UKZvGMo-FI9UQ{p1EUap6>3y%}CVFHC-{++_3~_ zC2x3E2i8yN?Em9BuujAIO7U(m-yAmITpukDdbmV;{_ocr=U$z0ChDBC+i~m!w$J0_ zeNHSPn!+t{r75u`?2gmt$T$3rkz|GHis@{0OQW+9 zKbNZ*h35e4u?%%j1LB5g_sLpJ`-FFwsNqzi1E*a&aN1g|&u8+BiO)2oVx1wG9t;X& z_wp+Di{+TTpfhHM4!oA>?9DT7;PoWV187v~3}`!n`IIKgKBYAF`y9Zl&qnK?aZZPR zPG_)_#+h17bqu=pV0=mi&xyr!uMy@N;2Nd(l62OWSWNj~4Qzelnuf^lj40O1twV~n za_epQOqHkBx0qyBu}_7}+OwGADa6_x_fh_u_#TUm>QYR1^f=eIl>Pn;{oWS)UBT9u zCHLDJ=deb~yI}aw#KWmBze>w>ua{xVmDhFf^m3)zjb78oO zxQox07ZDE>pE2LivpB!mY<_d)`7Olx!Co8zeFbCTcpR(5CKIoCwqq46~^n5E$R zSQ9b?*4Ng9%+f}?zR7HTYTkFJ&OVGUVzn*t8S|MXz_UfL4;MRw-Uhf|+KDUoGiOW= zzsGL}j*T&9dko=cYC3XL(1(F*&s6x<2f+K8%%7dX&S^h*c3x*ry>#XjrE@kq>zs{t zZq7zX5z*tC0Ys1a!CXZFPyVTfjwDlj*1-+E?VyEc^ByKsxH;dK_h{G9xJSE&-}Y$N z@arBeKdIZJ&rkjf&(q*6_U;R7z&ei|_1Dm?qjn9)r8VgIPo+A^AMMfdgAey;<%4(k zXmyl|J^H%nt2pNbs;QaW6Le9)A4>$y-`$z!+G^*&%gY{Y-lLUwHtx}$?L3|JFlAG;S2aVlIQl z0vQ&=@OhTeNz!l8l+GS?)>%_Koi&BxIFs2pQ{{15;l8oEBfEvr zIn1@dzJWY4$JdR1Vb<>3pS#(=mzY3x+26DIdB-nBS``d@(KPZo7vac))qw6|icDgHJ?wLjD8w~u!dAB*#2 zd<=AE%oUXU-9>lE{%)ncT=I8U?AGGnYrD1hw|}>GZ(qi-OJv>Vqcn&msIGFjX;&Kct>kVazOza(2o{mt5Ka`EvCHb>zkmEV7@jeJ$V8OdLB+DJay z2K)v%wk>xQCaB&?XYZV3@BF~t`44+%uw+*U8D-WRjzY<&jBRGVA^V!qAM=Hg>fd~B zq+?3v}C?2jhP>zS2g?P{AV6m_{SN9iAUv;SNn4~t5S6db@`}Qu1UpxUcNg0=i zw5!2D^C&jR^JsGeF>`x%xyH=x*hR5ex3YMnBNtgr?nO5-xfkS^y&mixv8Lw*ip4#0 zp5h=g&g;kGRyE48xHl5>_k?Qx^Q661#r!?GOFzDMXh*vDOC9TXTStoZ3q$|4Kh=3r z#sK%}NHM^z_2PfoyFMLR{BK9Phf4W=d)DtYcDKyK`xG^Z`;i{bTNpl>XnzOoa;;H| zcyiB(-~zqcQJD%K>Az2#0|mNnwx#%&PRWi@D1qRQ_^8g z$PX|Nv=Yt)p0Sx&XBqyEzU{93JAC2}`d^=UWG3%-CI#9DTn{|57S@kE#maL-5GN*F zTJg=zF?Z!pXv0>E90!q-9g`heS`T6 z^N;@-f&b&*2)8r6IQywS+*f_>iL=k`#r-k=C&wQt@ZHdz7bax(7H)>V*QNvuXAg5i zWMyyQVVuy=%V<4)3upc97T$XH7K8Oly2_`@{OqC}WB6-wOxaG^MyrmAbE#p8F~2)q zYc9Fl+s!-io+xchO0nXc;U0Hg;)rn8B~{fWci!!!iUnG+Q=9L(1fKm}HA9bWQPm_@ z`>kWRMvKI2YPGyZJ>SVX^Sx^)$w{>xNlrqTin=Y@-FIr^pW;~`DIKT}W&7b$`}Wjc z`P;yqu6ZWwU!@rCr`vI&u2CC7@~HBip3*zm2ISGIwxoL~+jQ2MV>_L7hVCT0$&o5y~dc)@j zUDJ;{CO=nAl<7L}9l?HKuF)Z!XzStwNRLs%{lgtv zxWCKZJCD9P^m$w8OpRvo!nrjG(ii^WsEz$m9R_I1%+5RB%be))5k$=PQ zJ9lVh{lXn2>qq*KtgoE=#vOF79tXIge$SgozgMhO{_cJ9~Fir70vKE=81a_rr|SdNnaORn+Q zsE^$GdXTejh4?P;s2X@zS+8PCJIYJG`r==Y;~JhN$6>qEbuOoSkL^60PBCTM+DLa; zCQ*E3Fvf-5(WG}zfKsM=FGwB7#R*q@DX-v#{c=3JCT0`HT;7KAQ!A|$GyIN~_T$YL zwfn&(1HIXJtq|!1)&)Vjfq3o2NtjFSc5RLt;^9+lpNd{o$h=H8P|Li}ZuhQ3-k+&o zdnIkVT*E|9rb*sTbiG(X*YR9T->x6?`_W>`=~3spP28@Z>z1^ga^2j)Cr$@GxR=pJ z%I)ZFq&$P33|>=SbQ5^$XS>$U6S`e%PY>Fz zwH^9x*ZM3?2oI1u;zj~I&;~k!t2oKaadMVUatxS#o7U%kahsMuo!h3hZ=T-f8b@Gx zmC3?U+PIIC+ZZ30;G*I=-|6)K^){_N`}j7k-}cBht&i*QHi|dwHi*R=4&*9!OR;R7 zwex#Rnjh#tx!owHs}{a__D*g`?K@@LNJg`CCK=7&H)C@6^Zq-Wbqwl2hN=Vp+eur; zV8=FX9fK{~SRDhlPf2Y#=RIm0*!)U6kl)9hyjIlSv%L2FHj>w*F?xr}V?48sbjbGt zxq?t8104y~u6zDAk{wYd>u#o6thGLLR&M6xxHG(C@MDx&ROj=dZCZQ%v~5~@{bYPL zn>|Zq@;}b;Dd@ik?CUdt>o;)~z1be61<_pj_B7YIin(Cy)N|+`RpDODHZATA+NSky z-Lg%KkI_13u?Nl%)|A|hYKj+k1UNPsY2WW#0Y3R`Pvg{c1~V+6O+2 zcsTx!^5WgB4ev*`#yhu4_0GpPNq12OG&%|qepNid4|NYUZjRbYyi(MQK>m{SqG394 z9*ECouxHchS$}*smpz+J&-!eodPkz{u~a2{!1;^Zs-rJ~F7)bk%7c{t-+!I*%B2Wm=XJ_+>A=apisNONk2}WN;Vjh`+;pAt-h}Iv z=eFTG<+rtBI$ByzlGA3|>MZ5Dvpq!|*yGeal z73#}=>8!u+i)GnZwBdQsE2`7~dVMd)BJaA$nl=TeLof^IKTXiNUkX>4cG=K8$L%Fc^8@ zv)^qoiD%>8_16mL_Gk8J;1d`ha-;XI6m9^$StkeJJs4~5I5r0G2#iI#(J>|$zT)vO!*-J&N<}IEfmOGiT#U$U4 zqO5 z{|cSD5C&dYz-pazFZ$om*0Y;s+Um{cRkzudwuyAi!su8l86W?(S?h1bd}YvK^y_g- zwS1oTUKex!v)*}Y$+I$VMH}F6{+w*r0QhbU#PYop(FoTdJ#$ z?`UeQ15d1a(ILj{E(xUldTWoqEfn_wbfzhDFxT@Ptxo15HXz$Gyo3$9_4ekEKUv+5CwC^)4w;y2n^Gk#$ z3-`FO#l>)qX$A(D<2t&kY8|85I^x^Qwm9i*4rA+1X~!vQ-_UQjZFcnoUT>rIKlR>B z^iyh+8^CnkQ1Tyj3nTwgZ7BJVwlh7~T|I@c&01YIc(c|n;J=x4wBit1N0a7YRLy&= z&b+S{X#H)M3dp9F|>> zU}3UoVeyvEdj|_--(!iHn=(Sj_h>Dky|2x@Rv4j*amuuipRm+NrjzkLvh6`?x3$3J z(OXe!q+Yt<8B^0qOiz3Y}l-b5Vhg&I z0r<=;$3fwy`6a8AT`@D5{VrLa>#hU)@xrOoU-g8rftV_2< zzkF<=cl~n4LgGu)Pmyime)z^aDw7l3*Ta~MwGR$pUaR{ykAU8a_fldFWOr>YfZmF^ zHpwOK+uZk*_xc=nKIOhXhjT2{Z9xW2HkiHEYPe;wj{F3DZ>g1IKGk)Gf^>A@q%Z;;RX2&exk`vh?h+6F1=i2?k+IF9nXk1(#BYJ~ju8_Kn2Vf;Vo ztiQTTi*tu8u63ek`^!G~S^gwf6z|gdXn)(G_0c}N$<;^OkNHJ~UH=<7^1)5sb@a)b znC!u6V|VV@q>87Ka3-0>wPIca-l+z(G0*B+LvG|I%zcQ{*EfJZrepiIS|50Sgi%|$ zHr!9GDc(?7FYaV(IuF%Fv~Tgd6#5vuBcjtL&owH?J@?n`OpBI!_lw{99K|QLM8D|q zoEATnzV4A6`MQtprFHu5(wASQTI8oJQZ4fFqKy4B{GS#yQ4=e9(xQ!(lfT#WX_p{m>Mh~9_eK>)g-BGS`^Ui!7e|;S!1uG=^B~mNrKAW$V{h!Kbem*yMF3!y- z-x=Rk_MJK7|8@GCA@$daYi#I1KGw+2+>~#1TzP&oYKNQ%cIF*p6OYye0_N|GN0tb$9%YgV4Zcg&u6|F)Z2{Yn~5}%oEFaH z$wh!G=v%1*{XxnPlHlye;9TV^_i2JYhqHG_q+csk>k`)llKtY_Xl1`kf_C5j5EvZ} z*6L2D1ky7;f%RdIrRYBo63^&YeeTkpQPCgP3gpv6a{V`{uM>i+&Jt$U!t1zz@v(F! z69WKVZCSiuh-+Vmu`hV1n?KdjtMwyWgY^49bk_N%fWAX!FYGDXCtefC*XqefwU4!t zd{lb{lat;_KC0ByKoigx?j!rcrTG*J#9K;DvY!&~ZIbMxQoD76XIF z*R1kKE)gjAtQK_!gF&+=3k4lrAj%*(E;|aHF@GRa|Imsn2vErC{m{OVlW6sk{7Yup zzqI%lqH{}k=-;7?vW0Xv)c6%aRI`@x;kyLNJJ_<%m8Xvv4uSSDOn)_3EC{+DT8V|M)YxVFU$yvy

    U& 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

    W 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 z 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


    _sU0!dcp+oU? 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

    xwl9T_g1srZI=x0VzcDtZ`~)k zw7APh0n5YbHuc^6a@1k*C^N`8-8hK3lM4A=U9D`puB<1dtQBR=7qg)ABK?}Wy$@?@ zBgcWq9Et;*+mLK`oAYcza97`YN|l1(J~9;UW*yv7KW%9U-19ix7Xj|{zf7v1PH=CM zoYTu5wYe81*H8Zm%4m2X*q_W}zGlFxDc(7q@Idfy?G3=6?jTys0{(d%{?AK1jo`l- zeGvR@=;IaSZ;|Zo=i}?A&qup3+N*x-Z@DyZG943JdrJ5Z^ea+(M3@)xbafw@aMwn!y`3^zT6bH=qo)wHEj@ObRdkM@acN>h2w=amWmq2H&C>L!_ zefOE@YwD3w@S6G{3tv;WmS9b7Fm@a=7{k`obH#m!`^3C|ajPZ6)hprvM6n(Id_bH# z==|3=ywG1ucq-80Y1hDfG#oj+)6NLr3C%BBjN@_v{}M5dSp9E2FyMDEwZO=Tlu-O*RhN&W zIJX8j>6TpZKgk@uei;?2Uxq-xjD~y}1Nrg;$d?iJfPO*xvL6uto7xv)?XrF}>2=7o z6v&v-T(>uYXIqjicSx_G6@N#yp-+hR(-t8~Sr3lin|e-giLn8=?0N_&*E(XX1Z6{>SO;fSK-= zarM)wttF#1{S!!QMcUzX2VfQFruW*~zGw607dioJ*d~xoxtIsZs-irrlAla4mE2l9 zwoo6yXHK&)zwjX41scc#4XE-8d=0*8y!*xox+@l6Lq7fdbZmLma}(qh_;!bmZ#91T zzSvi->JPgM7x8{sKu)E*l0Ja#uRFutA0N1j@LoK(i+?KGJ(h=Rr51HKmPs~YT z%%}Gu%MdWrViu5Zn8(0&R6vGrG4TC5nzy(M&(FFs=4Z)oS9jK3r#tK3EY7+a#!h>7 z+F5t+DONLZ=OI3D=b`Hq%cxWDs|Due!y0Kb>VBNW>wKET=V9#+zt^eVf!q_%@4S#7 z9mNKtdt?M9}%`xwaIi~OY)u@{uU{nx(k zTB)ofd@o45iz1)$t9xAU_oYVk*R4CnX>kT*FZrcdKl8@aU1#@))8&*Xbh%K_vz@t zZgR>OeL>LS)rvnaC9s;5)W>?8 ze`sB&unl7PA6IsU^V-9N`y7G$5dqxaPq-g1a6jg&;eLsR`yy_4Yq(eK?lHkW%eQH8 z5>#dJ89udYAHg7gJjfaXx%iz@K?+XSiRuW(U!GbLEg#*U&xsig3R+(sA0| z9%?Ux`p7~b>p6tc)FvFw4&hoG+;jD zYZpd;gLOW`DECH3WcpM0--fadPoBWhFAHRs4o8H;NO*E}a9YdD4bYlKzguZc`N9`F zU9`I+f-k9q+f333*heYBev5X-&jX2mj2EyH%{MhS2{skR>rCOcRo-yqrSLt(UBmDj zW2zd)RR2U9z9acBR^+fS|Hb<{M1OgJMWz_@nF#cXzAA>xWhMG`*5|#ziGa7sEO7E+j5`A6 z^Yd~3@?>Nm=jM~aWBVKWSLsK0ALO4WxeREI50Q5$--!C5<=>_9pyP#coQCz~--=Ma zUW}~?vV;2B)#Bel=R5@OIR@S*)+s^oenH&9QGM_w&QoN^QGcW}^gK0=-k8_vf70=m z5Z~OF%zO-kgikN66(yCw9SZs9CaCH5f$|&8{H=O@8_$_J?c8VPHoWWXx%a7F_-F81 zBVt+I9U!uEwn&lfoV!j&wsV$>@jP}md`%I0ALs`s`5e^r!GZK!PIB9%Uf3oTBAs;V z4JQM-RlnX;{e&N}dFh^%y7n9j*%(K$D+24d?||OE?iw-F_u!*r-ddGbBtb_y9}OBS z^*36DQMgY5`3}^GwbwKaPMV!y3iypIF?==q%Y0JUUkTy&YcziwhBE3M5^6u?tF_;8 zLbN|Pf__a2w(pLd2-dIjtZ^BkdqU7(9c7H)bNB+osz z`!H{)ZzJJcZSzL9+@sl7LklC^8wl|eOq`|CFX{6ruvQkQ!e%Nbz`>D1SI zet&H;{yIIf^_W{22cJZOrtntsc1orZ%PCe?-H?7O*oRM_Z93PJx1zhZSn{Y(B zkKSR#_!fHgv82N1_23Cj{sh+Z_nKJE2yxF>+yDC|#)0v4?7*C~wV1XqGVg@HmSXSeRM&g&tjz_jnCL9l!8AZn< z?;%`>blO8S(f;KXHs3qohYavgLA+Vzr*rXAhQ>>iBk1%?Mf?xy<0{d|?62NO&oR-5 zBSIfn@jg0Hrrc1>eNJgFRQek@#n z+s;;*l3#}7IJJASg@+baTan~c7e&K7-uFUseB{XX7p!*~~nw!k;#H-G)Jsn^@Y z+0-qw6#beaoQ@><*PYy^c933KWRNR`o*3C3T~D0z&YJma`omVR#wR!WYa{!^nxp!| z)}>@tn?MI&<<8pMN2A{d((g0>yWd}1o)Ye>9*LJf{6{!1ldt!@IL?cEy96%^`g!pv z=es}si^sE|7^4!!7X=^YvXO^k`X8n1{f`Xtp+$zqZ8t>lKT417fAr|l*ys5hZy^68 zL&uJ=xJBtM?QF27EBrh^6kc0Q0b5r)*IiN)r`C^4h#hNcg@vE7Ki-!bbjE)3QLzWj zbn&jTxE#3tD32qM{R!-utD?v8B;BR8=}_w!vzEUFFy^27cvBg!OKCid z;$&0bXAP`lWhccSc;d}KEKKRbfK5O4Xs}JM_YFvcY#+{o{RJ*STB?A3y7*4k`wNJe z3iLldr0!3>boRyM?xTJ+4%Xf_I+B7{{O$JeHB}kbaZ~!aJp4&FmxG_439KTzwDU9XXP>mIdljlrA^4MQ?LWXq*$iFZy_+?rKGa`(2700! z^|lCIubsD-whLW9Sf}d+k8ArBH@EXWKy`m@M1&Z)rF-hGZI69+{BUW1EymJuXg3Qx zJAT;6ZK~J$_}#@@&qUu_BAs|TKA;mDbUIOgC+43~^x+knK3smmO{U}ro`yc$#}=~2 zy}u-Vm?QMz5S>0WHAcN#f8>Gl*M*6*ym9RjbfMVuipApv!Y@U$E1Oh2*?e>tO*-@N zL81qe6-V2+o>S$AxKs0GTX1aTAl()rF7gZ4N6>A_v31+~ZLxLRQ`bk2e|)@E@c(HI z=jX47_kImMy!9Mo-4R0%4;QxnYhtXof8-79(b)LeG~IuXB)=YQ3zuKcHm*Al{~CJm z3b7A-=~vs|xx4M$YtkQ4KUZUDO=12>Kqg2L!oh5wOE&<#CYnS zba)kvgW~v30laR}#qrJ3#qsSPh~t~ZyiMq6WZr3f7-lyD0V-=DmVsH`>@8-o}hJzApYltNvc4B;U}b`;U4< z#eIsyr&5FNXGha*ueV~&H(0FG=*&0k>#x(U|1u;#$XD3&sBEM?hVXsJNb8dS6KP!n z8+^u5KKB<+1@@0k5#nEK^1fmX4bxQ$2y;O9(z0! z_eG9H6$x%Xc|RO(vG!!P_3-_}-}Z2O`xOz>Y=ZDdntSTp`}EK655y;=voE{2k@2MpmkMHpdxJAEjJ+@JU?X0L}zTB_Dc6QVF|DE2Q-bP8Da2G(Lle+i0h$@QX$w?D_g zCWYF?Z+OD(;@3R^ySO>TwtmeMZd zPmmAu&pg3=&fkNW8}U7eye@yO9`}Fm^$+;!?GZY>vh&=$v2y>pV|Tv#R-g>M>0=Up z^PzVpSuT@%&iJzjWLavsEW64R`%Z;9M`!!ljPfCevC&r=!S>6EZTns5iEaCRjyBPD z#|}sMor(uUZ2gIy;eM;p@bT9(!T4CD!$+yW$H>m}-~S7Wy+-?g%=vWa{@*aHRj!nn zx~KR2z@7fMpgld5IZ$rI8VKv4IjM8@zLSMD4ESM5B5S--8nzbe(Cu`GzkX@CYGWSy zlGU_pYo4|TzuNxamoZ{i#f7gqHJW(+%W%4%^<3Z{S=4h(z}fX>|Z%X9vvKPiNncg|iSdw?S_8xl^y>l+!WZz`SUG7h1uhUwz>fwZ&%xU!AYtE%> zve-n=L^ic`3Y%I2{0sw~ZgSX`uU5+?spTwG);#Rewc`^eYUSHdzV%8rbp`5>?5}!w z@IYBBl}{di>Dt*z6RSm?8uB3(_1aOdbq1SSeu(_dGSzo2i^co$%@g_CmQ2d5{*E`b zrp}O2U9P_69X=_N_E$8Uy%%-YldsOi{;>UR@=|&?Uy8@jTH0?=RhT82!;*ofGI!^Zm;Kp0z#1 zZ2B#H=Q8Mb9K8?gTrh}!i#^E{`klakTj{rWv&uxj2MPP1ew+AjgJ_3-`;Xwa*ca`k z-)SQL#}Tq`C0AY?*D0!B;So-M(qLZZ*16OV<9WfBj!jMUCXpQ*co}wKwesWcWrKu zf5+n0JoYe+lgi~C9WOfsj~_nWmA#OBSYYd~{4)!B1N7^_WW25WE5YR3CEZbBvihp% zFiBd_9Tg_>%;+$A>XviEWX#pw12B2;PoXdw>7Dw#wT3Y^xIfVz2B)x?v2i+|8O+aG z5U=`nYJ30012-IjeRZiw8!ztvA&vGjqMid>5jY319ntOC4+`wrUvVVDo-yqEUw4q* zFUcF}8*9qW&$)gbEABhaKY8x+k>=#!dA*6c=W{0F=ng&;8FYldL2Y3A~0 z`_=b7LSv0+`@Elg!S8oP#ogop?i#;1e?0&F3+@wfK4(LJ{vt9>?D!)3InFk$`^JWx z#n9c9oRG8^kNay!>ee=Su+N4@Im;O<;NAyXOAB2Wkq_A!easjpzkG&hlF3OP+B0MF z-cDUU;6LpoUpLMAoYQXc=X`I?{<*(aZ)dI$YuI0&I5#cl8N$!{HoX%^u?VJCiM#I$ z)w}QME_1Ry?0!4>LI=Y%aygC0$kvN=5B|C@`2PJ-I>Q|igGNVi8oj$Km`1Pqg71S4 z292-C=d^n7?zkF)+yB|`tu1rdd^U;)Ia}v^@Zlbfv=JdRa8E~Ie~fVY>}efNG2TbJ{k7JRIxQzS9lQg4$A#`)U~Wn$$NQ}I zV7yxe-iLifywe*NW{YVG-3uUJqdGH>Sx)cGb9_3&@R<>U_lCIhs}n6xN)Yss6`&6( zo|P2Es53xQS&?b#_0P%2$sQ8J0c|}oGfE7H$aw?(6h-c5)8|}{Rf)4p?cLDtu74U75qoFB_06}wU{nP1*b@6U*K3V`1N(T-L=uh(C4_nFih$i?MN*_(2-anO6g4yOUUXm-&% z-uHjV=NU++HIK!0n@Cq<RJ6I-L+93)IQi2Ua|?ZUsIWJ2@&Vnvl%B-NG_N+;&ujA8dU{vL zlFPOwed^yP;oAc{H0WI+qr~48DyDaZ;*_=tl5%u{K{+G$@hcL}oG`9}@J$=b?)aS@=wU ztqE(-Ef1SE?n(^I<9^KJ3XFmBC=Q_q>yvbhpWZ=TVK7zKJ#5~X*~}Wd_DHW0U9AF5 z?Py_*6o>SF=!I^yaS!y?cj*1CEdGwhS?KVgiA?S>=D5lqw|T#B92)VQe0s<^`5YrZ zCudL7Ir#(65P7*A((z<$ZV%Qwp=qSsei24OZ&Xdx^t>jjNc>f@U)6M zJVRmUUoOsWr!Hn4Ll*P1Tgk}JZdoNiyJd&@*{z4(qw4h!>}f%!Y;O`U>TY2*pOIfS z##RLypf|}fK?A=B{!be-)iG`|q_=eeaX~wG~GmI9Q>Ri4%e2%L&Iw zZxHe@Q<78}NHTFi4jLpCr$2`r^b$^CuYZ^BNMv(4I4srXy8^PQm;4DJzg8M^R5_R} z~8c7CDk+Rp4|E$^UTwv-mZ!9-*AKJgJ_t$;|Ik?Gqfhq^7od=EPAUT*V zmduxsR3Eo+stYjzk)1uHARtynCnrjRRDt^e8e3Moc++gHOsRp zWZRiXq-2Dq8G4d4Xy5yyNhulgcg1JWd5k%iY)3=2$;5mL?ZML?r({<5VXfa&}@5pR3a;xLG>VCi^|LYSWSNH zsJ99B$5x~*Ks}0U2AX$i?d`@qFD}3H{wD#;b<(QW+C%FmLlCc9P@x4TW4PR^jwifW3~(jpP+mp=48(0=U3Jj97@u5yHY4w_JSX)-LRFb z-`lr$UB$c4D7)U->z1t57a{%SzwX=Xu6Xa6HSTxzu0>hv3kJoqT~b2lm+$kJB){TN zQnuNZ3FYP9_od|O_uhMN@B0<+KhrK*)jq0s?b~aDEMAAayQGwAs{6!W-&6bC=iayX zeJOSCsD5h4fOaH>;8oYCCUXme1EdNJ~BgJaZ-k!MSfQ7=ZG zEh9#~7cz-oL!#$7W8|@+G3o{9scTW#oFRAH`Ci2=)=??W zzuQoLF7#ljB(+nT{=B>28d!f?49*3uy0W_=(+ef(WrG#E59=-~b3Q#6_QulDdpFE5 zvyRq@Yd2gT&wgjHuoBuEAziiNHoMY=HptGQw?(rIbO*@fBA?|t=*yACSko9;$!GXq z-vj#swy(uHq}sgdosCxL>u*Ee`;F%I!|Bg%Xil%*kO%!sbJ;_COeov%aKlEw(bT>$ zft55^vQ!&e+o%2TGgd?UI%RQe$4vB3^|pHbCG;*c?TH&GwiwE-N?^W2CsS*vy?4+C zwP`^cg=*iX_U8088(PxWZupsj`I^=JFFMZ(huI%LqjwRFt{v!?#WVE{X{`?$$6wJ0 z-8H`NHc7cZpDEGcp8Ki)qyso+EM9h$<;Zz}nQJ$_LgYg&w~xXg^T((YBLaojXj{_SP=G zF?f$R{RW#d@*$?&1DlFrY}D5Mm~$@vr{6&HvMYf$_@3=>(S}z3%U3m9o9~~{8ut|F z0(33s{GQ%E;PESIAGI~n=2P!zkD<1;nEo7A%{SSVCgjgx8SQJ-HH~utjQ;J1>C6*j zf{nQ&Pn>1$6@6YuV?`R_<)_}{noIE^Td(Xfrj#3KEWv$58siI-&enbtW4tJ2j9bJQ zN9)FT4aR3a=NJuYJQHo5avE~s4D4goC+Tx`_Z;#&C0|pcw*4uo| ze*gZwrfKp$b9!otPV2EwX)xG+?)g3YdDCJ^9{y`P{UjI^n(i|td}?yyhYmtdPp ze#9n;4SvVKrtVE(Q?X{7+CEmA%20nb`8dGlpVVlr@g#B|D>YsR)^#U-Wvywdte@6g zxocWWdgZ-=OY?p-nd0rWBa@p0_ryRUH#HXOO&3tjT`;kZ67X&^g5rIjI0em%80w0yk9SI+) z0v~0G0v`u~kFAh1fKQo*kFCJROHuH#82GqDnz~tskNx{Y@PWBktN7RreCz=}{sw&P zn)W&HLwRKhl6%o$=ky<@Fn6VjmpOpz)k^&aP`8~99Ov^xVrW$ z;;Kx;6=clqgezk(u5t-iB2K+WybYnpQ+W~dEgsC=L%t%e%2q!zEfSuh;Ak6gv<*1g z770ficMafZKX9~OkE6RoaI~piha=2+Ukk@kyoMuVTx0(-!chuvl&W}CJhHoka8Si(>f;5zMiozO8(SP1 zUq<89_C(`UrzyZ&z7Ilp%V?ChZzSGo0B^km-r5V^`Wtxbt!ZTmaTwd*k^c5HPpQqf zsK_~e@nD0y1$;;RSC&9?;5wv&s#PUZm$Pku2cG#k$j6g2X5B_pKI`` z!sl^(9>eF+Y0+^W-gZ=+17?Kt5ixMy`KAu%m`i?pFkc=x!f{^pr4|d?*w|m1gfS!o z=P3&Ji88sKd&pe#ot5Sq4{V_9*Nc5;gm0bS&y;TPWL_>inO8qa_8gYfJ;6Z@sWmO? z?@Sl@+dVimrKUcWU8dfXKwEPFZ$Oa0(AGd3s|-qaYDgQ4L2Dsxly@c9G^Ox1eu_3e zKpPZeh@XA34v*iYc>ET{lf5aY)wpIun{n+1lW)~Q&r6Al=Owe!R?2*yJxp#wo6S4A z)OnYoo&9L1AWo{*#zXtvboYkaY1yvaPgzYp>;&z9ty|br`0uHdsM>*cQ?M0{pM${i^@%_}^r#pHBMU1G~31 z+val`oYR}C?d}TDVcV59ANfK$*Glf@N{8EXHS*^grc&LC)x_6tPkYv3nEKpo!_+ld z%(wOm=Bt{G@}O;s0d@NN>p(l#D*dJN70{AqQ*Rpu++LVVa{F?5aoG&e?`3ieaM7IL zTyPiUl7-W6%yK`h*X=U{?k`=}ug0#T|Ky{p`P^uCvGse;if6G!?#5@r`>?OC=j~C<_okcdzC6g5y!{r{e{gez_BsKp=BrWetbaT8Pj>cA zpRk%}bMfR;{IB}yCdf-gy)O*9-szm~xkvI{CfR(%YYxesDD|V7}J?$c3)E>cmnx9LS9p1{q!cIb9!ccpbz4q)5!PVA^Far zeGm1wSOPD>Rzdn|b^S2Xbw~m3@38w?OYJ^O?&bwWOA7wjw6lJC>pga#X%Le=s84;h zrgJzpqpkt?bQ)k|+`-4;5qV3SIGzgy?3V!cgd^v1f5{f$lHjl19U*!>^*^j;RSbF} zm=l~Azar!r_|FJ9#S#C-O_Uece@lL(>=M`(R+axA(d!bxu;#~I0bPP|kGrc&^?^Di zc#ysaiF<}xou@DA4XV>y)T`blqW=lvJ8qynlfMtT(r8;fvjDwcb&C5-X=QE_eEQKB zfxx4E9)WRQs|MAEn;N>E3IRTL9Di zy}@+`M=bCd3;k<+W$?`Hc3~YEoIZT6lI$kX9g6JR?-$_Q;|i{L2aQrfcT1v zGmfHCs0xS*SNbzL%#3VGZ!m(=iiko>S<0p$A_^!;3);mEfwrNx`F)>z&Q0!3ZquSL zpZEQvpSHOt=brN{-}5}rdCqehlE!*c%+N*jXDPFY&r(0#RsAIMeiEX@o^%&XKtEII zd^_4S_NIQaSU;IoaTfK{U)9f5V>No+vRm8Ft>~v7ZO#v(ezN&^tfB|M2bWvL!TX`t zLs)-qqUF%B8ojPXe}m9RpESR2y4Ebns2<rj=c zi{m78@sz2XV{kz?ar$Qs_UiGYJ<_dm1K=_M`$=>Ae&~s(}urgxQ=uEu|TKy4XB@ zp-*1Cqj6%Cr(t}Q$8}_0hWpsOjLH-9GOEkNJ+5`nX1F&zn^C#(*^HXe9X;ML7|$%U z!x-EclaSv{OvRYW7GbSjQ-Sf0^|;nPn^8T9wV~(B;L{VG+yln4SOMte*OktWKF}3+ z+E~?RiHn=gRu}%Td@PupMX}>k=)+ka;I zc;=+a*MpBodxY^e;o!8Vb1JOiz}=@=j^c>0#*N-F;j({`cMNiqZ4fDUjoMitGt*kE z6_UD+$@V5Y;jj|NAUvj6hIdYw5QPdf> zv{AUaxVP2Z2hywe2FpN~_{(@3dhBIaJ8ojZJupWti! z1YhGPVV_0J6MBiyl=c+Ko~1Rwv_&0@5yYr(R5Zf>_pE8~%L&GJ?kJ|9Qn0C?VrB-NEb1Wo{{BaT;8h!AQmPXr7X=#)gK%=)fje4I{)~^qwUuGJB zDMnz62^bRwdWFNcupI0oP_CB2K|0?VcG8zw!ofas82$RrVf34JMdL=-b2iC4HA;f7 zEV?n5^LbeB%8g(F%Ka5=Jy{N%ECN1S4OrjMrg0`{^BmT< zyfCo|KO63bO|#hMUze8her`oSz?M4#`uUmir)f>0doQi9rJl=@TxPSgGMi`}AvWP> z*iQ7hi}jgmLZ5qip9`YowJ95Y*3ZHmX4_=@hx(S#caepi?>h|JEs57mq#UIZy5|6E z%?h5Qw4CQCz5OMxfuR{sHgF@-S($_J6qv;Z{3PwgT6u ziWMf%vj*R}%kFY62-~+0wlxow4OO*387yR7|oKfyws~#eFrjZTcO_XZ- zM}QXwXC*M&RWKj;z97ANE%3ZxVLJJ0ZuGxvA@F=6z6bidy64N^r)Mj_(#qXG;XB-c zIk{)R&+QM~h!-?#YJbd!bcb-EkC)+s`n>-9ZNLWD{?+j|xqszdl~{l29b55^5$OLg zKkK?%b@y}4Mt`nON1{38_8jE5!q7U+^>XTr3e8*PX`;jPg`cMv+JEgAy#IpM`*)+w zQ9&pnI;!b+?2FL!8wC0RvtTFP01O)jEXxL_WdYmBR@zwk9;~cYeMkI1ZK(Upk4(ncHT5)-}qMKdx_T)UxXSky16r zL3SARZG5`L?n;6l48S|#2UBiksQx#VQC$kOkFv>QQ^r~QeY2g$C;Oy2@7KrzY}vcN zSFM|v`_lVW{wC=8^%snXcUCI4Mfkzy0>RTVvm@lJ6XY!(a+d&}CQ7t!Qf!ZG=B7NO zn1r?SJa{{Tubm^6wX%iYUgV+hWUVRntBh4TVNM$~Zyygwy>wyq0uTRT% zGWzFZehVE3fY+5HiH@E%LwXmOsbj|TaS#hifmxd+)aKE&B0Lg5ImnGt#~OUu(IFWr`&x3nz1=8UPa(uDQF zl7@H^@c)_x z_4Ztn(TR}Jt013w&?7wS2tA^hXJ1a+g&0epb6($^i1z=+9O!Nljl81Iy6N?HgKYKZvizo7@tMpAn`d_cU%G-n-N2{rkmDXcIi~NC4109!zv@n0 zhQIA7Rj&#YCzG7nA;YlU2C8Lv8JFQZqQ#Y%U;HjDhTKRpj5dv{m<(5^g^RaPUu#sh z-&(nkC8=)>l4B&sfIj|6F$uIexq;cAY8k2mJ!kTNhiBZ&1XAo;_7uaO)RZQCA-AuG?L%fweoxU5uG(J!jFAVls4IE&Y5#Fox>K| zoY}CG+<1?>cYa1C>>BbttCkARnlwRD>xxC^T_(MEsc<%@l&0}g7Zvf`FZvPd zTa{5!hih;}rC5 z$ya25-vImjM%n((G;{lVezvo+cc~l;VS3dG_IJ2McSO@&^sa*EV1Lg~uU;&8=FvVp z#Z$nWZ=b8T=NIftCrnXdDfDdHQD%p#vD2?pNwQAe@;T)EG3`1rl0KWNmHlD(Y#NvS zX*%n~@~yOf-2oYx2wAutGI1MZV*+G#JY+S3<^IekyPur}nX4Md?{&t|M`sLaZH!^g zR+XKjiYpz3-qQSO9Xk@ZPC#e2xV`oym8{=AEkH*g3(tP9(hp&xG`ll^yEYWWIJ4>dNl`*FubgR{%Y2c z4O~}vjQq~+TKp#&J%=`xn@L7Z+%HUYG~(~62Y~x&H%m3M816^)5vjS@!%G**yDBA3kOQ_eb}&d4@g9v4105cj|z#g!^@nk4lr#>83bSZ}l3G z=$PNed#kn(-V?Tio^dwksrXDM&B-<2;;deVeiuhLPc1b&&uu?%*TZu4I0I#J`FHF- zBPLtn;`>trWD;`V(&Y4ni!FzltUZ20k+m?$S`6M5i+9FB);joPtr7N7Yw~7^RpiYA zc{9rLHjw0P49S~OD{teq@|GMRZ&cgi9NJV)qVrh>pS+DYNEkQ_7fs@0ToY5Wc z)%_Lxiw6FM$@u3gcs9K{2X-|ukbDg{^zH3u>g_@l?aP6uz(@KXJ$r_1qKTnpszV#R zeP9d8)UBY~7|`z)@akspisgT}C+gu?qNC}v(0xuspA|GmU=-O0HI(NHdsrSjY~mU| zezJ#80qX?C9wxf+`Q7}b+Ah!^U!W{q@ABF^`sBtaUIAH(QQ=llAzebm%$!3i~q)4s~gB3Hfv?8Nh@1dmTP5eILTHMoe|6A_OL~K zp87Ip`q%8JOx6eA>q`vi<4?5iqs__qOxVL=I`(jwxcMOA;&`cMmERst)y2hlhKtFx zhaB##8~|LTSb;gxSvd*(OEP%8-3^}F&1Cb2!6vqdjn9xx9LBIQIn(1BgLbRf^H0hC zh|3IV6W;@wb9=Sxunl1Pl;T)Yw zcn0i>H#@)Wj(No0=sY!~G=s3-)gKs&G0}O-x}}711}EA4ru4RH#i=mwz*XWGz zPkQ51>B);95w5}(N-NE%0;X2O=XK4Gc2>@W4FtTcS_*msZ;3{(`BBd5DjJ8?d8YKd zDxP6&bw4mrKc24fs%&J7c=uleZDfo1tU6B%GCQ{}&_*_k|M`sRNY}3w{0#^GcEGzk zVho)ymU!q%g2rb&&to5YdQuUm=n0E`96IceeGCkaefad`u5DTwzdIoIL9vd~!~R%@ z+())eqbH-c1?w8cA5M|xYiW6U z=F)BH+4`}E0~C9(1;ie*mKNYU+Sr3l6?;g64%&2L4?iFA#~xbKzo&KP^>`ceI{YE6 zEfXLQ;~^L0ARl8Po3{eL!-Me~B>8pN+^gJT%y4>5WC+gD2dD9K|S z-q!)|?TGhxf;`4+<*}-Dd9*08xNn(VaMj`V*#zAJWN9e32^uFU@@N!$9A>^>kk7~E z(HhW4Uy?_(IXOeIE41?1w_Wx{tk%Amsj@F%_c ztz4Y>R7Wnt{cev*QZL>uKQ5W=7?rCM~=$o01qmF%d#F! z)!H0?JfgNa#zSt#L4L+Uj&6nAj={RGBe%fSl&@8>2=s5hPZf&*eN91fZ4~=!5n*5gW!Y?v(9jX51KwvLeLPJTNVeqgJ1Zj55*viJkpxlerNk3kI7i$QRi zHkE1Ru^*2?RL)R*e`e=qeya8L%M>{b^7Ui&eSOHJ(dX-%#P1-JLP15kER!l())6GaplcTcjwJZugoh*ug(i=tjfzzcP}!* zUV>gjZmKBnpUcfXt;o$_k{jB?0Dp5=3KGx78m#8=j)S3joZ5!m)DO?p^!H91{l%ca z6Gq`-m-+Q>Kcj7KgfJL#GPqrGg1LU57c3Wv0dg^b%f;KrRCzGjB#T!0oM=4c;8DoI z0xky&xg0DoHEtB1fgDgxlWajOuWq)JY|HtOl$%R=+)1D@&s%Zx9GFF)gSRG@`?7$~ zeL+C(%O@WY9Y;zn*|g`Q&2gc8n45YEKlM!!);})@OJ2A-+tWAmGI7-DULx($)8}=- z#=et#h@(K~>ftO0pl*O!qCBjc{wAp!_>xLz5%Vt-DYs@}F`Ik13R~-sY0se49AtF5 z_n0bvwO8=8=)|uQL9_QjvkFeL-OB!~g0qtnKrBq1(t72H_ z|E0P0c2^E?tXvzvntoWj4pea7R_OWvANb=`EfoLROXrAK{AU=CQ)OCh&TPto;V~-r zA{L`MX)-#ic#JC4JFfqreKDzs(%_g>;FtpOclEdax>_#KB%bS;e{Vlryqn9*7e`fl zz@TG`&i-!$w>ewOo2rOa@}_{fu*a9uS_7N0rXT=sb7XlrpzIIy*sA482H`E*G*0FF z1E2@V%4gp~{$|+x`L{E*auxTKR=~j)BStdEmOxy&5Qi|*nx62{1m&-g2|Ohd}@k6@70G*;6KTqKTppn zZactaE#v5=@wXcew(f7sa>Dm%^S89^Z=XCE>~E`OcIK7~^SApR5AAP%@ky{>dgznT ze7$PZ1^e6Ue~rIABwyd(?)+KX{`N|pdHuVMd3oNyFn{~2$-(}1__tbr+wg6$zkNBE z$Jf48Y)#6owL%6XeKy74bn=&~!?;aBbp`VT@lKMJI3_E$Fk!;kcwl*Vk^_S;pZ0q2 z-wiv1aB z*BZ+384S0pudIdy;X^8 zSQ|GkC%vzVk*ZgjL=W(f>|~;Uu0@z|2D(rW3|=nBn8U==2iU%<%%4bM!Z~2u$)$`J z>Ww$nhMTr?97*ckzx|d~V^gY|)YB8;N%Xd$3;Y zO|LB2mtF<`;3WJ5S46n8^3SxE?8dW-^r}v7$5@)So7jx zgC=qt6f%JKSHBZiNPDlzGeBM`~+FPI!WrjYhNe%;(ezi%Y7ewN1OM3 z2J)2Plb?!BBsW!rnbQ#0V(egP|H)OFgF4A{y+ii++(m4+| zq(79lSCLhWmr#0S*R(SE7=Ie7To$4uS~U$k*9p*&jNhx2fohw^VO%f`CH zaZgh6(z?Mfn-AH`Hh7wc8(`B$iXUL@s2-gOpDa>q^Nh)4_6m<_WPhl&R~{yt2W`$z z%=Dzphpd)IifgE^NvgfL9J!D6ip}%qfIcRX&4V^gQ>l+E*y&N?E7ZpfRUb1mJu8mG z_Hy-+b23u{`nZ8|aM0$L$Ec5Nj3Y|);O9%MZPl|g{kHxbJ|7p$<%vT-lpCQrYqtyQ z;!@D1AVT~$J6e^`(~alzbeHpazA^Q1c+h72SLA#CMXEW*e9wMZ!zQ!bo+Vn}vm5h0 zml}NjrtE9Zk8xH$hIcM9c)W`Zp4u~%OB^A(@$Mgy7zZ7S5s^@pP&iuOS%rBvh`8|aBx#r*CtQ=IDQMD9f1#MmCPR`0@ z`5EqlVa}@f4$jKOnNGKd62*6FNF2@H6P@oc#p$L@LMfrul#`BqpOjVCeWk_{gqoqcR`#S7i`4ekDY+OJS5Z8ke%r{ zHx&Kw^Ut&|xLfc1Gx}&4YVe#JV({m0P~L_)!CARBKcnUhFuDQnnS|&3UC%xVxoHA_ znt;)-qkT4emV2Q6F~VC)=qyMFT|1oOYsM?`$Ng|Tu27C8XVMvC_E`-+JC_qWHaLjn zhsH|hl6&WmJC5(r|MzWD=S}FpJ5Y9Z?NP-7G4~Gl1jGWtyT5QbIefUSbCexrd1+MT z4K-y2=L?TWfS){{$xIWMnU{d;fwCfF)3;iCCFz4;TjLzscz(?E2xPBd4zsDRGb&r7 zf%n1ppd&sAwl(U}=De5sfV~3RHR5MWCFIwX<;OR3mPT&RZeq5EMQv+D&CRIpZj|Nr zR6z$-yvLtA{0p9S{EEqOBjmUNay*yIu{)v_IYyt2kmH8dDd~c9YgkF-L2EEyVvXum9v}Rc)6J5y<d1Y6d`9DG z$kXN>bdn#S*+EM1g;rkAkgrE8)%Jdz_)ulw zIk;Hy#l8G4V&!g@f{267YiS+t4B8}tMqQvYU44Ef#grb`S;H47F^#Ea$fZ%-j#QT>H`~zuraX zJZ3ZB=v0Bp7oTE2XcFYMi(|wW@IzrgoGCYmYTIqy9`IZ~Hhv}T34M++ocIL) z(@p;8Ae%?=H&4RXJVm}HjRUqO<y`rQFKPQ==HyVSgv*2V~} z&pEsuKBr0LbLOf2Lb5Mn;TLvbexWTzq_M1X#>x6lzH*yBXM6iz&ia1U$^BV9U)hkV z?K>~r-}kyu<4%?Pp6k^5vmJLcIalW(*M6q84K}+~J}l-^seTSQ+~B6#P6qMN9wz6v ze5S33_Bq-&^1EE>@moG;vW(6U>Yp?5#r4r=tLLveC~^I0`D}<`A3GaTlV;Mc8MAE6 zKjmx2^Y82Ao1#tQY$dL55`Wkmd`3j>V>`q8#{>G1^G(s_h>4|!~tzZv3FOp37&YoTKvH!eCYw`DOy93W^BsxCY9jvdJVSZfgx}izF zpN+;Yp8-h|B-ebwsmANKboyPR)2|w@O&e&h6aHjWX$Fm7*~fKkRNKSaGbt@}CS@7z zaYpFc#CKPyazR0>qmzQqf*9S}IADt_a4*0lcIWc_%AvM#yq?DgU(=IaE0lzi*N@{VQNo0C9LGyJj%V#v#TR3Q3H88@Z)OI@50m8hAz}9^ z@aBiFf!{N<`%5vl6t4~#7iY=f6e-o0>4k9z-tFnzr>MfeHWcpwnd z>GSsBE~{C_u<^RLG?*UH_vOE?Z=t8$ciLMTOxN~3xu>@8c3?UiH|sn4EiI=1YnLiV z591u|QsFoHe&moA-?Lp>e82yY7T<@s7`{*1&E)^{Pqp}d&mk?o>z*UXj&0XDf)R;a zH|z$FXBqr~s%Y_f*bddN!yi}`t;P0LnHp@5->Ajqk%aAN)3}zOCCG~rAEUn3sr-Qr zybtaV7z6qkK-i8pCpTw$s?zxufNORX|fNMG5$tp*5J~N?2f~nH*~$h>6#zQ zVt{k#oGp(7&X2@rna)$oVw}Sgf!~Xx@R=1qw>VGQF~>O+gS*KopPik5v$Jw2eK!p4 zMzOQA^G7>JJ#O>3F^|f{Soi2$!u%1=S`+9%F{0jVeR0hn>7?2vYTW9iGq)I>xv8;f zI_4(Rmi&U${Bf~g!Y{!8eM(e*b9QXI&l|W-sMZ+pEAuab=Wk-f=_gcr1-ZWOMBv%N zXmMTz)3N4*ATD`j!UE+4qRqtK6E*-DD^t#j`gf7+YZCjWA zzAISX9^MsNm-es!zoAP*b>?=R&fL_x^vZgzE)DsD>C$b*zfPB80(9xYJA-xUm9MqB z^zzriy0mT=)1`g~mA%|>=6B>IU>u3irOs{cz(@c))zZN@8u3$--f+qB74i?tfn(w{4ChI60)~$2R&d% z=Wsi^Jp96KtpZh^>Ug!y5(AqBJ{s&6W)G!_G>#Jzw};weYgMW84_*(^cP{I@Leknp zckEE_*&0Rj*XljnF!2uuwf2tpEA^hOQM^+99K7nv<*M+2;s;PY?Q8y*Mtzy;4Vg+4G%_`kWGX3G zrn1|Rsn^#*rf9!qytY2qt?!cD+>ANj1i2Y4fd)ajMd0fa@b3Wlx?UqQ{jJ2;1C&?f z<7=`Y&!=ucq(n8EDF3;-zlHdEAhi^H#kSHk;F=_U6)L@hIDYdxlt8I1D@wM?Mj6$jM*q98u-+5@t;{@m zR4X&zAJ@uELV(PiIGgdROb`vkj^0G%T(vH zZ+^SUevQD-XQz_=m+8DQF-tz5ooRrLHySove1x-VbZLg$6z+6Kjc|UGWOi2d#^-cC zdy&a`(tM+{atJ%CT~#1BPf`s>yD{i|_QyKo+pRM`wa#AgHb0*oH;kXbj&{oTuq=+j zXIZjMD#zuxEqbQ-*PY9bJgz;L-Ee#Gx$NZQ+H=|6j|ZR2zLx98hL4rng54Wif^;MD zU|X>`ixP|bwu4-IbtbKci&c4|OKqNpWlC%~Oq@#3UsvUcLOvVU@>pD6xR|q()o_t< zH(HoL^-I5@x-6#FV{w}y>r}%;&BMEihieFv!!(#Ykv_KvWAfNG`0I3nzg6Kr8-3hi zs?8rRb}FVEQEi>=7UG}z22H)d>ZPHuSzy>47`MW^>IT40^LCMH)+R~SYr8W1v|S<6 zyYE@U<87<-`o8?v^}U?+J$wzv{S7*O8?My$offG&V`T_2?knZK|F}jS{}RNfj;Z2p z80XAm>KxNZ@s*F&z6xaMm^L2wlKMGhFo$YhgYR>;^ZcLv>N|zP#d#kG?5F%jTjJdv zp=}Arj`rIU%Z}^Y5>mOoEwQRRv@PL%OW&5LS@&PGC6-?)ulMi1c?oO@p|{-kvNyH1 z#G%7lTjJ9%)u>#*5jt_D2yxv$vM278Y7Vt!PjqGW1l<`jKSGYJP|U<-#yUuKnE4$fwRMy~79rmy za`&SYPl{mn1l=bx73~hO=eLt>G%>V2QMnDeFdcO>eC0WHDTz~BQ z)O9y#?=QIShH`J4ho3$FLg#!+b&PU8g`GX8^*hA5^CimtAxGD1WuI)yqFB5W?HXp# z9Y3~BXTb}>APltNdzQX2a@~2QrtKblKNa6G{gQh~eNLThl3n|P>l&=Rz`6!KRdo&C zd!*i;qH{i7+{tr}rt0ThUcN2#d6_5H(%CP6&59PeW(D2l79O&$fu)Up?_H~(i@CMj zUn`?hCs%0IepSvT=AAV`CsznOp8lowy!!lYOs0&AOtmvFqP4opMG7v@u(JH0au$oM z$qtYysy9M+W0m%h@3{H&ZLLh*LYVB^W6qTKm}&i1_L!A>4P;E_a#eYNXY3k}|!spF|-@S)PbSI>e zKe2+zr+fx{R7c7|2$Pf=o0Nwx<2Kz@vRLrc4pHi`g^9}^qWhu*hSzp&9hh2LduD{r zm-u@b+b7q=|I31FE~l#ezx|FT`_(*Og4PsohGM=ZV5>X!o>V`XVsL-YBjuWBPXG-nR4U&#Ch1_3*o*1IOTO& z=iCF%eqUZ1+9!NMVrSaVjv0%&-HJJm!TNs-d_Yz^riSdG`0{jP{I+yMd|A3FzBK5Z zyTs4A3-JZ)oO?Dq=WdLjhwscy_s+3MHACU2%@EKgKb>got}=*oA0pk@l}>wNuHKLh zsxN|Pcai-zD70==Zw;Q8+vD}kYnViKjsBc8HV4MhcU+(yYY@k(WdgjK$z`H;w`$KJ zkLVU7#S8kiaHfSfZuB04?Nq>O+`Rp@xiEKIe{ox~up~9pt~i!{5HUqG$|JpmBG>6Skf1in>{9 z$s=7e1=9rI9Z;&evyk>%$Fh529lKTgzq9>&ztk>8XytyaDA3_ZNBOK&J$|15nrvfM zKff01)C7Ld$R1vcW^F(%8h;)Ac>Oy1c6A;7FtKhX#iY4S^18N$!j6FYrlIZy*-+Hv z+s|#DJwa0Ta@Do+32y^y<%jC?KSittzK@sfsDXd(Z~8UxUoKbUXz(}#ZR^}as`>%w zcLsRszpo@roI18%6FYl%E0g)(?^fa*AK@MR&Y1%9L6ZA(c@bhg`qHfhWd`5JhfAzJ zN4(?oS1S3>9V$}&B{!bE{!i$@0Dj(0t`W5>y=>mL^lkIX<@3{YhTpv?!by4bRR!VB zYP^%^@Xu4f*sFh}*qY6`GPX2h72QGFTaf)Ax_{kWFfY9lK2%jfe!5X!7m^({@I_J} zZ*(tvYr1wd=TT*RX~s#pjw;5_;}<94+s|~Kw`2bDeK7TOAI$7>U4Oav=U&bId-rg9 zep%7Vxv+vOeCNU%fK{!X4eO)SpPpoqV_~$e&^pvJ3vxf2>O~o~=fcKt|H8)n*N@&3 z3T*;EUlX3`w5HlTCacX^w9mdzJ^>f8wm_%I{^0q`w7%2=_ldV&yxTSJnRNHOXYsw~(rXrl zdAy6mJk=Y31E0{jUpAKKAB5fv--fXc^SG3AJ$SY~pjKw6Ghy$pX#%gW&^_}N>U*o# zuywVy?`qG#_7WG|8dxjJD1N$y$;-_Z7r!>2rL^@JiEM}PJxlSe_SNQ_wMko>Pm=Gu zyg0S_9(z!~Hs82yZP(`e`lHbH&vk1qtTx}CHu}4AjlVWu)Rqgc%@=WNaBaRn9M;A< zZsKyWYnQ67MiqQ7RZR`ruh6>-jP~f{S~?R=64}YmksXz$+M|PAUkUq^uvyuUcoCnn)rS8bLcL4t9+k5-DOXA+ROLZ^Z0+wc(&I>YmZ>Bx4UWI zqg)UZQnmXS4}TP@J`eo=H)UIB31Nfms{kLo-Z0rVpqheYAINv_VSc+`1_l7f$(PgQ zPn3}jbdS_B@ouTPN~g94=*GV4(oY2YzX{RL0_tm@jEQZ4miQzksrhE>IirTVWbs4 zV4yxuR-Gx&f~?R!Q-%5rG~ZL8{Wv%JsFe3P5*;I{W*F_wS%uT7cz-B8|J|D$-?PoF z?)SA{(gR1*~AW+l=i1?skcYcdM*Uqg^cf%9SA%_X%N%7+-%&b#NX+zqD0K0Gh`-7QtlG0M_WA% zp|g|TiLhHKU-g)|kYYC1FSq(J!Ug-PoZTt7g)pK#b8t-om!B(yhux5$Q2KrN4aFy& zh%wy`yu3}q7-jt|?NpZT?p>Nu8NVxCrf+7?WCGuzqv;x$W^Cc)`GGdI1` zWOI58;E%2{4z7XTm%fa)XUfvIyifJv;#Iy=b z+L)F%TB@P5YD;-ci^uu*%}~Yp`PpxJwgz_Azk~L>Oycu5`?1@s#%av|js1afcZ0Zp zGn20oihN~LzDgwK8U?wE_F=bfEj79a7PbM=sn1d1Hf)H=|5V}ja)Vec*LV@c4R(r8 z-yl)Uv8F)q$r;`IS){V!fhBCEO64w1>(3xcR(hj37Qobcq99(zG`GLOT;$JRo^XxFWMo&F{@BgPzSd%tZs>PZ^>%dUZXm^$%5)V_b1~@<$$_e$Rb(HV0 z9wDET&U8||zh)J9A+G~g;AWV-mM6|o#q)<#?JweCnE2C{_T&E7tNi!iHP61?clTWi zFrY6mpc-op?I+T@QiF9xIK4Q%#?J7E-gVsdi;O=OgHTNMsOox;lE{wile%|lzvdB# zYD`i6$aktSCHJc}B|C(Z!c3Pb%t?6>qudostzZ3P1KIBsV+b|Q;#I1%)7fF7avti) zo55$NHS-8qFUEeXS}$lX?WTIo`G+q*VDd1*ClAJhEkmepOY3oE6UEg8iN1FY$w9Ut z-UT_J*xJfu;is&8*tPiV8@r6fZN`=#r@5Nq`{jHNMLYPh71DQemjpt|U!zs?Y zEuH+W+z8ki{GM*wC!4&P?UBi~R47hJ{u5+!dME!LYKpaQv|JT<*pGNu4miOWQf0RU@Q%<7K|G!F*>rmGXh=%`fh5v7n=w5PnGMz2&Ba$!n zw|~VIlB|+V8q~L;ueNWKs_(QAecSrVecyw=X)n}0RPgji-!srB{K}t3qJPVZzG7eW z{T=?Vtulx&pkKN#eFXZhLBG^z?N!mzcWD->CXM&&V*QTz7vrZw&u12@Vi@S_-E#GL zFN3&YyZZdQL3C)I!+zebiiv}MD|s$hLb(e6fPJ(lcH#p%3&G_DK0V2f%T$(5wvlX; z(%KFCw7ZJm?)M=RVYD`6I&1n9zej}TH^({3Q&RXryis_~@=zmWp0N75O8sV|q`p6* zmU3SEhjX6vlkbo4EQ>27+fEtV)oR+IpFBSI!`oE*%(LiBrGK9pHl^$%uy~x&aTdQ{ z`#`l{Lh=1U93Q#eANQtENO_zKxNU8)vN*z7_zdpRd@Thobf0S}Y?ugJCPFxEAe_Cb zG@~APat`aJ>{pXNAqXY3UtW*TD8}ZcJ3BPB)Ds-fg62m|La~gmJl4kiaEo+qQlzBp zJCZL~lTA9#d~1rm+yxwUrQththaHWJ``*U_>Xs^dxh=GpJB#)$8CEIpQ)sNR~@A5AWKRf;gepXM{=jYVl$j`cs7oVSF1NhlHfS)g~ zXZ-xWOu;4tuqjLus8+pAI5>^lG}D!RZX@inF-94?GN4-`OSxC$Q+&3G;Yj(f80P~E+aBkJR>pZ#8{_>(%FB5tw?hYPSr=)OD1bDB|nM9xvEkZnc!EZ4~7dBbM1mB+(w z8mE818^$_iugdmEUyDboeLNW;zJ*vhH}*ZH@1feh3BO#h5edWG@4>H6W|-#c&OST-UML$m-f{j_vbp~P zn%@c9-yyY3gVC&#IPJywi46~Fu8w^4~(WdjG{x4K8?XVg+`aXjXT_1>erVMtcCf6Jmv8 z3qGsCc`rk5kOkUpn1u>d@lzq^`!w-WL;fqyUGAQZdJT&7G+riSyHEYohM zwPu*qGBMkSg~~e!lcMmBZ$a0BDF)WRi;oTcpE=I@Pigj+sK3)9#TFi=?_|kiT9O*w zNB+({e5c!&d`wOF4s7B+MqyC$W&ijYbDKbZ3+??b02U-040S8em$I&(D5$s3jl?sf z%_D(^{lWy%Iz9E;=OZDzhinqfYp9S=x6r`81BMk7?P4)c7wm>q-cP}EjAv$ioCk^JrHnmEFJANe%MhDQKl+R8nK!5lshlZplt+ew3m0%*{W)1ZTz2C)B? z963vv&0{eO#ngTv?Kc6pw*tSeF$x2xMF0yUgyLu^ON#1f^GpZM{r)nW$C@b|bY==- zOh>_!oCse6^LPNi_t9EligL_|5InSw1;vA#`Q9$Z6}Gg=UJX3{4nD{t^fM}4I2hSg z@bsB%5Nkm9&doWNgl4N{H@k{!T+D2ZyLvU_^srNwM6;prO=1wI(;&u(XK53c|eB0|GQ|k`Q?j8BMCIg zQqgGr1=6VT9!8_5|CiC|k&8&9T+qZb-A|*b7f7QwIgPIVUq++*{&VqYlmwcrSJCM5 z3#3tBPNVNW3cj!Y5#*TIP0zkJKB^KOyTz7tL!h^ z?1Gu-&HX6YfSWNE+TSl&$=esR_T*Dt8Pj0T57)L|hxT-*Y=P0h+8_6~?}qk5n6~{Y zw5OaeZsRUV4eKtqCmT1G`ZsFZ+tHqUh=Ogr{U2HTEK~kCBlQn?Dd=hBb7Rjc@hpCl zJl10BOQxj}>kDKIbRL}CRe0ET&O1S_fp2)~-S|B6(Y1801)poN2G&7tD4tP+HL7lH zm{hkmLNfCl@sX5cOtG=61UWz7J5-=^Ri2sw6)>sTRZB(=4wc zYeVomtGg3F`Cg)l$F33VsvW{lRh-?{Glo>&6Sx)#df}<)9PgxVKEq z#JB`LF6N_@frp3Rq;YGXQ=fU1YowCLn-AC9OUb|C-?g=PC&=v}i)uNv?y9%v|Ke{a zH1l?lLACsOch=i&P5ySJO}rgsPc3)n&`vn-Z;}_eYZ4Bs&7>rR?GTBfs9h0yy>xFiFXS zorTXP<0ACH zhl~3sUpib|yN=;vem%p*%zB24zr1tdxVV2wXk1LYPm7E1+{=HJNs8qi(g|4`1aua~ejQRY?dWiqd}@%8)XE^JMt_>TNsB`=*O1@nII63+XT zvaGCE%SukC_VfOhOUV1*wZi+Seg*GuX@mEx@741D&z$%3Hn($4Yy~fadF5XduW84c z*x`*}jHN#Fz-Kj&KRgh;CK6xeHBrUe+^xPf@uFkrv8Ne!Zc$<9=TEneow*8j=EunT zV^HbOQ;RRY{=`BCQWX7p^)lbOPWrRGYcQS~mvB5)bZYx$J{x3sQm{_dFZSzHAf6tz zhSsTEk6))A&%JayHSukxQ?7GNr&gR}I#sm(!gcEL#i4cTlRT|X-JQpD%K5=X&?yc7 z{5o~nwzhR@$m$R}rQ-35oxwUKw_B;TN3wQZI-QEp(J4a+o${?ouFIHCh5L1?=%tIV zQ-c?`u2VmD3D&9KFK%6@9_bvcQ>lSErNYvyliIISt8*@$PR(=b>(rrj7p_yQUka^L z=cj0OYQYqyQ(tVlbUHPntZkk8>#FwY)V>`dbV|kBnPrzwr~dR*uulE%sdng8{^hbx zr5gM?b?C*5uT%HFq_Xo?U#^MMd}0ZXecbU9k9|zxI#R*DLua$gEj;$2*!V8?jP~hY z9oK$4@3VU@o&LQ0mcE^5`W5=~*^8m|r(b~nyw79bmW!c38eaMJ=i7FyNw2JIMSsXg zR`K(*ZLR1J`N%5XesJW{>CfaRgZ1aGC)*!e2uZ^ylYLmBrr|5?py3UnX!vTfFW&S0 zo)9!F^}m1mC8S{o9U4YG*$xa!NR}}uQx#`;_l1j(LD|rw&J2SNXnB(0c-!1yr@RM_ zHwVG0;2wG3}k8W`TVIo^Ehyl}jE|Ao+a6FXUp zH~-4z@&Apj#uN_7d_KOawS4Z$`TWSn-@L8_@XC*gU+-)i6NMGJ zn0P?OIu$>!FVn@u19{-Dnzy|^zjTtSc5R4V8E`jl&9h)_`UUAcrzd zUr6z-l|<7$tB+pAUVLmTqHjXd~#gl=>1tREx#>4l$yt@U;n=r~!n zwfgv;(K~*C?JM9JY;|ML5Ok9VR;npQ0CC7(Ok;*jvLWt1h1s9R1?3_Q0oH!1F9W;57X`ir^CiJ?#MB_y@C(J0Uftw1PlIU|lgd_B`I^?dE*xK)o)5;Ci-m(n zCGMY|;r{6vhJ*dz(ix`;({ggOnD#y2yUuv8ee$s2`QIiFL#@JTwM;-iC(s=Ulp}QC zoO-(r>ksk1!pLRiY>Fl(erIB6p1GR*Jp0$A3+LHOmyl=w!+BQ9eWJO1?b@<7G|zs% zN6WK(&a(q0?OTTe_x~tetf-f1ABaOF3whu*)l`{F-{U?LeXn*q z)|M7;NiA@Qcs4Dpb?kFp0QSl6Iqvt3$cLi+-UB`iOmzJ2@!);G-j6d}{H7ILy!Rz_ zJx~9c9G@=8=V+h{_`PFctnco*RGQC3wJxx8CGwd`ex^hMjp$5uPv}D5t}Mq^sl!UL zvK!;++c#ExUJyF;e|*|MMp>g4*$l~_)7f1*XH7hjvFyoIF|Q(3bY-*ko3QM3mj*fC zcll7V-{k$DC8_xtavRzscrT1Uzg{TGpC`y?wKvzY9AN>Uk#0?UA-i$f0HN50Im!D+ z2YSojeHB=`)WG}(-}|ra>3jb$(Ep(F{vrDBe?@u!b$C9H+n%}pK3-Cu561IKL7WCT zwp=CSzdR15pYZSo`$K_axhu^-7Whza^Rd_l>5pX=f0ykV)mSK=#rwFSBY%E18w>M? z*mH`by&cb=4^-L8+u0bh@cr8?4ff#}qb}cG_492zehTj*wp*B?2LqO%(5 zT)VvHEoWnr*Rx1YzpKFCO2*%8g}+xR-@T!6TCZUKz79<7-r9JDo*Fru$j6)eJN@zY z;N#8h@0YVwK916UemU!t5PO49_YLrBuSu!#`ed&G(uXloc zHV6IFnMtZ)aPEgQb~@*{9KLxa)_oc$)jr{{JkSrvm<6FF~W@exCKv>i9jJ zXSNu9o~3ab*rNS9-lvA?`0^;fj?48on2s+|bo}bhoPLq8^ZpDT#R#XD$I-ek6e~Vi z{z`-R*>$mn3$ADDDb?!o4u@SeCtRvAMM!SBcDlv!&daQ>xLotr9PX?(MN3pGkG{Vh z-=~_=>`Y!oI-W~Zdr+=bB-aTsh+#8gWxL8dCsOiGLjP0Q8P&7+G2$8hE#P6m|`+f-0rxY`NGwC+!o#pTR5B9!e8D& zHfFF*QX9{0TiCU9E{NH-klnS>0k$n@lq1M@8+d2Ju7wQAwT)&mn!WcXY+KmYw)bJ% zCfhuQ_nB>Lmh|5%*U*_yb^c(7Y8x(c)y- zYz>RF^#-~;AQbxUa-w=0kArUboNB%I?I9G>nY1X?8O!do1$jR*g6oH3cPHGXvb%|w zlbGH8^Si4075ok`UAy}aZQ0!hX*bnHpBrrRDf&s{(X;oe;|0&%o9pFs8?OFL9^`u6 z6L0d}&85-tfOYE@{#_evbEgW!eeVmfQ|Nt}{5#8mC4>oN^Q&=T<%j$^>~QiIRJO_i zwXITjfVIm#?=6{jxy|!eqk+{S{=G2aUSI{?xj^UGo<*Na-xLZTH0X>kz%HTjbyddK zpg+DRl=0Q$y`AvhmF&E0YOmn;{tfR*2dux8v-%iWPTgu<5t=@8)GA$a(zc2TMihnBq#`O_@{xyGINqcF2|0Z)2fBqGJ zPVr)uf72JVTdLThJsDk;zE|*f=O5!^o2MPyYs&MZ-je%aKTXrMpG>fwjQ9zI{S+>Z zj1!9c#HsBkLA+YApW?awG(c-VeJ$HhS*_SlCb>R^To>uPGj`Z9#biTi?5B_G?Kaq) zRCA*mcy}lIQ{oDp|Hk493tPNNdi2j#=zmDdZ@M2Qkl&NQ?<>*wGoa-&>3@_zzYm|U z!RNAk9^_a`_LMmo8@?{9m+yB8{JvfJ{wJ#MhX;TE$$j@F zI_P}=G3EPvm9^joWi8Nr|E3B?D`5|4#qB{MQfm+9!k)YJ+StNrK6}tAc_)%RXofv# zk=&!1J^1@2WDjOL<+>tf1MI;t*&d|t+pZ;hFjAu0VXlHbum@QkYPohU#!TnZ^QS5H zpi%O6NB_MAxt7Hl{5(C4>_I_%62E8Z+Jh`_Y~aRvDgzCc}=5I&|w=rQ^ngBsOuf&8AWNjQ0TMGz>_V1 zr+d(hvhDUkSCu^mdOQEY?6H^Dw=WL5JW^|q5x(;Mxb?I*=fhf)A8VC;Ipe0b_vO0% zGk9Ol=R290yc6&5_&|4GZoQn-pvtTI`-j12UCMlCC;WL`hc^bFbtzNM#B68tA>7`) z#dp@_qVMw^oW(G)NEK_{H>>sBhroS>N1nO3`%H3Nsq|XSo>2FQ279ha@lP`wm0C)f zWK%5};N#J}&TLbIdl+{=qqnc!zCDUztJoez?pd}+k$RT-asTg)(0dfS@6hg1OuU2X z=9+cw+$*=XZ=W}quknr}`}K8`ty``0*#SMwZBf=YeLg=#`wGz2X`Ihgb6(b;@YeMw zC9M7WqwJlK%+IBFtM*QoL0@w{-jb8hANiSTzvETHhDLA6SE~JvpB`a4__j(1>mFe` zc%1EbECK!=P~&f(1*#gsQ>{{?s!lM)D>lBA+1N$q7t>jicdt=6U1NT|Te4X=O?SQb zO5r&2I)4dm)n>F*_t}iS2LI03*gspdY4+qsh@ht zt}G8Wmdj9ucaco&xv{}s3O(Nl9&F@$g}(fM=tdIT7Y>l4L`Qr$bQ*e3`!Y%$WA%5> z6tKMIKsh3u_*p|fb31f@VL@!GeYY0_ zvRCpP8@{*f{+VGw;p*1Mt;T|#6SY_{VIsqV)o&|UU^v(^(?yApb3f{y^18wxpiB5~0_DW{FI6YY`$0$R(2n}Ao+L;v@Vg6Sp)2NL z0sbhTPxi7iI6j%nWAbw@PVhVmyFWKvD0vlq|AWaLTaWQ>z4b`iS1;#1OjG2|Aj_Mt zzE8xfOjd*CE#5I3_K3i9yF#tyDW*_ZbR%eg19&hDyvUYXW@Z7G461cKNxnz#=)?8) zYG8=u!<8h*VSMHez?uUOGpsqOpXha80`|{&wroj_PMAzAUZvfjYTkFLde`zrWg=-S98;ReD}&ccZS| zFr^gp!P-6Tr5k0tA=UI-?FKDflr{g%Lu}1o4xI~SODurBkaEsjaze+Jcowv`o%NP{ zq0;5A9tv$YbbGFS`9e?5{f+rT;o5bd@+{7_vhGuE0M)bzwC@9D=J|No2jPDEzBQT2 zN4xwm|9+O9%tV+}K1B$b`JZ@|Ptl6Z^o-^{1(z8i!tYaD{`Y!0|5j~ZX!37WH7)KL zcj@wP)0cDG;Ad_d@R}AcuDoz8956R@{%!GXT3pJyjo1Hr>$m0K%Df5i$rV5U;rH71 z^HW~Y_w!}{onl+O-}j1j{e1Z4Mlp3-FW))eH#S|m{9C%`G%)}6o0+Zq<;#^b2|aqr z>-1z*uKJ7l7ynGc<&c3tFdJvRmM000g|rrju`>xW&s4Onxgof|Ow?R<#wu4}b;G`0 z0eP_s#YLEtWqL1B&Le>AS`D_xEmqs$LhwN{3Xc~>3WEbQK4gpN0`2;b#wm& zt!_@5z;tu%T4iq(a)q%r=9pn)S|A@*Y5L30eA;*9yFZ_i@8}fj7WUfxv!yxv(8!lh z{(P3(@?DBlDzvD(f_j=y0((qHsvLJYpA2mGgEigz_JBn)PRjx9K-a&%r>=D>Vt4tEbjhj9> zW3OJ5Db)^w{$43aa(s2nNYG*g?Cs%F%K)l1&FDsf!{PvT6g{=^H{$>W!x(t*4EKn^$^?VR%*-FCkdX0Wc*wy`yt|CYl~cO^}0*I z!!R8lK5>COOl>C*hwJe0u_nTfCgzqp%=0kdthpTBi z3N#ogwPaH*W&d3Z3hgXj(C+k8hsua{W=6Y*motnD{GKwls)w{SBe!;7_*9_Kr2w|W z7=vW(!|KF?cC;qFlLDKoKh|8TW0y13boe_{a=$uLq~isw%cCJbiy|5~_G`|m$T39K z86bNz!UeJaQ_&UsTD({Pj`r%&c3+G6n#jIvZKyR1p2*1t(R!a@@QCId%gE*^%U-I* zEeHe8U@lbWu4ar)>I2!&%@V|+R|uZzD+Q6>(Wg18g4&LB3u2$<*DJcjM-~RwU-#8+ z#vK3kRFj?7B!J(@!_qTgJdnC=hh(kw@Pw6sqsyIC2xO|M!2G zZhJa~rrRy;pj%8EbXzn^OSj3R7~Q^={_oQ5$u{UFw1aM2p9)R4fdO=j zFAMnwX9{fHWDD@NkKnPc7akYr{+nd^?hbKd$H+ogL0LNG2nrVMy&Ey;6TWTnf-Le? z+1(qtz;4T}CTUI<-61thYJvSpcX7}?9M%-0WDo?WukJU-M{`m7eRQTepHC29;&V%A zV{Uc-`E_&44>7mT|8sHYmJu+wTln0*DhfTf;$Jzpks;>x`bC~wM8MoejAnCtvyHhu z^(*JrDa72SUF5la@}PEZZ;fDco2ksLfMTR!u(87ByVX;K(u}?qwug~$8Eh!{y)~FS z-EnXNcqPY1U$iwU_*D!1ssSzb0KW*|TrFPN*N;pE9f2{)25TMcp9#PVapY4`6^npl z{p9$z#qm6F%mu%We7wI={482aiz`5j(g>lL+E>eY-IiM-V+@Uvpl9u98>1;`R0kS; zmuB0v5HySYP?VFk;+Ykn=iqay5uDsh@bq1w zkF96N+yEbS7;w?gCz|Wj2NfBkb6Zi;FEgX1^HXDBSI5Fej00af(0%M;UySPqfq>d$?C9n#eChYofXfl z^4w2UQ2VktVL}wfc0ay92Ww7$(4=28)-ljzx|`a)UZK2WdaO`PeJ$WIk$m`I3$lfS zW{-$n5@PYmAq0`!W$Pqms~j0ax8*VrqtTFr04 z$5|91cxp{i4wC7cB3T_~yyM_VjKPYvv>Iz_AFQQAn(7*mcxc({xC z)qg$!9zG8`FKmvf*pG4d1CGpqtuX^MnSpjUK}KExz2_LBWf>U_nnjmE<{{rvseRfckVYVRVVI7zS9uQ66!EcIN3Rl41 zu;RC2=;uV^1rd-@Bg09GP36ujNY9-&4?lD9lb_CN=-&!?9|O6+1@eD0^x!6`dG=@t zdcpS9DW-+*Q+x^7IGDc2zEAxWq|-gjKjQt=m&=?9`mwvVsNH0=n}T-J>P?bdpF3cT zp~gjX?1wqh9>enE-UDIhO*(=$>@KN`i3PLbfCcb%HCT`p{=X9ohKIlc z%pq?6e+dgZ>SIB7(2{a9N$2jQ)5BQe-8`Nb+DkCV}X2+Ddf2G@b+QB2o)C0`GWu*eI{KW6UIaC$3gzb zLJw|*K8yh-+~T{FOpOWDj~*^i--HdcXF&I6RxZwRo&?TP|I}_W+D$>bJhZzP-+c=G z#D>6#P~#;U9KKN~{InIUXnMMJtT_9$K33Rn)MCX)H!`g7zQNiz&;9^(F@Qcs(8&aP zF zE2zDpW7}AvyhDm(SW%?HiXy^_$3kEQ#$WNc7Aw|rtauApQN*#r39Q%}0xMpKY8xvm z67{j7Lo8uMj70a8#p3S|q0cJ_E9gub##dQj5})}9Sn(Lc3d#%lg=2+K5atvLOu!5J z@#6-a4a=RM?VPfBm{XW^ z+(SD0JoIuQeiqR=`Qp|BpbaRHhN=DHuNbAdX)*h*;%B<8p4b^|4Z$h>=4+6IlT6d|Bjtg-HOlSjwYWcLUO^kIT5Y0 zbB5C1F6^8tgIKT`*p;p0^9+#NI9(=#Q?YYKrrA8%QOwSvJ!0C&q3^9w**Vkxi+0X+ zI(AMGw{vp2opbMv?Xz?GXnda5Y#jeR_2;LKfiBzv%(>ZjUwvDCk7D2ap!hyy<0QfN z8DIk~2}jg64>GCdGvGfm+9hD>3iS7(T3DDW8?`WC-w2+#$j4~ zh~>6T#VRExLVl3oX_?spwCM;Mbpoy8fe#5%BHiB564ulcjEQJl6h*#6@!4 zs%G|~fxrqDOGh1M$a!!K0_ef{%<^A7C*u$d*Pfz(iId%uN-t#<@ zFoDJ`89Oh!j?PUQEz7Qj9zISnF4$Qcria5e$b!vZ3Y$OEnIBP=l7^>OU}?Ej$8{D@5F zGqE=3h~wU$8YX5+^E#DgR6!SoxuqFiV`7~<3id?2!AW^SG*`;UpuN-1m@l=b{Ztw^ z?T;Gqd-*uavf+-n!uKKs(QE8nNAFrF=PD;H+8xn((beFA0Y4?-La~w4opROx{2Du7 zml7cqKNf5A*s*TYS;O;k-d&Qz5^h=41>Z|Hbz4jM#~xER$MS80xVS@H;qq=akHMNh zj{4h-d0vjbmKzP?bp?ilM@M_@=Sy2Ia z%C%=O_p>pOU(B<2B-=ZY`!aQ1)Mc*W;2o5|gSMULQto1BMEV`~ zii)SL6?8ut{lC>{sap;{Re(Mt!i3@?{FH(ITaAXgp5ej-D`dsd)4FV5q|Gy$aJcO0 zpHt9Y!L(eX;G8~%;@Vl@Nv70d&Tb?g#FB3Jj9q34$J%B{T=YHGt`~RPHq@As`~6Qp zc9-)Ex-U@YyF`c6EnYi~si?_Y;=`mzdjYTd%Xy%2v)SC~^DNJsU4G-uw)69@eIYnMZ-sKc?vK5Fb!}gMGdMp_ZnsT)566NxFI|3~>94{0c`f&; z^7BkA2j}bnwP@qVeZuc-e&Day93BKbGb8y) zpv$8y7T6;cBh4^Yz2#Yj&#Tv5UlpF4pv=^WbLl~`x4Qw?jy&wBJ^b?6+PN^NmKUOG zj}B6Ny?_=XZ^1DZ0WE9lLVo^-F+Q~moud@@Rcg^DfoCm9HS`qNs4z8}J0 z#z=l2jWNKhVH{oq=@Xs=gjsMM;+HDB#v`4b!klih62CmVRkIuZ{{!G-GVSU{l!2IcpfcX=@5$4ea!7%SBavGR!d=rFXOS);E^UB9X^^ zU_V)fFvRsmT8^;s0N+0Ru)TH*$Qv!`ptr;N?lzQ;a^TtuKl2SmC#(LA>k9R;U2R=k zU~cF$8);oJM#&9pxEj|I)|co11Q@j8TE=v+mcs8WQ>^95S$VbXb8~A0>nZMi4_(jD zdfFN2XJdnX5T2Y)YuZm+Q;hQxv0d6e3f)67Vh@=+sq2!jgE@DwZ=4dXLb#p){7**z zTi7$dq*F}SiCIy#d!+r+-%b1Fa0mOPL8bkY{KHBercQvVvtyVZ+9Y5KYuf;DRN*^$ zZ|vWM@B|pm$_>O%b-Xu%>k!;jmJt)YH%Imk` zC74H|Nq2F$=L3EUnltu%bSb=^Mw>1l8w~%$(+K|e3izK(yrivtu3D?zdFy{5_5iJc zDQpeW`iHN9S*$@5)HlHU-I-}m7QT>J*QR|bplu;#9_Usu|8D_)nBR;0enbDU&^Ou&ue(3?N%YzO7r-*v70q@P zMIT5_L%-4Fx-$~YEl^(t8Y#oP3&0%a&jNSi&UMtDiy7Az3GR{V66{TE%FPPTM;|ZX zpQ2JOtJc)^Dj3)C%A)9i{H?9eB{9MJuHvEfij((?yjR9bd!-MolWO15(Hb=g`inW` zvO#_`r>N_cXyv8D(i)w+Wk>#;P`LpKNU{y++18aizT%Q6zoMQL+;5Wi+HR}H{g|+xT zE6!4x5o3QTGj{hV5z`cO#(WdnA7O6jZ;ZCaG|+RuFr=+J2l$P=+1jc5(5GT?O|1RQ zy_KoyDazs^v(B6M(T}|5Vk;k78oW9by zxL=CW`F&WIwXv{t3=vcyQqRYY)Es{6hynf@e#%y*75RqxO!vn%0EpYFl4^{`uC&vT9oIDBjn)y``b` z<=lqW$NDw24lb`aXnxhvHsJ8#)?;fAx4zuc()!Bt|85;z^L*>8&%f82ttRd(R1@|s zRO9!pSCjU=3h%O2YhAG#2l(Gg;rc0G?HT0)9Bo4Tqrf-B(QX{y&VO!* zxYu&dzZ2K!6N7mj@^W)0rL&R@f41%%W|+U{dkqHd-|%%X8{0;lGIp(NIrhy+;N63Z zLGQxfhrj-2BVsD9`Ez>m&7t_k(Hp zPzHSE8$;UBUa(H@i8U+r)0*7^?+Ree6x6?ssUM_2q#S?X6nv|uuGn^5B)wl1EZ{kzTr zJkJ4a&j8+|{R{U8@PI^r4CXvC)}Bs-|F5ab8y70){HH9nXHQvc&s`SB?U5+=;eN3j z&Fe50q8Z?L3ij%b=Ye0`Hr93uaPL$M#SAobQii`{Og(za*rV=Q;4y8}$J)-!wfm5^ z;vPB)_U$ zY*s@(JJ7F@4<&M%jqh*`Ghj~XQ4|xLt)#BII$C+v1?%KBUV1bO{+BOY0Jzb0;U1pP zJ-r`}<;+}R*MU8a&+p)wd8{%6;nQ-P(RK#rdl=qjt7%88jA`pI4y#|Za^Prj@ksA* zW%2du+Rf>YD#sBo(jQii7s1@@=-1oNUW;pv>$)BG*>>1d@59>Q{=~hA`w#cp(IJl7 zeX4cecG$0rV4p66y*Uu};RkB$zWq?P0ru+#*rVHF-GA8OX#2Yww{IZq*MYD%w*zi$ zm-ga6V1MFsHmv>oKl^tEjR9~8@dw9{0Qk2ZaO@c1)ONrlZ48S5Hx~i^4Fr7K59K(9 z4S=&7055+iv)i=(a17f4_q2Xr0vy!(wfyAYi9DzYZIY_`0l@ocGukaN9tQB{OOWYW zK)yZ={O)$1zg?{>hX1G1=o_TtjU2~P>M&mKB>euP-&~0_AL)HVrowQ2wK%{g=nK~h z&rq8$D;*W&Qv~#Xb(FH}>vn&dqV680T7VCCDIL{#8T8d3?XN1k=TKV}%FB-av6U^x zyg*Djj)Pfse$sR~^%L5D6X=GBKaJ^B2l!^K%Tzjw)4j`x?tSsNQiFFB`sOjeN?u|u2h;Nergo|5l<1G8{j>DkL89CzWcD9`0kfag~!|T+-N)( zhPe*&60AOCuYIOnseK0KGe$`{nr%coImib<&(SXYB8(O9{OKj^OTFe%n;wd>vQ?)m zA30rDa9O4a^wy;tC{F^$6o-MVyDn8t!w&GdhF&GEtb^8hazZ4x`@eY(X#V9j? zuC7}TGWdGc%-c!;{QJq6Q1>#l@gubHBed}&wgLR+Cw2GdNu76p{#g9A>yixSicX+A zCAD{Yaxk=UW!apzbc`(n+!~tctu@DE3{;moJl{!Il8?F!&ul(11?{9xF3bJ|G$zTA zSdj>ApkG`k!|u-qL)$EV>bk+u_TctJXt&e43}{z1DF?1pk}9yB43Iru!ThUY4tW2< zdNm0MSVQ7-8Grxj#{Tgk)LcPtZ8GEveRXr(i87I0(hJKwZ6!&>fw|4NkdQYq-fx9lFk+=Clim%?9Sbz7ASa4jp2 ze4Ejx+ZdzN5^PeA0`AS=_ZkRztv1b*OQmxIsE0bzy7{Cd{32`FVe}dF z}b z9F8^_jt?m8m1_x(ul_;yJy3k@lFxzWYoH`i{4mn42N9;pLgpO4d(=szft?y_WFW)% zc9%VL&8d5UK0j;Z=Laj7pQaq)K<}FF6msc8qR)3jJLrR8?xpa$cRP%g=x5dfd;Rc2 zJc9+D$cXxfk=x`BL;H`MjFxQ;Mi%QN{&xIH$;R15@rCBHDl;oPYtxli@a%ds z%r|@MK-Ol!yR)VW>D7QetF!4`2+~ZaUV8ApMQ7^ z)+t8hJ3t+2tld_wC`kni?-^;fSk@_O`k}`0px<5s`t2jiVzeO*MtKMH3A`Tw`1Vl) z@SLGomS%q={?f!stuET&Fb^%-9~6h)2FUd@{0V?#AcvpA^ZHDCtyv{s2h69XMhjem zH86n8wvH*4s!^kBX>||7?~i@{U7Ej870FcndVTxpUfJd2X*#Z(?%E zri5hvZd4Yh723Py@NQ^ALh=%L@4G7@c?10a5B%pi4>;aMLH?rFz3fe_L>a&X_)w!z zEYJeX2MhfoP9K5)nB!ss@0aAxqkmLuTl|LFqklBQ|ESu-gB0I;kN9~E`_W~ImF<8R z8XjmeWU}ZFdG)Q(=WazAL9yvw0`gDOBZjWoqpap!I_a{Z*yFw_ZzE z9=p4FI5XRo1ANZkqE6MN4$pvIg85;4y`iq+_wT~@+xeV!Vv_OyXSvoe zm{0p3!Tf0f^9>gPb8`fkJ}6*rjPU;1N5WzL_M?f(7$=80w-tb^*@C$n%yqeda~<`4 zcvZ)3pIA?Qe;46>mk#%-Uf`$sy) ztG@wWnS0x7d5(AZ-DI@X)k7KAwT;Hwj41m{ndaT2wgNxtRXT_@^8JcAF-VSkeFe;~ z2cBzd`$PBjF^f1)gf*U1rT%-x#{l@9DT<#arU z*L-h~Z=(Or8;_E1B>Ur_jFigHM^ftUgf^k=4tA-8{}Aa6^qYxq6!Hgl9X zQxNB8I8N+m3-p2Qs!_zlu^eTq&7!=0*4wqXR@(f~&j8~yaqKD3)-Z97x2s4wUMc(x z%F)lD6Zv+m7Jde$!q4ErN6F6sVUVTjXL@@AFc9;fRbR85&mZOv&wSsYzSbYlX;9u% zc3RDpLn)T~FNz#W{ngr|{f)snl)P%KzYEz-G5-kqi5-qne23E%ylcZ}UfWjH-XHU> zoPS*{F`ysaZ+VihYoo#rH7f_^q=c_4*26QiNb5TG0_$1;Z9?0}G0#otx;`z|b(&aL zZGDnOu2g(y0{x8NtAyuM=uZZE!s;AYUueH{1g%5nqm)C2mn(YtB~V`4tg<71f0ec# zY7)tExDLsWk{(!Erm_hx-G>hA{;7!c!v3K+C(g<>oHJ^;CFp<#UyRkhy~PCbpdrGM~4IWW7hG68sF>7{$FMq3ydx z`!$Qtq+we)m(cT2Z9X4vp!sNZw0$kt*{ju2!gD@oeSN)%`dZ=er(I}VvzCf+DI%@~ z%JKK6*-CQII70UObJ95Sq5RLYgMYV&{C3SgVm{eezwJc8>M~iK9sf0Ni;q++3wpa-s8G^L>Jz-Lq?_G7rDbS5t*4W!V zHKeR-F=o|u2l+Jz=!DbK44Hlmj_x_ll--{+)_S{u>sU7v2YfebyXX`SDr<%>#MFf&_&3I2i9( z7`GGjK1VIiiC~}GcKQ*7eeioM7x^LUlw`sOwHx7s;ZnQrhetGcgwt=lOQZzzEx>*l z(Mvh-M1px8@~vkKDMt@wDhJS)6LFy&<{gTkP3;sjl6>cxsuL3L!o3xV#_xM1oW^5c z{4Pb&*FU=fozDcmnW+T%7xO$P?S9TzKCKG(D-M%24&O(zMybjUm8l0F=^jDWfO?U} z`*a86m3h*=&?dBfe3#@4t?{G`m1ycqRXR(FG_2@t*NIbtxF!}=UAK3$C0)T&WIQ)AG_)n_RX^}R* zE$5+)y&fUDr_n~FKbOEbG}?7OxQr9Dn(Gw((N1crMHv$NT`lH_{g|PT;?5+eErdPq zNxgVEO_tG6X505rTUBvS(N=e8EA!XOeCsOOs<4#$^ernPA=|k%y^V7aA;-`NQFrVdZOVjZ9 zl~u8orB3)$lwsH|;wO~pcq+>~!e>g8O*{flVS6G@%r7Z;emAWbd%~>miCOFQJ<%a7 zdkR=)>aZ+CI1M>JEFGeb2BT33OOf|kgXKyYmPtA+hnxqNhvpJ23pPozNrv5qdVjeD z!@Q>wlN)*|ADJhitO>G<&)%8=wB^Z|#LC9@n5+1iaHe9@>gPN~HWRd&?_CrdkTW&f zCd1vjK3K*#?pnA# z6wiun%kaAb;8&V({&o0f9o5m+;fr+=%%gPO=U?lB`3Bd6fHyq{yjs?Srp+Zi=8DBi{C6$QW@wG@15! zco(YYZ&^p{^y$5AY3HLQPs|szgydWs$Wz12Q98WwEX`x3`%W-M4A1R&?3g$wz-K%s z*s8^lSqP^}*Xeu9v&Ipy(O)8P_;*i)#}V;;3~=;7J3j+mO;ME(xF0LXKOmnR7`^di zz>oEO@=v?qzj*FEXI=O?wCszT4Q)c($15fIM~l6DzVsx|w|d7D!FZ|Bn?}5IPolG9 zVJ+RAX&n$2ST-8VdWy2{RAz&+lD_;tl%1Y|Fkg_7ET+1D5p_WtmiVt^&%22pkzmWr!Q6Ds&v-_}rE7`8bsG-(uhXfc3O}2IUO^H;dSB z*#Ns_*k@VM7A{}@Uu;&NR9w7l`S*%&m~|u<)#F?f#9XcVT;G!B8sJ%GT3f6i;Q#PF z?x}M8zM6E$@z-74x6k6Y0Q>ZA!MduejM^!JcFso&Zn+~^uE2hN68D9eQ4Ksu&?JP67QNz;#RVwz@@Cw?`yiDw^E1|3u z`adSy>k@T2A*&*omttF-PFQt(NXK?lMZ2A;-R@W>=uxSlM=4k)_H3!xvq{+h2)i%i ztbZrk5}VGD&z!YF;-S)bqF_9-tn$pww9Y*RT+DHfw)5G&?wLop$M?OE(SBSj=zx%q zj;_Uh(DA z`_pVh-&mmKy&5(jv6fC7qgs!E96Uo_Q;ZKmzp;{Pib2~jqP@xk^JxLPAF$W86Fo!t zXy0yy`SE$5^9Sawz1zH2^MgpPQ_uMMKHK%Uh^14=KFj6*wdbc5AKoSAeCMBQLv2*p z{x6_2rDmAfRcPyl-{>E?%cQV$^hwVAZ1ZlIfAYijws#E5abL_c-G>2PPJ_P|YudWa zAS?9{wEVtjmE*IYRT$cF^3f;4?;nbm&`0-#_z}%Z; zn{3s56k`ao&y9N=`O$FTy%&=Gu3CF>vfqHUA-qSEy%nd8^XzzKG2R6Rd~Pw`Glc%} zd!m&YuFQ!6e-6)l-Jio%L~>f%T0x7~=X2e}4r4q!L!-~RZRvkiY#zM#?mDFs?@Du3 z=j-hiQhRQoXRbVI&$yQ2eLAYg`xW(oxdrus_UJ_D!)rCzLiK}W;ZLhQd)DOFYPSEi zHxVtD%O1Rm@(OrN69Z*lD05{RSbwD1PL+902HS|!elAO5pTBIpuzjn3VYpqyoZ%q& z1KbgxaUJ#~U_9!Q3$tWPnpw(>%BXQ)*t zGm5wKZ)|6Sn16*d{~|H}IW+$TFn{-KyU)AEVB_U81^(HVTdyh#OLbCHcs!% zgzpaAYnf9BH)9ds9X{9B4qZ=$-$;j=tS~MpM>_P$!%F3J9=8It=s`QbL;ZX-Ap2HL z&UHkTOJ7`|$*#_bb)MDgtar8{?fYmt%9IEr9mfV;hwBlHb9=EK$gpyGAE@Waygsn6 zT=iYpLJO?(GAHesB~HFK{_rsB23?t}I*FyL%JRZOrLx%Sr2S!Xg3j&y)%M%jrEOK- zx&)hdTY}BK*FpW(J9xjV9!9x2j`cw~y3EQh!~gYW)(ihTO^o533^74-`e}y1=dv#B zqf`DWdEA#2lAP{=HFU$8YJ0rZuu}!PUVyNFAI9BP{EpJfK|ZU-Jr8TR2i_+I_Gk?I%M4xLFo%8z@c3pr z!Q-px1dmxlpSYFBR)J-}t?Or3RJz4tKj9_+>xJDWn3g)a*PsjtnIoXr7&avqi{;TZC+gc;hLewoy*> zIO*99&r6G_Z3DEO$?+x}zxF6Perf$ZxF%Re4YY5N+BfL!9|8W%%(RH!1@H|+`x6}C=Z7xljJ&=Si45C=l68R zwG*-&JTEOX@V+)-Umz1TbRv03gHr{rVP=88hLZ)2NQ8QYw1z2w!^;p3hAFo4D8XY< zj%}W7^O)$j8*!$7GR@H-_%GJO=d#I?j5}G9aVP8R>5S*&ydB56!$Ir0-J!2%eJt~x zwgP{PW!rr4-)Utj96tbVFt4Tc28Q;zw8Qs({0V%UTB@>BW$J;3&Uhx9N;YAT56jKE zO&Db0om+%%{5N=ybawr9XeSUn%1S)yUk^c4e_tUd=g|0nkK+e<*qf>@$Nf{_iLFGNi96H&Mkp>iJ+XoP zvVNqrpJ2WA57&7tuG^d|rT4IYgRdjn%;_+UWwdziAE;wyV}_ti6T=Yp*WhzCJOjKB z{sMd-;Ohd|B8*S^{8c@qy}JO$!u1qWL16Dj!`|&9?|-PH^`)J+4}dl4(BA=ISG(e5 zl|DZsn>>hk%)d;aZ^8HzLga`v-ezju<$!~Li$VG1v@v{$askMP} zOfZ@1BtE3c1bJ=cFxS3QNw;=Y=jq?&NZ*a1?^O7%1n_G{G@Wmty?$9=@=QQpC$Kt2N$S7AGqTVU%X5g@)$~KIOi4aS6}%-D zaG|p#AHY~vJ_xX>o<#VGcVU;&GsYmfGA(R0>@jzypvygpF5d}j<5?5WTm}=T0hf+f zDpNQ=o2B>pw&)XW7;jRaZuo9sgnGPvQEwKmeO?Dx=VboD27#Ci@Ju&M&%)0&aL%si?#*& zA1IBxAN8M&y0Rsff` z&!RCVL*3MncQ4EehGQ($i4Ups^emybnRHp}_p?YhQUi1lXd}!$!71c2Q*NN{hFLUc zZnx6*%-p}!27I>~r;^PLT+ z>TOAIwAEP2zb))bc;NmRNj6Cc_aW9~lU)x0o`2touSLLDZ0@@?VLB1; zjss_jmK^l?t7QK1@z4IMP`-3C^bg}Wekd%CAf@gD!~y7&$Av<_J0A(R@3>G_nknS{ zX~FiQ@&`Jy7a7=hKa(A2%Okq3r6$?mz%?8+KQ`H1I!>oME`{Zv4WTh z8qY&K_4LeXVl&aiLmlTOJ#Sw!~9zhEDmgf6mC z(nVlBPUb3Hh6?B;(AUqm#s=B%t{EZAPYOGnD`FU>IzvZLOscl7-A@rbCq8mv8}+uE z&xFwM8#pXmR3XF1BkT&fUJ;<{mPA$|(RHHfMs_XG+BuvSDgoQwgz>N^nE9x<+Z`?g zyqqR@#bn|Y-$9u-FV@zd+r)3M)d)RiEApD68zlYY21!4;L9)Sj<>McR}j8qJ*}Y(?KP=v1;})sx1GN9QOfZ>=r^%f)T^g@Z}WOd4AHo7Q(=?`_Pp3E$yin!btlASaC9Jy7R`2;cbt-(rwKt(emu#vBxhG z&4=&45Vro@^%`v$8$?@w45h6Z(*ox>SU1$3=tfzrS~@czWpvsX|*MwzmV?^K7%*ymg8Vahtcj z!QKXRX=jO(_*j`}J3m6(tEIO0LEGMK!iFmBZW@1oW-Q5I+V3aFk_}bcTuG=$JYb)&6NXbt+1azt_#&wejTqqI{*K`tA%~ANwNwc`13%C zKZo$;_<6y6dFHTSU3?Vmv*-|7I%$|V{|~?*JT?b$$sDgt#c{P<3VJ5yhUk^pq2Ak7VE;XoECyd)s3O zlYKy^x&uu1>M;2b_fIC#izYlTGte{UMRH|M&}qONN&lElG{6G;w*=@fC_y{XHk;K2 z^!tGq7lYK?>3zFXqxosvNK=;nBmPdLWUSPA#GqV1`ko*nSKw3%@4_^p6@ z-^08t=o1~o?%+1&iL`Iq{4>zjXEy*0TLlb{(Oee8Ts)>YvaOayG0fu^8f(VwI0JP% z&OG?W+t(Nj&tLqzQ12?2d^>?&aJ?(k-lN5*O)HHYpXMryW`nKJ&wS8zn~iMboo!XA zT&{~|{jFph()K2&S7L8+dL{NIw}p$nS$iw(O-`?*y@~C&z&tFEjB7i540H0B>%In^ zxCGa&n%cyB&pl-V{&=5ok$^uuFD;|?8MM#!aPf`%oc@h^PXA`>S^b*_aZI1XSkC%) zE~qxK3{@Z37tnv`8B5Gir4s!-WZSG^DCznpsqEYkvK4D`CeBf_H6SeU_nLIFFKTv+ zsXu{^3V7fuBOCBjPU?%~0F~{WN`6V6HM*VP!Rcfp@|Y&*{y)>n?)u_!e-+}0#uv4| zVnS?rcVm5Mf7LZ;*Pwlhe8Dh#Lnk$+e zDvCbvq@u^Dl@nbH#5Ok>JC0F%!mA|LWZDCGyA!@Em2v@H3+uX1Bi;<^}URzDvp(t@-9X`V+zU zfwfXxjLRO_d)!xLi#{KWX9&bBnDm&1>0UWzLC-7nqsSS)aBYbE^GMk=v&S=%?!Jv$K$w zDVk3Wp80{EjXJh|PC)uN;w6^jSfgRAm-Dl_2}E0r*wzHe?`wkO_ccNC`?7Mm?Y4P9 zb0!O$L7{FlaJSPMdFo>r=KH`saAXzgoY8FaWPrtvu{`#O-_6o*ysbe6nHA*O$0w8C z>T0$ydl#s;w}9kXr<}}ltbP^AiO)kn%{(ufE+-fuHwX6K$Z5Ji3*uOUjAPY_tZ4}0m<#ac zhhymD63wojtdB+0%QSc*U&ghdaT(Z^!fzH~{A4-ppO=@krDfl(`^aMq8Q1qUn~hPI zd49^HThG z-kCHF2J$*P2M7BdJn$p>ohr<`SGDyhBzRn39zsj(<7^_HpU&Tny5A+q5|Zzz@a5#N z5x$(8ZXsXJawXW86ZzQT34o_Ly6lR0+I1D$Y@&kkUb6N5bwKc(;^jF(oBy03{jOHo zKl+JvhBkYJ&aIL3#0FJg-;VrBxSb(2_}u8&{n!WE80>9mKj(3RH<&9+rCcKazMpKb zjlvgEiviTy`0D;(TeUo|`?w8EVM&9-eL)tBoFYFw9J*Ha!1;papRosNWm&$hLEtd? z*yQVU*bv1Y!dMP~T~Q&Pb&2)pN$aume$3MdGGF}Iw)FR6Z2bWL3IYH6or`VwBj6uD zbE(g>WeNP~g)q#Vt;6t;q@Nrl7(R19(gYJfx2Cq8ZK3VzwhD9I{d0w_qD)~&2Oxfg z`)A?!hZNF%1KcOeG&=yVK2xc`fUO4f{f`Hr4;SG68ndmpJ;WXZ?Qe<%+fbWAy<}6U zmTU@wHXJG<+7PfQ^o(p%z&*J?4#s5)whP3#g6#s=UMbn)VQ*X|WVr;4!o9|Jm(spB}&Qd4-Wz!mq4Sb?Hh1c%!J z4o93m*Y{4HH^Xnfj}`(BKsn;TjYgCqda-+AP=@HqzO(`E9TGO`gJh#lfwtWn$5Ppb zu@wJ=TXSM1$`8U$f2(Atzg4o+A^m z@%^3roZLJ~tov3W>xp&e>s_6}ZZzQjoku#iMc8?S?8V~*>OC~ySlrirSt) zq8EfKkFUf%pKALM$68jz$Ew)?_?VG)Peam(INxg2ORC3ld|I-Sy$2;i9Fy7~Cm)eHkoIZ>}A2(_{71}<7ZFUB@B}nVl zSz50ITCZ4yi)kE{8ECysSk^9R!fB!jDwb7!0cfYBY%qIEw3Q{=TKy~9dRw&h2It@R(Yg=DJ#J$UpTs?W zugx5MXvgQ>?OIPai+6;KJN$PX+czs@*sLyhomotaG&TV=fr}}doWh1h@RbM+~ZeLZe$ni@$PxP2F%xo7v;Z0DTf%8xW2&%;b`yH= zrO?M5=wr6j#~kXzaS7VRsgJSH$JaQvix|(y`)E&lXAZJCpno^uGo5SZQT#9N4QDas z*64=xCW~E#^`_U@>sYSdC;Sfd3FX*l4{UStAWpAb&Vg*p z6|lbw2iabO?@OG6Sg1`o5$dlNF}0;4rq&8&r63>vFcA6Z0QRRsI#=rGd;f~??@zCw z@4tfY-F3M%zHKy@pI2b)&>gxSX}Xj2$m;&==|Z&0^`A!O=Cuy8)qqan zJ|f!rp4w?zfi~sbz}&Iy%N6L02Wt=gdJ_iOyqyQxkdM7E5yvsk=kAXCtPk6db1{qz zo6Fxjn9JY9T^o9BnL~LyKhDMYK+#UI-j2txgycp%YjIx5yoeKpVjtwuK3Ie}VS@dXd1XYNej}cz zY#U`+PZ0~sZ|Mhqdi?*9k?)1{xGvL9ESf_am`^$Jd&mLo2T0atScZ?0;QQj%Ga;w0v zEdsxWA$|h93?pH_`*Zo-fP4?^y+@pl_h)CWf_MAwv3d7iMR-3@;CMg6@yl>dBShH{ zD(i{u)@L&n@qXV`HqSx$e*aZA(36I_Hwj+8k$8C*od3bAZ0^~jd?uC0W4lG7Yz~!~ zv24*evd=j$3)trjxLzlLkK2^v&AAPgkvcVjJ#-Zh2H*lLqU%Lf9`>>Gq44my7qQFxNHY6R?!W%BIvE zoMEoS_yNrZ@|>ufp8|C^g8o}UIqa4?qgdMgmM6JiVx!7VHLC|Ee0xs!OWY8i>q+xV zd{pbdGqm|M<>pN!@TxVPUEGSCTU*K zf3tER%P+0{zVO_yTANAO=I7AXLD5!Ocv~rQTZbaIb?#mwB_liB36P$yXpUFdC&DfW7rp;TFYAZJaJTU$M`{;Y|eH_sG=x6tNL|z6w zH+G4*f%oCP*O_Vy_0{dDOgjhsOMl5;S~i3|_g{ZiZ|R(HSAX(7?mWPdm40-CKV59FACNZ)SlPcdEiyCme?AaKT-IfTvaBm0|P$twPfHp(m6 zUw-rlc&ZcSc93!1AoFVd^_z&ilHTXwdyqBUNA&SzP9&Mb)jXOlfHt)_oGWqcphLJf z>vhv6q762O{X9&mycOSr?&L1h`%1+3phF#n_xE)0K1RI%7T#a0oqfQ#l5t!hZ@Y8! zx@RYl-2FQ67K^IcDaWvnbM-i1nUCK+N?$kR<1WF+hvq1iIf3;Y$zFjuqJP6k93RM> zD1T~weltOryZ;+F7wE^7K9nzmU_Y3h?M-&o&@q2FLDv;hN8?%S}NM_obfX*ls+Z#uu$d^(3}^8#6Tbzm+7*t_F{&-76)L0`Rr(sv%v>)Zx?4Yy68 zIOEXrEl_?nmcI=$cKx_O`DQ48OSD%T=w|@?b8lS-z??6r17xYB13WdJdT{ozNI)g=fPipHKL7sYHxGqm+8SuO+n@t<0`^jl~LXHH(5Bd?0_gtzB=e!aA zKPd1>mam|X;V4V-c&W19?4jNyTWLNK*oL{?KkT!>8A>L5{|A4SO?xl&8}h>&#I6{o z>n;2&AOYanS%+sH!oZNh7WPJYFP#}$a35d7z8|jJSX!*QjiuB|HkR~krE;n?2IYjm zN;?mfY0)G7L|&CQq2IUlezSPLeb}Vl=+kX!Dq4A+a3C~~yROSb0WIVeT zVH82$uN_Lc6Et~07sq6P-yq-r4)zkxv!&TT41KAe&lj>^7tE7tWI3=uG}#toJ(K#0 z_xKxRY}7sY`%Xv~qSz4eI}3kTN3s6n#rq^|FPbGBruMS%H^`I4;&)9Vwja&@pZMOB zpbWoP%#YJDDC2uVp>ZXPakVHkt|Qr!>;&Ult+ivNamD58JWq@JdHL+QDv-~P9}2r? zBBd@0+Mf|p|Jn1@Z$p@Z>^B(x=ZW%hA>aG{1K(#FjvoR!H}w1c8k|hZ@DU;3Estu4 zepTo8$owgnZ zqW4)w`cLa&Vo&u8mTlk3rkGEZZI@%)LKda^Dl0i6@=k%QIIEP-5fNX$7X4(M^K*RZ zFV?x`tbce5(7s5yekVMfm|W9Kc`P*7@0Q~U9p?HS1NDPqEuJd~inZWz{-%OJt_j4s zPflUXnSq_Yt*xrK*zVhhu@>_|HeM7Q`#^k2_?$(TPP2d>kiAu5X4SGz?W4R}iarfI zR+Zu%P?lCy%Lf?uaAN7j$4zX!yR8c2n0fA@Jjy*(RA~2oyOjL=4$f<<@@}`-I?Mx} zX=H}OQd|Yht2ii6gvxmpwo{Z6a$XH>9`S~pS3f6wt_{izb1B8Gm^D~(U+Nq5Gy46~ z8T~#wqknxV#vhx4{V<%mABLqbp0VE$IAfn!Ap9)go4Y=cn=Wfyc5PNgbRSN%BOS92=Za!1x z*$8#YBG-Ayb*9Rj8E1QtpSw`sO?Wm6{qR^a4UXH$2ThHm7&C<9Jb>d(iWFlUBgGhF z&a-NYPy0KL|7jRM#tU!O$ItbW=81Z~6?o^`B=xyj_`RVI`6lXfJoK54GK!%SYfpgv z+D`m!5|$Muu$}RgTWIK5c!zo5fHyY5{>qWY$yxrr%{F^lRmfr+x@HW(Ij*hqn<7PvhdZ=SCMXYl* z)baL=vw6RdwQ2L>Jpaf9!SfC5q!aM^NUROxie2?7>~)0CF%F+M;<#Lw#Lh+$d^TPK z@0#h370f~CHN^p+jAQtpe89)mV%!({ce#aatfeG4ml^I;?Ojs|+Fauz#?XC!xl%b9 z>Q7XHeVqPzd2qa3!5EQW5Y__|x z5&sPM>fWZ8U!Sk*E82Q?agZ*>nYW%gmvi7^|Dwd zX?-lWksi1K_IjCva>Juf&?*P{s4 zE<5rI(tmT`KPUOutj1W`qN#!Nd~>`Q%i8cWRgZzbQ7=Q=c4roQ5_BK+;$m4xlu(T1 zR*oCw8|xA=8Ln87uL;je1wG_vrJ0lTvr=aq<^RFC0)54^(glFKcvj)5pFsX5u_A|1 zyvQMxq_^it(%ZvWB(1$N(Oy303EH63$z`0j#j<&T>z834W!LJl)J4}yv0B$kv0B$k zd4Ljm`^DIPtKcKYqR>u#Nb8h@gdK7Pi5z#a`1| z;&}|N=i@VDleM|=cnQO#K)l4#Oqyr@4I&SfsJG{wUJv6Xw0fg)ya0y=jEevm$#D@) z+%HRti+1XKb7>KMKM=p)B<8zO;+uezs27FOTFk42wDxz`ovBKc_#welYG15Zs#q`H zzO-JRWym{YL1&JQ$QQiOhj(ABtr&QScUr8C$F{x>@P7N($F^qQ(H6*+h-V;u?0T+Q z{M{??dkX)3Dg5@%1RBx7I`+bKG+bwEiBX2Ta-6=;?z2|nf9>q!*1OTh;RHA)hr`iC zbIgM|4&r-krq1KbW=gUDGo|&LDXm`$hwt0h1AJe15`1?!rP%*Y?9_0|iQ#JQ#GZ~* zDvL*myoy7dK2OfC&#U<9?I7m@pL`Vfkatlhn`i!1p=Ttp15oBEo@(>X??k%G3Wx7; zgbV!F;F1n-@fLUL5T<{>PS5L<+E?~V@5J66E^;g7==Ox?`FUnCdkx;99yd(X*Zyn# zipT%-)%h3xZtp`eIXu6QtXuZc<`fYumG=$WseTm zeddGsSXn1lJrZ@XBsOM@ZU@!&!s_9~7qLv^uNsWYRf6%o;yawLXNAtQi}DDrBQ^dj z)`71L@SYP_(fca{cAr>VH)&pP_8}X7M!+^@VmFNJ!0rOHF8Mpuzb&jY{71ijls7`- z@W+cddsj8^X4t>;M(Xi1y8o(ysn}Mtk@>&%S829xEk76f#Ez8md-1&pddQ0JNnd?& zWvEYgA<;31BCeri6<1;jvTz|ub@0m#E za2pr?{$zOkhGo{7p!l4B_LgnC1~%YZUA`w@_ric4UYsj*1F7uRTz%i+eyYBTa>xd9 zFJ)5ham%;Cc^ohY`4v~`=TEvUt}u2L*)$&ij`rcc`$G1iqUVG|KN>k#B+q>WeSUX@ z=7G;m@Qg7Q3hGkbNq<6KQMs6Mred8>u@3MIuSvCq=69}GjJlP2p1iFJ`%7<%sle~w z>>ZkeLACupbPlC+Y~n7*VF4e1j8E&MEcU>20mjhn3EyXwGnvNm=Rrzxq*#`ngD4hk z0L;sK&|;JC2zhA`;x^E$(GtCKO7v1n-vi)cSCMyw?~S7Kj7sIL#9FVCR@I@^SILq;JjwX(|5sGmhGm&bA2ppf_iURx3Yz! zrSn;74zW^BC2bBP2N7TJuedNz_dq)sPYo^C0x8L?wZQES6_T(%B=%hw|w^xd| zAE^ywH|=iD6Tr*AF?9VS`VpNncCEwvS_ZZxRF+Elfq!47vcKG=RF=XXZYxs{EWgZO zb;8)Ku2tOo;F0dIQdKQJcP#YngfWQth}-^J^Wt5I-+DQg;kZ$z`ja8;1DwC|uEJ&< zKNp}aicw`RuGfDz7}D0Iu2v7sgnnw^o0Qd*r*`cV=OW$#nl9+hiz_0>K-uM7l;Z9Q zEqAe7%3Z8R>v24omr2V9@}KKs$wnc**<;kdaU1n-Fs@Yl=JV@BY`gg8V)BmsWZVm#{QTJ=_z4lCaPJZBDuQdCsl0x=$n4ArB^be)n zfZo1cY|l2+9UIp)`T1B8c9(|Xj&yH^B6t;^H2^(_F>*N<^9#KI&zP4KWrb3e;EFnb z_AsIacn1Xc^Ava9eS0VBC<_x@0ntHXJnc6Jc(-6%7#Wlfa-9sBfsr}OtfY$~*^**9MsD&$sZ`_S?Td8T(4 zknIU&&3wTF4@a~9j+4nA*}GZ7{)$dT8Cn>4kIvDm)2nztiyIyKZD?~ zuh(swntijEWZ(S#46<)>*sqdc5Ae2LtyGpAu^_%Aqg}2%TKJG-UT>?@=Q2sLU{)y> z%tWzZNiZJI{3P6O$ruOknk|igjwBz=rtwE%eUN!-&_@(w_#@o+yyXIS^0h9aJNXbF z3e%O!0)=AXYs`8M7l#>rj;(BzWVgdSvfA1a|CkuyAKKbY5^INdu*qxJS!##;;w4*K zvjlh1&eftF@{5;jZLqHVzU!jM^S{uYggeCiJse;3Idea2LoD~RMwy^y5#|!JqTS!- z>F40Sxy2yoal6w%htC7@<*&6n<#^hvJo^f4CHpMQ`@Mz79DBMucy1D&&wqb`4f-2a zoGJS23H|l`_5Jn4{;Uq)GX}-x{XS}Wpr3=HpU$G61n4LA*Y^{J{d`?uL)o%CQS-$v z;J(HnLLcFLk~AMKTnY{MJ>UVyY=5;W#U-b)j(7CDWbJ13Pcv~;ZZG9cNtx9ct+)pKj#rKl(n5{H3 zlwHQC%5wD2L;Wis>Mgc`e00cS)AA~V47_u}=LNO`pcj$&^nYe(Hk=M@G}`@0(=IFv zZ-zRkH+FP)hGu7VWsp6_8j!_O>Tb-SoV(Fd*~|?2UaeU6##jETY)z-!W)0YJvF-%9 zF331-gUBAPy&oIYmX&28jE-1rc+V8lba%0?`+kOJAPSumx|iwYAB%E+E(QG6Jx71{ zcb>1p${za){j;rsTnjvh74UAiRkzvi!84WlNj8_$!e01_{3G$5HXq$KY-Oj0P`kcw z{8eev_}2^}`=2(ymtnq|FJa%Xc2xFn-j2%t1MR#V(9110tqqjXH2+fVu7;;Iy&iZD z@*CiL0e-VpA$~*W9%lB^5Q^i`_ym7{P`ocPGt9fA(Rh!Aa?orWO=W=l!!;i^^ufb2 ze9kgsJtG_bwV(5cni%x2iej-Dg1+Hzpy}0D3;JzBUJ%6wT&Cu&sqKH$UbK^ zjk@o@R)3T4TtuI?(T(9gZL<$WZvU}HnumvzA%X_s?k2<<}o>T`PczR0VK^kvbqkbJTBT=JI__u_CpAv2f9|8O}Ge;cGc z;?0t++(3E6|2P%pM`0^p6KX4ueE(LOMmyso-@i2s?cat8wRmTuw{Nr!@59k-w>@qL z{kItO4m0Hl!uwe8&W7?>pxZs|zTa|}cGT@cZtV{9u}E^OnR5Eb_nG<@;@P5|d=;F( zt>5n#ihf6f>=mu|+k}2vIl=vYu~7FB`g9@2WB`o%Me{pO7tH)^3JI^J#Pc)c@+q^ZIqjn`*uloc27FMcY~;3 zL2y~M5aVn`*+vonw-9Y(QS2rdJH|WmcPr@K5^TQ={m-Hz>iXx#1CH;F6Za(q+h(|r z6^zxrQRkWd(fXLtr`nt)@ErM8s(WVAnJSbcg3kXk>D~*T zZz>b?`ksN-+iGt0~Fu!Tx$`&+hfqbi(4r2n>wfIev5hVom2WQPqHI8 z>AUt~jOTF*U!5eDg7a(z{=Fy(eZ@rFLn8YceSVIi4{0LvE=h`LCw&uO;Hpkw-epO) z0z4Zlif7&xNw#AcQ@9_$PlyQXc90oe^`O(PO0tb_q?~LTEO!jSxq;I*{il6@hEZmv;`vu}mBDDOL(fYktI5(VY+?UdspP1vNjXM7eoErkJe4nH5d;MH3 zh81DX1;CY9oHyV}e4`X&BVZCGog*SFKF-m{63F>2U^W@s6YwxL2Hz*LXbADZ?In@# zqe?d0eaR-Eb;;sxd%Wi<;kV!O6xZjs-}8j@dO<>Xo?pxr%=y8c@72sIR>E`rihG~h z6EA6#&w!GXXpa8`zOoeacLCi$33E(?IU>EsTwYd~)AcZ)dkqTml3nOqSqwVjTs7sW z0rpw`L-sbT7YlR9R-+GiVEkS+^{A(>Qd?|Qe7oEIGvqeRs>p}UVUzYGAjJU~|GJXS zitpXt2&1lb`DgvR{)6^1;ISFvOt%UB;d=(3BelnjYwJ-Qa)tzDLB0;Vr*Io-zLnFr zSF*cxig4$X!Y&)3-9=0L=Ygxx{y9U+*)&6!d&;_S8hghSkb71LAF5@N4^_Lv*9c?3 zWr?*CpEY~Qj|(FD{36K&{Ir&yF-vy=;uW5NZ-;RqSWKQ3Y%+i@I+ zXdJtvlwHF^>GTE0)b|2ox+G*wH5W0awK%4OG^Pxo<(|D$Y4%FxAnvV%K3@; zJ|nfY4BB$_1G>F8(Z<`_M{S*43~lw(+bYAhE)WZF3$|4cve!P*)_!X1TWqUdx0l_C zZS}>ofpDIvwRJ7F1+tNMf1+*GaMV4c0yqggCFrdBrc2~|x)a&V&*@GfLqO+lss`W^5ChkeR@AM5RbwqC`y0Iu)!r*nNQM;#7r$y%KntOM)# zdVl@iJJi!Wl5F)1)&abENg9(!;7N@_ctW{gE$q)j$gdaIoxj^J-hs}!6YU0K9a9I& zG3in4_7TL3V($+18(B$tMa9_$##VUdui!My+(Xc?!5zqG&OWRe5@^_6$gb+5OuzBSk9=z?b~ zxxP)@UPE_?pnnb8GI(3UruYiBRc)eNHmb5qrX_BXhe)gYJk~9vx_jFFJnxNsSJzV> zl=mq27~XB-DH`u{&5?2j6^+;LN0>u7gC2u6dnx*N{2V^QcdHHhcV!;B|JqX|--6rQzoJnC`P@Ktl ze3t{?tjM8UGb5-k2bK>Jd5i{9*)=%7>MPkFhKX4IRXH{X;$Q;wT@;?%2z@1RZc_mV z`|z`F(Vm!37LL1lB%jY#pMTefAOmRQ>V@wTa(!mduidG+IxIRSxhIky$`%(>hUu{tCt+*!W zY#qOszx@%vEu(K8APa`oPZhb2#Js-6`t>v~H^Af{sE-4FxhwR11S_v5JgXln@D%XY zU8KJ+xmv`zhmAjqF z!~gY{vpaeqPGqtB@jt-*z^CK`L9)7y{e#yZ!Vtepuuk(}hIl#`pR3^+@Xv&GiUzYN z{113$7$(^c0KX1gCFvvr|0c^cTU$?ILz~@0*uVhhFD(wWB?$jF%z6J{K|n9Ai4!!p zAe`oU5>O@x*MspM5gvC2IK}gmRg+(_YKfeC9`AM5a?j6)HRtER&O-g{7ySvG(sy|d z-LKV2-(7#3@M{$@H=IsgM7&PnZKS6MbXU;B1`XBa6z>L0MBTM!GVGgvIJU_0%)E(E zXCT5Va-AEoPA2+QM6UBw0myzEEjHwz>%T-@f$~4g{w=>?PO!bPVg4;#*A4M8-=0G{ z=j=}@b{73Q+pwPx3Re!h~d z`vdDf>RW_g9_S zk?ADc_K67?ha_y<8^Zm-kxyg}rMx%VSV$+5a@vcrG)pP)*L*c*aQ;r#z}XQ)r6@G}QIGWVWDXI$D{1BlC} ze4bkv@CAANW7+NwczgxW3uk1z{e*n)8h_2sCOU|eWq{yqWi;F)GtK3J*b`F{-3-RhdpT9ocX$mODH-6yVu`w%AA zl^2o^A@_+}72*>YA->vEru)Q|R8u?4u$@)HCvJu82O7n5{dyD3HlCNVEQ)zk%@Jj! z`tg7xoy|7H6M4<|T@g%|52xvOjLGHSrpf*pQS9x3`dPM4$F1zo{pjx6zkEXe4(QY9 zF4AR{B^WyhYo6Cn@G8I~yq{isUp$gzoIqSWtX12v4(#@@o+Vk>mYH2D?ik_n4a`xK zVGuSNT)KYl=kwRTH)?eRJj$;id8T2Jwtv&xP;Nitn?Tv6V}@$0E)T zYmBk`8sT?)jHB&Ba?WFULe7!zws1KE{@RLB_|2wMY>JkLKEJ!53-@?`L-IXIFHBs6M%<| zY4TU``?IR&=<#i*rTi-=DZXtc^o#yj@a^%{R%OO4{!I+K{0qvHD`uO!#vQDV8`1QuKJ-U(&DL${{9cL78G3A$VTK;ZRX<&#b64d5sY_rJ8&-Pt&^fq~%m7z0x zmY*jku@a1h09x=E!ed*!O*8&$<%V&=93k1!b6sQ_s}mcMT# zdAeF*y*{I}?$v|!_*Bi$s^RaE{m9x6k*q!74&pVaEALA6>-V;0*aNy|sfaz@BJONb zx&Gq__!yLwQ4H4Y`LX;g!IkOI>2dU0A>0wFLAZ>}xQNafi@f zw@Y`jjj;1Gy~`I`EAd%7?|Q8W@CNm$p;mE%A@nr6B;NPfP+I1(=~j_8nau!|VS z5*$b8|Jyiz7=Qk8d|Mnmjyo@69M|GFh6Im8mIvpi1m9D4!^aed8g&16NS$jx4nG&1 z6jEnA)Ir*V_g`yuFh?$q^$6yAg)wP zAWZXa57C1a%0btl`E|u{{m9mWXJpddR{YK>ai9907>pCo*Y{%{?MD^wU2)QWj4PtN z8~+QP+2_`EX7mBnbXRvwxXygcEqoMBq%+r=BJ0e%qtD;(7ouPEPrh2=Hd|W_o?l>| zZ`8?${5GBZU2R?iJMaPQM?QdWy74|uHOL1L=~%g6xA9?{p*sAF2nSPsfd3Q@mu&Yi z4?1I2+3SL4V;}D<48e^pU`Z9Z+!HQ7m-`&I$mQNS zBwu_2t;bAwkMPI4*B4~|w)G#Ytv}#tmK3kH2j|c|cs)nD^>f7GZjleaE{c3n^M2bn zdTHZuc7TVYY2ID2&m8D;dz6jCbjZcS)S|(3LQQEey*px$o>-sc4vR- ztjb_yJx|NNXa)ha_6o%y>j-=RO_!chOsNx{C_(UhCZY!;qY!)w3B)B;xR_`_`3jK z_eRafme%i87s|Y*<=*-6L1!~ad(n=|zeyF}bf#~fb16Kwo#O=FR}3_$SG%9n9oZLP zvkUcQshvX6P9C+h5!;zf?eOqs6qIbEdSVWn4gS#F`i!A54OI+_E^lh*pjGJavz<(PM<4NvL*DDYzdiUOUUN9WMM8$v%mC z1LjN2#yIge!gYE#;ASra#m(~ko0+lfgGAB?@EvczkZ`pV;_plc-R)Cm4czS$i@5Q9 zq0ny}q~pf5d%xT$NSx_;c@Nx$MZQq9T}zsJJhvz~zF7dzwpGDcFYgzOA+| zBBqg+^%%vQzNKOdm$JpA#Wv6u)He$&t;_;!!KDmy0TJ$R=9zQuvtBOntfHXaUJzd&QV`# za&&(crj+x7#bV48YY!6V4paAYKkJA4Md9B(9)K%uNj%{HFqYE+_Aa-de7{{VLf*ry zB!X)xgKP3og`CIWE8D5O#XA75w+7;!C9>?rzN8QQc!`@h0{J#q90BVv2H)?D{W|k@ zkqxeL2;z7;#g6R5a^dx6dcP#36=t_flI@9cNwN*Eaxk{1zjFs;3_Y`?L-{=uXavsk zszL0|HXC`9`u(0{V>G8r@AvZ~SpGfClUYErYHcEpLw~PG#9Vh}MR(E!dZW)_laRn*)6hj9-*Yk3gJ&*eQmh}*OV^BB$e|=Ds+1fQeR1nkbeSyObkqZ6Zj*Z-%?B_yBw3LFXDJV z2`>%bL-H7%ra0Ocu3s(e&DI?dqEsOV&c&Se?)aAK}0_3-<`K<1-g(wSH z#B0MSc6PO-1Gc-?Rn?8HYgU+E7tQV8T~S|1csU7i2hKNZSB5(ajBzKYBvZa4B`S2u z{pgOg8|T%F;s|Nm-;y36%~868vA7f~BG6_#S?+T->obpD}_U`g2W*si2;Tp^gei%oh&hGL9;xXlF zg8;5|M3W5}09TMJvV$00?e5?@QJ&Xun%9;9irYfEAa$E13z47BOfHRJ=XInM`==@A zM+Gg_DQM|OqNOVrBAtXt{JTVg$8>qz+ibEg<4rVfs8naBT&F+*vj?e87WR3YMh?D- z@HA~9<{U*G?36})bB#LKkHRc>Yu{*R{H)N!&U61pdm!&`-Bee9+P;P=`&#V2udav} zGc3s%vu1r4_{EI2YNG$o01MPCi)2FELFh#CdLZ~0}PfD%v-M(imo+b z4x9k-#wKU+Z_-&fgXnD;MEVEMcgS*$M1Z5vN9|8wzg7XRObf3x`i zTY6yZlOPF}7wr`P-`WH3%R%A{Dc%mVF~`WZ;oKPHuN0@|l$~tDRo&IL;R6zVbra`& zk8w#O#f%u#jRYqnuG|l>S-@dmqK}WvbqHT&HWy=TR*bvquFm6jsN*Kia;h|kISwAv zZ645nWWGr}SYWDdG?R?gEXj!Ni!pNe^2Xx9NPA_ZAH#DleXp~8PHX%7_(vl8UM|8j9-M~Z->2FOfel7q@nDBZQT2n{G5S)C4S;6 z%wsh?AUQ8_YVwlN0V2MM&&F5_9^RI6lYg~`?G5a!incN_0{G$rM_;eQ|CCXs&cye%7wpqU-O`^ zG@wn+_tMWgU3{7oZcky-!bsJ zui|$!{8q-^jtpV({1tJoOYyz|xcF8t)aM1bY_0fr4^7=?S>2bhF3^X|uK5<_08!Rm z&+2Z*xzjqH5ABq)bq>+8oooZN33FOFMQ)eyhSPlzS6xHvv&jk`0{@gvwSzK`xSv=;vk)9 zW9Ik_k$tONK2vXb--Bn`^8&?@m)?7j%VeCg0crYcHe&?;8?5h7O>TsAGw@Ugp(e>>o_?EA*)uSweel-01p(Oc^zjGju zT{20Enf=5*XEDFq->eyPPZGW9;Cusl8ro8JC()fxibn~1u?hWYIZWUzznc9m$ycj0 zUHz3O(VO0u{c?`DD9KMCvaB3nXcQwhXZ0M%f0F1vo*zv2ah@N}&h1kQd17t=$rIX~ zZsuC|@nYt~{tVXCKUd?v{#3*nI1?V)M>bk4@2P43Ya8vy|4)v4%IkmMM*SfYj+({1 zeX`wx->t?6)7?t)J-C*1bPvvGboo%A?rpDMYcakBL_c1x?~wd>%?g{5uf6f*1!})p z8b7=Y&PGWGxcgeq@s0=Bd3^isjTdh=IWF8_b~G-sfNbaGI5X2*degs5@uuJErFhdH zTd=-qw`n_n)Bn9Wa&1gz{%roPU-JE7@A@aG-u1_9tTJ2I3c1$mk$2-;lpbYO(%b&- zinsk;*V5bmZmzfezw@{KVUcUCAV>4J{W-3;{S#r{nK1thSclzl@n*&Qe&4LdMH0O9 zb?_U)z`0VWZk252v{tlhwkEB=ib>(G(hBvZjnL+|JxCy_F36GnD|5%-*Yd$z6^cx z5f(ic(EApr#Z=v@jBA~5bNO}VvzYPeeyEeO%Q}zlOy}WEe&x8<1WDhPCHu}XUk~Xn zUZ;2;vP*s+az`D-MEn=Zt1mKpa*4tRq{J+~AmvWXa4abiM7$FL@7Z@ykndw3=A0|$ z_c5H8R+lKv57t|I1(!8#jeY}}-sO5B*(D?9c#G#3dslz?y+TIxr&!!rAK{0wxHl_e zaksKq+yFyy&lN(1vK-5lesH@2l{N&kc=G_|Z$Zr1Px1KkR@+^?civz*pBLx31+ZSj zxZHqKtuxNaHqv-OT)tXJ#vI~W|E^+KBdoRI;9_qb->Te8w$t)!xZTv4CrEM6zYH!y ze#GON7Xplzh1r_s0IxuMx5Ou+{ysjDc-P;=C!##_iMdy_%_lgYy>dVK(Y?`1aJzxS zZRST3jD+4cnQnZT9+UBL;t`dl*G6=wH(gedgGDgha;!0yNe ze8>wC%8Ld04T1FD0>+ebUvU^ctKZ{igbIme;W$R4hCV^4Eiu*Aed`Idwr|Y6HGc z3J^c&hwrE})Oj6wZZ^q}7{+=|F;81B!jcz(Fg>$pD!>R^o40{3-3fjY~d3rJSMAAM1mGWo5}Bk-D@ z8>`6mc$1r4k5I2$KbGt9K}D`d1^jfm9sysPdg49DTWsEIkn54*-Kw4nd$b4qz?@!) zA9&8a9l+m^2PF4c?8ZL*e7fwTf%XL^hg1fkPvRt*pQbW7#FygwA?^G&Unm+Y;m}mM z-a>_qW&zbZ0`-<+tiQKR$$J4eZ=3@7H(RYsM>uL_2CcmC@waMu0b`PLc>!Z8lDr`6 zNl9KXiyzEye~jwrIgQ1bQ(^f|Q}Uxz8iB6Ur5Jr=N1E7(^D>IByjp4ZNpf#z-2kx2 z+n%1h{8dvjzVD-cGu*EEVda{8QM?k@noV-Q56wp%k;za`?53RcHiLnN_e}U+SbOv0$b2NzXA z-wlPWepL>Y-=84fk%sR&m_FOBe_(jojZhD9rWJ4o<}WJmZg96~!oDUu)v<%*Xu1$gF>*0KJNh_EezUX5Z+7uK zThn})^U`>j^L8)Fd5(ICex1*GUNWt*7~iBUe+%EfWCK1@Vsq9bh27kp|ge4Z~ z9nJb~>KOBPf9$0DChXhpW6omUw<}h3oggB7#xk8JUthvPS@((WWV!y|nv?Fz3z;kB z?9=>P(kTRP0YW(V&H{b3uv|i}IWnH<6Ac9EY>bnj(m%h6he# zz6ZgJXa~fKRqg3@9r0lli1~R{QwmsbTHolfMk}%qK^*s`=y%Y`;Fdn(@hh zVBHn4?kg1Q{%m6V*8N61*ZopE*4^5oUiS#L?)0jn8o_W>j^$=^+1Mgj zY`Oe+*~U=lBcDI{%*GIZ8PGa=Lu<0oodxIG<1)1@32j|`;_ZIa=Cyuw#~;>?HQYV4 zeKN}EVO;)!h=ST`H< z7Sj8*j0E@&=aVS`{gG`=QXHQsMcZDiZFg$>6}C-cZ|M5L_t9`)??>+%wf7}@PdBmg z)7fa_xI*%gPUy|%{GGv^*W2ZBH`r<1r|r_Xy^>85&Btj+TJu7 z_A3GI!Pay^9AKh*BkFONoU=>367PynK;32E+naVI0&VD;70Q_7$qfnYyp3 zZNd1(^v?8Vn8OJ?y9*-3wGGZ<$(~d&m(H3Hv~khjEAVeS{T+vY$J5`H!I-BsLb5yW zAA@lT?M(^6_|8&}-|}zCW<&K&7)#7de{aF}@pUXdOd$F{Q$O!xKWpqwrT9K!wcO7Y zl24Mo>5h_cF*}m(JR6>M7MHg9MkccC#Ubd&Yj4UauuFF_90zr<^Sx0AYZA}HeQf7e zg${N#)pebzs}=793+R1d9OBEpFqeXG5%p7d!o2(%9{6fZoKXFBuyrk-@jsa(PMnVy zs?kO&#Q|BZ&m~+7vX+#0cm(ia9Q#hYr0cFH+zO`@9XTL%pR?Z((?H0{YF~YnR{E7BC+0Akp{^gwoJG*ae!S6SPi^~^>CsU3bjjjjymLzMzd@$Dl z?wzdnC!G7_f>Va!y;Mhn-(Sx1=dkQSTFcRMPMDv)Y0EjMgnzRodn@rHDF)`6jHaB` z847!Ah9dTNhJ>$o;6B`&(XQB7k8koXT7G>G>8)i>T{m&npXhrPEuO@9K%aI?wy^T$ zP@cC7=oH_B?!AKTNt9TJd$<3JTj~Xq-x5E7} z+JhB}J%F-N2*X0QZ((r+Q$D8x-Y1*^2&)%kg`!&&Yk0m{5i0!wzk9wwlPY%nN$|#pAEE z7>*&m(>RAQ!z09;CS}~HQ1J_lxd8k%qPO0!Xu-$O-!4nTLAZlz`%8=`zUmvN;Hv=h zTYhhwulDV&=d0&>%Y3yI?iC#N_4v2UFGnH2lkTUC=jAUT85a5QJA%xI^IDw}kB^8| z@LMc{JM`_niEk?VxoH8vKaqa;%uFAbT)x{|n8WV64Fbhlmhu)ai>DY>2U=Q+(N0|G z1!pF{1M-sJu%4O8^a8t0;;2i7h+L?bZlU-$Qan7x_raG^9wA9bfqsd>o!3k6p59oj z>|1$<`GehIhAsH#?u;Ys0Y(4wmhX(??CrZVUXs+lJ7f1G&v(XWE~@X0UtFX+<6l>J zzW0nAVSIP{c&6tV;@t-GyO3-Pc>iPnB4wP@8+QAuiM3vpK9d_@7GI*C> zCYbz=`~H`syjNlt8}KcT*&-gq^)0rDBP$WU7I7uQ6>#N9@d@WdC|E^ z@n&*nC~}j+?<_y^%SStKX#^W*RJcCQ4D?eQEx2+k@%Gc8zhyqiuPDb&jju4L-cKlB z0rj@{0UfeAO%~WVks#A!Tmn1D3O$8e^YQ&Wtg$AT$q6tA9?vNk|3=@72=ZaC2?u$( zyW+h8^TCe`mwoX0y!y>R{RPP*2|m)gz8uh3zb;P~ZO)tbenjuTn){n^|8i(}g1BNxZM7>7;Kod8_;WYdWmOpI}lMK=8rb#2Dks z2LGe(j*o-1BFR?%wD&gnA7LoRU}p31W3k>8F#8V1K^Wj(qR-3bZYBonj+eeQ3TF-s<_{-;zDio4zaOQx0vlIlW%TaiCs4`qx6+ zxMR+8d<&?p_afB8@2K16vA}r0n+*Ehfb{{ND%pDpW&J0o3#zzO_&x#cK+=0VAG^a$ zzOF94@qjpr-K*3kUlK>~=@Cc#8SuezR$=qP^35=ph&aLltdD%7Xuh$GbJKLSP8@kb zyjMUG%7Ta|HJDoi=p5xuBiXB#*@d`#^~tE_Xrp>t1a&>HL25lemlfxBrTON~m-(FJ z#}TTRJA^>OnUv|CWy4?kGv67-Jwtkb^^i@9^DNytx(T=T_QD(}? z<@-|_ixGze6X6`<2p|^0a72B7p!>NXrZFGEI1U>t*|IVA3-W%9^&-j6fozYh z)bH78>hr+FY#l3@uL;&UISq3u1B_YxM|ZJDjp7v^nI^}8)Wt(&aUj2jI$C?c7g(0a zXr-SbjvmlQ)igD&)H8n?l&hup1Wc~}aGL(CV>XW+cffva@sW8Y*53|eZng{J2To`4 z7CZZvO5a|VzL~|N$&JNZ7O-#gSp2_fjHh;0^QGse(cQ9AP~I)+Td`&hxR3n(^=6O> zdcquVyi;)YZw6Ulj#57WeMR@C{eEGd+SZ2a>(bmJ`8es|&Eu#bLhf0gy)u>N9Jztvf;9Lujay*WY~kYsNHeu8I2r3GUH3Zk;_5a`>b z8`Yd6)@gL^NM-EYu^7-$>r|PB^5RXZ{?AWUz(KZoO0a0_jz4Jt_hU(S>!XtDs$+Ls z=kgKU*TsFEo6$al{_*Xw4aW`8pBY?lX4T$R0M=*mE)INiU^ldF2;vaLIl#43%pdNH zxr~p(8Gv_p)RFe{2bd}E`$}IvU!{MqAi_PR`ju+6FQ4|l#p$tVD!QG=|^~XHTo3`4duG};bot{Pc-ZEKJ!(X zt9eV;4&18fPq~H`V7yYm*Q7{xKVIzK|7vMJ%)>=GFT4YKk}dp_+~Wz3Jw8Z|k?O)1 zm`gw;>Q%kO)rc=J&Lp^wVbCei_QIm&<>}@|#%w+vM^Z?E7Aji_0i(^)=pT3jkgXYpqI=dG*05dOlV?MbF3n zH--4v3MLC+*=JY=>#H0`vFZ+(=2g~a&nL_cbvu!lCQB3EYH2t_md|U>j z(o7jfj~T$IkijT7iC}ayn^!`Ap`730q;n&T=fRLa2d+k%goD8!Nv82T2!1LD+;A}LXp$79AXfU6CY(D9cG@lm* z);Emlm?-Qxx(4n?kC4tGe+`Y3zD6Er27?dcTJ}V`L!s`%XifoBjQN7M!Mp^6eQutt z=L_d1>-V`~GU}Y<*umRAVt(im#yJ1WWIcY?OxDxz;mP_r9mKIlvp&bkeSSHaVzOt? z70S~YjIu)khr$?b`M008KA5baX?&-XA?%no4(?iZlUOpOu~@tQH*lU=tjtbjuVC41 zIbNrv|HrwP$Z)!b!O0px^DNAydAhqRt0M@G}>-Rt30M_^6 zd<#sj`Ho@pE%er(LAOlS)Y**<5<`#f(l@f6`6HBY&8GRr@3 zH`x!qvJegwrt4uc(EuhkgSn2MOfm&u|M?GT{ds2MO@*`Ad2y+m^J1oczxpZn%ch@O zFN3*tGniY10USeczKiAg?)#APM5$t(`jh-K~pM30B zK9uvDAIsLS>E~=cz5kT0U(@&5`m^SnY-8N`BAaldcOKzJ`ck1h74ZOdwPW1#0NZH& zKE0n!`!pw952tbiIK6HFr71!w40YpWevll_a%L#^i|H}{V=(5E2Jl*E zus4smf!9i$2k@xUg-{pZR>96`e)qkPeP04}wI|IO#{~oa`ELe0KF$*C2i6hWmz`4@ zc;;qP9A@+M0$P`(!A5TkRxOST?I0}b%S*8oS&ZgBMCBqj@?uhVoX_H0AWbjm*w zH=W>kFU+UUWMR(cNhGgSWV5+t%X70qo!7(kxdMNlMDo58PCsFp#&_;}EL+FQ)-d{q zGW4C3=KP$3{&CK4k!?!IM&DX*7i~QrM*4muURXIv55M;(>EZYGBt87LPcnwzD-3=p zJ1ha1Ir%-$!eD(-ZOANL^y|Bh ztxtRQEi%}L1(R5e5-f|Svbj*U4EEtnPq?=M?U(itcKG?^&yJksw-LuiKZH%@$P+a& z!W`5y;@Z*v&euK>+OGgStwh^9$5SXfZ7`>C26Gx^fEz;%aATkw+~_-r_;Jl};>V^@ zLV1yi>|^yYBvb6^?uOrX*Tb_5gQq+E_A^+6m%$pGS^70x$kLxDXS0mYlT%Qh2e_Cp z2-bk{I%161&^t!IhMFw4hVBM9$Kr$?%F>?)2eS0?!RJ}}J4#iS@m+Km&e=|}QF8jh zT@>iY8cp+ehtoooe*Uj#wY>+WS$cVAYnC3jpEFp`Ggvl`m5pZfkL$@|>zN|2XC1Bw zWBbE;YA_E3thF?je0C;B81F}ZxPCqN^YuWx(w?-Q+@5q+;(9KkZ4t(=>cQ69gLo5u zJB#0j8~F7k(f8{N_9rJxe}}p-Zg*-T8yn_q4V3$raziYn{-qqr zv!y$)G`C8B+FSf4mV zq&1nvhgtg|U$RlA&-Coa`d%#aMU`y^^lrDOaBH?jvKc%vz!ahLBU1T?Fh8JNr*qCS zf6qQe&6$9I%n#@;LG7P4w#<+GnBbf_dXf6$zE-^hggFU8VkP z=GRnp#wp!-^5K6YzoyE+oG!nnzJlyGWy1LLcqW~8N_YKy_}|D6sj|W8@t}0^=55bq6wBkT`4}c zvi-$q>i0}E(aN1O6#j~X>AtP?SDc>7eURM8M~%%zTJ#kk&T$qm+to$li!Z+y4D!0& z6+38rCdNpxHx;38*gQMMOr2r>+hV33$^E~_OqJd%&5++K1>>A|g-PqV3)iziUXL$+ zTWW7whU;N(1Mj@a{TZa8|tErVuJr|D;G85*dM^S_OlCroUqCw~~8lR%CS z=_^iq7thfyVv`~^gdBe&OdS3@eh(L0-z8gg$#mI2#>kKBURba8PJBlO`9YvB$o%up zXxEvbU$(cCfFF(*UTi)(#_RB@JoN6pPp`$4&z`&8&NFIew$vPI!PfNS^$&Q_OS zi`FKeEHqg8`8rI0zG{7Wk}}AbNU5J2kU=tFZH(Z`D~#nh|M(2OKTyvMwV$-IeiX0Y zO>pJj=HEgx)Mxa$x1G`WdvOHaqa;7+8R|A>)}}gw?p2jhbgxp@X|n6*c*d?@=P5hs zgsKAD)(KSvw4D$6h@J8wYsWlfC!fM9|F(S!EBxB-{}VU;e`K(xop$o|`7TH(LVDD; z*>2Ego1JX>cs}j&7v?N5X!kt!3v+!Tg!Fi(0J@_o;l9xT?oYFJ`_T@G_IxYhR2uVR zFZ8DPhB-du0~Y5)eqxgUHR@J;6!$(KS+^p|F>Ux;-fh?4V{W(8JtoeZ?lH=_|I1Ez z6(3Bx3zHY=E|hhyu`@Xc-z77>Hqhpdyv4F#+XA~@cQx0p*Iiv|cklZ-*{=7S#5+ZZ zi!TB^&j4SHH;Fu73CZ$i(Uso@+oSq7{9N9j(ciPr z+(h(!0$4o}!gG*hOMYhw!DvI6+KBSy3Vs)4zDr8~x8H-bK1+gF>x;TQK|H!c_OI0W z!oirghtPYSOW&kBknK%^NANU-e3oMTp5&KwCZBa64*R$1#&Ot}u{V%^PSyLgE<8m( zt?29NE@t1ZbmN$P#q4hO{nWP4$L;Av|63IFkMn#bUGFQ2ZKHZxC3!)*(<^k+o6|{7 zmdeBA@(oxH_+NwNy=WX|e(?2f=3jM&eCs|vL-*>B&(Qw7IMt2sS-Q|r?=8$ZcG&sn zfLkLBeb2HJ+xE%1IbBbyOVjnbj_cC(I^~>nz5eXVbiLhf9>N38ryTUNg7a!iictQi zN%j@PJclm*U%KAzoRzNUW9jL79p8j>wJp8zEhd}9>wO=Fr89od;iBP90}T4VBwer5 zjZN3vF1x4e?L3j`fJ7-{^YpSqEor9q{QM`uCo{+w|`}>uv14C)=m&D8UsIzSc(bEA39U z4|nJK=5B4D>tERDT<2pXgv(=8*+^#nEkGy=XJ=(qxPILq+DOL0v%8NE#T=^jCR`aP z$i7#YFX62qJ$}Aw)9b7qHoeaJc`Uo0l`W>SO*qHfY)$$7VPEfrv#g&`p3L?rFPP?9 z$=37=LRrkmF&kwOv8>s56PX6n!N4Gk;DC`Ey1n=1~gYOfW_lRzKUs{M}fa zTz{J50GQ*YtWJHP-sdOI09HM0dKo9$ruIkrs+{a)_$Hg{aWP&sm+7ROhfxMH9rG!% z7>v=Hrr(dIG`(*6Oq!lwpGqSeTYeX^u~mi&<&VG|J{H&>fD9vmY+mID`-iyYC*xKP zw9Q62neFQjY0PKD&)8?=>oon`zc85l-ZVXKf09P_OIsk>FINElEHZej_a4^k$Ij$L z`AjZPBfD9{OKF;%CywXK`0cc_7~v$z&r?V*sHM3LX(VUm zy-szN=fIO`dLNc`ShkpzEu^wX(#Yq!!i#*aK^8CXV=&h8G~#EH3=U&*8T=lDah74( zLRPkbo&Q+2l$Bl2&VL;HPA0$HtC3#-hZmq8ZBFyZ@Kuc40K zEbe%X((6Bt|C=r1WB9+_BF0!qmYg(M5u0Sb zw}ZtdA^EE>oXr--pZp>{>KP)^=*&#$LG&!)Xq1ejfoa5R<6>l9E4>4pKhc5j0KL-m zcS~ogo)29}rI@R0qK)INzHe~1{XLb=+9817NSgw*wFWXe302ccT`Kv0nXFt7Ezj|A zs=n`osr1fPyWTHTDHmecX|mxc`-$JKzw3X@=I8_Um%;dFy3m_p$yY?t?@p+f->+?2 ze}mQGw7v~~7Y0w1=sZWj7()?dCmRSBrXc+~w-~JRzXp3z%+{!CYp}M*+`#DJRJu!S zW_Jl*z9JQKfr32bM>0V^+E~#?-H*O2$Gg*DuD3E+zS%%_G-drLgZW*T%HBMf+m`n* zHhx?3-esvw-fQEGo06(OCnl!SIU&8l?x&}Xl+^ae=Q%u{#phvdrTb|wn=5|R;Vwdv zD?bmw=D-^i_m}@hUSt(y+u>br$a-7+zT*wLw~fsv-f{3vrz#g^?l=BLc#l-xZTa0W zAl3M8xc@ly*(Y1`Cb|uML`*+*ES&b}IVQ(=)?wIUJiq(9aEa%4f3y1Xe)Mnuc%7zr z%&*?Qw}F4e>)(9weQfKE;K?AOg;?n<5X9aA^d5Dsg=jaDodq9H(%i$Xa!$*(bmyLE zVqFTO2_N@wc~_;-9Y-3g4Lz!-v2N#MwV^j$nnLGLrJ&b+Uz4If`#C?lI)(H@C~uos zEThYztS$TaxLCz|e0H`P>1(o5^!AMOln(MEKVx_dN%72&`lS#a_>F2TUYf+>001vS zf2q#K0r(aAGI|pe0Anr9Vq<`;hrW589b?NlnD1=X7s#RLL)6)rX6wf3d8RQvnZ)aU zCI62Rz9eHgUnAaiCX49D-8=sOO^|hrh&LEti|gYgo#SSO&e5O6`hdN}Gm7gR-TiR*v5?L9ZY9?*twPY+57g=J397 zMH95$#p-=X_10tCy{zn0cK&18K~{Ev$_gi-FMqb=uc6fm=hXSQ;+YK%B-r~XWbMie zB+tHrysge#JoF06!am}JV<;p0h~w~o=;L*^H;-lMWAGt7<|P3Rg)tn$dwf*qai}F( z9~Y17rtf6)xG_tw6TY<7S)3P~*{(BS;U)Sr0DY5|1`-dyEbE`);XNnFJlvBlG;D%F zTnj6shaj0AtP^yx%9~g&;f8FJbnp0bz%c#2L%Dt_PSRkSvt(OBdhu7w9Dj^wu@PIH zYWpO7`)#~lcB~su`g19FRj|7LVW{uPPV!d_p6Pn|BK?9>x1V?SXpZJMa^0(hBXtwq z=);qRhCDNa%S6xjvDeu;(!0s}aK0}Nw(i`n3i~PhRx(~~v%NV;52I(s6Yt=4{$pkO zrf{=_;U7zu?ow&qDfF*p$1y(0 z_C+ZtKcj({BzG|1qV?n2mW$ty?fAXzc${bZ^oy|=XGPC-mL$mX22 zjrRY6Ok!r{SI$lQk#Uj4+GL5?^ z^PkCYcwmG+zo9Z#9nWnTJI-_5vFuoVOxm7*fLv&2xRa_rL;c6;VSxI~&wr&g$7^w3 zVGp*_`S<#O75ej!pD!yz>3m5KmCu*olZB!O8855sqd)V0N!IhZnq+2obCc`i+hnq3 zrN_y(EZ$$WL4W__{RP1~dXUXCH&&Q)#DK?ECKDen>`M1Pcec*_XuYj-d$Qivxh59#5vT;#Du9D8yi$4<|F53d(R6vZ=&bh-XK#vt@-3 zy;(7#ADCSY=ero3Yprshw?Us7tgWM8W3g7QSenfAZ{hlL;2MK{TbN9I&=jVZqvj{m zI6>a9j?pYmM<~P5PYh%nXIp#aJP~A0$SS~Ak4`|J1gd{4wmg& zuJ{KA^Bs;b4JN$3CJU=YnaI_ZX5VKjgx1WzSkT2rR;sA#tCwz%XZ1E#H z;lDv9E#f}4sKc9l0?vok8H$*ivdw2Mi}`iH?uLJIKBn2z7su-5z%66-^3#9E>TUPM zV=)GwN%HOfDg@-3Bw7FP1j4PvOZ<3HV=?AAlzebYI_87Bd@S?9ebM0FS)#soE;E3! zuf|{boo1)>rua|vNj7_n=a>)DD!X33Gm6W1l>oq4$aG3{9YJMCEiH}SOoeNCR%e>m3j`o9j-ufGh}zktr%qaZ(^ zZGKBM+2-G7=cc6{>v^ah>)FEAQ{0aAywr~MY&KZWooqi#L)zZY&B1N&=e3Icc`+tYRJSVKrV)-Z^zA-)}J z7~YOG4CHID&>EuHn_H_z@m|*~xZd5m{2xbCJ>5Ca>is#Id_O7`z8}2pvC;aoVx;R` zrAZ9_(pk)7>8C2ntx!Ii{hp#IH-Aa*NAdSOMft@qoW(QP@5PGpb5Op3{l1+2pUM6o z%Kqp1di-6y+ARJFvM{$vxb)$`(}$SI4{PZKde0f`O@1a_UUC*^E85q%X&=klFJSFk zy{NtECGPT&p*Ny$`chgT0>nEG_bCUIQ>P7N**$?OMC5nFDchgU^K>dtn{d~{* zIl}tsd)iqXrs${4O+Uw2KbNq6s#rh!SU;m#ew0Zi3!-x1waEgR&mp4P}^qL2KDFMQreu&~?ove0rf>ALzhGMWdO z-5ouT>cx48d%kdI&t}iO!)1qe&pQT4y7tK)-xVA(Y2Ot94m8u->Ca0QZ>8a077e(> zaY!jYJ=sKWre`bjg#k|Wdx_cq(mMX`qHnloe}vL#V|#+pK0h1Xh74#I#5s-RgFlRNUnu)&?Szk$VUz0}(M9YCxZ{jF=Z!GyF`s?3R zq>NJQ%(T2gyI;db(HmuLoXdfum<}q^Sf|xz6y5LP?xDKh_Z+47x9vKLVo+@ArH=*G zWfb{kOXJU0*#Ae-I{|5(3-#-?Xx7Q&9DG_!{CiA2@$LQ$f1}eBZ+p3mIO<62>%yL5UNr9M&iA^376#rMKD%}adRxM!H# z_Tl&dqd;80aHO$r?Hwpz3VV4x0B92M74?NmnneF$DSneyKJsDle@2pyQM#AAiSvv3 z2=OkS5A(shc{=ikI%?kUKnS2nnK9ZM@Y(LLCH%#weqS7^Bjt&daKG(nFoYF?>?V{sG>iq{t zAq+syL7$Oy7T;eP9Y3?jcJX{> zzZdCwjoTwV`x!bA4(s&ajn2DYyLK#hz^rp53(RCNnSPG^16MT>Y${SZ4x5Hh&#-yF zt7q6Oj`j?jE27&En;8ajQCqOdY$Dhc>>}8BRT6BPDhM|Br0D(TjeM+Tjv)Jn#GCv( ze~(BR!FW>}@efCiAe;YnF^$Db`!QJ!_(Wb}=Y8zX41~Uhv%Y{YqFti1a$osSV;?(Z z?!9$CP>iL-7YWX>25{EqI#Hg9e+{QI(cfx(CfYpsp&T7S?r3QP#@4yISjCJx+ov8ui zpyZe%*Ou3r#20^c7GwSn&|)4MECF9d7Z#4w{>om?jic`M!e@pH-mdffl0h$pW@yL^KU*Y``x?z z@8L|pU8%1J+SqZC{7;Jy5sl27pySh09Hs)zeVFGNt}#(;+!cyE!#!(Qp5ay}~cOuyTT3>&J_s@G3x(I;5 z2Y)Glo5VnY-i+TT&|MAnfvDqHbCTYWoqwKi=#%lDX|pnr(`L^`!`wk3%G^OF@gU}} z-KfqTB<1@Fk@NkK4os2n$2X&~V3;D`5B%ov;Q4z7ZN&UNriOA|&e8C)#V^o$#PNC^ z)+H^@V!S6vZ_eTFwg=y}9W$`eE657p-}{(UIRW6W@n=P`DNgSA83#=+?&fP?YohH_mV-te+`wy%GVQ|l(u zVGppM;Gdn*M)|i2F`pmI#ov-Y+YkQvKj6PHdamEbdAUM0+WR+|qfZ=MEL3B>y57LM zwR!(`z#4aej8SUf0~goIeUBr{Qh^8lu7rhm8?ackyYx9FELi?6oXc6HdlS7S+=}pE zG7g8wSq6`zTbvRPcx9Yt9&=YH!(lJAUV;0g-8Yo`jJx4My%apC!Xh5rWvRA3Z@`0k zwatTaJ?#HL=o9*GDBoq#?SHe0_Wzb~9Y62H?w-%PYoa{gu^tcde1BRU{ zUFD?rxu2aSer6sg^D|GrGlzz-dja=Fj%R$Xm(1t(50Uv?Te$yQv}gX^Er{`Ng+H-Y z_q!eE#Qav!N2Nlb_&qBGIe(->Gbg@2?YXmQh$itn2f{m z_?sjqb6^>hIlfFHyDD${Mx9f#IiMdimjxa<0kVLC&v4rU#?aOBn)j2)mlo;vkxgU| z*rNE3e_=-P|v5W2`Z1b&V>lGJYz+v0K0B{6@}Aj*~Ps;ALQ7bWT6>pY&M_ZeK1 zq_-ulO47$}$xkAm$}I}J60YsuBz^8%oLe53>6;?OGKEZ!Yvb>uP-l`Cug+0>eUjeK zH8)B2^HaVn!TJjfV9ezSC5$gk(&ruj;RlNU)}}82;7WRuvCRF%Cc@V%#>%o3zBfqw z)9E@p@b^*nyS+Z3eUtP)puLmyKA(FfeA=gIz8gx+^FqG}X4g%N4iY9eU3#cbf&jwN6v; zi2+@N>RG*odoI01xW@|jj{&m;G3`-P!z-}A7)R$3bN+1n{Wog5A54GrN#c$TA0JsRRJ3V?z!>q0e(Vtt;N4AAaB6kX$eAuKeSEo z7ODqS2wnX062@YmaVG0NL9njHHT&O_dv^k~@y|=RTl>vv@v3gU9p3_nIC={eDG65O z>*g{^Z#5)8rT!YBseUWq<8HHf>Orrfd~-!gA;7<;4}6;n-*#i}0<%~T-|BCK@`opG zt6RBi!qJtxCmib!`!pWv+$f;^SFDA4byEHCvYLm@+v-BRwjH}nfHvOSwvBEquD95d zL594w0{E-dTevMB`D~DIs}26I_tndTE0`UuJ^<(_MG%1&P9xpa_#%GJbhO@1JP6h( zCQ0~7W%!%x0&8Gx6TYL^9$Z&<@s8^fbYG zLa@T$Ko=29;>JpHr?(*H`3n-Av;s}kSYi{QACc~jy>E4f2=8Jn?!pIsF7pe`pKbN- zKKzj=VMP51A^F%CA$bn+8NBb>ZMPOk^#Y}O{#e&9X84*UpAo$Naj1W6ypX&M^$gIa z@WC)w-2ki~)MNOXtiTa#S(_rL$J?ENcE{3$2BW27H3mz@KeEOgD^ zd}1rY3+Hc%g0aJ;`M)R4KYVQ=oBugBf6l9L-)XMlWjDZFF?RncrySG8nr{*#T7IfR z9N82vH1t8AfYT4Gr}9Nru@CrF?E#!T12WmBUP40x@Hm7a@@dsO4DKVq-eD9DlI0^F zgGln*86@+^7O`bGLY!yTx4HIs$Ru*O7RM z&4GMA%_KCOh~CuwxMj_T8=IDYb!@rW!EJ=cmU}t&cnLd7;ol>NolhX&>wTm$$s>LR0M+_;-y-tlMgm&WaN8TyZ|YpnjmODet1Q9OxG4 zWs;+H1o8#5w7z_hc}swg2o?QByAUYm0{-m`X8imAxOTp7r2Y1+{kvN_w)W3&aliI! zI=S}y{y(jKLkHKsu8pWkl&w4SqsH-5% z{wdy;TvcF8J_lnoZWWTVy@ZinO~M#n7wzgq#v}k=tBMzrvEN^DUNIma!hFv6 z2q^lj#vkj9tO0qT5q{SIe|5tDPt6b5u=aFE%Y7e9GJhkS^V&IB zFFHpdf39C^YO2Wy6puhZl^9nR_PpkClN6UI)+C&O_0EaiEI9B!DR>J_Rj5mZvG7eh zj{6k+{jDI3M*U1hu+YTI{v*iiL;jEJ*$(S*H%A{>e@&~eYyFt#MEF^_8D#5iH6i&a z&%-`HloKe{T@xrC1$gwv`}xQV#kkj!+zL4Q#V5|UIpcQpd5W3@U1|A z;`{46;GPG4{c&@P6#I_%^T8(+W1jzhm$m=-S(HOSMthdzk$XnE!8J>~8rQ5VT)1`x z!?kaI)Z^L=16;eO2jSYQdkELAc7tngz0iJKd-(-Du1!_o+Ep;-AO)^n&2a5nC9YZG zJC1APy`cX%(XPa`G_QXI*P;>E+|2RD7uv?Phk6NrO1O43&V_5Aj!@&;NDZ#N_AKFA zk{eumqMUH;K!F<9;x)L|i?yH3aBUL9wI4@x9M?V^N4Pf50M{mesmHY+V+hy68LsUb zC*j)bT3n0i0Ir1^;M(isWL&F+F~y%`T-y~xxV9(e@4>Z~V*YttyMLT}T>J9*j^o-u z4X!=&u^QJR7_L3}u`#aQ`zGPq7!9sH{IMF>Ryh)8~CwHrHt)8_HXSmjd z;acf%H@LPtT#ai_%eYpUOt|J{fNNU}aILgE;o6bU2-hA>HpaDIwzePFzTc|HwR@9g zTw4ocUa7#fN4pcQJ=tA>YrDfcj%&A@n`%~ui??=H;M!g0e+1XE5ZBzyal_Vj;@Z}5 z7p|QhrpC2vG`RNTM#8nL-QZg0cEYt)%hb3wOM`3ES^K*;60Y63k#H@@Ev^Nqac!QA zYrl^rTwC&k9@i2La4m@8nw{ZV!&qZno6-SXOEbW=pT^3#_Gh<%qKYFjt~GQcTx;y6 z#I=A<;2Q9?l>y?xZc1GHXZYI7V-eSk=jbeHFRlf+aBYDG*Q$1@aV>-4+OA#3xaN3+ z-3_i+eA5U%xigKLj4zBcoAHLk^Ia4nj(w=-O`FPom4 z$Z+kwF~+zS(E(iZGr%>+7#Y`g!kBA*ka6w3u7qp5y8bHt*=z$S`fpvM=OnS?GMJ+-nmYVYx$LGT)UsOf9V;*wHKZtT${jft+eKRba(jY zReL`APWb;T_%{^(&V>Je`RRN#w_%6E{#Eu8zKqKsE^>Rc(s#|uzY8M_zYDJKqYS?{ z9_HUi8-D+jf6q5=U+-!^((rqYtG)63zIA=qv{(3hjDtG8O@PDjec3KSGy&e#GFvP6 z?|9^#zuULniJJBe(famctGfO3N6tr2f_>=z@#s&NpQxt(#1B(UcJSfxvlPT z3zVgAL;H5^N-rq0Lz!vYR)5>J+Lh*QN7oA5YEkxwdE(rE?a?g7Ir}^Mde(AL!pmWR zACjHPPiR1Y!(&j^I}Xl!lTdDCGv|J6y}X)>&&<5k(K>&oqXli^8DtYTYE#MlrmKRC z+mPK{5Oe;dw>$jzFNc(N^~kcstwcjN4q^KF40Cnsd|!aS)o}*kk31J`YR>`uOM!PN z;g7WcpO5^D?)cfiDBs7nt;W~9tsdY}v(*HA+a!+N(Og`gVM~r3AlzEvEzGHT*tV@M zq#`B9N7%O5KR*TQz4xKNl*b&~Z^k!24|AA?mo+yuOYl5$*chIr9^kpxg0RU3*i3T3 zy4=FDmcjClAbow*=Wp#Ly#74=6CUj;Ub8ttd`K89*#x$j^JkY>32q#|UP^dFool|n zAiaCx-&Y+Xc!w}}w}kX;~Cmdz%99kq4UB70j0W@L=z1VV%cEg%l}q za9Vh?#4~@^ln0zASgvsc%X$y6ybE9n^AllyBKI|DVRm|>c3T)sdk491$6@mJDK(Bx z(BSBmFA&UjC2`*m-|Cj5$R~ON+LofnkZx7FW=JP`R}29%kh40)ghey784pxKos z6)*fNy16(~;;VmOp9Mb=4uAK3=l0}NGs1T^z;~9TWhKJbGk?7$(6|lX1FL3F9@Ff} z^zF1K;YkMcZW*hh^@)5>9tPaK25|R-6)N04H4#dKfKz~bINc9$g1PDG+@KAIQ@=ptHWD0Q+z^4eX#6nZ zZV!M}PZjPq*J$80LQUf@Xy9>Q7lP9!O?he!!D(VA;WS*rr>kMTS22eb_o)DVeNI$)B@AYTG#C3Z__(Wc_%Olg%}&B;vjivgTlco$G&Mk9pTp(n-_>wh zqJh(a=Lt@y1{v|ASQS5t)6&^lHJ$Anp{A$4O!oLhQ~vdrL}xdC*Eu@7+=RR(wnO~L z9AMmr)76IG)pQoCfm7%k1g94UdFDrlerlT^t{xBZ>d+7dv^&bC8O>-FQD&Hr4TLH)b4@Dv0F-hnD z&&9-lu)lAB?);^DLEH7_G&dK+7>S7MUwzv-xu8Oj-WVlHvj2FzL%F{zaJVh?H*Uk} z&a9!shrd?)GmmFB^dKWT+#RB#!!#{^-KWN{W5d;Wbd1sAQBC>5Q-oiSeA_wvx)b08 zbL$Wt_Vzb!!|~~zlWP1*(cstBn+Z<42XZ>}scv}>>98xns+)=q&;F=^(?B(xHfiAT zER&y}(Ub=_5S-FF38z5<($p2O-pd^=?;%b3c%;LFe#UJ$TyE09>94QUa1#H+{C@_z zxmWJ)s=}!@&Utm-|$s@8dd?uWa(whOQLy>g9T zv)gtYMsXULy{LiNXG~@oWCSw}ycX)^sjrpPkuTnSg@`PJYA-viN zD~?-f2&*>Wbm)W{PFHE*^fkk+xxB;Ux{cPh zdEE#NKE886gO6_#oKh2w=r&qKx3_5F^qv|{-8Jx-#bmPxP5E|#;I#8#=iu~GE7EOr zhv;^ewb`%@hs&|!YB=4bfm80w1gA3t+P*9HKhnOt;+jDBcg3YOL}#}h>>QmflJKbg zcSV1z`@7=S<7zrf(7s!IBKyv38kX%Q9^*H}Lc%(*^)MNj{zCXuT5UQ}?`!<6F6J zvtb(!$LSil9;jB!w4ZJvxL!WMfG$_6_1bHG(CBH`tLbv&P_;gGE|b-gH076{A-wzg zo6f2n^ecdnylE9ybLJ@WZD-)6%$oL{|r zOwGSiHETU4Hi-g45ux>j;>Di`S8Nun#ew6t=+N`|dRp?uQP<~i zU8{j}s0PjtGF#@;9L^Sy@7Ch^8V0ZqSHZgKJ9l>YN!!p~jxeix+_%$kn;5RN!~Z>f zPW_bj;{1Wm;r`DTa4#+c*v@veti`vp-X72Lb<%$5+weW;r`eO2_pA5hzGB*wVf~Em zCZkn6;+pR?JYu`r4j(jF%?lbBFZI=wAODNsw5^kH+He8yCZjvVBQm|34cla*o%#!ElYl>0He*EI(^cjjD*aM~Tz zp)=4Mu zhZE*=n(qZL@>aoU^|!`$`O+}-8vj^*k=T<&#OCkX6$T2cuj=0 zXS#AiwRL7(C&5Zx-zD4qqK4B-4V>Z_-T4{OU4~kBGG2>MPpI+fmw{@$xsus#e$tfR zeS+Y#$_;!x;nQtRD8qD2chUpt&Y%s4%MJ~kk~MJJ`82`lqf0nG!P&YI=`I3b6{*6h zhC>=SU8085Mh!gv$Kdporu>g;g46g;!YM(*qq(r&IgXZ%cn|e_-W`y9i}Y<=vYiG_ zr~apglW!@(>5fZ`_;?o;KD~5E!^hXE;WTTYnqQk4oTh5ZXZ}EZyy45v@$nxUk&k!j z5Fal@Up0d^oNxF3Ma{=w(7@@HcL`1dIX-0oAO8yRDF$HGLxoRQYvD9Z4JTg>Jcjxb zoJ^YX3qKN^Ug{*AiW(80u7dSm>1g>1^|YS-JW?fm(zoGoIry_0PFHH+wCQbvQ*9r9 zckroh*^O}O25{=Gf>XGb?vm7S`XEtFUnheJPH$_N zM*X9YN4h&B`OxUwa5{VRXEoh*(ZI=@@u%WGMs(L-MR$7+YTz_MEoa`YfyYrscmLLu zpKc*Ig?AE8f<$-yJH*G!&?n2F4TpWvE z$66nPQy)$Fy^RE?JzsPVPH&yZ^Uk+JaLPeA8MNVWX*{Zi(*qhf-OBLE(nn##Q^h+o zm+^NR=Kxl<0fJ)$z^hb(mx*jwF#mc>l+<4>zyjmx-Qh9fbn+Vw z5C26?b59RY^J*cG;Piy1+`Ec+_~$HV&|E?H7Kbk=>2{#OQVIM2TBsG5f#->b%@ zC9e^jZZU$>ZncbA@{NY(iqteWZGf7#${BCU(v(l$Pc(OOf9GiKyK~5!IwoVTl>F4( z%a}15n%k^_)7!5QocbBTX{FjX?{Y0Z-J^z+S%WtzOjmF*L0$f@eS}XX`#XnEk0YE` zcFZ>~8R2BmhT~6lof@C!Y2b8=NO1Zgj?3ca>edXjqx-q+=%L@J?{!-wJGy;a;c#11 zL9lJxs<3oP=Y%n7(SPTcCrvIpc!9N9dJo#(`tfyyYqQ+ony33->N(_HlO3%YC~te# z?H_aM>vNncs8i#Z?_Ra7e93Nt-D7bIpQ=Rxzyryz3g1U>KJ0v*aLrmK6!jD9;Z9j; zp}3&mo((FhUzFwI?|BO`#^iKpKh4p)XsXNisOI5}ZFT)CQtDy#@btFx?} zaNbvF5-h@;Eig_T^pAVI3;I6_XTs00zy7PvNpG&d@e_8O2RPuH;JkT)<85zYhxD$m zn{aE+MarRe3eIz*@$;Z>Yx)GyZ86bJH8Am;(1sOMLXe z$^B)g2R-`v=~rHbawr>M3Mk7qS<4dOALia0b1tX|=k1#B1!wtjIDeMHyiWi<)Q7X& zdoTMqPP}Y&48(JACC2!p*qy_nef@lbZSO|s99(NnY(>g3*k@dGO?ZCFv4KKUj=L;U(2?-KKUv8 zU>}X(=E{@j^l>=TgeIrc>Tu2!nvRWte?VjPmr-AGp~*TL za1{D{7W#S31U!WG`waZXTut@R@6+%%_Iu|gm{)}QErfn;Il_)An6K3LRzcz;EBXs_ zoX$W8#@?R5`-47K@%~^hKB#CZ&aV^1tRaMd7y~&!-Xxy&jdEnq4k|kK8|?jOuvZOV zOsI_kd>U_);&9iD$WJlBJ{-FX_ha=0A)q3qc1%S|0?g;^VLwOB!~Tw%m4$#u4^OCv z{eQ{K#?SB)uVdq5>}G2etQqE!17$VPe?9as49ride@|$7S&(6HxdOK3J_OsRdjJfA z2nLe?2AeMjng_TZ2DsJ-+Z&JEmhO0>QS%5?wYC`q~5StCnUuj&1dFd=K9Q zKkBFDFSDchH;ZEg^w)c?utSRZVCi0V)y=S1f%e8L?n-x@gT1OBL-QUEeSN5aZ4&%G z5A;<>orOJx9h-g)cER|#Ah(HAwh5ElB=iz?tXH%-rDzkOY|}+L=@!g7j{_!_?pU1O(J_z&S zwE20YP*gJsa2;qy+UwhFj_-d>cK~mBw|-qls%h?a00Hb zsG~Ut!<>s@jJpElzBfak6?S1qO)=boU>;RI0B7X&J>|J=hW?svvO6vW+nQo}%55+F z=H++-+uIPgaZWL158O_3y7z{3$9bUjgb_5S$Dxn^m@rpZEbM7)nR9ud!wGvfU(lCb zYfyHpqD+Mkr<~=y4&Q&^-E)xN|Btmf$^P%d#(zve*uXgeGS3O%A;;dcH5~^&vKaV? zX&~?s=<7J}4m0o&j$^feW3|9bOu$R(fR{{$^$Q_@cPoM3<|ChZ1o%lIoJ$W+SkK1E zX8+?})Br3oR{J(@q3966@q8B(4!C|g zXQRu;7|=sKtWAJ5A&;ybf$Oq0otp$}!x$rO`sv%weiES%>?_PoKj9siPZ`Gf2H4j2 z2RQ)F;rc_qj^n_W(+vqOTH52|8NQ8(JN40>dz=b-%2`8*2Sh*Gjowxiy_P#wXsxp22 zJ?9KCGr*v76;wbf1uJ*cQVMbaO-0K>%d(3owSv~R+Re7i0nI?nJUT|JZKAft8J#lI zR%{Yo{-52WijX(^eHhx`e*r4{bXf zqcT36AH-1&=5)JTE7b-COYS)W`>82OFEtO7bL6;r$@W^7v@VFW$oPbL#~jqt;rTfH zS8!YNdrsO1c&`MURu2@Uy#wi-;Jq5HY1K!JxoZ^Eklpdjh&NOX@tGDJih2Ve*}ij1#UYu7wd2 z!rHiLv{aEooJbd=pf1ueNrEvz8y`YnmT4NP34SjOqItM2^Eipbo66lkkO}|9 zJZm|W70=1C7HzkYDtusn`3xU!8vGsT&Ywn0ANtVYae%27aM1*~XaroSd8Y736&_%` z9E=^?u7ELM-JSRG64ELMml*!~Cjzc{z9&`x$ zC8$U0L5JAB(n~lt93%QB=%<67zashCC=unX+Rm?Ka#yzVH*livFQM{X3h3ja{==M5 z_+DV|O*f(q&RN=nLZlzgxyq2|F_+3Xl)pivt@UAJtohRdrN{UnDL0U_)&^x+XBv1b z`YG*G@0Bpm4Cd2tOuq-{>TaN`X;SA?cS%ZK4aE)${DI!zpy)SVd1gLAR|9)y_VF3z znfW5^>^T?wo0$X10Xg@3LYSQU{h4-yDnCqsSXk^T>*J1PYQzQb9HDxC5}u<}&yN+O z-zA8v>s@7u%KN+karhGY{!id{$E(U;&EBu_c|VxFe_s6_o=f2Q3RStOB~T7*uTps5 z7v87BAJXgycbx#y3T4ui=ZzY1Vll1r4Ai+y1>-o@*8ERYdA#6#@pJV3JX`|+JGJdY zSJ`#&U4TEFUrs3t-zFcSa73$MY=rVDsxr?ka(Qy>fbKBCbBOBut=JFL`xffq-F_IC zL4Oxv3Q)=cJcmD2%>~r^9G-irzSn$6;oS@W^(q|R=hOe;!>Z>zP7ExezH^`cs{OH( z^l~08jMvu=BF-a^>&)5^;J4q3hq(K8+UsJzu-Dyp#xBR8xlu=q0c4vt2Jd7sT6t0_ z-}8j$-skkgPA! z1^^y!a%m*KuqaK|#Yvp_^{zG;`$uWEq14x?g?=#xH#nM@yC!9O_O`-UniI&1IoD=6 zbuQNyymuwJ2B? z@eb5&f3?jsukf7nzADBBWxQ|e*E8PdD|la5d}!AXAKGUOJ8G{x z)^gE!&sXr?L;Zgh?-M@qkN4`Re;?k9eDMB~58hk<=8gAn^StrCgyH=T1@BpicdZBS zpeJG(-e+X4I8^uP+xGQCzqZ$1eb$XPlZI^Lh*3VzDW8>Lcy>SrDIx@jK3)2kdk(an>Y| zQw+Z=RQTP}1o))*4W#&mc3lg>rWzUq_yv8P6oB~MBI6hONKxY#${N-9g|=Q+;}^=m zc)tq2Q2uI$->$fx>3a8L6u;|duRXMD)(7_W0Uz7Be;jw?D>ne~n_(5SfMY>pZ3q@* zJa2o9;<=}KNY4`h*J^rhnq+h$P0#V6>87C?Nug`k5b#fduA3&&xFyo|H$BLda6h!& zBknJbwznv>UDN7K+jSegX*=DAwqMKjrtQz~qPSldr#h1~Da3>Op~RWTaL<)5KeTI& z)n0h|kiGDyb8Z|~2H;(sU{`@XrcHoyFb}*2Xz*^DXAtAU@>x_i7d^FO+at@CEf`0v zg?Zo#cgeCvDBQ#33(!B{U)jUk3@q&`(F?dH6WZHUfD7<^kZs zvlDMc;yg_BoG%)Bo_WagHxF7i4?!>wIu#FaVu5-dpzcETJizm}@2PnJXzo7MJizyd z*gT}4hX*(|4|UI#9jZ&+Y|ps;J9}c$>5G=_Ess+C_f((B_AURcY+q36pZ+ID{`=@Z z*oXcTedvF|d*1YadYU)=hcUc=AFEpPo22ui|Ba6_ybm)ST3=?h*G2u^UKiNl##=%l z;9U#;6XG1@axlgBY6agt)Ekd7J{)niJ1rS;4D@A#{$v>sK7OqLK1u`VFTexF2&R44 zR%ROue$FVPQ=d?tlTt8v2hw>X(7CoZ5p82>-;J_v0DS;;m-NAy!>4Ij58vT;gz;nq z&dGSmz0No4Jaf{(<^*U!o|8P(2ZGe}W+2Q74|AeX%?S}-JMGO2i5uEH_A;~;^Pb9{ zh39SX-7`l-eB(}U-gxa!I!BMk_AH~WXLGdv;bn(1zJJ@!ZT;N7epc%x%c#L@&U$L+ zmy%J-dyrAZ5&u3JW%QYsJ2rUBsIBjM%czg<_MV5)Y#t(FRWfP_#4WCqaq_*t zS_|48m`}P6Y!4go+4WqQ**1vAhYK~hKJalG-tk(KiiD!XrXAy1sSMW(cT1CGhNj3O@tl^xT>_URnx>$xLZ2jj1o z*G#mQIzeZ7q{|SYz04@7-~HatyFwSd^HcvRcrWL@oI{*l4;#Sm4+H-27I`V){!QMi-lq*!G$8%(^ZI;p5bhlBq zZ)+FTq@B6Z=yco!^FAw3vIVV+Mfuh=2=Bn;Q){D5>36DNn#f@C+-DhM+5J7GdtX>4 z0UWj*qtn@-l^kHl;r*%gw-}wfK~~gdQ#|~xuA@wlV_bU41+t=c125y`2EYl%XX?W; ztTv!o9D`{I544(TEm{t|597lz6c%w-99J`psi^3=wAIsyWV!<5Pc>{gWnIdl6$bv+`UUBvQ#^;O-A zI5kkhdl69{;Qh`g&UKa9qNxnn#gQqkARjOnyDJ=NlUQ+09luq=w<>{bFGTqukZmS* zcX|xc82CeVU}H3b43Pb!Adn4EALA*-1C6P8mow(Jz`J$J2jYFb&}~@wo1mO>AMFS5tlTM!vf^EME|z0+M(D%n#5w7jdXt1QVn$J6T0s=f(O5~j zD-rsj`OIOwH`lw$unVOdj#2rL;6pg32f`dH`Kft1c8F_vh_lD0>dkGF ziA1z?ZK{%=^$NK&!9Yg-=4vguVt~x^S~BI2P_C8j8+a6c+xV!`Mj@&O?~ruyq(#f= zmfD2kHCo+~HOTv@H=03@psiucBeDyisxdQ8v&2CxX&@jloP#B zw-)ba|B9#g`Zj7i7H#?IJ4$cuP!I2-EaoF?@`2{(>ru8AreS`$_Nilm zrf-tEhIsPKt!MWIN5S7c&~A&%6^*~~eq?qBreM38;^Qj=|+{0SnA070mhrX433tEfz)eOn<#2wp+nzOCRJyN<;VWuhte;tt#DBQ@xA}EzO7b&%eLF zdRgJVRl(MpYMAHhlK#d+TKHDL=}JRb`5{og1fH?{mGAGX#H-dp+EQJ;pRPL>zQwZwmLzkC%-V=anFL_wP(IxXKw?YcLPV3_AhwK zVG;UOPvBxpXLBh_vv+ZJ-0O52^c2QJo8iADsQ=RG@V+jHOqneNmu5r1H*k8n?j!Kq zw|+D5a&DJv$^@?R=$zj07dD|Z6yO3pEu9E_m)se;HUjXp8rmqUCkK%?KFba@*8^XS zB7E~M=)VDZHW=>^7c5%_gqcl2WcX^}gJc2hdHBP)dK2b40odZ9Pfj3Hly7qced!z- z#$Xx7$v!aN4&||K0>EeqBnLO~l}B&qBA3nvSZ9Z2myQQG^#E^jr(TBBcE%;|C5&G{ zq<9^1Ry{MlN|!+n?(L#`1SQV266Hwzc+!%9vKwsF_Nfzqr?P>!#siOylRBRo>$Y2Q zKF?RC_-=hfBlK6ifgHT68Il(GxDoi+34DBpCrkUy z`J*Ea^o*PwE26lyL%#5&ApB zYvs1m;kR!ajY5B!hjqZidgR&O$RpaNidM(N-Xcymq2mEodJX(1XJc|66Kaf9o-EEZr@NS$7 z@$H&vdN+TTyhHhOMbw4)^FOI?`@PfVSKmg#`~PMh{iXEn&3E>!Z}kbkVtw1Y2Ym}P zjrw-U%RTGcFZ%rl^lk6|oW9+B7t^=(T#x#8H9On>a^$a@pVxfr-+nfK`+xQ`^7CC& zd*9%YNQ*=Y{R(^(+TNMZ~Y0pIW81v@Ab#a7#CiBQ>c8` zX#=h=AU^}&*TZ~TzwyuGuYdF3!{bZO<0o$e{woHa#`{f?hjHBu_sSLnZ%c#>M?S8T z`8vXqk>l+Xw}#U^KZX4$FSi4qqTgL*@bI$(_!-Z%G%la+m{fNW!yzwLzShTQs4a=c{Uq(b|UcXgkLw$-qD?BqZrSAamNLC7WdD< z*pX+a+@?3z24!07O2y3U39V(~pG{3wkp{5Y-gIox;lNt#etnWib+m6jXGTS?(=__il) zW~?bauMe>nTu+?1HymSAxOTP>pNoK=aGkLT=!Q3?7lW>fPo#P8*L7*Dia}pt&a?KZ zY`-|md4^-gv7w#uCCDUyWt4TmzFSp$o&_R4^)>E!=ETYK+5Mk=y082F68h(~U;RUX zo;4EgdvFcmLH`KSi6nUqQQVrKre%-*v0v_Dv<&YaVfyD0F7-IPZ%oPrS{@Cwob{`w z<=Hts>z}uCv}^PI&~m;)%fVE~$hlr`)tkY7lw=*0L+KXxgFX@LC<7UilCPqlg^YfH zPEv5K6W2eL^-fAZ;WGV<0s8S*Mp-W|dCNP;$;VGnx+(0f(2XGPC260k2iggi*NpSE zR9O8@aiV8XWj%_dRs&HVdW8V#%L8iZS>I7lV35} zi0}3=dfLOKJ_7F>H-bI03GA7_{>tr{e?>M%13hh|_Dm?!Qz_^*0puds?`nD2iu+^Z z0k?R@AIdiXu2Q2Mo_zpv&VfB?wj`qyWmmqQI8oOwe1=F1;kSQTHUZ=m+n*x{-DKH@ z+fbHuFGKe+@#2qLyk*(Ln7abzI)TyT-+TRc>hbI{|9bqMEp2}F_#Io?{^#`g%t^nD z9=|v0*Qv)FZau#qALK*(B}b?ppYb@Q{rIY&JN>JyOL0EX8`SH0qth~s%h6Utvl^TGumyNrd?YB zv}+T{cBI(~q*;Mni{EV1C@lisoJu~k_k$c|G*=U6sbKVh_fLMv=wl&|xth#ta4u07 zw}US3nm)!yXGhAkawpOX_%`^iPC!{6X>mbcf4T*D1l}t&vWDf^dNEA3|8@fIUGl^m zPX9aOhe@DE*xo2ShhlpjXk-)6$eTbT@x=M!mrNH!Io$s#(?}kly5dXJ#XuvQfJXlM z>!y+F`?}Le45N{#>DskbKqJ~9N+TFA+#5(~L_3|WtKF1;)+$DSi9mnfyXBL|*Oql}mRdi1$H4Hr9OHyC+b8Me*k@f5jeWX; zh_mBnz4=px4q;v$>^}HbgMS(IOVOZzImJ;K<%j;h&QR&yB#(`F>I)TJ0w2kADUj5r zFaCSz@}gu{fJ$}+_?KN`tfLHYU~zw&f%}e$h_t$TSC>qyS`KM-S6X8L#mK(m0FUe&AK)YVhI-4sErE_prYHZh%>Q0hk1X^4PGuP{7TwZa zmVGo)Z$9jnWt{l2mD1I&PuN-r<>Ynqy5{lhU$aWjv>EPSzP$CIyixqp+S1>gDI}D1~|t zLcMjIu6ZN8%Yk~wp>BwhRe# z;~^bdVg5_^*T{4y?b=&y<$_DEg!h}?uc@{c?q5}6-CMmB$_Bs6OZsh`LYt0nag^FA#0{=3uB<+mG}C8JrS-6`6~7 z5GdbvuL?CkY7RByUULV?mbx&bb3Gy3gXH`+Tnav`&&_o3#9T3e^ucxzt|#ijKR+K_ zLS#yv5S8-Pv35DnMJ|lvGll+PoST_V$%QIsiMr#2fNw3ICBnN9ve@2!pmiK`8}2Vx zjakn9C)>5rmbGl$t!&(h0*;%0TMXmA&S%_(JlT#pDl+jLQLP}#F~SBSCZ@KRVZZ2) zW8b)TQ5TNq1wgKZ(K88e0bU~f;w;i)fp5hOXEXSVz!~&=!vu=2{2a`G*%NLfWZaq< zZt;v$Ph}DQ(+vLgm^T^vAl!njUuL(dBO7-HaBZR=-hNo`cS6NzcqOJ z>zcHy;zG3i=+s}1majMuEr-FJ?pk&6v^@Hsq~*(cpk*hs5pD_T*+x)k8Sx^Y%YTlu z_Wr6T{P@>9GJe>(|BfVY{CszyXZ(D+GSvK}8b9$q_=)$%&pECq{PX}9!_VJ;@Pi*1 z>st&zfeJl^^>a9;bI=wKxDlinBCp}60v_hpg1*uQ8B?Qz@ElR0;W0vuM?rd%P@SMf)?Ak*PD*3XJhX-R0;GJ1c zB~SgrE+Qe{;u$8k9wOVJCqHW|!}D8T5X|LBL=NMM0{T4RmJe@fD^v1RL;Erx(KB4( zmSa|WX6*W4)tPjVCue2_!gzyV+*%29Qnv{-XSYq>R{(qsegekQE<0o}pP8O1wI^js zm^UkidvT5WjHJMIKO_0%LEkfy(efF|z&>GSX9JNOVZ?b9#_^6@PDIOe(L#v%9XYpb zl%?E|;V?k?zb24V9k&2|;dwr%(OwQTFzac9Ifjs&s+q>rVu4&+IWSYgT*8eYo7<9z zQyXe@I+D0l<@`GCmB4d*FA*|AX(t2P!LxhL-eKl-x1i1&54acyI2kLQnZ;xhJJ0R_ zTO9kUI_DbR77ns_BT2%U5(&e z^n^h^OIJHR$ocZ4n7@^zkU)CAvkY)t9!$0&JaRtcQ0*;I;3GumlGMmsd5I7ct~G!U zG(ZeFrZM9)?GHw2STEenew#|2)gt@!Wl>ZKe06wl2CawHEt< zvV4On=Z`QqE*^L{XkF}S7+X7xtu=2zYR9Yrscmxxq@wMz?|W!#57~xhuDA(4&rw0RPJ<0?tLX%;2{`9b`EWu4L1H=zLYxmF(jQ_n`+sk59 zwpbr^PA_<#u*Z`-Aw*U0-ZO0~IvgN!f$g3+KRo~KJ(rx1zj`aB&m=~lH#}*G7|s6f zhrd4_Fht0Ant{C0X+WPu7@e4R5cjz4<;Zr-IgjH;8AlRs6e-Vf;zW)_RDnFfGwdY5 zC@Jr6g7;|q@LHO)UCu!f#98aZP3dKTSCj#^Fz?(HxgejE`m&9QaX!o`N%&^a7tW3H znjz?d8*pup@_XGV@R>pGB+mf3)4+*MAZJTqUTlK`q^3cEk}Zo9G0)$e!t2EcF-9^- zBPsA;E{o=2y!1#9@T4I;s=n~AD{O$HbrJ{qfU_im@17qh(_jkfJOa4N2RW4t`mO-< zTm1Rw1D$u%xwVtJPv4Ek2*bo92_5M9H~zr z60T>#e9YxQ*DCn~!S7Ew4S(AH#+A@+3h6)pZFR0E*B}*ck^nbJ3^%XyQq${#gzK{2 zxCxSE-p|53AAx|I0O?A^O%Ti>+U4*b&)sAG$2O2n7}raHdg?yG@7YoSbfV3;K^z9( zk`r%qw`ZFaAT=%wl78oM(U@QlaLY9IbnfBv;akgbHQ?K{Br}|+^de%3zH-`ZJ=&`o z64)9$6ucKPyw78J$F&cIwh-?nh7x+mL^>>(fN-twajf(z#IPK`9&Zxk2Th zLmNzAl|maJL$~Dy8m$F=j83_&jC2v~7AG;8(l}FLnl6Gk6(3%y=lIO0J(e%@324uV z?eUfA`7rM#&|Wf^ChAyw+7MM+tj;l|t+03p;pn>updGL|>DcNhJY7K)iP=sLc;`Gfg*&>*3oK0`b`VlXy9=4d!G)UmIh}jln?cozoAefF8uXE-CO^&y($S zf)Q|#DUm{*MX~3-?1PVjz&;2A`=FOtpGU-9(ATE`ho1Q!?sE5NX*m-uhjzsKb!t0; zh*N<7kPolXhIzp%#}{CX>+n0Hd38=3ginFZC4i1s*`*O$dWS}F*Yv}<&e+D}1m?}q zfsBx2qM&z+n2(i+F#_=MEFd!;hrbaZcePw}4a(klE~0rn$lbq!4BP}a*`aQm5^Kt<2y#nyP0<Sga zXCB~lRw&qu253JFaM(*idkN>j0kUc-z%Ur}2d5%I1MD9_9AcqAV|ULf^qOzdzn>Ca^gF2)7T0YaUUSj-)_oE#Rgd z^ME(d9Po&@zn?UiZKLQum2&j+Q8&a@rb~QOY02-1WRv5jrgViykX|qsF6JMrNFWEa zAbTALfNeDo(@AnJ=0U*{`pdXq$pG>I_m$zjPxxFr2>5U^aemcBbJ-H~ zA#b4Hh_EOP^Vj3}>M%b%<`4>#eIsjKu+fS(yPWTI|ow=tTKeXbt_Ic}ivzWTW*z2f!zFN+SDHos%fUAf<$ za7Bx(V=6ybbEvWz-i`j$Zt8c=OYbQEeRD}2Y4)E>>Oc?g>yLNONA(YQ*A>>^(az!? z(+O#5mE#MTJF0LE54LG8q4}&)U(Ep8--Y>;fKTwgrQ_#Z=$mavALK>GqZr@8yw{*h zwj=HzKSbju7zb&eiu#S-*VV@Em_Ryj1^UkIp`0wkKz1b)ep5Zhp)^#6>75G?cH?(H+ZDa9%$ZCd zi#6W#atY6<9~b88%!x5ZS%)T&c=_EQ{k(h3&$~bPysLcmPlw2?_wD5meP*v*(N5v5 zUVbQH%?^9QcSr3B@12$3kp(Lbm7^W>$v1Z6Stq5(0k0e)ZCmXL$9CI|KX&+~QQ!ZV zCr-AFG}Jble$Kzmbk{kL%~Xi`5$w~%1ggW_&xH4Wt`)qWE9qUsXxDH|&tV_AEU%Oi zXp++?d7r{9Xv^FH{VI8(M&fUd{=OD|_tehS*iN8#JIPQU;YchGa>JBp(s_R8277)R zL#ZzTw9^Q*vlnP*JkX97#xRQLz^`1l2ER*Si|&OvNCsQ95o}T4@8g>nA8K6rp?z<~ zxAuZp>$-j4du!>Tf^`*kT~@U{Ilr;ncV*mX&U(h(fxp?dSKcZ?_y93%8k8&@TRjWdeVHxJg3DO@sEnjI`8yxG|5d%1ncGLsCpMVj+x_jhR?MvJCHn-4 zzTbd8%p{78v5++``q-Z z3d{|6PFq#sa$T$RjeBF*_=4UB7rgC+hAnjCatpfDZwUcYK>6wMHAA(J;0tZhnohybt4TW9uTfp#9o_ z``4l@81KK9`8|p+QW*?>2;w}RI3s{oTjPyR^baxLUI|~kX4DwclE9NGqmoIB5omr? zf6_7o`~ZnJ?zCKE+_7odvYgGYEyhUJ~?Oe@xRcvJEKD({X}Q(Cyry@p8lX3Yb< z&4+i0(~)?uBhcnH)t(8o5$`#JwpYAm{!t=5YB>L%0X1J>{$G@dRcsv&eLtDk6u*zf zFKT5w7yJl369u{;We$<^Cwg)}hFfj`7*4ahY<=5NWZ$bH=!ZvGZq+FJQU7&V68yjt za}lr(Eg zgnMm}mr^+Mn(4QJJq)(?^tq&E7tph1|FefSU1OB?Kd|i38!(PzBX?*r>`#MLaX<2 zVb!60Z=l0q3p`u!KPYqgPOYnfUfg|sy!?>Gy4il!Cx5ZO(FgiEzTbWow7t}N!u}An z`7rb`)Tdo+3+UT28)zHHk_%%W&U>|6^va(V>Ri-b9jlHN%m zTaMgF;|y4@68PN&JXsF!Nt)3)a-PBb3c!alE?z@g_JVB0d({yicxN!K4S2;-o;HYi<&mJ5!@;%!y$td^>>u9u4m|+l#vJwWggB!@h`jzQiQ`6>ROQKqBI^v&vvz$a50fbNuC)BR#^h@EKlu z{5~Sx3H9+#sMBSj6V_4Ru5P17tZ&eWS2uBHd_FlIb3xw$_`4nOK1J$Wi*kkf3JT0` z@1g$kIPT zKd9rB=YPPQhNzzB!S_Jb^OroO34G3lIeUeta8|qF^u$rL%x^@T>B3AoQ44fyVWPH0 z)^g&JdhX!%SYD=|vo4DNalmg_4s-9;p|2^!PU9e`A21fO0%7-wjUX&ha@-}-QVwlG z+b!GcIkC{?n!>AKFVRp~*D+ZCkik=WLAw!TrR-z)%wM5u{$>Z#xzUDXbem`89`YGb zCf|_R?fZIFJ4ka6=}Ck_n~0};96RVi9gIDBJ;s-HrQGG@t#YV``W44dI9<)H4(hMz z#_nzA5Yr@qxIO_u}#F{@P{T$0YBW?BSa--Y0{I z8TIvJFlN;8`G7|q_|$s%i@sgAR=YsIHfjbrh;rjYKDznHOmYzSnmJ&uDwbq8@?EZN z1o-*2nVebc=f3+H?7nsa-#DJy31L9zCxB*(qbS~#@pGI)GoJkolx{{lc!#Uoel>-5 z2-toP#PM#rMmPzJ<^LD~^fZ&SY@bQG(Nj6|2ZR0aXvV_^%9}8!xQVgp_G4If!*69!wfySSC;@9F}`K|NP_^ajlP*}L+nwlnLnwlj8ZC9f^bf0;Ae zggA?>%eCFb_iY{szFnn@&Wa13T#0DJbi)&&3@IAE@LKp}5P}k!=Vs`T!_@^nknJiTbse zAB@s#M6(TO0O?g)k~y-(Tk zf1Rhf|JU=L-2c7*iTwW6?KB6!63_eup53~i`Bz<2cUM#b%$U2s4Q&es?*M?e9O@2+ z|5ztkNA={FB+PHj@J$uYkeBctQ#=>0#OW$f4(k~n4JteuRCv^T@VM3sj~Q+}IwN*T-`=!Xto7qyap0ujtJD zOe&LbOg*)i-^W`fq}gOTG!^Bp!V+J6aMX8q1~fvKOoeHQJyj0iS5S{ zKlbZOH}3>FGh8>-loJVdS^P_(JHLcE3$N9S+w1iQuepbl`$hZJpH14v;vtXM>%~D( z7V5N|2KhY$^eFb(=`wV)8#eSXhC^+hF+9&;KH*beq3{vmoI2^`-0mU?2{P| z=dv+iA4=O3p}xG%-GhDJOG6?Q|5%}?QBcPV<^&>ErSs-o(4(hE^JbJm6+QSPsIyQG zA}Tqt)9_xu(;bR*vC*yT^@Aryg+qxMyxGP;bUFRR8Aw zk;;z0;P`iI#NQ%q4Ga+PLE3uv{Jw7f2OeK{HP+7z6ctz=V?L9cuAt2uk*?5c`0?mAgSB;yM!cb1(D1%DN2QbOF{WUPA95 zlk-eKxx6}^S1hRj;RTx7s`sYbJb3@;OqxF`=TADb!2IgTP~W7I6L&$m{OX%`<};m> zyPJrpcNSKA>mBp7p7jnV@0s%G*S0QtXStfz*8x6sKINKmUcm>g=%QylWE=s^X7w|` zGZLP4>{+ef9-h`+zm4&O#|y=TeiL=+F`?kr^T&kZqI!-AX%zj>U{zu&N}uYOO3Uf) z@_tw|wLP{qd&lB_JnhX#(On*$_UA5|mq>XgY8=BHgfMyE)~Vd>#2xGk)<~FtYo@j` zedYjiDziLF{87+Y>VgQ~J190JapJKoBL0AD|9Br`m?^#ASFFCEIoS0G#@)lD1X7tk zSdIbF{Y|w)P3f3Z3-`s>?%~DkF&eXSM__G|NxoOrwg>Y`@nRNyv(3RAQe&+3i*~0q zu=|=Z514HZ-ccv#0}<=x^5Fmn4{&I#@;vo6y(w@5A*BA3%+SzX*UORo+brj&1j@{Ko; z)JLI?0e!<~`nbymWBJg2*DSp$WLPPyW0vzq(R$5LuW=Mf%|C+vV`L5PKh5IlIO>Mc zoFs&cEFG%}Ggt5trTKcg_sn-p$~lgv?>Tut{0H*=DdFz5pdaA%SiTDSL%;ZExxaYF;yvB% zOQNUi8a(hK#_VyA_)J5F71vobq1s!RF0pc2&MNdWrK7E^tV6cjz5N#1hGOmgz}D{7 z;~Z=xZxv~Pmiv>pGU30rKj!+P``x2}W-&HK?~RMHd}sHpy({lNXKhAuxIY8*AHavQ zi)aedlzdp<31Q~9RcDuRU(h}o&Pe&UuMEun*0m)MWX1jPN51YO<|RalixXnpdw*vh z@q;sV&*FAyH$gz0jkZ3Z&$8yFfZTw7aXdWHSnn^&u+EICOy@!Zta(d}Rt>>iNtIyb z2v#0o7c`ueN8CnvaJt?fPFa61xN)k2C76C&X~$Rw!jfUl(;KY?1L=LI${g~9vx3}B z*9|64O$hX<^YppcU!Sbqc}kyP!{PcA>d5$Xnx}C_A7;xKs4X)O+L;l{-bK-O580_r z`(_4jUKj}W3(5-cVSQy-9kazbz4v~(d+naMhY}-_;eftvcos*G=b^Nvku3`j4^Jc_ z%CGG+NsAe631}1VUIKl#%~Ukqf$)q6cpRuV4c*rTil{$9x zTRXGyF^=Q|^P`#6zFAaYptcXQnJ<&)juUTnUShwOd-@Ic=~r2Q?AuA(PIXcqNIpmD z*~aXPcn$4O8-V#{i0B)SROUr{FV!oUOI+Un*W!t9;n+|ouek9d=QzN7j(=!T%`uCY z$+WG5xqX`E+1H)xo@c)n`axR<$3SF1wR@i#3};Hr5BsTt{*I5L{wLPW=yJK&K)b?X z9p@hAq%*U4$)VaWq0n4@5ZU&qf!=}HzK7cyd7Ex6(ww;-&sjt^n*zv`GWcEwG*=9~ zfNKwbf_jcXBAyZYTE;zRblf1s$ZHP$c5y4yII?}Z5ZAl`;Ky&N0?*bGqU5y%D08S- zs6490wTLI8WUO8CM)^LT>9VJ2JU>etNXZ;IcI^MHFW{LP`VE~w1moj$ZD%Ovm<_xO=XH^VscK^B5NMZc%8 z?^n?8W7s$^NVCD-G&`cjzg(JOVD0N^`&VKAKnHks6VG1tB&$&O6@!ezvy12(6oOr! zh;oak?ZiPlZEQWFo7`ga+NXue+5>6eOJ;InCdgcj54ut*UtY9a>E)3tou|CzikEK* zecaeq$o*&70c^i{`qw@`N99@xp$4K)F)|~QBb2t}|Wzw8= zowJy3Vfy{~Qxr~ZNTy>Pt~>XD$EUlLa#=mDV?P3A@(rWAeOIslgRdg{>lZyAI?sH} z^h0YnrU%br{DO$zbx<0cf5w}})VlS)b-Y(x;bs^=$^zwi{HaUSu^JD2*PrsQV~?Go zF|39&RL9b)qb*mydQ7`|PcV zVS6j0-FquynmgFu3a4ssMFQCRlcsUz!ROgqk)YaJvEygD23wWVT^1wlW0^O9_Q<8$ z9{50+FZG@at~Z;nSszur^0Uu=j9DMK_h}(+Hvqj=ZXn{Vz!#BBMpXjdUx(-3>^UKe zh#h_CzKzrJzKt07zK!`Iyt%_?--gomHB7$!+1Z`fe0AKTFxDAS>|G!F?%|)Q-j(%U z>_zB3(BFA}^xnNcGrc#!kKT)=xSoQz9>|G*N4;0XiHk?U{~KAXInxts&cm`#XA;5qGn7$X-sLvji&nJo(4 zKZ*0kiD8%O9}QB*mFcKC>Am)%j_VddyFos&-X9$5cq1pCa&#}V+ev+^kI&FKJ>=+F zF9rIH`}LEw?r+Xq;+Q@wbkpFAC;jWAml<4rnLgUAz%~7SNlj}CY~MfN4V&pCT`M=C zt`9Tipj?dxI>WvBQMH`dQO_NGp%=!Wqi78Jith1XMGii6@}HnbW@~p%-&1k#NfkZ9 zvwEB}**G`1(HuDVKAN2^odxg#oGnLG@oc5utqd=}b9ihww;ut1f+l&)8PrSvj4%7! zlO7uleG&A{6kjCeB=yZMh3DT}abcd1_-Ame;(5)<^Yi@i^YHwAY;7Ri;aLm3C|_;> z?f=*b)jk=v?t!!v&yiGLJ#+NLMfz$!XD;`h@NYLO^dIj-|CJ{wT?JpNyvgwBhc{37 z=gsX7+IFjh(%{D(?98E-%DVL@=vhkq{mKd42f|qrHB^V;UZ6iQd||%h#HY1u<@eC% zD)wISkzc@e7;P?t-}0HMVenl#c_<9m? zHlEc;Fa{BG7%6Qv4dvu>{>OXB>r@*=q%59n$9AzjrS0rO+U{{^?7mBM)Eq-HtQa6Sm_V(x)uT&##~$YT~b248@5oQ)UT-0jn*j7uR< zLR^-xdHedv*E)Uk;FLfQQrYXD%aV%uONRr-JusjxstiHxJFTd7sqz)V&halj|dIl7LJr z-?uVd=xwytE(#E9gF>wwmtnPS6vX;ROz92b!Pe98yG{tPCOi>nwmsp=fswl;(`tLu z=$yISXnkO1hPCx6qmvkD{2TA|!Ms-WVZ?eYoU`sY?kY0{f?Rwq!&)C*nQnu*YX~=5 zj|EqzqwI>1bKopW<4lXwc+<0K+Tp}0m`rIJQ(;cXY2(cb`sSaeg za6pw~1L{v}qdv*}c4f`h2d*Hz2hKlCT7*fUFty0%QYcKL0VeA67@gpYY@>PN>0V6y zt?VJi?fWgG`tUM6VIy>D}AmnUzeI@fZdJVqj3&c>Rqj1}|2vE0GRcyX+? z8;RsQ*8N93_-{EDY9;}6tU4HLYtX-Mf33aQdw=aoc&-hidKI6Wnw9nbaiAB+y7RhS z2!DkPe-*0z!`FAwzD9S^KF0Kb&;6}5&!LU&*=cN3(atbjL-o*)vKHxD2s9L=q9M!^ z25me6c%^qS({;s{z6CrZZNs;%KLT#?uDf9#xptv(P54|z-_XVe24iKLfBNoezHd{_ z_dgnRZhm|I$4le4L7#i`+cONFmlb$W?@bC+;R|r(BAA=UgR4B6)AmY$sVNzr#b!jwm0;?*!g{ks@UPn>rid!EBUgliFn>(5W>%n1UWzf6D&*ZW)P z{<@Z3@>y7;vzYDEHukVj+r4fG^nXpWvW|Lbbg-A@IKzG2ZlAQ1(z80AfN=I@!9R{%n&cf80zxw1@fHcJ=qlAIF1kbGOIp z<@>g$rSE@&_R3Z5VSGq#v#?*cHg)|}aI*S2?MD-@<7UWc{n%%e=Cr4a0aR-g~O3&d2Uv2w&{ zErkDtMFCc9zcxz{V?ck{7E<{+1IjnT`@*GTtS0{Rw4}n_X_po50sXr)EwS*Ew3$Vv zX#)#CO{)##tOB$gNUt(UP=9 zMOoGvMbD+-x!?i|k@AX))9PNxu;vz(q+#Co8AV0VPNp@lXi-{jQ6coV82WlP4f9OM zxu-#bcii+RwSV-xZKWbDYX^w}*&(UV*tw z%97^}eL2-x^i*{o(AsdYyHs=c(P=t&bpn~;an9~TcFYMRJ0C0p`-kEsH4*Uq4dA))sOuEN^8p#psRj{k^4f4yI_A7L15Urd zwRkorrGAFfgV%w8SM@j*oUURxy}nho*NvTZTb)3*Y`>A_nL|B{G0)_)1~Z=L)`ASf zeV!(Emiliq4d#LDTO;nNW&1Ui^WG(LE-Vs(?O-0|Xef(&N@SS`buhO($g%?<%U0a) zd&WD7p7DNB$#=#2TnBvyKs&XauI-AP`Ki%WMl|%?cO=LmY`>hH`&R0SGx6MagyqZ` zgZb`9=(+Dk*=`|D(-M(cUOLHC8E!vfacZzmR&5{7;*8Dz1 zK63}S^E%Hx>RrSC-M90YkZ34Xq08oB3^v;&nSDcW!b}d=fOzDe1M%#O_G!x zfUTg{O$Kinw9yVSh;S_#0b~m5j#@#mngW6MlW@;mhE)JPQiRXX3DyRX^$h}N#eOjd zZBl=|*%VlrUYAsv-nh}YbLlmiJ8D-gN-N}ft7+axX@&Flq&416c9zV`bTqvku%iy@ zF12Sm@IF#mHle(_+qkpo?J+x07u2rWlU4w-YBtC!)DyXV7Nx1>)jmaDMXKag8|Z~W zddXw}7y+*QpLOO6CbLmyDfQQPc;r>P4fTLGZWNjIJ3EzGp{G^;i|-w2{_^z*ocQ*E zP&3~DtK5TP8$@$pQ(aE)9O;^VlUq)9d^=id8)|eu0X+MqI}c5yWk13P@EF}WJR&Vw zJC*%U@s`Goc$Zp~1@~$XckdUZcU$ap8qAF_H#q*bXyUw6Zov5a)O;*ZI}Uj=9M4sRSTiJ)(Yrfc zQ%asSI`q)iRlB&Ap}l6_@z-Fyd++k#wavIUJ%fm|6Nyxy!#Vc8kK^3KV?b7b4rX_9 zV0<{?yhpy&$b1%^E-nmxDa`7ii`4zxGTk zzyFoe%70R}+;JXS;ePt%WQ*ZEwDO;nEm`NGm-M%@3jkbaaw>`_hmmB-h!tJ=3@@aHbI+$Fb@`DEYfb$TL*AqoOQbp zQ=^5xy$CJ3}1;`PJj+}v1( z*Zi|UXDMXvOz;me_hlXKrFiPG`Iv7K@!;G4z;k#uGu%SY6h&GdKg5|I)f=7Py6=w* zx6D06&v^Ok&(`6Z@&h}YDc>8&;F5yrop)%rNi}#eN&+J_*?-l0cGmXl9e7OFJ{96!4VGB+$x~q1^^(7w_n62Hz*CH!)+J$@jiG8@u-p9et4sj*N)!Ki`gfN01-GIS=0ub{z@vMLF?w|16Vdm=JtmtD8_b#V8P$04bQp1>4=Uq4Em|(K z8_H~8W$=4uLV}DlTvJJ}rfZqcS7UxZ)g2z^kwduO#UTh51)m86$rQ|epREBNP9Q6; z1)RP-!stu^ycWW9;z* z6hr@bpJ5E>mcjDb%b4b$;&|!!n?%}Upmdi(qDwmfX1oIt&tZPlW-u3nEYd=Ikx&oE zf_Q7r%aD!(?IQkuip!KP28Z>aZ!ZRC`Hyh7#XmsiVq8}uq*qfx{>WsV9^eYKByjOZ zI)q;G9dHXv$=vnPWJ-r%koTl^2)*Upq#bN6sRQVMm;Y-lG=~$68R#^b$tlo7PwEP; zoxfdA#3O(k99sv_hfN5yn1OE)Zxvz2l@{0N!z1!%j~t$#KT^h9BxxBRNZWumO9MEv zGrBiPjffVz@03SpKX!RClP$e9tBh(E+*GoEJ+ zGdl6?EaGc4!=I7i^Hzpq#1Y~OafY}<93n1%23d)?Jt6eB92ep&pQ_H~wy`~e!ft+(mfm}4vYQ1EV<2fGPgy-WGxoSN?;0_({;y}>5!Wa$$q&(DW_f~qH^z}ql(lRAplulG z?3xt>a#0Io(}7&n5a6q9U2rMx2QUI(;XS}8H# z+iP8(Q}VoZUNE)yQ{{37GTf`|2wJw}mgPCp8=L3heROyS9q2mQN2oH;a}ZoOnS%Rl zL9evvZZAHX(mDF@^pABdiz3LB2a`(=?d$cry*d8noPFreSl0s_kH?X1T7a`2 z^MNSy*c;|C1@sNzUCwQAqOX|38Fwc4Hl_}Vz}zfcsUBpV4rJXNXyY23Tj*B@b2tj- zaF32mnFDiJ19R8}b65j&h_av&=FkFjxC!Pk1m^G|n8W2Thd+Z4a0=$I1!Lq3YSwCD z4#~$MaU9HH;?tpVi7qKa0DR0U_ z|Kuu=9S`n!!f2 zXs4tg1$>rZ3&Mf<@WGy&k_~*1eo8a$6Dvp=iT-E_^o3>OS$}h&zhLOE8T!*h`G*~WioV${pM_@DA@a|2w?HeN09z z&0Sny&6z8muI;V?WFDTmQqN%}=ij$#osn&zh_Lg&deD3+?sb`|~sy^y|W(LnPUuVkPsrb;S zOGfmHDn)%#u4Vd!@t2E_XjW()b0(lp!TiE*nh#RZe6TmoYk}sEoP7Fl8Nh-2H!2vd zM8kJU)|GVs;p$8x{`p7Fd?b?`94E&jBP~XOY<~y$F7&6mvK({(>ORHaU+>nBP?q7; zhP2Y3%&YaGi(KXp)cVMS*{a+#%9$L+4_Cia%Yw^4qq5+ysyR(y{ePhH&*K<9)U!K~ z&*#s!%Q(wno(SI^PNyP%b@5AYRjU& zxY~|(dUWYmfusdt&)}(zkM=qV@yObXvDejcq`Lt&w7u5Ac%K>)FP;NfFm8u2J00L7 z1->OO(8nbME(WiUjl(;b^PkF}?}RpREH*)xQX=%Vpxzwpj@k9C(Q;86sRT`AhJVJJ@*2oi6uyFfImmU@FepJ5V0={74wj<1A(e`dW_J-Q|wi<W3XMWr#W`{Ck(S9l~>b>4;Eeqhiyid{({akm_wSApWJ9Ak(FMG+O zXv-Y-ekq>w@|7Jg-Mmvj75S8tWe3WTuLAXJWqb4z<4x!M5m*aAuFfU~Z$)hc}9c{RlU z_#j#rVZ{0vPo?KEymRiK{T=VNqrTcl$9Kv-z8K3Pc*g}(9q*;PDidYh)z_Wp%m3Ib z+1SH17!US8_W7!@m!Eg+;a+3^{*0?k_O)`1QiaOiQICIjCdC2nA5rjd@C@#0@!$bz zLAifG!G)RO;)DtpFECtu-2*O;>^?s({+)F2@|k~)4t_JvLkG9}p@Um5KnGs=a7K@cuZD zJ)z(Pb?l|!q*izFIEnGWNp6rgP859Pvpu;PAUnaP*rL5QMjQ`*;Xd$fmc1p2w%3VN zjQI@U+wqOOgk`c9#E3Nn*WDt;x+IFSqdQ*^E2NCC(bk3~U2xvFR=LDH;aK1jk zpIU)^*x-NmjCe5^0Bb;$zxTu@4)@!~()0A8%-hBqI&ZsG^Y%&&owql7n73oQ{&PIM z$@#DG@ZrInn}_eO>CVH`YtGNZuU%m5M1N^xHwIn&*dO#6JMzCWcC4r5`9ymHWB+KY zuJVbM7HGUVN+{F8hix-ZEjl^TIMAgyHuq6@G&le)p(+Q@)1U2S{ovNg%5Dj$HGrlpDx<>uUa$8#@0s^(Fl1iu_w)Gu!2@`|&-*N|=j-)4uXE1p^*XzX zpVhv~FF!92jv3zZ^igf4s$b-vWYfsM{Q8l9^_tdeuYbS0{-j<~{BYXb4cS?9D>y}A zgsjJGMK4kv=})rn>Ph#M712bCHvWpmTvipVO)z)%M2_y&;evkRcT zh0urS_Q#LLLLXzQRsC>%J?r6Fa}~JHIv9Phl`*q2hs<3OL$VTK&I|P>)diKLS3SHN zk~vb?Z=HnqY`|Ji+!M_g&nlrz6s$AFbFRPr8Ys!pYkx;5-Mgax#?jE1Xy`}u!_UtR zg??ZRi86EKTvu&XUbWwQZQf7Ucr}uB$l3jr-`0}{=p}wT)dAmKA;6{yP&t;*H=({uABj25|(6`@v z&!tS*^PqfbzvmLHza;FrgcQCH<0%6fIOapgW7~5Hw)!IB-DG`W9Js$>k^zqaPM++! zNZTLeAQ!hWxv<}J3D)1TpZX}(N#rGp$;%UxviZClT!($#LyrH(-P z8t>nBE>$6;XHqYP6P@%-DpGPLh38Rt7F8_h$sql$x5;!+S2>X zxOeDXMfVP0lIRdpW!ondW#!7}R92ED-(UQk*7*uuFHj#7$vIN|F6JZbLbgWkx^a5t z>V<1tOYpI_wM6;n&U$72=bh`7OFM7e{?pD2p6@^LE&g_E&9xW0UTbE3?!5o>)aSPS zCs*{?)CE0?18w^C0??zi3;l|=N!R){SfEGt1_}sUT$B9G z3@G=ALO8$hm-q`|J7LUcXcatL4ecaCyO_gtw=A?#4K|55#`F%GFOc`=)EDSiD_*c( zV9$0*o}sR|ypPkN|BkCM7qwZ+4@kKBAz=-_~5QC_#myD z`}68IF@rZN8;}lN`d*`xXKlb4cV>hy~3x4sw)ZSAud(Uy~kqJbLq_`?izoLNkASr6BD4jI9<)R3{K!rfUcKwOPAHK zbyp44h4+-%?%$z4ooBv7xv|~b;vqxT>G4JyJXJk{h70# z3Ft!3Qo0!b_0+N9jxyFw9eY_a_M>~9$Nt6M&UI`^7h~7>bq{;=Rq+)2ADXS$kFl=p zyg-9u^py@b}A_fT4YCZY9)J(Sk& zbWYp08>eq~HC>y&-8{mkZ(rQwtZ$#))49Igb_2(r)8*KM^_|VLds}V$UZY)%eOMP` zf9VE}U44zXYk#oeZmx75duwIqV;|ea*lYZ{IreV&7I6+^CoHae78`#o`@U4r;m`)G zUli>p6sTi{T%S3Y#!8LpcTIC{5yRoIME5MIbe?nHVAzyN=G=lxyE%9LATc(O;q~QK z$+^cIAKu-$M@?imZQ}u++eb^!+n;-+^>u9<;a+{wgKB;OjOV~AHNRU%n#^G#-z&M|;VLs>^sY$*(Q_f$=@#4ScNcnP@GsM^*JTJ!mf3w5> zJI4Nq-?a83Wd&@{|AjD8CZ2J;3w4+GPB5d7H=b8i9k+Z%eykAADlXu;g`60^*#+ye z9;9r@IK?!i*(G*vf#)OHel(Ya3C8m&{Ee~j<1lt5n4XX9gKx$1nC~t!5bEK`DCzk{ zn!oM*BAlIH;JL#K*7a48u)Z2~-aZxweefL5J?vt2B=7sO_a*FHgn$ga6H0V7DpGFu zjSu~%co5Nw{So7P?(9u;X-ZNq#XOSP!&tT-^UpTLs?8=mL&rOvy(!HzFIjAHOTFC3 zExqJGui}fA@|&!&S)uyM3VJ?c^T7+%?_|$DlRVqXo*kB)g>0&z^609+C6_JbDoHyf z?E7W#J>p&<=|9c_Q+vzYbi50bv)K5jt;je8p_ zd7jVubV{N-Uag?IBS=y%o0YRWFP5D77`Ir@e4O;kwkx%ya!c_#D;WMN+$?xBK<2JHMIR{)h7b%?xn% znejS(WAXs~eCo#K0ear(oCj!*(epe&HP@U6C`3QaNaZI((uez5AD(jXgPF+stCf^Z zVr74l$lsrgRQ{6O$lB|h#XV}wo9hq#3xIwGLVtUJtn~z0>t#E`yt8|(hQ-#9gemV`iOid+Dg;B_=`E-{C8k0 zg>e$UkRh~PM_UQo6~CDq1#`47!JHH3k+*`al#jOWD;qIyoDS+g_OsgAUh-9&FXqVk zntWo|`zfbWM^JmIeh;S|0k|Oj+JKgqfR>NKn9KhdrX7iO!ua0vw%JX^gTZcsx;8-_ zVtK)CilBB=Hro7R{6aWM86u~1LVp-Tv>)p5KKfgG+S^U_XDvli+#;D@t7ro#;k(N~ zpY34dwL`f!6{QdQqtvr=Wb}o_{B=lcq&d>N7HIZRPwJBs+&=NB`9)v;a*l#Gzo>-Y zD*mBfjE;{Ivl-|%4*h2O(>p`6c2K{WT)}T<0=0{_N&IGf(JoT(H4$hRh3X%N@T@%UXaznRv8J= z=Q{L(yDFZ2_tD?8+qO53|JTaHh4$3&JRF{%uWi zbDNL@N|P+bd*ykt4`G5mb`#WNQVIEmoOqxQ)MFC$qz~m2oYzpcO40WU+HAmFA})BO z&pAu^3KrKc^?yR2BGLZ|{kK%i2MX_OszTd3h}qU4qmzC{+d7f*&}l~=0-5yF2=e*U zc6*u9oVJt?w%WX5`o>+<vA)1P-yn%*MuhpJ`e_A%QS_!(Vl2*=N$xU0UQd<5*yx=G*14pc`z1A< zo=e!<$>nDp&VJpTN!Z!a-mY`yMZwskM$4@^?WDQ#h6fUQzZB>xS2^y2Ih#+8M$Y_X zB)BgWY--%68xQnBUztR{!w=)C?9Wc`V_1AC!FM8ic2pwENeo9@3~jLfPrIlOOD&!M zov?bntc!i~pzirCrSlPu;WLLS0BkqgNo z%N=u{Z1JJ>4$er@idO9QHW!TB-wYd+*pbStZ__Dm?JVo@H4c=F$p=RW^Mi8 zi0bvy=7tBpYhKWicvL^|baV782bLEKF-?g_W2*g@$3mZln5JyIm?k}oX=tz zkm@?7DZ19BxSZFOW=qk3V_u)W!+Bm$-r+p2-?zhgUZ1$5^LhQvjh^L+@D!)c^F-L= z^cM%5F#Z775j683}#7ci8eoxT3|q8*i-c?A73~ zw-G?;QQ$xiF{fZD)19+GcOC%Uc>r|h9Wbu*pgV=Uf}lJ7KzBX`x)by9eF1vm9O#4f zpgU<^!2>L>pdZUC=+E*B1_*ftD;`dtYs^lYTgPEu!JaPj3W~Y;MBUlle0``lo$~b! zw$Imxx^pDU*Y{g==kXJs>CPDFiM2?ir6k=|I_4y|E^I><+?Yf#% zM{IXKx4Uz@^SNE@cH7#{6^)qcLYom*?8@d>K>$)2^_U+d=_LW-Oy8Jm8V}GWLv6rv&EWTRP%^VLkp`Op}*}vG& z?ZrXeJ3Ev58KDj0?(9tJXLOPI89gb@d)lj$vorS1^L{ozqtIUVen!Xa{fyoc{fsU$ zKco9LbLd}V=Vx@0`5ECk*}o;{WRZc?zev5A`paAt{biK&oXlGJhp%|vG zxzl0)&wdTh$0g^n-pKqo7dO~6s zRI+D>T%0|q-JU%-$6iZw0ZYfsb=dYMKiTRSs}iDL#h#@(#Av^_m7Y6fO5=aFQrWsk zQg#XZ{u$|cwdCC4`?XZwT*=~*wO!2d-Hd}t>qZ>RyFWYRS#gYk$&(4+b9f&Eo{4>< z1m1G?(G7UQrjMpFTKp=Z*KdECJ&?o}DDbPTs$2-r&vD^91c~QSD z>DbX{s}7!>gg%KhD1os*{Im1kpwUSWQ{UuTw$HNk7qo3?K2X6XamWeUbE{*#U8vq~ zE8R18H}>Q%@V}n(P@kW#Z5}!$!M%Em^E`BDOXu@YkT~`yckrF<_k;*z_tGQ(V~%C% zSvih>o8+t<;~0iGj6cRY{t$LYN2p%mOU8V6+ETPx=9~xJHh#L6ImzgNymaui3;XuT zy%IhM)i2)Sm1*SIzn`+{!l^F!U~(6HpzUJp*K?gS z{q%41Pkj2e|Bip+mCerUoQs>C*Evm_oz^*au>hlQAb)k7x;Flrs<7D)TQ)oM*T&6u z{PmUN*v)HhTi|996<)!2>v zO4+9zY>#WmuT*>u`IY`ESqr3fGr!Viu*-S8x8B42N`%?>O&h46SiCg9(rNekl} zwFmcpXk6r1!ujYSANw^y_$m9CgUC+q|M-V5=``2UBW6qamlAvD%W~&jO9#rSZxPOY z*E84B`f{5cF16$J<f5&VDGp zaXNS9$!pWOk4W|y9w~R$xqm6|T<5-b1IIq&8prPP*70`G4LZ5+koBCwy- zf0y3(wd=b;-AY+#;V5Ds7m>^2BB~tYBEGkei?}F>i`dWNA~28EW+5&C&wfIMxCm^Q z#zoL}i=kc2|A}o|W{{>_78ilv{&Uug*0>1#4(WM<#VNea;v!Bs#YOzn8W-W%K8=eA zW@k^K`a6Ih-?p=vgZ0s6)c3$udtzKffg~=%K0nw5Nq#WT;vxdd9OEK_^$OMp8W&;f zuZ;CqD=FK)iI$bdMYL_AayH(LoQ>1pIGyY5C|ljsxmzVM?z=WQ>)dUdI@h_Ri?Lr% zpU{1^|Jy#H2fw$E4_H?F+kHZ}I@C44)-#{bNt7p7#Ew)OND>G2OMnme)#rwv9deMuJD#28zd4iQZnff$HsAHyB;~wH5>oVULT(~5bA7824kHZx=NWTjuBnu|EL>bPZnqPm|} z&e43&GK?quy0`Wuw5<^TKi^wB6W)7?{~LR2SF^rV{M7Yc%4>|)$0V5KFia}l=&yYr zcagKZoAaxt8}sX;pB!>J$!tD>=>O*`r&o>#bVy`$klv#h&*<>I8#=t!1s$%ZoiX{R zYs+c&L7h$BV zWam0NpAjb-czxV;4u}y%Z4P@#%_|ki1DqcH#!k4%Q&oJEC;nqJj{^FS-71+kHG@0z zAEVzqFK7N^U~g<5L~}1#{l_GE7fK{~s>HktPn2>xu&=Cn7oNi@V1;Z@0yMUm*8K zOObSb#(OLs=jR`RhVT26vLE32w}3zHH{v`k?u+0)3hoa`WAkxOWK;mPYr?@UX`AEA zx92GMwmC}pt>Q-o0)2gGUV=8DZv>vZh2i)@^e>iD+ap7opW)^NH~ASt^s}+NA1Rv{ zL3&H&C(`lW125M!8TErbP2wDAf_8|>YKMgC`!YKOY4h_oPG<}t<(D1>+W3;Pwy|pS zBeQ0E0{LgZr*hEGk;Wy&Sq{ z^37VhXW|kcsHaMjJ3-vzk>*Z7UmBPAHCxJ4BWUgfJKrw3&1MsGC+ugr6AHZTb0=ih zdyqQ;`29`2gP*0zQr=gRFYLXw)V7n_Oht^Q<0LlV5>{@Xu&;}@o9ny?u5uzoowV(d zY1UFb80=ury|k9vbKgpG9lXHG)^^sq? z_D}zzKD86&_CB?fq&~H7)<8!kHhi0b+VH0(&sx~CqY~d)>l$3y zdJlb$q|IZj&3ehRYWD0ki)()DBl2TD-S-pk6bK@?AJ6GCB|2ZY?*QzFVBodVj`2s4 z-xNPs-oiL-+}pxjR)Zblyw16a@e<>+H@tda`FV^R>6mhKL!}>!&-Q2W*#Sa)HhDO0 zZZ9D|TPeh6M?1u4V|>@{#az=GcE=>fK;i#qIs3RSeTOZs3uC(Q9B|4ve#`x`XAALM zXP{3P zv0l=gXuGQebtsFNn+)Yu%Bz#S#IvpOlAK?6+x8Rf?n0ov@DSq#$NTM)4K%M;jf5ZW zlklprAJz}+2h0I$j8i5(HOWy>w!mm9iUb{?fd6rvsAFQ`xj*QYvnN5GRujHHLdYjQ zrg0O;pA94C{24^cVJ!6C{#vk+v~^JasmoB0oRpjLsSTVCG*y=c=z@WcLfINxHj%@< ztYH0wla?a11*GMNLwQ`=o2bL2fYz4~}`d z5!X3%KUUn&G6e~_Y=u2Cw3AI?_Ho!Np-u5@f-~68C!ON5^Nn$)9w37oacKE<_XSF}k}bwZna`w3&HbJ#0wJl!>I-f=-2 ztaD}}&?bY{I|yig< z-)*QHWsE<$G|BLD(Rc&it5cIN*Vgzd4RzBr@h5|P4L^q|3A-D6r)@($om{VuO6)vf1XG zqxCsG_{P{k`02^l=k($y$-u^hAHi;0iuzct{r5arpLvn8^`CG$HTs47hVa-%ZIZXP zZl<^Pz82b!Q3icl3iCh*U=M3Jg_mSL7-x^Yjiy2RS4wSpJRNzV1$Y7Z>Ze{*x3^B6 z4(p2tdBB;@1upEbtt$g{zA(4JySHRQod2!b#I&1)y_5|r>D<7J&?nx8{Nnu&Kqm`Tjg*;tFs)gJdU~y%B77E%E_SpmWJymhdo`$p`Sz! zqx+ERarcp?610234pU){hcV&WLPC1po0&O!w$i^ajf*&@AnI+fF3VQk@ka8jrwq>) z8WtrhIMw86&Tq1UQ^rhGlHpiJ1!Xb=-$;(WckQ#Ki?EDx@+4Mf4YU!#k*o~dujUqo z<6X|=$GJyqq5r};F}881daM4K#mQ5CElk!!9kFk$c~;sE&}T$5^c%{Wm67T(3)d_< za^Ma_^Q<+8nj2!zHltk&V!po-1vhedcg;=@)04v5mq&O>&{o zmP!x*>#0RJ7#)&TaGQ`ERjvfQr#JIEQo}?Oi8)MAI^(9R$VD}Eeyp6{# z=M@XWwRle82Uv;c1iAk9bAa-u#E72+9cir^l61R3M;J;)88=A(&ExD5D=rTFaHfon|raoDiow0~vTe7%ohgLYpjF?UR- zwx27xS{CIjS0%HrO|Jfu`P<|Q?U;_~5AyA$u&!mcOjmNXzcZY=k}J7Qu5y`NWzOzg zrlP=}!}Ho2-$`H}gWVi7!GPt`=6M-vl|v;P0Cd*Zhe#T;bUtU~I)Q7~51T zcg6G6hE;(ecN2i7s{zNs_Ba;9xL4-o#;wZBi>t{1Oh@6~5MY|r4PBX}@Jv?@wqY85 zExPjPM0;Jin(E3H(DgO>`{Gb`JJpqgCAxB`Ci&Mxu65-PpMtJ*F*Yf7a~XE$Kl4mi zZi#f(m7mS}?Yi>0jQ@_V{4V16)s+Rau3c9?_i5+4vKPZMF;j%|Ja#ej+UBv z=@Q-d-gd;#d5lusH-=%jVXtTMH8;XpzUF2AcKI6qX)r}H zR#$SBaK$D+aoe5c2iwc>A-qB&XLx3Fmy5DeS^H8&ahlK>P7*l_bRlQ`uTjqSKjB`^ z(mRzi2duh~v62D5uZ;ba(S@zZF$VUsbCsX$FUciARWpKt37C!&3v;q>Dk7j|I2 zuUk8C)j(%EaDB#aw*&w7#Ba0%^L@K*2R?8uI?;_Cn3eGx?7(PE@>2&~+kp=QZmz~A z#qOe#V)u+I?DqJ&-0v7Z&{@tBGpF&pzf^QX3)TXO| zc`Xq7XBtGb^-zXzK#zQ!3*`ch>Y@Icv6^^nAen^-rEgKAG$%9zIn+R(}BMO zrb-VmeaQu;sScRFub`NQbQ4q47SAzV!MVru+b#B(e*1*yn4X+@V=xVOfhqsQwPUK= z(lw^uE--EIwa0V_!?d`fdze1g4NQaO?lGO=fa#2GVEW7r!t|qy&X^AW9WagX0MobT zJ7fBS1E!mNDW0K@`4RydYg<*PVclYFUMY-pguDjrVEwi}X9@E8t_Z-t@={E+`>Q-k=(|!j`r+9$r zj@O+rUFmI)=?QO&>GV!8btR`U-N5v5gL~cE*8$VM-N5wb8-(d!U0~Wc^V%^zR@OD9 z6I@_=n**k^7^Zc*#B+SW^yOYqZ*Rae$fb;KhPEU9ZFsJdsm-fZYBS<`L4xZAz_kW& zMQq>w(o&@8PkKl6B3Uaj4}=GpZB4UbhWUfKOZ)Z~8|~3o3fo!K1?|(lNO|kjX)u1E z>B|rBKo5bY%MAfKoAt2Ft?b5>*~@OsOwVO^WZI39-KSfeW%ufgYnR<$Hgzq# z54pfJ-T~8>8Kx~eyQh!$ZSow`=Q^>Q$~W0#T0X;bOe<1v45n?(&X~^s9WZ^?158im zJ7ZcUx5w0nVfre=wEgAn{M9)efB8un-K zbZ?-JbXZ1U?3=ZJ9QLojUH=LO6YW*t=}hQj4D@jl7rihZ#|U-ebHwcejIm?}(e9R! zCLx!})Vq0%MQck<0=gyweG~XvdBL*wm-h*|^=mNx^FIRwe|6!!GhG&}X(~FBRQj=elUHed7=wXwWK@xqDt}UraT&Q_7ifH_ zOr#-ptPcggtk0i?Ya1?G?E0LMNXtZBhI#|L?q?D9Gmz#odEUp?j~YC?lF@#wl-c^x z3v-*YexR;mo=E>37mgTFHZ z6Whf4{8<^GRa0(@B_#v;IPF z%LyATVW@+USMl3)_<6Vo0p1jHO@JK`tfzde&`*Qs#Zbp%@EhyGe2st!FTS6G&tZH$ zU3@#9eS1Haf&NZ~-@Xptk7f1V-2?SruwK1`NX9?`jrq)R}cg5kZ*2*_W_h{oIj-nw&e}$6#TV@XYTy1V!An;%BVi2m z&uoHs1+S(mFa{@W(3~T=Pei9e*SNFC7B9 zqZz-6Wt1_RWDaZ%X_=uLZ0)-1TV18Co+|j3JN=SfI|ErAkrrEjltZ1{3TEZjw|CC} zA&eF$VSMsXb%yp&*yFLT7E}YQ2Koc<8b61S94-6`wnqEx)bOy z$Tp`eg*wDOoUvGnun&(*`yk@21iYJGvBP_;m3M8iYhoWVl%y;Z=Ko1@Qii%x1-8cU zDAn={Ft;PEcFTerO`xyvZUBB>;^+ky%W!Nf2Kqi3`X1BnS5*pq$29=$ zT-!VEu5;3(f{mO9bxY+K0k=sFyDMnbBh#oSjupIOMu_P+CsFE zp^jIf9hB|#c8fqaY+HQyBD|Bz))Q?Ui)9YhS95gzzIa>L@*Q8%^*s5PowST29UgS1 zgG-$t+A3%VX`s)!L7a~3ZL@L4ucI~&+G)6kLOTxEV(1r2LHmfsJB!tAXj6X=Izs_-Y9EfPj*xR3Ft_6+c^~}+d0#!o`S$;c(;1;m zn~ba8CgZfn;U^59U6hCGTR}%*TZcj30|Xic={2n0P>{)gf=&w25bd!%Qmy)m6Kviq z>>IFMg|#^5ee`2%?TKb8%P<$0f6nw@Nt;EmE7RMg^6fmX{IzsFjB?Pzu=~J|=mxTV zxlrLQz7W0XOHK#?f!&-Uv*s`e)*pp=9rvodt0=C;Zj;@Dq5#)quF;7ogCDCr~pz=0qtMeNAKOZS|X)?B6 z@2N=^?J$3VXQ{3G0JFVr-RiK%prEt`Jy3@Ez;N9Y0`uZ0gU@2-tegoba!m%|Id|SchMC^~acTjJz-#aidI}`I#h-+G`^Mt`RFG%&M zB9iK5?5{grrSP}cRYXDg{s5~J?Pk%w?YWoI4CP3m7ud{3D2MB5Q4YRmu>i-nuw2aW zok-tu16%jF;Q^s6TNmpMUC(v#I~>-84r|YUdr-%1JDlf56XxAxwhGz=8JH*XxaE9w zbU!Ekm=5z;x;J2_vY+!`Lb|}bSm5P)UaXKi&x?5HkT@@j^<=Pmg#AvmNj%u^eAGbq zJH>rHv97-u?Bzqs};N6z)3^Mr=kd&8k` z7d+(uXb1k6%5TQvdtA=%iZnIuHKA+{FX-)_?+Zfh`CikT(%m2WSHSF#f==v@0tfp; z!|ac%Yp5<1`?UM2Yn~VR&$3Ih=Mq5UDTI9%nvtMGdUXFVVI=mKZ2$DvFt>TM`9 z`wG?D`!{!O6W_DlGrLwg?>(_yoUhbw=c{{mbv-w}w7u)OG0R%UdG2$nXOa6dsn#;% z-IkGW$2s!_VeHa$O>~~N0+wI&7Hfqonx_|NmVh3~Z_iXNs#^+$WPD9&k z5T|_;e;blewma+{_Hf?Mi(J!v{BPdbHU4rdz1`#Ab63~+H*M=0f77V4~}L$Sk^&#?_4|Oy^eOOU#{ZsJWd;b8Fdus9pu$YP8)TV@@8o{<4tj2 zyO&MBiF}t=YOimR=k~5r3bxPPtC^j|?4B1(Ek)_iQk|am3_JfX#Wv;Iz&1{ozL33} zN8inccNysMU80H0U6LD@ zmzNiZboqLaOpEK<@`qQL?zS*rQ zfo_QwD*yFmqK}_1;L#WA4+lK@33#+P;&H1z9-n{8@c7(@NBfVS;gJb=IL-{rOAC0U10FK~k7GdZkQz>Vtd6VZ583t! zkiJz{E!H_E{i;acVEuf7zRrCR>AO-wUvcff1nP!1n#$`qC;HyoLFucN(svK~VRb=c z2cCcCQ)iyv{~z}>Ug-giJ5qs%_F%prUn}2BX^eCiX{;J5%6r_umiW$c~}4V6{lMv3legF7s%9OP!2B0!}O*O%kU~!=ca7$8guzuZS8hT zijnP0M*%J-h8^Y>5YPLBINDfRrjG;#I??9bnR%0k>b!?8Nahz4XN zkE>4p(pg5tb6%;8?BYAuLEl|;mXWc-{uszep0kY1X7sJv)D8MN$j8Uqo#o@|cfTKf zUFx714|R~*TYD_gySmR;E_6_gvkrQq3;JqY(3gX{p^c{UL}&i(&*=M)YoPD_F6evo z`2QAtjV}1t6@3G{pzjbD^yR;FPv5L_Z+-u2#rx5u$%-w3kk^YP?X_3I{(Q z+{1qd){y8&yI=-4M)YC8Gl6j23-C=a)CC#iF@LhrhZrhVn)s@4VlH{r=996T`2~4f zeSks)AD}B^ymXj1Lh1vwV}zHkW+u#)fNA|;HIICVcTRL90bj0yF;AV$i}y_+Mu@9O z)wS%Bp;bHUeZK;*?i*SR7}r!CWA9UfE!a^EHEw@%5={^Gfvbo}xBme~R<= z#GQ~S8?nDDWnP8^yoc=6`0R+=NmC{K-2nae_a?pkp}u<)K%a8P_yD;kdGbo44d4Qn zH_lX>7b&5xTuq$XTWwI*D7C6!1?C3Pt_dJ!_3H{lZ1#}0G>(`vYM~#({u>oWa90rIMKG`q+(+`fsDUHVH2Q zmV=)K-3hq%!{5-~(;LKlQb3oDMVV0me<*o8L#UH;dZIA`kI?u5^r08>waY>NgEaBG z=L++Jxg~<~Korni*IO;zA5ohRx;?)#?rk6R$CnxE`f1`{@L{;$M92HlC!inU+1c28 z`1+xD^LQ3=2zVeQz`yN;ETB=~h3C2KV&H?_&vMy|fDanS!JOkwQv9D!$X)?B%b?9S z0OQ4gfxo|hVE~jr3~Q;vyFj;Q+}@_jyuD2g_}!ny+2KdAngm!)Z)U zm^znph3Cs6o@{)k7v1Cek52H+WO$n76i<>)v`b+9?Ie~ zfX+2;zuu*EF^Hgv_rI`%@nqz*hj?ey=5E=K$V`(2ujw-{OGExMu+O9zFdE z1EJ1(p71>27AVKNTzoO6O*@+lT%ML&7?=4t%$M0QZLkI~t8(SeavbUkb9$#%N9t6* z{W-+l%PsEh3mEQf%(FVdy?KFq+#44#InKAqvG)a#<2<6>eL*V6GVRQNP&vNiACwPT z)?Xh!xcutx!w340|L^m`%MN^C`e!Hd-w7XNy5NKSR>}wecHjd)#s_QWP(H}IPJA%s zIeR|fV7?cyM;l4LHxBvXq`V>yvBx=oRUqYwlkmMGFWf5Oh5BKWcvt*@e1JUBFcf$} z-~)fk2hh)kp_CVtzzgFXc;OC#7nA}oG#Ci4m+(TYH{M|txI7YgAx7YZSb-P(uALXw zR}LWOrM%EqV9yJW+jxQUjf5A@7Fc;WADoiQgnQ+X7dQnyGse3Nh4~%UI=H?I`4^ktZ>5;0`!LKU^ZQ9y z`@JJz4s$%%h3~+8j(63PKhklp`3Tl809rt$zwqqWVH0`Nt@j9c8hkJgE0E6bU(2#X zw-U1va6fTGmi-3mfm@YOPQ~LqAMkZz_HH)M2O7P#>j2-LJp&32fJ+bfR`D_6RcrnD zL)o{tX#mSNs%0+b`TGF3d-;w>5i^?W&^5l!K#D`LyW`0ESqvHfQ!*v=8LO|oJ8 zuS*o$`7IJ`!R9D?2CD?79&M`ipEbUoJ?I~nAB0$<}h-mn`mH{BY**Ua}eaDcPl@bLoXdGPlc=%>cJ z!tgX;9vJLb7yxzoYZTf5z<)O2W(1r|J|cWY?xMJbpwH3PpK_O%3mx!hpbcR9^8Gx} zsuLaHT+S8t8WDRo=CjYc$Nq&*uz$t{_65xpd+%0z?58s9H#|+T|L0nXet%NMx25{= zRvi!PHzmO}zA?^<|5zsb&{myXM)B{5_R)uR1#-nlzQb-+1q0Bw&hbZ9l*jaZ-Zp z`oXt;uy#`?%!>=nh;2(qm>)MHGqw%aegu-CDZGd?>hF#xC-a@@ z?%s^v;uvx|!OfSIb%h(5FTD@kjqU}y$3&{P3Az__w<$@~y`1)B5~F{FCVr)g7#cQ_ zZGLm?_f!%@8*4t=Sf9lSdn-%Tg3J~BaE4XAK@WrOU)`G+Mv5}{7doylR$GeF;Mtkg z_wn^0Yo$yUcY_@ju?XbxCMJ&yy|N1dqxx819_M$zMO60cQ1+mYqUokGR}x z^NdGA=Gp7&yyx8Wh^iAFk>EdJyLa)Cr{V8efoq!!4;h-*z|R|ZtZUYA~sn-s#5DB>v2nM1E4OQjhhPaEijGIRC0(Xg8jEK~Suk}o`> zSkB{J#$2CKLlVda8Anp|9jR5RoU#$mD@tBfRw+3$T*l5T>IRGVVnoDX{PdPzl{&1) z1ohyV1<=@B%W_?$T_wW1i}0>0FtJT_HT!7e96YnU;9O5{R z#7%*^8gDZEeayuTwAv3pD0>Z1w>5`{40ANlcd>F+;cVzjU(RpgSm@VZ9s2bcl*ex| zzD@5-s!Qd@gvmr|`E)7Ft*@4?T!?hFWB#3Hxl47c5gKk1a!4ZkWkw8}VFsD9l4MaULRC z%cF8wXM6F5UxD1tOyncDK8^Kwp4$U-E%0Jkj&eDkseUUX!kOwxd6<6tN_vkU(4w3Z z&RN6scRWkScd-ZBWw>t>axmi&!p~JP2{8 zyNRQEaT7P@&+xo{bt34+@t_xz{-^cg!Uvu8Vkpy#Uq7f=UI2O!&ws@;V+AMVj;IpO zjC+8dn@Qs??`fbquQNGLQO@zDBF)vd_GM@Q5mu+Ewru1x;Xdge1GD@^hGFgo(75%q> zkEZ)T9lpQIeA?oIUuyke{qE0V4A1O_a}cH>Q>yN!!us0U*-DS z0@)mk&z@tv^c*+l7Ic*IiS841%=5opDpt1YFgD?jGPfWju2aL61P64bB z=jrK<=E9IM|dI{g8dIR76e!Sz-7L!YCF^e2{2zV(LY_XwW zi}fSsRRN4oFz4AY#wWwLG4BN+pMWhE3%1y(|F>S`0w zwFo}PoW6wd1>W_uoAE^s%$c=v-7>nam;m^}T$Osa1CLN!?hBlIVUD6XAgGOJfwp=8 zKVq&ikvHx?$L4>LHXKhev2YT`M6Vu%DfHeen-KUfO_ zUt#{dn_7vkCJ6n!NEznGz`IlwSAqW0m<%kp0pqr5%sJ>U?fqwf9$-s659`Zxuno}n z3iqdQuZnmj@@X>A+wi_|KVU4;M$MeB&_}3 z$)oR-5AOYQw-)&Uhseor^#8*9u{C*laT>6TG;7BVo)C85wTEGa}$4^u4Nof*XUrXBr=3AWCDr zqA%bMG}gepiv6j9e$+sJ3ecx1FF!7b(EFXq&1!xKi$^rYsLg2e;aD;6OpPS(j5wx? z$GmtP4;@#Y-MEk^#Bm*9awF>7f;+u*uEr|lG=w^(I0Z30Ml(Ew7}!Y6ks~WqD2SOy ze&q1ZYvsWRPS)smSKhLm0MZ1Nq{I;Qwnfm-H#qgi-JDP9XtCX?kTz z1gC0@R;rf_1{}uWcS`s!BV%hJeD@T5w*uCAtKnHPe0K)EYk(iIzDgM5?HNzaUEK7_ z(M4R&MnlvW%k-Q|zXIN^f_JeQPmNv#?`B6GS~d%w`}J3wZ_64mZISYoC6n1R?6ayr zF)x7f(J&@uBrzi`{60+N{mT;gXqW>~M;kyl79Kt*=w!ZP{{aK%S9lvdFWq_YfFbwr z(glY72NptEzYk@+s*K|u$2Z7qNeNh!$Oo=Z;D=^pw0!}({4nV8FLJ+F+6Z$2wt@N| zb1dQ<@C+ANh~J9yz(LT-UvNDR4DP^sWKa*sBfUy4T2dMrT||1-!C0O`T@SQ*8pjW` zSrm168T3z|1Mg?Td)0?>UdZDB<%VQrjGhhU6j2A4!JMZT-wCqkknbQQGC_#Z0X+#k z5OOe#HfTV%Uxc+utGtg8hhGLVT@3HOm2uVY$~Z0NB3O40bBFg8@(>95 zFF2ZmDvA^1R&99#I-aC4tjM2pKR{h%|4!svTkLo#W<8H zAJ}4aG3Sez6Q%EFSvH3IOGKLp^(F^((VTO^ z4<+E-X0DP29}KG?LQDbXW7|?ms%OC%Fb~8ES!g5X!NE9Hj3*Fdp>ZsIKA^Eh7{|G^ zl4u=c3|6+&7=xvt=Nr&R*q7$i$mDD}H89@|=G4F(Z5O8lhN%o+Ij1Eb(A;g}b1{FL znAZdSvEG9*%Awz44#gbkFO4w>(vJZ>RbEM&o~yLcrj^k~agO%g*NSgM8^$-5AZ7!| z`Y7W~+790Yf!+&x*ylJ1`m>sk_!r@y!@e`$)vw=&xgP!x`ZKO~5_nr3G%jy0t3xcG z^o-=Z5Nwf-IsW|RCj)?wZD)sQlVDyz)UWk}W!eVd?Z!Qvc4Pw4P6wSZ`evfdhTq%6 z6@_C#&Mg+OJ$vBULU?1E4@oKU89zGWVUneRu@{59;oWv4wt+n=-T?MZNU9W7*8Fv@xl+#MpD8UtczT>q@eFZ z17Ld?_jSM~LVE~(iETNE>G@z=>is~s`}mGI_wwz6O+xpdFTl8P|G0K2@a+^D3x+%^ z#NPu}Xd7Vr84nWv;h#C(8PQ&ZcK1nmN|dDmXQ(W_{E5U*Gu4+D{WPhr;q({bXOx;~ zZ~5L|*cZaN8f1(&32UV={e$~BUDZI~GqArZ!`0>)KEQ8ywzQgP`<;Y$F*Js}@)q`P z5U!~?ZSV#?N&|$hIfAhhM5D2c~%VA5F>&1y|LV9 zae@zK>I5kBdK~&>N_;Wto_|>{ZDM3^!S3s$2^8{ByL#74L-+Vyy;Er@om*IZDxbtCOO87 zX#FBJ$;!;A(JPNz&d;2o(nj?kpv8J;fb2F-BfK7Lw{u^@TqfAa^d3QIgXt&r7__%A zUibaC0(6e=vCgQ8w7xuHKQBoCH>k_lZYdYPRl}Svv<-7g)Ld2;bjP7XmLknnp`5vd zBcmb)%xzA?+}WU8gFugFu<;Nf*OS`Jv+>|qW(nsy5qih|P`L=v|7`)MTd7i;cY!R> zXF>Xh;Th&5!aQc}FVlEjOTK@#aEBW7Y3yqOI#@5gRpSfmrEN)OWlzxE7B3$2eVYao zbNwcgZIb(HaUIeMzaP#ZI@3wD?T*J^Sf24ggs;7oW=47r}f}P zx}MJWfUY2S0$t&E;3;Cw;V#g1x_i3Dyod2PQ~3_`tC3TExe&&Uv_${=L|C6p?u&UE z6^&vJcU*gRMdK0)jnQUsN8=jbB&ZW~5a?y>8|w7*JQ`n=0s02%z4Ed}xI@>_!RS4W z(HqA4H=sAhE{QZZ<%6xjy|Qt?oRp#dau-*Bnzt0;n!O&%N2WX5D`L5|82gyS%H=wj z%e_GDnh&8IthK{7^&`4Z7~W_@neuJ^;%EBeJ-pCAsHYzOw)v8A+Q0X+=Zly6v->|j z68S=2-7yXM!q3VVsh;qKobd(xj{Xa@pCsXn3GVsg!{x{qQ}~W)$QN>ZzTki-l#D0X z8Ts!eb2a^d7sgUvkk0W5Aannb%3P8tb29CZa-yppW#a)ME_E1-|A%qx7v&G=d@$6W z&XJ7H1tOg>eryWTSw-m#^N6=d=lN1Pd-FB(fzB|e)*l5rau?B=?XT0m983BbRA6Tif!ZEj`!bk zFlW>OO`c}76ygj4L+n4=U<-s?#>RM&o*a4NgQ&|EtIafEIkUy&c#cEYRaoZFeI&Gn zy7u>@w7u&i_quIuUiWm{Uzd8W+gg_WzpdMDb>M4G!q+=sY(vl#7N3{21wD;1s90A%dmC(M(J?(YN#5=KV^EJ|5?LFRr^iPa7#wYbkG}QR| z8r0rNhA9tI9O{z5uJrXWAU-F9ybX!?2V zSf2}L_kVpTu19E$aqHB+Ryq4RH$XQLY{*Wr#`|CpYxuonA7K5m1nV64Soam=jK%Zj z`)F-gCsC{e5)4xkFfPHzkiaDx1e|+#85*C%vjA^+rZ&{djAiw|G5&QTuY~m)=7N!51bsYJZLYXrDMO4E6+{~fcw#*69cK`%7LzX0<3g>$rHM+W@}*h zJ?JH%>m>yKm$FYw`2_zl;`;xXy&{B@2r8|BSgr*!0u_| zo%Y|YXTYGN;AcY#;4q4WN452c0C zQ;Kh6k);UF@N1#X4$0mn@uK&_)xmp>4=F>uYnJYdt6lne9QIYfd>AnkFVdyWQXs)R zvXixfW8d}`;htrL-m!0o#dX3cQQkQ107CsJkft@y`s&aY5q+08LOob_I@qS40Y2i` zZppCisp5CrLhP~G8Dx*mgAAKpD<$Vg>~1x@Q|%GJCrxII$Nb(_A1S%bM@m>@`VsRo zVGlHk?+8MfqGvc_KD*c;Iv;-Irj7JG&)UfCq>bLJjYVP`duSV%pOo`$sb2iW>E58z zeRxHQTG+>r=tIn@fY+)hl7jhoLjdQ^$1Pu7mPf=42Re=bypR1FtsM=2ASihRwuL<0nbAn z>aFYTQ15;&E4MfOR@U30UTAY=FZym!FG;;`b6J_VuMV_)9qLDV3VXZoY&OhO#et-J zGzZv(!`v81$})QkF&5PsfD7f1jL~Sz;ooL?SWJdq%_CpPdQjeb3d&!S_l>y&-ro+q zv^$sb(wl=0FS9uC(yuOf=~sU;a`y{d7WQxV1)vS^)7gQf_wKV?Rxv!oyX}Pkp9Y%3 zyV=lBk)KNyq--|ybvE?12*!(TU_V!1v7|fz-|gN&vT%+m1>O_CLH*IFBBL6i&KzhX z{TE9LewU~OdcwD{Foqm9hBpQsT(;X`3};-7;VEA-GG_tF;*^wMMfwIIedVNFq}d=J zO0(bE&TU@MPCd!e)LK%8!Z_H35wxo~AfN0IfJ!-)6AyCKCJappQkk ze;#1AVFZP|e3M`l%EkKR|DPqBg$?v~H>(4~)BoWDW5qDNhrnU*j*_ zM!#W8o6#TU4o-1!9jBOr{wT4-PBy;*^7aM%obe{T{tSIfC4P-V2dbCs2RdY7{iIi8 zg&#?=gn<5o-*<7U!V{dT^ez>wmEw9X@1+pp8dKImyNIXIb_~hd({4$LhO#+CH5=z# zq97@aa(N8Sy)!x0LG*FKbydDE8E)eG{Q+ecV<&ono}(Dj^RSb0|CrT2WOxn%{z=Jy zB;p&dEH#<=!3-!{5B1@BCfFtGx!il&XWgRdt%yt;2z;25Bx@U)`IXmQ6FK>mArBOU z<9DP_`oNQNWlSCNSOj@%^6P4I!owL?m9n-`M3FvF(Q)nwXG|L?dINx;T-7_1 zsHXV%*wf?xI{qR5!}up&C;UHdcaOi?+XenpWqb_aZ(`@><3M*N!W`wtfxZP=KMl68 zzY_Sh0_+OBe-hvOf4TT`(~0Q>q+a49-v-Q2X&tX9t!{-yB&DyevaB==iuEU zfk*utqvHdYW1qmDPx%M*qemrqzykfK1gyq!0gXIhvR<&wdkS%5=Ldjp4JBFiz(=bm=AARimh<91Lql4pkGoT(}ys%zr zVBfjw#{%nIs?gU156|$n?d5b!RcAj{ zbqahzm^1Pmo+0wk75X4%*0vb<2H$il=6q8Oe6tDcA;q2zg?{iJB-*Si9E8?cv7XF8 zpC0X7{7&sXg>pe=~yNA#hoiO>%1Q}j9T+gs57 zAgqxd>I00saQru03`5=kxr?xa?8#O1h>ovMF^9XD!>!R3OMeb(5; z+vB<_uuA|7?$c|nwTQ=0f|$(pt%GNq7yo1!qSaoZCDR&<%?vbDN%3N$ctP04z?vfs zZiG4Fn#3C-Kh$1?I@oSi7;AGc=F@|3Z*ZDR3PTxaYAOO*g>r2AbI*-` z^0}2WQT_!}`A52p0NGcR5fNVpYcm$)-hVbRxrcF!#T2gaBJ9(_U7_}^Htusi;5y1C-^5nN}k z2AUlSy0SOu$|9~S>!2(LbftM$&=rMX7mNg5IfCm-m)=Zur3-YW5p<<=+q5&OdTm{a zdIoi6Pnb8rQ{)3rkrq6wPE%Vy)vNzDdGNXDQ^lqiX(cmATR;DAriXv)|BoI5(ZgPS z2lVhe+fb8ax%!V{L!Fd<~GG2+=jB9xiB_V^_gF0L#67^&4zmZQ~(>Q9N(}H zvYi+kY%{;Yf<@=Bp$oRH<9qnEAHv!-9{V9r`)Enxx|yVpm_ituJqnZCT!oC_CUNb(1iTgy-5r@vg$Pw)VVh zY%q7a201=4p24Tkx5E32YQ0CRB!<<&bc)oGF>vg2c7w?qz z``})MH|>{sXy2diomzC?9GLEtg1zbfzIK%!G3Jn_(EVl~x=$kRK98z&ZxQHzRZp@L zX&>o6%aUP59!L#9|Kr;O(0?Dy$)`>KPq_v9=k*RQXY{`s#-0LWB0X2$CD1dkw`aLO z4Q4_?`J+l?ETYEO9;%@b9s8-?Z4!R!!2exFF~y zd$JTdIzH0 z*lMUpSAY$KG4K`K23i5IL?!&-){-^EGF@*Y%|PkG0MR$gf{#jCU*NYS4!p4fgrHu%;`}{v~W* zANTW3JT8K7K@{@1GVY5N`>fGf;>k~+Z#;QBtjqbvli&IStjqe-f4p@WdjZxZi;zL( zIx@twK9agVO3ZMT#`=ulz7IY70sfDdk14=-NdOpsukjNCjqh`2qjt`@o!N-42z+Ma zHU3s|!gJc^Lh9z8+Zd-81Ri5CA0tE@1Nv9u!8$XG2S?OB{so@zxs25P?7O%8*WNpx zm!$~Jy=9C!DtpUs;vV+fWCp(fTl@g%XCvlpOR(d9HpUg(0Y)dluE2N$l&^rkP*$Uy z7h%A-Ybw}^lRPkN_rS22;x>%7t8b@y08(`<4_zwCQzQ8Hjr!13;|KqYt*e;W z-jK+^9Q4}}E(zr^=zpFoN`F$W#`X1uuTZFSsztjF-NT0OSnpVXI@r%iAy-SXo}d4F zR@r;j?`khXyhnJ>|7Faj=fc+DxiEaUN!`E7YVy99^JN5E z*U`$lVy@!*O}0}$`HD{hA0-D_+=nAFTa`PqbPpqj@&lpINN zpWHA1?%YBpy6Rp5hdVSW(4 z`|Qfgw$Zpo0?AFp`&;0jod#Z~x#0n(8ayx3jm*eTCb>rzSZsLCv}u^dUDKYk+t&Wj zZhL#-?iG^M)VzhHHy$MEhbQPCaz*JkSU`S`2Kl*?z7@v&&x;Zuv=^?d>)O^ZgV$AFRuYjqW^1&Vg4`rkU2_@S(^Jin);a=z)r`rtT-1u zGwC{Xoh_#qSx5cOM9d+QV3*O3P~t(CV_tNL`^C}r8lgSDZHebxpH=p}x3GL4m^aDQ zELVRjoC9luwJwWO&w=6p=qoB`)>g%;=fLQtPKKqKJy(v%4dA=(dwi4_+2!{=ifF9=g{aF@U1u0Z-%v6?=!~aPCjFRkGQE5 zKYJJHGX{MQq9cPRp$_g&awj#z{JXRINLyGhhM(Un-OS}Pm0=Eh;V(flsUOAhP34&Ml+`by8B%=gn2sN7 zXR;;E{>V!aRS!T}EBuY;;g0mT*p7x`-n9h#Gknb|T4XPJ)LK8>|G!W=@KTBCl6(V` z>nr)$Muip)8njS*qGOuEa|%dPx9Av6eF^KQ55xV)|(!l(0w&kFEmV{Rj#@=7SrfO5sA z1wM3RTr;3e8zk^_kZRLnJH@8$jy&fx&I}l513&L5(r?iTg@D& zjNcTP{|x2I+(g)K=i@x)Jx+Qu;9psTQz8E2j0@1;b-cf6N`E}3l(HVld_BGk@m>$S z|Ao1vhVeBiDKpW2q;eCh*NLsaQtt|=r}(+x#8SK~|4#s26HM58p5SmLhBIF{+XI)H z?@WO$hr{*{4x5sf%rkF8c54)jYkXx)EyzN84-)S{CcF|}i@DHdH?TX9G$$F&0~&2V zCHv<$6Y+d1Or_ao!tO#YhkmX;#_mI&0QxVGWqMyBT4PNK&;+VjZO9=(KSW z%MYZiS6(Qr5C5CO0CknM*&fDlc4H`8qf=E}uaUsHMjm;Ny(iF~$L^`7KA)>PJDo;%K&R6dsr*q0{890R zO0y*m?C$Q0FT!j0z`81TcUS(T-rd#8$%pO6!k7`n8|IM#X!yyW{AqZ~IndVLXBlm! z?Utgoc7Ib}sYh5#zICYI8){{4AsKC{E+9 z|FE`NG=9QEzftx%K)>JohtcnG5B)~l*J_Pfl2vQek%7jekM71kVl&CEgc4otvMgrf z#9B;MDBl#>Tn2O7n?-gV%pz}N4$4hn^ZCNk%yZDB{D=7n_F_@+gjr>B~CS_l-f?`hLVhCJXyt#`S!V zx1JxeP?clX8vONoD%V+KI+*+RApg1dhJKO$?pXojn!WA2?h6^eD09?>@^OWEhw*v$ zU*^rj2v-H4H{$#a7`ue)EzkJCThcwTCjQ zxt!zn&eo)jp_;sXQ^6$;ur7zcWH@GX&bK2YejV z#WZ=zNf=Aam5X!82w^yT0&o}SgR?}KUl)2FfYsj(@)yf@9c6sOa_h!4;aPyKx|khN zAj6#?^I|N-I{HUaH49`d@=ht&16M2!EN|Y@`^%f)3a$frJ{(^i*tWo52ex8aFJ9K2 z=l{a8RBq>7qS`q}7iil#4cy-iUfQv(QL1OQMmKJ2P&>W@Tf<|=hm&Ik8g~4)1>BB5 zN4w*L1%d63xA`2tv?{#OqqSAY^Q_FJkgxxZeEpT&%B_<`nR89+Dj2J9kq;d%;&hnA z=r9H8P@vss7WmSk+Bf#;3-jXub7yW7e@$sE+CKQGx@VQ3S7|L8X>Bs2wKY(u%8S;b z?8~hk%hoP>ZP{A5;M`%{H!wj<*?U0v<7zRGyXe7yH` z3O#wRZzmiRXyV1sr7E_`r5%J;Q-g9-`;?fik_G!Pok9VEy)h&R@TMGGEnifAR5^>o|;u zo(_!He2qE3JKx_%eP=$ii}3q5A>MY`U-&rNI)ME;4cK22VBhKkyOsC3j`wK{;(HX| zJxuo~Fb0GDES}F}A_3?qIRG8ao6l(X$P#aT`4G-COU2RmA>MTKCx8pTJ45_w>@H4Y z3p!YbAdPjHD6B(&9~)&XUx%5z&u>4IqRo4?ee|P}KQ6DC-?0uH4)ZPS#bP*z@cSiP z&n2mPZa@GYNanDO=CJkqlELLW=Z_`-IrkFge6P=(yYPMob+C@_X!L0k`h3%;&o%@1 z|9PJ;egUxh>NFlt1DaX)Aho#?>|KH0P>$}^N!A2?Y!m8W*FAG+4*Y!370tTXO4J*- zy)ISZ8x(o)TYQTF=~eQ)Iicz=MKAvA3H3b!QLhDa*^PZ>L7$4fWYkN$5~Nsqrq`&C z-O&i+$4b(!L6St@DvDh#RpI*+>xK6x6dSa^%-$zB_*BPs$wcWF+9d(vi>seFKf9#* ziNJPACCB4id=67T*QU8t4f-g3LZy!|;3JVf9^m~x`&3|>i_z%wUZKy6_IUT1&-*Or zefHj|4XaH2`@KczH*dFhzoU4+(>s9mutuMmLZAQI<=y8X-si0y^tnf)&r5|qgFg4} zGm-b1&HKE0kM{gGYV;c`^t;=qUo-EwAMZC8z9XHC2_S!7*XY0faY5$#;O*xS)_+U~ zYq3;LRkK5Y- zpVIGQ-tS+RXxLogWJZ~W&4s=a=Ey_+hW8(5b6?|=x1=hRM-}ZdJ@=5=&g7No-#_p; zvx5rSWRD%Be7g_6VNOHk|2saFJZ}Sa;pYvX;Bemii4^U-26sNLZMSUIvGYj(4*SQcO&W8Fm}F4r5TwrG+j4adM>x#x zCzbZ`t*3n6!$KOT^gNEtZ~+}J+%K<5X-l&%BBT@E2ODJyt+Yr9d&Re_PEAGluch!K z{!u5Z`1h|@OJM@vcZsDH-)-Lqwuceym#$!6Bp!pZa`tw!Xh+NfKe!i<3&hfVxG{Fu zt6)2okz?!2eBQmnT=hB@%Tmum#MuA!s^p0+41qq@m$COE=dO^dPWsqjNnb`&w0nvbIO_T{pAkuj~j?p{sMky zNgg@1T=Mo=l7s#In8aY_y zNrd_p+lBp6p4)iEcJKYs+ZxZZKML&(GK0%^FLYF+|6XX~ld23eC9?aKBb9vGLCine zq$leN@ts9U^?`malj8#UP)%k2am4S-{NsrAWh{<}a=0)_^6Gzond)PS^5f-)wPoOE zWvcu*M%WrPE@pF6;xHeU1<)}{%#PETLQ}N}-+cfde!qu}sf_nd8RN}FA3A)Kw<&Fx z*L$6H5a{WtAb%QLfHCzfz17{ue3JJTt9U_OiEx(k^9MN2QXI!;-JdK|<4lWzK77wb z(7oFZ&P8bL-9A*t_ioSOEX4FOZ$HJwZ5fP*p>9_2FvSNC2-{74O`3Y)RspYfbG*)4 z?5%fkjOU*9-gCe;7+L0RFI^GD^x2ff>i)m7A570@pgqFRXI#Z$^tDq4YQX;3n_xSk zKPVAJCVQ_9%;Sa*ZGRs-Li1$@8L&d!tg#z3B1|MQKL=7StJzei~!*=eF-DKh;5O9(;%h!t`y|lMLnu zD}7>~{9LvY^Bj8)bk*>b_gOJ59?K~8=dq!Po9;a3)8&`Pd@d>FF(1Ge#(5Mus_00Z zM^C7Oc16PH%tjfr3w{sg`w3U6d=!QCbUJI$cKAM7=h>Sl+gZ%t$k#GRus^;#jprvM z>wH{WXtTYAt!<(YJ$Uw6VZMruc67RTO!#;Sv$cl%(D6|ypUwAB|8=p6o_oc=znN}Q z_l5-etuJAAsJMT66!@r<4-Ie8F}q8wcc`7krHe&Agt3b_A0A%h6Vp52vw;Ej6xWrU z``JKSiMKvHpYuAYL%h%HEH63t^Ew&dYoFJ7?|c9AIb%*lasSfejI z{rInwQfJ!|JiBsk`>RWq_{;DxB_{7De~4Az&S*&DYbv*~^IXgL+O{w3*#6mD%=jJG z7iEUR*9smIffq9X7u2s7&LD3sX8jLExpy_jipaVFh_kCzoNX*-^0YtJd6=DLPQ^M8 zt9AZ{bsF>@S$mN}J4#IcVO3sLV_Y2S#uIi1r0{C>+tV~=uCqoHc80YX;H?qPL03rZ zd=#vu>OVF})>lsma&EKU`pOA5uQdz3<($^qEdbatZ#|WL=3g%R9w_FrFG53ynVAl| zx0vBI75#1S_vya$WXZE`d0QoK+JHJ&pF-M@tQT_|`tC!l-4p z-@xlg(Y(A9E5A-`+nM>TzHKv#&u&Nbd-CjcE_(9pwnowg!bzudz=?t5#Plh{$q*l$ z{QR*$PWHJOPU<+F#V+)h-$UmxJGyp`wol$TPqm-JfZxTqWat^zFIjl@v)F%HEa1+h zjl0k0ogFWuo>JrNSP%8La@Jw;DIQ}J;71oPK$P#-nzxj=6ZK4 z{7wq8rk+9i3bKBMcIoCI>pRC8Jv>_BPiHUlHBFeq<-6ds-87H2t30jfz_9`K+kY0r zoXhZxM^M0bX$LJv{S;&^N1LW0$Yaxt_=xdHET2;s{ySQ{^W(Dy<4=40h?B+tK|hQ< zj(R7^`tNo&W*1x|7;}T0%_*I)1^Vyw{V%|QqK~@FLqA)x_YPuq8t!+5&r@O+jD}5E zpYMHy;NP6K_3$@+^J$U^>_@W=-+eN_%Jw-h{{!aC)P;lG(fQxQ44pPj^ByM4xnQRE zFegc-riJ{?heo~G{-#;YMc~5R^_Yub+@*fG2r9m}uzSu87WJNU14++MBe}`SJ?B2^ zJ?AW&RE2FS)Ha>5KE7pNU%qL$E6zgSxTNnnLH+t4VO{w*YAY|09F429=)KNHeXwn1 z50cx$?;JnSldQ|>$>QJ>0UvuY?*QhQ6Ykg}OiG>rykC#-Epf@!${pr9sOvhAZA(sI zdsukqJ_gpmMYv;Mmc;JiDtGMXiS46!`<|>l-nqxSwBKvox&Qe)x%wk0Pvg1ED)F6= zIFcJSt!QYPiC8Onel~Wm-rSTF%fE&5Z*MF2>dj4AG5lL+{_RucEf{mtgl{P^ z#ELk^yXyEB44z@E^Bq6RXZ$_Ny?PkGi^lj}`1qaq7@heT@GTR{Zq}8If8A#c%qQ+O z#x~_%y_vr6;x)z|cCVg}AK^0w=G=m^n8cFtOYl5k09qt*+O)X!b!}RtckVgO9gg$9 zcfa{p-n*|btM~5j)w6r|B@yi2J(3D5=V-RT(nH;=OW z^>{zp7EIPnKs^_v-k)x7W#6|!*$tcrf~gH1Yfpi)>oxAxzjIW*SFbe}<(_>G_@VFW z)w}k!kFtB;obIPkiD1}^=1ik(Z$!$iKbsWe+H0 zYd9^ydf>h6!|g0CqwMR=-2p_2;>JZonM+oW^(d{^a=tT_mOPBA&zhD5dexrce{3@g|`0a3dMKg6D==@qjdA zlOA|^o_DU?euMx9sd1BVk@gr!S7^U5Re8&HrkRg~~ z82!E!7z5~S;D|($j&PLdS#IRdBS}@DJj01(>dPcCzt>;%nENrm*IoGg*^^5p3Cjz5 z9YKA9dD!OGWf;lamoZmlfvzM&>|-Qh`=29qEO%!k@y;JS+*nL?Y=Jh(O59UQl> zNDQ~7LF}ET;&x&yUMg)U?nP<~CzJGI%2(dG#=LQEr2U>h&W#l3B3y`blreo!uD}>Z z0q2+x8FQ{UfiA&rvcB*gsluE+GXOs6kl)m+HIKFc@zFpKt zU}M7A?&d?HZ1Zlb@T0O9qvW&HnOMHMU(An2l^-1;3}^WqXPH4PxBf^P2g|Zy{&S$s z)Wn_-tySnLyf?#DA=hP?mkn_hUdM8K^#gb=qwo}ZaCJYxBTL~FSBeh&k?TMshvzen zD~#!xV2nnyEK5_Wg z*W@*hqj-*^0aRCOkCQx_>%r`hU2SWLyFD)sc(SXX%*+Z`W#)-PlJ(ch%}>n?XLTHB zD*;&7y z8hx=UJJAn!QrQXi9m>hzEQhXJU5381#Ss#d>2SfCIk)Jo&IKk%LtaV7p=Acg_ti#6 zGnBs;6jJ3H!E?~VI+V=Ma^Rc9jSpJfWlJoM{P{XZX<4RY8m!IaCB#t-vbg}(M{8X) z=>f+^**k)`mp6#A*S|f3-Qr-d8XUVY*P)Dlw>BS7zJPqJ*hzl`K2B2PvB1X`&c_(1 zNb66k&Xt$Hocrr}Il1BNygX=>w@vHI!>dde&h8n*WiH{ks^>OsvDy1giQk$}dvZPn zKgh$Uujm+_kmehHAf7z;_4tNPsA}JMy{FM9(}p(9v{l~afp9|k3GlMHKET@-9oU~` z<_m|1enxFP{NA?aMH~;wKK_MhYhKm${A^9re)%V}3HQG0GJ1o5aZeZYEr{cM?akZj z&th*z(L97+axKYt;pEzhz+&4mDe@g?Vn zhj{_A08SmU@Y!QlSZ6XN9MMVz0Rh*!Tww0;BtTxOH z;gBUA@GyhgL47zLbR@kn1o>8l*R?ErL*ocbt+V`}!_A2_c3zA1?}2$8o|2i~xK`SL z?->*>C9Q}zr@k)Za5e$I#gsa#C+Sj{L^eztPd4OtDII>#e3CBqt?esvTqY2AD92?! zzy$d8YAa_m`&PNv)X428+=mUNZzO~^WdUxD8a7new0ksh%W~p|Qrs4My^#=VKg#V~ zJXf-!nZ@idUXV}iL3US&+9BB-&tT_F2Rti%VqcSe@SNfU%U`K272yR-qXsP7IIf2v zu3?-Cj1izcwUEpx2xhr@r8@R@1KPg{iNt+Fn_Ut)q zUk6}YuawnZ$NW8vH{*W3x+lZlgu7-zMAhu^lCAi5?J;m23wVB7qyr7*%zxv|e$lnq^O84T8P01!@pU`aoRP=M2 zS!{s$IoH_Q0VWUL6B*u>zOWC(`vrl4*$%GHrCvA9Ib(h^WfflOeP&w@ZBMBku9sVu!dC^-&B#Cjr6vf*CK!~YXr6{sD3>nSie5%NKP7C!x zmiR z>q^`SNF$+we25g~gFpPP1DUoHaTa$C$cQSPDkst(VEd*-r^<=HUaQIpv=JIX#^c*P zxc?l^X=kO5(GH#y8bsK>c0GJYIdbLvh^j`Q2Yk!+1n7l<66mPD*|x(#(-@0<;1bD( zzPSRY0;3lV!aVWKojKo#^yfb>Do^6EFVrbIyN=V*DC(CpnUbSPM;+M<3O|Q7jrREE zs!XZlbcDEZbx21XR!;ZfUbcjp_N`@0gmq|3n5iux!lu{~^xaVyqXPGYxST1_EB2fO z_%Yc}z~9fkB6-Od(XR7_xq`=c#kXX9>zunx(NUQqed8ljguVjBSAMhoyk?*MJkVAD zjr}|&empIh$66M$`~QEU_h5znya4bO3b7X3zkK%E0<;nFrQ`Tg`gm68BT#$9>meo9 z&tsROEH`r=#F)RfEI&6M3>A1V+()kmj9+qmP2=bFOabr}Hf@?FzLax*Kk{>aCLetD zRcyH+!ItCkON?C_Bc)%oPmXoahsqBD8@-GFUimrk8n?wP|2q4=`R^8MX#VfT8hUdd zYpY(hzg7x>)`#x;z4*w&V-Wa;jP6#pS5yzO24J9P zg4-V1Tyx#y5z)UjKlSGPL~$hUgL8hm{r&NVLj8?Si}zUIjSACz!eRq?mqCMJsO|6-u^_p-13 zanNu9Wzv&I|1%yP`)S^`<9|&?!5X4n{oQflee(-oS9gT3%lDtfhW@`Zah@}AVL|7A zChqHf=YJ+{$G-DB6Sr~Sd7O#sz`kB}0eNtY(I2l=rthiCD4r+T*!im8*VazreCHDQ z&LY?bJOB0jok>OeVBEeA?CSqMuGWyoKQ6A8%>fztJL2m5uYWnNehYhBJgcVeNBpsH z^w*T%m!BT%2uA_pK@Elrr^}w?=WXh^t-VsubXg<(VC??4)>}Qf-WnC8$=uJ(5p>99Uo#zo@FI>}pgVB=Mu8qNe)G`ooSy%)7WejuWU_1NtX^NM zItbhUq`W7Hah=~g7RO~6o^?{zALrtv@aO+-c7%eDZ9e#jkihSe$RLDEI+MR!iH-Tf zC*tR$ue|Z2Szo}%dtZ6uL#w_AKZ0#;dWGe*!+A|M!kYhz`*wxGeY-Hg&!qKaMk%j{ z?>g4&qv$)H#7R9jz0cn#}8fze;UAqjGj76@NP6uwwg-kVRh%{q=Jj`CeWVfWU#x#aDZ8__h1VPCTL*O&)XRc; zzH_cU!X(Etq zi|43DB(hw+Bf5fL3;aI~bDU=MwBkDrW}{_pnq;X>Fb*!$D2=+_Nl&UrcOD3ZcHti zm%kSG)!K!9IE8nU0LR#m!n>V?J_wFGA(P&HrFoW-ccFeod;V_RV}!L@!)Uy()mhHy z_e31fNjXVhS|V5Dp5ZXOe+>1LL&$o(!+W!ytVetWf{Ws-oZ}04;r_kq+6QWba3Bl{ zAOCQG;q8rC=hSv5zY9t^KFK@x4?Y21>nue7mxh@s*FS&^ z?R&m>0@;Z+6v|SRp^f|GpHg}c^pc5wIC(6lV;TDkaI#3mNnM5qCngamC9xDI;T$Jh zXZ|vr{NB8?IrltqGLZ95vcNkZL|cIeaJ}8Y19K5SY`sIbr(}T54t9ES5Lxeqr-jiJ zkLH^!t+d@Z%)cJG9olWj`hchP=ZmLAFWwp9!PAQU0-gxN)9PY|r#sIDPl8V^;z}2M z;c)e)j^PUTTLa-LPrw!K$sw-rop;2`@LEz84gORjw-cikJ5gAlufJ618s=H2t3B&< z^M3Z7ovVnl$IbM$E14hbSs$N$S1;LOxPY=HnArhR06QS@D^-W%UXBaa19L*qJS^~k zBANVhj9|Yf1$o;5orLzvJ+?$n4<7#n`ow(ZG|xtx41G>{St578Oz*D<^=gQ+FB(Pn zMIZT6xFaIeqibIRI-J*S*~jSdy&2l|<#PS5_R++BYO2}RIw{oFk{1THSGZs9pUpkB z^O6)!n>IATv+i5ZDfiF4@nmqqQE5g2^cg6pN=YKisnQ7cMRyo;2#nR*N3y0%mUpg# zvGJ^wEC<=-{=|*BOHS&gbj9|6ry15glC6757~n06pZ$se{3L*H{tBLaKF3$Ot_k*+1+#M~qdt`805^r1DiaGZrx@9V{<0DJitT4{$MnNINwM~i zN?Bg$B*Mk!W6) z1q!_7n}*kyZyw%^>xp@)1~A&izGA@kcP7+jIEPr=NE3MOpqmgP!o{S+N7cYe*_#e8oqFg|-z zAjba8_ulz?j^2ayVrd>h2lBg;TV4x4@59d)_}L9Vhv3JcbLWKO84#Vj zDJ{rW272yrxxw0$9c(?4-O1Vm=H>?4y94|-l*z+kj=7mI7W8{7{EUJzpMl?ams&11 z*yJGu`XTPa;NM*#F$yW2nfLauHbVR4^^bv-eRxZNP% z@$5bJHhcaodN#_rlG`DhnQ>G`kaw612 zJ=J-wR8>o$?(R%jE2!JY;vNIMb7Gjqy#dR&@N$rcaT}znuk>W#$+em8YOqmU?`Pt> zjx^8X@g!o620elEshUiV&Eh#k3x(X|1w4nSl8aQH#&U?d-pzF5c)mF!8Gpywo1tDC z{J#g_`5T8H*9Ffv{|Mh)AR7>OsAF6cEVVT-cf5OnGEB*Dhu;rDU8HlDO6Q%C#xY+w zmKVzMK+NOdoK=@mUsRXTFr_ZTHAwMH0 zU~wPWVR1K1s>?XK+5&o^tHU|AE(3Yt_yoy)I!|)9O_bd3DU$o}{gS)s5y^dIf#g2= zhU9K2@8&?ApvBMUsuOZT{dEG#VmhG|ejn#L0qc2m!g17Jj2Cpk3n-TwcGqPbipq01 z4YxTO-^g?~tS*87J3AU8Z-%lc__@{5I2vG%jC8n;V}8RfP;PT7 z-bTn^7t9y+LN6E0cWfr^jU96VTt+E273g6I%3~SjGJI2D$pbis3?qY`h8)Ln(2)(1 z*Et%OalJSn#?W8yn7l*>Yjllc+U>+$P^O2nYaN*51M_>#X7{c@_I0)@XXRTbWrLj0 z0(p;T*gmRJ<7f;Yh?|#osrRr|HB^l1Y)@3w;EG5D4 z_u9G)VuIiA!td~s45UwLe||0Jjsp5Zni>r>RqU}ncYy8LnCMWxq|p#ItA?I`|q?V=e1sw&|WZD z2MOh5AjvJ!)n(xOSjRE;8Cja)f;ko@kS+-`KrUYjGHoImX962{L^m>H8_dsm#lr5R z_sctt;C~nGxzxIlkWR?IDJFAeqLi=~GT;WrKMi_@>J@#w{cX@I1Z-s^_^v0xMwo$i9O#&eA?lhjQoihsAlIB*O)^OFvvQ&O?%J)Oyh!}!L94%%X_*yvw3*QPFo>-M9RfO| zA#_s)o@qo|@sMFtMk36|X}HOeAW2P!LSx|XSV!ika<21GB#kFc8ZTA-xt-_!6l?_d z=W_MQHtx3x<;S7?SR3`*p3bTRzioAAT0V1+T#a!Zd@~Sr2IgT^`V{T(L(sk#v`5{_ z?o4*Kr%Y#UQU6^IuoyMk?SXckpdHFpwB6ChI0?Eu#{jl9$ZQw*0&RV+wT)DK_46defd7;8<6XbAlC~zgM0)!Mwyf-fqpgdwTy%B19a~CUhIB%BhZj?t_JtV zTfwe(8bCKh>D*4JBNr#w4eu!UwyTDAU%)rCl`VJ%@b5#cNb~hD2HJV*dO@MDD@D0}DCo+^+Ghxjhm@8MKU*|jTov2ez-f0_1=L`G;{UrZKUQgHY z>mkCZE?*o$91zlIu*aw?St{^dRR;8y2qxTfS)|x7XQa~R;Z7#DtJO1t%5qa zYWYtjpTYbhl;0?p^SLaC@*Fll4~%X2mIst)@%kbxi=ccsFL&;PHu+arF>diVln;jT ztvwv#XRR}BEm^1!{e|NSbeWCoySSMArq8tNVb22{5eFl7!U*l(Ad^h*A6SCZe!rM_N z^f9T&^*!vOuiYK$qOXSi<8P%-E$aCZia*`W-U<7J?;l`!no{1=ZoZqvR^B-cT>d&MLmkf0u@2V`_y&5c zaW&A)SZGseb|mxo3Cg<|9zU6-ldKzcQBCyCl6z)(;wLZYqAJlg$z32-<(Cudc=+Ai zLG0wfp8@x2)b6)qJfNmn9@GN!K)jp;nh2(Ag7H%W#nm|QTM>tEI_2t9e9cY)u9W(S z)0YmSK1)b7bNO+S%a^OT97Z`4!rRd{TRK?}??;~;d=I4c{ucL-K+moGY)zm(Q05>W z5C;tnOh&iHk=m1Kq!#%He`7mb2P}_Vz~0QovKpPVD?y5C!ZTkrx~LrsVcnu6Y1dVf z#PoETR0V5%>~_8SjxL22=>N>OaW^c_8kmlaYPiKR4BsEY*} ziS?q9+dH6&gXt?_uCaRiGcy82pbjS?AOf$<&AOYsdXUWoh;wle)*h~F1nXNzvY zxO|-5eV>w3H)vPe6yk258g6Ty6k%)0i?p2>+sSX=a&p{-+qVph;W7ER!26bo-TA&{ zHnDbtF{z!>n^@Cv&vFRvSsHBe^=!|wb&HhlT&)A!T(bV~6U;r2+qWSkw|Sz)-5kQ= zq%D)wJ^%#=C%K0M@71s{3Nb zHevry==ZnS|FiJ@zfC~__W$w#{?%+hZNVpe|Id)+XpV>VUO*fkd_enWg2{R($Yf`v zy7zY(t|$CIr&V76k+Rp9&EI(dc{%eFVXsdZ>s~1TPTA`d%I}8qgHWD@XE!Yato42L zwEVkW!d_pby4UyoLGRe`&r^iGzHIhB#}#YUy}swBiF3r<_b?b}4QO!($d5{(_acxV#UMW_ zf#&NnNp2JP2Sweo-PqTWDH83k3G_4WAT0K5;IU^D z$pxF#j_;kc;++J*p}8mNG70RxmC;bgK#tW7CAr9ZG#)mH1p{yQ#zb2c}>yjNH%ZeE9Skl4QMtU8<-Y~5nqT2k|0lgxRVN7Ni+C4mmkSLX8 zV4kV>fsQuzA~QGjQ`Z95KzBKdo&S<`!`S)%NUUGyKps24i0$Lz9PsU(`Y4NMEQ)5L*(kZ&Z%P?nFu_p^@btj4|;o4udK7Pi*X>UbN^zL~eDNTJ&o zN#XST8~kr~h2WcmY#%)c*5H+N@H>uMHlR)B2KqPtL^cpol7Y4r_K$ZJ&Z~cbtwt*O zqI*xv+Gct;r5luWw=493XDc5C{!Zuiwepru{baC7Vf>PTC||k(Pj{v7-!#sO0H3Ry z-3@;~Pjf5z_lb8drb3@cdq{`4$Gl&sUH6qHId{?>AfJJELfdk7yRw7Q!`dF&9o|;B zdlAs*kx4=6M}Xgv=P_T|ljF!km7U3k)`OjGjn%}R)k~$_g+RL_JT$P)hjz`Bb|-n! zuGv1i2N^s9k0dnn=a_$#qTfF_k5$w&vn}KGA;(mI6W>;$Q z`3;kq-dPATcOl5!g&=dm&g;Ao$wuvg1(}Y+Y06t%!H&aVTmBX{L7kr21et+s zf*0`pCPoWo+qq4!;2K8*;HwdIq;o-t1LZ-(h?0!PyiRmqtPcA^`@nF$qp=+7+|O); z60ji_f-Nyfu>pj>i=gjD#Rd?{{|x1rrwC;_$`x#fxEAsJC#Zuo@C36Jc4pOqt*|!gBj0>w%o7U3Qv9GZ7cjxz-$H7;Rr9q*(?=j2jM%)KmxkzbGvFoR7_>Ktk4tG z*&XiP8Z}_=$6>#P+o$yV4*bsGzZkx!aa_=EqwyQFk9xtk%Xr+_x8FG4uLaMOSNH{NECS@#rX z$AW*bnzg683*=D?{Qk=pz+;h`d(R274aXt}<#qJ{%cgH-itj0a@8ckIwj~j3%L^77 z?=L9ZJRIc+jXU+l^Bt0-5quDoC+-n+e0z5;Pr8CUnWXPZpsihjcNSbGJtBNhFLWpD8^YI6b~T?=;cl{A(@qWf}N zG)c5y0gmNmEXG6MpVy=R-nFR?Y^fZ5*BvPUb1eAp10{9_@1A*5)n4%5t8~nNAIRf5 z*cQik0-jUAw?>`|6>MVDA-Vbr_&?06Zjki~z`1fJ&Y;wXJ}@W4#X?;gw*oxM(6=JX ziIS(0AK05@fkJkD)&E@SMAYF~(tRpg(_a5cJst7&8DG`GwAt`S1Gu^}1i~_wRby+wUJ^_xJmEZT;>1{`aS(G7jC`q ze*f&P+J66iTebcE!mS>^e`l6upvUk3;ZtqD|HT8|y8Of>f4_gIptE22^Dp!J_tpFR z{on8R_xr=Y(eV5CGr4he8kZa8AU7Tf2OA**#*PFSIsq)5{pCit3n(|@xZLR0f!ye! z+;h-b5A(YY7)Kr=S>73%NvyYJ5G%d!5Q#EGXOk0{3~4DR>CQeNL#7bx96V=mJ-=&e z1fO9v-)9D&9O*`pA$W$qd93z*hfmM(zC%$ElOrn);(Z4l&A~Kx+ zxmy4}hBMFSZb2Sf&xOJqjc$3+o1VJ`tbbgWTRs-#jxhF3P+qUd9ie;_lppZ;5USkS z_K6^O@>IDqZ@;(P*?XsWw?Ieb&ZO5>x%1dvqTCq=Jbx4L{#cL!H-e8a#s)G$Q|`R) zWHKg%sBha|zR%~qTUe93zh*M#%fkPiw#nwh|6SXpCg_*jChtG*ZJUgJ)896+fArhg zCd)q3woOv*WVXq~xBmFH$>fhNylpb(BW>H{`j512lgy7iw#k|-%OH=8sN11!n>?`3 zTSk0(hrexd#-YlH*;9U*ZSu}Rf7`_VwZCnG_KL4IK`Gt~rlT4#^$X{3J`W9{STgjIEcALMhC3oUwy-e<-f(pvi<{iy7WKkGio z8wP$>IaJ&SVRN{61<223mRhvO^5MJ1U~%O1vD7*jNTB;kExlh@4mKIq2Rrf*wXYcL z6(B#Am~a_kG)G}nWT+5dy7faYC!mi{{vz02p+wUbIs~xH<#9Bn5A5%{4_SPfz89dJ zOBKes8op;La*E&cq;Ul(Pb4gdv{?Vj4>5NNiKeonPL&;R^SEj`he2#}@rNi6!0rJ% z8Rzq?Fdxt*gZe6RUKqbCpZ{{8gN?90*!FKHWiI#QDE{C06YxCr_qfns@=1A66xBPM zhc`$1=$#gM5XNojSyKVNwtuQ?Jwxbg>k0YnHtuhrPZD`N8}qXUekEi?K5**^sv zbRz1LAcw+V`8v=ideA3npijoC`lOelD};Xj4*mS7=nA3yZ%~eRms`fF`rz1C-uhtV zpG1AYY{rDYsQTcig1|Oo`~6%e2zKL5vJxMRwZC~OljmX#F8N!gCp=|9Ge7V3u`fA| zOx!2jMFspW-OKdE@Vk|_XM@3q?QA=9e;0r!3gC(c_+kLgSbsf{dI9xBGSd^KDS`Dw z$=MFtoK6ex3z;^iB9VGEB1h>W=%U z?&yAY-I3^{JFa57W3L43e~Gv5$hyQ|cTA_cqx)HPN6|%0cSwmo`?k~$Vlt*I8+6AM zzK;iM(2_UC*6h(8G4{Vql&jBh-SHm4H=LID;P1l3*x$Stbw>}XheDnUtHPfOkjEIu zZwB3gdx{M`N$x@&yFZpD;B`9Pix%f$qM;H_H5C$6a6Ocp2n3Es$D9ZWzKDdvSV9z2c*4X>x z>Na|wqo-Zj|7!$a9(fV-ZMmkPt2% zPQ#p9hop3cK3{m2c<2-F+qF$a*wwk)TIE3)VspoczFlO`?wuj1mmcdp=lhO8N zJl5;Ehat2vK${VYJtCA#P@b;XHbVL7&2sg2?q7-J%~1YNC_jlb26J96%sD574BDc^ zv4l3R&CGtH@WOg4@J`*zaErbz_IHNr)E@R8dqthv!#?|VtQThw<2VjTr(g^JIF+5_ zT=S~L%gA#%Z%m;g4#cw5^e<7{AKcx;<&7|*Hy=kSvW+%^qmwy6IT2M zv+_U4y{%ueSWb*!du=@JH^@98~0@jjr#ygkew`+ABJ z@6+#UpK5|NG{ahk!kUKp*>*bw4g6^{Noi~pew zhIgl)EMguBS#Te)by9{7zppfP{u6v=uB_gA?d9|L+E@3PW!E`8KS8Ms%FDSY! z6n#H7{=7|GmqFk0LOed%B>33}^*pE1XR9%|d!e7FeEn=;oV(!r_saMQ zP=1J&-?>TfvxWM%Zelrtvgln?)OSo~eZ}L4GZeihv>6R;K1DqhiGH?Z{lUl2j#m6^ zVf?H4{GZ`|Hnv^w@v|8p@46NJY{|OY$IsUEjfJ)PO=7KFe{2e*KZc?2%3=tHO-lZ! zEyL@}|2f<*-m2&jpLnZBhX{S0sFSOYDmp|c{}IZ6Kpi5)OH;n|)*+?0`o~L41phes zPEm*40CI0M$iGpx_NgOnAP-qSNBu{`PxkkYXBeC0K`RuUA<)4#fN3<>8F}zq^qp_p z@8dfI9k{>n^_>~s7w-{$XUTfW7fe=9pUh>o9%Z!=U^M~EW`I4^UslIlKv~^|%j%d8 zWc4M2tS$~>vN{c9HOMqYPGd|_OGZcZIX4+SCd^w#m-J>bx--b=v`#)gac6%S9p2~c zGP*L7$>{n}RYnKh&(2oUbIXyiu68D)(T8iv3$c}jYWuF?)aUDVRzGvGiTSRX;oiRF zWN4@KXN12)p}%72?-dTe(oa3~L+!1s@GAU$TOE@vC81=!G6!dku>TZCat|%T_k$&m zOy96fswx3KQe^o%dD^nvsv*lm`FPmhU7}xNB$|6c*&xgB(vaoujdJzk4rKYUje;x} z%9}Q7%ku9w3bNcX#9Dud$&R~tjPpJXS^o7#L6*aOE??y>%eyGDTxhdnBb$G0tGuq+ zM~3I;A@54oUZUL}NQVE$`(ylPJGOgDe~cGI1ox?;IP*NGiYS{@rnT{cULfgDyJR$6uDeq#?_1 z+2}3HBL!KGZ_6llco#O1}oLs*lhROBJt{uqr6zx5;B#^I1%JtTxt98~Nw-D=pvV%PP zXLuiHc_y*G+ndEg_rc$%dSjf_U-rM1bZ&cT4xhcWk|-wo6G8S@`s}4O^zxVejwH61 z){*Q_>&aw4%3)VI^Y@;e2y{A&pBv~wa?dabSM5)d*)vW&hEezgU0_ zAp7z_2Hpa)@Me&Sxwf`PCV)L2;>jH?;_k=?a&-~zQ$EP{IFm#@dsH6utP&#>=-}W7 zY)w`~l4C2Ir@}N>hZwT;gg}$%n zdSil*4{+;Oay6duFbg^%d?!1dfVatk}Z_xY1P{(Uw~XYo&dPrg1CyY-|+#9#Vh%D zlzcoi_iF!4x0rX8=4b6IdGZ@H#*x|J7F)gg&f<<^SNxrd@kYSSOLJciRW{vLI;UsPxhqX$A90 zx@Kj%>t6u5IV{tiUsgICW6Q43iQ5M9v?QQkg6JT$fS?<~*hp=F~T&IMx} z4G)5zJ#KLyS_X3W5xnzeg7O<24S6LQD1#fv#@d_h!QpvGAgt#kc{?gF1=P%{!jB7sq?@Vu$DEUi)XI;QI z&PhIZMW+A``b+Gt=v01Jw20jmwJCSF56ZcAoqzt)>B3#;j%X$98~^;JIhen62*|Yo z@H0$u&m=6*Xu)M_U)V?4mHzol&vjh9gZ((qU+Nsd?qFx8vNl+6Bc21>5^QCw`trR|s36dm)= zJ!%74pR%b3eOD$$veW{+MR+dLsK@v0NHlFXl6{{hvG;(A=vzRhQ6r^L`tA&#PsO|T zJ(c=n;???>TQ(G3Vc8(o-zt$o_)c_ZrT!hXe>c>3<6A35_|A%C+K%;=H&!r@OAYGm zL;7^5p_2`HI9bpBr~Yjl0eS#CeumVFcC`u0T*W*`>kD8T10HEk)@gw2-Xzy_8yT01 zcdPe;M9u420&81=`whh<87{B^dLcXpmV<{}L~<3FHYfZ#n0EB! z=dmyGhbh~w(mI}N!13`74VG&(*53SzRHeXq8f+A#W7Na+3}u1}(u3s$K)HP= zG?(QC06XYVWvIhqz`OuCJTE|)BXgIW>+EBqc>%^|NL5cL`9lTW+xVVb-MgLpC_?!m zD35RF{+(qg_;;bSd~zMTORU7|F1nTdk2+;yJHI!s_?JGm<7d$4j5eM()aTpB@a-P> zb{fix_2k$Y(3LL)lXa)!nH*_K%d#Qw)kJ{I1)6gfgMQNUe4(pB#*CKSn1iGdaBY$5 zGIDq>&^F8k`UddJM9^hXc=tLE-@c)DTb~2kYy&wprj4JY@PTO+z;rEqYujjXU(?3? zlYZ^oM=p}UH)3n@EY!OL`byj{KTY#~LVG3e=jn|q5BCP$fa9Tzxx9`0K|W(X0evO6 z@i7E^V4Hb-9Qy5j{KjO~Lx?M-jZi)l%40Oj?}hS6D91H;WuLr8$x-RncTHV<7qjot zwx1--3Fos9zDdw75$~zrWd?h-Wc-&l$|`o>+$@J+o9}d%=6eZ)`tFq z2cO5}^!Kb5ODo?*0s-~JAN=L6jpn%KQ~=Om!HEnFr654OPXLu*yJgm<=( z7MuXX*BGA#UPqhtwG~no=5}zjDN(6sz z$IOoXy<9d2dmF&6*zm69@}RYtkC(@jPtbE6!PaCvs|Rb{YX|0I0r1*vWEfD(f=yGr1c4j_9l4=XR7Ip``Xq6wBj?Z4h3i?4_CPjz5;WgglNeUDS?k zJdfibdN)4CKI1-?qi?-%H=e=(w6kctTrEeES{eLj+|M5_%qML-J0CU#eiWVNJD*n2 zaYo@gmSY|K<^~cV1o_fhT z0oFK=*UjO-@obxm_ltQI8@^z9bro2T0}mO6c|8pCx{jZ}@tqIK4_udh+gV-$j46!Z zITbNyVq+gE#iis_gf+vzU4V}`-WSFY2G3M;7o70qF6hB?7xdVXqVM5_A5#bTNdh<& z8;9mX4COfw!RA=J1K)rXzD4qHU^6|2?cy!9H5ijP&Fzyd2J6@07gC!S{fj6y4`RJO z+xEq$7}tunzk9o~52D-EJ~bG8zYy>N4Ym_wjehqHSA|@-`-V4wADu9r-5(2d-!R|I z?i*I{cLv$HuW0+-+elRfk7tN6U?;wVW{@0M=dn$A=P-+&b5`Q5C;MjG2DA5W?GIie z*)H@_*qRJkF^TXuJy zLacRXEq1rTY&zgWVVI}$f=o^x{^`+xo z`4M!Vz8UP#dicifUJthRhC2A&3Ey2`UFU9oBb?dEdXhURh^#+x;5xSp>PeZznx6%I ztt}nD2kQbYB`S0T-zgn^72>{l1B(SA9o2_gtXYX-+5N{lrDPSlpcc&)0I=Kh?Z1 zC%G^5Wdry;&=2%?tOfUbWIPuUWnXdI|M%p}v5(I#U;bS8%jC<7cSZS zUvBr7FPDxzyL{<0)?2=OmV1HZ3(q_5D_;y_wdKp1o!;`rvW>}?c!eJHKo5P0yLD2q z4bSnM7;EsOhpf;GC|itNwwMCb!z*DV_i#3`V%|Tb3yk~XTXZMl*`4;rLnOViSfcrx zFfKL>M*o(#dWAwz-~9pauM z-b2KAT5~ABE1@sRpm$i>w`Z>}lJ*W8mdC zVx1Uz1_R%pEfwyqKYAlOvro_e`O)R|KnK?WU0!Qz?_?R=u$Q20Wra}@fB80Gz zEt>@861fQBqNoI@a*3^?wMbFf5G_}g)o4_-1Y~_@P*dL*t$;Lef|{wM{a;_2(AblRraqUu>|)zTX+hUKUJh1sKC;1!G#N(rZgb0F)8Ce#<`YzLg> z%7eDYva+O{w)1F4^WDzyO7k23%8$TSf`>n_LY*_FXMej`M8HMm)+T3>I`rwvA=%52 zdHc{@L7o6IHua#tk~$T849DBb2^~iS9+MRg#qO;HX}u{Y3h!KV*B8i_t2U%!wqnDn zf3ylDtp0;+^A^HOEUN%1g~zI!1?{U5WS+Ve!|u6TnTB8~gyR{do#K-`T7O-*)qvE9 z3ewDFvrF{wmC}wxqiyd-XDFA{w1gXK+#-ps>~Jjk)r6GPT>`gTfSBBb)W(!w?Dd{* zk5nqAi1wq9!r1D0xKC#D^mDzT^A^dP8Z6tKb3;8Ntn)mD?u5rN5^*ZU>#p0M`TO@1 zp?CE#fzvQdH;|r8b2xMI_lAhP^=VG^G(=l)63l03MI!;5grp}QfP7+}r~oF>QXpav z#_tfv<~hMa;4}QQ>{6ta``A{hhjX=mmh`ONlb&XCc9D|fonwyT+S?!iZmvF4eq(Pe zKz!w==q-rgz)Q4J97@nD2H|LYQEfm-e>3E!3=T!eHl#T!-+Z|DjU8#$T9orH?FTAO z=LKVm=$p!vJpvS}b#zrK3g|kveC8Dtk%sPX53&agHFY*{*)jEI2Uw zV0drNHcHl@=$FQafw5y6&G*$#`!NI5rjB+5>j;c9z02INZ4ykwXKwZip&x zK#H5G??Jf-SzI=mZ;FK_pJmLI7Z!`sOJvMvW6eL_ElXCpj2tScn&3U#c_sT{-+)3s zV|*crR(Q0IUvmxL><>#_pX-rR%g9Jfh_%tZ3c-P+(`Zx6b7yNzmExG;1VrTt7ta?|D585 z7UYhc;B5Vkfc5#9=(Nk11b3L~>Vw+#W~yhgT9206f5-X9Y_2jyG`zImlDR^vfEM3c zLOFunXloP3Pc`{a>BUagGgBOcM$j4qRC^^LtqoCQUvwGE0J8R8X`}B<1lw`eR!1Z< z*Ng>3YWwk^{j1XtG7+4T_(z)Y>siqUrxb*$TS$W@P@Mt-9)I;#Mgp36DZKju>hjJvRt<&X!s(|%C!T@} z#P2L{8XNR-v#!R`FpK@*uuO`8CLzFGeo?;*#T(hU)Vp2tQC<-7R@FDRiywdxJFGEG-&MKUL%QgF) zqsE#$SX6{3Tcw=nRrtT2^WZK*tB*s#WGyZX*BG$kVi|o0qk9ekT;ZDY5Bn4Eb~C1r zZ?+GZ1x-JX>{?SPNVuvWcnQHp*s%MIbWO;*_Blkj7jp?3T|eGVg4bw$%4<`e@^QV< z%|yp^T}8-Ic$?MkMq4X%dZOQY6z{PHa>0huEXtn-pK{TF2u+q%JO;l`58$>2`B|4* zu0o?aoF3e2aLh$+Z5IDK6OZ3ibi(*txE}6NIxaeN`AQxRmf^1JByB;1te}M+k48HQ zuj!yipo-3c3LKelMCdp!7jbBwGUmlXHCF|9fv{F|l9|-x*|gfzk_GRhuJ>kS37$ybM$AHlVVi%7Hvvjq)W*l3+9s zshx>;y7}kuDdbA&s~b~*p20=D+HIxm)i!6MS2t)sI4(4Y8gOUdn&LvB>Z61oMR?K+ z99wA8ts7awE2-|rn-z^=u+Y}~LC+TSD1)9IvK(Tl6Cs1&D4x%RF(2}Umw$&G(&Xvr zFdy3AjtTm3oBP%^`87?rnp0CmhJbO0Mt2fJZqUP3&gA(nTMmLmkNqUTKgwZGm83j( z(`x9!%TFUHfz=S6Uu^pkNv}{Vw|?d3Z23Y%zDi?Lrsr5B;kpC|u5C!Qu4pCI&)6@W@t`Dw{ot3qe3(If*4_4Ns+dvrIQcS4DL!jCNAQ=QGH(1 zLGhsD;-AA(=Y3M~51NYnIKHyg#erURO)WI4zGS%TtCdLR6&Y0zpd0$SO};j}tv@y| zDZZp|x*6Xos($FqJoZH+Ni)QvG+EPdv- zt2;Nzwl)i-h%tvv(6t83JXs11djIRx#N$`9XV9JU1m7Xv}iv@-ycxiJWDA= z6kc;mSO!w|p4+q=_kMc@^loJS={2z65Udz>KFn8gzQO`4Jl|J&C4auV(zucLfwSuN zvynwD7(bv0nI6QywNwL!hoLlm>V&%Kc5S!@&NsgwJv*TJ^P3fYRujw-x{uhnJGU5^ zOR`uwNMENMczp|On#64*rW_oqTsuhby;5@nm!Dpcoc-cb>2CRVMCRVerNRS~Vvgjt zalA=~8YdMDOSq-oL=XOMP|nq!T#&SA-)!;bX5xF3+g*d$pfsr;K(wwx67(|9T3Xxm zF8msq^5TwHPk%rB++&7LkeQ-%D;D>znbTD;4!kOzZUekpQ!oy8MJQz8B@-qbCFMiR zo_N>XO_A9#r~%dAPT$q)1w^Cj3u2|p{nK%Q3Nfcwsk;`M>m~;scj@9TZsztRIpQ|9 z1zvf(KTXniS)T1sA=-3L9ox!p@BO`30}{Qp*A&{!wWg3!PJi+!{K4_HC6aqh0l_i{ zhcRGe$v)_nD&&<|f0{E6HM9ltFKdJakl5cgpXn{_P9!x7@67jRAosnXLKs$1cv(7T zgob!W?mk^{C`_Tcz-j){P0kkazE48jy;qZxdY3`rODJ)R3ZYeTMU$uAeSY)SFRcZW zTDPy8c`W#~_W8Zc3R--}6KG>B~6r3sn zlCeLU;X>bEQN^B@lxhd3mVRC7-n!~X(}-fVC)p0!WPE_5y5MEgl;OYu_l96j$A;hs z_6=M~GNwtq*;NT-+OsKwd~U+tY20^oCP}pa-^U1fzX{7*=@uYjHcJ)^&2Yuqh`ylz z96Ny-`b{YKf-jg&;vM(+7#uevv;SpbQ8H;=EWzl|^T1X?Z`q)!bw?CzDRuHAos8TF zng6*{XOR_&J=dOJysO+*I_caA&2D?m;#UuMJBBG^`Nsjkn7fQ^6_kHn|A~CLh)p`b zsa!eg7Wu7LKH$a?Eh~{IC$;qPaBV1E!$&@crMr9B>3VofB`)YYJoTS=4gCsgUhmz6 z)D^_4qjnF=ZCQJOO(edSH}}Di?_)`sT?=Zj!jPz&b4U}M#$*y8Zlj9pkmTC`zZ1HB zK<#SPGU`EYGp-}Nz_-BoaQXmyCwKv3)uRW63tzaL2av1$FRA<{>ALCvPujzd%nQw= zQ|}e8BJTl@Al`_vI7QTJSR~5AoA4jX;&MbDp|C7(9I_2(Tj>PV?AGiAO`LlChX&QG z2VC!+v=SX^kSEEA6^%TgGR~`8lMcVdqPu14MSHFs5GS^tyQ?HEmo2^~@5@>)p9l2T z!0N@|iBn5{w=V_`gGyi$6-`9U%(~TQ)l$5qD!79Bjik5&dMs=jG%|W^VXUIUzkOEm zNXa=dJtR^7s=RPi>Q!-Wgw208V*kz#+kRn4K~txBhXC$f&}UYxm?hn}jH)FT-OGZ_ zjuF^%y&4Pfr+rhwMRW!QJH7;wAG)t8pGFxZ21$+AQv#&E*`yxB1`TYK3JxA;bJu{G6_I6PR*v0#j@Pf2t(QtBDd4eULFa4Nc>`(t?|_iL7o z=PlC#X9|AS?Lf9u!h1FNxo9-{XIAu(>oFPU-mt5vU={H7ZS%Gbqh_O{bq&<$6nFcF zcW-rjqSh0UqOMl=<*fr^-tU-F5_`OzGLKe*gvTOx#+#@p1{dx0g6=S9KXbH;SBpTcQOLEn?lDgq{EVm^&dXKv)3fW#8w?P#E`k5! z14#9A-f-)(X$Zme3faKJ1h1+WjP7?Ruc{^Wyj3#x>-XbDKVi&l&cWl3Ezv)245Zp7 zmst%yD4xwdItNMkw)#P0p(DANGe_1fsjmZ?$t3LPGuvh1jnTt5{l}ek_Ng1u=a;8% za_PLwmLf0B0ogO!TsmjA+$h3PkOz$q2z;(CW-q52Y?x#xug7L$k%790zcAZwsh^(@ zJqspP89MW{<=*{5KLqD@eGyKmM$S22n+w3W7nZ_hTfdKsu2sRAKFC`?2eB!Rn#iXB0fkYO5ah)WP1=ZmE?YOU7#BD%_6H49oODprv(@Uc| zzqs}G_S3Oe=c^a+gmvF;l{4~1k_c6~c4WGnqYUl$EP9Ntu8oXN!6xD!1i}+fDC4#D zNw@TscUlRqN~2;H3SJMwC1op$|0&v@fQ~Xo?* zcSvQR;E*S|$99={N6|Pd9^%;Tb@CuEn%!TxiU^qr<4TMqFWQ;^J^QHqCk?m9u) ziBw(wdkS*nBwKbK9D1krPHjp3(Y9Ppzjor=dYBG81PZ>$OSdO|%s(i*rX4K0d$6x& zI^IctK=_R0w5ib_N8@E4^JO^Z#Pe`=_g&h zrUTa(x{;s6yhP1tb`uW<0JL;OQ;VWV<&8AEsBQIqB&&8$lYB=GDqt3SfBt9jc7;Ug z$kLg6s#l;;TeP%2QF!4JE`Jh3M8L~4O~okpky`yLr;SSqi!L5c?XU&kJo9g1E2qF~(VOZ`>U$K0))9?$hFG@fsQ0E7>M zT5NR;_JQPboIRnRKfsM<3+=phyVvGf`_a{GOHKTvoW17ivji!FuwaZ%+Sw zDDwSh@SDFB#o$))1n>KKENk-{56ujgex}c=3nwCd9$uHxTz?qyzZa}7t`SqDOv?O6 z;FljR($JL*YK_ty3~WjC)A<=Q!;3B4w%rcdvq!&pa3wuFuu`Ja!uL(@ z>26_?kaxocNJxuRkkqPpWT*<&#aZLE)i7(7Q-DVj1Ae+qI>+`WAE@MOFQ^ait@a@H?4bX=y{{ zpSueWlP6OXDcr~BCnN(&4m%WY2hpvz#)QIe1<9}Ovt~3TIkuNByh={1<7b*1$S7I( z6rMGMuW@O8KUz}bGDUhh)!|^5$ANk}ZKoRwP^Yh*e=^Na>dQP8d6r)&{ze`~3YcG= zvW-o;d;EjV&GtT_d@dka?KZ!u1EXJ;L8@Op|23F9$;XJGa>XJ;X~~!b9eI*dPOTtz z`YnonnYsk|qnU2K5~-4csdSqDU_KBn95+{1?8@f%DBNly0q0|MR zd0ICg6Wv1AWp(R}ly@f_=;4Eb%pLCqkGHo-5ama~==S%+EHx?5p3OPElS#p8=Sw#HS~duW z@WCw?4J|7+X|A;CbRIO{KlTAIek10sa}t%Gn$_?>#c7v)h2IF5{iovlhXfoK#Gjvk z!8NQqYp)kubp4jzYAtmi6eM!*to;wwao*6`<@}piX^!ztOR>@VCeD9G`(l0k6o{Ma_CJy?VnsW%tJM z-0@cZjIFy5>!NG?#~ZC=!+23Q9j|Ic7 zJMkJltqi`%Aadlc3`n&r`5Wpe%>)|buLny9pI{{eVVZs>D6PM zBJC}_$G3b;4nTNs$0S&#alfu9x^};#(r3)Q{C$nG>RjlsSBzGLDgS;jgHB!~%I`=b znXb6nUgP?7nkV{>d`wAM5*{6K5=CbK`}bA?+QqAEsUAaN5C(N*f)Bou*Eeebw>{*0 z?!NOaL$~$1d(7vJrUF8gmaV6qcZ+UElAvI43crmucm703)$tj*JDbm4;jLS0L1a{) zfIdd^EFP$sj6)s_2!FR`Uch6bIxwD|gxK@uHiA?ntcdd5xX!j|8(U3T4;Ws_@<3bY z+5Z(Q6i+!|l^R~=L*z)eQ4G`ir^4)o2b{#!sQWB28P`W*Z_Z$fWe+nQ4D+vP+Ik9EaK zsiJ74xv}SJSAeqR%701Yt@8&!f#bRCmia9uMWxz<8(})P%Rryb|0JlxDb$k~yagD& z{r{UI%h*AGs{I~8e%!AkF-MWc%%>W+_Rx$&T~TqT=C%s>=g%jK-AYr-nfvwnDh>H9 z`6T=?A4L}e-*vbF;NUJm9og*Sk=(!-rlgJK+-r^rPbgq{23Nu4aRXt?b9lwznliue6C%=8I72dWQiggXb`O|#+_6! zu=y~1d6@XEpwEBX2F5tLr%C7^g5-kUjbw5Y7DR9*AEds;Sxlo$PE1KSF6F=X{Ooh+ zD!gEi`q&y+


    0bIvu}x8{Z7u5;D#JX;(#f)bI>*d;#>9`?uNgO=o22Jn{Lg_xv2 zdpx9s8bicS$nb8f{>V=CMZ5GzjqlawlgvA8ieo{TWJgyfgj+>CSB~&Iw1Oa=JTb`h z?pcvV(#IJ8SrOL}eX)fy{f_kYWBQWZD3p4lyiN$ROTbX~9`@%Ug)(uw-zJEs>#J8{ z!LE|*vFE&mY%KN3j{n}X1(S#2T$^vWN{co7Q12!voeR!P=2tpI;HG*`8d9Yrs{f_C zF0RD1I0=EyScjhj27N*YZ}!Ll-%654Ttehl@43Qi>nfhjPvCLdU8tBmM%g1u+X>0; zl(2Ktem>^se5A95a}(?55E7hzJy-@WKZR^{QiS6^bi=5R2oa%jxmy>PI$ASUrNA&a zmQ=4oUo&9cmynN&Q;a`v0&8um%yjlW+ElE@k02}EU^{ApZEU2+?avckBl}g(B zSiiC7+s5~0{?TFwYuuvSzc@YaR=>{PmjRgJmjvbuh_N&E-0%0|VRm;0sLe0#Mc|uT zZRu4a;VnVi*JGcMZb)6UMQgy7#=_wA)vn#0mmu7QPX*8O_r}Gp4o*1#g_}Sr&o4-B z`p+amDw;l~K1({BNxiiI0=v5FfctglYA#ZH2rV!#wqn+9AL<%+x)zY~06J&aIC}n? zPxJRp7t=Y;YX)@XQ~cke>a^G&x&@_on_oDK>m#07dsR)#nP4$@%sW0$#L+ClX}@Fb zpt%0Npn3Y5ivw7Vw%6zefMKiSX!)=^bKk(!lRCKd`OV!rg?Xu9?6o`ffks)7A1-i2 ziwkwO?06`bxxPH=Vi~IE!3+BuP?O{JM{a-#3X9F#@JN!pFsSFI?Fmlh>Rrkhe7Izm z<4f1-(wgqU@yUvvLv|m1YyTZo3#z)_p={_!Ad;$_pOsX|?t|7UbQB-pCN@m}aWH$| zi}_UV&m`zcm9+p0nTXhM(vRO&7v8oj?H!0UWxZVEY|NiX5qcBc15a`0F71H5k1*}= zLkYSnc3s^C1P2MMxUL7dD+7zRMYyi9)6gfnopmuj8p=tuPT#8d8b?7HyUPg${_cbJ z+t3_86wdULEMNt~l~Z`#qhx=H!TugWY}Fq(bd>REiB-IrbeFu)+1d*5f(W<1AMUmv z$o$VEh2s(T$C4b^H*y2&!>6UgPH&XvSs5QM3V6|K93po=cogRb^US@>${U1>EW|Ws zCwS-6Wob0?USBkg961Tj0EU!Jxdr%P(&eqY0f6&z)mqO6e6od(oA2=>BOFg2q<6b8 zSc_n+7ysj}SMDV7ueC1MxN&BRDjk666io1Z8aETly-t{6f%PjKt_P4gYo98n`MmTg zUYx8EWnjE%h9zmG%s1X2a9MX(^rNcG5-s?s=fem{pc$qIuz5?iv5%AwISC}NZDM7A zv1`9P?-Di{e_BMgvg}AYehA%e9oo*>BmAouJm8ye`4`hx41%h6CvP@}|Ku;tMbdy@ z3~wymX?Jn)Z&%W4m^a8VYoolWCo!3+jQl5#5Nm$l*J;Hj&R38qC$(WZ zqV`o--f-HfCDvP4&XitxPHh6^o?G)*JiZoS#j2Fy7hkR@AZR)q{$T;BlRshqnyO~M z*hT>{{NH$l6MyYE$3N3$-NeD?rq^9w%@rv@*kV=FrA=1o71hT$FV#tGGhwRY)Evln$ECT$zwQ9oJeRz2hlWy z?05J?7MW$&0jp^LSQk}D(YkBjIe9AX{f(&#uA#rwT8@?s1KHC;j1D&4#2x{~|C=2N zu0Q>E`Dtdir=i83BcqwD@3QU*Hw%kzdJ;0xU~3}*cqGFmIuTRMn&A{HlCrq-U%ufx z4~|&S=y%X+&^h7@`MSs)+Dd82*8EriguIGW1+B0{^iiF#`k3dKnMrZl6R^e+$a$6Q zRxKZ!*XPl%_Y;)bzPQ`Z$uwz>);mttZ%?cS35_x++!(9}zGiCWJ(fX*m=mfJ7U@A^ zAt}cnN*xj?-ERYW1ql{sX`Xp;E9?m^uaL*tam!5NRlVDz+X}5Na{g{T z>TL(v7RVCH6l~wjJ3{jOS-Z1Fy5nT_1|Y>+X%JBXR3(8IJ{SmLM3TYS95dj=jOA{N zQCx!puhUwaJ`)D`cWH}(5YUtpb>@u8Ky;K9jOH^oGx!{;hJxF4k6(wyc;BZBIZMio z*}9ISI1tXX90kQNh*))(At;cS!BelVM=@dJ+21=W8A$!URrY;1EtqJ%==!m#D@~ry zmdpLQc}%UE8Q0gS4@2rSSD#;4f6IgatNj(}bjr4*r!V;xCwMmkdS;Mn z@e{gh6TP3=7n>3q!`=Q{FldOIq!X}vjl?zc{{_kM^w1b8V(*JQqUz>V2~=FA^ri76r|xCEXv#Hx zR1Njfp2LG>N7kW@*kP-D*YHlIKV7ZPsgT-PD=X#+ua=zo*Ep)vy|hnsj zU7SCDe0V4CJZrmn%qQ?xWr~}r?Z>mCg>K7g_}uF0CF5a9V+ej;_iq5)_sM1>=l;UQ zL?66S;5?IK*JP-wn7lJHYNll>?^FDK5~W7|BeIi=yAe`p0}3XbyH)kq9{U2b@-YVm zFB+f3BHLRxVZ2jby0CvDp1NfaOq39p+XE(Cbs@gdzf0{4e)gt%fGpdi^-XECrAD&f zw|c)PSzq81+(-=z$SlZk@5i*1%{P*sEy)?ow7-4~50L;?XUe&vUbD?aBDR*n;Xap#^%fZga-kS~FM>5Yygm*$7dq< z<8|VWqCN|;Kse};R#o(I{5|&v1dk$%d4EI*4MH1m02kX!?<3))|1o(eCbEh}>F zbZlO2-xJYH#K_%lmHH7|@bMo?g8Fci;jk-||LxMc(;rO{ml6v#m!?ePg<8y`tNw}; zuvi8Lb&Rv+2~fTfBH8T*y{^z-FLJ43?|ip^Ys+%#>~$05UoKkjQhDlM?sKORXsGYaYH~{23nM9~3rh zNXnjb?QO;dv3ri1>SIt+Fg$?Dp`H;1_nc?@Ub$Yy{-nJZa_2${8nK}#Nc`R*XJ62fb1myX_`cU?feuGL zfwbG>enWZXrw~z$-+#B$jIf$GHPck7L5Ph2h@30w0??EN;pK0STLa|!3u7QEq*jwA+TXha>X}r$JCp zKfhKlKRJzZlwCY?y#5!BX1eeiDCA)+P^^kL32B;EdU}at_4qf327N@%to*WBs~0Q|MZGC0DK4U%T^B2sPoXeEP_@V12~3HUu(waB3_hP zvv;|O#IVOGxWU%F-IoRZ89vUiyvR>a`nG$UvppL1nd)aq*atwB3(c(5<>13Upc$g? z64@1vIu9Xg@KQ`2l$iZ@*IT=CK(nYW8*=zh(w7hRuz7guv5&F@&J2@!9ZK96=y z=C(9yE#ziT=$y;?A|W6XmV6Mm^b!~A?fq)m1Z{AXiF!JQg|$coU=*vDa{i7z9^d)m zG=t^k-#0`X7t+tLJTiS_KYy3Qg=jXHGlwiW7FSTfZ_n3U zim49z#cAha22O7Ne0~e}D2&ffS(KYT7;yc0pdPWB@T^|;M)!1#@@xrvwX}F!oL(ZY zAVbAbNW9$5Kg;12&PC9sT!t=!i6*3M?Rg}Q0_4eNIt98?a&y3poc0_NC`fA=X>Mta6B1&Q^ zyLNV{m|4)N%dQx`aJ|F!^O&0VtlBxWVD@!(UTq5SXz!i}Pe;)ll|)L(h>pVCc&PG^ zIm&ifLW1nUVB^ZF%Ac*K`uBZOrL}L;Hu_BeyQLdM#g)6a?v!-9T!JWY4f|OKO9h*d zIpP(52BM~`NO7}ThpOMV*OTnJnsF@Ecwc~d4W0tp>iXlGSBhE5^h<*&NyIuLYB zipK@D0ZAsR?Ykd}tpiyKLRLXk1$u|_10Z>Sno;)^>Wlb6ewG6Li}-GS_JW=Zht-tu zoBH$pqc8pZ721G}R|PbdmoG{{kI*DwrCmXEH$u{ia*m??>x#Dj>*O9EyGRKv?QAn_ z1geXvmApjs`>NG4coTfM3yqgv9^sTUW8Y^w?6ZzzOPa(s+uptQC|3MSvk6|(d4t7| zzd80f_W^#=`)tGC`5_io3~h&y`nd^K4 zp8XgNG25%LZsi4vo+Xr#+y)EO_IT%kiS04ie~42xYR9VD$3M2 z5joz6;p#@xuj6+@iCmb}HKI>Ig7WvlaPBYspZRN9&R3Z7$IPrAdU2C2=edzd9O;YZ zkXM_jYhV92S?TcLOk&R|8fVGWA3C1$A6EnFf*nlkkv)%S!xp@4*as3)qV}rY>uf53Az_{|E zoW5WGCq)&bKDSF2K=)Y#W_09y?Rb9ZY&v#iQqsHe{P1vzl?BM9yhiBIvT%QyUh9BGLL z5VVaeu3vs3dBWaA#+);v`0Im4szDL5lhq{6*J+7&jMUs5jN6xCQpt7>v>tDS(C)Se zmCo_qDaSkoenD*16I;Gxf+sm2Q4Usj4ng?SY#*8G9PIn27XhlzR4l23Ti^`W9Hak& zHJ=B)>-M=b&biy4(mo6~jw1lk+8Zn?MHhDq2jip0)QII2H?&J6Kdv&Q*(ssWj$+Lx zeq$@Itfw*#+QpKP@oN|A?BUeGcm1Zn(v|7(KVtd2RK}nWkCUZ6jA@gXQ>9O zlFpxpIDbW0B?V_T+G^czr7ocDVh?gkG9oyrNJQ6VP8JrA4UzI5p*i$mJT% zMOV?Xfrlc3t(;q^bi{3f%DRwZ1W* zG5R3>G(tHXC3sS$vUg93-2&*gVDSja?GpdHku@-V^K4+<)UGq(?9m7{;)ELBy4`4_ z(#y5&CU?cDRaLgeO&+}dpmu%}_*wE&lU-r-ci`&tV+)j$DUc+elhlglV(X5@^hCie zJ!%p^k`?jWLHw)rk5}QOTsJ}LU-CB=iQTl1SCDrvb{bdt(F^5=Iw16S`46)EI}Ju_ z*o8DWYEEc-i4R96nUQL}HJ+LVdex{dx z7fX6p+jtCYZE≤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�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�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

    %FZ^nPx^8mkLyve={;6Fbz)U=1&^~M*`mf~s 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�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%0A@-FM1OmQeH_e#%H;(H~1$9jxWqM8>; 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 z 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
    hi? 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

    6@i^cD-IYG8*Ou(2kGq z!m`1}h;7I%!84GIIvPi_0oQz>T{tF|!rZ>3s?vsWkBh-pDXF^8_G^vr56=m4!2j3W zh4I;jUdQ?^tw!g@&fqwF5OfrAXD4C~#uC|6Xe`mDB9jy6UOl~A5ATd&-aS^NjSJw# zco=&V0ya7?PX8jf_K*AIw0*=hZ9j3ohkZ3^zSsH@e*Fph9)MpTv+>>fOU-&oEbavp z*j*W*qbRfgx6D`P(2=bsct*P(_dvVp*_jo#lzV^=2^eERM4rcU%&o4AX&T4~#!pr? z*vv3LEVTeHct>s~+RTLD`5?u(c0$+Om30$5@85*)bp-cs6>}G`GvNQS4A0>T&8xO; z;sn-qj8$iSHM#ElH1rI)TNFFylUw@onZ`FA7W8-~T=pTbW4vI;;GX$o)W2qOeJL;- z=?%ZX&cm~{72I#*UP8o0UIUF8bY~E;@mYiOq`=Mq3GU%YayQ0l>4m{4sbF+YsC;rCKbK>kq+)r$P^a9zpAJYU#!*u{1q~*!Jk2o4H zM(F&QmwEiY71B~Fa+^~tatVGvydt-CL`5zSWw;|CJqFXEj95rd!1O%XZA_JscP#>> z87p$#-#T(VRbXo`jTW1!pEE{m-4!j4-Uqfm{ND`k_;HTeH{FS6!hk+P+B|$`u*;qy zCiJ6J{^&Yc`_0v~(T<->|x+z#_zHO}*}G8guK z#AM|OIwwwWE&Pnd*i7$->>L5vISR6K7-YwXXA>#0fyXqmGXi9X;*Yvl3vhGaF(x|% z-sdQ?b38Cs{ERes9!8AcWHvwb>WRBc#mr*vq06F;* zpv65KD1GCK1kB3AO~IoKiX)*|gmR{XZ&2=9KqgyL84fiY6$}EIYmHGcXc)tw6OP>0#{iGM zVi<%z`BouD{GuRQ{Q9rBE~?1SSjX%uRQZ840pthISFJ|;5w!9%RQ7zz`3mmnfm^?T6s`80Xso zdDAxzrG1$^Ex1SDpvZzwBO?VU3&Z2Z#t)e+{H%q^$c3LWnMnDCI>zJPbrZD94DGXk zOhicZ?Bz&1J$oNz0C|Q!z%OEmJlxcf+c*e)ti0?M3UZob1i1m;`Ig~4n0L7|1WMCp z!3bEVcd7fxJWB{Y!>9drj2FzOXFVRBYmyFMVV2y~cMiOc7Gz&O=ksR7<+u%muJQQK zkIOkcb2_xG2=Z~VchNMUUm?gXi!Jt7>6&29@9Vrd3iK%&`Vj+p2SGmuOGlNl`*7eq zSI&iV@-L~a!n@{!tR$Q4z9g_m=4-I^^&7flYu31~*qTJK^^Mz6X6!QVizYcNrqjKa z$hb#j(+%w08$2fh&)i^iNpMNocPh&+~LI zBECmIHac0XenT#|4#v#|Fz&Y7uFSn*N zy$UjnP6CSCu=^Xdj?z2pit3cjK)q^&!>LD9n^?}F1C*Q}jz2Kzken?+qLmKd4VPIA;+5c+u6yIaPcdr_8BXULqd(g4wn=f1;cbfj+GdnJ#Q<_TxVPaj3U< zeZutQhEJG&%(iE9}X)4>MiNipha(X5NaT0#cRC@Y(=!W>y!!lizQcc2vIM2NLI zyz8rho=a|#If-l{)L)K$qIqDRyM^x~56o*<^i>Ybbt8;@)nyWE`^p3J@#*?L^1wX0 zqpv(LmmX>8BM;2qNA}e(n4?FS!sq$$Vcz--{FyWD(nuJGZ`2ddROqlEsi!!rSg)bk_- zc1C#h8@%&r9(WIQJYsx0Iezfd>&F02P~8JtQ@Y+)hZvzgr;Sz5TXW2AytiP#1pPIw zHm8_Yo93i)aUJf>oaBeO5zn!+yD{Dh{bUDx?3`_!v!GnlwSGMF!N}tNEu3XT`v{%n z8A;c`sDGP#0`JUh$i=-dxDWT}aJ#R0B)bRX{kOTm8kv72+bgy5CEn>7(fy7(UTOOs z&=)t}WdLnB47NenGS@+w_`MnrLGNMHoYkzBa|4v4o@0M_<}{#fA?Ues-a{3yS%c!l zU61q5U`#sL!hiSISvC8y{tfR9n&%UeCO@7@@qs2r2A*HmmIpli;}=T&-%aYhNx<`E z21(2FBh)|5&QGRiT>#%L!1uQmz8?j?Cjj5a2Kb)f8X3a(1lKcTf_(RM<9mD;pg)jVHeLmx=WCctQHV@p`Fw7wVVE z)iBHCqe9B|P~Hmk7jx%m{HFMgAa#@nzpL%? z9ld7+Y-MvI-Q(?3*Uj4!*d~pF@Z)0+{B}C3RDr1Y` zeJsk#ZMh=ur_2XEt%Nr2g#P4{4Dk@q4DTThzQgk>te|Jtdf^wHeSfP(qMgs zfqtgaeXe-lBbM1Zm8Bo1?Fhd6=Tvqc^@W8dXIHk2^StcvxNs31I z{vJm6QZ)Jl-{L*?UDH-wYqX-QW$nnI>#$wlPd~)7_Z1l;%A+ca%>t7@yyLZPBmtS^ zCC`;0iz&fAbS-PrDZX3z%O`SHltH}vY&n!|(a4}VPQ7P`$*2@YM%DMb!^!Y2($qPV z56bU>e#)=FIFq*`w3nksg{2?fbG1hxk8FYR+lF&u z(W|lI3T}jm_x%&PpZUwu!% z;gDYEiZpKpp4+C-3fklu%}F#ie>iJfWS6#e#cIl{vEg|Ykiq&GhOHoD391ZHtjZLx zRb}|<7%GEWoNAlN>Nc&F}g5r4x>><7nT# zH&dfGw?)%7S3c?IOPv2syg zKhWl_4B|G%jo?|8i09h0*sf!PE?CwMrH%QH5g}v4wNq4G%oMfd&7H!=hUcer9~(6I zpF?@Pa8!@@FX5R9T(*cYUG)DQSyad9{}owO$LRlgSyabZI@2-sZI(D4%I^*HSIq1k z^Y^3(-7tUFx828qkLMe$W}p+;w?4q|oG!S{`dQJtEUPlAVppCjFM6~KtQ7xHUap&| z!AbkbfSsYrqx${Ds+?}MhT!+eE^@D?pT}hPm2_gGvZkh|YUTD9tQ}a7P1}x!Y|*M6 zR|>5GT)!lwz1g9-t{Hza12UE#g6q2`GhC0I5{m0MZgw3ryV{WL=*R0~Lt2#k@2DIq zd)fkc^IYF}Lv`a<@wDAbfDR+O>dn>hbe%XP%^Dw|TWS~mj@tz99eVm6>HhC4RGmr{ zRT>~YDkdxG_6q{(har8Hl758p;R1>uA$2#zv9S}%{#%%`mn&r)raZbp9H!-^lYNh} z^7a+lF+M$%=U20QXiILpqC3w6`GyAbZBg6PFfxSaQxu**FVnZ8#2@?oSYR@;JZ7yU9$ho3AigX?j~cty4`egLDt@!BjDx(p^nos^&j0LF9#C z`a(7Rp9xe?)%1C4`h|&f3{ul)sp$_UiW$0K`gBO|c}>aKbX3`2kYFd`whfwl>DER| zo>sOeW?en+Y#fIBD#_NJ$#!3UBH6kl9@l0J;>h=ivoYK5!+77F=PU0r?3Aw6@4~xr zcAtlXcb6#dE`oOjI`R2E#ED~xzdTX$?z zu|0U6X&c@LFv^jOd$pQJIC9%=1v>=Ku1x4`8>n-8 z9ueQ*IFWGo+1w)7^v9o~z&&vgRHn8?wU_3_~=ByIh8yKhLq5Bbt=!3sJCvjpqcz0Se^rdYt zuERl{&<@;(CV9?!nI--c(p(0dZ_&RqCy%QZUjT=T%$ zln*QS=49ZV;>22=K}5Vyhc`Fmnv$@-NV#Q&BiHjOVe_OJNq7et-tkJ$fLQ+x=X7&q z+wcM+()Xq8J=(yzM>!|KcQDrOK+J9!O5fpq;q#7hPCSn_lkFLlF#V zTchW7H9Ygm1m6w^U88m0!|FsFZ#>L7OHTQ>wZAY~!u#To_8mZTr1uJ-cU$=osbeJY zYh*0&!zxX~vxa%}pOGeveL^{_Oyuajn!Y{$Iy;^jyMp+d%L$d;<^n-%0hxLW`j&Rw zzsoq$)L;(a$Jxn(BMY%?nl&$8MLbl)9}Bicu*v&DQen8qw7=9`>x z!C0Y?cZ2goVvIuGS@J_-jMzJOBz-63GoMy)kGw&gyI*te2(+vGLl*ZC`6=6%wCR1e z#vIuc^wnzjF+TOa_MA3@I8XZwG&zpzE1Lze?87d54*tdbZAVI3n<(BKND?bGxHal> zlT{rPyZThR&M)a0`1gL;-0oov!$HO_yB<_+3}p>wB&3gwwEJ#^^ammR=c}U|UxM@-t={by46^$kRMuu5Qr2eVSnu`= zt#;o_kp4GFe|hzw##bQy|Au(CUt}wg_Cfk!0}-26^Nr6y`cEMJCzB>g{Jo1B3v@&j z?$tFu3+YP+d$(s~+IF15H`<{pNcOm_Sdtw`3hxDICd$*rIbgHx;(r<(I zd~i=(<2FctJ<7X%^p%Cu*h0JSc4*T_@a~R#6C2-zcOOQ2w?Cnz)hTJ?Angq$ZM%~8 zM1*(yxEXfe=N5KO>`}nrWANvNzvJ+SXIY+rKa3f*0lz;tkOMn-QatY3BIzGcR+5p3 zAK#nY_**Dzg4w%$!qs+PQu(6BOCdeEJf-n>kbalRyZzE@?Y=xn&w+kjqoi*#dbgig zit{pd_fbz}K56K=%#Zcn?UzBBcPZ(2mk(|HJ)|c=dQOSmcPXS_3+cAGO5a zhU-}yY|w^lmGlb1yB+=FCt~QHLh){a_>NC966wH7I{G(t+c5zp42 z05_&jvu8GCg4L9t)(L zHTTta7#s45IL<)emlJD^#98{N-B(hn3wu6Y{5H;6`UKcJFs76|(>)*B+G?8~Sjg^t zFhv%GZNt+qaZc9G@Of@}6WYmh;!zSJ!5+ z&56qT3HJS%o;cO>>vd{+3laBogw{F5$n3O`_dqKL>-OAvbt_u zrk;Dj#`tjk+W_rU>}+-xG^FG6t43n&%KxrqRFGg?SL#-kmf?AxB?JGW^SZs?p(#hD z*)X{~{Q@)q+v*)EH$;qA`uh`2f5X*3|Mg&B!{zza*1q!`dy(ZC2z_pn`=-yVmzhr7 zqG$1RrpU=*^Uev-JA9s)fP7C0n0f^(_bTYm9#?R#aT; zOBg6WpM1G*e!d*wd3Tvt^Q5ZfMCOOh^J}%7Ua-s=sH=zgOC`^=7r8#=%Kl>Cay33s zPI$T6^LpR17m0Ee-9NdyzXv=$SCNl2Gap3Jf6cdd3={=av1qDO*{q6Bae59sX!UCa`e2p zR~t;E7}s0b*?y_6qp6PBh%ePo@H{c01FQEh=PY|Mjx6iqn)Rsr znBNi=8VhlJ*%YZ0=B-(f7w=rv#>?23lBP7CVdslC^o;{|ywNw-?^m#*bLQI;r(?LF zjobJo&;sSAbLNivt*876oiWMYo?_iiFc&B^k*!u8J1-i`IUDbz|LKDM-A6xW0lSYL z&nH%6T`=~(#DM(j9>0y>bsDF5&tHJ?E8XAYyWZ%WsG)O4C(t=ezUT!kj)taLl>5IH zDE28~_9>?6u)LkDyt@s=+M5hK@nYX{a=zSmo^#~hW$E+z-P`^Nq?JZ@9~(AlFcSNa zvyHRjZ(nVg&_^5o2=(Fki)Gn*q4QQvz5vUoH%#vXAfP3r0ou6R7M%p7-lj*$0d< zor>E~D41$FZlPBK+0W(9VX|LwEtUQ9`Aqh)zRdEt4Q8Qd*~dZPI}l!fQ>B#eC=I%5V8gLHX^A4sm_ZVV-edbm01+!>C^9uuISAFi4>T%6mP|w@h})f_Iph zEgNtgZWs8yFlN=5U_9kOrX0|JQzYKMXx`g=4YNN<2@$vHVcr#nmLFXc)VXt^Z@uaH zHbu{|%vd^?>v>%2sh&Sv(;bK2gtSu7$xP7Y+u|8b&&KiVp=z$80jye?)Zy#_B)# zSzPF}rG49C55C&>__@HPj9rU@caPz{W2J1*)vIo>Zx2Je(T0u(-8+`b_O_Qsvwi2K z(Zq*#@aG_>&V15Tg5w5Ywi)cDa)dTF>N|`x*9G?N^Dud%w`HOI-GBMHe6pT`2q71`^r_#_2wZjg}H3}hd%!MO!aYD z=sgYEK5jIG>EmX;=_3K=Z$0&KiO}R0`rpSpAzzYUtxXr^(79V$)oj|wDbUAsq1cOe zZJXddshC64?U0@b&zx|TcgG2!NmVgTzZB9x`A=!G>`#5#rIlOGpl-LErf!2>SfQ~8 zPt5y%blVF3!aIcChPl7PpsZ&=e-ia9X17}DQ#JGn`|~06%MSgorv15{_6O(g>!6H1 zv_IoQ`h)p)cP4I#1zTe=e;wt2NhO=R{~7wUm|vu%T}RV)%tIS(QFlMg34g#wOMi`X zq8wEBgBI($$U*g)(EnDhDKVV>XPl<~3s*D!ubRj7f8H6?{{i?CpQ~5>Y2nB0U)A^R zCwwO00}P)>aP{p=ocIFzd%M5y$uBqNh346%_lr`1w?r!I?YA>z~A%g`^MiYXb%> zFP6uPGrerSDKAp=UV|%m_Hw-dHg7LFva26*kXnyxR^9oF=cISVCoAAnZ}q*)*H$2Q)isay+W?#tFQ^b;l1g zI1O)Z3*k)-<;|ELcoSdy!SPUA|BQ?qGvAiXX?BVSW)84Gxlhz>B*p0O+yu|1fKL;k zEW|;)3!|$a^!8$yD-D6ZN5OYIJFk%DOIGs5vwSx~zQq|z+Ax;34AZiewDVco5=Z?Kj@Qh*~U7x^vPg=2k&}N+T zmxBJO`3ms+F75tl5ADuT+Pwq6&)`DpxdiG7tUDPUv(xV}ZCI@Ac^_HK{MzBxhHxHi z1)8HDoSvr({kR?X$Aj#6cX6*JXFF!&eL0>rcJIf09Q7He?BE_nEOE5zntmsw)XY2T zue*#R+x&b|$4=k}=KYY*R(!~b)Q1e;yk8o!4wSs%Gu~8Nt@yfD8%Yz+`>Qqnu9I_o zbzgzZVOvblj{18|8`del{Rl1Nx-s9kabcg3Gkl z?mf=OhpaKA3dtQy0ITrbFP1ioq(5}=Fs%t4JL0$Vq z(KVzUVtM_7lnrDDjMvb=mtoAdQGH|dWcrp8B5zuHnu+7l+^E7mSO%W$ju=#5p0c4~ zc`2n`2GEYai&EZUU1p|(DeAj8yYDHWIr=5(`@!seEWH0%)zOsG(^39Ep{GGZ&#u@t zxHs(LD0W@1!LG^xb`9hdejezqw+OSdi-(r_e2kC zFZ3ABQ+m93q$he<`$vzexj}j;{`^`kJuE;Ez^Q@Kg?@2i>Gvy2zlD^36xWnEughlRTH;U|=Y{+U8&A2JbJhrp zynBxOx7Jo&=dJD%>-C{JPC$R!jrY7}&N6QZtb+%}iXx!fG@xH0&~Ylza|+OSa$w8= zI*SRE7d_|0_i7xNV<~C+jhD@@v#(X>f|{5Dvd|k?H?3s8egb_hJ^$XYF$I4+<*y6G z6aemr#1z0d(KV*v>sh_W6zHLSJ;oFm?v-9T#pXpP7W968YES+6>n!L8v=3v=ZsS=y zG2RAaZQ?`L>i_%kHk)VlFW%;J6M?7g5uB9BlWmQL_?pxm+(DRc7S{_yYw>)I zbGT$$UNvC)NvLNxl$8x-P2;j^CP3bjPJc0`!<@Cr4Dyi3CDvquOw`8|)|%j3GuS_- zQ|1kLR@zw5qwPzCCOk*;$b$xF$w~hhcZA*740GE(Wd^7F1UwtT-fH2SzQOnKd=1EH zS^kFi%gpk@Od)P>+j$=xlb@Xycr4IfC_~YS^ zgFhnUdFO{`P6fJ80s2n{K1>3B6oAg+o^XcoSl)855sP5FTy7@5_Eg90EH0@wdqw7i z>~xajHcXaVE@{YZ9a12df?Zi+(93SaBzegtj@+d~1i2+TkKIjX$d}ueGam!qYeVlR z!*fcbh_4LWXdp7$>vZqmDo*NY?_a{zc1e{9FUSHYSj}h4@A9Sq&AcEJc&=)-kOFd% zSc@`ogr1L{>WT$=;d$_}AP?2Xp;R9745T>tVU+f&W9`~WG$_wl>>(0aY z+C9rNCm_#|j~k8U67~N8KfXae^rD|hC3eZZnFM%o8R(~V#VYS{;K@0_i{rqHYW^JH zLvnx*sGq2t@u-_I#21geFjy%s@J_Z;MK@EpBwCiLo9m#QY$ykLF;1hKjX?L^z>jz? zp6X^PLLI|B->73xJ%BnE*RfdDu^2r2InH%YiOJb;!ap_<*BylTy={lM z*UGMX{2=Puf5JzzhL1xud?XbFc-Rm8?16{KKjazmlJSx8ti{rhi+rPX=!wjm9l4&< z;9YDN-j(*iJFCJwEAXz=5Zfc~Vl})g)9`MLhIiFnd8gO#?itdwPT}1c&RUZlhIdh2 zdG{6nn)K9D|FI5+<6Y`t)WOr!zi_;38-jWmFHxUOS~3vba)U)lYw`Km*4I6 z0q<~3^HIIS@hm9>M{#~Y@8eT!)j~@9#2U2okoJeb4!s@hJDdlocjn@J;JsRd)6SEz z3p@QmeFYo3P~mwpl!5gJ^%cj#B+Bz#4bRaRIS+W%_Qr$nmwo!iK@T6hSNi#<2Y0{m zO$g80>G+md)6viIEr6SX1~-ig&yw(b1y$#IAM1LuS=yJYd`qBwYf$*M6LfBOvcfxK zQ18r8AHz)n_-BARj8IqTx%4@TuOZV&UPZru8ra-pa39GzCTGbSBHhLl-%f(}MC09a zybJG}I|_4!-JQWT6@Laf(00kX^{M)49c?hKV{At%XX!BA4{7P-z)l@0#&rb~*x+~; z=VcdHuSeg1S$X3IzhLgLgB>##>ZpKueY=pFP0#EFSz1oWIMX@g)k-K6=QsISc4?`1 z`p4w8>~od_4VMjCYs_fDG-p`u$+QD__?mmb-Jld zHmExC=mO5UF2gQmbEGDsY`OPFlzD>kXmMfrQNRQIe+3s+yMi;bB_ejCA7h`vdxX3+4kQZg&f;iyw7el!d zeh&I0K|1#3=~Kcjma>twKNx$5F^6r!NY@S+>z70OGt-kc@KJV|15BHi1a^SAA$Mmq zkvaH{fM=q}a~}LohhL<_PK+-+-!55zW+r8?#HB#9WF@9?XQf?6z1YDwJKFug*=# zHk1LJd!qd|7-V5J)QM+Wm--9#Cy?aYyK#O7b!NgGd(m)mpgEO&-y$Ts7L2Z5zv?=Z z^Vb-k`JVrk_FY6wo7|8)Esuy^;T#wG^2}@P-cliHuVq^xEU|kH@>Aux=9<^dB_>Z4v(*&$wa6cd*rY&DoEwuTKxf)*S~zu{Gle z!`9tb17dGf9ryR2d_xu27Tbwu8sk2q5x?~HHA z#qzKYKF*Qb0D6n_&R-1}mqX9eIC=AAz~xDSJ4EJc?(X?*QCD1!cNK#S-K@do_^`Mf zAHd~5E(qZABkcu%%VT$i!DT^%%Lx>hBTya}@DiTaiR%X=fsZQy-;lQ}sJ}RC!gBO^ z06p5^JItSTO~i&YpiOgSp4x7jN8&qGeWdXzM-C^*0cQ1HthWC4xw@oMoI$8j)cLP5m-=k_C;5GEy zyxP1WE1eI-VQu^_6tAZOKOHJw10SyXPJ`F*y#64=>xIRqkJk-JLA-ut0JgBy17275 zfY<(S7jzK7>CtD{27X3k0~;17HZb5~o`TbND>%LBKd^zZ?bP<|ShZiZeOsd#?S7dQ zip`5du$kGuzJA!f#H{WUyfd&*@Hp7L@o~wuDlS{DIs5Hij3LzGvMJ77E0`H3@3IgX z-|g+erp*C*Bq^AR-{JT8Eq=HC3}dC%hP`=OcN^9WJgps|4SVZ+lk-VvyY!y_JBpPT zGpsxX?-47d9ld)uL|^vF~jK`|6?mL_ycL zt(ss8$kXjtpT4bXrnV}>zU9aL zGEi(Cm=7R`tzaiyt@r>m*jj%kur;M;Y^C%6SY`enABwFHhG45Q|4-@X{6D(y`TxUL zo&EEFx9-f$|M@63|Igzl!86R!qb9+#4xT5&vksmo!?RwVRt8voaYJr?lwRiGHv*o? z#emgifYtCjy^LY?OMUqZ4EbOO=LP)*dh|hX@(z9yw6}oP%|knOF9(dOoGkCmZlHB= z6?&P^a^zxPv40PoVNBQh4_s5a`wu383@#d=|KO#04AZGijF>L=2h$b*0m}0NhUqE2 z_z#-tTp`Pa`O$xn4zy|J^W|2cG4&q+uZNp4mT3~C70Bs8-{EFKZUNf11C5)3z8OH< zY@l&^R!`WUG9Z6KL-CpMC)9X*_9y(Y7wq?Z2iTvY_!AZj0e?bT7k|QN;O{*e?9cl; z6#L))hGGA-D^K5_@M2sL`(OP&{0WD?e}BTkx!wH0Q0N5g=93K6~e z6o4M8Pr-e6y{)@Hf$!VyjScz}md-sh{)Cz^{)E5w;!iLi@^8)j=AQkgyr4g!q>De{ z$RuCgLmGdA&=KlS_(uoBy@;8oZ}Z+{4dUJ(z7KzbVW8_?1H-@Ix>vmGwX1^u1a;l( z{xh-eW$3c*WlX6}{w9cptqK;VSVOU}tS6s>p?^LFH{jt0pi`*^4^ILfK5=ufP4mJbIy#usTSxIxNpvn%Wlk`eRkW8%ko3*#+9B>yRoQ^;oj;Qr;mH? z!9m>n+xOuswf=DNQs>U;9xqjQChSIQ7rQY6?8dfLfq1FmO1#vAgF~@!RZsC!*8cfR z)A|uFb?&UQ-(PyB;-$L!O9eCYmll|Ha=+rGdhvhmvM~RrU>0Q6&-t70F;40idENb- z7Lc7=2I%L!ZFa!^e1+oet2_H0CuOk)oGpcs`xW2g7H!AF8)lv-B(ws!RM&2Lh*UF zhv9SF^wXc$-#O@iCr;q^v;KQ=0_P9dzitNybGw?Wpq*-0& z`aj}0fpwRk{c!^I6GP(!-uNmR3`zU`YH6U5ecz7K3Q|8PFj8?Fq_{Z-rd z!82j|n!DJ(F~Pk8)Mu*T>tCZo@%5G-`~XSje)>%Nfv+bo|MBCiYWoUiX8TS{$GrfY z909-PbmE(y-cNkx^W@zbfEfl2zQVUWl*#FXvH$hoqYvSCKkbgQSAk5d8X(TTJ+q5V zd&7=?*t861BT&8+KSFFDegwL95Bakevei%?tk0mav_r111@*>|FX zc>DSHfw$Q|oGojf+1-|X;Y`@F+2L*30wpf%)~HadeV`{>HoJdVYme?5Yb`$ptOb6r zqr7HVTMF%;c3#qk48U5PvvLa7W<=$|GvFeZFY{3xJmf;lHsimyPF9UJbGCxvdHMi`H*~@9Pi?-sbsC$wttHfE zKGe!E{J@mc$ME9F{~dqClb8SZ{1JTQ59^PJEcy{(`2Pd`hy#~($J5$~f%_wl%+T1$ zKXQM>4b#qkf5d&4h592NZ4SlOabGfQT|fEs{Sl`u-*XI?{)h8N2i? z;Tnty;j{sl$is8y04A=2=rIGSS_cnsI(=^DEf{SB+b;b?b%1D+G9`WyO+;ZkWtF;uT$ zs6wai_^BTdetORkex7y=mtL_=HwEu>=^Dc|=2A@z7tlH19qL~wXkqwSG)ckF0SCS9iR`js1KO_0Q7f-(qC0~@O(ymA79o!;V9@9 z-f@ZNIpSH4MamhD@ny>=tgzU9TLiN034x5mI}@6rT`hv(NXuJ0(2y*EPKL*c;^-96W&GP0C}pkG~^-{M`CPi zGzr|H(-{k8or>I$2JPZZ6J0P><%L4Qt34KMotUDb{^j&y5m};!h^a1 z53IlgoohN^4;_QKcv{El)ICz+K~Hs02l|&n9<2Xs;K6&q1H^LVLoM*&Lf}CZj`zR= z^s{v?%EzD8mN`IBchn4f=QI0PDjNP5^e*W1j=T9E{-<9+A|73Fh z%d?pNub)LY6A3mA@&LzB#L<0>9jwsZdKT0DZ|!Ff-Ose# zk5}lwHSg@De`4GJF8!}j=wEym)Bl#U4)^oq+6=p|%0ka~7bDH#>CXfG5qCI+{(@se zHw=nWcyP$xGY`fF0^;nO*J{uw$bt=)b5FOz5Xe)c^*HD z=^pJp%jllnh3@%!WgV2!ePloAzUdQ2_wn|#+oo^)_Q!40+dgJ={^!KASH3Shbe74t zwTpaL0k?-=enC_2$bC%IPr3>Ac2u*xSknVB)p!>Iqyr=gT4ieXBUK73o`^Mh-0DNpbn0;5yg%i>udX-t!S%A4=1c;_-x7Z90?lh>+?k z@8qQNN+PYKYYhcZX1?TIg!e#BqW3`hj}>&_J-@i7Fc$ujbZk8?Tz>5uR_S;BTf@S8 z*wyxN(DuxG5;oxdQt-_dTytv^ta}r|PCSx9#CRcYOA8^z9}u$jD7~LD-i7*AGR9Yj zXLe#czY|y+vAyBiiFDn_ldYc4g8f#KSbNkETob`{JGLf*dK>5Z=#uL7*G*>hy8V43 z-2pTUS1#7yO!p&MU7tWZ{)Kz;3WTQ4WoF1{f&3A`vq*XmrfHx56;oNNXeRcY8bSs| z+*NjGkvXE)&ZT}xbao%!-&vkPa#sJmy-o) zWzg=@^GVKeR!0u6)HO|cSDwL1hiIB3$H0E?(y`ySl)OGQulZE@{xZn_6{MRX-2(l# zL%&zx+4esBqZRP~>#Yq1w)9l5b~8mnJZ^=(tao}Zl7H$_W8HH zi+zQ%@$T()@A>y-B^CJE;Tz=nygVX45pSx!8t}niu9w~K~Rahria9!IVxg7}ag{&FJu;s1}J-I=LmNNN(fg@6u!ZJaE*g@)XY2)i%SU${TZ zf9L*ef9d|GIj+M8eQtZ2%W0ouxYHABc#}YR5xC}j++XY-&WU)3Z02s_+z0Z7bjG{2 z-2(QFlMX{0%}M53&j=!6dviNEr)RX?hiz^C|JZx;xT>rCfBd}P7r6JbDm%EaSO%Ca zYAOYBffiiKQp(Co&=$~^u~pL&uoA_VTR6^WGh(*zzQ(jc%QQ`>HRF;MlpOUIa0sbT@c}XgGHss-;Ibp-fW^4SpI52TSSPYvu6JuO~ zdTUbY&2Q+?KucY-QK~c1J7z}ATQYY*&I{WkfG5bdNs^ih68MX=tyOxhnW zk(tuGido+t&Z_;wXw0oEswm4Ut|-sS#rOnoGk77UZTbGsp_`)1K+6i&H0Eb=wfYV< z?H7)-*mvQZggW$|FV&}gzzGxW8`N=c^N-V{T+0$VcM$w=sEUUW{16_dn@3Ct86Px} zaB(*JAigv|9I4g`7WEE;httDGP6)m{KpiV?bwsb?&Tn;i|48NXxMBHlfXy2Mmng0cr7L-$28JINE@tM)y2jmK2Ee!-&b zLEF}sgA~YDrh(2N00-c;%;zK7(|I++tTc}n;D5(>qmv%~`j)i)Qq-RTdc`>Zm#mlL zf7*i%6J;@~y@y+dww*pd$iw|A*m!vb}9t!oS&RZ0cK{pq#ur zQ8|A52+U_B<~0iQ8?BHYC%v9?4O^0%%nCjA$uWb$+MXX^?N}9PrF+lUL!aCL-SQQ9 zcLo0bMWU(drY$6gM#ZtxtT@gxDP0n4IEVP_a`4yXLeC@!Ju?G(W){~o&9iupndUk8 z9afe-DS*`{8KOHN*M+SZli;2g&Z=AIUajh#<`7nBf&M6f{wN0?s%6PacdVPoLHEpK z_S(_VHP^Ex+aWux7g_AJX4bHM6zrwimt->rqOU5h7mCdA571W{`f5%>`+R1fbkfm4 z@7Fq31}hHq*DaUL*7_{#a}*}s#Fo(9n#Vzh%|rkF1^bo$rTcCDCHuP#hRn7kL*|~@ zZ0W8@_D&J>*J9|emUz$)xcgZYt8O<=Q(E7IFNJZ}(7Vhbm(|UO?yEsvh3ZzB>RLB3 zd+ssPd9teW-rmKkTV`48btH>`sS-FMUEP|Gc~8W=7c;vGAL@7Gcl~FQ6UK7D*mAqY z-u)EtMY6llVy8ayC)hXi&{-k$>yX)!W5&&i&^--jk&T9ZXT4`yx1-)wPfFF~pHTZL z#Q(bbm7wtmUjJ#Wej@6V40_g0gFUf>7wD``;B2<=r^F6Vk^7{S8Wq-Nlz2IVa|7RsStPjH$ia2<7j z5aeBz^_#)>H-Z0egdEI+Jlvr4Ex%rYe5i7%fTz0`(q2Gg_V$X#EP^533_Q;(%Wg5q zb#2hS1j})ZZ3iqP1T2|=Wu+lOg{5HeGAAt88WO5V2Ymn-8Uf4ugTV6j`SuOX#=JVR zUELvMgUYj7gdHjjAUhP_!RTxWd`q$kt%=+w^i-)f;WO1HfCu(IAyv1K?GSpXT;PM^ zq7N}f`v{BO1~@w6;0q+tIie(6$F|{0$F?YibWtAJmzpeV%a|bRZ=g%m^H;#(tC)N9 zYD?Y02!4JD)1z&+`0P4|`?oKc1RRIQP@RZNl%*8_*^=b^P9Sr)Cq@uRDD<;m*6bO;~)_z^v}J_`IfmF_ZqoOsj?JOmfbdj*-hZ*wh$5j8g%h5V(x+%5&tF$zNVNP z<33%5alyM?QDQvsb}RV!S&R|${R&kU8}eA^y?M-<3>#2XF~7IW;ixZ`E%sdeCK*_H zF7yTQaR_uM`qKEAuXDQ3y%q9NX?N61=sOp`Wr?pP-Gx3p>vBH|GP6*!-Z+fu;zIX& zS}gd5u+hs0p+|1;;Pm+DG|;0&M-S35L!rmnKIl7mcB&+#WeoIdM@K%ZAaIDNKF{rBnf{eOu*H=btt z6r3jdO!iHm&+?LURQjAT1o~Ve=#xLy&lw^?qxADxQ%)G`Y&8P!pE`atB_vzby@t}# zsoGwHw#HBK!RCipXCq^UF=A~TMpG?Ip?w+n45sX8tCC?+wgp@4uPn&z4a>AB5ulT) zIJY-l3fnVX3g5F>ir7;rnf9bh!L|~~WCNXSWJk2Ug6{Er{{Z7S_YW5L8&x3H&h0g`Y73KSYy1_j|9&{^nxZ ztL1xP-JwQx|7$>eBugrcYy9KmH5DIa$zJ%laWH(W0zO6%J_7JP&>J7Y0w0q3@!qEf03Pe#s zy1rLxPRwL2=M>gVaguL1n-z;rkOKt1b&+Q<5E* zPdNtpe=C$V(7I7G`9`~3Hs2EFT2~@_-imP!L%w1${ug1ao_LDd5dPlMwWB-%&0~0+ zP4V$O%%cnc)BYmuk#>cU{5NKQ6T~{Z#6IJ8T0au@nfAA7{@s|{`aoJI+L4tuBED*~ zZ0hJXQ2nwjy7Oz2JmP)sN4%!S`6g5w`6ZL7zc^Qa+XJ-zqHX7*zf|jqWQq^^zxJth6L-Iv{E(g856LCI#7|01kTtJ45b~E~W9WZ9=*sP_r1~Y7W-k;r8US(;`b@w zcl56a`6)2M&x|4YG26QFa~yNG2eN9~Yi*8WQ%qT=IY}{WNoBvIurjsrS<@)XGwJ<~ zVYbC3Q`61CRW;zTWawgb?cog8K=Vk@&7lT;JI5C5t}S9stny4=|H~7u`pMC{`e&g& zaPv9pA6pE0PUZE_Kk2HEIK8l%=rs>MUkd+j)qSrSuIuky^amVoM}J+f(mG#bcJr*V z?D{CscvfR}juCRZoY@)Vwj8)~tc+4zd=;qj6`iM9v|6er{hx<%kAu%zL60`Tzb1sQ z)wbnBCIDY^4q}B>%zi;A?X9DHj>X!cK0tVbLZC*qhM#4(6vth7#AtBYf{h&ZN3#4)kscpTHZ68)H% zD@K7{(_)k`)VYxK8u*rQy}QfNpz4wrQmrj=+3X{aOVwRsEqW?`GVwz^b1VToq3Inq zM%6ptdDNx(cLSekF|6So($TN-^>2MYZ^f~OFGwfp_~wEi9Gq`LSZ8+?@y(-xZ^FFz z#)5wS_PC30Jin8^`m^}1;vYU^ge2x2KgL>aD4YGRZr%%>wpfN<3$nf!;SCzrn^ID&>*b5Hx zwL0mr!#VaUe7})mVjXX+2mH&lGJ(sdQFfnJCh$}x@S7=UukLHy3%z1u4YNFWs0?*) zL3?#y1#om%aai8+faMDTOQV2gyAGD?bg-!V187HU_Zlo$;d?LjukojjZV7^JnG1(T zx9kj;j6oipbkmPF33cokkNEuo#MuP9Hs9NPNawVr8`;6i_O-~h}f7@eRPm$l$Si$9c=5d`}FbMhH>Vmn~ zgJ6+TVyVkC9|E|e0c-mO98 zuO(%enJZVv?@ZiZoj=jFho-(IfkB#CvlqK{p&DWg_qlga1P%4$*8N@W+h$|_No zMrY;eF1na^Gkoarn2%R~ea0!x@cqZqH;;Zx=v%&QT?RP4`d8aY*7zWfpSX#G`|~}* zpFeI0Q2lvYYaxF=_bgTz4BvYs{BZkx+IuUTO?%!B2Yh-*sNz@|t~lUNw$8wh>e~-f z9Pks`=S#|s5%BMK23mVQb$qr_`1cdx-}l@@{(Z31zrQ|3`1d=xe;*bmSGT?={QF?Y z*#{Q;MA-WxxiPyW7(9LveB9;SzrO+geJ#D)6yfsk`v6O}@bAkag@2#m?ccXA;{N>> z&A%rchq2D>=d(gS7s=Kh>Y7V4{C4LYgx~%R`R%Y>lh0=j&1iGzL&;gcC`wm9AN7Hk z{UqzKIlIP#f5aG*?a(V4yuFS>%9ou4KfNZyHIFw(xaMIwmldA)ZmvT1`vdB4A)j}y zu6~*hhlCsFJjD5m*U_#Qcx_(Tn4JWj*gUr^n^BB3m&XXb@aZjx)r-LgPW@OEq^GQb`#U5ni$hJ4n0F2P_ghPqe7w64T$j9iO z7p-Wxf-lGC_E$bP@{MS2`*m|G594zqAL$~pPnd%??nunHGL>v+W46g`vG>lk*vY5T zk8Q!cEc@V3J)NzNQI78y>R_YXj{5$Ip1&pE{4aAA^0&L@hAJtcWTRpfPa2S~EeRUT zr#2tBaMDda{8yYm^e~r!x0)vcPtac{2v4AS>zj~U@`2#nHeUoAvYf{{&GQkb?PPWn z;=MNLgyeGAnKxm(%6DYZo>21`*c9*z#b|2$_AIRt!Iq$p^n{UBD`j(s8lS=Tbc``7 z?NON5R|cgql;X1}H9o5q@mb${!d6gx20ZOu#pAP9aVGpdBddmw677itiYFRZaU6_e z?(`shy1{2xW2w(HKX~&hSDZ1+xt`18j4dYS9RHx^-(y~Lbi9!g!ugW!#56G1T9UeE zeU^Pg66m*+vBH)raZYJ9xA)a&asQO#$nxd=A&6e>#`{mhP+$-P4(a za*8L^c66Q#F|F%nIab6P_X?j}7gN1S zcew-~eX(F@eAGHt@X>?*ee!Qm=PNp!BlJuy`3~rh-rPD0ojp~;x4FE1^E`2;ZNBSF z+ox#%CAAm!w?yXc>AcHOef<{bv@Iv$F2`zoJhQZ70QQm=a)u)F{ z&+T#9UWx}urdI~D&iodK%9m1$!^xK~qHO@$62J8b-XvdSE@E@id*omDY$LvWOvD!6 zJXwZ*o~>}j7Te)Jli%?94wv7c#un(G&Q)r(vwP@(Oc7h8>0*l%5nCjS*kYMRJIJG{ z)fHQ8`OXzv{0wz6g`Uvhq1ZyT1Z|xWufh=lM<3J!ISITrAl{EoNv%%us-sM3Y}F z{-~s~xtu3kjXdtyWe_orsArO*GtvThJkxish-Waz^#O=WJjO6lT(ZhwJtE_q$5^{g z;v4Y$Hr;XY7_$=JTDQtphS=fUKoJY+$3Mwqq1r%Bv#-w8?(8P@(mq@(@R1(KnsPE( zXJrs8Z2#2p+Vm%qtyPQ-n^{^qb+I|LstEqSDbSKh_vh%mG<=JUq~UCd>HIZ`?CYg( z_8W86yQZjP_o&13ha#rX*JG$Bg<0&s?FNq~H$Ln3?JDG3p-lYo^`ad(h?pOD65B z(Vp(2RF+vfmSvXc?&9{tA4LD^9u?gcU8}DftnF)g*VXp6Hzz{p!7ns_=J+iA+W>2= zYvawk$JAA=9Tx=IPK08I>XIf_(6J@Cz0tCjl`A^h^laEk?Tn)Srp^ zcjEVAwO!csDzruWj9o#nFPPId=sjAScAmcpX7w~a{GvjPo0-%gEus6+wL$oMy|iQt zt^Wn%?Gaxg{Jlk5(gJ^{HWGioFD)sjzhm*YRa#O8-L37H$Db+o>5Z&mqHfL< zlVGmuSfuL<0{K|E^tYLhMX^Ca7$2*g{vOW9qBB7SF?=l2u>{j@_!%poVZAG#k$P7~ zO1r#2nH!(!B1G*(jl)vMN>ANuwTaXvjkFj-4f>k+K;FC zkk0k2_jlB553#)4@uuaSH6HaBJ;UBv9M0aoZvZ${-md}g!xq*D>i6lr>yj>@^$ofQ zp9Fp{L2TCseoqffQTcsbX^9)Zx2StwNf|j3ThazS1lh_+*2xp`xvoy9uR3(+BnkAU zyZl<+bQK34^-R28OTVK~y=x7Ao_5Pe(Bfa0P?~nLV z>yP+R>yPA8>yOSKYW>mq0#gjAYuZ;25aj9Ltb=<3yhNk0QoOC*LT!5*RxY4? z`)Up%W~+VNq9jR@`tAT^!Co3sHajDLSwoV`W}8b>rrIFO9dnrS4dT(BSYvh9EZ}%< zu7dtl9Jc_MDYv9r=^RZS=y?eKX6txX-PrGFXf=Rm1KAP_^f=X9n8&Os>v-KAm|y-x zR$bPo*0a}2Y)aCorANp%(An!K$zm@Nb7OQS8go;`+-P2lFfUr~@|=&ht}^*uR=p+I zV&97xikC&%&PQ1>%D$&u^uWPg@5|BjyZh##Xvz_Ekj}pVhb;!PEq*@A@Qun?ibZKb zc@)a1{(c|z!|<(t?(czLNg>;y-tU1dl~Uez#F=!?dlLM0?W}jTSZk=%tu>U3wT3cn z|1Xutt0h5n&Rnvo% z^Lm#`bS912sO)};sktHkbhd~QW__SY0et@DVjP-_4Ra|Dx7fE(Suii_pS8XA1&m9- zRUQRyqyV1x|JPK0`|lKejv&HIG~<1nzI|waoFp~<0&{T4((7~w>KNkhZbQ79Z|Jrn zemC$hvefjBELnevpJJ5JS-LKPlLCp~uY)}m_;BUIQSoy7hqWtIyy$Y|pp51k$T$v& zS7xAJS^Pg4eKpYeL6jF4%GF=UQfGti{*{(<3O;~}w?{R+34D`JMRx>bwhbTdZpPlW@VdHjxkZ?;d6#yPiU-$e=8qd-C$b-NIVqIIjxVs1#tVxDg_3mQp zq6eIJ7rW)yDuOcv@Y9(ta}mG0I3(N}FX=tg6SpG&kcM08vunN!wN&BIHNVOQlOHv!)5U1bfhVsAIlCV@8TG!`;XH+}D`U z3n606@5k{mSrM~t*~fL3ukom@Hr~(gFho;*)2EKOQ=RK-fuC}LADZVYDUf?V^MBC~ z&VK0Uw0d96pY(~w!_;;|3g=<JvPx+l5Rd&MIl0&dX)EBL3)JXij9P)>bQjV=B zExojF7u&Xc|1t1-Oc}F&QNfxP-7Kql;wZ;WIng+P)t3nv=>E#FxtA&Z4?W;r{I`w|+I7#UkXHX((?*!j#Wu7O8_6SG@i0?i7x&?hX@5HW@6h{>8`5F|* z7^dDuqPI%g;+VblEM^b*73K1AZ?EAkR?Q0&W19*%08eLwE-#Ez287PJ-49-KQ#9Q$ zqWAdi5@b@BTT}J@fzzwml2%!b^`1_D*E`nJ?o#y5&r^=yPPDyLr7iJ=x(@Edsdv2; z;s?z0=b#bc?@Kz13>^{=8Ba1uuhY5j9_aUO=y380zrUH^neK&-e-|=;fcBM8cFd5d z>UbJ!ALKqv#X*#kU^&vOSL05lJsw|V${=6$dJL0QAXIYG`?q=C} zXLyRv?(Cc`SNC}6L1!Mmex8T#pBcV+pfOqFflo)R!PZJ@|i zrP;vM8jPpe-&&IF^0z$qb~O1fL7kFVdM6o**Q)g#u4Yo%EbAxa^3l{>y!EU zv64vl^JAn}sqd?)?^N(A!IAjW;mFb880`a&L_XGJ8tWV}*4Upu)*0GZ89sc}vF<)< zLbAJ$O8&LBS1OqV9|!P$!#!y%{6?+5r=5~955gny64@(_mrf>edO6#T7VQ#+9;5FW z0uQM_9S;YS1Rlovz7Wce!BdQ6h7D=)3vws zq^AB^fj;AfUjx=fphG*#7K1KC1HFxcsb^okO7443Zr`)TuD4&`vK9D42 z5jZnRTo!%BRd;yMh29WNSz+2#EcSbEN#cB}#XUv%-}5dec)E_(-I|T8PK}A-rjgQZ<#ob<#K`hsAX4Mmz1S#sz452t05e+Nd;l-XV;!z3>BH z_esOINn)+f28_E zVX0Q?*QWD}2oCa%DuXPPV=yyGf)8cfoLCaXGJU~L^=J*3^6KF4WyIr={O@;5Rl2Bu ztNUj0{BL#LiTW#*{r0(RH?Om7fI9ECq0VU0zgbf2+x^vtfBZh>Jp`WVo$mMj)afg5 z)#>v$ZYdw@UB6?gxiOiw=10&=+!LeqziVl(FIf~D{-!l>Iq_*ueHr=iCGqy?Q^Y`_QL2l{o!X+3Z+05!muhads<~XM2BYl8$p3zd5 zCi6RKbVjpa2>soJ{%V4}`&%ITxik z-xYkMtg^03j$hiI0Yglzr zJan_kqNGuNF-EpQvMP75>SH4;_Li!Ah3;XttokU6a>5=3j`xGlT0)FU^XkAlHE$MT ztV26xE6uAm4LUO)_8D|;n*}`K_lX(M|Iq32^!Dyf>5a@gO`F<2m6Q`A_wDjSOwId5 zcY;?yS3d{)QG&5|8Cd;;z{{_U%-U^;qjl8YE_qZHy(1a5U3zAs#2P-3qdT6beFc2$ zk+rvX6V~(g+QCJ$q{flJDw6_uU=u9muYs{iOFBXue(4FCuU}jGVW%XUN=70vX zL5r(FldC|RSxVpXD^))P^s>G-${yGDX|AH$xra@g)bnd0ynh9Kx9pTuT;4oRs^0Zd zu0rpdcI;$tbbn=h13}W-%+d#YuX{LTQ};KUk7O9)_so!DsuoEZYp08MSLyB?o&D;- z?+jzY+W9CiHnGBXIi!l-!iM9Eb39QvTRZ};=L%3339sxmYlxKSFpb`jdNhflAXMsKj9Zj@xMqFihD9b`>( zKAdD>(+xq@MKYU`)$eF%$9QR&V-m)ueH!YoLk_N5O!@KfGertnn}E6M=XoRQQag3c z8+2%kgYWY^YnpsDQ_{?2zkK7La8L5p_^IQ^)JXOtduOaQuQ|wC99TBHkeSrnQ@@kaoNM3LHL8`7v zbeGrGRkC_6^|reZ`x!5-JGg2`7Tq7F^DfP+<+|ooJG1@_nLQeTx)(9~K|=uQ1l7@5 zDLNnCyxLeteYE5otOs`*)I0XaM?sF~SnQR-kmLCl`!xJMK99?>9Wp$%)U@gN%S=(v zhCzPS9CYBZd63^tklz9!zt>g-x_3D$ZvwT{4PtH zV+vdGOs#C%E0xc8mtSeVD!&Ita`~n4Dt}n9zf>o`({%Ft*+?$Gq#sooF3VL?n(~wj zMp^8d9BZ-7N2q&E7|$o%qP~$Z7xcOobh`%hD+C?qfVXA~*$%S4I})-T!tvykZ6hE1 z4fNGwkX8J4~`Ek?g952JLDbT?mEup{+h8`92Wq&55=6qFt>2bF#>ZP2Du;ZWv5dDbavVZ zI}IPY6}I2Bh*kGezRRjyg>oFUK&~k-eJuIrA%U>R0dbvG%uG*Y;A2Dre1wFn5UE^91GZZsx<{{QpxZAOT?pz=DW7}Fn$hKXLd0&P3&jK7* z0-h^?#j1Ag0b$qT2DEE?eb}{Zon13;^|ot!barhN_?>c9)dO$M`P{C3d!28) zmO^J+(BEF2U7M`hwFi3j^YpZ9wOd)!QpBo+dw+N*ocrVL%_5gjlli)O_k($By5@ceL2bc9`QH&tG9DL-*o2b|k~;FiTB`CC^52?`a$W00;!j_(SG4VyV|eVfOT=Dl z@cZ}-m(SKVM^aS3&B)^}&2OW)Yp8x(H2kwkgZOQz^QTHbejB~_Gf9ee^V{x79Gc&@ zAklx^B@H3&nw<#WY>r3VC493PiCWwhZDVPtFYd}cjd54@Da2iFax3Dl?79Bs_NT;M zB)1PZ<#y1R>$6nyt#oqRbCUaBl>Y&~*K6>-Uh@@mt?Bdjy$T9_AJWnNNY#6k<4ECh-+Veb3fnL4;1_Q zTz@2GJbep4htT5O$G=4BpPSG554z-y1X}0jW!hSg8(u6%6)&%!2+HIE19a~X08|~=L znRfhW{p|pL#+Tf&^vTYL_pg&yzEPL*$wr$LY}<@)&*R&;k~^lZ!?(pLA8%ZQ@{o}h z``JrI%~@xD_?hXVjOH9XlG)dwemY<>Co?It)JY*#XQO=E`+N7)mG66YP2KK2Yf(4k1z8EMmlRLLGSUNn5sTV{7ae$NJO?j-nun{_GsHe!CZmH568--BN;CqjFH^Jp!^e3^F$yd>yGIUT5KNje+jn@QYfFWE%`t z;u$p$3}ATodH(hj$sC>kYc}TB9URk`y)|6-wm=}Olf$ICwg_gQZ;0(+L9DRAc!_$R zX(Q!kfPT+4NKFN+SW_jP55!nOWFzIq?6zQwoqVvG$g=D<_-E!(EHVe}8sX>FMDkq! zbZ!Lm$~5;C><{i+y5H1SvcEmakXbuBXsHtEdc$fn`rcxq9AT36UvyU;{n8liXis^a zwut`7p0>lDwnUX>cZ_5942(G+W9EXd$1r+Vi@!l|9RAoYxooyJr*hbqRy7}9fZ`ZO zIo4%$e~ixjYJE_iSjtu3W`rLag|Wv`J}|PsJnvkNBy}{y{FCy~bX8Q>^9aAF^s?{$5$pGdvf3*DTVd zSAot#kM89D58WSK5Xqiq%wWwcJIgAe-QTW|T=&I*uLIqV4QA#$hx%;j4p)wI_}blE zS8hwy{CDzehCzQ1$JmjWLlk%{8ax)GzN<+*w)1#UbrNHpt%mZANr9G5Gpm>#cmA4< zbD?*-|4HZB`2NBD@%9arBUAhTa4XkqOrpD_;8Dz{ZI!{={0&pqr%G13pY~-c&q??f z=)H^Z`#IF5T*GAZ2$y=k-RXyKwfENwE@#!PhjKG14+EX=Zs+IyZL~+a7kIk^blyz7 z0RCkEV0RNA0DpDFQ+i%0h90E5!E}zD=tX(5sLw{h=Vbc{zGuIes+)r>bvwYDlvkto zUZ&cQ1>lX65H62&7p)2S>limvX+7%-h1U71jL&V<=F)hAbcZ4H4#>xykdMVAA6r9} z?;#_5AtN6{M%wOn!MLT%^==!TFHSaE>L~wWo}n?j8DrCWUt>@}T^r?1Tb*A=Yk~(y zVBQ4lYN_rZVAbGkrZ*VD>*Qn7yJrW%^YoS(@p-b5)up0t8p+yG7mwfg8&q2I2Gk~||F(u|qir*}6(7S}R7e;&Ef%DXfS6KD8w7y5< zQ5=LZ>7L95ZOivBN@a@v-MtI0(Y?E8^mupAz-e0;M|rplz;l-?{S#@Qjh_kB_VQGo zJzAdCdQ|RhhTqq6?~bfWFP`;o&uJ!E`#>LG@6Ux_s_(jq(ZTsKxLz1m6c}I9Vmb zHU&Um1VV2Fp+6(~1^>@7E42UnR(NhN`90JZ$pq~;vM|$?6#LTpl2Pp0KYK({HXW0d zjibTWfrvQ|Fy$MWRmd0K0e)Ze zn58!ueT_%#JWZ0DY>1mbKnxxHB2z-cpts>yrivKj;8v2aI5o~d1Z+RNz);W>nYfr-6P2pyTDB=VhSl zrLY5+zz&Gq`t+{n!%Rs+T{`!r!Fk}HTwiHFKfh8^p1Vs{eznM;EKC01Q z#4E)E@Jc9nrSUZJ%CX!0^9u0^@eA>a#v`@h8BZSR0FTf+@uo9FHW9CwiHh-17*B~`J}>sqFJ&>Ok6#v@E`BlU_$Bw>=a(Jd`sbJ8{}cR@aZ3C$ zZ2*4hiave(^7mU$6Tf7fUi~t80Dk#=^#28ZIW_(AevyBEDLIY&GW&G#%W2jxwtx8N zmudee_$BC+_~rZo_~ma=r;lI$aLZ}pm!Q+jFQW(Gm-k2gU*MO(Q{tBw=lkcEt4<@o zTzIw&vgkvE`d7-)$9*95xq2GDwVfyf7N&=6}oWQewzj4bo~KvsPp>Q;)jWudIF68}## z^0sdW1Aeq$i}nwoyq@lx0H)o~Ta+Bh)KLST+KsaA*)f|Ig#cFIF{3nX>UPwB8#FZ~ z1CQCJIh*B}jv6B?)aH9X+Gsf#l0$h82K{_(YMz5=Tim*!>VsmB?GWG%#C#n=th0#n z*6kC-;mJ*C)U*0dpzpQWe1Xf2G|{{r9Q(4T_-0zCRU62Ph{|6v#1y_enR)Y9iD zbmpq8uDffZ4BbP8f~O| zN(MSt>Bg%Ybi7LYQ2u!}TJUO&%BzoqUh8!-kf8qFeI+gZ$bodx2@S)xbi=wqbS3Ye$PMVEF#|iP)P;rv$ffLHL z=?f=xcPNF`%qHB-zelP*ig_H0u-Kc${h@Oye@cjc?J&yLF`U+DUAZ><)pg1wn|2>f z!&`#D+d&=Pq6OYQ@q@RoMLr#EJ$?N%{7%%rMhIQ#kwYT^xJ=V@A^0l|xV%8cWdL-c z0l1WHJvw~8L-%1<3!SFEEA5WY;1CU;l%FRK_>8rs0iWL+SoK?IyGxgYWtSU1c|M;* z0`S9M7|A8);@cg%i8x&9L3xAqD%tLzx0En>aPEutZg$4UDo2)y35*gzVP88 zYwKS2mbKL{4=ig}4FMnjDLZ+);eXpszP-lXwq0cS>2~r3kG|3jL$i}{FaP)L352j|tYQ;^-VQ;^-?$?metgzPTB z&%$863`aX<_*HpuncXa4{$7W#jRIf(blAcn;Nd@|!yb}{uES!|-F4XFA>d=)OWr!{ z+Ls2_VM#;4$A3zPO_u++b=cw6?s_L!{^>gGOOL*Kq@n4sf4=zN*I^&M=v#+<@S?X4 z`|XR~I;`PEZyom9i{3hH+lvG1u=|b(-*zWI+u-@Osh($9f{SOne8{k#XUk%S!n0h4 z*MM$%TG1PadKuREhw7|ZU{NT)(KhgFl7V$n4(%?(nvKT{Yd5Y0|B|dIsCWGM%KeKX zT>QHQ?dfa?@o!vT!T#fOB&BzytQ?Zk2!<_=WF1KZJEQhVlLWuO4!2sF7I1 zMHstnYp$|}@@r)0+G*`$yMxYVG-kJA99k=)`k$gcqc>znv&duWd0LMDWDopXgbpRS zNx;0@Fz+4seFkJBAVI9Ak1;2iUGRJ6k51k*<%MryiBu6AGp1BZZHKzjQL-cqr zmCl5S_fj=}|KSDB??2PY0LfJw%4<=+Oea_Wc!A56KBoER1wPNKb?py`K3BNn<;9mysx2YOpTvh)jyzYX5^n7a=CImV>-aB_wIrT$vbpHr@kd=8qvBt5CZ zpq|h4)|aLqR_yx_=B$gOwq@OI{vy`@Yho)tNGONqfB>dbo?@GDE#st@}sxM6PTm~=*$>1RL5g+`FABKn1s*hAlAOv4 zDQC{~fU?VkiB*o!;k|YO&X0tl!}0Rs6h$pV#q2<8Q^!3;20#+mmV@ z7<#+=dKO>RVVG*08NizAJ{oWRWZ!t}4=ridVZR@5J^!uoR`$wx>%tetTOWOHyfrZB zrF&?d;(o%Bn#(w`Do0A_sEKEV*^(vm1|zd>TKw?Tc@D>rX4`nVKU>=P$zFKhhb%QLNCx;?;BhYa~-udg<}0If2soA5;Drd@rRk^!FWj zea%SLPzrgAmg4qSV*K6+#P5NuDNTymnfX_&>Pk7L%7p%6(2igsymc(hRSwg;Bf#HxBl47?;E>i`hJv$_d!?(BZe>eM;9rHY zVeO^-y|x}hn2p|R>oE+Y9Ba`ltJsn)ag=K>Tzyle$1vO$r2b|$_5Dfkfvo-xu<`sy zfEl(lUD%g4*|N-Bdco3$U}pUSxFOhj0_Z+UkgXa#NO-G_usmaPT(W;k$)c%~N=l}x zc#C13(}H*(=(8$NV(-QcXPMD4EVChzSt(vRxLH#2gdV1QZQX_t+X+Lctq(AC86s@| zjAQo8x5738mxMpUV+XA@MOf_jLk0+6F9`hA2zIOMlrDcg~XJVXw`84PNFo?Bx{$;Q;7YN^+pD8_l`=!t)mneP9^A&olhw@%)XG|#` z)BJ=3&kH{R8)>)qX6hN17zt@W`Z7-Q7>Lyle|vi zYoYZ0(IWS6hw%F<@!d@~))-aY_}C9F-@SDr>+ARM-6=1of_CZC($)JY?s=aiHSd$= zgPA00FXbd%a|XxT?z$&uuX&>Go)D44Nv#*oCb`v}!t1WN^2yoCZ(g}4W0-1R-l>)N zp60G_R!_1gA=ahbmh?W1`I^cD8GV=RpZ}4$b5%4eyd%BpPah9^`AA37bF)AG?O%_4 z_Nn7Dx-YQp_ciyt^29%ngdKcz_FYd^%zi2qw(;gzYiB;$A+s(0;g2_^_s!U!QXV!U zHA|k8w<3H*-iqOKavzNtk&a6#fbM&}-DVmwbmPTYUwyu6H;#wEq2P&rlw^IO)MRx`~I;H~I6bZ9k9xUiwUu z6wpcc{q(VXuG43Uwq5W%j~|Ke$glZ1=BkLfHYN(6%_IJKU<8kU=$$(!9fyOC8K@6F zAzG%d8E?&?cM67EGRH+TE9z7QL)V$1>lUMr2@=mAYX%K-Ktp=dZ82!L7c^`K4fleE zpMr*T*TV)HZUYTNLBl&i!zV$*A8v}Z{s=Sj3mRGk4bwrxbD27yJ~pcM%7uS7RuiAnx#}b{ zTaw>~_z7dtx2RBKb;%bN^~^rkC9Gqs;Pn>NnTdYZ%4M^2o{&1nLwDTq&aeLz`q;K3 zhp+zYk#T)_`(GLT?UBXcxhDX_V*LLxU@UzxY|}cxvu0W8(&=W_bQt}tDa}~g27OBN z$Vq3N@S6&!L+;bJv*8{1URs(lmG;jm&lS~465}n#cp(_C1LFmw|7{p=I`Fd&<4wo^ zdof^yhkavJ_l(NOtL7(z~SRN=BNhYoUATF6uUn zwFhHO$5;hoj$$55sb9ixp=93MuIu+&$y~KSy@TM=osVpB>C_6LYnN@|I{3?e_w|x{ zxA656U$R+v$kCv!@33ed-;zJ4U#p?Lot{`W#W8y6k)jCqm^68~Yi(x>rK>E#7G!WF3KWywRI7?QxqEI}DW@3+yZRw;|qdJy*hyL1|kVpiDEf`pNj2 zzR&Tr_7{{hE_vLUP^BoDHVkl5$gpkGH| z1FR!l3;jxK2(k25p;$xE=3ObVhCk`n5c+C7_tN5Qy)`^m_#4V7S1IK^B3RY}mPWgy zfz}l)9_tE?lJEBw^lJ(Iw_mQbPPFu?`<`y=2~oDMYB=BhpyS0aL|LxR7ibb?_o3eN zqU>W)rs#O~j{>fnbaCR28Xgxt;Ne63u7=COU-~^_qcR>FJ@&oZy2ESwHHk;WH@9}p zyxoK1TmSs`6)g|zMDcD0omq17e+!&Q*y&uA**3VU`?y>0o zx_0y~GquCGpJ_3$ey&;{CHgjzt~T0uc^_Y3J;eCCA&bOX_B_$%E!cIH_d|S)_2=;_ zjQX*z(2Z3S>>sW+54dtfyM`TnydtxY@yzbQ{4}L>+cqY=A_5-FkN5FYYwit^7V)~TYv{{>3**!YsWToxq4Bz zme(oD3Uy_NMOm$`>^o8RhOX?ODEqCh>}yfBQ&;v^Q8rUowqKN8uPggRlr7Me?G|N= zbY&lkviB)Q(B5N_;J=v3#+qzb_8QeUS$1^uw_HA(%+%kvj^uB(+?>LHU;igL+E@E) z?Z#*|x2(aSBnMdPQcaE760LtQv$gpUvx3%E%G*nKQKxqqtJOPVT3%W7=XnONm@)MX z-Wdy}=)vlIbmQQ4LW_AFo*S3h=7a$sdEyXPt0ukYK%cWSS_hp~E|6z%plhWLAUD9@Fl<;>0q_hd^Zt@TziHi_!e zx1t17^e*^5rYlI+0Gr)%BpLkCu*z87+;5zs=GvzF#G-y7>JLQU^y>zouPo>rrDl1oPS`PvhacD`!dZp+%?~=0$1wXL>_$78^1ET>k#sr%OD?@IC!29 z`k&e@Rp%LFdwuxeHtN|S*vwzw?6R4@bY+4I;*cA zyv`#-sPp;|>Kqt?t>HaJ%n7KSj^G-fg=jM7(FlJZw31`VI8<5ZQnbrnb30gxmDv!+gKj z^XDM#{RsE+Pl9~B<0D{BGqL*npkGPHQX9>_Zx6C>C=VB9;*GxFp{#N=f3IduEcYE^ zVe>B#z5|^FYM?w`fOQM{DTlvMQ^9lJ)uC-K{DsOy?>9|ISCgE-Kx2*-W2W*kH&fXJ zQFab5+el@3qD=U$>rqygCtGh@#;VJ25Z|ul-=4%b^$n+Zu21xDmaGPD$o97A-ha`5 zUm4{6#tG%xBpR_Tvb9va4^Y4hwbuQ&V#<*j?>!xwzgG9+Ix>_!h?(7@kGyI8!Z za<9kuH1=p!-%C!O%L5(Mb|}jc?QR`5xW4@L^}gk4vfwYxPE80pb@?itJGgumIqP`) z&03w?Zq#JZf1N)%WjWt(9mBOm6YuZ7XwrL)H%*2KISyt1<$HJt_th@Uos>Zo96o9JMhn6g83Xj zkMM{yv^SRMJ#bmw?|3b}IGw){x2$BT_C}oN+e=#m`5S?`XY$;FTpqdIe=d;AYVjF* zS>@l>OqrIjp5nqjP>DU&0E1IsoNyqz{HVD3Qec&t02fn5Vd~J_&;Y%Ciyg|lD zBYdH6+S{c4V`sfYQ7@L)8%<-Rin7tXEWrnzqJ7XQ!Uvs#sSNl?iA33D?sGN>9@EpH zKY;UOIdk!(9cA<;T0t;q9XmiAZ5DC#aNlwCcL6+(_8hY%fWI|XY2t6g`Rl*TIB@@; z`sshS512kgnbS7`E~0~6ajDksJs<7fqPc=*N#j}P^FgeT&Q^N1s|(Iu75- zW@+PC0F^*$zcCKAuMKqZY;GW@zn*8G3$Uy2-FdxZO4&eM*Y|y>QCfYthZD~&& zcsfKp7Rlp~5|T%W*L{@Qd+^@M0M2{cb-btbxir8%CQ)@F^mk1kx2aEupSmyb@->6o z!C#{e*^R5nZXA@YSK@bx&0;Ug3$*%c(+Rs+@*C7y;J?lX*Q3rGs8iv;P953Bw@~MK z|8*|D33YypIy?N=xq#~Y9(4}-uk$CG&klO4BFL-G7EwpDNoN-Nuutf__oQP(s<64E z#qUJ%JKTp&KHJP~vK{S$MR}z2d!Y6AC&?!dw0?r$L0UOza2DEW@7odnwoyIc=rQ^Y zJggvE0gks%a^5h95AJUroa4O~IT-)!aIQUi`;%I~AJ3t+M{oY}W%sww@y4qYUy$K^ z@-2b4)h9Sy`@_8b&qw-relt_(CB3xncPNMn9>3i09G`Z=;lIwtIhw2#_^o3_ouX9P z>HDrd&V64e3Ezdoitz zCh@l>_5Ee}=x>VFA8dGQBDdiwqgdgeeb|7r4ctzYz*i`R{tY&k&5n6Ec+;d}Vbc!6 zrorzmiY5POeyHL!;Z4cwneF>sp_quD;lKrwue?NKPtbI0>Rnd5o8(bebI=<`C+ zw(fqk_3+I;m${wF9qw(XK9RlYwp$i&aYuOj**j35#@Pn=N+xsKR)z~69hKq5qs8#6 z%EMqwAtRbC)%to>^rij3E5I9HFA=`NIZx(?0AI9r8{&e^Y5%D&v`L1~rN-=L9{*_H zt9`)v6wxYGyyZI96*H}&^2r0QO_qr|+S=p_{IBUP^*jXRXB%_|`I6;<-oE6|FdyQ> zTEqip@VfM{c~foxhfD9*+$Im~*W4@%zee`4#kJZxluS8Rhz7x8J=ow{t4@&J*Q(Lh zIhPKy;b?Qj%wyAYyyrBi9ldnU;C@)v9PWo{^Em8jTVNOCjohF3R@jP=P;dKqTOg17 z>rXf~3}zR97=q2)uB~sZ^IvE0)mlH({MOllIzYGOBv=>Gbn6yw*Af^ULmrZ%sV&y3=2}!f)O83N;%0uk(ghC-h3cb^dT2 z;l=xV%M@?C$n&J=!C<&pz)&^>7}gE}hVmi6u-*?0+t2rg;oBj=5GG)lH3S&09|893kQecZ`W`bMh^jov?0KdGz1tX`hlVROm7%UuNxeOZ32exPYw=4 z&z!+w_}84lVUYd6P@Loq!|rPahv6Xs!|#Rw!ykqK!}~*kp=qvf7;+Q5VK`$5FiaCL zR1E=!^+SMR-4I}?@dHCjls61dT{}1o@dAb$h5*AYLx5r45Ma354-8V6Hw^2B0K<2M z9ES8Ez%X$LFk}n?hKv2c&=TYg!xL8z4#QglhTao{!ypd<2K(&6VF>dBgD=~EfNEMSCnV4e$h+oa0ct2>34;}`i+71$PLyW#H=^y>U}Kg?Gg1p7xf(7 zjty7o>g^Eq8b!UmqTWH&yG&Q_9Z~NsQE$7b_de=n>FWJP)O$tLdt21|2=ylD>b)T9 zJum9jiF$9KUYf4nMp5q_4~cq@iF$?I+!y|f$>p!pdIzm3NhYyB9Khqw-}Lv!@i(35eKP*WgXS}r zNPHiQ-Xl}b_z%~wV_k+A^-_i2QTP@5pf!S41FNSyqyE-(Xdh{ybBk5|y*}4;9z*#e z#Om!KtbQ?KaayOMJ5?RyB&B1VL77kSZm^FSJ&4EX_oF?vp|cURwiWaJ3fJ87Ft9E-hH*6r)i8b*e;{^6qUnV>I!o2_g%z1>A`R5?}}6vr55 zr(AYzMrLn|WA@gwnEj(=bobrW)^lIm^r)rRWZ-K=<+^hUp_r5Bx|xy6JoXl4!a=HJ zrL~A$(393r$R?6wlX_-t@7CxxLRDSHDBq zBH(Iz3}giDi6`|kV)N0@t7t>GXaOz=zm3uU&q=;Obw|6-Nj~YLzfDxf2Tbd!{2;Ub zk;ciBtam^^RrzRNCFb)!>fML23Wu?JU+0L+QE#ww#7jjTZGG@Q{O@^=c&mV0J41ZE zk2&4u1J}g@o|gcJuQu2F!NVLXPZZ^&UFBEwaUHVD#O1FHzl+bIb6>0>*GK=k0#EnS z{4tNYn8y?!^`;13Q}spU5cGwgwe~anguaONp__yr9NFhBt8r8YcqG|%4j>X`bneEV zKGEwE(k-tqg)C3tZ#mKZwKRz}6kjOLgiZFgMaNI}#(C-=s$Z_F-+2=FyVzn6rSoC< zt(~*gw`)Z|bcR4%xBN7K?~U_)DP}$1<=7CV`#+~kw>}FVe-r(K_Qy^HVL@1@_EN8is8dV1_n z_v_v}A@p>H4?R7W>*+U8ht6TCzTO0jUDJ8gp7fsW#L#`c=?{AQdIR}US6%6T$BleJ z?Vin--7ddh^9ffIKE*wogkDG7smT0>*>tvmSuYdsx0%*?pQUuJV{7_h-KBo(w9n9F z|1!UI_FX};@BQ7E>|gF{9|JZZpi8$`gZVGV{7s%R0sj|1jO$Fx0?GPRqkl zy}CK&I_LBUnV)$H8N!@?cg^7UAikeDc%A5(-e-Py9@Ti&|GwXC>iMAQL*lUsR}FAJ zXn}0K=P20`*;;Xw^UU4=kGoUJuKnMVARSI+7fyfehEt0Zr%MD*-wN=yNyS~YnF_*|eCH^nXdJ>wG1RF;2`uKj*QSvw9ZA<2)wS zPtwh8AYT913@v_Uu*3Y0OBBzskdbpzTC$7sQao-^a+t|^A3nM?Wh$-d(EBeX;$D6K zTs4mL(Nx zy->AYFx54Wn6UPopov=jcGPdXh-Kc#MDC(TBAsRHL5Ot^@7b za#$wicG2>=k`1i-+aJaRUFlP>iEnM$$q4KWbBLp>%zv#)<+ws zSm~`F$}1A^weC#^;QNXrTz@Y!=gS5u7kXb2@+(AR4Z6-<7CRc(|_dt1@RF3Q!7xtm_ku&#j)3od(#{(>!;3iTPxGIz^tnc8mz@7EB) z`)v$|tT4IikGg&(^m&%(lit3jJ`;o0cc(IU#j>etKStiq)-d<^HF(S~7kx!*^MhWC zM_<<);yMTKVQz9<70s+o%)pKn*=Ta2G?)A23b&$oPhGy3_K zCFEX{d1aSQe}N8jI>r0nvUaCUvZVy@IF|gqF}-}RNV}_1{uaJX zEd4FkSEJ}}u^u}Nf2(iEk6?CxdXVm!P#*lW6{byXN2NDR#jL6Hn)OFa5AWV&>bqor z>55%Cy=d;(0v*-$h-p)rF`-J+k0!*wPW=cN(u<)ViwD+^r3W}({w%rlu|`p?2_@{VGLSZ=vlyJoOI;9LdHqIYW*O z^=0WWm%b!9*Yu?!8nSNSeSe9*Uqs*Nx0Ce5F++l?-)_|OM~IKUQC=GE(w%DGLU+Oj zyY>B~kG?MzeN#>+ufCy2OGCZ&s5*wwqhvp53{8*TuN#B(=ysNNbzkaoU>0iGd`O?3B?fBBae*MRn?)ud6 z1J|eBOk0P9zPmd}@qAYzJJqKb8aw}&E6z(AesXCdjxIJ-8p8+b1+l$N>(i3 zZ!BEQhVsTjlI_DQQ_ zgZ}NYW=WqfG1``>=1YuG^CbqiJ2teALreglwJk)A3sv~i?T!Z58y~T@H`ei-g8$Ox zN~~Mw%9ZH#Zo=J{Df(Q8PP*#yuHPl-TE_DSKCRC!c)R%KFz`1+x@H-bj59bra|Aux z4Qn?p7P&07wPea=xf_1IdjA0Qq%}`)( zDn2#XKPvVQ`(r;5_O`!z=Z%bI^nQ_SJ1XQt%a=^D;VUQW=i&_(fk9p0^x#!;docFVw=bZDL z^SED}rgQ#u4d?oNnr6OO(*Zp0jDg4CtKiXm(9pUL zm`yoLwRlI%dZ3I6opVZOS_CHPXji!IP~I9rJ~!4PjWM+9 zZRi|vIuE%Fn9u58`RUHiuYI@k{V%?IV^8pf(>Z?}FP|m;+>!4R>lTmy#mdt0bO!hC zpJqBw^RIB6>RIBQ)U(8s)L{AB8HYMw3nO&v#PiFb~9mU!qq zZpx`a_UT&B=-vQ&qt58=6M07W7})b6>KWY)xYlpxkgzkiGk1mNQOiR4Dk!HbmsuH_ zOI@K0pG&<9JRJ$SQT$h>Pgmyg+@K|N4)+kyp}y-kvEH@ya^(5j|Fc|~Z}o!WHX`45< zXH%dfWVS0Xd1cNuZOSRkE~x7-H)tW)_yvz3-=>PY-{!jQ_x9}bFyO!?>p8mdmm!%@w?;2JS z?RO2Si152!fDA_DoD3dlUngnp?wWiAL&tS8vyDztPV10P(tXA1c$~)K6t_X^7ppXp zIjH(;BXdxN@=DRznf3xHn5Dbleu24a;6H@xaY%=iF?Do#2-m~q3a(#<;p#0{aQ!$e z*T>i8%2@lGI9R`W;Oah^jv#w$MAG@IUaev(Bv+s7(=t7m6; zZq>`mGc(+;;aQ&p&y6j9t`a9O?M%n~vKLfLyor8`F0H+UbeHOp zE-wqsS)=ZD)deP*I z)C;ES#WZ}TCq(BSBKd9&pSI>GrS-D5>%bul=-l9I854OkJ3c0w z>x&!{Ri{N_Q1ysK2+xDQ3~l^Y!_G)quXK0AHU#*pmz(%yFHfO7pk0*l)SZ_~_P5RZ zcL07SMV+N?=A9L-+5a1CZQq&U-maDvwaF{LWwDY^a%Pxr{cW+L zTX%)k^{Dqh**gEQH++rOzOQB7K1vs#-4|NB=Jz!ZBV9D2O(wK00lJvjI){9Xx@f-! zU3}i#Mi;w8>SBZ*PO}Kh(bf&n!5p5Qxd0g^Jv`4Zf4PKoF;&sUix;DHafrIkOgT0$ zPT+(9eh9T zEVp*C5~H$@V&!Ax?#$)mY!9SwaPB{UCH^^xZz#-qo}6kRE9qiaXX6kVGe zHa_r`DdU4fVfyz?nWBHA!|p$*KJ%&8{w^Z#X7yf0$BOm@Pj5|C^KPp8_lLdVu~MA# zfhU!*uKPl$kAz-Mra6R8XkQX^GFixy_bG60*!veK-jeY0YHG{@;75M5FOkXdZ8|+AO;-ys<;`({W zC+$b2@??2^gmQwm*5M(ipM%Ff*jsweFPkana%Lr6o2O^a9LDnPdW*0abkhC?lAU_A zao29ti?jaWBWKYf>6zO{x!Q^Y*DRlYDtKR0n$3;w#+;KHUpByhmuBY>~h} zS^m5RtLX28XBxDke*%+87PdhaJ|cPe&27%7hRX%Y0*94-^YVWi z=j21b!Mnakl=!-yA(<&-`E7 zsmXF5DOK#w@fN-A=Juhi7ux#;%3|rRdyj%QogpM+NPBx`pkJ7x5kmWWD1Mvtv>Ws^ z06It~a~RiH0@|L1Ue=`09v>yg?s?EfzSz^C<5{$8=(Zaj?@qAf2e*O4U6;>{6krOKVA19(VjBuKgf?Ta+$DKS&iEuFBAhyW#4LyjlT1( zIbdmj)>GiwTi_S%R|^(e<~H1-A4vP%jxFjm!9R@Uk1}Qdi1x$Lv!7}6?0VFrvn-A+ z>N0`$x%r2qeo~JgHQv=}U=`}po;bR%5%-7Rx0SJpq4$%#P5=!d9x8j@vfR0RW@Yay z2G{4Btjg!)_)BG&8HpFGaPPiHgnqypi^p zr467t>G3b?T}*A{O6+EPkZ!e?)m}H>E{)jPqv`RAlo0Q zDUHcFR*TRl7AGjN-hQ%eWwhUbIe9f_QCnKPWom3V`T~D;8yh`w2yAo$uuE~);W<`d zewV8MGS5)<_6db&ADoLU|9L~OisHghkDXz&Qe~UvN1sy%8M3|xj3)W27?Jga0;ENK)$V33rFp+v(3 z&ZrT6*)?X?)o#vBGTz6uOdJH?X9x6^&VfkKl0RY}KND@9)teJ$qumn&!LW6aba#(N zS{I3pMTo}dJ_zsIIp_IbgvFgeUe-Jr_8;v(RZnukoHwgF(MOdJk_FQ9TSZxDp6DvR6dcr)0(#0=ew5!-4Zo=x zIyqh0i#m08WSrD9b-^la2usu%TCZUEX;YY83B!!`0OztAb3Zu;ak{$*xP|P;KQ9?v zF9N^K_gUn8_tYi}#v?hPH50T}fYyFI8+-xxd7rlh+U7=m@fg`a_?F~vlHW)%2#gI4 zJ!=bWSWyf-UI!lV4F<^1zY-jDmi7;?i-QI0EZZl-;yM+J3y&LImMaS86+*T9Rn+ifD* zdDB#lQ`fantb;$^t73#$pT>!|J9x2=-6|R^7V&VlM!eyLLb2B}t=N09MP!cW3W$fM zQKTQtsd+@r^KN4z?^scwb39+5b*uz^%L+7(8)$h3u`rkCB!r*fjE6W*!Qh+e$&801Ei#6(R}f}qVv6!cS>#PH69Czxc? znS`8PCb{iIUw_*BO*r=Afup^^l*FVKjJ6o$dh&G@FDlo-uIH>_3V!q77cS4?Fy7S& z;cLvnZG-n+;0^A}yxtw)b#95*x@k@2Jo?Qm!1hp8lF(;?-sOcIu1lyfU$kkR-tuI@ za%-vCI#T_-oE5yvuUyR+Mi=`Bt+n?S64&C2XW>%Ph}0%+~o1b76_Y zY@6*ckC@{ykDTW)f7t+8uVh4v=AeA`7P8%L9`=?Q zIgzP0*IPp45cuEl`!7T9O7b~Z1y6oWXMxUE7yy4bVPRtJhG1~;GH<}MY=cD@i}GKf z{GNqLwdh<1@A@|2soZE4oK{uA&# z4|Cht5Lr9n}EkZnU@--@Y1pAywo^@ zmyXZor4w^_>Et|KI`s@M`4>&8HQ`wei7|KU1(AEAK<=gfLJoOta(qkxJg7U`~=xhIiaxKaaRXr#yMfrA=moG@G z-H7tLJ`H$|yz-E+ALUPho&yWAYCR}lwJ+c~tClsXWoP%I>_dz66lkwP`7?{U*8Uac zgHV2Qc(!o*?jGcXg+iy zg_C?~oU}Waxr%nPO`Opp^aFiH23Z7OI^{DLGbl3O8?tRj9Sh{wI!BS|hS@f$GzE5G zF%vn+F~{s?JB|6bS)@Yfg$;UPfnJ!p;(1w|WQE>D@pmWqyW!zz{_X&OH~vI;LY3tw zRaq8m1D+EHqj`REJ8<|qn&-Eo{M5F|Q9PgfPw>3#(I}p;`4~Ju70vUykHGV@(LC>i z^7;$WJb!E(c%C&SisygX3ZC;;@Wv{&@;#$=Gp_C563%y}Y#@~-T4lb!i1J@A%B+1C z$0{A`W0l(S zZNmrPTVJbmJkKh%wL|}UAH2KO8pXS0l%E`EjpE(7_rSZM)+jsl!e0ZP)5EM%Tb}Oo zfTzQ)lGkRH+Va)+F8F%4RjM0nmHMbWyk6xYk8AbgtWi81u^Bv^V3n4j{4Xe9y1-ET z8p@Y!3V04rvPwrLTcz!|b{5z6FG#Q5gln&D40w)Cu}WvBNAv8!I{{DA46F1a%HKu# z?-wb$oq_Umv#rv*C_jjDkE+`by&dqJpJSB{qC9}|FBWyHeGlbTZv{LT=2@k{Gge8$ zwL1;Wd2vy8?FYDaWj2%k@Mgdx&9_PyORUnck}0(daJ`_UXYJo{{ew3Gp2=$2qiR_; z$}W{zr3EPe6UrBsTvz)Kls_se_MY^)J)3`eJ};dq;W5_aC0{u&)m8FR{YqXsw2GGw zSMk!3)x31{6<#{Kj+dHVoUS7Y0Vt?Odj2!35`8!=*SY#Xt3O?(@% zu{zpDq*ceZ5ffhl|LV0;!%?kttWhg9p3+Lk&uXO;7qrsJOIqnvP%EA0b>b!j@OK1(MZ%GODTb9B;?K04`WU!8O|PbZOor1aN)o!nnp%>G(f9q=5R4|z$k zO8z-|>DWBI)DLwMXiZA3Q}HtDq*)cYdQB%C+n|ej&dfi==J|$~V)Oh&RcxN$QWcx$ zbABJ2=Wo9lo98}PY@YXa#pe0+Rk3;g>hEIn{D?C?&(oaIJfHVMY@Tmg37+$MnODAB z^%A#5=WH;54~crIF-0#OPt!{$vh>o)Y`t_UM=zc3qnFO~)l1$yy;L_)FVzp#ONWN( zrNhJZ(h-|pI(oNWIy)BE!Slmg!1I-bQM@v(0IyaRN&`?n7Ug*hJJr69@-dYGkN2*v zX5W~t=DPc~nvdm;l)R-5vv&x}mO9M7J5jzI|9^!~A%6cDQmO1<9&1Pl6>>-lImU?Db;TnDf!o>I}h=< zIS)f__rDGL(GNz^zchY-mbWB+e|GQU*!|h_WwHCSJ*Bbxv(BZl`?Cie@%yu>_W1o- zSxM~v?4w1o`!n65`2AVmh4K5di3?))XD`l=-JgB_+t~eC)^FqYXZg>@@5?6tCb}>C z;F;Kc+2yB!$xub6Nv7(n3MJB$j_L;K66r@sH$r;RG)^y_o1mA@Ptr>lChMiZ6ul%( z*Gm^?=%q`u^-{4aqcc?*UH>a!y}D5HzEUU|)oZ4Z{LTfx*A+^qUIT3l)p689<(mJO zkf{xYQq!A-QiVFkTBeS%jJQ^}u~53`DU{ldv--_}jDAoktyiBXsLv~YGT=G>A)cj{ zFH_6cKN0X;*;XiB*j^YlmaF{*ht=c{OCbE zOQowJH2#|f8TlG?sm~GA=d7Oz8TqzQ^3@kgwd%DUq4yUDJb|NylGKRzm#FVAQQto! z;OVE9^;gSAq3qHr(4>~nRLd)V9`IZ~i?*xf%hdAP$6-4!6iUsPK<^AD)vDKbgswjZ zn;Rs#u}S_ZOe$9Co2k<0o6e;5)1j9Jo77KjZ-2GDjg#@bX}~Da7KPF2Nlfxj#k*5% z(&;ojdmM|x_s|5~UxYeYHuTM?b2pPJ)ORdX-*I6q-aiGplw*tH-4z?|{~37O$0n^; z+a;*&IzAll|0!%>Ut3sTt=RAr!$1qJoyfy8Z>0~DWr^yz)jAgw^@4vgWN@HOx;WG( z%OG7Jvp~6S#I;c+YFUX=)|AJjQIEiW4717dOxKn#Qm&os3v7Rawhp&R33%5%xYlW5 za_t+qcB&7PmOl*t!Df^0!L{dc?LO5WpUGj;>yseYciW`rRhzt0wY}bKChdL*IyBZM z+vPL3wokRchf_4dsRv=3$JwMa6Ks+f*Lm2$`h|);Ww@5RNGa>HNGUs#!X(Q?^f!}i z5|8#ij%zyA&X!Gpt;w=Tjgxdz<2d*@^Wam#535f@*<_U6jWUWWfnQdiZIS$yI@uRG z3SX-pep-EwMLGwc>pXm}z(AD2Z>#TPk))wI>C!Nrba^<+;K$YXwMfl(!#5iX-)#cQ z;MdjXS)|ib@Q&&5;bx!=ejdfIT$rtsuFTO%C!RqW{J#2upkY4zy%L>tu?%JK1M7!b zq^5HCV=Hyi@m2T_zp#F|MLJoflTNLMpZE&?!%wWYStRc|e8XR?AB%R7&p5#%`;GOJ z@D1Owelot{Kh{sj_pSJzfo~hWr{H^Bw7=IdI<~);H#)Yz_r$2!{@xpR$M*M5-4)y4 zyZx@%{@&D)vHiWZBVzk|^|sjl-u1TF{@%|EGXE+ZWny~J&=?A;Q2xD;cLjpxA5`n;o~2LkKYJ6Iz?ju z$Rm6uFMOst_Cm__uBVS{>5$J zHF!%t>~Zk-1o(Rr{5=K!o(6xK%-+0}Pv3=u1H^lahZ@3}8Z+!Rlk-jnU{Atw(eyWe+8~_}$*{Z)QjP zz!!Rf=X0WYeh10}@Qo$-#@*3}PR6zDk{-2x!?j0p1D=cUjW5ABepK~$f2#Vs3vvRU zwm$GV_%wgJ4!#fk<3HirKXC1TN)-EYrKdV>q%rw5`o!_ZjN}`ihi`lVzHtD)u>{}v zB7EaZ@Qp9SH*PCyf!XNeY+C2CZn67<&o$g9_MTs3?vr+pctiHRA~Wd4T*DYqGt6%0)3jpml(8t&h`Hr=iMni^czxDr zQIo=>ED>cR#NNYe%znsV1KPk0CX|g7&+oraIE#MdLWu=s2`ICPY`Wg*LtmtsW*@K3 z;zZ4KyV*FONv2&4b&O(SlflK-b#eM^otzq*eY~NG;wQ$4y;l~BhpI-2N5<8d*|r`| z-@0_C=63sd_MyYfZF874+Z|?pm&2^x=rHR%4zvCPhdFT8;A-fb=gd8`r=Vd*p0gLe zkM$kkYZT9iBeroy&+NI;f&p=D&1SX_S;)JXcCIz<* zc82dey*Q&#xID)yT$%sR^~$wx7J zqka5?|5Ri6)U}-(H-^RTpuhj4H&{jUd`}!{JpBQV6Hc^wL$Nv!`$w=-JEB-@=o+}hd7IK$Z@Lz-9 zOr-l0UwuHJvut}kXpu&nF}^&p;CDrwsWO-4DC_3xIywF3tcm$KBNJQJ(P_=S<+pE0 z*zc6qb$3T{Yxz{xx&|L=-xe0RF7HbSd;XBv?+PoI?+HDlsE5<}WH2jOrrFm#&ZNYR zx@;0*MKKWCK}xJ!EyXgaF(lj}Hpf@Cq`+6U6rb_}Z;IXQ$C!{}?SmK-Q``>43cq94 zxV#u!$#X1Lw$F4~8S4t1{dY#rv^-}tJ5$85iORXCTMH<*nsT3bvy}5u>0H$2aiay$ zrtt7K-W6WAwmG=j|4HyIV>g>r(#!<9C%nEKN3xAMxA#_J+s`&e%1Vx}HNGLoF(fKJ zf_G{JT~CUmuosw?p?JrTxhc2=#mEtV)a+&G5((x_#&g_3jR6QRb$s>n0 z@;}G78-J0ZwMd&&*rtBp*yOViDPBGueEjQD+q1OK>x16R`Tkmsv&X3g`zhWxsOj10 zH@wn)n}$uCZ)46s+StBFz`K0-Bz_GWR6sc@p0Nm|XH=KNv(}bXz5KiHfMauT5aR-J zY){*JM>PirQ*3U4@8%wo$TqD{?pm2~*dkG^{=b94tOp@azfQoje^w|wR5m5>e}cxD z*Fa;YJ~oXH>WD^bD~-FYGL7$p#=q(8^J@>jaY>aTK4 zY;FT+Wt=G?)ORT{RjoEFhvO7o&|1YlMvK@#SJ4NGxzacs1r&2-x&itDy~uG~7pW6g zzRiCwQigk}|7&hgbow!iY-`f5)2GY79n85~(xn?$DCME}Q~Ga$%^j{|XDH7Mo64N4 z=jvUdSW}9v_sM%?mH(8RgZ34K_6TIi`A#z2_GD||yE6vY(_Pr<@OVVdK=JK41B7Xo z{Qd?u*xkh<&E6AyVfL2;oC5HDow3eO%$#+{3R6-g^^tZi=W~k9bT368@a)XM0J9t$ zyP0C(8`_lbMT3VOuJD;Un6gC&%(7I2RXnmh+cTEMMM7ip|vGe(xnUesUVir#-fz zI6d~I5~sKNSZGgQB=$;vlXQ0xuwR8X{2JJY$1-xfg8ee0jc0?G0sA2tY+prKjG~WM zVidpa!p_ttTYl$;&(zTOmF}Z%sO_ExS$4F8&1aL9w#(0_IL7wcUent4e2n{Z zFRO8kX#0P{+P>urrR|T#X}e;FGv&5VjL~+=Q&bDOD$wo&U6k_Ar!gm8v#N2K6$xx# zPEW`R+Ix39?OY8y=~=ZJ?;m{2;3`HP(}qG}IM3$dxW!Q*s|%Bg*RuSoFnuF=RN{l9_evZ+ZAiCHR%3*T-iwMZU5JOHy%ooYRUB`}{p?Ds zE*%cTbmqaZxMBS7uVVaBgX+6fk5FS+y9b(M#bA~t?K{gGfVX~t#OvG_d96FZ^X^OX zzFB3z&rx34Z`J92<{Hf_=ZO2!Hm`w2uODMPJLXM`@C$YR@QKj;VRFE8kH;E4f0z{T z+?N$2z60gsvZLb}@9z}w+@BLYujot+c!~@baav-H*|y3ej$CaOz2zFw0w0var+$@I zY{=t;x-$6dD=ngLsNLKP@Ca8b?*@0*-7YJ$P#FVi|Dit+DB`!|&5jYB=wR~fVY z_}f609lis_l6EyRsap}tXOE#S?yE!H5vc1ew}^Ests?PSn`FH2kj8GVhKzbw-7T(x zysj%PE2zg9eQjxJLEYUoxb}R(n$qVAUM*c&;NwS%hX&S|*Z1aV>}+0Bx~!nObUCh7 z;+jo7lsH0MSGuC09{%#0(j~aI6xYfN)|OTjc%TED)@t+Dl`bxLcXukuMb!AUnZ~b% zy8;p8SG8@WZ-(y=O>#CCh3yRh7UIu2SLZM}^?yck+RZJ=-`(9e%Y8yucUKzA@!9UD z>gYSm{o8*Bs}jQY6YBm=V?Fp&BU%7g0{?kWLrkb zeY;`6dC2+&$T{szCO%5wLsU#l_kgFt9UZs3p z0-jUXMa%hHnE{V~4<|M3=cHo?Icfck7Qs#X{=Vj<#&0?4L_H^+JjzL@8aXLZrL9wF z&MiIQ$y3X23a!bYtZf@A)9{Wmjciwow9p-6jk%#*Bj;^AR;iJ44NUBvXg5=?Lb98% z0iu_86!@X{cY-Ih&t?tvNBS5sMV$kl9RsXUxHZB)?1H^+Yaebx`7Mz7Ts$|{^ZF;p ze%|b)*w1?%cH$H8q3s;^3D}8$b&tUxl%Iq@cyb*R8a8l3<3{Lx4*ENr!Reiz41G>_ z)4vNW_M-FeuS;XJ~p4|t|ISe0uS0UBwZuu!Bn6)jByO*V1b({}Up z-zAE@Q!L`t(oQI|ikcgh{R-2bH=!&+Ob6Z2F=u!`cyR{Jd3_u)=cVl5&^l+;DR~@~ z|5?uZ1Ej;5?xq8Z?)Q`XvJ7|HSBh4;{_cc#{DF6JfLTQJ5#=jo@ zn-03Jb(8+LT@&;73V7DX(D6K!Z+Is<8R~yJa5F%@l)3YJa0zmxH1=g z8_Hj}OWAL(TcoUE=+(7_kv#*R8`QEJ)v`bL2zXl8I+QXU%07nvHm9)nJ~Xm3z2N6i z4x>x>T*QaQpGWXHjL%P@UqgWRhgwB%Kh`VjWMANUe^sBi6n5>OKeq~ZmQ1OA7-Pyi zN|czMuVBBvf}TZJ zK7K5GjTEsyaWrgDvRvO+)>-uDaZ-I{vY1Qvl|O+0R*A_r4)+<7;8%?ksqUqDT?A=% znn3jU%I*M-KytqqgM@WGoiES{|L?=|6T}pH2JBTC>=^Cgc@?(Io98fB!{(sPXxX0m_%TuT%zFa% zY+HJV=J7)|ZLm+7r&jzRlhd)7h3%QlboTsOv2h>lS8Us<&y{)Uuf9-h-Vm>1;|?6T zijA{n@4En7c4^zA`Q*=>SNBkzlWm;FeVNxek7hAB7Ki-vMAbhZFd*Pr^hUIQ{)_$r z&$I7F`{!@;3wWN)jA7II20U}Rhubt$tw1&n<-fd6@z49~DHcju-=BM9z;l$&F2(0< z*sJ3!EP=J1tbzWhcRika{UT+(t^W-H&$5L|+2Vyt*|O^cp3w`GvJvXKTtgrD0~(5B zVbY}>_TJGdCeYbXbf(4?{yMyelkHzKK1Wp>cnF_k_)v~n@?U6f$Oqlr3A;4{?_37E zHClb=A=vnjx?2TWKW@-cys8>oiSq3<-bDE_J;lZ;cJ8ShvO~&y2jTg>@%+$pm*W1r z7AkAg*I(EA+$Jrp87lYB=-K+*m+{<-3lzJ%sfY61|9}Vd>;omr^{-UByeS)Y6nvP7 z^3^DxT%z!ysXN6lKM)v9m=g;n|r|=%XEacx9YM zYMh{vq)8g-#AJ#`PSX+C$cx5A;;IDEQE3$Y^Et`B68!_-b*PlN z?B(}}r7K|@=Ub%!#)EeFYL2q8Vrhy7<)cK}hwXr`<|rGDGKNo~=s(LO2YfX<{H40* zHKP9!CN<1rf_EwIg}>x0<#Ej-dY3Z%hmTjviNh%GIrwCxej%vv$q~u}zK%IN52SU6 zO!uZwgH`M0^8uoBG`G};9=-e{)Hhh9_HsGDn#Z~542by8>FQpc$I0gmWPPjHp2snk zDo!2|m9yMxXw6w(eKY4GU&3os`k5Dx(>#+7eT4GgN&mOeI9MnDe-8f}fH#e6bHQsL zu2DJ3V2 za-+Bf{e%~CMN^kj@~oWp~Kt(>T66Fu0)RDW`AZ$G(G#znTFXpQV<|`N_Sl|I^g(PNDliw-vG& zdX6bn4!P+0snTcM@~P5ijKlMr(v-Xu?*Aw}`{`#&|8dvhuzAHaI`4p2a>MJDae5Q_ zj2>SHs+fjtB3{s(bPnwu#F)<5iAi*x0F6idv^N~jrSTqUanbytoNHN~I}AN<@rJAP zQ)QX^y2?Jdl4Fbf?+bK3Z?ZMe19(5%h3(BBXOZY^9hyrkf(`ifLk3qiW8;m}E%~F8 z*x<}E=Dd&yJ3pP}D`#V5x*ybI++~BGQ>Kia&NUibcE}I;4&*n`xYl2ldHgRJX?Uk0mu zxKFNw|JzVbcIe8sMAd#5=YX_$qTm&hc@9*6|Up zZ7n!oVwHSl*NM!rrQlqdRjOarQ*20tuTa5OHjgNQA7PD{q7IWRWE#~?OTg+aJlYJOFdncoO(iXEHK@e*Cb={F~4b8KixUuZ2zc+lV~VoaVNHj<9eSyLoO zkae2Np)>bL-f3Rk3qJfAz9#*j%9OMHj>CpPPusP5%DkPj5BW>-UD1BZFHO&(Yjlp^ z?W&&}F3%~dJU2mxD;V2s*DQRedS9@L#x-79Uaiu{c%FS4bBcSz&JKglS`GxO==?A) z?7SUupJGEp{{{R{4gE*kW`3$Xo7zrg)czv1{WLbFI*)&$_}p*&Cw%Ta-JP&c&Hq`i z&YjcRrZ2U1owHYJ`*Z2r6kFG%o_82->wL##TlZGDt+RJ#6Ym7?x~sOXxHB7E@jHuj z0k-&}jpYNcP4-f)lQ1to!(3zsm0ZM`?hGC5-#QxSDfaKuHm!3L-chYl`phCa3uGOG z4`y&uy*gZ{Jjmzp{}-ZqZ<#V@^%vZ?ep=+5RgpShH7yV0Bz3-Osybga4gKg;c`h*1 z-33_s*0u6`6`ti^ZIR`!mug?Xk8SPVnGGqWv;4lEAT)q>vW5MoGUpbfGL}AHu91EZ zo1y7dV=hW_n5SmJr^Pr~OJnTO7OAF?Ig6m;vU1zNp$$|0&p0_?H*g8OWaQg+1N-DxH-YvZogEaSXCO-Sf9ljEYSpEcjHV{YCJJ zrj4`9m`q=#m-*K)j6*rmtrLHjsCN~Wk3yXq^RZ!8$xl8Cuqs-4mpB!8P6M7(EAJMI zR_36e;M~V{X{4#Zuc&;aIDqCo66yDKViE9|3XG-!uUQYlmVv)hiO=Oz#A)F9G+=iO z_EqLHVF;d21Mi>i%?Tt2Q_FrP&g{aZS&)&bvJ8|Jyv$ndo0W7{L+2Al+o#ZaMDj61 zdhtYqt42MqhiqW$x}##FUnk!Qn9YNql+vp6&c3ic6f)zO4)M&BD$j439N9*dVWWz7@XSNpp3f^-fx= zt%jV2))0UD4wKI}3tx}yrLITTHnds$onjS2{#%cUt!t7MS6bI3W6E1~mzFijfvUW9 z!u{UMt!t8p!qy~5?2TNL)T(y%mAb31c~>>aYu;~N^P2a?MZe2QRpKL-w{3UWn)iPu z#9s6MVnX|C-Z61uX)U;%_#pP0_s4scwik7v?GMLjyH#y_ag4V2QrrGYZ>8P$wA1eD zHtnuKyD84&Wt4lv+I_qu?JjC<_nUFrU9PsfcL&WVhX7+wkv3egc0pWO5oeEO^SXmEeEYA0%8C+fnm zx^qvYow&G1!S2NlVz=T4z-~+!b|*6=n)uV1j zn>EuSz3P7sfdAP=^*=SL|CtQ`Q$zk|y8Bn?&wY57(r2f;&mJ|nR)b$5+O6Oha8O`1+E=fQ%`0!Z>`xP~=BT_Hh5Kt%UiE|jQ4e0xSTvlr zPmU_`a_?@%UpOa^bF|I^RS(Xo{=-wdm3f~1-q`*^xDM<(8m$99H9l?!g*a00F z-b<1B9ZN0Jz<|1W%ebyp%FQ+!(Sr3^vs4`D;#}#36Z&l@fquPe>d>i3@g?_ve zJ4f#xeOZzDxc1bN(IWFbRUFSh(266;JmDCz#)A5%cPp}9*#UgYz85})-y5IVSHb5W z4_pI2)vfq^_MXz#H#&gNdKDjA2%j<@_#}dsPQWKg$a;+YO=W!Q#W=~D);e$Eg>QNB zq|P<|l+I<>kC5lDD#lwRIadbFi)(CR9nFg;TSOY~_-I~SW0lVeKSXgo@|>aKbJt;< zNN1SuO{Cm3_u~Ec0E@8#=xL3&2TpgXeP)(7dhXK1Ecs*h1m7CN<Jh0>yy^! z499cU;u-X;LY5`Zr?k}D)LL(Fcs+ZjGaq@;sro`S-y+W4hJR3&CKS2}y&P1Qw zb{NzHsi!Fuo8^pjXb<2@`*Ypp_D0n+s`aKOEA<@RhYdj`^&QpEtjshyNxfy#b0 zicfD_w&9QZsIo-^4e6IsvIA}7%=)qD_@##QfT#cZ7%?UktMyil7?ZSs=jQYnF(zFC zo?E)cSdUE&cy8?xz8ye@ zP?i$#^tma476CJ z0}GV>ke@A3&q7KJc$(C*b81;S%A(HFO9*%djldWnL7CShdwdQbI-4G2W%x9T9REa( zd3i;z#Jmg|Wr;q^%^2_u{$jMyc7N|AL%=h1qDAtd{0_7$pq4xI0Z+af^AhWMFY01H z@1RzBUfcb`T~U6=!xpJqiE@rkcXe&|Cw#!u>rso8zd$L!Q(Y7OgC^jixSq7fj6(WE zlaTpng3wi)D71~cGG5Pwgqt{_(;$tIT)+#RjanhKlTOg4>jixegK)_(G9s2!&f%fv z?jRW+4gKzad!F;0jX8Hhzw@3g{>>OuVx`h|Ft-JIUJ)Z!Z`mCIj|2S*#R<|J?a*Mb zs$y1jz0pGho@Gy3qGE`b4+(gd|H=}zcYW93fT!~5=vco_D7P=YTU?twLR?WeBL9TJ zA{8w)h}HU$;C{+H^#yD#yI%i z5C`AuuTJliG*1{0-`9DLKSPVa8eyEq=cT_Wk_O;@KknX`|-DIUItNP0KK zp?8Na4!*iL_-fP1$3`ygE+Ji~sewu&Mgs*eLZ@pocdj9`6 z@#n(G@5VS_FWr*~zceeCb9OD#Iy0)Z&UCxh*{im%oHvDh;O<+L{76)v*5-Tt@dk`9 z4N88M>CCwn_0Fa+N#`-RTIw9=>s*{`Y^g(eRnDW%<#)sCoJO7M);hg;`}hl}b2hxr z#C~{=DdIT+)HxPj=a;Bc-CCy*_@6@^UwECD=s5{3b+%GG3+jCFE{(aFbFPQRH?im9 zCxB|W~<)omTjmBJzC-9$Q2PxmK@pX$}>SU2-EwMd2oJ(jd)3S-PILMry zZJOz@Jv$cVxX(G9OPt-vC%AhDgA;GU|Mhsr*rZOCvk%M9m2=`9htJU!Je9{&<0zjK z#tmia`2u(kt?!1{-}y;!ujSuc%nhhd`TP#c2*kFm$* z$Q%{d_fTZ==8#Nw5Yq&-)d);y9v<;*4rh`voe50)1Jh#Ph-dRqJ_c>dkuf#Nn9{ja zZagE8Fg07HG1r1A>W47h@k#J4IoF{Y`x(MCLe)6WVcFm0ec==%zv%|m&+n7(JZHca2M zTpd%DmROkfPc>Hd`yTQ+za1=}YJ=qh70V^pfMtZv|9O10&aWB&>{yhytMlTBYt#9# z`q25eV(Pp~OH7^b_P^8l8{5G&rwyikRZMRSVM_BqQ?#(LI`lz$ApzJ@92w0ex;e_f zE6dfs0lnlLg_|f2#A{*`Ddv;T2ibCGu!?d!0=vyW22TARun4&(i#%^Ld?82Y4V)RU zkO^|$c^%t~PI40~uu3j9ckuPNXTTbZu$=ObhS`M>j{WeAT+VI|z3OwG> zMKLk86m!^};$q-SP@bY`EI-yeB6wt1c=YbZFrOgIALs}#suNXSfVTo+lc@0G?sj;= zjBH{*J=;78`oLZv(ZY+H!+8OjZkHE$-*f8wD!|i*6!4;(!V8PzlLD*bUj>DZ-322Y zy9&lao^6gj1&{w>ggA9MCr-V&#{3xJw5(7xLhgSKziif2i!{AdBTjYLL=$M3HH%5p z;GY%!UMtS*&06L{n&Ah8d;pnWLmlHY^Bf)G*Mu;B6%)T^5x;a|QK=RmybJFyD&@o$ z9u^W0qu(2gha=YagEoe)Izm8TiJ5kH#-8@68k}LeWwt7XOI7H*-Kcym%10GrD8Cb9zrJFT(Yv zqj)#G^Zj+kYi!k-tUFpU&u>R(ERptnM*^J_tmPHll=O=ZH|_m*}>Sv^-C=QIkz-Za?|&t*p@c; zjl+GL)%&W^o)3XF#S9jKww647;b#z%-)6LrAM{QrkFc`$WBG37JPX=Ck_q3Fp4awW zgYYhjef<;O*F4GKqPb>kp zI4QUCy?M;_9e6}@1(!^;r{#WNJx;hX|32_X&3&o1ZTJ5uZ9S*1QJ+G6lR8IpPF-g| zW>WTco>Oz-9xzhA)(rRKUxa*RJ@}a+T%MCDT%3_51g3Pw`?`U*-6MD#h{4+SAJFA zc9nU1rbjDp8}ROI1MOYbhz^ZK?C)dF%iFkj0SVeBMj%*nTBAh&=5=$8nRyL?&m9BKE^M9xxZAh|LlY$pn@{W#;! zv0UQLo48Ip@8yzq5*^-hUi2DtV#9{cLU3KGaQw|K!iiUCu9J7xCFotD*m0uI$7|em zJn!zh33TQF8!7|sl$R52$nS#khIJ1J$2Uw6PP{o@80|B;2jE@BoU!sAE~zr{U%Pf1 z9kr{LZ`rwX1(#Sk3gwl5-?ejvh^c+SVhmhmU>3iqdF%19)N43{$9H?VVp%UI(FFAqrFN3Y8bCJCUgV<0; z@iSUyJuu4rg1P+VkgE+32&5-NxmRAEfDh%X$mzw-$a@}}jkOiDW=(rnhAaChDL3sc zU3r)1cyLqkqU_Z)4>}5V?VQF~*#w&}+y6S|d_|MdNc&t~O14NZ!R}XdSNfShb+Jga zo_mq+=^j;X32fxMRr>jU?#wOR?}l(}^AtX_Y7^@A zx`DmTE(IsjIcU@u<#NVd*Q4HkifKh37{K_KTbR9i&0(dlqJFFguJ#6|)IfXrc<0Ss!t5#Na;Aja*RJlm1jW849Sqr5>MtoLbZ5|>3cK2c z?CRb)eWq-)UKnX`o&Wc>+tpIs=l}OL*j2QP?COlS46aplhJ%XV-#-adu`cb~)fpod zySf+eyZxb#^_k`#k$tAO9JVtLePtyRN150r_)9Oy^Gr789Khx^Z;2;X11_zD#W$U&`mg%K5bIX4$?&j;@g3HpwE5!uuO0gAVv?G)EH} zS6Y`@1j@Bbc9e2{*UR^%x&J-@blBiuUJ7oC+T$z*)&0sE=Qlk$SFIA`?WXbZhl`l- zA^hQQo0;$}aFnl2unOKZW&GSwqWGqi_q&>6(ZQbsXb0=uI({bEl>Nl};U|vhn4kFL zPZU3q*10C8klu}l>^=Y=@qXwV#UyD%e&P#jL%GmZKk<$?Bm3w-|55qxFCQh;jZ^m6 z(%j#|M8#KW(J|ngk9Q@6tuvid_sp zN%EIjs-u9Vmf}-}&tiO*;IkB;a(pWAS%%MYd@Au-QIPwmt!B#Y?q6rf_xI(M_&Zux zs!wnRgFOXyW@SNe5-07t1v2%TML0IaDizxqZ6ia_Z=cY3! zk9P7&Mv+f4;gf(*B0in)NfOJt*hFrbPIM%U5J^v$&9X>@p>_!`Y8+a5FL4W=6w?NO z$*wOHY40=fA&CCUn{7AyR`T*5;|AEoV6d}5{<7uS8uKjBN9Wd2zUen^Q!zom(1J;s z0hmxM^w#y^cqFyKV~>i5_*uyQYW6kTXitX;xFiU4rUYR^<1pI$Pc~?04~^>_-j#uI zT@!479hIy5;ocp?T<2js*e!}YKMmaMs8^AhQ7OyN0nM{P9(JNkIWM3NzC4{5-830v z(LP!s2zztg0JNuXp>XW(*7h`w8v~shEi~ImpOmwmX-pW(^=^bNat-tMZ)py0qW$`$ zmk;CJvF;1ewsUply!b-~1&dj6u#nHirgLz$R*^Tt9)o`WFge!ON#_#QS8^iD*0`F0 z%^S6`xOU`F{8q zP4Gd^EZn~)45O5I7^yTm+F+EeQ!wfk!l+D#{yGi!rvsx5fw0kZt}$ynsdB@IS5Zc(7}q9}eS3uY&RJmm@J=qhkEzf$y*HU9O9-?+eC8>ifW*-%sB^zxjvL_q3hu z>-&fWQ3V zT6TucT`0o%u+mKV4l>*q$$zAI$1AN^PQ4NuZ>76ycC?S>kJ?~)k6!WD!XKU|2^^U4ZIz|yR;SW zeZ!*hroP+}hV|p|uvXh}@DGt#ry3)%ojE@}o7jcD<@&KjqH_{pTQ<%8(%_=`AR}a+_I_D#o#tY+R)cGndQE^0qURQ? z^F?&74&7gbvHn!lp}Byw>bw%o4beV9Wq+_$Xf_neW6jWWPg)GFiMYq!9NZil&ksS{ ziZsgjIlU8;6kTYU8qlfS_~au4;*IUeKQj*@|i_s7bw1q=7Gk_d7+rIF^>~y?xr!1$G28! z0B`?tJ}93jwm+4|lq(i|0y&pBuPI!@jXcL;LDzk&DSc~!W# z1{hGCb#GAo=G}t4H;Y&J8jI%DKLE`O&b6Vrw-z+(+NJq(QK9*XbFDN#-9eh4`~hel z7e%wl=~`=Qmu5kw*%C(c=nm3s{Q+q1-IiuqHVp03yg;QnEsW+K9i%z^2cY>}Q(K%9 zfOA5-G>=nhKGM`m^C_`oG#}mkzo)rplx!G4bNe{=R%uQS!+C25X@36)pm}u^&d|ZN z+IDF^_qsy!iZGmC>>$n0{QxvS8H?uLiS5!{tI|9rjOOAF(p>Zd(A*eBvk^EO+ogH6 zO7k~iG!KhGGo3w(J~L|WJ#_x)*FCxPP(7MYx1yZ>Cnd3T)Y(M-R73nFbOCfv>t3bX-v%wa)5448Ln$`JZnhVaPJalxv1$;3)_sr%x=5(mO zD_t*IY7w?{X7V|!KiwNTJ0^ZxhGZ&j36^pDn!&?0pvNzt8_v->h(L4uw2zkJeu5>O z5KLoIu!I+aeUyFQw3o)8#iY8vO!~yiT+MmlS(y@pV(erMw8yj5tgB-^Nae@B@1Q*` z@#~$>Re3V*LxIyOv5gMG7II9yzxZ*WYHG4YZeLM?Qr0|f%lf8|16lNaH9Bmnd^Jx} z=H`t?tS(~nvD4nIw!Yu>enGcv&U)aXI)4E=t8FRh>)Hpt3_Y*6&MHFO`HT{A%DYy5LNl27^lwgLC4phdo(tXxkgz5JD0 z_M}plLien-$@kRLJ&RPm{cWq>>cjN5t!(>MolMBKkI#TDZjtY4{2A9Y-sz2@liz(5 zsH)JYbT$VkI)IOZ^i!|A^BAt54%5%jTyHEL`1YfY>p(~b+pEKMz)l7-+qZx3gMQ+< zA7#XYHDNp;9N+mUKAyE#!Lud?p8uoZDfxjRVYwy@%PL$u(?Kj(TmzO1Gp>%)u^+I% z`*WNAPJU)K&4;M=LyfWTr(>IhPl9_X*8Qp8N*o03#Vqb^kw$6N{zJ$1758RRe@=;O zuv6a0>B`(l4b8Qu0ZZ5nI{S9!+UQt%ighSn#0eCC8@lfu^}Y()lahsZq?#%@lSQ&# zhTYI9ych&tP~O1e@fLylMT$u%S){}y%v{7GV-l{9j!8&+5Hb-FTc0WWD4A+Z!Wzx0 zmY9TYA1N^jAv@BX-HKiAp5R`2|4>*QLgs6sb*BG4ufDWI@+!i2Ya{1_GK`gjA>$Og zRa;7X+tM4+H_CE;9==yi@{|D0<*b3shkVPrZGoyS$%@UWR(0;*+ahfS^_jjF8ISb$ zKHV1W@5${B>yId3CB@y;hRKsWcg@pWsNGC^eQPtbDw$R5%=!c8qPnynX_+ct6=CvK z-6CIU?x!Iq=OHKOAzwejGnR$q%N!|R6_5*ii+rWIi`Dzy#XBxQzWk45tS0<?%fZ z-ys=W4II7#4i)!V1iLC@uc$J%EKJ7sGi49fyf!kHJ{dBm?tPlqM#f5H8FRJBn0;Ft z8AD&yo{TO0i|Qj^#aH-wdbH1PGAcO{NOt<0OqE06ugQM@8uB_eLaV^t|O2f zj0*GZ;>p6e7_t!V`yUB#EnpLhb9m3{x8{Yz=r1LQYr6}umLFWG6v6rW(w zwyTec`l@ZGd)mvHZBfTuBU1VFwziPYo?Q=l47Y_FRa+>i^0_`tKD}Y`Ir5fP`!@(} z6+-ek)e<3}>mgIsVe&aNbYIB+C7CMIZ&&geSijV`I4$K*QPvT@+Zw1M`qp0xZe9;L ztybmq!~ci9FOQF+$lI^(&SZ{UkP`@)1XL2@4T4CrOcIa)Dhg3nT{i*NHGrYnLLCdow5SKs~p zF`t>~s_L%#9?$owqpMUqm4ofH#M;qLPlcWK3C~VBB6`9jiS>XXqkO~=i(W$0^}|Lm(d*yh{trj*b+5IlkI@fUxeu8-2E z!@d6TE#yGYF`;bf0#ogHwV&2_#8;G+5a_3Uu*p;N59Hl#b56T}g^f91XLo`*y}QPoo!Q}G&YVp>z?@zoFy}J(!kF-U z;kTQ5<_lLmuCB!`VfOSJeJP#skKy2!3il`n_s9VEsDQl>ZO=WrY8^H90u>G z0Pm>i$UAM4LbiD43dd}-E8qN|m-ln~ql6H*0n?mXIZVJ7ZQWYh2Ilj6y@#OWJ*W`5F7fV!a zn)qrm_$t}PG8#+G=bZX4=d)@$$AIje#!)kTfpOF_$njtgxc05}UEBPm!<}>OA;buvgT_X?ijrM^f)Uj=Uz zpH=au;Z09X=8TkD3;H!fj`-F`U5mEjKfOz=yd#rM^KB9GM?VuLIp5UuHy%1Dgf7O( zZP#A}ToOCgp}gj&@r9Y4`NFGR%l(>AzECdM|9Nf?ec_c5vb+$oJS#j|Uj1gzd|~RE z6OW@6J?LxDnzA1gM{gY5eH=}F^XH4BELhIn#L?rcH97x$cys#^Uro4plQj6p;f--{ z_jt46jb9et*x%?m-rT?X#Qo&)9{9=gr~f!VS$lf-escL6KcAlrf1^u3d8i`joxq{0 zoZD`CO%C3NJTV%ajn)zOQOD8IpT0fb>ZN_OsUO}C{nx{&i|anC=bvJd(yunD{c1C0 zZ4v4}A0?O;7y9Qq`_M$Y{M|OiFyTOrNG+zOmY=dqzos`~Zm8Zw@I?%h9ryN($|9Lko z`+uk_``>zA`1Zf=v>#{xEvI#F|MrbPpZ(vyv1j%_XBC$-&8=$vEUNP#Hu8SfjU!oN zPu2r{J*#KyfhKJ1x}S2J(D{0xjYi%#zv^Ax`rK^dW|1Ye7biMO9cAFOrqM zo+R4)q793YX9CLGkf$ohKjKkmI#;(&$%=>YPtUbSMk8V_K!f@2z8*x}r5t*@UQD^$CX$8sIV zvMBHa)6Djqz}N-f(Q_T*J|usd>(2D}HiR|L9OB*g1l<^0ck|2(UJt<|Xf0uYM|AM- zc`Ma-+|h339BV9UMtYqF3P;ieeZO?wr*Qu_v;ZJiP6SYI@*+m4RZg9XR^LjA;x<)Nm6Ul8dlszVPWsmB< z3JYVp-c#YdpK0vY{aVlMYS&*o+Ew#IeD3bx+o5C1hp+LNLSw#H&-A5qwx;Lp*Z7*o za^0H7db*aZuJ4Httnc~TYvHYPjE@VfBQmF3l{4MVG>&Fu>*-w-nwM49QR07TKC@o{ zxsj}uwOv7Vc?@+aMI9)fG(r#leErmX$vodus`Ehg+9~|n19WYOdhK+6Z4q4?u3kHj zU%Q8{<*V0z!>=u%YZKIK7x8O%(zVG}uYmYeI$g9gAt0MMkPXE)igzvQ8a0w%>2&7L zH;c*#)%&^-^)6BCO>3D-2MX<;bCpg9o$2&4l38qC2VYpN zNfF>z+M1MH)sD1xku(ll3VoJVSY^`JR>(ukf39jf{q5n=DF%<_1lx^y|P2i&w|O~-t+7oS$AXw*rmLv%r>bx4cm z{$yIxd7f{no}ys)p`N9S!OdySV}8eHYjW1!ZyFmfBFTV>eu<@{9(t+r(qwPy zAY*1vCfS11Nu-N4%uYPHWHYnhK(dF9hN<&b55MJ)=l->-f=QKm1ef{DzjeP>#vG%q z6XJRyoz(bz@aZvOwet_rA?yt{^o79dS=xy`S;|~kklv2I+H+qyFAQJ#k6DvV=Xv6z zyZ0w^boc&rJ?cYt8{zY*csQ=pygU4LFYGkW6Mi4=JkPUQ`=ZBpn&(L~`S5rT#deaP zUblL^X9xS{K+$ePTT1dp`){G^Q^N4&1(Y8#`3>@A`1FgaPuJnwqUGBx*n7cOwDOTb z-z3AnbRSW)|3w>A5g_V4a0{keOr9@>AuEBkxO(!Cu>(c~i?^;;g<(MLQ{ zLYH%~wlJRepD=Lz-%;J$-6v60@9;2skh!C8cdAe5@tHQR$EVx49v$=z{TQH^Q2E!W z`B$}ZeVw+Ydu(_$s^^$@o4I?;`)w5GJ?U+lKaTA*@6~=^>pV}gU#Ay!nrEPPpDuiV zAlcai9n(YU>&w`V`qFq!qWT>iV+o@(;cueOFTXmj|1a313B#ug_S5KljbL~DKzaoa zI)?9N!G4eGZyPpuufM2Xy7&6fkJuCuY|`%2xm}-P>fZK~{P*eH_Uq!h_mABQR)uH# zGkSHj{ZmyNPFKJCtKZ%EL+lX+Qbb^n(k6*{ zZ-d_~M_-f1TD3h=UU-@Bug%Y9PIG8`!K@USOl@1v*oM>beOT)2pz-^<*c4mRE~|HE zBx`u}zJj@Q25Jf`d-%fd?%Gi-^=Ykd^A**JeQZJoQ_j#@v)@o{>d)f)6ritUU^gF* zWOm9^c-(h>lacm8Et`DX?*;kRc;+p=n#ttbw0{=)_L7%rACC6#ohj#Ssblr7!B+XU z-;46C{g`*=-GaP;_PnS4(bcvcTG)Pnt!IvLyk5R3aAx)Kc_#VTO=jHNf@cKIufE`S zRyi5+8)+gLijIS-9O>M#+fm2A(K}Hj$4UHIC8%qOg{?n?d`C1nejPFQO~~=UhfMzB zn=x~b;rb5P$ADAHCYKshZ7KWa@1Q+2M@xyVbiUgbkrmB>-5j3I8a7rk`(KRA?h@Is z5h7cEs|9^~(W>lmP5CP-9$j(8R6` zZl3pQBWw5< z+SgS(t0rAw&P;)gbde5Kx!$`_x8DrP9=j!9VV$jirP_K8<7-SkQmP{*l5D+?V(YNkhSy;0N0f7y${y~UST^}C*!xPU zU+XHx-uwCOJz-{~V((YO-bc>hHs8mn@RlNzYV&#<-+?;SiG6KmGvpxD=h7TWxmcg; zj-q$w%W^Gd=0)9emHliXtH2oxe195GaUtX}4mwchH?%!&;2UKkzn}8%{T62TO%-I% zHPFRiCO5{FwRy)gzvp=L8!z{xx9W9sBBN+diH}{A z4$@hDZl;OG+yeg7m{OKYd#=;?&MM7+#_;Do1UZx#+4?5sS!s^Z(9P&!@SjL!&vbip zfna}jfUkyZi^d`ai4`@bKqf=2UUveWrL;MxLTfMbHzEJQ!L+|SWJhN%JtfLbm6bWo zr~~cuH~YpwyR|Xhwo!rcT-tZ|;1~I_#ygsZs(L$H9sfgpO;Xw9tyh|ANzTI9`dqW! z>ZRwiv1Pf_=v*h<+hPxWf34l`->1VU)cI|7UEwYdm+|cSlZaL7GtWoe)1!j0YM2hI zhI6bsuHu!3RVE!)tyQt=FOc;{6{mb+|5k?Up|EPmyBw<;SpciFvH_eL;J7+M#i`yL zr@jnGX(x)qxl8+P-7HyoXWh}Tk-ME;pJpV9n-SHUn<-bMFmbFZYsNIc7kXPWSAGwNW0 z4x{9h2<6Np?^O6eA4dBui@-C%LGjy**g<+a3SIOE{$v{a+6JhxV}Y2Y=%Wh$FpuOp zgEbKLUrlnA*sxs0jyb5;G>P<)?4bP9&s(?%|54*`Ta_qCLJO!A|dJ9Gha0{{~qcsI-o3OxT>$ByGuQTxgY7_G33UCY0qi z?Y}3d3I61kI^w=XH}-q~22V|6LOt@omE%I*M5MFcWjTU@&SRPgxlMrl#zT&Ukmoq) z?jjlTsWvZon(cI0Q8+ac#%kJ&e@<`q{jK!Q59%~$ zbBw(@Kh{orqR_r#$meX7?#Xe@5bT64+gAgJfCIGuLu2LJIV~d~+cdOowAI^E!1p@Q z_BfedYpiyS>eydceO%o)e2ZYeG*YN`(;Qa{U$;#2eCc_t(=qh?NI^M^^!r-cD`kS* zHZg$v25r6)_g()z@0%(AanIMjgo4S}9B#$rGhLT4tH|}m zTw>yJrCz-Luk5$!vFw6#&N8vnPf^Z3FtMU?%BRRS*)b2lNoH=;Re9HFaD)=;Y41Sa z+05&^Mv@J^DG%bX(5KZ+?<&Rd^)e|7%(b*;=2MaTc#D+cC|~cXQJxJRC#Yvo9K46O z+o_*%hlS3uD$hAEsSs@&2P{$fQvsLLY85+@@tL)r?^!^KPwwlE2IT(4(eCAbb$s}8 zU-v>sxu=~3xmWj4?q_x(_r+bvy|Np*Cx(!FVVH8iL?`!gVaQ$X0nS_!LhhR?PF(K8 zJIejJO33V<;4>Ljxqldt?Q_%V9Soh^&j?P_$^Eo$5a~E>|pt^Ipzgyk4+H&|m zhmgDBB*^{F9?CtT3%UQf3%SqiLhgKAPH<3P>s-j~;1njO8#|YEhLIHw*U9>vFl7C= z#PDT3JcO(r;iBl3`jGGVBwk3>&@S$#9o9Aj7Y`-OJG2gSfcsxsEct>LkeU zgXg-J;Rj2*@c*UZ$?(B2Wmv6~;R9jF@Xa2?xatrxG@S$)&JRO|^ShAY?P1FBH(|=K zKqtf8Fl1QJCWI}+f)Fx%x$MMcct#j9JfjO4o))GI_jBVSL5Q}+y#Ky(=CEzk_H9dq7#p22 z0Bb;$zkL73_m#7Zqnz7yXBo%X=uF~hHGekpFT#Jyf5yhYZ=<|)MsXGX^L&2~E1wDZ zC=Z=wylt{o&PICa#;x15vy78Y+qQz{GhUi(s(nwiddCZWMr7u(=SA4_wzlG}#e%t& z))H;K+q~5*uwgWwOZ&Ps&*1N~(EcuTcH@2Mn<($c;y$!T(4i=r8%=Q3Y-GyymvP+{ zoA0q4o4ccR3wy!)h4BRs^|>D`_FOYRs@D6}${#Ki*y8>(@ANE|QnyVM`r2j*Ll#fi zB>Yf<=hIvvt&O2Q;};wIFD}M)0eo?S6lI%$=UpgRl(O^jJGgwSG{8~P<|~>g)PFv^ zcm3xR<0jf-Qo*ML^WuvQtRd@oOl=b6Q;mD9o-Q@e81*@@fpoNY^+5bLTD=C?(kh1k z&0+)1t!GktBpXo;Uo_*tOI-`F8_%jj{nDs@5-ZZuCQ26DY^9!2N|4o9~zSUR%fg63ax|cPnj3 zcXL@?-2+%vl+HM=kgj(f6RTU*-_7{##cx3y--k~;*viNEcfQg+E+1CskncOpv6*$z zFCabJ4hOLLUi@~6$u_r?yq(@H^NDokjd?Mhoo+JkTtRrf8`#|n?56k8{J0Iw-hFn2 zJfH`-ea|x;aocnEiR1Q-&vcL5H`+VL?LXSXm+_fl%J@8;jL$eh85<1YbF}ObGG2KS zWSrPh#t%)Wcj$C7P7KJHr|D!ISae=sW z1aZkL^>Jh&F8vO1=?LNyafwlgO#^1m^Ejmb!0dkQV$*(IY;qU}D6y#td~%i=n?@n7 zP}w>79bCQ@c&U#~vne(i+sCFv$Y~kwQPa#C$T#lW4SoW@7|q01T07K2K8toWfuoeZ zVXQ7QvSG{M2U&JjG1952`;?fmD zk`k9@X>rNO;}X@=g}6lPShRI2UBwr~*P;WHE`~2ngilR?Z;gkK6(T;3li_oA{+>s& zqpLjDqhcbhDXdz<8irrXWLkUEs*g*s3AdZarE^~XW&88ROGEqfMN9v`Ka)RGKdv)> zcKq$v>(39nJNM^XH~x3|^TkKH_veEy?$0?db??syeqw(P?aPAvd@oiV%9q#S`mfoS z{r$xg^yMRm)&8RD%ZDglN9D=2YFwu4DNT8@34ZKW`-?|J^bcp>=}85Dr2b-S9PO{1 zin{i-WeS;#O|b0)@NIp6k@l(Z_s8JFg%a9`=N%DE%Dr;&JNO=MwZCYF4_nA*dy|it z78k~iw?z*rn@np-H-Nv^!GC1bUQGdOt*~=O%&bIiOuV>ju&O(I&?t)O85zI$p?H zd_Lh7?n~Ec9c#FLS|5g=k`IGt-ocrJbwcpoOxof?m-$$cWADyz{mmPCoKO=O^ zed&zj(&SP%PYyVv__a;yGF}KfuxIY)K|7H7g@j@YF+`S6d z|Gz&oZ~sG``}1qRWDecC6Mr5kD*k-Mg^`{5^V+}tFZgrs|2==6cUbl3W}#DmKJ^>* z{ht?qxg5GNCNzisJm%NUp;J^}K6HYXf&Ck8cc{6MKah!Rm zjx#s@1f02UAnOrle&|quGmqZIee%8+x_>9{P$xc_9$|I%)GrT)@JpXBQf^$xoUXwV z{4xT5X^{60WnP-+Ie^b~yL5A;TLN>WwGa4e_LI-jwf)>@_wN@*F2i*?V}Z`iN!S#+ z>_4;6{-AOnXAut{17E)gzCQLB?dy&%;`TE5VjX&1__fYQD+4~d_WscQ<;U*-_4Jn)cQLND z9==r-!cVI-KcyI3$@j(W`+fT{tOE($PoG)O{qzv9j>gHh>U`A$U#0!Z-47Idu7QgNdS*%eV9R~l`ROs8pUyI-Dt=09m4>K(IubrcW$(i8;PS0f|8{rdJkIj%l?j1)Isx0EiGI1%aQO)s>|cai9e@MR^64d{t z`p`LvuEBXSy@Or7n#qgcQ<=)1&!OXJ75SwagLj|J%aLEoYgt3}CnzrqvMs3-zl1J7 z+{OL!4R!s(lh6Hf{c>STXusUJB(z_?yyU;nFNb~?+Ap`h`0Mt|sQ)s*bbrnL^0VFC zFYBMx?J=+IFMkqzaDPZ2WbnZV_#k{STZ9iv^4>xG-Rc={=zOps;DcF%RUf2lb5tLk zBa9q0n0zoFJ~#$G_{&}+IID{_f-g=s)s}|v!BWi!qqv`ut|osgRyRdiW&N7K{YbBQ zn$A~aLrU-FXT}NWS1oAcXU4&IhtOX7ZBuD|8eh*t&!PKKpZ5^_I#eEQ{n@p!7r*^L zPZLzTIZw5lu(>91!{#Wf_i5PPnXtV& z*xq>9-X7TAUf5nHY)@A4|6y;Lisy6V)?r{?v++AD}OsjD&Le7QNB6H zP`)K+nniL7RqKIad~f^%j*^G*{*=k!?Sq&-waqUFRWC30rqLv&g3{gZ%bXk7ZUmSPf+^V-v!1Iey8vlX5aIT&L7r__GK;HAO7@A zV9ht}N1?6rCO;^JADHX%nz`oCfeb=e>O?G&(imPPfO*UZaf=HSC&Akr3Nb9{{1lFo&I$YYM!`HO| ze4S-h$M)&k78PH&2qXVsrZw2$IP1W1UjBu1oD;GA6xi%q&T)?H0lwORPZI6rW%cT9 z{lFxq><8j5U|tvUw?J0stc6XdaGR#_@kVJ&j%!e0zb}fv+J04`>`_}stnBrnt{v9f zKc4?p7=edZm%zOpD%5XuV8!p6MmEJ=xy-<6?66W zcxjM5KBLC^X7EA1Ob#b(|A%Zx zjxZ7K{yN5|PAInf$EOk;*X-fAOLo_sz-`YT<6)z;_nUhV&;P>{O1yV;67L>L2&hW8UPwgn1qFD0bK)+FxyIZ%=>;6~8jauyu*Y_GI*P~Q>3!;R$*xKw@_vN9hOpIC@FtrPeV%AMS8%$s z&A>kk@Gpwqd-FE72=-&=Me6!JqTgOC7N~KVt`$UZdo73sIO#%*lkB%0A6;lt_B=f>j(MAlftOn#J`C9CGgD%@X(S-(aFF?1#r>n{mOD@#53p23&Axb z1*cKvp9|=J1?;H;yt4v!gSa2s=C6T0UJXup75Z1k4mQ7R57~UjJc^AE679zt+sFAU zY3(&^=RfLv^M~sKV{2_w2$T7E+Wt<)(@K8Cd{)RYHCq6ST~7gv*G0&Co;ApORV;q~ z-=VSi{YcfegRuBr+C%QY42!Sb9l+vtI6Rf(u!g}eJV9KE+b+#xlRuP1GN+{4BK3Ph z+a4cBYMWy9j~nT2?@%k*UdKFI|K{2t+smZ>4s=_n+TJIjL1-@PdeEseJT^oFn#&!*g4ZiLUa8Jz!8zGY>RbL05W!@yh z*LA?uYXtAA=Z)1al3S(4-i&-SzZ$<1@_dooC+!tV>9oHxl_xt{iZUsxt-A1^-Cvf& z%1us|SC&it_>zhTb4n^6z~_E^mf&Na%Zu%$M zm-4@C+%&=+dfYT=)sG)Ht=rx8xM|#1?Z-`zeXXAVE30@J*Wc4tEWq|e*bZXn7IOow zGg0>Hyv*u7&BVE=75ufJ*BGbPUvFF};hNRy=dQCkcWqf}a2A*foVz5!*_2S0o5y|} zhdqS42J_e!TZGf+>n%4`ir}!Z;IMJvu)SoLjoaYM|I*K&Nq!srB%j&$-0Q13tl%tN zH!5~`STc_M=3c(1z;&;5QnrHGhh!j6P`T4Gc)1mwJoBXpZLMmcoD1ciiy*t71iQZ+ zc7NF~+U`#X*XIzfOA4-EvYd1-W=_0Tv!k^j@!%GR5`}kk`V7a za1-;ohYH>%skgJSCePVi8H2QZXXAph++7P}oi37VL8QGIvb~o2g>zI+LVUWC_Vs=j zoOx@GSpHs4B>1%ZU8`3DhmHWxHh^bOvqU%raBLAA`;VfeaO^)Mi_U2l@axIo)3Jgx zRyV#I4*r)^l(mZi8SP?#85myxKg*Zfih=XSF`nQ!umSkcSw4>Yl0Eg`Iv%uz*-vfZ z@xh>u|9)GiiwDI9`Ory>38B`K(X;m}yh?ERe3EiLfG=A>Y!KzWsmyy#x;oy0d`&}D z{2wZeyds_E&GO&}1@MFXU$h@MuI_xD=fSJ_+Ao*HHu%?kN$h-Ojpo(r8ZU|FBN837 zZ}Y{qteSL3@~TtqWE$+`P1R25?ARu$dIdjoMm>AFcx({%Cn@%l1$&`&h;*$<;_J(N zc-E}{z~69P!~6%n@^^EZ zD!1gcRKAn5uX1w^bE9Yz4pB(tS&lu+vV#YXkRo3VHr*cycJGVZ!IRRK67w_Da z7VB)WUFQ6H<>k&FP_}VxS#IOPNzR1J$2yx6EY5vv>vNmp%+98o`rIERle2MZeeV7# z3C>*!Q=I=XMmeVgo0}>N@ju$xG6{Wyo2=ejBEc=9E_UvlU6%U|p7}kVSrRKc8)w(& zPO})0Hqq%q-_AWz@P1QZbh^F(H<<-YKd&s8aQ~0_%o(kpyQ8!UgR`U}0w2j4JeE@0 zk9q5Kn6CLM{Kk*f9>VH*Z`B3+XsA4+Tw)^kStIw^7UrG*jadDd&SzKui~H=IPj$T? z<4?ABA3E0d8u2Xv=YI;gz7DwlEO0%IdG8igena*$L&fzO!pJ*B8an~5uLG{X{L9Am zZNKm6FMU*hNiH_kZY6$W;Qm7E^|K7zUrfd7n*6ghe@Oy^!flGyo3~F_Yz%px{Euo=gZO&{J|pV3ORWA_ zvnl8(TD7TNPikitL^K?q$GmODy>QRou&MZyW>a0q0TXzF0WlyFF~BJAEnr@X3-A6@ z--i_ZxO}`q6X(e@b@ z?}*g#j>sT9U%+|CY3o=uosHyAn}!%n7>=~;i^0$6-3Ebdc8g-OuEADsGwino*os)_ zbWNl+4+3ypbe0Ze-WlM?25szlAgz1g>m5R2}!pJHeMvm_WBWFFz zG14S(jC7}1y}Jn`Bg=AU(m8%Z0yw!Ko@|RbPbNK!_q-26GWtJ)_t zyAm4O5@v0_0C z+b5$xJ%m|bT|(z73Dy_h6rx(`{I0%ye$_FanYItvH~--@!P1&#wmv+_$cjc&IWx+Y zmcC*`xf@V!rC@Gdi))inZV$@s#z(u~X2{~q(i`r0VBh>5ON0e4I5R$2;Sem2l}KBI zwCvIwE?9!J*%^OdF$>qD`dhtc+&o~)67&3rC#ct`&X)eny9oKS&?a*_^HTex9?zGf z*XPMu@LlpPCv4jG{&vNeKt2lD+(_+*Y?frazXJ7hEI|4Uq+1@BWNIh* za%O4i1+(d_wT$g6fK?7HO&JRqN@o)p{bv*1vdCCn8fo>?IYf2fE3-tacc#Var8-0? z>yFbL^lsop#>Z}3(WiGU5D_=g#|PHAfwPyr=c{3KMp$q5(XIH*S!1wQuZgrb!snYt z@G&{Uy_U6t|I8w1nX#Jgmxr?TZN3eZ=aO2!4P2DQrE(GhmRHjVM>nRJ&(| zrzSm(tyj*jdpv$_^3xICdXag*S`$ClJ;>^?FqPdAL!i#{n37>WnzNu+KVHrtHc2|b5s7vBewvAJ>T^wy6ZLf%&37ShRcwk) ze143#DGfHTHp2cmoiDp^jC1uW>yc-&>|Sd1PK%0m{$XK(^Vmw7KNGyuq$p>T zG}bu-eYfVgG0tg{Sy_8IJ42A0j`JOpxPDUiQ*PT=EQzDJ@2uQyKcjuuR< z8Huc@4)RVrlkM9a&x&>fyR>>l^(~uhHn857tf*S~$@sZ>W`j}}iWyW#IuABah;TL< z$2hZkn`{?e$CNtLyINF76LdFz8uPkSt=>FARO(sKTXLq)&Gamil5Kecb0(o)rd9EC zN$10ne@;HLZyY4qeWIyV`oUM!h<>hecBxR7JC$Uswr&5Tu%TXTJ(X*B{w>;AYG%Vo z{x8BtUWZ-Oh?4ygI=fY~4Q0-xk7MV=$ZA(b@dcV)m|z#$7-nPS7-w_rSm!F(L}O&W za}8{wIko`*(a(*v;=hFddHB!po7+R{qso%zdew>(zwTmv-x>pjj8py zb*eqAB6~ny(!r7IBW2P6kc%Wqe3i70LeDh-jC+UP_-*VVjq?~(r1(TD_^!}a6 z9(-o+v74yR{EpJE)?{A|*;^y{ewRMTQj@#p-%Ch0O}-8EpW+m8ko3R%J{m}SKr+#u z&m!$Y1oGWwtd3LD>p$>4r=*{nZqHw3Q1*zt2k8`V+m*E%l(O^hQumfr>$H2O{=DFR zh~0f1-~Yo`6RnQb(lh9N4x@iA#$dmxrLCqBx>?oO7C1`{c9f_q)64(PgrIP#Z~jej zoZtVmfAI6}wfkK|_bV{jm+0?jB<@4pE7{TTG3Nl+t=0N}^bV96GPXe0QIL5wWFG^Z zjg^lAW63Us7`A@;YgUe}v_29%=m#J5$E@DN@$hZtJmB)$D{dJ zQv#jwD%dxn4UIQlBm=M3(|LPTx5G2|{@8>|^iKF~+1L6Bm7)elJ7xfd^u20U!_6Lj9|kE zk6wj5Z*LJ5?rVy^!b38AuoD?l+bG}vK!$aw&*2#+xzQ*o7_m8$70tr4s?i>5rwQ$o z(bkzFc!*@OtrRV-JAtLtPT-JSd5p01?VKXo+f<@+I4^~*T>_iC81kD48=L??A1}iu z`5CuryB@_DMitM&S}G~n-4hHPrE?tDbLmPzC8xSpY#uX*At_$W9|X>*&B*3UnuFW6Jm z-&Ds0-S5D<7w-3T?Vk;}H@HsRmwF5k?f29D@%+o0br^u>Mt`F6|20~lhQ@xPAopm< zKL&b;g+Aio`@NJshN&Fvd40tD=H?V5fa?Pg2)w>3`BU}srM&IX{z^ciXY5#d2xNlW#f1BtA z7Sf)>;G^|uhpX};na+WBgLfVujq8KTa@`Z@d|q%E^(<>|ji;tDUg!7s@U|SDVNrZu zh=b3gUE~vMVpN~M4|#CUS%{HSVgDAXY_jDFOD#QXJp5K!--7mA;m34luHWy=q`4#` zS?XuI5a}a<2`eR2E1j=Pv9giIW{lkb`{6#LbmxDad?J7 z!2t<4IZlzYNv5@u`m}-I5lisDaZr73>qM(}q>*C<$;C9Ye=Xs|XenB0pA4Citf*~K zXxogV)ZTY;UWNWwDR^-i>~j+A^itUCC9vCzffo~H*fGZoRSx$<4kZQ^FA`L|K>IZt zy%*`M6?lRF15xiIX`%7r-aC!er>g0p@M1pF`v=m$&!=<8s)nF^Z~HVu+2q@hPI25j zIy9c#i1cWk{yx8+`z7TMb-!tM2JnXR_VIlWl=|DOyXNO0#<6lU?3%8vA^ed9d+ER0u!y-S zy#$Uw=S3*7`Y3FvYQ&hiM|J#zxJQ+R_^Y41nZfwJ=HD*&)Oc~<62>+>j<%0fuJ;9I_i@l3TnC;q zRx3Dkuhr`9UBRPq^5JoGcKBO4Zg7$&@bulp*9QZarXcUxWx2a& zsQ9Fw58i-huF~VvFy2K9Ce@6j{IOJ*CLcTPApgfI)ZNm#XEx(=_-iI`gldAfnWqYNCYS`Mi^MeQ@CYB;6V z_X*TDop1`}+VK?B+gE9n>r{+-6>?uu8DY21fXoX-`zpx%O5oE};Lstz%#$5<+|Q%R zocd=MsOP*lLEgl9YasJF$iQ<=lza%X({PF2CscR~qn+@YDRVi_Xf|5^NA7>LHa!$Bjhn0T z9JQY7)%=>gpZlY(pR+}@r!*4Ii1sUqceLpEOiO^z(6i{j#%ZXoak_pD{lDaM&Szfw zOou1*uIyL*{=fOEJ)g0Bq`v>VDtta8MC~nU`V9FCyOd!M##b$|k#EC&Zb` z#6Gs2<07lIen}a8$OXLq=6V$)h^wS<~`sldIATRmE7G+$D{Dk`UXX;|z-V<-5~*a_z;eH@E)GIL3yGOqC`WJc{e@*h5aAsXBBj-8P@-f?69 z+QY!Guf%9&Jc8O!?bdil3;HQ!;y={jF7xx+sm5h$zr?NxWEeyi5$o$L7jXx6^(u>FJf@w!yy z2MhkyehfnMU8+lh?zjI8c-Sia-}Y%>JYs#&y)Rd}K&k%TQGxLY`-j|z^HyqW)(r6B zSjagJ^6mw>_lErA;ll}jA3i2Y_6+nrDt?pK!H>UJ{rJi>ogZJr2;?U#YPN*^Ub@!vzh zN9w1T^2UsWtUsE4)e!q4#(K?~S$aX1*@Bpww$ry(7&(mgw?jVReydkpM*9;;_RXIQ z)nyW5=WMIeM=m730^H41^O~NxTy_mM$~0~_NWI3UMc7>^`x%}aT(*>PdsE7e9Wydb zU^lyrEBm>g5=PQka=e;m#`CEkCEBgt=2ZBlS}&?oEo933QPHw*HspZ&({t$lb+`vT z3$htmapxT#1+NB)_6JagFvV3_D0?U28nC1ZT)r7`(tV9G-eV^{HfERQW|$ctGoHlt z^jI}~Nk3-%HP;W}*J>Io{)Y3J`~>hB+*iS?+bp$BxVOS#@Eir#zCpQUlWh;`k#1m4 z4aY8qk7on3{5aMaF_(029xXK7PB;dPn*)5H=gq5R_JVyKv1|@unOfhQQQvyR4Z6oc z1(y>1_1+pyyi!u^hVbka;xua_>@_N$(Ri?{l4DpY^jBE<`wJACxp|2FcGRPT-AK~N zv+(RZaG-pN$AQtK{`xrlHf$Uxzt=J3dlxQtr4P?ic;90?C$X3AV z5(}69{sO<97$wC{i2oN#d|gXE`h%O%AEY|a^Aj}t@I}f#^e5<^bniOVKKS^uG*Z)B zg;9+=q@Qb$Hyb*>2%Nw zI#^{0!e7W=^L-Q9R3q>g|EW($v1T+dez=11Q-Cp(fi;%{b1nn+OajJVDg%oYjPDGq zkKb;r9@qs|A4Gb;PO$o0q$TL;f6X7%^N{$xh?9M<@B201&T&6f+84L;vf3UyseWE1 z+Gp(4jX&ewiGFOB?5BOnvDpP|rm}(#`#C-(2N*9iffPsvgHfX&>` zY3z#Z#0>wU{-9eDZY9VPMHTwcn;< zo-C%=Mi@BW72_ErA=^qCXO0T=-%@ao^K`a)KGiQOfOj5UJ*odz6%pva(HK(=zWYh^ z&M+TyJ_~Yl74Z3}Y?2}Fqw(6^u~wyj)`)(tJ3Cs=*JB0k|1y}cqF-$vwQU+!G%g(L z%tSkPq8(`xu%ZI}Gs1~uyl-|#xP3FVjmI7ij5+Jur`gy6q_e#oPsqm)r-sIe1Gn)p zXG#x+5qoaqW6qv&LFHAP`1&@L)2a2kd`6(}mTodt$z0f z??dhVg7?w1@gDk}tp27t#_N9Tc^>`0b-Y1xBW$1 za~|e=K72bbzVrF~EBkkx&wq&YF`#Gj`E{{u81c4n=JVYNoZrnF6Is1T9AL}57JVwU z4?^>`c>*g+SLfVs|3mvZ_e^!po!%u$H%xF2jG?v3X%3p}Pgm#q2dZ=Z>FQknz?gAP zZJvKoY>I8*^JBcOq0B#5@B9ho>PM3dle?L#PteWP_x^>=)$dp5>Q$aLNjFz-Lfg{g zI+?3Cbv{>5{ms1v${f8XSl`;5`VsgfjhoTDdX~y}i2IPfwK;rRM-%QmKFQa;mU(~f zx%jofeUe>I=i;BYcRd#`Q+i8>x%h`f;xRg`ly42p#jpCn_q~#?!^+jS`uo0tvMNrl zxV8OUym5NRx%imvUC+h;^$R{1zwxv1=i+bC^?eU+Yd;si_zON4FMk%A2VJG&V@2&x zHy<~_{?pCJncwf(eB7?XT0io{=Hrs=zmEC1)`w1PKJNLyhc_ShAmsW>o{y6s>UutI z^+O@&<2vBO>N$b=xKQ};=$v-*am1xQ()W|>bK1?vb-<8CbK1|x9V%%zAJ^f2^XGIv zAGh`sJ|E}jX3*29&-i@Y6QA<&wlrOTs(;XYTp!)sn??O?(p`(waWnd#^gf@9yZ4j! z<8P;Y#`|JbpSGWi8?KI>&sd@L!31EB03C|Zr39TuK(_{9Po$h+vU+Ln3|fPdk;ICU zBCOskV25UA^%6Hefcp%`wJUKg6W3^M@2&9HRg9l4LGwGmMO>sj$v)o(m%6s+V%l34 zeoQ_=SVLI6N8NLs%2h|QhB^3r+?%a`L;{9Iv3=G=R^&izJC45TG2rL|$-S(O!3KU)ylh)uh&S=QI2_)rVwO zl`z2Oj_+rqHTD_wu18*E^(v8_UqEAesDE(&Gf@BFI#s}@TTp+hL-75Ya6cBwh7s?m zn`5aRUu>y0HHox-(VKNGoqK0)T^#|eh2FJvaVBg9pJHZe-6XN1LR^!PCLk81EJ4eq*%a*9&jqJR?+E*)7~(+TnqkHdjsakE0A?_OgGrDSo!-QQiKB z#YWVL?}6w-J_f&_HPi`^tI15f9sW@%$onfLnffPg^u1i!h()kX8pj(A`*JOyJvK#| z&UCm;d0v`>uf;E$?DHY*DN&|(v3+YJlzSAm`PNTB|I+&9rd>W2rd*g(M};DD%4w zbpI^qk?x(27~z^BDDM{BbGWVM5aQ+`$b2~Y^V&R_e8aTM>h}%WuZ7lyHyX=wwQ{$s z<%SdPkFa_VfGcf{Pq7JTUpdM%gVjs#!VG%QQ{%cisg}X6uA{wg(Z8cuTzb^EVSimchP%{ZP-Eg_}c0PJ}7k{eb=M@iHIRdz;ChxT4zUbG#S^E8Q~YLwXR-~=kqCN zh)3Yrhn06G#zP;4a$E5@{~mvlxSz2I(HHOE7fhxkJPR2Prl<25@T&yOZG*DRwkmwjj`c-vW z6^>3zLg@5V=(JCGI_(pz(^2%!gI}i)DeD+?I!)5+6!jfBOQR*LJ@(W4;kx^Krn9;~|1>%& zhrdnwkvd6Kv6R}Y$*vGQFIZ1y#(hF~h`nwSNJ1ac>jq0KPF8GP`Hx2l92}jizX+c5P)~WzjsriA=e&I&Jf3sQk^s+H zW&C-0&Xiysw&yt=ba>fK?Rm~7mFG-b{_Bf{@drAIh28L+hyy<|7M>t~aoKw2Z@d2V z>-4w7`+uCjx%Y?XZ_8}~f2(6ZufP3IunxQNw_E?z-rt^3{q5dmKaFlTLARHmWZhbI zx;>)9(h+*y=5`$y_o(Hr)ajOVsKrJ_pQ?UOfsD5%r`T9tgni0&f?vOd;pjIfL`=K} z`kfS>etnC3rr%>Xw%6~OTe*H?mi_D)tyWy~( zspX1r|AWx=^7tfMeWca93S~E0z<2OXdVU` z=fNM^YCLGGN1%FyfzN8Wa<$wYMz-EN8g?-hZAs|c0iVx;Tr+2+)LIaSEqHzu^h*Ct z*KwJ&W*gHX<({`exz zHUjUcwp~Bb|86Rc4G+}b&r#BKXV+vcTwj!A4<0sH?+t3*mt>ZmoEL^AFt4Kdm`f%pX}>oyyE_@b^Y$X z5aShQ-FStn>#Rj#j#n%Rq1Usa*FoXwH7;1MI!q6x*XSF58vW(LkFGe0`s*%M-?l$6 zUNNEvzIwe{?uu^4D_*Vg)YQc%+qCftZLH$OsxV{q3Hs}!RXx+|^4VIfhF-5X0>4ct zXNGPqCq5R1So+5wsoSJbV^PKszG(^QcJ22891bg9tL2ud$~@^9aP7W1#BO!6KiCwNRUt#`e2pC9x6KwWj)XdVL0`zS^epV^*67retc^yY_t zojRP-nGU-d9~s-34$B4mW={`wc!Faf1wGWEHAsicR2^Ra6X{R@_Du<2haYt{-sK9> z2h#U zyRQ=8dwO>&kBU^g=omN-2_Z<&nVcYc=br}yI((hdboU*^g z^}720uKg-AGPGaO`)o>^VgI3YTB7r@=UW3lc0mtxx>hZByXs@1#_=w%%e|@-x!3FD-e+$>?xXZ_caG^&?iRJ& z&MxG>zk;zquY!_~plV>;?!MET^T?DDX5@Igh-bg=!pZemI| zI;iVJ2aP%%yu2r%gPb1dK-S82p@WAt9W>>SggkGi_Y^ff2tj&SSi$4^&!LAKdZ>q) zsvg>=z5)3Q${8by4~VLK%_dvYzWFyrS4cGAR@J*!(4U zb~(6g6L?vf$lG3sYx}9~xSmO8ec*lq?zai$N|5Kkq&%7G-8OY|U2cUZh5plTs&8Qx$L0JW_PgVt=E1+l7xi13Bg?esU&~tbHM|>fRvF(mW zAN?U~{ z8QzL~j0K+AihTGr`X5|JGwMkD*i${pu7|^>X>Zdca7Bi??p(tfQV;rST&Uj>^_hh_ z-|g(VmxOpOovBP%MQ3S!{gP0Pd+!5=*vnOXJD|KLlR#&`(0S61-`Ui2f+G07U)nPj z>_wgFSwr!huG%ylvQgSoj`n~9@2p@Ai}tr~Pj@ox*G*f_co}U0_K+?+YfF}{Ex>o> zdHQw;A=*Lqlc=_X+MbNI(?0CW2y^qfZcK-KH3v`!Y9rxohA)7(d&)dD2YaBi##T;(GC(`OTO8ERy?3>1=euRRoxTD(_rWM1yU8RUx!w%!Y{7G*(C%oN&N3Ta zg!r8T-$FbD=ij$wC@TUFXs8;>_m~)l_L-8BYzczUz~dmDRh8(tB8gSMDJHhgfu0cu ziyjhKqHq5dtr-`h{I_@QNB}Mi%G_{*V=d&fYNWy~p4*LkX7w%bmbQ)E;qpbu6U&8$ z!gAK&p>y9BM9PhW(APjeqjfEl561C#?H?HenHt$XhC0$7Gs#h`Ass$WwwIBVY|CQw zjxyV~J7s0R(fDq~cd-yPyB_grCcQ%(!8Xty*R&VRC4>o(lZ=o3QA4#$N*|IofZb9i zv7(*m&(R(aDM@{7gsVFthr?)JvWfJP;xI+$d)#8^XVH7xi`vj10)EhbkD2&3<3oEB z|BvoD(~kR!&OrK=Qs`$b7sGqjc(e=8+CX~%kk7t{4?XL5x@VQ(StcpDRXT$erAbMx zRrC%1Qz>vc(phY#<9R!>Aj1i$N1k8>?pkSoo`wve{OSCdH=i!``8H75Mg3V(ij=(l zc09*-I@`BsFgTy_BH068lqLwRt5GK!cO-xKA(>S-jR2OMjeczc`lY=ETc2y0?7}s{ z!0e+R zUy-FZ>Wk}V2vN3TA-dI#_KfZY+x^y86pgY=%75pXh%`D=%#5@@!#AmH3+iabeW`pF z%F{iHaqj|LA8uj|pTfRJvy@gDZ5_>$Tg?L~e~Qh7{FV%>oGw_s0|bk0y~J8)Ani@a zWh=g2k|dvRp#8~#A%m>mN5rJ<{gRlC$G6e|*}*EZZ;5SiO9LFGum{?6CzIr- z*w6qxE7kGYBLRD$d;;X?#dW&B8{Zkwd9l>DwOnM*wU8CQto>j z+DZ0LHnb>;DK_rTE|AHNvVeL0CN6}tx z`j{-L@u5G`4@|lkacLsr(*(q+@rYN2^6`1&WW+C}AB8^DNBQaT%067fryHwj9zeNP z7O(Wp&c(HJwQJS{<=Ppzc7}GXG2Y$;yFB&J#_GYkYurzg92Q*9(5|maP@Y4&y!3Ko zb*hTbBv(48Psvl?TX_cU_aBF{@mg8sdLQMU2XEs0%qZ7O0{JE6k8F3H=Xa~`Y)zP? z?k}Or=Th}Q?K4I`LiePz8!Rd>@WKxD9H9xm-3%Lj`IxW9e;wF-@HpQ)=G^0)L;Sl+ z8xNrUsG=eB7|1>rI*5ZVdVwSKmJewhVKDPf2abIOj!=LYzk4w4i`@p%TSiP$vnX@jQdFOynkq`B~fUT!}Ec+tfB%PL6 z`x376v$T^P+s}#g`zCCus6G<@DD~Y=4K8 z%&Y7NiRU+=KCkHRMRNgEFY1Gs(LV&wdY+X(mLrt^HOE|@=9z|P(YmIsZFxJ)Xq$Qd zd$m5v+$xM>MOwd{>m|u?f`zr80A(Y^EPIK_xKEmk<5E2m3e8*QQa6oN2J{7ulrBiww?ID%s_ylPyfi0`zSkbCA{5;nGQS+Jxuz13S4WxrM-}x?S zgyRVQrwGY5+HaWlLAww>>oSg$i5F6AZ;WL{calD%_&CZ|-2X7_=OFOT15CVC;QKT- z;<~VkHT+I})&cm81<$L)vuF?2S#7>ypQB#VS*UBO)k}NRxxh(^qY#^klh9eQzPugp zoj#y8Ls;Nk6Ki!k;`w;fYQ&pt#NUB2qn$(U9pG69ofALa3Jz40&ej(XX8TO$zavYr0a_)VCmzpik$wVbovn+VP}8XRT>KOc=an|UTU+h`qU8x6l|h5wA`8E4z# z?wqr=xI%Nbyq(l|bi= zluh0+$Xt8vTGlXUE#cV!C63gb9a(Ma&*IaLOE;H_kF6l=Aq<)))~>i(dThl?DYaFG zO%p~|pl!sl$VayxCr*{>Q1*qlBRg98ugehJ-Xrs)Pwflb{kjr%ero3Z58a1^QeBUOK2}t*c+YMd(Dj-YZrj)dExKJ z;P;isX|E}>a(=8!;gWqF^c=##@!&(j<9Gv=dYib9q0VG$q^~TR3nQCbr}3jig&%p4 zo+hQVW<~LIv(%9v(Hxy%RJjpsvk^L$tA=RD78oaa9`a?aBP+t;p>UA}*#pYuEy z;5>aCy(e+bKetol}CIvwAWZ~ ze5emY^*N~STkI`n-g!umQm-9_y^318;!C`LQhbE-CG8pVQNHha@)6=oNsfo_)A*7R ze5nug)fal}2mPf&kNv@y1_bz08uQXQObTC`1iqA}@}<-uzEr^ZQnJRErb!Kr3&%T~ zr`G4TEFI@`y-2*t;9PSa?R{P7TpKSrn;#tOteZtx5#elHcoE{HfNNvGheZ5l&N+_gD@y z6gWkd%dzrDaztT_Qz(BlM=W2FBbf7?th^Tas*x`r`IhCd^5ytnlS5d{${)t>r8(3W zd`#nj(3eHwfR@&2<5^MCd~>a4qkHFhYS?%#V{JSfJn$hJ6DJ->W8&EvmWC|owDl<_ zE4(k2c;C1k{;@7!giQ15hZ0oI2M%}W0v+eWy+2bqpD<`Zt>LU7&IitPK;?WCx2&n) zeA6X`^Bp-e!1-wGZUfnc!uf_dR;Zls>UNy(BANE&Cd@4B$BI5Bzr*usUCd$N!U5nt zalShQe&&k8_ex+>>T^6Q-&=&|)J5v}UM`P~3f~*WIasBU`^46}2h_@tvrRPFE*4C- z8#hHZl$GzuDKGy=&YBpj^G|t^4K%m0T42sf=%xZXDl7j4=^y88M*5AL3=LVZ?@dbj zGNe}{{ZpjxRLdJ0CP4nYd=1iN#r5FfN~hXr2~|quz67dyd*xR(n)X;ShDxR#G+l;IhY(+$5& zr!&jJgNYMo&SridO#IjV8tj?4^9cNUUxVZ9lYN(lv%80J zoINWoG|t|c#$}vvc2}B;vrBDcOPvk60G!DoF!ujk?u)S{$roSK7*etOF~!1HLZ-v{oFn|VN(brEtsM5{x_zyKS&kpB!JSLp$GPPg9^WOuW*Q6HS{Cn{Kavx?{cxYC2?H)~^Hdpz=R@K7aI0${bN&7NzD2 z2%guMJ35!a4<(j4x_+s_^ZHpF&&SR1;(7f{j_2d12jKbFXZgiTHF&;u`~Y}fAIb6j zGT?zk1IP3F2#)868w2rtoSx(P)bMYI=jmLJUk1VR;7`T)|2Ob_-ArFR@4B~lOU6vj zW7Q5C-gSRT7@q8*64M1fRk6Ji*R7HieD8_tdhmV!aowjU`^I&(7(aS^L_l0ui}Bls zdNIB$TJPkvV(kkSaK2GPscMbp;V0b%ux@StJlu4 zkvYsoet_&u>o@KSA6%}+q$dT&jt^>ad5GBY^SOh-<A!y7ylmJdFk=*hW607eCP4txcvMj;_|lzF3;%)mp7z&+?8`NY^gn7r%O z;F$c}tpj87&u{gKv3oH2F|o&K(oA1Wo;Nc{jD2{J7&~F|smzsdHUuV@Bdo69FqiS{ zz?l52GrlqQBWHPx{mnBRlfQ0J@5lCMV$06)%(IsAJa8-N+I1Ai1=c%% z1>5sAY+)P5GjyL;FR*8JLRwQ!!q6tR5ImS`vTfHTI#<*;D?FGE`b@FlL2U2jdv$al zm&uhxJ_cph>V`WHpxr|;{%HnZPos~|qQCRtpP#+mWFxvM&x(d8w~~FDplRzjx}nY! zS95$z_xc_B4y&k*66+H|R}XNb*L_vbM5=TLha+WE|XsQo$2nWgmSQ2YOQX`S4w8-Dns z({%6CP`kEn+G{gR(6!8ut~S9Z|8H86uI@=Bz1F_luZgFU-McQDHJ?*ss9eG z$fhV@w&VDHSj;1hNEp#{k>-t%w`G~zR$T429fywU8lK)d4d1mu2htf^YhackhP{nT z$)?bIxF&Y{PUoHnenk(=n(P&v}vSq?nAJ?ThOF-MmkhG-*(6&MM>{hZPl%BmfyQv$v ztg@8WHYPji-eB^n&5LrHw(CX!lNppdsT&kb25hE`A%@#27PCudIIM$hCcSk%tj0o9 zojH1MEVP|sT-5hcqJq0fMwR|H@H}tpQZ=}XDY&Z>WsyIkej%A{>~U8-3EcHV$hx&J zbo}%14}i1A`Mn#>-@WmJf!9}d#!kY z!fC#Tc=Lk-qsX*wG7`Lu0#BpC+ZgaT78oVYc0scafW}eVX^q=N_?&c(OBzAr*@KdG zQt}AJk2dOtHl;!i+8-@-z%DpwUqu($wh4TG8FuXGlw?CwUUEuPJ1{Yw(N{m#H|EzF zYf{GjjRKd@IJuYB{L;SdM`g!o@WQh4-rf#i^}96RW-3@^sIn$+g#5iiJB=e`rgm?oN4RFm(~^SGD+ z<(~&1)wtNtCEh2ep{HFvzBG;$^(yf()JgHNT=>U7!oDBOAv-_9c_f?JbXl*^k#t7fk>FQq268kUyFp}*l0=_vkf`4C@&F7O6lT({0KJ`b~l+mJ0S;{blXGLV@u`vaR`8JGwNz&pWU&Ys<{RkJ*K|I|Y%Vhtf0p43P3R+% zn~ybRWP*N^zSvRGz^uRwM+q~S^vps2qpnZgx0GgAWE%AWgE(ltcoAWkdcJN^rac21 z-fQPdDg#pDV5YEObn!!5KUzbKNDbNvuicF`2iMefN>%iG3t{ z<)O~eDYS=TgmYI4#b%gGoh$vNF6nS$^3W#oo%g3CHR<60ex&RnQDYiu_GJ&LF^#mQ z!)RBno}FsaahxzRd1TXB{&0*Y4kJIcmGu37`MIr2@w*msMfXyx z@swXTK>zwEo-)Ed8vVGnN3AU`vIjs+?1F_hL6PT^|`jbhJ5ur-Cchcs&nAzNjiyDL6Y;vVUCmpb1sWVH>x`3ARU zu2Q7eA$@+3bW^vxVs1Zkn18xcv;P7%Mv0Sj-*;@FJ=gEvDb8mNvA^PtJIVjghi{q( zA2k=gY7TtXZ213j8+@3L|0kONwnX1N#mE1r*#Ef1-}k53f49Wn_mdwUX+K=eeZMz- zq$0DgR{Q#Xb-m%)X*?F<_2(%{{uiowEJW-32`~J-I(RI^iyczz_G%FeN!9xP6#M3C z?z>Nw`1<~{;+b#=(L!>p&KnxYM@tw(LQZII^64)_#6e1R*01L?*W+J$;~*En|G+rN z2>XIBedi`0KgBUd#+N(}a?kw(-xcnOgTR*_Fo-xvDXX{uKAi_|eo=xk9%M`1qw)0U zq-}(c4(ZaGhS9!^alpZgO|EOInJq(aDWtXMv^V3tiGSzHO4^pO2KGw6xtH#eU9#z> zUMja%rZK@bB{uNg1|Ax9mBUqy2hCPyyaJuasn?jD=8Ei1gOFeibZ$wYpl z9QBc}=^SS%q&*w;u(5>!omw0~*kEIkTG(EdD4fHVh+YF4I z={({tzkM97C4u`mzF7+_16~o$2LF8=pmBU1vnu;I;xzj>Qu%xz#b3O8ISe+!KJ61} z&M(5&Rm5E9(>1Xd*rQ)e;IWtX1g7waVlQRmMs73WkIgmNu32cZ5tga1e^TM^C-vZO z0-Iz>5V04EYh{hxW>CiR-q;KE+Zj#lWu1t9tvPdzS?97qd*3+5=$ReE& zL4K!Z2vg$I7io+PS)_d(#Mfjcev|AhflqB|I8e~qaIjz(Z0xUgGV5JR94ArnnY$n( zo>_o2v?rjedKAw0(O`#QeQcA`A8X|{;*P^^dc**-UV=r)Q| zDlwivU$hmUxaf)T9Im^x7>~M#h2lJSi8#-Cv1f#EB*h7zgN!wbSP#vk?21g*(97dJ zHVwT_CEk5jBo9XR#-abVM6Rnz7h}C6B0aq~gUMEO|s5N6M=bainww#~o4QNTaGe zSn`M(N2)IIi6b3R<4EJGL>x&iLtx36Do-5gh&GNiyedQ-N&Q~LkuFwpjCQlh7fY@% zdH3s53@KST*8^kX7o=u&FOhn#hkA!l>)+j5^xC)+?4R)qU_rdQ{qH>P^wqj=w_o=} z{y%5G?(0)R@7I0prSRr|)_&dXnzFv_e%;n<194v68sI#!UpD~f{V(j-tz8x8QzwY?jf6jj0_}jf}iq!MENT(^@vj;Y&MV#3+9JuBzon1_4l!!CC)H6xk ztNEE-{q4~`w|d|`y1)aTJ-YD=`T8LxO~lQj7V`B&N}7n9MJ(j&hm=JGOw%;immoVQ%#nakV! zzcH6L))qeKxxC@F@PEr(-o;(vA?NZ+bG&nL|Hxe4p>ct8c{|4qJeT+3uJC_&F7HiE z8UO0Jyw&pm?YX?}B(d+YpSir9$$Ty^`&-QAnIE{cxxDLkh5ys$@@73SxVgOiUE%-o zxxBFt_|E0k3^13c?kx<4H{u@n_s!*fx~g{z&EwI0UP||UO5BBTNRsA!)Z)Ks;w~ZP z?tZ^&P;+-44D!W1&)l5{gY?Yv#9KTV+}&Sp^vvDu*3R7>xG^{miTJK( z?ryhs?(RQt430zIxN%?{^2-~2=I%T=r1eIzKBvGJheU|yY(E^*(#p?^ZLasjA+lt> zx5vFDa}aZV+q(Oo>wB_$;JLmf-M({uPxkP+zAJh-2D$%k&AIHu=}s4ZE<5bcse`ap z6b~}Tmh>7K(J9&KJhx!y9Wvyd#n|3M65H!Ji+niUGs4dzhyU3#%T4DW@-ti)KIDrz zEbt#I$bZPpx-XWU>VmAdlO2KIXn;Lt|HS;t)dXZW6lT_HMXPJ_-0t_+dSEu)|3%eEY*dnqddV^+|x0p&)? zmPOH!=@?h-v3>ACwz~COixSwWoVpELbHj~IIS(A(R*o?W#kZ(EorxQ_b|h}ts-Amo z2sboE;(G(~bnldGJ>X3{czmLoS%2v!TZ8@yXQxbbj_yvAt>?7#+R7zQePzJ7&v0?t zv6?Jq>ziK+yTbXb-2bB~!>%bqg1mG9vsFRfMor~>N1wSyPgU`>w~Zy*HtPFn;{#FK zsEz*ZGsxoHb9@^`?Ry|{8@11=p{+qfn?Cdgf^8q5bRBHkxl3s2$(cd{?FEuh%r~_(iaGX!~pUKhR&pL-$u|kp9x{ zaiaZATrOu0*v_yJ{dKRVoeuE6I?Jlq#t_lh)a zoED^woicAD(Hx1k5w@L0ZOde*h~7-Jk8lUIA(we&k1(1)4TR%u8an8F?XDM1HuG3t z+EvAJZHF^|069wNM~)H(VZ#$b z+wk&Wa`fA<*K$WaKWI714zZobdbJ6da%Aq4%$}(`yzdazPeA- z4$D8%4(g-xLE3@zVC^_@F<3iF2W-dhF9vVNEKNJ+4J32n{m7hg5He>BEpv{GL1gYz z-D`Gb-usauC34L+rRyJ@11lbr^nPvgL*|>vGB9j5IJ; zCwLkSY`CdrW!|a%Y+=z@wl*8`vYHvAoS#asMNNG2tIMV6rYj}G;a4QX>>l8}@e@yc z^_Y=a-^br);VfYR__&-!IjGOK|STIMtoZ);8k*)ly{BaVhept0S4U zq#%A<0_tuDZ(l*Z<;btpoy*qJcsU1oYgy!~9HcV?t8mJ4ZV~9MmLd;VqkI~BH0ar+ zE@}9L^rxh?9Z35#W6cU54l;!gC*Bi#HycP!DxMyoJ;f6 zU5DLAq`DawSB|v|F=SMZYJuM<)%8xUITChtnIzB7Uf7sM-?5=pqfW@i+)ni4h6J{| z{9%);_y+R@qpo)fGgOT-^nLMx)K)o4C*AsdM#hR!RnUc9;7P}5V0ArnDRCh5O9tdt zOCyylnW{z=fkrl>Y7~vpCH5cBYx7XMiRMO>N8_no%vSw9@)IN*fOzQ~GCeRBi^oy8_=i<@8*7_cMHd96XYdA2c4N`d>b$pYjsq zlW0dDRjB%=6a1+abk_>H)jptnI>CE2&BIF_FK2}xkGsV8#8;Je3ADWEcBcm8wYDGM z(s9}J&jTL0Hh!s}66||bmW;biwn)fOlhQ9nrC*4)x!^gC8TX-$G!EW}Hq!bwj1hC2 zME{U1Qy%(mM>PNDHk1>McP|N<%R)N&s8u7`kOSb!>Sv!_^w_hlcg_R-bUyzVNH3D2 zovR9Chqr+@^J{L)`vTv(@hz=i+^EnMvx>@eKzDb;R@F-JtLi|@m$Xi56kFR3dqd;p zPK?`6$cEe%etNSjj7>JPsPRU&dkDt)YqMWnzqAI=hN|^x^lV(xxU@*vmYtBg5!-g01LCeyfv>RI{Iz5eyA zQyk*G4eztW8Z>Pm5kACtiPIS2OJldVb2%6v{M&o5Vrt`S%z3rz*;>LgWY1fm z^S7;*7H+TOwt4mY?jw$ltF4bS7XJ$5?0sWgQ=63jp&4?Y4teWD{`S#Kto=>2Uru9t zJ;#ofkVTqnHb4%m4lt`ZlDWD@^B7`n7IR%(5YepWrMsfKUM#lRX-vD5<+tyI-j0)P z9VT4WBt1mRDS@VQhr`CT7uqoFY(1dRb>^7(@slfQOT z=rQ@V@qA4F>)U-}8|s)$7s)GVmSJ_$<*@e4dJ75dRFPGsP!uAxqpnFPH8s{K=JIW$` zC0*CjKx3a=_^st08s72HuuZUOf={o%SGHd=E)vQKMz$v*T9H@TwGKh!UmqkpKM=0P8hqkppT{`SoGw;q?G zduSh0j)Gqe&d(JYF*>_Pa~Yxax*f_{#mrS%Zz-s%uPbQ%#=ZAAcyonYKUv}T^}q{g zO9$F={Wo5W1b$j0<5=@=J$%$zBk=55+mCPJhjPB^RKAvmAH8^ABCu4Fhp*3H0$;nT zWh<3?2LJ72z}GbzzTOp@uLr7$uNAh7_bs-820y+QJ4zDT3a7=W{0(<>PP7!Bj2oEG zhctX9-yfRK(;X+Hra4YbY%3(%D(mYDR)E)4^$i8p^$!(%AH1hNsQcQzm(Ia@tWWTM zjo>}n+xs;z*G!X3<-gLtQr^A|XkW*C(dOAa?O{s0UZgGNX%yR#`v%4a54 z;e@QM8dmC3>v6l8jp}g9uzBO~9&H{9S|@|XJkYwXm|1_6$*fbA{`aN(y{yAq_enzs zr2DqZxE-eT?TQ_Sul+r(#jTC7xu-JM7}~#>&hC_CZ#ndR{Z!ydO`T<$I@?+3IyW*l zaY!e4-Z`A(eu_KNGmS}#M-mo? z{HyO`#5>^rsuBEMR+@O1Al_k2Qa7BxD;dTrvhi*f#w6W%r(itfzlP3j_pd+IuYQaL ziie5%Q-jn$RMej$>PQfE;9VW^(|V2*esvs3@~Z=5k<1icPG_QD9aMj^s6WxK4z!~R zWnF`@$U78Ug03Edt~NqfF+N>LYhfCpt1VgHekMPW$!N_}lKrDAq-Of2(fdsTG1mSW^)Dvl8R=U|7Z=FeK>|+43%-Q(dyr{+W(VUQT!l{jmHj z#&&5uKgky5qjg_IbKL1ej+kdBwzf${I5EK`1Z3|m{3NPBTbPbj`URLUVI%sb>-q>=_jtX{SxWO_N%m=U2dBQ&(GB0Fv`=l9EZU{x z?fNj>+pcz63mMJ!?x(X*(cU(37HXByPg9@-1`Lp|F= z{lKILUi(`#j|H7Yd(0@G<}Q?RutvXSO&o~qa@Vm^+xc-O*B_9d%V4VAf%X#Zrf{}b zO&dKyU5jT~)Tm>7mQlRr8`Bd;jE@+`Mw$3qiFdQ{$15u~Dr7MEgC<_dMzR(#>t~F?T zTO_UBw=AN*UxjBWod2eJZWXd%{@T4KjrKZ>H`$zu?N7HqC1m8bFWlGMgSr*WuaU)l z@DrtUpS)lC>qsx8{C<7)^Ik5yd@p8_{f(zsvo%P$HsqU$^j%1QjP?!t=|C&q7twpa z^leDbN4lh}+vKr7iWmMejWrVw;G-1Xcnkk&J!O=3A1i#zfpDg*1y!-schRr1HV^FD z^jN0cl}pd5V%=TekELel-l-4k{r1Zu|GGGi$F5kVnbQ?({;pvZkL1{E*CQsIa@M^O z<8ky|O&rE=Vayr@yKAh;%&U6ey*o23->Ud%@bv`Bw8LgO7c<)*SG%{+8h2X1*LQuf zCT0v-3Fq@TzpS7!uJ3y)vw8(=bv7@z6a1`4S#1~T>;(R;3AR+pw*&d6@q8r|mtX7N zV!7bW$1aL|I?0-On>XLZJKS4L-zfR$te`3BBk%pHQsU=0CPHq_qTNia&9sSjQ=3;3 zW}r2SespIszMl5WbM7sz=vTtSJT1}gL|PTnKBs*o{|K*}c^eKeUtY_149x4wAiUmx zSn%3XsFYiea+_}t!RrIy;mf@Kdg#Clt3&ZxXU)9e<#pkze;u!%3c~BnT3*Y#qkXrA z!On%l-bH}tdS%R*+)`|#SV~F@v!=GeSHnM~$1}1~72UK}9r~kJ_8<}tNOrctCmQRR zbv@`YX3`z&%=$h2r~NXtCvZFLs`?$-J^1fExv+B?Qd{BrNU~eZ6$w1bfNP6T9>r2J z!uP*S<+bZ2N4vh*@$3-3r@Jo2%aa^U-7MaK>Hk|7bz!0?j@7k7Mv z@tB_bwA9MpEwpFJyAF6J+CKw)m~QL4b(#%);qfz+k1=P+_o}^^8^P^GrnsNx;(fn_ z-;j`Bhwo(YH4OeE@~9`yLF0oiij?PD;96Hdr??Gm3-(+w|a*5;F11w(` zB{_6aI!8x?5osp;X84ow7lyxZNB37zy&VmDNBZfgUMY-K0PEQZj}iViR>?{~(iy8# z!aD`Jgu?}L!n+0SQ$a_<+XZ0>Zxzs4`QZt_DQJImh=V1(SrCzMsGxIGqC=N(5P9Dy zkP;3Qv_Bb-cl!$r#ism^wwd#U6~K1JK5$tW}*Ei$X7?h0!Oh-{F;aV%t3QOA^C7uFg`?S z_z>;K2cw1$k>GtlC7wvFUehr_f&2$#@ zrSPf|azXrRe{?ZuSm>a8F*+I+IdpM!SKWMvkz_#*Q+PplVn~7?67fUF$C)&Tv^oJg zB|)e30<*|mr%IOhZs{uJ_gtOmc305dO|9L~xj6p*TD+g7=-hNi=R~@nqtwy0iq1$1 zcdStEE1Kr0R_-e*c9>T(q|^NzC5{!!eMO|FI{apiXbsP5DPMiKqq05>e=`1b_>=HQ zG+PSIB`hC$XFW528uSpjb$JQ&ve?Mv->Ykc{>G*C_N|eSSBGz8o4RKr zs15@cCNsTt=rp}YhldZhEb{1a$xJ^zPSogeg3#k38aud$Xy7)jqbV+s7n|ZaFQ#gEu_eLN55D>w3w?&ZHN@dB9)HkHl-=Ht z=r~TinCj(~SDzO;Bw?=_(fB!218M$%6f$8A+8-FzfIxNa`H*{hqSPOh7h)2o|{ z@xJ2Urki{ZPVe$k=o@g%8tA8fMz2;s>%+Nz&N8d>IlwKWnM;dXNFO!C2vXqr>&2Lox|t9|sYp7&Avt!fOLuw?}D>+zidePrbG z5u>^7OcvO3C~#s*F~^Gh4D=NH8y~p0P`?poRQs+AZKQat2dfa~Z1rN!Nc4jpxH1Dg zr#wA+y3dI@C@;mF)V#EpmCoiGSAS@*RUSJr{2M~J5lZ3P_-`wQqyG~%s!2+ecN0w2o2kD0)bGvG_S{H?`% z&g0;D6dt4Q6$Z}ZM{iaA)bQRuf1D}%`l#d<*_y(_toP8|7i4%CeAE8OX^yto>5iX3 z7aAV~HjWzN*dJK}dz^@Leh*(qRJ>z<3gkB~!Q-1wJ{qIk^S9+e<~k6`90wvL{ORx~ z<1ftdG3;GOt)=ilWVnOos2hJeSLrKSFGe;va^bLT>u-l%K&Q%p|7U?7rO(%pPU@}g zt1N{X;nN&hG1DEeRj1nFCo;lIU}K_@RtjA*I;ej;;YYG!it((+Z-axyu!<86bKq-c zJJ#Fh+Gu`Q@fp?RgMn$HW;tk`9E%HgkROrYQx)5)pXneOA^*XkrzP+e*`PBAbY|4O zU65J#PC-`P;eye1?-n%PPGgZFj*PnfNIy_;S>2ljW9r^27+d$7f^l`gec)YI-NAy< zXj{8J7Wv*N$VMAarp7xyNl$Q`fY0cZ;~bGf-pW)TA;U)?y(OLzwr8m_wnwB|3sfqHW;4({e=Ab;I%%&Yx?Ov{$Q@~2XFp|I^Oyf@=Ewd zXQOol0XkseK0(z1l7EtY(t*Y_$bVA;m;WtvZywhH^8foIO^Pm%-zWL+XyWou`miM} zxDL?xhUA~-+t+6mD{Cn%kpFCqC&(wzn3v=tN0t5Uko|)Z-&*!tw6c$J&tPP~BWfm> z|F|+dGY8=cIwwO*<7JTfOz1!sbYL`eU>xN9B;+y!vOWf~KNhl2e9MGBoB-dlpcA7Z z|DOWusIvd@wm1jz?1TmzDRN&Vx!hAF*xMLKFpP9UUX1S+a@kK4vcILRP?7zn`CRrl zE#R`>G*^-R_D%B?`EQH$mHpz_;If}0WPg{C{VI*@$Kl;Q{{-3RvRn$eEP;H|xZ{mo zs?EPNeF!W=)rAdVV*dX>G=6s?VWZG~HwAt-6+TnNM}&t$`Pud$ezrWq*U!>9G~d?G zKI7+S4LYx%{U9cy*&+!)OMNH&?2F5QXV7PvUwiv(2h!dfjPIRDd%Xwny_!6#@4Z^$ zeBO17x(__P*AQm1=?pZdW3b0ErleQC@7~OQb*+`+^~zeAJeE}X&V~<6Q*B?Fe(}Lq zY}m=K_}bfaJ74?Cj&^**Z2RNc?h~?(`qY(aN#?O#L=yc!Foh}q z_vP{b*WrKP_5XvumX!Fp`4Lku;guf%KQ@Z_9m1u+m3!%~yG-Cq^{%^Q1#{7Q&|+KP z^#^v{9swMznXh;X`CBye6}vR^6)j@Eq7=NhXyz-5@LWmjc2TA}Z$V|}FY8Uk_cl5= z>x_u=?@waQE%^2j{?j+_iv3jc1fLCPpYeg^hv@EBoZUr<__NK4^qJ(M=qM05UoDzkW6-~9c%PA=_DrT+ub_KQ~rrvF~iMpc%OH@^}3 zmn8Q1sr+_X`mckCFE!_$q~M} zR>;w>zCW-W-S)C*cigC6(QX&@7YpNk$1*Vf3uAlwE90$~xP35eEba}JC(FT_m9sYd z-tQOhJ$k4w=}mPAUgEd1wo&}9iK4TTm~z%0{jXfXtg#puz-Q2&9;MB-nl_h#zc)sC zqof zo2c`O|DDMDX|mu^D4xU$p44f0Vx+Vbkv4>sBq#!^GK( z;oh?ssZ7edMby<_zihVkBhxw|(-B^ot|z{w^e@xvL>`sqyKf+wF7=V=P2n1uHhN`x zD2fdqR(Fr>oh*$9Q;OQ7I3>>^)Yio z`k0cJMV{!nA@k&`c{Ya5Gj})ns(FL*RX_f@pRYoD;)Q>T7XJ;Zzd}1sM)0*a{8_fn zr+zPym2rLL3fbBbP5w-_$}!w#9A44Ct={>)-Yw=5G516mYlyJNv0i(;^?QS}$FIB+ zhy@1fpT|Z2{48SN{`u2O1NYC-mj>>ik6#&l|4g!9TL0Yd*FT?z@&5TZjQ7tv(LYmT zdH+_OM+)d zD=(dAuLz#~Hf&&?ePbJ#XJ6R{=2^rg@a%?5w243VUkFVMyyk1Yv| zLB78vFb4Vd5)p%xy)j62>~mnrrNQ{s56VQQS% z|GRwP*k8mh-XGKthWnQvO3!4cNLSJ?7!EZepK`89k^K7(It!&mm*lT!blxo0sQ`dL zf4_c9^WN&WQT#kx&$|xIJ38xEEq7Lnu9^C~SjYC5OK2YjA7?844jov9_N#fnOL@^B z9pEFKi|wDca*6L)S<#7lKG&%HM)^Msu^?@e2dz*=rYk&S2K9zj3Gb zmv^kgcMPWLNwEG2)9~^9cJO8hKXaGlSj(5RV0^(ieWKvSghBA)t6lxaQ6-XJ@RxKn z@f~;SYln16luwO4QJ&rkZ=5Sw8DCZe>Y|g&#m5-Zx3H#9*;^!cHG*3=vhyTJVDX|LLk3{xkf0);P zsOx|fn<@)Vg)~hIs z?C`7*c9+hOp}SGLV0RZDac}YeUhP+YMt8FPVJknQd#`4Xhk8Z;lX<`Ixq0Az?-la{ z1IhTCF9gc%mUncDuf6I}XxY50B2YHNH2&>&w|fi8>S{OlUyt4#+~?Doi^|?N*nYFH z#kAk`2jIU&V~ZO#w%8(U@gm4rrN$Pk^vnTm3n;hD;jF6T5{LGpbGxaO7@RICzu4raDrm>}~zu|pTW#Hc&*Yoy{673Dp|HWMY{nNi%?2SpMC-b>N{}_39h;L7b zbnV&XD!;M~92ZcmTJ3LT{omr=Ep=jk!y+)oQKZrO!!GF0`V@ZdFx`K2O(wHan?GCu zU0T8K32znmgtv%$!VfIw_k`1W8vnRE#k{FMU#B|9iaG^;*h6U(MB0@+?G;KZ5ozD$ zX?CPpN_5uy-g0lLTPogNC*psL1#TFs%C7fJ^ye0H`R(wLU+??o#U#VNXQ+1xY{6P} z*3ErxrRG&K9^|__JYpSQt+n0AB4643VE(t1WW?kZ(gAbz!@_@ z1Njc}C)${+c?HKLl&^4cAco9a%;(GMH1lN>DJ@rEnk*@xuJMb5`EH$cnvVBL=}nhD z1`79#jZGo#K-|uO?McK=8e=ePhbJai)=P7)ZW^z3>O3-0)5~Q-Yu9g;Xq>{VH@n1-!j8&BtgIAx=~ zHkr{Guc!7y-Xc*>Ii3A6al=*{%F31uP4o^vH;>+vZB92ZAO9M)XyEzcupO5^Z*+3k zz&7abtrRy2l<8nRKhYYDQZNrH3em1jHvZg7%R%cB>8zTL60`gUQ9=dQqvOX{7UwPYg zR^xfz=Km6HCVA4Hv!JdG*t~GyzFyzj|2VLAVXuM-m3hYt?n}b3=cvCQ50r;s{r!iX zL39lL{Dz2gJ+Lge9i=gJVAy@l3RPgjRM-Wb30BX^bITAEy8HvUM2ElkbqN zG3R(c%gcg~HU7GQ%d-0*ov#`WUmxKUFI3I~k@=d$;sh-|#+ds0={9_4eHUezW0gJH zduk&1n1JrRo+QQu7!RCkrZEBd)QGVF;gD+B(K>M_syg2I?*;r$RR7rH9;B}XHtdOF zdsYEMn$vva2g~W)mdL;{1$|HY`V)Ll-_V$)2Hz)te!rKt640i^(^!QCv{^t;9q1{> zf2#W_d`oB4nNxi4StG1XWj{t`W4xl=&oC-<+i5*ye{H`{v>jvez;=w{b=^sIO%QeE ze*3yA)w-_aF&DKiiY->=s&N-@|5hv*e9Yy{VT!qUzYR9Fp!<2$K33&$>Vm*^bCVYY zjsvbH9svJSY=ZXi`;P;1Kx^wEU=Uy)$|JemdxOO~M+^H`xKusABT)X+$FNhNmD|9W zi2*jyUrr;1oSBF5HYhQB&6-Bt0v@BQ8p>mIKMxXTcg+vv!x^Nl1Ru(iA^)`ZZ>+EU z+k=$zDZZh0hFyR?z&CA4q1Sl*h4PN_uJL+2Sp1*z1ZmTIlnxx(LotpL$yx||(-h?U zgMuD9AM6LHt0Ep_^C0U!U!Only3gJ7eb;@yJU?*V=Ud1zzA9+3yTlO~=U44PaL08d#$au{K zJ|?~LBDckV`d(;Td`R;83{?kyHjm?iNJDU3V4^;W@Wws-V`tCL3$Dx0%;UP{`OZ)F zH`Dtoh3<|0_I~)mc|!McgXrE^u6uVQPt{~T?^ij2d>xl#`krKY^}NCR=9qT^eRF?f zn8eoL>&_`AsPHwPojMdI{A0fGkL%3$di*2!-J$dHy98}X3}VX)h@Z%tUd&F>IeV*C?qr!Gp&XjyEY$i*KL48yo>1LVp|@`JUFJLylT`cGZys&fJQ0r^>y1Yy zA?-V;k7QUa=Xsf9&QRs(=LN8zRbs`pT5wZB=b9pS@Unl-JH_#{kj_Lv3WihBHtsi-h?%&rOm@DwT zU!A|2%k?cgs()XW5!rwF_7LU&BuJaKBaPx67Y$ahwv6@8a}1v^zgj#bPj zIrRIkaW41aYT57h1(sba@+@d`Z#lwzWoyz!w<4p5viSI`Wi*$ss?j`lo*&W{-5eYgKIjyJ!ccW6&ziuYY+ir3HI#kfvs+q*>cy+_V-#e3oN z=Ms-#ms&HCcBQYb&6o>4^eeAeEiZPll3RPO$CR`I(abx)qlv6DHKkFDtb)#L{v zw@s=Na?uI7fd8#bA^Be3tIYS*->k^@IDAX;(b4CXk1V8}Ci(EIXM~{1oZP>BS0?o@ zf03&E`S1S`vNrAl#}WSTFU;}ER5gvY$MXG`m7t0CUXq+l?Q?ITxt6LF-p^V-e>R8n zdB5IU=BFt0TJh~K_PGP>&ha_i?sO!2?T%XBM{@%E?bsYKb{XPbU*M5%G-UohLS{mi4+QOMRx;m_IGM=Xm||i5TvmTVuR!Q@{Nw zm4$EGqPc&si{}2_W5a{A^I4Qla;#v230_R_B&C=1KQ7rI@~GpINARr9_Ykc#ciqy9 zzJSfnr18KaUwVH8dK5d0el$YXr3Z}LIwHK|e>LA7b2xqtzzk_TpLveJ=HXsFRllv8 z!(%m`IXN+RsIC*Dyx$Xjt(Hk?i|6olUCP=Fzja-6h>ztW{|x?aCgoow=Id4j_H)r3 z-}PD?C+n==!?-8O6RXu(&q%B}UW2u#(mY1QblVaakL^li(;k`SSyM0{>0z4uSBW@w z>2;TmyRX^F*FfIt5;4Y&f%6(FR!V;c>~jL&OZvEfF!p5h7MIl=tD0*#pPF zXYBN@_ab|+Kghh}{|urW*K-4}8~bt)c^>%bzetgP{mjuomqwnW@srMah3Kb^ODqpC5Qk>6QD?bD_1K zx=Hhwt@99YumtjxOazIPUt-6NmpY7=d*(K=^a6I^)k_?8RGv4@qeiJ zuiC)@=Xs&yi^ck{jbd!QoMZ%;BZtzV>woIy@wvq=$|qSD(tp^B&M&#nQ_O?r#AXVa zI$z$jB$UqAU&xn@1Jwtg`;Ql$$#ub~lT(Kv7w+0$5W z42sIBE9YyCS~dA8{XR`S&klPEN|aYIo}aH)V6tiIbRdI-*0^p<-e>vaDNijk<=_T4=9Jw*QD~mwMEn? zcYMip zarpVpIbqCN6UkgjHJN$pxz6o!daio5^LAavT6Y|KJ&Sbl!HC6lkB=cdZNmB#HnD3W z%kQ4T@+-g_IxBs9iD_-Uk}q1x7fE@I!zXOGGGd~dzX$odr?UJX;2XjfjSmj-8?I{R_`o4f%LnP-s7gZbj`Y@-_d#TI%TciIq;m*pmXk| zHWLkU3cgQNXn0YfA+f1Z&~Q%BpsrD(zUK8M+JA%kX#c_&bVhbV*wKr3F<0O6ID8Y2 zdK0*ehjZLxxUAR~DO(n0XGU&I?9f^197)5G5}VX$vN6m4g0l^hwX0g(C3#S1J%MMs zlcpubQb_mG9RG2jayR7ZtHiw(bO)=x*wHD!Q9$P-osjnzY>A+Alw`+_SW98oV&*zA z+){WC#tu)Tjchu`5|HJpS-o3Ykaj47S-U6BvZXWTN`FXRmwHmU|J&uRm)EtAZYylm zFmYcw>(YkMgdXJ3aFBgJ` z3v7MM=i4scMSEt#l>X0n-~Hu|c($2+ztCD@8fvWyw=9}+xxSg!j;rna$uO>m$h*5f zp6zCrWmrpE!mUz-WzprxOTNK!*nLEK$8^>b7GagbEQ`im&cEwITa-0!#mqXH#tr&1 zTjy-h@D*Qs$L|l&S!*}0x>pEtaGyp7Fg~RIl~`LL>3kOc=NkAN zfzsbH@9z$j)rq>>ud)<&OaZU&qPuJ?g+1u|n5X)byX)1yr@P~tVXNC4_7`+C94P2) zI9PC^;f;cm4Q&NaQM@B6%yDA8rSPOIJFYQ^{$IfP(@_S$gtYebw!*F#XW4p6m9s-# zRBwC3p@QQ&qw{UZM*5_%b;nL79_XhWX z_Gt8fG`^by-dUu!!Wi^@j1;rYc|FF`b(R9tV+RU0LMDtBgO&Qb9KT5M$&Ga5tZ3nn+V@j`9{UsC#!o9D-emYXf( z`FCf8+*p7y-T?lx>|oZW(;AsU|JtmO74-G1PjH#pzDRQyTNBxiA)uY#$rd0t(IyAU z%-Msm6L$$afigP|LT-@Ol4dDv&4S!CKyEh4jw4%zy_h2IWz!3pd6aC%n+0^g(upTc z4zd|75t3ua5cDhh_r#O3;}?1%Gs`${Dj+lPJA243klpB6&SfV3WZ1gY0*Tv=&aic@ z^#=;NXVcy?W+Qr9>JLJmBAq15t-3HrG0DtHE;9%4yXT;gnUlUUQ{Kv~iriG2TqG}w z?1Y;f#&)AMGRe?HazS!qdf4Fb$V`W?%+P)0!R4a@JYEdjvdDI^33@H=pbI7=8LEs3 zK0G!ww2UP8BO|e@j2!gJNZ4sEBO|mjg1%g4<#uJ1mCH!VB8^?~_b>4Zje9WH5xhy=n@L%U+p4l>Z zAM>=IkC_aA@|4EMl+ENmrstJeHu5uczf=c&%Pz>rK3$Ykkq`KZ6!@1m$j5Q`7m^L4 zi{yc5>-qnIkBQIq^)U~mhL)M|eq^RECs1b2oZ|MQ_bXo?^V`kb$HWR;5~0dWsqSds zRKm0d<(yB$f?^wkoV1t1Hk^jNn8@YCeOk(IPqh@j=zu&7H@WEE74<&Qp3}wo<}~KY z4rfQ{%*+*$mO|p)28m6geSa8-E9WSgFYv;o;Rsnc%D5nhAdVx5^JO2FpIn$6$vS`0jI{eT-!i+iPqw+168> zys()1QCZ(@JM8{45JCh<#pSKhr8atNZfI^jn-ibqoC#d!<*wX+tfJ;0xL0(8&U-)SXQSEV+HSVC zHPf4q?k}p%g6w3liWJl_<$d=Nx*wD7U!07(&M%#$oC{C#Lf=q%F4~8UZ|Sa3T{^3v zJ7cc}Jjtp!|2|3lZ)Jlg+GzrU7;=9=yN9`O2DF5kByf3KXDdnMjq z0a@Co%68U!kZoUC`g;℞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Π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¬Y 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 z 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%0D%DDfD%Pkh*S-@LD4)v-v|4B?p92s8`Y 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

    e4N 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

    (B7^uuyFTA`ewsa#s=ctKRa#cb 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

    8NG3ZGi3 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%0A7p?XIsy%X9n4 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

  2. YauPp48P#KnEn}-sp>_kAYvxq8#M;m^d*Sz*z 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