Remove rust dependencies and use published aar

This commit is contained in:
ganfra 2022-03-28 18:15:46 +02:00
parent 7436647571
commit e121007d20
17 changed files with 26 additions and 3196 deletions

View file

@ -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 {

View file

@ -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: [

View file

@ -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

View file

@ -1,50 +0,0 @@
[package]
name = "matrix-crypto-bindings"
version = "0.1.0"
authors = ["Damir Jelić <poljar@termina.org.uk>"]
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"

View file

@ -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

View file

@ -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/

View file

@ -1,3 +0,0 @@
fn main() {
uniffi_build::generate_scaffolding("./src/olm.udl").unwrap();
}

View file

@ -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<PassphraseInfo>,
}
/// 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<String, HashMap<String, String>>,
/// The passphrase info, if the key was derived from one.
pub passphrase_info: Option<PassphraseInfo>,
/// 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<Self, DecodeError> {
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<Self, DecodeError> {
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::<Hmac<Sha512>>(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<String, HashMap<String, String>> = 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<String, PkDecryptionError> {
self.inner
.decrypt_v1(ephemeral_key, mac, ciphertext)
.map_err(|e| e.into())
}
}

View file

@ -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<String, String>,
/// The supported algorithms of the device.
pub algorithms: Vec<String>,
/// The human readable name of the device.
pub display_name: Option<String>,
/// 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<InnerDevice> 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(),
}
}
}

View file

@ -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),
}

View file

@ -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<String>,
/// 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<String>,
}
/// 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<String>,
/// The seed of the self signing key encoded as unpadded base64.
pub self_signing_key: Option<String>,
/// The seed of the user signing key encoded as unpadded base64.
pub user_signing_key: Option<String>,
}
/// 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<matrix_sdk_crypto::store::BackupKeys> for BackupKeys {
type Error = ();
fn try_from(keys: matrix_sdk_crypto::store::BackupKeys) -> Result<Self, Self::Error> {
Ok(Self {
recovery_key: keys.recovery_key.ok_or(())?.to_base64(),
backup_version: keys.backup_version.ok_or(())?,
})
}
}
impl From<matrix_sdk_crypto::store::RoomKeyCounts> 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<matrix_sdk_crypto::CrossSigningKeyExport> 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<CrossSigningKeyExport> 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<matrix_sdk_crypto::CrossSigningStatus> 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<Box<ruma::UserId>, CryptoStoreError> {
Box::<ruma::UserId>::try_from(user_id)
.map_err(|e| CryptoStoreError::InvalidUserId(user_id.to_owned(), e))
}
include!(concat!(env!("OUT_DIR"), "/olm.uniffi.rs"));

View file

@ -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<usize> {
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<Mutex<Box<dyn Logger>>>,
}
/// Set the logger that should be used to forward Rust logs over FFI.
pub fn set_logger(logger: Box<dyn Logger>) {
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();
}

File diff suppressed because it is too large Load diff

View file

@ -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<string> changed;
sequence<string> left;
};
dictionary KeysImportResult {
i64 imported;
i64 total;
record<DOMString, record<DOMString, sequence<string>>> keys;
};
dictionary DecryptedEvent {
string clear_event;
string sender_curve25519_key;
string? claimed_ed25519_key;
sequence<string> forwarding_curve25519_chain;
};
dictionary Device {
string user_id;
string device_id;
record<DOMString, string> keys;
sequence<string> 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<string>? their_methods;
sequence<string>? 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<string> users);
KeysClaim(string request_id, record<DOMString, record<DOMString, string>> 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<DOMString, string> identity_keys();
string user_id();
string device_id();
[Throws=CryptoStoreError]
string receive_sync_changes([ByRef] string events,
DeviceLists device_changes,
record<DOMString, i32> key_counts,
sequence<string>? unused_fallback_keys);
[Throws=CryptoStoreError]
sequence<Request> 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<Device> get_user_devices([ByRef] string user_id);
[Throws=CryptoStoreError]
boolean is_user_tracked([ByRef] string user_id);
void update_tracked_users(sequence<string> users);
[Throws=CryptoStoreError]
Request? get_missing_sessions(sequence<string> users);
[Throws=CryptoStoreError]
sequence<Request> share_room_key([ByRef] string room_id, sequence<string> users);
sequence<VerificationRequest> 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<string> methods
);
[Throws=CryptoStoreError]
string? verification_request_content(
[ByRef] string user_id,
sequence<string> methods
);
[Throws=CryptoStoreError]
RequestVerificationResult? request_self_verification(sequence<string> methods);
[Throws=CryptoStoreError]
RequestVerificationResult? request_verification_with_device(
[ByRef] string user_id,
[ByRef] string device_id,
sequence<string> methods
);
OutgoingVerificationRequest? accept_verification_request(
[ByRef] string user_id,
[ByRef] string flow_id,
sequence<string> 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<i32>? get_emoji_index([ByRef] string user_id, [ByRef] string flow_id);
sequence<i32>? 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<DOMString, record<DOMString, string>> 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<DOMString, record<DOMString, string>> 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);
};

