Remove rust dependencies and use published aar
This commit is contained in:
parent
7436647571
commit
e121007d20
@ -72,6 +72,15 @@ allprojects {
|
|||||||
groups.jcenter.group.each { includeGroup it }
|
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 {
|
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
ext.groups = [
|
ext.groups = [
|
||||||
jitpack : [
|
jitpack : [
|
||||||
regex: [
|
regex: [
|
||||||
],
|
],
|
||||||
group: [
|
group: [
|
||||||
@ -13,7 +13,7 @@ ext.groups = [
|
|||||||
'com.github.Zhuinden',
|
'com.github.Zhuinden',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
jitsi : [
|
jitsi : [
|
||||||
regex: [
|
regex: [
|
||||||
],
|
],
|
||||||
group: [
|
group: [
|
||||||
@ -22,7 +22,7 @@ ext.groups = [
|
|||||||
'org.webkit',
|
'org.webkit',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
google : [
|
google : [
|
||||||
regex: [
|
regex: [
|
||||||
'androidx\\..*',
|
'androidx\\..*',
|
||||||
'com\\.android\\.tools\\..*',
|
'com\\.android\\.tools\\..*',
|
||||||
@ -35,7 +35,14 @@ ext.groups = [
|
|||||||
'com.google.testing.platform',
|
'com.google.testing.platform',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
mavenCentral: [
|
mavenSnapshots: [
|
||||||
|
regex: [
|
||||||
|
],
|
||||||
|
group: [
|
||||||
|
'org.matrix.rustcomponents'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
mavenCentral : [
|
||||||
regex: [
|
regex: [
|
||||||
],
|
],
|
||||||
group: [
|
group: [
|
||||||
@ -187,7 +194,7 @@ ext.groups = [
|
|||||||
'xml-apis',
|
'xml-apis',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
jcenter : [
|
jcenter : [
|
||||||
regex: [
|
regex: [
|
||||||
],
|
],
|
||||||
group: [
|
group: [
|
||||||
|
@ -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() {
|
static def gitRevision() {
|
||||||
def cmd = "git rev-parse --short=8 HEAD"
|
def cmd = "git rev-parse --short=8 HEAD"
|
||||||
return cmd.execute().text.trim()
|
return cmd.execute().text.trim()
|
||||||
@ -115,10 +101,15 @@ static def gitRevisionDate() {
|
|||||||
return cmd.execute().text.trim()
|
return cmd.execute().text.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations.all {
|
||||||
|
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation libs.jetbrains.coroutinesCore
|
implementation libs.jetbrains.coroutinesCore
|
||||||
implementation libs.jetbrains.coroutinesAndroid
|
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 'net.java.dev.jna:jna:5.10.0@aar'
|
||||||
|
|
||||||
implementation libs.androidx.appCompat
|
implementation libs.androidx.appCompat
|
||||||
|
@ -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"
|
|
@ -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
|
|
@ -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/
|
|
@ -1,3 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
uniffi_build::generate_scaffolding("./src/olm.udl").unwrap();
|
|
||||||
}
|
|
@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
@ -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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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),
|
|
||||||
}
|
|
@ -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"));
|
|
@ -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
@ -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);
|
|
||||||
};
|
|
@ -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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)?,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -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()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user