mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-18 13:40:55 -04:00
Upgrade Ruma
This commit is contained in:
@@ -29,4 +29,8 @@ thiserror = "1.0.25"
|
||||
|
||||
[dependencies.ruma-identifiers]
|
||||
git = "https://github.com/ruma/ruma/"
|
||||
rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d"
|
||||
rev = "37095f88553b311e7a70adaaabe39976fb8ff71c"
|
||||
|
||||
[dependencies.ruma-serde]
|
||||
git = "https://github.com/ruma/ruma/"
|
||||
rev = "37095f88553b311e7a70adaaabe39976fb8ff71c"
|
||||
|
||||
@@ -22,6 +22,7 @@ use byteorder::{BigEndian, ReadBytesExt};
|
||||
use image::{DynamicImage, GenericImage, GenericImageView, ImageBuffer, Luma};
|
||||
use qrcode::QrCode;
|
||||
use ruma_identifiers::EventId;
|
||||
use ruma_serde::Base64;
|
||||
|
||||
#[cfg(feature = "decode_image")]
|
||||
use crate::utils::decode_qr;
|
||||
@@ -312,7 +313,7 @@ impl QrVerificationData {
|
||||
let first_key = base_64_encode(&first_key);
|
||||
let second_key = base_64_encode(&second_key);
|
||||
let flow_id = String::from_utf8(flow_id)?;
|
||||
let shared_secret = base_64_encode(&shared_secret);
|
||||
let shared_secret = Base64::new(shared_secret);
|
||||
|
||||
match mode {
|
||||
VerificationData::QR_MODE => {
|
||||
@@ -360,7 +361,7 @@ impl QrVerificationData {
|
||||
}
|
||||
|
||||
/// Get the secret of this `QrVerificationData`.
|
||||
pub fn secret(&self) -> &str {
|
||||
pub fn secret(&self) -> &Base64 {
|
||||
match self {
|
||||
QrVerificationData::Verification(v) => &v.shared_secret,
|
||||
QrVerificationData::SelfVerification(v) => &v.shared_secret,
|
||||
@@ -378,7 +379,7 @@ pub struct VerificationData {
|
||||
event_id: Box<EventId>,
|
||||
first_master_key: String,
|
||||
second_master_key: String,
|
||||
shared_secret: String,
|
||||
shared_secret: Base64,
|
||||
}
|
||||
|
||||
impl VerificationData {
|
||||
@@ -401,7 +402,7 @@ impl VerificationData {
|
||||
event_id: Box<EventId>,
|
||||
first_key: String,
|
||||
second_key: String,
|
||||
shared_secret: String,
|
||||
shared_secret: Base64,
|
||||
) -> Self {
|
||||
Self { event_id, first_master_key: first_key, second_master_key: second_key, shared_secret }
|
||||
}
|
||||
@@ -477,7 +478,7 @@ pub struct SelfVerificationData {
|
||||
transaction_id: String,
|
||||
master_key: String,
|
||||
device_key: String,
|
||||
shared_secret: String,
|
||||
shared_secret: Base64,
|
||||
}
|
||||
|
||||
impl SelfVerificationData {
|
||||
@@ -504,7 +505,7 @@ impl SelfVerificationData {
|
||||
transaction_id: String,
|
||||
master_key: String,
|
||||
device_key: String,
|
||||
shared_secret: String,
|
||||
shared_secret: Base64,
|
||||
) -> Self {
|
||||
Self { transaction_id, master_key, device_key, shared_secret }
|
||||
}
|
||||
@@ -580,7 +581,7 @@ pub struct SelfVerificationNoMasterKey {
|
||||
transaction_id: String,
|
||||
device_key: String,
|
||||
master_key: String,
|
||||
shared_secret: String,
|
||||
shared_secret: Base64,
|
||||
}
|
||||
|
||||
impl SelfVerificationNoMasterKey {
|
||||
@@ -607,7 +608,7 @@ impl SelfVerificationNoMasterKey {
|
||||
transaction_id: String,
|
||||
device_key: String,
|
||||
master_key: String,
|
||||
shared_secret: String,
|
||||
shared_secret: Base64,
|
||||
) -> Self {
|
||||
Self { transaction_id, device_key, master_key, shared_secret }
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use base64::{decode_config, encode_config, STANDARD_NO_PAD};
|
||||
#[cfg(feature = "decode_image")]
|
||||
use image::{GenericImage, GenericImageView, Luma};
|
||||
use qrcode::{bits::Bits, EcLevel, QrCode, Version};
|
||||
use ruma_serde::Base64;
|
||||
|
||||
#[cfg(feature = "decode_image")]
|
||||
use crate::error::DecodingError;
|
||||
@@ -41,14 +42,13 @@ pub(crate) fn to_bytes(
|
||||
flow_id: &str,
|
||||
first_key: &str,
|
||||
second_key: &str,
|
||||
shared_secret: &str,
|
||||
shared_secret: &Base64,
|
||||
) -> Result<Vec<u8>, EncodingError> {
|
||||
let flow_id_len: u16 = flow_id.len().try_into()?;
|
||||
let flow_id_len = flow_id_len.to_be_bytes();
|
||||
|
||||
let first_key = base64_decode(first_key)?;
|
||||
let second_key = base64_decode(second_key)?;
|
||||
let shared_secret = base64_decode(shared_secret)?;
|
||||
|
||||
let data = [
|
||||
HEADER,
|
||||
@@ -58,7 +58,7 @@ pub(crate) fn to_bytes(
|
||||
flow_id.as_bytes(),
|
||||
&first_key,
|
||||
&second_key,
|
||||
&shared_secret,
|
||||
shared_secret.as_bytes(),
|
||||
]
|
||||
.concat();
|
||||
|
||||
@@ -70,7 +70,7 @@ pub(crate) fn to_qr_code(
|
||||
flow_id: &str,
|
||||
first_key: &str,
|
||||
second_key: &str,
|
||||
shared_secret: &str,
|
||||
shared_secret: &Base64,
|
||||
) -> Result<QrCode, EncodingError> {
|
||||
let data = to_bytes(mode, flow_id, first_key, second_key, shared_secret)?;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ warp = { version = "0.3.1", optional = true, default-features = false }
|
||||
|
||||
[dependencies.ruma]
|
||||
git = "https://github.com/ruma/ruma/"
|
||||
rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d"
|
||||
rev = "37095f88553b311e7a70adaaabe39976fb8ff71c"
|
||||
features = ["client-api-c", "appservice-api-s", "unstable-pre-spec"]
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -50,7 +50,7 @@ zeroize = { version = "1.3.0", features = ["zeroize_derive"] }
|
||||
|
||||
[dependencies.ruma]
|
||||
git = "https://github.com/ruma/ruma/"
|
||||
rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d"
|
||||
rev = "37095f88553b311e7a70adaaabe39976fb8ff71c"
|
||||
features = ["client-api-c", "unstable-pre-spec"]
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.tokio]
|
||||
|
||||
@@ -24,6 +24,8 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
use matrix_sdk_common::locks::Mutex;
|
||||
use matrix_sdk_common::{
|
||||
deserialized_responses::{
|
||||
AmbiguityChanges, JoinedRoom, LeftRoom, MemberEvent, MembersResponse, Rooms,
|
||||
@@ -33,8 +35,6 @@ use matrix_sdk_common::{
|
||||
locks::RwLock,
|
||||
};
|
||||
#[cfg(feature = "encryption")]
|
||||
use matrix_sdk_common::{locks::Mutex, uuid::Uuid};
|
||||
#[cfg(feature = "encryption")]
|
||||
use matrix_sdk_crypto::{
|
||||
store::{CryptoStore, CryptoStoreError},
|
||||
Device, EncryptionSettings, IncomingResponse, MegolmError, OlmError, OlmMachine,
|
||||
@@ -47,7 +47,7 @@ use ruma::{
|
||||
room::{encrypted::RoomEncryptedEventContent, history_visibility::HistoryVisibility},
|
||||
AnySyncMessageEvent, MessageEventContent,
|
||||
},
|
||||
DeviceId,
|
||||
DeviceId, TransactionId,
|
||||
};
|
||||
use ruma::{
|
||||
api::client::r0::{self as api, push::get_notifications::Notification},
|
||||
@@ -1038,7 +1038,7 @@ impl BaseClient {
|
||||
#[cfg(feature = "encryption")]
|
||||
pub async fn mark_request_as_sent<'a>(
|
||||
&self,
|
||||
request_id: &Uuid,
|
||||
request_id: &TransactionId,
|
||||
response: impl Into<IncomingResponse<'a>>,
|
||||
) -> Result<()> {
|
||||
let olm = self.olm.lock().await;
|
||||
@@ -1056,7 +1056,7 @@ impl BaseClient {
|
||||
pub async fn get_missing_sessions(
|
||||
&self,
|
||||
users: impl Iterator<Item = &UserId>,
|
||||
) -> Result<Option<(Uuid, KeysClaimRequest)>> {
|
||||
) -> Result<Option<(Box<TransactionId>, KeysClaimRequest)>> {
|
||||
let olm = self.olm.lock().await;
|
||||
|
||||
match &*olm {
|
||||
|
||||
@@ -17,15 +17,9 @@ serde = "1.0.126"
|
||||
|
||||
[dependencies.ruma]
|
||||
git = "https://github.com/ruma/ruma/"
|
||||
rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d"
|
||||
rev = "37095f88553b311e7a70adaaabe39976fb8ff71c"
|
||||
features = ["client-api-c"]
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
uuid = { version = "0.8.2", default-features = false, features = [
|
||||
"v4",
|
||||
"serde",
|
||||
] }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.tokio]
|
||||
version = "1.7.1"
|
||||
default-features = false
|
||||
@@ -43,8 +37,3 @@ features = ["now"]
|
||||
async-lock = "2.4.0"
|
||||
futures-util = { version = "0.3.15", default-features = false, features = ["channel"] }
|
||||
wasm-bindgen-futures = "0.4.24"
|
||||
uuid = { version = "0.8.2", default-features = false, features = [
|
||||
"v4",
|
||||
"wasm-bindgen",
|
||||
"serde",
|
||||
] }
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
pub use async_trait::async_trait;
|
||||
pub use instant;
|
||||
pub use uuid;
|
||||
|
||||
pub mod deserialized_responses;
|
||||
pub mod executor;
|
||||
|
||||
@@ -48,7 +48,7 @@ zeroize = { version = "1.3.0", features = ["zeroize_derive"] }
|
||||
|
||||
[dependencies.ruma]
|
||||
git = "https://github.com/ruma/ruma/"
|
||||
rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d"
|
||||
rev = "37095f88553b311e7a70adaaabe39976fb8ff71c"
|
||||
features = ["client-api-c", "unstable-pre-spec"]
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::{ops::Deref, sync::Arc};
|
||||
use std::ops::Deref;
|
||||
|
||||
use criterion::*;
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use matrix_sdk_crypto::{EncryptionSettings, OlmMachine};
|
||||
use matrix_sdk_test::response_from_file;
|
||||
use ruma::{
|
||||
@@ -12,7 +11,7 @@ use ruma::{
|
||||
},
|
||||
IncomingResponse,
|
||||
},
|
||||
device_id, room_id, user_id, DeviceId, UserId,
|
||||
device_id, room_id, user_id, DeviceId, TransactionId, UserId,
|
||||
};
|
||||
use serde_json::Value;
|
||||
use tokio::runtime::Builder;
|
||||
@@ -51,7 +50,7 @@ pub fn keys_query(c: &mut Criterion) {
|
||||
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
|
||||
let machine = OlmMachine::new(alice_id(), alice_device_id());
|
||||
let response = keys_query_response();
|
||||
let uuid = Uuid::new_v4();
|
||||
let txn_id = TransactionId::new();
|
||||
|
||||
let count = response.device_keys.values().fold(0, |acc, d| acc + d.len())
|
||||
+ response.master_keys.len()
|
||||
@@ -65,7 +64,7 @@ pub fn keys_query(c: &mut Criterion) {
|
||||
|
||||
group.bench_with_input(BenchmarkId::new("memory store", &name), &response, |b, response| {
|
||||
b.to_async(&runtime)
|
||||
.iter(|| async { machine.mark_request_as_sent(&uuid, response).await.unwrap() })
|
||||
.iter(|| async { machine.mark_request_as_sent(&txn_id, response).await.unwrap() })
|
||||
});
|
||||
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
@@ -80,17 +79,17 @@ pub fn keys_query(c: &mut Criterion) {
|
||||
|
||||
group.bench_with_input(BenchmarkId::new("sled store", &name), &response, |b, response| {
|
||||
b.to_async(&runtime)
|
||||
.iter(|| async { machine.mark_request_as_sent(&uuid, response).await.unwrap() })
|
||||
.iter(|| async { machine.mark_request_as_sent(&txn_id, response).await.unwrap() })
|
||||
});
|
||||
|
||||
group.finish()
|
||||
}
|
||||
|
||||
pub fn keys_claiming(c: &mut Criterion) {
|
||||
let runtime = Arc::new(Builder::new_multi_thread().build().expect("Can't create runtime"));
|
||||
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
|
||||
|
||||
let keys_query_response = keys_query_response();
|
||||
let uuid = Uuid::new_v4();
|
||||
let txn_id = TransactionId::new();
|
||||
|
||||
let response = keys_claim_response();
|
||||
|
||||
@@ -106,12 +105,12 @@ pub fn keys_claiming(c: &mut Criterion) {
|
||||
|| {
|
||||
let machine = OlmMachine::new(alice_id(), alice_device_id());
|
||||
runtime
|
||||
.block_on(machine.mark_request_as_sent(&uuid, &keys_query_response))
|
||||
.block_on(machine.mark_request_as_sent(&txn_id, &keys_query_response))
|
||||
.unwrap();
|
||||
(machine, runtime.clone())
|
||||
(machine, &runtime, &txn_id)
|
||||
},
|
||||
move |(machine, runtime)| {
|
||||
runtime.block_on(machine.mark_request_as_sent(&uuid, response)).unwrap()
|
||||
move |(machine, runtime, txn_id)| {
|
||||
runtime.block_on(machine.mark_request_as_sent(txn_id, response)).unwrap()
|
||||
},
|
||||
BatchSize::SmallInput,
|
||||
)
|
||||
@@ -130,12 +129,12 @@ pub fn keys_claiming(c: &mut Criterion) {
|
||||
))
|
||||
.unwrap();
|
||||
runtime
|
||||
.block_on(machine.mark_request_as_sent(&uuid, &keys_query_response))
|
||||
.block_on(machine.mark_request_as_sent(&txn_id, &keys_query_response))
|
||||
.unwrap();
|
||||
(machine, runtime.clone())
|
||||
(machine, &runtime, &txn_id)
|
||||
},
|
||||
move |(machine, runtime)| {
|
||||
runtime.block_on(machine.mark_request_as_sent(&uuid, response)).unwrap()
|
||||
move |(machine, runtime, txn_id)| {
|
||||
runtime.block_on(machine.mark_request_as_sent(txn_id, response)).unwrap()
|
||||
},
|
||||
BatchSize::SmallInput,
|
||||
)
|
||||
@@ -148,7 +147,7 @@ pub fn room_key_sharing(c: &mut Criterion) {
|
||||
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
|
||||
|
||||
let keys_query_response = keys_query_response();
|
||||
let uuid = Uuid::new_v4();
|
||||
let txn_id = TransactionId::new();
|
||||
let response = keys_claim_response();
|
||||
let room_id = room_id!("!test:localhost");
|
||||
|
||||
@@ -158,8 +157,8 @@ pub fn room_key_sharing(c: &mut Criterion) {
|
||||
let count = response.one_time_keys.values().fold(0, |acc, d| acc + d.len());
|
||||
|
||||
let machine = OlmMachine::new(alice_id(), alice_device_id());
|
||||
runtime.block_on(machine.mark_request_as_sent(&uuid, &keys_query_response)).unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&uuid, &response)).unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&txn_id, &keys_query_response)).unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap();
|
||||
|
||||
let mut group = c.benchmark_group("Room key sharing");
|
||||
group.throughput(Throughput::Elements(count as u64));
|
||||
@@ -195,8 +194,8 @@ pub fn room_key_sharing(c: &mut Criterion) {
|
||||
None,
|
||||
))
|
||||
.unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&uuid, &keys_query_response)).unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&uuid, &response)).unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&txn_id, &keys_query_response)).unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap();
|
||||
|
||||
group.bench_function(BenchmarkId::new("sled store", &name), |b| {
|
||||
b.to_async(&runtime).iter(|| async {
|
||||
@@ -227,7 +226,7 @@ pub fn devices_missing_sessions_collecting(c: &mut Criterion) {
|
||||
|
||||
let machine = OlmMachine::new(alice_id(), alice_device_id());
|
||||
let response = huge_keys_query_response();
|
||||
let uuid = Uuid::new_v4();
|
||||
let txn_id = TransactionId::new();
|
||||
let users: Vec<Box<UserId>> = response.device_keys.keys().cloned().collect();
|
||||
|
||||
let count = response.device_keys.values().fold(0, |acc, d| acc + d.len());
|
||||
@@ -237,7 +236,7 @@ pub fn devices_missing_sessions_collecting(c: &mut Criterion) {
|
||||
|
||||
let name = format!("{} devices", count);
|
||||
|
||||
runtime.block_on(machine.mark_request_as_sent(&uuid, &response)).unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap();
|
||||
|
||||
group.bench_function(BenchmarkId::new("memory store", &name), |b| {
|
||||
b.to_async(&runtime).iter_with_large_drop(|| async {
|
||||
@@ -255,7 +254,7 @@ pub fn devices_missing_sessions_collecting(c: &mut Criterion) {
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
runtime.block_on(machine.mark_request_as_sent(&uuid, &response)).unwrap();
|
||||
runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap();
|
||||
|
||||
group.bench_function(BenchmarkId::new("sled store", &name), |b| {
|
||||
b.to_async(&runtime).iter(|| async {
|
||||
|
||||
@@ -28,10 +28,10 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use matrix_sdk_common::{locks::RwLock, uuid::Uuid};
|
||||
use matrix_sdk_common::locks::RwLock;
|
||||
use ruma::{
|
||||
api::client::r0::backup::RoomKeyBackup, serde::Raw, DeviceKeyAlgorithm, DeviceKeyId, RoomId,
|
||||
UserId,
|
||||
TransactionId, UserId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
@@ -64,7 +64,7 @@ pub struct BackupMachine {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct PendingBackup {
|
||||
request_id: Uuid,
|
||||
request_id: &TransactionId,
|
||||
request: KeysBackupRequest,
|
||||
sessions: BTreeMap<Box<RoomId>, BTreeMap<String, BTreeSet<String>>>,
|
||||
}
|
||||
@@ -259,7 +259,7 @@ impl BackupMachine {
|
||||
|
||||
pub(crate) async fn mark_request_as_sent(
|
||||
&self,
|
||||
request_id: Uuid,
|
||||
request_id: &TransactionId,
|
||||
) -> Result<(), CryptoStoreError> {
|
||||
let mut request = self.pending_backup.write().await;
|
||||
|
||||
@@ -325,7 +325,7 @@ impl BackupMachine {
|
||||
);
|
||||
|
||||
let request = PendingBackup {
|
||||
request_id: Uuid::new_v4(),
|
||||
request_id: TransactionId::new(),
|
||||
request: KeysBackupRequest { version, rooms: backup },
|
||||
sessions: session_record,
|
||||
};
|
||||
|
||||
@@ -23,14 +23,15 @@ use aes::{
|
||||
};
|
||||
use base64::DecodeError;
|
||||
use getrandom::getrandom;
|
||||
use ruma::events::room::{EncryptedFile, JsonWebKey, JsonWebKeyInit};
|
||||
use ruma::{
|
||||
events::room::{EncryptedFile, JsonWebKey, JsonWebKeyInit},
|
||||
serde::Base64,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use thiserror::Error;
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
use crate::utilities::{decode, decode_url_safe, encode, encode_url_safe};
|
||||
|
||||
const IV_SIZE: usize = 16;
|
||||
const KEY_SIZE: usize = 32;
|
||||
const VERSION: &str = "v2";
|
||||
@@ -131,9 +132,10 @@ impl<'a, R: Read + 'a> AttachmentDecryptor<'a, R> {
|
||||
return Err(DecryptorError::UnknownVersion);
|
||||
}
|
||||
|
||||
let hash = decode(info.hashes.get("sha256").ok_or(DecryptorError::MissingHash)?)?;
|
||||
let key = Zeroizing::from(decode_url_safe(info.web_key.k)?);
|
||||
let iv = decode(info.iv)?;
|
||||
let hash =
|
||||
info.hashes.get("sha256").ok_or(DecryptorError::MissingHash)?.as_bytes().to_owned();
|
||||
let key = Zeroizing::from(info.web_key.k.into_inner());
|
||||
let iv = info.iv.into_inner();
|
||||
let iv = GenericArray::from_exact_iter(iv).ok_or(DecryptorError::KeyNonceLength)?;
|
||||
|
||||
let sha = Sha256::default();
|
||||
@@ -149,8 +151,8 @@ pub struct AttachmentEncryptor<'a, R: Read + 'a> {
|
||||
finished: bool,
|
||||
inner: &'a mut R,
|
||||
web_key: JsonWebKey,
|
||||
iv: String,
|
||||
hashes: BTreeMap<String, String>,
|
||||
iv: Base64,
|
||||
hashes: BTreeMap<String, Base64>,
|
||||
aes: Aes256Ctr,
|
||||
sha: Sha256,
|
||||
}
|
||||
@@ -170,7 +172,9 @@ impl<'a, R: Read + 'a> Read for AttachmentEncryptor<'a, R> {
|
||||
|
||||
if read_bytes == 0 {
|
||||
let hash = self.sha.finalize_reset();
|
||||
self.hashes.entry("sha256".to_owned()).or_insert_with(|| encode(hash));
|
||||
self.hashes
|
||||
.entry("sha256".to_owned())
|
||||
.or_insert_with(|| Base64::new(hash.as_slice().to_owned()));
|
||||
Ok(0)
|
||||
} else {
|
||||
self.aes.apply_keystream(&mut buf[0..read_bytes]);
|
||||
@@ -223,10 +227,10 @@ impl<'a, R: Read + 'a> AttachmentEncryptor<'a, R> {
|
||||
kty: "oct".to_owned(),
|
||||
key_ops: vec!["encrypt".to_owned(), "decrypt".to_owned()],
|
||||
alg: "A256CTR".to_owned(),
|
||||
k: encode_url_safe(&*key),
|
||||
k: Base64::new((*key).to_vec()),
|
||||
ext: true,
|
||||
});
|
||||
let encoded_iv = encode(&*iv);
|
||||
let encoded_iv = Base64::new((*iv).to_vec());
|
||||
let iv = GenericArray::from_slice(&*iv);
|
||||
let key = GenericArray::from_slice(&*key);
|
||||
|
||||
@@ -247,7 +251,9 @@ impl<'a, R: Read + 'a> AttachmentEncryptor<'a, R> {
|
||||
/// Consume the encryptor and get the encryption key.
|
||||
pub fn finish(mut self) -> MediaEncryptionInfo {
|
||||
let hash = self.sha.finalize();
|
||||
self.hashes.entry("sha256".to_owned()).or_insert_with(|| encode(hash));
|
||||
self.hashes
|
||||
.entry("sha256".to_owned())
|
||||
.or_insert_with(|| Base64::new(hash.as_slice().to_owned()));
|
||||
|
||||
MediaEncryptionInfo {
|
||||
version: VERSION.to_string(),
|
||||
@@ -268,9 +274,9 @@ pub struct MediaEncryptionInfo {
|
||||
/// The web key that was used to encrypt the file.
|
||||
pub web_key: JsonWebKey,
|
||||
/// The initialization vector that was used to encrypt the file.
|
||||
pub iv: String,
|
||||
pub iv: Base64,
|
||||
/// The hashes that can be used to check the validity of the file.
|
||||
pub hashes: BTreeMap<String, String>,
|
||||
pub hashes: BTreeMap<String, Base64>,
|
||||
}
|
||||
|
||||
impl From<EncryptedFile> for MediaEncryptionInfo {
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
use std::{collections::BTreeMap, sync::Arc};
|
||||
|
||||
use dashmap::{mapref::entry::Entry, DashMap, DashSet};
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use ruma::{
|
||||
api::client::r0::keys::claim_keys::Request as KeysClaimRequest,
|
||||
events::{
|
||||
@@ -40,7 +39,7 @@ use ruma::{
|
||||
},
|
||||
AnyToDeviceEvent, AnyToDeviceEventContent,
|
||||
},
|
||||
DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, RoomId, UserId,
|
||||
DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use tracing::{debug, info, trace, warn};
|
||||
|
||||
@@ -60,7 +59,7 @@ pub(crate) struct GossipMachine {
|
||||
device_id: Arc<DeviceId>,
|
||||
store: Store,
|
||||
outbound_group_sessions: GroupSessionCache,
|
||||
outgoing_requests: Arc<DashMap<Uuid, OutgoingRequest>>,
|
||||
outgoing_requests: Arc<DashMap<Box<TransactionId>, OutgoingRequest>>,
|
||||
incoming_key_requests: Arc<DashMap<RequestInfo, RequestEvent>>,
|
||||
wait_queue: WaitQueue,
|
||||
users_for_key_claim: Arc<DashMap<Box<UserId>, DashSet<Box<DeviceId>>>>,
|
||||
@@ -133,7 +132,7 @@ impl GossipMachine {
|
||||
if !users_for_key_claim.is_empty() {
|
||||
let key_claim_request = KeysClaimRequest::new(users_for_key_claim);
|
||||
key_requests.push(OutgoingRequest {
|
||||
request_id: Uuid::new_v4(),
|
||||
request_id: TransactionId::new(),
|
||||
request: Arc::new(key_claim_request.into()),
|
||||
});
|
||||
}
|
||||
@@ -439,9 +438,11 @@ impl GossipMachine {
|
||||
AnyToDeviceEventContent::RoomEncrypted(content),
|
||||
);
|
||||
|
||||
let request =
|
||||
OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) };
|
||||
self.outgoing_requests.insert(request.request_id, request);
|
||||
let request = OutgoingRequest {
|
||||
request_id: request.txn_id.clone(),
|
||||
request: Arc::new(request.into()),
|
||||
};
|
||||
self.outgoing_requests.insert(request.request_id.clone(), request);
|
||||
|
||||
Ok(used_session)
|
||||
}
|
||||
@@ -461,9 +462,11 @@ impl GossipMachine {
|
||||
AnyToDeviceEventContent::RoomEncrypted(content),
|
||||
);
|
||||
|
||||
let request =
|
||||
OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) };
|
||||
self.outgoing_requests.insert(request.request_id, request);
|
||||
let request = OutgoingRequest {
|
||||
request_id: request.txn_id.clone(),
|
||||
request: Arc::new(request.into()),
|
||||
};
|
||||
self.outgoing_requests.insert(request.request_id.clone(), request);
|
||||
|
||||
Ok(used_session)
|
||||
}
|
||||
@@ -633,7 +636,7 @@ impl GossipMachine {
|
||||
) -> Result<OutgoingRequest, CryptoStoreError> {
|
||||
let request = GossipRequest {
|
||||
request_recipient: self.user_id().to_owned(),
|
||||
request_id: Uuid::new_v4(),
|
||||
request_id: TransactionId::new(),
|
||||
info: key_info,
|
||||
sent_out: false,
|
||||
};
|
||||
@@ -707,11 +710,14 @@ impl GossipMachine {
|
||||
|
||||
/// Delete the given outgoing key info.
|
||||
async fn delete_key_info(&self, info: &GossipRequest) -> Result<(), CryptoStoreError> {
|
||||
self.store.delete_outgoing_secret_requests(info.request_id).await
|
||||
self.store.delete_outgoing_secret_requests(&info.request_id).await
|
||||
}
|
||||
|
||||
/// Mark the outgoing request as sent.
|
||||
pub async fn mark_outgoing_request_as_sent(&self, id: Uuid) -> Result<(), CryptoStoreError> {
|
||||
pub async fn mark_outgoing_request_as_sent(
|
||||
&self,
|
||||
id: &TransactionId,
|
||||
) -> Result<(), CryptoStoreError> {
|
||||
let info = self.store.get_outgoing_secret_requests(id).await?;
|
||||
|
||||
if let Some(mut info) = info {
|
||||
@@ -725,7 +731,7 @@ impl GossipMachine {
|
||||
self.save_outgoing_key_info(info).await?;
|
||||
}
|
||||
|
||||
self.outgoing_requests.remove(&id);
|
||||
self.outgoing_requests.remove(id);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -747,7 +753,7 @@ impl GossipMachine {
|
||||
self.delete_key_info(&key_info).await?;
|
||||
|
||||
let request = key_info.to_cancellation(self.device_id());
|
||||
self.outgoing_requests.insert(request.request_id, request);
|
||||
self.outgoing_requests.insert(request.request_id.clone(), request);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -763,12 +769,7 @@ impl GossipMachine {
|
||||
"Received a m.secret.send event"
|
||||
);
|
||||
|
||||
let request_id = if let Ok(r) = Uuid::parse_str(&event.content.request_id) {
|
||||
r
|
||||
} else {
|
||||
warn!("Received a m.secret.send event but the request ID is invalid");
|
||||
return Ok(None);
|
||||
};
|
||||
let request_id = <&TransactionId>::from(event.content.request_id.as_str());
|
||||
|
||||
let secret = std::mem::take(&mut event.content.secret);
|
||||
|
||||
@@ -1066,7 +1067,7 @@ mod test {
|
||||
|
||||
assert!(cancel.is_none());
|
||||
|
||||
machine.mark_outgoing_request_as_sent(request.request_id).await.unwrap();
|
||||
machine.mark_outgoing_request_as_sent(&request.request_id).await.unwrap();
|
||||
|
||||
let (cancel, _) = machine
|
||||
.request_key(session.room_id(), &session.sender_key, session.session_id())
|
||||
@@ -1116,7 +1117,7 @@ mod test {
|
||||
|
||||
let request = requests.get(0).unwrap();
|
||||
|
||||
machine.mark_outgoing_request_as_sent(request.request_id).await.unwrap();
|
||||
machine.mark_outgoing_request_as_sent(&request.request_id).await.unwrap();
|
||||
assert!(machine.outgoing_to_device_requests().await.unwrap().is_empty());
|
||||
}
|
||||
|
||||
@@ -1145,7 +1146,7 @@ mod test {
|
||||
|
||||
let requests = machine.outgoing_to_device_requests().await.unwrap();
|
||||
let request = requests.get(0).unwrap();
|
||||
let id = request.request_id;
|
||||
let id = &request.request_id;
|
||||
|
||||
machine.mark_outgoing_request_as_sent(id).await.unwrap();
|
||||
|
||||
@@ -1178,9 +1179,9 @@ mod test {
|
||||
|
||||
// Get the cancel request.
|
||||
let request = machine.outgoing_requests.iter().next().unwrap();
|
||||
let id = request.request_id;
|
||||
let id = request.request_id.clone();
|
||||
drop(request);
|
||||
machine.mark_outgoing_request_as_sent(id).await.unwrap();
|
||||
machine.mark_outgoing_request_as_sent(&id).await.unwrap();
|
||||
|
||||
machine
|
||||
.create_outgoing_key_request(
|
||||
@@ -1194,7 +1195,7 @@ mod test {
|
||||
let requests = machine.outgoing_to_device_requests().await.unwrap();
|
||||
let request = &requests[0];
|
||||
|
||||
machine.mark_outgoing_request_as_sent(request.request_id).await.unwrap();
|
||||
machine.mark_outgoing_request_as_sent(&request.request_id).await.unwrap();
|
||||
|
||||
let export = session.export_at_index(15).await;
|
||||
|
||||
@@ -1391,7 +1392,7 @@ mod test {
|
||||
// Get the request and convert it into a event.
|
||||
let requests = alice_machine.outgoing_to_device_requests().await.unwrap();
|
||||
let request = &requests[0];
|
||||
let id = request.request_id;
|
||||
let id = &request.request_id;
|
||||
let content = request
|
||||
.request
|
||||
.to_device()
|
||||
@@ -1420,7 +1421,7 @@ mod test {
|
||||
let requests = bob_machine.outgoing_to_device_requests().await.unwrap();
|
||||
let request = &requests[0];
|
||||
|
||||
let id = request.request_id;
|
||||
let id = &request.request_id;
|
||||
let content = request
|
||||
.request
|
||||
.to_device()
|
||||
@@ -1494,7 +1495,7 @@ mod test {
|
||||
content: ToDeviceSecretRequestEventContent::new(
|
||||
RequestAction::Request(SecretName::CrossSigningMasterKey),
|
||||
bob_account.device_id().to_owned(),
|
||||
"request_id".to_owned(),
|
||||
"request_id".into(),
|
||||
),
|
||||
};
|
||||
|
||||
@@ -1523,7 +1524,7 @@ mod test {
|
||||
content: ToDeviceSecretRequestEventContent::new(
|
||||
RequestAction::Request(SecretName::CrossSigningMasterKey),
|
||||
second_account.device_id().into(),
|
||||
"request_id".to_owned(),
|
||||
"request_id".into(),
|
||||
),
|
||||
};
|
||||
|
||||
@@ -1595,7 +1596,7 @@ mod test {
|
||||
// Get the request and convert it into a event.
|
||||
let requests = alice_machine.outgoing_to_device_requests().await.unwrap();
|
||||
let request = &requests[0];
|
||||
let id = request.request_id;
|
||||
let id = &request.request_id;
|
||||
let content = request
|
||||
.request
|
||||
.to_device()
|
||||
@@ -1644,7 +1645,7 @@ mod test {
|
||||
|
||||
let request = &requests[0];
|
||||
|
||||
let id = request.request_id;
|
||||
let id = &request.request_id;
|
||||
let content = request
|
||||
.request
|
||||
.to_device()
|
||||
|
||||
@@ -18,7 +18,6 @@ use std::sync::Arc;
|
||||
|
||||
use dashmap::{DashMap, DashSet};
|
||||
pub(crate) use machine::GossipMachine;
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use ruma::{
|
||||
events::{
|
||||
room_key_request::{
|
||||
@@ -32,7 +31,7 @@ use ruma::{
|
||||
AnyToDeviceEventContent,
|
||||
},
|
||||
to_device::DeviceIdOrAllDevices,
|
||||
DeviceId, UserId,
|
||||
DeviceId, TransactionId, UserId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
@@ -69,7 +68,7 @@ pub struct GossipRequest {
|
||||
/// The user we requested the secret from
|
||||
pub request_recipient: Box<UserId>,
|
||||
/// The unique id of the secret request.
|
||||
pub request_id: Uuid,
|
||||
pub request_id: Box<TransactionId>,
|
||||
/// The info of the requested secret.
|
||||
pub info: SecretInfo,
|
||||
/// Has the request been sent out.
|
||||
@@ -102,7 +101,7 @@ impl GossipRequest {
|
||||
pub(crate) fn from_secret_name(own_user_id: Box<UserId>, secret_name: SecretName) -> Self {
|
||||
Self {
|
||||
request_recipient: own_user_id,
|
||||
request_id: Uuid::new_v4(),
|
||||
request_id: TransactionId::new(),
|
||||
info: secret_name.into(),
|
||||
sent_out: false,
|
||||
}
|
||||
@@ -122,14 +121,14 @@ impl GossipRequest {
|
||||
Action::Request,
|
||||
Some(r.clone()),
|
||||
own_device_id.to_owned(),
|
||||
self.request_id.to_string(),
|
||||
self.request_id.clone(),
|
||||
))
|
||||
}
|
||||
SecretInfo::SecretRequest(s) => {
|
||||
AnyToDeviceEventContent::SecretRequest(SecretRequestEventContent::new(
|
||||
RequestAction::Request(s.clone()),
|
||||
own_device_id.to_owned(),
|
||||
self.request_id.to_string(),
|
||||
self.request_id.clone(),
|
||||
))
|
||||
}
|
||||
};
|
||||
@@ -138,10 +137,10 @@ impl GossipRequest {
|
||||
&self.request_recipient,
|
||||
DeviceIdOrAllDevices::AllDevices,
|
||||
content,
|
||||
self.request_id,
|
||||
self.request_id.clone(),
|
||||
);
|
||||
|
||||
OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) }
|
||||
OutgoingRequest { request_id: request.txn_id.clone(), request: Arc::new(request.into()) }
|
||||
}
|
||||
|
||||
fn to_cancellation(&self, own_device_id: &DeviceId) -> OutgoingRequest {
|
||||
@@ -151,14 +150,14 @@ impl GossipRequest {
|
||||
Action::CancelRequest,
|
||||
None,
|
||||
own_device_id.to_owned(),
|
||||
self.request_id.to_string(),
|
||||
self.request_id.clone(),
|
||||
))
|
||||
}
|
||||
SecretInfo::SecretRequest(_) => {
|
||||
AnyToDeviceEventContent::SecretRequest(SecretRequestEventContent::new(
|
||||
RequestAction::RequestCancellation,
|
||||
own_device_id.to_owned(),
|
||||
self.request_id.to_string(),
|
||||
self.request_id.clone(),
|
||||
))
|
||||
}
|
||||
};
|
||||
@@ -169,7 +168,7 @@ impl GossipRequest {
|
||||
content,
|
||||
);
|
||||
|
||||
OutgoingRequest { request_id: request.txn_id, request: Arc::new(request.into()) }
|
||||
OutgoingRequest { request_id: request.txn_id.clone(), request: Arc::new(request.into()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +232,7 @@ impl RequestEvent {
|
||||
}
|
||||
}
|
||||
|
||||
fn request_id(&self) -> &str {
|
||||
fn request_id(&self) -> &TransactionId {
|
||||
match self {
|
||||
RequestEvent::KeyShare(e) => &e.content.request_id,
|
||||
RequestEvent::Secret(e) => &e.content.request_id,
|
||||
@@ -245,11 +244,15 @@ impl RequestEvent {
|
||||
struct RequestInfo {
|
||||
sender: Box<UserId>,
|
||||
requesting_device_id: Box<DeviceId>,
|
||||
request_id: String,
|
||||
request_id: Box<TransactionId>,
|
||||
}
|
||||
|
||||
impl RequestInfo {
|
||||
fn new(sender: Box<UserId>, requesting_device_id: Box<DeviceId>, request_id: String) -> Self {
|
||||
fn new(
|
||||
sender: Box<UserId>,
|
||||
requesting_device_id: Box<DeviceId>,
|
||||
request_id: Box<TransactionId>,
|
||||
) -> Self {
|
||||
Self { sender, requesting_device_id, request_id }
|
||||
}
|
||||
}
|
||||
@@ -260,7 +263,7 @@ impl RequestInfo {
|
||||
struct WaitQueue {
|
||||
requests_waiting_for_session: Arc<DashMap<RequestInfo, RequestEvent>>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
requests_ids_waiting: Arc<DashMap<(Box<UserId>, Box<DeviceId>), DashSet<String>>>,
|
||||
requests_ids_waiting: Arc<DashMap<(Box<UserId>, Box<DeviceId>), DashSet<Box<TransactionId>>>>,
|
||||
}
|
||||
|
||||
impl WaitQueue {
|
||||
|
||||
@@ -24,7 +24,6 @@ use dashmap::DashMap;
|
||||
use matrix_sdk_common::{
|
||||
deserialized_responses::{AlgorithmInfo, EncryptionInfo, RoomEvent, VerificationState},
|
||||
locks::Mutex,
|
||||
uuid::Uuid,
|
||||
};
|
||||
use ruma::{
|
||||
api::client::r0::{
|
||||
@@ -47,7 +46,8 @@ use ruma::{
|
||||
AnyRoomEvent, AnyToDeviceEvent, MessageEventContent,
|
||||
},
|
||||
serde::Raw,
|
||||
DeviceId, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, RoomId, UInt, UserId,
|
||||
DeviceId, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, RoomId, TransactionId,
|
||||
UInt, UserId,
|
||||
};
|
||||
use serde_json::{value::to_raw_value, Value};
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
@@ -322,21 +322,17 @@ impl OlmMachine {
|
||||
pub async fn outgoing_requests(&self) -> StoreResult<Vec<OutgoingRequest>> {
|
||||
let mut requests = Vec::new();
|
||||
|
||||
if let Some(r) = self
|
||||
.keys_for_upload()
|
||||
.await
|
||||
.map(|r| OutgoingRequest { request_id: Uuid::new_v4(), request: Arc::new(r.into()) })
|
||||
{
|
||||
if let Some(r) = self.keys_for_upload().await.map(|r| OutgoingRequest {
|
||||
request_id: TransactionId::new(),
|
||||
request: Arc::new(r.into()),
|
||||
}) {
|
||||
self.account.save().await?;
|
||||
requests.push(r);
|
||||
}
|
||||
|
||||
for request in
|
||||
self.identity_manager.users_for_key_query().await.into_iter().map(|r| OutgoingRequest {
|
||||
request_id: Uuid::new_v4(),
|
||||
request: Arc::new(r.into()),
|
||||
})
|
||||
{
|
||||
for request in self.identity_manager.users_for_key_query().await.into_iter().map(|r| {
|
||||
OutgoingRequest { request_id: TransactionId::new(), request: Arc::new(r.into()) }
|
||||
}) {
|
||||
requests.push(request);
|
||||
}
|
||||
|
||||
@@ -357,7 +353,7 @@ impl OlmMachine {
|
||||
/// outgoing request was sent out.
|
||||
pub async fn mark_request_as_sent<'a>(
|
||||
&self,
|
||||
request_id: &Uuid,
|
||||
request_id: &TransactionId,
|
||||
response: impl Into<IncomingResponse<'a>>,
|
||||
) -> OlmResult<()> {
|
||||
match response.into() {
|
||||
@@ -522,7 +518,7 @@ impl OlmMachine {
|
||||
pub async fn get_missing_sessions(
|
||||
&self,
|
||||
users: impl Iterator<Item = &UserId>,
|
||||
) -> StoreResult<Option<(Uuid, KeysClaimRequest)>> {
|
||||
) -> StoreResult<Option<(Box<TransactionId>, KeysClaimRequest)>> {
|
||||
self.session_manager.get_missing_sessions(users).await
|
||||
}
|
||||
|
||||
@@ -834,9 +830,9 @@ impl OlmMachine {
|
||||
}
|
||||
|
||||
/// Mark an outgoing to-device requests as sent.
|
||||
async fn mark_to_device_request_as_sent(&self, request_id: &Uuid) -> StoreResult<()> {
|
||||
async fn mark_to_device_request_as_sent(&self, request_id: &TransactionId) -> StoreResult<()> {
|
||||
self.verification_machine.mark_request_as_sent(request_id);
|
||||
self.key_request_machine.mark_outgoing_request_as_sent(*request_id).await?;
|
||||
self.key_request_machine.mark_outgoing_request_as_sent(request_id).await?;
|
||||
self.group_session_manager.mark_request_as_sent(request_id).await?;
|
||||
self.session_manager.mark_outgoing_request_as_sent(request_id);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ use ruma::{
|
||||
},
|
||||
AnyToDeviceEvent, OlmV1Keys,
|
||||
},
|
||||
serde::{CanonicalJsonValue, Raw},
|
||||
serde::{Base64, CanonicalJsonValue, Raw},
|
||||
DeviceId, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, RoomId, UInt, UserId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -883,7 +883,10 @@ impl ReadOnlyAccount {
|
||||
let mut signatures = BTreeMap::new();
|
||||
signatures.insert((*self.user_id).to_owned(), signature_map);
|
||||
|
||||
let signed_key = SignedKey::new(key.to_owned(), signatures);
|
||||
let signed_key = SignedKey::new(
|
||||
Base64::parse(key).expect("Couldn't base64-decode one-time key"),
|
||||
signatures,
|
||||
);
|
||||
|
||||
one_time_key_map.insert(
|
||||
DeviceKeyId::from_parts(
|
||||
@@ -929,7 +932,7 @@ impl ReadOnlyAccount {
|
||||
.inner
|
||||
.lock()
|
||||
.await
|
||||
.create_outbound_session(their_identity_key, &their_one_time_key.key)?;
|
||||
.create_outbound_session(their_identity_key, &their_one_time_key.key.encode())?;
|
||||
|
||||
let now = Instant::now();
|
||||
let session_id = session.session_id();
|
||||
@@ -1173,7 +1176,7 @@ mod test {
|
||||
use std::{collections::BTreeSet, ops::Deref};
|
||||
|
||||
use matrix_sdk_test::async_test;
|
||||
use ruma::{device_id, identifiers::DeviceId, user_id, DeviceKeyId, UserId};
|
||||
use ruma::{device_id, user_id, DeviceId, DeviceKeyId, UserId};
|
||||
|
||||
use super::ReadOnlyAccount;
|
||||
use crate::error::OlmResult as Result;
|
||||
|
||||
@@ -24,7 +24,7 @@ use std::{
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use matrix_sdk_common::{instant::Instant, locks::Mutex, uuid::Uuid};
|
||||
use matrix_sdk_common::{instant::Instant, locks::Mutex};
|
||||
pub use olm_rs::{
|
||||
account::IdentityKeys,
|
||||
session::{OlmMessage, PreKeyMessage},
|
||||
@@ -45,7 +45,7 @@ use ruma::{
|
||||
room_key::ToDeviceRoomKeyEventContent,
|
||||
AnyToDeviceEventContent,
|
||||
},
|
||||
DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, RoomId, UserId,
|
||||
DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
@@ -130,7 +130,8 @@ pub struct OutboundGroupSession {
|
||||
settings: Arc<EncryptionSettings>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(crate) shared_with_set: Arc<DashMap<Box<UserId>, DashMap<Box<DeviceId>, ShareInfo>>>,
|
||||
to_share_with_set: Arc<DashMap<Uuid, (Arc<ToDeviceRequest>, ShareInfoSet)>>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
to_share_with_set: Arc<DashMap<Box<TransactionId>, (Arc<ToDeviceRequest>, ShareInfoSet)>>,
|
||||
}
|
||||
|
||||
/// A a map of userid/device it to a `ShareInfo`.
|
||||
@@ -191,7 +192,7 @@ impl OutboundGroupSession {
|
||||
|
||||
pub(crate) fn add_request(
|
||||
&self,
|
||||
request_id: Uuid,
|
||||
request_id: Box<TransactionId>,
|
||||
request: Arc<ToDeviceRequest>,
|
||||
share_infos: ShareInfoSet,
|
||||
) {
|
||||
@@ -212,7 +213,7 @@ impl OutboundGroupSession {
|
||||
///
|
||||
/// This removes the request from the queue and marks the set of
|
||||
/// users/devices that received the session.
|
||||
pub fn mark_request_as_sent(&self, request_id: &Uuid) {
|
||||
pub fn mark_request_as_sent(&self, request_id: &TransactionId) {
|
||||
if let Some((_, (_, r))) = self.to_share_with_set.remove(request_id) {
|
||||
let recipients: BTreeMap<&UserId, BTreeSet<&DeviceId>> =
|
||||
r.iter().map(|(u, d)| (&**u, d.keys().map(|d| d.as_ref()).collect())).collect();
|
||||
@@ -456,8 +457,8 @@ impl OutboundGroupSession {
|
||||
}
|
||||
|
||||
/// Get the list of request ids this session is waiting for to be sent out.
|
||||
pub(crate) fn pending_request_ids(&self) -> Vec<Uuid> {
|
||||
self.to_share_with_set.iter().map(|e| *e.key()).collect()
|
||||
pub(crate) fn pending_request_ids(&self) -> Vec<Box<TransactionId>> {
|
||||
self.to_share_with_set.iter().map(|e| e.key().clone()).collect()
|
||||
}
|
||||
|
||||
/// Restore a Session from a previously pickled string.
|
||||
@@ -541,7 +542,7 @@ impl OutboundGroupSession {
|
||||
requests: self
|
||||
.to_share_with_set
|
||||
.iter()
|
||||
.map(|r| (*r.key(), r.value().clone()))
|
||||
.map(|r| (r.key().clone(), r.value().clone()))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
@@ -592,7 +593,7 @@ pub struct PickledOutboundGroupSession {
|
||||
/// The set of users the session has been already shared with.
|
||||
pub shared_with_set: BTreeMap<Box<UserId>, BTreeMap<Box<DeviceId>, ShareInfo>>,
|
||||
/// Requests that need to be sent out to share the session.
|
||||
pub requests: BTreeMap<Uuid, (Arc<ToDeviceRequest>, ShareInfoSet)>,
|
||||
pub requests: BTreeMap<Box<TransactionId>, (Arc<ToDeviceRequest>, ShareInfoSet)>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -72,7 +72,9 @@ pub(crate) mod test {
|
||||
room::message::{Relation, Replacement, RoomMessageEventContent},
|
||||
AnyMessageEvent, AnyRoomEvent, AnySyncMessageEvent, AnySyncRoomEvent,
|
||||
},
|
||||
room_id, user_id, DeviceId, UserId,
|
||||
room_id,
|
||||
serde::Base64,
|
||||
user_id, DeviceId, UserId,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
@@ -103,7 +105,7 @@ pub(crate) mod test {
|
||||
|
||||
bob.generate_one_time_keys_helper(1).await;
|
||||
let one_time_key =
|
||||
bob.one_time_keys().await.curve25519().values().next().unwrap().to_owned();
|
||||
Base64::parse(bob.one_time_keys().await.curve25519().values().next().unwrap()).unwrap();
|
||||
let one_time_key = SignedKey::new(one_time_key, BTreeMap::new());
|
||||
let sender_key = bob.identity_keys().curve25519().to_owned();
|
||||
let session =
|
||||
@@ -163,7 +165,8 @@ pub(crate) mod test {
|
||||
let one_time_keys = alice.one_time_keys().await;
|
||||
alice.mark_keys_as_published().await;
|
||||
|
||||
let one_time_key = one_time_keys.curve25519().values().next().unwrap().to_owned();
|
||||
let one_time_key =
|
||||
Base64::parse(one_time_keys.curve25519().values().next().unwrap()).unwrap();
|
||||
|
||||
let one_time_key = SignedKey::new(one_time_key, BTreeMap::new());
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
use std::{collections::BTreeMap, iter, sync::Arc, time::Duration};
|
||||
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use ruma::{
|
||||
api::client::r0::{
|
||||
backup::{add_backup_keys::Response as KeysBackupResponse, RoomKeyBackup},
|
||||
@@ -34,13 +33,12 @@ use ruma::{
|
||||
events::{AnyMessageEventContent, AnyToDeviceEventContent, EventContent, EventType},
|
||||
serde::Raw,
|
||||
to_device::DeviceIdOrAllDevices,
|
||||
DeviceId, RoomId, UserId,
|
||||
DeviceId, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Customized version of
|
||||
/// `ruma_client_api::r0::to_device::send_event_to_device::Request`,
|
||||
/// using a UUID for the transaction ID.
|
||||
/// `ruma_client_api::r0::to_device::send_event_to_device::Request`
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct ToDeviceRequest {
|
||||
/// Type of event being sent to each device.
|
||||
@@ -48,7 +46,7 @@ pub struct ToDeviceRequest {
|
||||
|
||||
/// A request identifier unique to the access token used to send the
|
||||
/// request.
|
||||
pub txn_id: Uuid,
|
||||
pub txn_id: Box<TransactionId>,
|
||||
|
||||
/// A map of users to devices to a content for a message event to be
|
||||
/// sent to the user's device. Individual message events can be sent
|
||||
@@ -77,14 +75,14 @@ impl ToDeviceRequest {
|
||||
recipient_device: impl Into<DeviceIdOrAllDevices>,
|
||||
content: AnyToDeviceEventContent,
|
||||
) -> Self {
|
||||
Self::new_with_id(recipient, recipient_device, content, Uuid::new_v4())
|
||||
Self::new_with_id(recipient, recipient_device, content, TransactionId::new())
|
||||
}
|
||||
|
||||
pub(crate) fn new_for_recipients(
|
||||
recipient: &UserId,
|
||||
recipient_devices: Vec<Box<DeviceId>>,
|
||||
content: AnyToDeviceEventContent,
|
||||
txn_id: Uuid,
|
||||
txn_id: Box<TransactionId>,
|
||||
) -> Self {
|
||||
if recipient_devices.is_empty() {
|
||||
Self::new(recipient, DeviceIdOrAllDevices::AllDevices, content)
|
||||
@@ -108,7 +106,7 @@ impl ToDeviceRequest {
|
||||
recipient: &UserId,
|
||||
recipient_device: impl Into<DeviceIdOrAllDevices>,
|
||||
content: AnyToDeviceEventContent,
|
||||
txn_id: Uuid,
|
||||
txn_id: Box<TransactionId>,
|
||||
) -> Self {
|
||||
let event_type = EventType::from(content.event_type());
|
||||
let raw_content = Raw::new(&content).expect("Failed to serialize to-device event");
|
||||
@@ -119,11 +117,6 @@ impl ToDeviceRequest {
|
||||
ToDeviceRequest { event_type, txn_id, messages }
|
||||
}
|
||||
|
||||
/// Gets the transaction ID as a string.
|
||||
pub fn txn_id_string(&self) -> String {
|
||||
self.txn_id.to_string()
|
||||
}
|
||||
|
||||
/// Get the number of unique messages this request contains.
|
||||
///
|
||||
/// *Note*: A single message may be sent to multiple devices, so this may or
|
||||
@@ -257,13 +250,13 @@ impl From<SignatureUploadRequest> for OutgoingRequests {
|
||||
|
||||
impl From<OutgoingVerificationRequest> for OutgoingRequest {
|
||||
fn from(r: OutgoingVerificationRequest) -> Self {
|
||||
Self { request_id: r.request_id(), request: Arc::new(r.into()) }
|
||||
Self { request_id: r.request_id().to_owned(), request: Arc::new(r.into()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SignatureUploadRequest> for OutgoingRequest {
|
||||
fn from(r: SignatureUploadRequest) -> Self {
|
||||
Self { request_id: Uuid::new_v4(), request: Arc::new(r.into()) }
|
||||
Self { request_id: TransactionId::new(), request: Arc::new(r.into()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,14 +333,14 @@ impl<'a> From<&'a SignatureUploadResponse> for IncomingResponse<'a> {
|
||||
pub struct OutgoingRequest {
|
||||
/// The unique id of a request, needs to be passed when receiving a
|
||||
/// response.
|
||||
pub(crate) request_id: Uuid,
|
||||
pub(crate) request_id: Box<TransactionId>,
|
||||
/// The underlying outgoing request.
|
||||
pub(crate) request: Arc<OutgoingRequests>,
|
||||
}
|
||||
|
||||
impl OutgoingRequest {
|
||||
/// Get the unique id of this request.
|
||||
pub fn request_id(&self) -> &Uuid {
|
||||
pub fn request_id(&self) -> &TransactionId {
|
||||
&self.request_id
|
||||
}
|
||||
|
||||
@@ -368,7 +361,7 @@ pub struct RoomMessageRequest {
|
||||
/// Clients should generate an ID unique across requests with the
|
||||
/// same access token; it will be used by the server to ensure
|
||||
/// idempotency of requests.
|
||||
pub txn_id: Uuid,
|
||||
pub txn_id: Box<TransactionId>,
|
||||
|
||||
/// The event content to send.
|
||||
pub content: AnyMessageEventContent,
|
||||
@@ -395,10 +388,10 @@ pub enum OutgoingVerificationRequest {
|
||||
|
||||
impl OutgoingVerificationRequest {
|
||||
/// Get the unique id of this request.
|
||||
pub fn request_id(&self) -> Uuid {
|
||||
pub fn request_id(&self) -> &TransactionId {
|
||||
match self {
|
||||
OutgoingVerificationRequest::ToDevice(t) => t.txn_id,
|
||||
OutgoingVerificationRequest::InRoom(r) => r.txn_id,
|
||||
OutgoingVerificationRequest::ToDevice(t) => &t.txn_id,
|
||||
OutgoingVerificationRequest::InRoom(r) => &r.txn_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ use std::{
|
||||
|
||||
use dashmap::DashMap;
|
||||
use futures_util::future::join_all;
|
||||
use matrix_sdk_common::{executor::spawn, uuid::Uuid};
|
||||
use matrix_sdk_common::executor::spawn;
|
||||
use ruma::{
|
||||
events::{
|
||||
room::{encrypted::RoomEncryptedEventContent, history_visibility::HistoryVisibility},
|
||||
@@ -28,7 +28,7 @@ use ruma::{
|
||||
},
|
||||
serde::Raw,
|
||||
to_device::DeviceIdOrAllDevices,
|
||||
DeviceId, RoomId, UserId,
|
||||
DeviceId, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use serde_json::Value;
|
||||
use tracing::{debug, info, trace};
|
||||
@@ -46,7 +46,7 @@ pub(crate) struct GroupSessionCache {
|
||||
sessions: Arc<DashMap<Box<RoomId>, OutboundGroupSession>>,
|
||||
/// A map from the request id to the group session that the request belongs
|
||||
/// to. Used to mark requests belonging to the session as shared.
|
||||
sessions_being_shared: Arc<DashMap<Uuid, OutboundGroupSession>>,
|
||||
sessions_being_shared: Arc<DashMap<Box<TransactionId>, OutboundGroupSession>>,
|
||||
}
|
||||
|
||||
impl GroupSessionCache {
|
||||
@@ -137,7 +137,7 @@ impl GroupSessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn mark_request_as_sent(&self, request_id: &Uuid) -> StoreResult<()> {
|
||||
pub async fn mark_request_as_sent(&self, request_id: &TransactionId) -> StoreResult<()> {
|
||||
if let Some((_, s)) = self.sessions.sessions_being_shared.remove(request_id) {
|
||||
s.mark_request_as_sent(request_id);
|
||||
|
||||
@@ -221,7 +221,7 @@ impl GroupSessionManager {
|
||||
devices: Vec<Device>,
|
||||
message_index: u32,
|
||||
) -> OlmResult<(
|
||||
Uuid,
|
||||
Box<TransactionId>,
|
||||
ToDeviceRequest,
|
||||
BTreeMap<Box<UserId>, BTreeMap<Box<DeviceId>, ShareInfo>>,
|
||||
Vec<Session>,
|
||||
@@ -298,18 +298,20 @@ impl GroupSessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
let id = Uuid::new_v4();
|
||||
|
||||
let request =
|
||||
ToDeviceRequest { event_type: EventType::RoomEncrypted, txn_id: id, messages };
|
||||
let txn_id = TransactionId::new();
|
||||
let request = ToDeviceRequest {
|
||||
event_type: EventType::RoomEncrypted,
|
||||
txn_id: txn_id.clone(),
|
||||
messages,
|
||||
};
|
||||
|
||||
trace!(
|
||||
recipient_count = request.message_count(),
|
||||
transaction_id = ?id,
|
||||
transaction_id = ?txn_id,
|
||||
"Created a to-device request carrying a room_key"
|
||||
);
|
||||
|
||||
Ok((id, request, share_infos, changed_sessions))
|
||||
Ok((txn_id, request, share_infos, changed_sessions))
|
||||
}
|
||||
|
||||
/// Given a list of user and an outbound session, return the list of users
|
||||
@@ -412,13 +414,13 @@ impl GroupSessionManager {
|
||||
content: AnyToDeviceEventContent,
|
||||
outbound: OutboundGroupSession,
|
||||
message_index: u32,
|
||||
being_shared: Arc<DashMap<Uuid, OutboundGroupSession>>,
|
||||
being_shared: Arc<DashMap<Box<TransactionId>, OutboundGroupSession>>,
|
||||
) -> OlmResult<Vec<Session>> {
|
||||
let (id, request, share_infos, used_sessions) =
|
||||
Self::encrypt_session_for(content.clone(), chunk, message_index).await?;
|
||||
|
||||
if !request.messages.is_empty() {
|
||||
outbound.add_request(id, request.into(), share_infos);
|
||||
outbound.add_request(id.clone(), request.into(), share_infos);
|
||||
being_shared.insert(id, outbound.clone());
|
||||
}
|
||||
|
||||
@@ -553,7 +555,7 @@ impl GroupSessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
let transaction_ids: Vec<Uuid> = requests.iter().map(|r| r.txn_id).collect();
|
||||
let transaction_ids: Vec<_> = requests.iter().map(|r| r.txn_id.clone()).collect();
|
||||
|
||||
// TODO log the withheld reasons here as well.
|
||||
info!(
|
||||
@@ -587,14 +589,13 @@ impl GroupSessionManager {
|
||||
mod test {
|
||||
use std::ops::Deref;
|
||||
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use matrix_sdk_test::response_from_file;
|
||||
use ruma::{
|
||||
api::{
|
||||
client::r0::keys::{claim_keys, get_keys},
|
||||
IncomingResponse,
|
||||
},
|
||||
device_id, room_id, user_id, DeviceId, UserId,
|
||||
device_id, room_id, user_id, DeviceId, TransactionId, UserId,
|
||||
};
|
||||
use serde_json::Value;
|
||||
|
||||
@@ -627,12 +628,12 @@ mod test {
|
||||
async fn machine() -> OlmMachine {
|
||||
let keys_query = keys_query_response();
|
||||
let keys_claim = keys_claim_response();
|
||||
let uuid = Uuid::new_v4();
|
||||
let txn_id = TransactionId::new();
|
||||
|
||||
let machine = OlmMachine::new(alice_id(), alice_device_id());
|
||||
|
||||
machine.mark_request_as_sent(&uuid, &keys_query).await.unwrap();
|
||||
machine.mark_request_as_sent(&uuid, &keys_claim).await.unwrap();
|
||||
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
|
||||
machine.mark_request_as_sent(&txn_id, &keys_claim).await.unwrap();
|
||||
|
||||
machine
|
||||
}
|
||||
|
||||
@@ -19,14 +19,13 @@ use std::{
|
||||
};
|
||||
|
||||
use dashmap::{DashMap, DashSet};
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use ruma::{
|
||||
api::client::r0::keys::claim_keys::{
|
||||
Request as KeysClaimRequest, Response as KeysClaimResponse,
|
||||
},
|
||||
assign,
|
||||
events::{dummy::ToDeviceDummyEventContent, AnyToDeviceEventContent},
|
||||
DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, UserId,
|
||||
DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, TransactionId, UserId,
|
||||
};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
@@ -50,7 +49,7 @@ pub(crate) struct SessionManager {
|
||||
users_for_key_claim: Arc<DashMap<Box<UserId>, DashSet<Box<DeviceId>>>>,
|
||||
wedged_devices: Arc<DashMap<Box<UserId>, DashSet<Box<DeviceId>>>>,
|
||||
key_request_machine: GossipMachine,
|
||||
outgoing_to_device_requests: Arc<DashMap<Uuid, OutgoingRequest>>,
|
||||
outgoing_to_device_requests: Arc<DashMap<Box<TransactionId>, OutgoingRequest>>,
|
||||
}
|
||||
|
||||
impl SessionManager {
|
||||
@@ -74,7 +73,7 @@ impl SessionManager {
|
||||
}
|
||||
|
||||
/// Mark the outgoing request as sent.
|
||||
pub fn mark_outgoing_request_as_sent(&self, id: &Uuid) {
|
||||
pub fn mark_outgoing_request_as_sent(&self, id: &TransactionId) {
|
||||
self.outgoing_to_device_requests.remove(id);
|
||||
}
|
||||
|
||||
@@ -136,11 +135,11 @@ impl SessionManager {
|
||||
);
|
||||
|
||||
let request = OutgoingRequest {
|
||||
request_id: request.txn_id,
|
||||
request_id: request.txn_id.clone(),
|
||||
request: Arc::new(request.into()),
|
||||
};
|
||||
|
||||
self.outgoing_to_device_requests.insert(request.request_id, request);
|
||||
self.outgoing_to_device_requests.insert(request.request_id.clone(), request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +176,7 @@ impl SessionManager {
|
||||
pub async fn get_missing_sessions(
|
||||
&self,
|
||||
users: impl Iterator<Item = &UserId>,
|
||||
) -> StoreResult<Option<(Uuid, KeysClaimRequest)>> {
|
||||
) -> StoreResult<Option<(Box<TransactionId>, KeysClaimRequest)>> {
|
||||
let mut missing = BTreeMap::new();
|
||||
|
||||
// Add the list of devices that the user wishes to establish sessions
|
||||
@@ -240,7 +239,7 @@ impl SessionManager {
|
||||
debug!(?missing, "Collected user/device pairs that are missing an Olm session");
|
||||
|
||||
Ok(Some((
|
||||
Uuid::new_v4(),
|
||||
TransactionId::new(),
|
||||
assign!(KeysClaimRequest::new(missing), {
|
||||
timeout: Some(Self::KEY_CLAIM_TIMEOUT),
|
||||
}),
|
||||
|
||||
@@ -18,8 +18,8 @@ use std::{
|
||||
};
|
||||
|
||||
use dashmap::{DashMap, DashSet};
|
||||
use matrix_sdk_common::{async_trait, locks::Mutex, uuid::Uuid};
|
||||
use ruma::{DeviceId, RoomId, UserId};
|
||||
use matrix_sdk_common::{async_trait, locks::Mutex};
|
||||
use ruma::{DeviceId, RoomId, TransactionId, UserId};
|
||||
|
||||
use super::{
|
||||
caches::{DeviceStore, GroupSessionStore, SessionStore},
|
||||
@@ -51,8 +51,8 @@ pub struct MemoryStore {
|
||||
olm_hashes: Arc<DashMap<String, DashSet<String>>>,
|
||||
devices: DeviceStore,
|
||||
identities: Arc<DashMap<Box<UserId>, ReadOnlyUserIdentities>>,
|
||||
outgoing_key_requests: Arc<DashMap<Uuid, GossipRequest>>,
|
||||
key_requests_by_info: Arc<DashMap<String, Uuid>>,
|
||||
outgoing_key_requests: Arc<DashMap<Box<TransactionId>, GossipRequest>>,
|
||||
key_requests_by_info: Arc<DashMap<String, Box<TransactionId>>>,
|
||||
}
|
||||
|
||||
impl Default for MemoryStore {
|
||||
@@ -137,10 +137,10 @@ impl CryptoStore for MemoryStore {
|
||||
}
|
||||
|
||||
for key_request in changes.key_requests {
|
||||
let id = key_request.request_id;
|
||||
let id = key_request.request_id.clone();
|
||||
let info_string = encode_key_info(&key_request.info);
|
||||
|
||||
self.outgoing_key_requests.insert(id, key_request);
|
||||
self.outgoing_key_requests.insert(id.clone(), key_request);
|
||||
self.key_requests_by_info.insert(info_string, id);
|
||||
}
|
||||
|
||||
@@ -266,9 +266,9 @@ impl CryptoStore for MemoryStore {
|
||||
|
||||
async fn get_outgoing_secret_requests(
|
||||
&self,
|
||||
request_id: Uuid,
|
||||
request_id: &TransactionId,
|
||||
) -> Result<Option<GossipRequest>> {
|
||||
Ok(self.outgoing_key_requests.get(&request_id).map(|r| r.clone()))
|
||||
Ok(self.outgoing_key_requests.get(request_id).map(|r| r.clone()))
|
||||
}
|
||||
|
||||
async fn get_secret_request_by_info(
|
||||
@@ -280,7 +280,7 @@ impl CryptoStore for MemoryStore {
|
||||
Ok(self
|
||||
.key_requests_by_info
|
||||
.get(&key_info_string)
|
||||
.and_then(|i| self.outgoing_key_requests.get(&i).map(|r| r.clone())))
|
||||
.and_then(|i| self.outgoing_key_requests.get(&*i).map(|r| r.clone())))
|
||||
}
|
||||
|
||||
async fn get_unsent_secret_requests(&self) -> Result<Vec<GossipRequest>> {
|
||||
@@ -292,8 +292,8 @@ impl CryptoStore for MemoryStore {
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn delete_outgoing_secret_requests(&self, request_id: Uuid) -> Result<()> {
|
||||
self.outgoing_key_requests.remove(&request_id).and_then(|(_, i)| {
|
||||
async fn delete_outgoing_secret_requests(&self, request_id: &TransactionId) -> Result<()> {
|
||||
self.outgoing_key_requests.remove(request_id).and_then(|(_, i)| {
|
||||
let key_info_string = encode_key_info(&i.info);
|
||||
self.key_requests_by_info.remove(&key_info_string)
|
||||
});
|
||||
|
||||
@@ -52,13 +52,13 @@ use std::{
|
||||
};
|
||||
|
||||
use base64::DecodeError;
|
||||
use matrix_sdk_common::{async_trait, locks::Mutex, uuid::Uuid, AsyncTraitDeps};
|
||||
use matrix_sdk_common::{async_trait, locks::Mutex, AsyncTraitDeps};
|
||||
pub use memorystore::MemoryStore;
|
||||
use olm_rs::errors::{OlmAccountError, OlmGroupSessionError, OlmSessionError};
|
||||
pub use pickle_key::{EncryptedPickleKey, PickleKey};
|
||||
use ruma::{
|
||||
events::secret::request::SecretName, identifiers::Error as IdentifierValidationError, DeviceId,
|
||||
DeviceKeyAlgorithm, RoomId, UserId,
|
||||
DeviceKeyAlgorithm, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use serde_json::Error as SerdeError;
|
||||
use thiserror::Error;
|
||||
@@ -704,8 +704,10 @@ pub trait CryptoStore: AsyncTraitDeps {
|
||||
///
|
||||
/// * `request_id` - The unique request id that identifies this outgoing
|
||||
/// secret request.
|
||||
async fn get_outgoing_secret_requests(&self, request_id: Uuid)
|
||||
-> Result<Option<GossipRequest>>;
|
||||
async fn get_outgoing_secret_requests(
|
||||
&self,
|
||||
request_id: &TransactionId,
|
||||
) -> Result<Option<GossipRequest>>;
|
||||
|
||||
/// Get an outgoing key request that we created that matches the given
|
||||
/// requested key info.
|
||||
@@ -728,5 +730,5 @@ pub trait CryptoStore: AsyncTraitDeps {
|
||||
///
|
||||
/// * `request_id` - The unique request id that identifies this outgoing key
|
||||
/// request.
|
||||
async fn delete_outgoing_secret_requests(&self, request_id: Uuid) -> Result<()>;
|
||||
async fn delete_outgoing_secret_requests(&self, request_id: &TransactionId) -> Result<()>;
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ use std::{
|
||||
};
|
||||
|
||||
use dashmap::DashSet;
|
||||
use matrix_sdk_common::{async_trait, locks::Mutex, uuid};
|
||||
use matrix_sdk_common::{async_trait, locks::Mutex};
|
||||
use olm_rs::{account::IdentityKeys, PicklingMode};
|
||||
use ruma::{
|
||||
encryption::DeviceKeys,
|
||||
events::{room_key_request::RequestedKeyInfo, secret::request::SecretName},
|
||||
DeviceId, DeviceKeyId, EventEncryptionAlgorithm, RoomId, UserId,
|
||||
DeviceId, DeviceKeyId, EventEncryptionAlgorithm, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub use sled::Error;
|
||||
@@ -34,7 +34,6 @@ use sled::{
|
||||
Config, Db, IVec, Transactional, Tree,
|
||||
};
|
||||
use tracing::debug;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{
|
||||
caches::SessionStore, BackupKeys, Changes, CryptoStore, CryptoStoreError, InboundGroupSession,
|
||||
@@ -69,9 +68,9 @@ impl<T: EncodeKey> EncodeKey for Box<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl EncodeKey for Uuid {
|
||||
impl EncodeKey for TransactionId {
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
self.as_u128().to_be_bytes().to_vec()
|
||||
self.as_str().encode()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -930,7 +929,7 @@ impl CryptoStore for SledStore {
|
||||
|
||||
async fn get_outgoing_secret_requests(
|
||||
&self,
|
||||
request_id: Uuid,
|
||||
request_id: &TransactionId,
|
||||
) -> Result<Option<GossipRequest>> {
|
||||
let request_id = request_id.encode();
|
||||
|
||||
@@ -960,7 +959,7 @@ impl CryptoStore for SledStore {
|
||||
requests
|
||||
}
|
||||
|
||||
async fn delete_outgoing_secret_requests(&self, request_id: Uuid) -> Result<()> {
|
||||
async fn delete_outgoing_secret_requests(&self, request_id: &TransactionId) -> Result<()> {
|
||||
let ret: Result<(), TransactionError<serde_json::Error>> = (
|
||||
&self.outgoing_secret_requests,
|
||||
&self.unsent_secret_requests,
|
||||
@@ -1033,12 +1032,11 @@ impl CryptoStore for SledStore {
|
||||
mod test {
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use matrix_sdk_test::async_test;
|
||||
use olm_rs::outbound_group_session::OlmOutboundGroupSession;
|
||||
use ruma::{
|
||||
device_id, encryption::SignedKey, events::room_key_request::RequestedKeyInfo, room_id,
|
||||
user_id, DeviceId, EventEncryptionAlgorithm, UserId,
|
||||
serde::Base64, user_id, DeviceId, EventEncryptionAlgorithm, TransactionId, UserId,
|
||||
};
|
||||
use tempfile::tempdir;
|
||||
|
||||
@@ -1100,7 +1098,7 @@ mod test {
|
||||
|
||||
bob.generate_one_time_keys_helper(1).await;
|
||||
let one_time_key =
|
||||
bob.one_time_keys().await.curve25519().values().next().unwrap().to_owned();
|
||||
Base64::parse(bob.one_time_keys().await.curve25519().values().next().unwrap()).unwrap();
|
||||
let one_time_key = SignedKey::new(one_time_key, BTreeMap::new());
|
||||
let sender_key = bob.identity_keys().curve25519().to_owned();
|
||||
let session =
|
||||
@@ -1479,7 +1477,7 @@ mod test {
|
||||
async fn key_request_saving() {
|
||||
let (account, store, _dir) = get_loaded_store().await;
|
||||
|
||||
let id = Uuid::new_v4();
|
||||
let id = TransactionId::new();
|
||||
let info: SecretInfo = RequestedKeyInfo::new(
|
||||
EventEncryptionAlgorithm::MegolmV1AesSha2,
|
||||
room_id!("!test:localhost").to_owned(),
|
||||
@@ -1490,12 +1488,12 @@ mod test {
|
||||
|
||||
let request = GossipRequest {
|
||||
request_recipient: account.user_id().to_owned(),
|
||||
request_id: id,
|
||||
request_id: id.clone(),
|
||||
info: info.clone(),
|
||||
sent_out: false,
|
||||
};
|
||||
|
||||
assert!(store.get_outgoing_secret_requests(id).await.unwrap().is_none());
|
||||
assert!(store.get_outgoing_secret_requests(&id).await.unwrap().is_none());
|
||||
|
||||
let mut changes = Changes::default();
|
||||
changes.key_requests.push(request.clone());
|
||||
@@ -1503,7 +1501,7 @@ mod test {
|
||||
|
||||
let request = Some(request);
|
||||
|
||||
let stored_request = store.get_outgoing_secret_requests(id).await.unwrap();
|
||||
let stored_request = store.get_outgoing_secret_requests(&id).await.unwrap();
|
||||
assert_eq!(request, stored_request);
|
||||
|
||||
let stored_request = store.get_secret_request_by_info(&info).await.unwrap();
|
||||
@@ -1512,7 +1510,7 @@ mod test {
|
||||
|
||||
let request = GossipRequest {
|
||||
request_recipient: account.user_id().to_owned(),
|
||||
request_id: id,
|
||||
request_id: id.clone(),
|
||||
info: info.clone(),
|
||||
sent_out: true,
|
||||
};
|
||||
@@ -1522,12 +1520,12 @@ mod test {
|
||||
store.save_changes(changes).await.unwrap();
|
||||
|
||||
assert!(store.get_unsent_secret_requests().await.unwrap().is_empty());
|
||||
let stored_request = store.get_outgoing_secret_requests(id).await.unwrap();
|
||||
let stored_request = store.get_outgoing_secret_requests(&id).await.unwrap();
|
||||
assert_eq!(Some(request), stored_request);
|
||||
|
||||
store.delete_outgoing_secret_requests(id).await.unwrap();
|
||||
store.delete_outgoing_secret_requests(&id).await.unwrap();
|
||||
|
||||
let stored_request = store.get_outgoing_secret_requests(id).await.unwrap();
|
||||
let stored_request = store.get_outgoing_secret_requests(&id).await.unwrap();
|
||||
assert_eq!(None, stored_request);
|
||||
|
||||
let stored_request = store.get_secret_request_by_info(&info).await.unwrap();
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use dashmap::DashMap;
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use ruma::{DeviceId, UserId};
|
||||
use ruma::{DeviceId, TransactionId, UserId};
|
||||
use tracing::trace;
|
||||
|
||||
use super::{event_enums::OutgoingContent, Sas, Verification};
|
||||
@@ -27,7 +26,7 @@ use crate::{OutgoingRequest, OutgoingVerificationRequest, RoomMessageRequest, To
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VerificationCache {
|
||||
verification: Arc<DashMap<Box<UserId>, DashMap<String, Verification>>>,
|
||||
outgoing_requests: Arc<DashMap<Uuid, OutgoingRequest>>,
|
||||
outgoing_requests: Arc<DashMap<Box<TransactionId>, OutgoingRequest>>,
|
||||
}
|
||||
|
||||
impl VerificationCache {
|
||||
@@ -119,12 +118,14 @@ impl VerificationCache {
|
||||
|
||||
pub fn add_request(&self, request: OutgoingRequest) {
|
||||
trace!("Adding an outgoing verification request {:?}", request);
|
||||
self.outgoing_requests.insert(request.request_id, request);
|
||||
self.outgoing_requests.insert(request.request_id.clone(), request);
|
||||
}
|
||||
|
||||
pub fn add_verification_request(&self, request: OutgoingVerificationRequest) {
|
||||
let request =
|
||||
OutgoingRequest { request_id: request.request_id(), request: Arc::new(request.into()) };
|
||||
let request = OutgoingRequest {
|
||||
request_id: request.request_id().to_owned(),
|
||||
request: Arc::new(request.into()),
|
||||
};
|
||||
self.add_request(request);
|
||||
}
|
||||
|
||||
@@ -137,21 +138,25 @@ impl VerificationCache {
|
||||
match content {
|
||||
OutgoingContent::ToDevice(c) => {
|
||||
let request = ToDeviceRequest::new(recipient, recipient_device.to_owned(), c);
|
||||
let request_id = request.txn_id;
|
||||
let request_id = request.txn_id.clone();
|
||||
|
||||
let request = OutgoingRequest { request_id, request: Arc::new(request.into()) };
|
||||
let request = OutgoingRequest {
|
||||
request_id: request_id.clone(),
|
||||
request: Arc::new(request.into()),
|
||||
};
|
||||
|
||||
self.outgoing_requests.insert(request_id, request);
|
||||
}
|
||||
|
||||
OutgoingContent::Room(r, c) => {
|
||||
let request_id = Uuid::new_v4();
|
||||
let request_id = TransactionId::new();
|
||||
|
||||
let request = OutgoingRequest {
|
||||
request: Arc::new(
|
||||
RoomMessageRequest { room_id: r, txn_id: request_id, content: c }.into(),
|
||||
RoomMessageRequest { room_id: r, txn_id: request_id.clone(), content: c }
|
||||
.into(),
|
||||
),
|
||||
request_id,
|
||||
request_id: request_id.clone(),
|
||||
};
|
||||
|
||||
self.outgoing_requests.insert(request_id, request);
|
||||
@@ -159,7 +164,7 @@ impl VerificationCache {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mark_request_as_sent(&self, uuid: &Uuid) {
|
||||
self.outgoing_requests.remove(uuid);
|
||||
pub fn mark_request_as_sent(&self, txn_id: &TransactionId) {
|
||||
self.outgoing_requests.remove(txn_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ use ruma::{
|
||||
room::message::{KeyVerificationRequestEventContent, MessageType},
|
||||
AnyMessageEvent, AnyMessageEventContent, AnyToDeviceEvent, AnyToDeviceEventContent,
|
||||
},
|
||||
serde::CanonicalJsonValue,
|
||||
serde::{Base64, CanonicalJsonValue},
|
||||
DeviceId, MilliSecondsSinceUnixEpoch, RoomId, UserId,
|
||||
};
|
||||
|
||||
@@ -431,7 +431,7 @@ impl<'a> StartContent<'a> {
|
||||
|
||||
pub fn flow_id(&self) -> &str {
|
||||
match self {
|
||||
Self::ToDevice(c) => &c.transaction_id,
|
||||
Self::ToDevice(c) => c.transaction_id.as_str(),
|
||||
Self::Room(c) => c.relates_to.event_id.as_str(),
|
||||
}
|
||||
}
|
||||
@@ -483,7 +483,7 @@ impl<'a> From<&'a ToDeviceKeyVerificationDoneEventContent> for DoneContent<'a> {
|
||||
impl<'a> DoneContent<'a> {
|
||||
pub fn flow_id(&self) -> &str {
|
||||
match self {
|
||||
Self::ToDevice(c) => &c.transaction_id,
|
||||
Self::ToDevice(c) => c.transaction_id.as_str(),
|
||||
Self::Room(c) => c.relates_to.event_id.as_str(),
|
||||
}
|
||||
}
|
||||
@@ -498,7 +498,7 @@ pub enum AcceptContent<'a> {
|
||||
impl AcceptContent<'_> {
|
||||
pub fn flow_id(&self) -> &str {
|
||||
match self {
|
||||
Self::ToDevice(c) => &c.transaction_id,
|
||||
Self::ToDevice(c) => c.transaction_id.as_str(),
|
||||
Self::Room(c) => c.relates_to.event_id.as_str(),
|
||||
}
|
||||
}
|
||||
@@ -529,12 +529,12 @@ pub enum KeyContent<'a> {
|
||||
impl KeyContent<'_> {
|
||||
pub fn flow_id(&self) -> &str {
|
||||
match self {
|
||||
Self::ToDevice(c) => &c.transaction_id,
|
||||
Self::ToDevice(c) => c.transaction_id.as_str(),
|
||||
Self::Room(c) => c.relates_to.event_id.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn public_key(&self) -> &str {
|
||||
pub fn public_key(&self) -> &Base64 {
|
||||
match self {
|
||||
Self::ToDevice(c) => &c.key,
|
||||
Self::Room(c) => &c.key,
|
||||
@@ -551,19 +551,19 @@ pub enum MacContent<'a> {
|
||||
impl MacContent<'_> {
|
||||
pub fn flow_id(&self) -> &str {
|
||||
match self {
|
||||
Self::ToDevice(c) => &c.transaction_id,
|
||||
Self::ToDevice(c) => c.transaction_id.as_str(),
|
||||
Self::Room(c) => c.relates_to.event_id.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mac(&self) -> &BTreeMap<String, String> {
|
||||
pub fn mac(&self) -> &BTreeMap<String, Base64> {
|
||||
match self {
|
||||
Self::ToDevice(c) => &c.mac,
|
||||
Self::Room(c) => &c.mac,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn keys(&self) -> &str {
|
||||
pub fn keys(&self) -> &Base64 {
|
||||
match self {
|
||||
Self::ToDevice(c) => &c.keys,
|
||||
Self::Room(c) => &c.keys,
|
||||
|
||||
@@ -18,14 +18,14 @@ use std::{
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use matrix_sdk_common::{locks::Mutex, uuid::Uuid};
|
||||
use matrix_sdk_common::locks::Mutex;
|
||||
use ruma::{
|
||||
events::{
|
||||
key::verification::VerificationMethod, AnyToDeviceEvent, AnyToDeviceEventContent,
|
||||
ToDeviceEvent,
|
||||
},
|
||||
serde::Raw,
|
||||
DeviceId, EventId, MilliSecondsSinceUnixEpoch, RoomId, UserId,
|
||||
DeviceId, EventId, MilliSecondsSinceUnixEpoch, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use tracing::{info, trace, warn};
|
||||
|
||||
@@ -80,7 +80,7 @@ impl VerificationMachine {
|
||||
recipient_devices: Vec<Box<DeviceId>>,
|
||||
methods: Option<Vec<VerificationMethod>>,
|
||||
) -> (VerificationRequest, OutgoingVerificationRequest) {
|
||||
let flow_id = FlowId::from(Uuid::new_v4().to_string());
|
||||
let flow_id = FlowId::from(TransactionId::new());
|
||||
|
||||
let verification = VerificationRequest::new(
|
||||
self.verifications.clone(),
|
||||
@@ -145,7 +145,7 @@ impl VerificationMachine {
|
||||
|
||||
let request = match content {
|
||||
OutgoingContent::Room(r, c) => {
|
||||
RoomMessageRequest { room_id: r, txn_id: Uuid::new_v4(), content: c }.into()
|
||||
RoomMessageRequest { room_id: r, txn_id: TransactionId::new(), content: c }.into()
|
||||
}
|
||||
OutgoingContent::ToDevice(c) => {
|
||||
let request =
|
||||
@@ -225,8 +225,8 @@ impl VerificationMachine {
|
||||
self.verifications.queue_up_content(recipient, recipient_device, content)
|
||||
}
|
||||
|
||||
pub fn mark_request_as_sent(&self, uuid: &Uuid) {
|
||||
self.verifications.mark_request_as_sent(uuid);
|
||||
pub fn mark_request_as_sent(&self, txn_id: &TransactionId) {
|
||||
self.verifications.mark_request_as_sent(txn_id);
|
||||
}
|
||||
|
||||
pub fn outgoing_messages(&self) -> Vec<OutgoingRequest> {
|
||||
@@ -630,7 +630,7 @@ mod test {
|
||||
assert!(!alice_machine.verifications.outgoing_requests().is_empty());
|
||||
|
||||
let request = alice_machine.verifications.outgoing_requests().get(0).cloned().unwrap();
|
||||
let txn_id = *request.request_id();
|
||||
let txn_id = request.request_id().to_owned();
|
||||
let content = OutgoingContent::try_from(request).unwrap();
|
||||
let content = KeyContent::try_from(&content).unwrap().into();
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ use ruma::{
|
||||
},
|
||||
AnyMessageEventContent, AnyToDeviceEventContent,
|
||||
},
|
||||
DeviceId, DeviceKeyId, EventId, RoomId, UserId,
|
||||
DeviceId, DeviceKeyId, EventId, RoomId, TransactionId, UserId,
|
||||
};
|
||||
pub use sas::{AcceptSettings, Sas};
|
||||
use tracing::{error, info, trace, warn};
|
||||
@@ -355,7 +355,7 @@ impl Cancelled {
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, PartialOrd)]
|
||||
pub enum FlowId {
|
||||
ToDevice(String),
|
||||
ToDevice(Box<TransactionId>),
|
||||
InRoom(Box<RoomId>, Box<EventId>),
|
||||
}
|
||||
|
||||
@@ -376,8 +376,8 @@ impl FlowId {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for FlowId {
|
||||
fn from(transaction_id: String) -> Self {
|
||||
impl From<Box<TransactionId>> for FlowId {
|
||||
fn from(transaction_id: Box<TransactionId>) -> Self {
|
||||
FlowId::ToDevice(transaction_id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ use matrix_qrcode::{
|
||||
qrcode::QrCode, EncodingError, QrVerificationData, SelfVerificationData,
|
||||
SelfVerificationNoMasterKey, VerificationData,
|
||||
};
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use ruma::{
|
||||
api::client::r0::keys::upload_signatures::Request as SignatureUploadRequest,
|
||||
events::{
|
||||
@@ -33,7 +32,8 @@ use ruma::{
|
||||
},
|
||||
AnyMessageEventContent, AnyToDeviceEventContent,
|
||||
},
|
||||
DeviceId, DeviceKeyAlgorithm, RoomId, UserId,
|
||||
serde::Base64,
|
||||
DeviceId, DeviceKeyAlgorithm, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use thiserror::Error;
|
||||
use tracing::trace;
|
||||
@@ -287,7 +287,7 @@ impl QrVerification {
|
||||
fn content_to_request(&self, content: OutgoingContent) -> OutgoingVerificationRequest {
|
||||
match content {
|
||||
OutgoingContent::Room(room_id, content) => {
|
||||
RoomMessageRequest { room_id, txn_id: Uuid::new_v4(), content }.into()
|
||||
RoomMessageRequest { room_id, txn_id: TransactionId::new(), content }.into()
|
||||
}
|
||||
OutgoingContent::ToDevice(c) => ToDeviceRequest::new(
|
||||
self.identities.other_user_id(),
|
||||
@@ -430,11 +430,11 @@ impl QrVerification {
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_secret() -> String {
|
||||
fn generate_secret() -> Base64 {
|
||||
let mut shared_secret = [0u8; SECRET_SIZE];
|
||||
getrandom::getrandom(&mut shared_secret)
|
||||
.expect("Can't generate randomness for the shared secret");
|
||||
crate::utilities::encode(shared_secret)
|
||||
Base64::new(shared_secret.to_vec())
|
||||
}
|
||||
|
||||
pub(crate) fn new_self(
|
||||
@@ -647,7 +647,7 @@ impl<S: Clone> QrState<S> {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Created {
|
||||
secret: String,
|
||||
secret: Base64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -659,7 +659,7 @@ struct Confirmed {}
|
||||
#[derive(Clone, Debug)]
|
||||
struct Reciprocated {
|
||||
own_device_id: Box<DeviceId>,
|
||||
secret: String,
|
||||
secret: Base64,
|
||||
}
|
||||
|
||||
impl Reciprocated {
|
||||
@@ -830,7 +830,7 @@ mod test {
|
||||
let store = VerificationStore { account: account.clone(), inner: store };
|
||||
|
||||
let private_identity = PrivateCrossSigningIdentity::new(user_id().to_owned()).await;
|
||||
let flow_id = FlowId::ToDevice("test_transaction".to_owned());
|
||||
let flow_id = FlowId::ToDevice("test_transaction".into());
|
||||
|
||||
let device_key = account.identity_keys().ed25519().to_owned();
|
||||
let master_key = private_identity.master_public_key().await.unwrap();
|
||||
@@ -994,7 +994,7 @@ mod test {
|
||||
assert!(identity.is_verified());
|
||||
};
|
||||
|
||||
let flow_id = FlowId::ToDevice("test_transaction".to_owned());
|
||||
let flow_id = FlowId::ToDevice("test_transaction".into());
|
||||
test(flow_id).await;
|
||||
|
||||
let flow_id =
|
||||
|
||||
@@ -19,7 +19,7 @@ use std::{
|
||||
|
||||
#[cfg(feature = "qrcode")]
|
||||
use matrix_qrcode::QrVerificationData;
|
||||
use matrix_sdk_common::{instant::Instant, uuid::Uuid};
|
||||
use matrix_sdk_common::instant::Instant;
|
||||
#[cfg(feature = "qrcode")]
|
||||
use ruma::DeviceKeyAlgorithm;
|
||||
use ruma::{
|
||||
@@ -35,7 +35,7 @@ use ruma::{
|
||||
AnyMessageEventContent, AnyToDeviceEventContent,
|
||||
},
|
||||
to_device::DeviceIdOrAllDevices,
|
||||
DeviceId, MilliSecondsSinceUnixEpoch, RoomId, UserId,
|
||||
DeviceId, MilliSecondsSinceUnixEpoch, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use tracing::{info, trace, warn};
|
||||
|
||||
@@ -159,7 +159,7 @@ impl VerificationRequest {
|
||||
|
||||
let content = ToDeviceKeyVerificationRequestEventContent::new(
|
||||
self.account.device_id().into(),
|
||||
self.flow_id().as_str().to_string(),
|
||||
self.flow_id().as_str().into(),
|
||||
methods,
|
||||
MilliSecondsSinceUnixEpoch::now(),
|
||||
);
|
||||
@@ -168,7 +168,7 @@ impl VerificationRequest {
|
||||
self.other_user(),
|
||||
self.recipient_devices.to_vec(),
|
||||
AnyToDeviceEventContent::KeyVerificationRequest(content),
|
||||
Uuid::new_v4(),
|
||||
TransactionId::new(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ impl VerificationRequest {
|
||||
ToDeviceRequest::new(self.other_user(), inner.other_device_id(), content).into()
|
||||
}
|
||||
OutgoingContent::Room(room_id, content) => {
|
||||
RoomMessageRequest { room_id, txn_id: Uuid::new_v4(), content }.into()
|
||||
RoomMessageRequest { room_id, txn_id: TransactionId::new(), content }.into()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -446,7 +446,7 @@ impl VerificationRequest {
|
||||
self.other_user(),
|
||||
self.recipient_devices.to_vec(),
|
||||
content,
|
||||
Uuid::new_v4(),
|
||||
TransactionId::new(),
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
@@ -454,7 +454,7 @@ impl VerificationRequest {
|
||||
}
|
||||
}
|
||||
OutgoingContent::Room(room_id, content) => {
|
||||
RoomMessageRequest { room_id, txn_id: Uuid::new_v4(), content }.into()
|
||||
RoomMessageRequest { room_id, txn_id: TransactionId::new(), content }.into()
|
||||
}
|
||||
});
|
||||
|
||||
@@ -541,7 +541,7 @@ impl VerificationRequest {
|
||||
self.other_user(),
|
||||
recipients,
|
||||
c,
|
||||
Uuid::new_v4(),
|
||||
TransactionId::new(),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
@@ -656,7 +656,8 @@ impl VerificationRequest {
|
||||
)
|
||||
.into(),
|
||||
OutgoingContent::Room(room_id, content) => {
|
||||
RoomMessageRequest { room_id, txn_id: Uuid::new_v4(), content }.into()
|
||||
RoomMessageRequest { room_id, txn_id: TransactionId::new(), content }
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1459,7 +1460,7 @@ mod test {
|
||||
|
||||
let bob_store = VerificationStore { account: bob.clone(), inner: bob_store.into() };
|
||||
|
||||
let flow_id = FlowId::from("TEST_FLOW_ID".to_owned());
|
||||
let flow_id = FlowId::ToDevice("TEST_FLOW_ID".into());
|
||||
|
||||
let bob_request = VerificationRequest::new(
|
||||
VerificationCache::new(),
|
||||
|
||||
@@ -24,6 +24,7 @@ use ruma::{
|
||||
},
|
||||
AnyMessageEventContent, AnyToDeviceEventContent,
|
||||
},
|
||||
serde::Base64,
|
||||
DeviceKeyAlgorithm, DeviceKeyId, UserId,
|
||||
};
|
||||
use sha2::{Digest, Sha256};
|
||||
@@ -32,7 +33,6 @@ use tracing::{trace, warn};
|
||||
use super::{FlowId, OutgoingContent};
|
||||
use crate::{
|
||||
identities::{ReadOnlyDevice, ReadOnlyUserIdentities},
|
||||
utilities::encode,
|
||||
verification::event_enums::{MacContent, StartContent},
|
||||
Emoji, ReadOnlyAccount, ReadOnlyOwnUserIdentity,
|
||||
};
|
||||
@@ -55,11 +55,18 @@ pub struct SasIds {
|
||||
///
|
||||
/// * `content` - The `m.key.verification.start` event content that started the
|
||||
/// interactive verification process.
|
||||
pub fn calculate_commitment(public_key: &str, content: &StartContent) -> String {
|
||||
pub fn calculate_commitment(public_key: &Base64, content: &StartContent) -> Base64 {
|
||||
let content = content.canonical_json();
|
||||
let content_string = content.to_string();
|
||||
|
||||
encode(Sha256::new().chain(&public_key).chain(&content_string).finalize())
|
||||
Base64::new(
|
||||
Sha256::new()
|
||||
.chain(public_key.encode())
|
||||
.chain(&content_string)
|
||||
.finalize()
|
||||
.as_slice()
|
||||
.to_owned(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Get a tuple of an emoji and a description of the emoji using a number.
|
||||
@@ -198,11 +205,13 @@ pub fn receive_mac_event(
|
||||
let mut keys = content.mac().keys().map(|k| k.as_str()).collect::<Vec<_>>();
|
||||
keys.sort_unstable();
|
||||
|
||||
let keys = sas
|
||||
.calculate_mac(&keys.join(","), &format!("{}KEY_IDS", &info))
|
||||
.expect("Can't calculate SAS MAC");
|
||||
let keys = Base64::parse(
|
||||
sas.calculate_mac(&keys.join(","), &format!("{}KEY_IDS", &info))
|
||||
.expect("Can't calculate SAS MAC"),
|
||||
)
|
||||
.expect("Can't base64-decode SAS MAC");
|
||||
|
||||
if keys != content.keys() {
|
||||
if keys != *content.keys() {
|
||||
return Err(CancelCode::KeyMismatch);
|
||||
}
|
||||
|
||||
@@ -220,13 +229,14 @@ pub fn receive_mac_event(
|
||||
};
|
||||
|
||||
if let Some(key) = ids.other_device.keys().get(&key_id) {
|
||||
if key_mac
|
||||
== &sas
|
||||
.calculate_mac(key, &format!("{}{}", info, key_id))
|
||||
.expect("Can't calculate SAS MAC")
|
||||
{
|
||||
trace!("Successfully verified the device key {} from {}", key_id, sender);
|
||||
let calculated_mac = Base64::parse(
|
||||
sas.calculate_mac(key, &format!("{}{}", info, key_id))
|
||||
.expect("Can't calculate SAS MAC"),
|
||||
)
|
||||
.expect("Can't base64-decode SAS MAC");
|
||||
|
||||
if *key_mac == calculated_mac {
|
||||
trace!("Successfully verified the device key {} from {}", key_id, sender);
|
||||
verified_devices.push(ids.other_device.clone());
|
||||
} else {
|
||||
return Err(CancelCode::KeyMismatch);
|
||||
@@ -235,11 +245,13 @@ pub fn receive_mac_event(
|
||||
if let Some(key) = identity.master_key().get_key(&key_id) {
|
||||
// TODO we should check that the master key signs the device,
|
||||
// this way we know the master key also trusts the device
|
||||
if key_mac
|
||||
== &sas
|
||||
.calculate_mac(key, &format!("{}{}", info, key_id))
|
||||
.expect("Can't calculate SAS MAC")
|
||||
{
|
||||
let calculated_mac = Base64::parse(
|
||||
sas.calculate_mac(key, &format!("{}{}", info, key_id))
|
||||
.expect("Can't calculate SAS MAC"),
|
||||
)
|
||||
.expect("Can't base64-decode SAS MAC");
|
||||
|
||||
if *key_mac == calculated_mac {
|
||||
trace!("Successfully verified the master key {} from {}", key_id, sender);
|
||||
verified_identities.push(identity.clone())
|
||||
} else {
|
||||
@@ -294,7 +306,7 @@ fn extra_mac_info_send(ids: &SasIds, flow_id: &str) -> String {
|
||||
///
|
||||
/// This will panic if the public key of the other side wasn't set.
|
||||
pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &FlowId) -> OutgoingContent {
|
||||
let mut mac: BTreeMap<String, String> = BTreeMap::new();
|
||||
let mut mac: BTreeMap<String, Base64> = BTreeMap::new();
|
||||
|
||||
let key_id = DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, ids.account.device_id());
|
||||
let key = ids.account.identity_keys().ed25519();
|
||||
@@ -302,7 +314,11 @@ pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &FlowId) -> Outgoing
|
||||
|
||||
mac.insert(
|
||||
key_id.to_string(),
|
||||
sas.calculate_mac(key, &format!("{}{}", info, key_id)).expect("Can't calculate SAS MAC"),
|
||||
Base64::parse(
|
||||
sas.calculate_mac(key, &format!("{}{}", info, key_id))
|
||||
.expect("Can't calculate SAS MAC"),
|
||||
)
|
||||
.expect("Can't base64-decode SAS MAC"),
|
||||
);
|
||||
|
||||
if let Some(own_identity) = &ids.own_identity {
|
||||
@@ -310,9 +326,11 @@ pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &FlowId) -> Outgoing
|
||||
if let Some(key) = own_identity.master_key().get_first_key() {
|
||||
let key_id = format!("{}:{}", DeviceKeyAlgorithm::Ed25519, &key);
|
||||
|
||||
let calculated_mac = sas
|
||||
.calculate_mac(key, &format!("{}{}", info, &key_id))
|
||||
.expect("Can't calculate SAS Master key MAC");
|
||||
let calculated_mac = Base64::parse(
|
||||
sas.calculate_mac(key, &format!("{}{}", info, &key_id))
|
||||
.expect("Can't calculate SAS Master key MAC"),
|
||||
)
|
||||
.expect("Can't base64-decode SAS Master key MAC");
|
||||
|
||||
mac.insert(key_id, calculated_mac);
|
||||
}
|
||||
@@ -323,13 +341,16 @@ pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &FlowId) -> Outgoing
|
||||
|
||||
let mut keys: Vec<_> = mac.keys().map(|s| s.as_str()).collect();
|
||||
keys.sort_unstable();
|
||||
let keys = sas
|
||||
.calculate_mac(&keys.join(","), &format!("{}KEY_IDS", &info))
|
||||
.expect("Can't calculate SAS MAC");
|
||||
|
||||
let keys = Base64::parse(
|
||||
sas.calculate_mac(&keys.join(","), &format!("{}KEY_IDS", &info))
|
||||
.expect("Can't calculate SAS MAC"),
|
||||
)
|
||||
.expect("Can't base64-decode SAS MAC");
|
||||
|
||||
match flow_id {
|
||||
FlowId::ToDevice(s) => AnyToDeviceEventContent::KeyVerificationMac(
|
||||
ToDeviceKeyVerificationMacEventContent::new(s.to_string(), mac, keys),
|
||||
ToDeviceKeyVerificationMacEventContent::new(s.clone(), mac, keys),
|
||||
)
|
||||
.into(),
|
||||
FlowId::InRoom(r, e) => (
|
||||
@@ -543,7 +564,9 @@ fn bytes_to_decimal(bytes: Vec<u8>) -> (u16, u16, u16) {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use proptest::prelude::*;
|
||||
use ruma::events::key::verification::start::ToDeviceKeyVerificationStartEventContent;
|
||||
use ruma::{
|
||||
events::key::verification::start::ToDeviceKeyVerificationStartEventContent, serde::Base64,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
use super::{
|
||||
@@ -554,9 +577,9 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn commitment_calculation() {
|
||||
let commitment = "CCQmB4JCdB0FW21FdAnHj/Hu8+W9+Nb0vgwPEnZZQ4g";
|
||||
let commitment = Base64::parse("CCQmB4JCdB0FW21FdAnHj/Hu8+W9+Nb0vgwPEnZZQ4g").unwrap();
|
||||
|
||||
let public_key = "Q/NmNFEUS1fS+YeEmiZkjjblKTitrKOAk7cPEumcMlg";
|
||||
let public_key = Base64::parse("Q/NmNFEUS1fS+YeEmiZkjjblKTitrKOAk7cPEumcMlg").unwrap();
|
||||
let content = json!({
|
||||
"from_device":"XOWLHHFSWM",
|
||||
"transaction_id":"bYxBsirjUJO9osar6ST4i2M2NjrYLA7l",
|
||||
@@ -570,9 +593,9 @@ mod test {
|
||||
let content: ToDeviceKeyVerificationStartEventContent =
|
||||
serde_json::from_value(content).unwrap();
|
||||
let content = StartContent::from(&content);
|
||||
let calculated_commitment = calculate_commitment(public_key, &content);
|
||||
let calculated_commitment = calculate_commitment(&public_key, &content);
|
||||
|
||||
assert_eq!(commitment, &calculated_commitment);
|
||||
assert_eq!(commitment, calculated_commitment);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -18,7 +18,7 @@ use std::time::Instant;
|
||||
|
||||
use ruma::{
|
||||
events::key::verification::{cancel::CancelCode, ShortAuthenticationString},
|
||||
EventId, RoomId, UserId,
|
||||
EventId, RoomId, TransactionId, UserId,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -57,7 +57,7 @@ impl InnerSas {
|
||||
other_device: ReadOnlyDevice,
|
||||
own_identity: Option<ReadOnlyOwnUserIdentity>,
|
||||
other_identity: Option<ReadOnlyUserIdentities>,
|
||||
transaction_id: Option<String>,
|
||||
transaction_id: Option<Box<TransactionId>>,
|
||||
) -> (InnerSas, OutgoingContent) {
|
||||
let sas = SasState::<Created>::new(
|
||||
account,
|
||||
|
||||
@@ -21,14 +21,13 @@ use std::sync::{Arc, Mutex};
|
||||
use std::time::Instant;
|
||||
|
||||
use inner_sas::InnerSas;
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use ruma::{
|
||||
api::client::r0::keys::upload_signatures::Request as SignatureUploadRequest,
|
||||
events::{
|
||||
key::verification::{cancel::CancelCode, ShortAuthenticationString},
|
||||
AnyMessageEventContent, AnyToDeviceEventContent,
|
||||
},
|
||||
DeviceId, EventId, RoomId, UserId,
|
||||
DeviceId, EventId, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use tracing::trace;
|
||||
|
||||
@@ -190,7 +189,7 @@ impl Sas {
|
||||
store: VerificationStore,
|
||||
own_identity: Option<ReadOnlyOwnUserIdentity>,
|
||||
other_identity: Option<ReadOnlyUserIdentities>,
|
||||
transaction_id: Option<String>,
|
||||
transaction_id: Option<Box<TransactionId>>,
|
||||
we_started: bool,
|
||||
request_handle: Option<RequestHandle>,
|
||||
) -> (Sas, OutgoingContent) {
|
||||
@@ -336,7 +335,7 @@ impl Sas {
|
||||
}
|
||||
OwnedAcceptContent::Room(room_id, content) => RoomMessageRequest {
|
||||
room_id,
|
||||
txn_id: Uuid::new_v4(),
|
||||
txn_id: TransactionId::new(),
|
||||
content: AnyMessageEventContent::KeyVerificationAccept(content),
|
||||
}
|
||||
.into(),
|
||||
@@ -371,7 +370,8 @@ impl Sas {
|
||||
.map(|c| match c {
|
||||
OutgoingContent::ToDevice(c) => self.content_to_request(c).into(),
|
||||
OutgoingContent::Room(r, c) => {
|
||||
RoomMessageRequest { room_id: r, txn_id: Uuid::new_v4(), content: c }.into()
|
||||
RoomMessageRequest { room_id: r, txn_id: TransactionId::new(), content: c }
|
||||
.into()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@@ -438,7 +438,7 @@ impl Sas {
|
||||
*guard = sas;
|
||||
content.map(|c| match c {
|
||||
OutgoingContent::Room(room_id, content) => {
|
||||
RoomMessageRequest { room_id, txn_id: Uuid::new_v4(), content }.into()
|
||||
RoomMessageRequest { room_id, txn_id: TransactionId::new(), content }.into()
|
||||
}
|
||||
OutgoingContent::ToDevice(c) => self.content_to_request(c).into(),
|
||||
})
|
||||
|
||||
@@ -19,7 +19,6 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
use olm_rs::sas::OlmSas;
|
||||
use ruma::{
|
||||
events::{
|
||||
@@ -40,7 +39,8 @@ use ruma::{
|
||||
},
|
||||
AnyMessageEventContent, AnyToDeviceEventContent,
|
||||
},
|
||||
DeviceId, EventId, RoomId, UserId,
|
||||
serde::Base64,
|
||||
DeviceId, EventId, RoomId, TransactionId, UserId,
|
||||
};
|
||||
use tracing::info;
|
||||
|
||||
@@ -239,7 +239,7 @@ pub struct Created {
|
||||
/// The initial SAS state if the other side started the SAS verification.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Started {
|
||||
commitment: String,
|
||||
commitment: Base64,
|
||||
pub accepted_protocols: Arc<AcceptedProtocols>,
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ pub struct Started {
|
||||
pub struct Accepted {
|
||||
pub accepted_protocols: Arc<AcceptedProtocols>,
|
||||
start_content: Arc<OwnedStartContent>,
|
||||
commitment: String,
|
||||
commitment: Base64,
|
||||
}
|
||||
|
||||
/// The SAS state we're going to be in after we accepted our
|
||||
@@ -258,7 +258,7 @@ pub struct Accepted {
|
||||
pub struct WeAccepted {
|
||||
we_started: bool,
|
||||
pub accepted_protocols: Arc<AcceptedProtocols>,
|
||||
commitment: String,
|
||||
commitment: Base64,
|
||||
}
|
||||
|
||||
/// The SAS state we're going to be in after we received the public key of the
|
||||
@@ -267,7 +267,7 @@ pub struct WeAccepted {
|
||||
/// From now on we can show the short auth string to the user.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct KeyReceived {
|
||||
their_pubkey: String,
|
||||
their_pubkey: Base64,
|
||||
we_started: bool,
|
||||
pub accepted_protocols: Arc<AcceptedProtocols>,
|
||||
}
|
||||
@@ -286,7 +286,7 @@ pub struct Confirmed {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MacReceived {
|
||||
we_started: bool,
|
||||
their_pubkey: String,
|
||||
their_pubkey: Base64,
|
||||
verified_devices: Arc<[ReadOnlyDevice]>,
|
||||
verified_master_keys: Arc<[ReadOnlyUserIdentities]>,
|
||||
pub accepted_protocols: Arc<AcceptedProtocols>,
|
||||
@@ -375,11 +375,10 @@ impl SasState<Created> {
|
||||
other_device: ReadOnlyDevice,
|
||||
own_identity: Option<ReadOnlyOwnUserIdentity>,
|
||||
other_identity: Option<ReadOnlyUserIdentities>,
|
||||
transaction_id: Option<String>,
|
||||
transaction_id: Option<Box<TransactionId>>,
|
||||
) -> SasState<Created> {
|
||||
let started_from_request = transaction_id.is_some();
|
||||
let flow_id =
|
||||
FlowId::ToDevice(transaction_id.unwrap_or_else(|| Uuid::new_v4().to_string()));
|
||||
let flow_id = FlowId::ToDevice(transaction_id.unwrap_or_else(TransactionId::new));
|
||||
Self::new_helper(
|
||||
flow_id,
|
||||
account,
|
||||
@@ -440,7 +439,7 @@ impl SasState<Created> {
|
||||
FlowId::ToDevice(s) => {
|
||||
OwnedStartContent::ToDevice(ToDeviceKeyVerificationStartEventContent::new(
|
||||
self.device_id().into(),
|
||||
s.to_string(),
|
||||
s.clone(),
|
||||
StartMethod::SasV1(self.state.protocol_definitions.clone()),
|
||||
))
|
||||
}
|
||||
@@ -540,7 +539,8 @@ impl SasState<Started> {
|
||||
if let StartMethod::SasV1(method_content) = content.method() {
|
||||
let sas = OlmSas::new();
|
||||
|
||||
let pubkey = sas.public_key();
|
||||
let pubkey =
|
||||
Base64::parse(sas.public_key()).expect("Couldn't base64-decode public key");
|
||||
let commitment = calculate_commitment(&pubkey, content);
|
||||
|
||||
info!(
|
||||
@@ -602,7 +602,7 @@ impl SasState<Started> {
|
||||
FlowId::ToDevice(s) => {
|
||||
OwnedStartContent::ToDevice(ToDeviceKeyVerificationStartEventContent::new(
|
||||
self.device_id().into(),
|
||||
s.to_string(),
|
||||
s.clone(),
|
||||
StartMethod::SasV1(the_protocol_definitions()),
|
||||
))
|
||||
}
|
||||
@@ -695,7 +695,7 @@ impl SasState<WeAccepted> {
|
||||
|
||||
match self.verification_flow_id.as_ref() {
|
||||
FlowId::ToDevice(s) => {
|
||||
ToDeviceKeyVerificationAcceptEventContent::new(s.to_string(), method).into()
|
||||
ToDeviceKeyVerificationAcceptEventContent::new(s.clone(), method).into()
|
||||
}
|
||||
FlowId::InRoom(r, e) => (
|
||||
r.clone(),
|
||||
@@ -725,7 +725,7 @@ impl SasState<WeAccepted> {
|
||||
self.inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_their_public_key(their_pubkey.clone())
|
||||
.set_their_public_key(their_pubkey.encode())
|
||||
.expect("Can't set public key");
|
||||
|
||||
Ok(SasState {
|
||||
@@ -773,7 +773,7 @@ impl SasState<Accepted> {
|
||||
self.inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_their_public_key(their_pubkey.clone())
|
||||
.set_their_public_key(their_pubkey.encode())
|
||||
.expect("Can't set public key");
|
||||
|
||||
Ok(SasState {
|
||||
@@ -799,15 +799,17 @@ impl SasState<Accepted> {
|
||||
match &*self.verification_flow_id {
|
||||
FlowId::ToDevice(s) => AnyToDeviceEventContent::KeyVerificationKey(
|
||||
ToDeviceKeyVerificationKeyEventContent::new(
|
||||
s.to_string(),
|
||||
self.inner.lock().unwrap().public_key(),
|
||||
s.clone(),
|
||||
Base64::parse(self.inner.lock().unwrap().public_key())
|
||||
.expect("Couldn't base64-decode public key"),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
FlowId::InRoom(r, e) => (
|
||||
r.clone(),
|
||||
AnyMessageEventContent::KeyVerificationKey(KeyVerificationKeyEventContent::new(
|
||||
self.inner.lock().unwrap().public_key(),
|
||||
Base64::parse(self.inner.lock().unwrap().public_key())
|
||||
.expect("Couldn't base64-decode public key"),
|
||||
Relation::new(e.clone()),
|
||||
)),
|
||||
)
|
||||
@@ -825,15 +827,17 @@ impl SasState<KeyReceived> {
|
||||
match &*self.verification_flow_id {
|
||||
FlowId::ToDevice(s) => AnyToDeviceEventContent::KeyVerificationKey(
|
||||
ToDeviceKeyVerificationKeyEventContent::new(
|
||||
s.to_string(),
|
||||
self.inner.lock().unwrap().public_key(),
|
||||
s.clone(),
|
||||
Base64::parse(self.inner.lock().unwrap().public_key())
|
||||
.expect("Couldn't base64-decode public key"),
|
||||
),
|
||||
)
|
||||
.into(),
|
||||
FlowId::InRoom(r, e) => (
|
||||
r.clone(),
|
||||
AnyMessageEventContent::KeyVerificationKey(KeyVerificationKeyEventContent::new(
|
||||
self.inner.lock().unwrap().public_key(),
|
||||
Base64::parse(self.inner.lock().unwrap().public_key())
|
||||
.expect("Couldn't base64-decode public key"),
|
||||
Relation::new(e.clone()),
|
||||
)),
|
||||
)
|
||||
@@ -849,7 +853,7 @@ impl SasState<KeyReceived> {
|
||||
get_emoji(
|
||||
&self.inner.lock().unwrap(),
|
||||
&self.ids,
|
||||
&self.state.their_pubkey,
|
||||
&self.state.their_pubkey.encode(),
|
||||
self.verification_flow_id.as_str(),
|
||||
self.state.we_started,
|
||||
)
|
||||
@@ -863,7 +867,7 @@ impl SasState<KeyReceived> {
|
||||
get_emoji_index(
|
||||
&self.inner.lock().unwrap(),
|
||||
&self.ids,
|
||||
&self.state.their_pubkey,
|
||||
&self.state.their_pubkey.encode(),
|
||||
self.verification_flow_id.as_str(),
|
||||
self.state.we_started,
|
||||
)
|
||||
@@ -877,7 +881,7 @@ impl SasState<KeyReceived> {
|
||||
get_decimal(
|
||||
&self.inner.lock().unwrap(),
|
||||
&self.ids,
|
||||
&self.state.their_pubkey,
|
||||
&self.state.their_pubkey.encode(),
|
||||
self.verification_flow_id.as_str(),
|
||||
self.state.we_started,
|
||||
)
|
||||
@@ -1078,7 +1082,7 @@ impl SasState<MacReceived> {
|
||||
get_emoji(
|
||||
&self.inner.lock().unwrap(),
|
||||
&self.ids,
|
||||
&self.state.their_pubkey,
|
||||
&self.state.their_pubkey.encode(),
|
||||
self.verification_flow_id.as_str(),
|
||||
self.state.we_started,
|
||||
)
|
||||
@@ -1092,7 +1096,7 @@ impl SasState<MacReceived> {
|
||||
get_emoji_index(
|
||||
&self.inner.lock().unwrap(),
|
||||
&self.ids,
|
||||
&self.state.their_pubkey,
|
||||
&self.state.their_pubkey.encode(),
|
||||
self.verification_flow_id.as_str(),
|
||||
self.state.we_started,
|
||||
)
|
||||
@@ -1106,7 +1110,7 @@ impl SasState<MacReceived> {
|
||||
get_decimal(
|
||||
&self.inner.lock().unwrap(),
|
||||
&self.ids,
|
||||
&self.state.their_pubkey,
|
||||
&self.state.their_pubkey.encode(),
|
||||
self.verification_flow_id.as_str(),
|
||||
self.state.we_started,
|
||||
)
|
||||
@@ -1205,13 +1209,17 @@ mod test {
|
||||
start::{StartMethod, ToDeviceKeyVerificationStartEventContent},
|
||||
ShortAuthenticationString,
|
||||
},
|
||||
serde::Base64,
|
||||
user_id, DeviceId, UserId,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
use super::{Accepted, Created, SasState, Started, WeAccepted};
|
||||
use crate::{
|
||||
verification::event_enums::{AcceptContent, KeyContent, MacContent, StartContent},
|
||||
verification::{
|
||||
event_enums::{AcceptContent, KeyContent, MacContent, StartContent},
|
||||
FlowId,
|
||||
},
|
||||
ReadOnlyAccount, ReadOnlyDevice,
|
||||
};
|
||||
|
||||
@@ -1342,8 +1350,8 @@ mod test {
|
||||
let mut method = content.method_mut();
|
||||
|
||||
match &mut method {
|
||||
AcceptMethod::SasV1(ref mut c) => {
|
||||
c.commitment = "".to_string();
|
||||
AcceptMethod::SasV1(c) => {
|
||||
c.commitment = Base64::empty();
|
||||
}
|
||||
_ => panic!("Unknown accept event content"),
|
||||
}
|
||||
@@ -1464,7 +1472,7 @@ mod test {
|
||||
alice_device,
|
||||
None,
|
||||
None,
|
||||
flow_id.into(),
|
||||
FlowId::ToDevice(flow_id.into()),
|
||||
&content,
|
||||
false,
|
||||
)
|
||||
|
||||
@@ -23,5 +23,5 @@ serde_json = "1.0.64"
|
||||
|
||||
[dependencies.ruma]
|
||||
git = "https://github.com/ruma/ruma/"
|
||||
rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d"
|
||||
rev = "37095f88553b311e7a70adaaabe39976fb8ff71c"
|
||||
features = ["client-api-c"]
|
||||
|
||||
@@ -76,7 +76,7 @@ default_features = false
|
||||
|
||||
[dependencies.ruma]
|
||||
git = "https://github.com/ruma/ruma/"
|
||||
rev = "fdbc4d6d1dd273c8a6ac95b329943ed8c68df70d"
|
||||
rev = "37095f88553b311e7a70adaaabe39976fb8ff71c"
|
||||
features = ["client-api-c", "compat", "unstable-pre-spec"]
|
||||
|
||||
[dependencies.tokio-stream]
|
||||
|
||||
@@ -23,7 +23,8 @@ async fn on_room_message(event: SyncRoomMessageEvent, room: Room) {
|
||||
println!("sending");
|
||||
|
||||
// send our message to the room we found the "!party" command in
|
||||
// the last parameter is an optional Uuid which we don't care about.
|
||||
// the last parameter is an optional transaction id which we don't
|
||||
// care about.
|
||||
room.send(content, None).await.unwrap();
|
||||
|
||||
println!("message sent");
|
||||
|
||||
@@ -86,8 +86,9 @@ async fn login(
|
||||
for event in response.to_device.events.iter().filter_map(|e| e.deserialize().ok()) {
|
||||
match event {
|
||||
AnyToDeviceEvent::KeyVerificationStart(e) => {
|
||||
if let Some(Verification::SasV1(sas)) =
|
||||
client.get_verification(&e.sender, &e.content.transaction_id).await
|
||||
if let Some(Verification::SasV1(sas)) = client
|
||||
.get_verification(&e.sender, e.content.transaction_id.as_str())
|
||||
.await
|
||||
{
|
||||
println!(
|
||||
"Starting verification with {} {}",
|
||||
@@ -100,16 +101,18 @@ async fn login(
|
||||
}
|
||||
|
||||
AnyToDeviceEvent::KeyVerificationKey(e) => {
|
||||
if let Some(Verification::SasV1(sas)) =
|
||||
client.get_verification(&e.sender, &e.content.transaction_id).await
|
||||
if let Some(Verification::SasV1(sas)) = client
|
||||
.get_verification(&e.sender, e.content.transaction_id.as_str())
|
||||
.await
|
||||
{
|
||||
tokio::spawn(wait_for_confirmation((*client).clone(), sas));
|
||||
}
|
||||
}
|
||||
|
||||
AnyToDeviceEvent::KeyVerificationMac(e) => {
|
||||
if let Some(Verification::SasV1(sas)) =
|
||||
client.get_verification(&e.sender, &e.content.transaction_id).await
|
||||
if let Some(Verification::SasV1(sas)) = client
|
||||
.get_verification(&e.sender, e.content.transaction_id.as_str())
|
||||
.await
|
||||
{
|
||||
if sas.is_done() {
|
||||
print_result(&sas);
|
||||
|
||||
@@ -45,7 +45,8 @@ impl WasmBot {
|
||||
|
||||
if let Some(room) = self.0.get_joined_room(&room_id) {
|
||||
// send our message to the room we found the "!party" command in
|
||||
// the last parameter is an optional Uuid which we don't care about.
|
||||
// the last parameter is an optional transaction id which we
|
||||
// don't care about.
|
||||
room.send(content, None).await.unwrap();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ use matrix_sdk_common::{
|
||||
locks::{Mutex, RwLock, RwLockReadGuard},
|
||||
};
|
||||
use mime::{self, Mime};
|
||||
#[cfg(feature = "encryption")]
|
||||
use ruma::TransactionId;
|
||||
use ruma::{
|
||||
api::{
|
||||
client::{
|
||||
@@ -285,7 +287,7 @@ impl Client {
|
||||
#[cfg(feature = "encryption")]
|
||||
pub(crate) async fn mark_request_as_sent(
|
||||
&self,
|
||||
request_id: &matrix_sdk_base::uuid::Uuid,
|
||||
request_id: &TransactionId,
|
||||
response: impl Into<matrix_sdk_base::crypto::IncomingResponse<'_>>,
|
||||
) -> Result<(), matrix_sdk_base::Error> {
|
||||
self.base_client().mark_request_as_sent(request_id, response).await
|
||||
@@ -2400,7 +2402,7 @@ pub(crate) mod test {
|
||||
},
|
||||
AnySyncStateEvent, EventType,
|
||||
},
|
||||
mxc_uri, room_id, thirdparty, uint, user_id, UserId,
|
||||
mxc_uri, room_id, thirdparty, uint, user_id, TransactionId, UserId,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
@@ -3154,8 +3156,6 @@ pub(crate) mod test {
|
||||
|
||||
#[tokio::test]
|
||||
async fn room_message_send() {
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
|
||||
let client = logged_in_client().await;
|
||||
|
||||
let _m = mock("PUT", Matcher::Regex(r"^/_matrix/client/r0/rooms/.*/send/".to_string()))
|
||||
@@ -3177,8 +3177,8 @@ pub(crate) mod test {
|
||||
let room = client.get_joined_room(room_id!("!SVkFJHzfwvuaIEawgC:localhost")).unwrap();
|
||||
|
||||
let content = RoomMessageEventContent::text_plain("Hello world");
|
||||
let txn_id = Uuid::new_v4();
|
||||
let response = room.send(content, Some(txn_id)).await.unwrap();
|
||||
let txn_id = TransactionId::new();
|
||||
let response = room.send(content, Some(&txn_id)).await.unwrap();
|
||||
|
||||
assert_eq!(event_id!("$h29iv0s8:example.com"), response.event_id)
|
||||
}
|
||||
@@ -3226,8 +3226,6 @@ pub(crate) mod test {
|
||||
|
||||
#[tokio::test]
|
||||
async fn room_redact() {
|
||||
use matrix_sdk_common::uuid::Uuid;
|
||||
|
||||
let client = logged_in_client().await;
|
||||
|
||||
let _m =
|
||||
@@ -3251,7 +3249,7 @@ pub(crate) mod test {
|
||||
|
||||
let event_id = event_id!("$xxxxxxxx:example.com");
|
||||
|
||||
let txn_id = Uuid::new_v4();
|
||||
let txn_id = TransactionId::new();
|
||||
let reason = Some("Indecent material");
|
||||
let response = room.redact(event_id, reason, Some(txn_id)).await.unwrap();
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ use matrix_sdk_base::{
|
||||
},
|
||||
deserialized_responses::RoomEvent,
|
||||
};
|
||||
use matrix_sdk_common::{instant::Duration, uuid::Uuid};
|
||||
use matrix_sdk_common::instant::Duration;
|
||||
use ruma::{
|
||||
api::client::r0::{
|
||||
backup::add_backup_keys::Response as KeysBackupResponse,
|
||||
@@ -277,7 +277,7 @@ use ruma::{
|
||||
assign,
|
||||
events::{AnyMessageEvent, AnyRoomEvent, AnySyncMessageEvent, EventType},
|
||||
serde::Raw,
|
||||
DeviceId, UserId,
|
||||
DeviceId, TransactionId, UserId,
|
||||
};
|
||||
use tracing::{debug, instrument, trace, warn};
|
||||
|
||||
@@ -717,7 +717,7 @@ impl Client {
|
||||
#[instrument]
|
||||
pub(crate) async fn keys_query(
|
||||
&self,
|
||||
request_id: &Uuid,
|
||||
request_id: &TransactionId,
|
||||
device_keys: BTreeMap<Box<UserId>, Vec<Box<DeviceId>>>,
|
||||
) -> Result<get_keys::Response> {
|
||||
let request = assign!(get_keys::Request::new(), { device_keys });
|
||||
@@ -879,7 +879,7 @@ impl Client {
|
||||
#[instrument]
|
||||
pub(crate) async fn keys_upload(
|
||||
&self,
|
||||
request_id: &Uuid,
|
||||
request_id: &TransactionId,
|
||||
request: &upload_keys::Request,
|
||||
) -> Result<upload_keys::Response> {
|
||||
debug!(
|
||||
@@ -900,7 +900,7 @@ impl Client {
|
||||
request: &RoomMessageRequest,
|
||||
) -> Result<send_message_event::Response> {
|
||||
let content = request.content.clone();
|
||||
let txn_id = request.txn_id;
|
||||
let txn_id = &request.txn_id;
|
||||
let room_id = &request.room_id;
|
||||
|
||||
self.get_joined_room(room_id)
|
||||
@@ -914,11 +914,9 @@ impl Client {
|
||||
&self,
|
||||
request: &ToDeviceRequest,
|
||||
) -> HttpResult<ToDeviceResponse> {
|
||||
let txn_id_string = request.txn_id_string();
|
||||
|
||||
let request = RumaToDeviceRequest::new_raw(
|
||||
request.event_type.as_str(),
|
||||
&txn_id_string,
|
||||
&request.txn_id,
|
||||
request.messages.clone(),
|
||||
);
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ impl Deref for Common {
|
||||
#[derive(Debug)]
|
||||
pub struct Messages {
|
||||
/// The token the pagination starts from.
|
||||
pub start: Option<String>,
|
||||
pub start: String,
|
||||
|
||||
/// The token the pagination ends at.
|
||||
pub end: Option<String>,
|
||||
|
||||
@@ -2,12 +2,9 @@
|
||||
use std::sync::Arc;
|
||||
use std::{io::Read, ops::Deref};
|
||||
|
||||
use matrix_sdk_common::instant::{Duration, Instant};
|
||||
#[cfg(feature = "encryption")]
|
||||
use matrix_sdk_common::locks::Mutex;
|
||||
use matrix_sdk_common::{
|
||||
instant::{Duration, Instant},
|
||||
uuid::Uuid,
|
||||
};
|
||||
use mime::{self, Mime};
|
||||
use ruma::{
|
||||
api::client::r0::{
|
||||
@@ -27,7 +24,7 @@ use ruma::{
|
||||
events::{room::message::RoomMessageEventContent, MessageEventContent, StateEventContent},
|
||||
receipt::ReceiptType,
|
||||
serde::Raw,
|
||||
EventId, UserId,
|
||||
EventId, TransactionId, UserId,
|
||||
};
|
||||
use serde_json::Value;
|
||||
use tracing::debug;
|
||||
@@ -406,15 +403,12 @@ impl Joined {
|
||||
/// # use matrix_sdk::ruma::room_id;
|
||||
/// # use std::convert::TryFrom;
|
||||
/// # use serde::{Deserialize, Serialize};
|
||||
/// use matrix_sdk::{
|
||||
/// uuid::Uuid,
|
||||
/// ruma::{
|
||||
/// events::{
|
||||
/// macros::EventContent,
|
||||
/// room::message::{RoomMessageEventContent, TextMessageEventContent},
|
||||
/// },
|
||||
/// uint, MilliSecondsSinceUnixEpoch,
|
||||
/// use matrix_sdk::ruma::{
|
||||
/// events::{
|
||||
/// macros::EventContent,
|
||||
/// room::message::{RoomMessageEventContent, TextMessageEventContent},
|
||||
/// },
|
||||
/// uint, MilliSecondsSinceUnixEpoch, TransactionId,
|
||||
/// };
|
||||
/// # block_on(async {
|
||||
/// # let homeserver = Url::parse("http://localhost:8080")?;
|
||||
@@ -422,10 +416,10 @@ impl Joined {
|
||||
/// # let room_id = room_id!("!test:localhost");
|
||||
///
|
||||
/// let content = RoomMessageEventContent::text_plain("Hello world");
|
||||
/// let txn_id = Uuid::new_v4();
|
||||
/// let txn_id = TransactionId::new();
|
||||
///
|
||||
/// if let Some(room) = client.get_joined_room(&room_id) {
|
||||
/// room.send(content, Some(txn_id)).await?;
|
||||
/// room.send(content, Some(&txn_id)).await?;
|
||||
/// }
|
||||
///
|
||||
/// // Custom events work too:
|
||||
@@ -445,10 +439,10 @@ impl Joined {
|
||||
/// MilliSecondsSinceUnixEpoch(now.0 + uint!(30_000))
|
||||
/// },
|
||||
/// };
|
||||
/// let txn_id = Uuid::new_v4();
|
||||
/// let txn_id = TransactionId::new();
|
||||
///
|
||||
/// if let Some(room) = client.get_joined_room(&room_id) {
|
||||
/// room.send(content, Some(txn_id)).await?;
|
||||
/// room.send(content, Some(&txn_id)).await?;
|
||||
/// }
|
||||
/// # Result::<_, matrix_sdk::Error>::Ok(()) });
|
||||
/// ```
|
||||
@@ -459,7 +453,7 @@ impl Joined {
|
||||
pub async fn send(
|
||||
&self,
|
||||
content: impl MessageEventContent,
|
||||
txn_id: Option<Uuid>,
|
||||
txn_id: Option<&TransactionId>,
|
||||
) -> Result<send_message_event::Response> {
|
||||
let event_type = content.event_type();
|
||||
let content = serde_json::to_value(&content)?;
|
||||
@@ -528,9 +522,9 @@ impl Joined {
|
||||
&self,
|
||||
content: Value,
|
||||
event_type: &str,
|
||||
txn_id: Option<Uuid>,
|
||||
txn_id: Option<&TransactionId>,
|
||||
) -> Result<send_message_event::Response> {
|
||||
let txn_id = txn_id.unwrap_or_else(Uuid::new_v4).to_string();
|
||||
let txn_id: Box<TransactionId> = txn_id.map_or_else(TransactionId::new, ToOwned::to_owned);
|
||||
|
||||
#[cfg(not(feature = "encryption"))]
|
||||
let content = {
|
||||
@@ -604,7 +598,7 @@ impl Joined {
|
||||
/// * `reader` - A `Reader` that will be used to fetch the raw bytes of the
|
||||
/// media.
|
||||
///
|
||||
/// * `txn_id` - A unique `Uuid` that can be attached to a `MessageEvent`
|
||||
/// * `txn_id` - A unique ID that can be attached to a `MessageEvent`
|
||||
/// held in its unsigned field as `transaction_id`. If not given one is
|
||||
/// created for the message.
|
||||
///
|
||||
@@ -638,7 +632,7 @@ impl Joined {
|
||||
body: &str,
|
||||
content_type: &Mime,
|
||||
reader: &mut R,
|
||||
txn_id: Option<Uuid>,
|
||||
txn_id: Option<&TransactionId>,
|
||||
) -> Result<send_message_event::Response> {
|
||||
#[cfg(feature = "encryption")]
|
||||
let content = if self.is_encrypted() {
|
||||
@@ -774,7 +768,7 @@ impl Joined {
|
||||
///
|
||||
/// * `reason` - The reason for the event being redacted.
|
||||
///
|
||||
/// * `txn_id` - A unique [`Uuid`] that can be attached to this event as
|
||||
/// * `txn_id` - A unique ID that can be attached to this event as
|
||||
/// its transaction ID. If not given one is created for the message.
|
||||
///
|
||||
/// # Example
|
||||
@@ -797,9 +791,9 @@ impl Joined {
|
||||
&self,
|
||||
event_id: &EventId,
|
||||
reason: Option<&str>,
|
||||
txn_id: Option<Uuid>,
|
||||
txn_id: Option<Box<TransactionId>>,
|
||||
) -> HttpResult<redact_event::Response> {
|
||||
let txn_id = txn_id.unwrap_or_else(Uuid::new_v4).to_string();
|
||||
let txn_id = txn_id.unwrap_or_else(TransactionId::new);
|
||||
let request =
|
||||
assign!(redact_event::Request::new(self.inner.room_id(), event_id, &txn_id), {
|
||||
reason
|
||||
|
||||
Reference in New Issue
Block a user