View file

@ -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<RustSignatureUploadRequest> 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<RustUploadSigningKeysRequest> 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<SdkVerificationRequest> 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<ToDeviceRequest> 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<String>,
},
KeysClaim {
request_id: String,
one_time_keys: HashMap<String, HashMap<String, String>>,
},
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<OutgoingRequest> 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<String> = 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<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<(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<Vec<u8>> {
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<String>,
pub left: Vec<String>,
}
impl From<DeviceLists> for RumaDeviceLists {
fn from(d: DeviceLists) -> Self {
assign!(RumaDeviceLists::new(), {
changed: d
.changed
.into_iter()
.filter_map(|u| Box::<UserId>::try_from(u).ok())
.collect(),
left: d
.left
.into_iter()
.filter_map(|u| Box::<UserId>::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<String, HashMap<String, Vec<String>>>,
}
pub(crate) enum OwnedResponse {
KeysClaim(KeysClaimResponse),
KeysUpload(KeysUploadResponse),
KeysQuery(KeysQueryResponse),
ToDevice(ToDeviceResponse),
SignatureUpload(SignatureUploadResponse),
KeysBackup(KeysBackupResponse),
}
impl From<KeysClaimResponse> for OwnedResponse {
fn from(response: KeysClaimResponse) -> Self {
OwnedResponse::KeysClaim(response)
}
}
impl From<KeysQueryResponse> for OwnedResponse {
fn from(response: KeysQueryResponse) -> Self {
OwnedResponse::KeysQuery(response)
}
}
impl From<KeysUploadResponse> for OwnedResponse {
fn from(response: KeysUploadResponse) -> Self {
OwnedResponse::KeysUpload(response)
}
}
impl From<ToDeviceResponse> for OwnedResponse {
fn from(response: ToDeviceResponse) -> Self {
OwnedResponse::ToDevice(response)
}
}
impl From<SignatureUploadResponse> for OwnedResponse {
fn from(response: SignatureUploadResponse) -> Self {
Self::SignatureUpload(response)
}
}
impl From<KeysBackupResponse> 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),
}
}
}

View file

@ -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<Self, CryptoStoreError> {
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)?,
}
}
})
}
}

View file

@ -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<String>,
/// 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<CancelInfo>,
}
/// 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<String>,
/// 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<CancelInfo>,
}
impl From<InnerQr> for QrCode {
fn from(qr: InnerQr) -> Self {
Self {
other_user_id: qr.other_user_id().to_string(),
flow_id: qr.flow_id().as_str().to_owned(),
is_cancelled: qr.is_cancelled(),
is_done: qr.is_done(),
cancel_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<RustCancelInfo> 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<InnerSas> 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<SignatureUploadRequest>,
}
/// 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<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<String>,
/// 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<Vec<String>>,
/// The list of verification methods that we advertised as supported
pub our_methods: Option<Vec<String>>,
/// Information about the cancellation of the flow, will be `None` if the
/// flow hasn't been cancelled
pub cancel_info: Option<CancelInfo>,
}
impl From<InnerVerificationRequest> 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()),
}
}
}