Merge branch 'crypto-improvements' into new-state-store
This commit is contained in:
commit
1733808221
13 changed files with 145 additions and 106 deletions
|
@ -2064,6 +2064,10 @@ impl Client {
|
|||
/// * `passphrase` - The passphrase that should be used to decrypt the
|
||||
/// exported room keys.
|
||||
///
|
||||
/// Returns a tuple of numbers that represent the number of sessions that
|
||||
/// were imported and the total number of sessions that were found in the
|
||||
/// key export.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This method will panic if it isn't run on a Tokio runtime.
|
||||
|
@ -2093,7 +2097,7 @@ impl Client {
|
|||
feature = "docs",
|
||||
doc(cfg(all(encryption, not(target_arch = "wasm32"))))
|
||||
)]
|
||||
pub async fn import_keys(&self, path: PathBuf, passphrase: &str) -> Result<usize> {
|
||||
pub async fn import_keys(&self, path: PathBuf, passphrase: &str) -> Result<(usize, usize)> {
|
||||
let olm = self
|
||||
.base_client
|
||||
.olm_machine()
|
||||
|
|
|
@ -20,7 +20,7 @@ js_int = "0.1.9"
|
|||
|
||||
[dependencies.ruma]
|
||||
version = "0.0.1"
|
||||
git = "https://github.com/ruma/ruma"
|
||||
path = "/home/poljar/werk/priv/ruma/ruma"
|
||||
rev = "48d1c9747561686e1c5627405780f6de01ee17b1"
|
||||
features = ["client-api", "unstable-pre-spec"]
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ pub use ruma::{
|
|||
error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError},
|
||||
AuthScheme, EndpointError, OutgoingRequest,
|
||||
},
|
||||
directory, encryption, events, identifiers, presence, push, thirdparty, Outgoing, Raw,
|
||||
directory, encryption, events, identifiers, presence, push,
|
||||
serde::Raw,
|
||||
thirdparty, Outgoing,
|
||||
};
|
||||
|
||||
pub use uuid;
|
||||
|
|
|
@ -314,7 +314,7 @@ mod test {
|
|||
let decrypted = decrypt_key_export(Cursor::new(encrypted), "1234").unwrap();
|
||||
|
||||
assert_eq!(export, decrypted);
|
||||
assert_eq!(machine.import_keys(decrypted).await.unwrap(), 0);
|
||||
assert_eq!(machine.import_keys(decrypted).await.unwrap(), (0, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -27,8 +27,8 @@ use matrix_sdk_common::{
|
|||
api::r0::keys::SignedKey,
|
||||
encryption::DeviceKeys,
|
||||
events::{
|
||||
forwarded_room_key::ForwardedRoomKeyEventContent, room::encrypted::EncryptedEventContent,
|
||||
EventType,
|
||||
forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
|
||||
room::encrypted::EncryptedEventContent, EventType,
|
||||
},
|
||||
identifiers::{
|
||||
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, UserId,
|
||||
|
@ -158,7 +158,7 @@ impl Device {
|
|||
) -> OlmResult<(Session, EncryptedEventContent)> {
|
||||
let export = session.export().await;
|
||||
|
||||
let content: ForwardedRoomKeyEventContent = if let Ok(c) = export.try_into() {
|
||||
let content: ForwardedRoomKeyToDeviceEventContent = if let Ok(c) = export.try_into() {
|
||||
c
|
||||
} else {
|
||||
// TODO remove this panic.
|
||||
|
|
|
@ -30,8 +30,8 @@ use tracing::{error, info, trace, warn};
|
|||
use matrix_sdk_common::{
|
||||
api::r0::to_device::DeviceIdOrAllDevices,
|
||||
events::{
|
||||
forwarded_room_key::ForwardedRoomKeyEventContent,
|
||||
room_key_request::{Action, RequestedKeyInfo, RoomKeyRequestEventContent},
|
||||
forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
|
||||
room_key_request::{Action, RequestedKeyInfo, RoomKeyRequestToDeviceEventContent},
|
||||
AnyToDeviceEvent, EventType, ToDeviceEvent,
|
||||
},
|
||||
identifiers::{DeviceId, DeviceIdBox, EventEncryptionAlgorithm, RoomId, UserId},
|
||||
|
@ -67,8 +67,9 @@ pub enum KeyshareDecision {
|
|||
/// device that requested the key doesn't share an Olm session with us.
|
||||
#[derive(Debug, Clone)]
|
||||
struct WaitQueue {
|
||||
requests_waiting_for_session:
|
||||
Arc<DashMap<(UserId, DeviceIdBox, String), ToDeviceEvent<RoomKeyRequestEventContent>>>,
|
||||
requests_waiting_for_session: Arc<
|
||||
DashMap<(UserId, DeviceIdBox, String), ToDeviceEvent<RoomKeyRequestToDeviceEventContent>>,
|
||||
>,
|
||||
requests_ids_waiting: Arc<DashMap<(UserId, DeviceIdBox), DashSet<String>>>,
|
||||
}
|
||||
|
||||
|
@ -85,7 +86,7 @@ impl WaitQueue {
|
|||
self.requests_ids_waiting.is_empty() && self.requests_waiting_for_session.is_empty()
|
||||
}
|
||||
|
||||
fn insert(&self, device: &Device, event: &ToDeviceEvent<RoomKeyRequestEventContent>) {
|
||||
fn insert(&self, device: &Device, event: &ToDeviceEvent<RoomKeyRequestToDeviceEventContent>) {
|
||||
let key = (
|
||||
device.user_id().to_owned(),
|
||||
device.device_id().into(),
|
||||
|
@ -106,7 +107,7 @@ impl WaitQueue {
|
|||
device_id: &DeviceId,
|
||||
) -> Vec<(
|
||||
(UserId, DeviceIdBox, String),
|
||||
ToDeviceEvent<RoomKeyRequestEventContent>,
|
||||
ToDeviceEvent<RoomKeyRequestToDeviceEventContent>,
|
||||
)> {
|
||||
self.requests_ids_waiting
|
||||
.remove(&(user_id.to_owned(), device_id.into()))
|
||||
|
@ -130,8 +131,9 @@ pub(crate) struct KeyRequestMachine {
|
|||
store: Store,
|
||||
outbound_group_sessions: Arc<DashMap<RoomId, OutboundGroupSession>>,
|
||||
outgoing_to_device_requests: Arc<DashMap<Uuid, OutgoingRequest>>,
|
||||
incoming_key_requests:
|
||||
Arc<DashMap<(UserId, DeviceIdBox, String), ToDeviceEvent<RoomKeyRequestEventContent>>>,
|
||||
incoming_key_requests: Arc<
|
||||
DashMap<(UserId, DeviceIdBox, String), ToDeviceEvent<RoomKeyRequestToDeviceEventContent>>,
|
||||
>,
|
||||
wait_queue: WaitQueue,
|
||||
users_for_key_claim: Arc<DashMap<UserId, DashSet<DeviceIdBox>>>,
|
||||
}
|
||||
|
@ -156,7 +158,7 @@ impl Encode for RequestedKeyInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl Encode for ForwardedRoomKeyEventContent {
|
||||
impl Encode for ForwardedRoomKeyToDeviceEventContent {
|
||||
fn encode(&self) -> String {
|
||||
format!(
|
||||
"{}|{}|{}|{}",
|
||||
|
@ -168,7 +170,7 @@ impl Encode for ForwardedRoomKeyEventContent {
|
|||
fn wrap_key_request_content(
|
||||
recipient: UserId,
|
||||
id: Uuid,
|
||||
content: &RoomKeyRequestEventContent,
|
||||
content: &RoomKeyRequestToDeviceEventContent,
|
||||
) -> Result<OutgoingRequest, serde_json::Error> {
|
||||
let mut messages = BTreeMap::new();
|
||||
|
||||
|
@ -224,7 +226,10 @@ impl KeyRequestMachine {
|
|||
}
|
||||
|
||||
/// Receive a room key request event.
|
||||
pub fn receive_incoming_key_request(&self, event: &ToDeviceEvent<RoomKeyRequestEventContent>) {
|
||||
pub fn receive_incoming_key_request(
|
||||
&self,
|
||||
event: &ToDeviceEvent<RoomKeyRequestToDeviceEventContent>,
|
||||
) {
|
||||
let sender = event.sender.clone();
|
||||
let device_id = event.content.requesting_device_id.clone();
|
||||
let request_id = event.content.request_id.clone();
|
||||
|
@ -255,7 +260,7 @@ impl KeyRequestMachine {
|
|||
fn handle_key_share_without_session(
|
||||
&self,
|
||||
device: Device,
|
||||
event: &ToDeviceEvent<RoomKeyRequestEventContent>,
|
||||
event: &ToDeviceEvent<RoomKeyRequestToDeviceEventContent>,
|
||||
) {
|
||||
self.users_for_key_claim
|
||||
.entry(device.user_id().to_owned())
|
||||
|
@ -295,7 +300,7 @@ impl KeyRequestMachine {
|
|||
/// Handle a single incoming key request.
|
||||
async fn handle_key_request(
|
||||
&self,
|
||||
event: &ToDeviceEvent<RoomKeyRequestEventContent>,
|
||||
event: &ToDeviceEvent<RoomKeyRequestToDeviceEventContent>,
|
||||
) -> OlmResult<Option<Session>> {
|
||||
let key_info = match &event.content.action {
|
||||
Action::Request => {
|
||||
|
@ -505,7 +510,7 @@ impl KeyRequestMachine {
|
|||
|
||||
let id = Uuid::new_v4();
|
||||
|
||||
let content = RoomKeyRequestEventContent {
|
||||
let content = RoomKeyRequestToDeviceEventContent {
|
||||
action: Action::Request,
|
||||
request_id: id.to_string(),
|
||||
requesting_device_id: (&*self.device_id).clone(),
|
||||
|
@ -546,7 +551,7 @@ impl KeyRequestMachine {
|
|||
/// Get an outgoing key info that matches the forwarded room key content.
|
||||
async fn get_key_info(
|
||||
&self,
|
||||
content: &ForwardedRoomKeyEventContent,
|
||||
content: &ForwardedRoomKeyToDeviceEventContent,
|
||||
) -> Result<Option<OugoingKeyInfo>, CryptoStoreError> {
|
||||
let id: Option<Uuid> = self.store.get_object(&content.encode()).await?;
|
||||
|
||||
|
@ -597,7 +602,7 @@ impl KeyRequestMachine {
|
|||
// can delete it in one transaction.
|
||||
self.delete_key_info(&key_info).await?;
|
||||
|
||||
let content = RoomKeyRequestEventContent {
|
||||
let content = RoomKeyRequestToDeviceEventContent {
|
||||
action: Action::CancelRequest,
|
||||
request_id: key_info.request_id.to_string(),
|
||||
requesting_device_id: (&*self.device_id).clone(),
|
||||
|
@ -617,7 +622,7 @@ impl KeyRequestMachine {
|
|||
pub async fn receive_forwarded_room_key(
|
||||
&self,
|
||||
sender_key: &str,
|
||||
event: &mut ToDeviceEvent<ForwardedRoomKeyEventContent>,
|
||||
event: &mut ToDeviceEvent<ForwardedRoomKeyToDeviceEventContent>,
|
||||
) -> Result<(Option<Raw<AnyToDeviceEvent>>, Option<InboundGroupSession>), CryptoStoreError>
|
||||
{
|
||||
let key_info = self.get_key_info(&event.content).await?;
|
||||
|
@ -637,8 +642,8 @@ impl KeyRequestMachine {
|
|||
// If we have a previous session, check if we have a better version
|
||||
// and store the new one if so.
|
||||
let session = if let Some(old_session) = old_session {
|
||||
let first_old_index = old_session.first_known_index().await;
|
||||
let first_index = session.first_known_index().await;
|
||||
let first_old_index = old_session.first_known_index();
|
||||
let first_index = session.first_known_index();
|
||||
|
||||
if first_old_index > first_index {
|
||||
self.mark_as_done(info).await?;
|
||||
|
@ -672,9 +677,9 @@ mod test {
|
|||
use matrix_sdk_common::{
|
||||
api::r0::to_device::DeviceIdOrAllDevices,
|
||||
events::{
|
||||
forwarded_room_key::ForwardedRoomKeyEventContent,
|
||||
room::encrypted::EncryptedEventContent, room_key_request::RoomKeyRequestEventContent,
|
||||
AnyToDeviceEvent, ToDeviceEvent,
|
||||
forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
|
||||
room::encrypted::EncryptedEventContent,
|
||||
room_key_request::RoomKeyRequestToDeviceEventContent, AnyToDeviceEvent, ToDeviceEvent,
|
||||
},
|
||||
identifiers::{room_id, user_id, DeviceIdBox, RoomId, UserId},
|
||||
locks::Mutex,
|
||||
|
@ -829,7 +834,7 @@ mod test {
|
|||
|
||||
let export = session.export_at_index(10).await.unwrap();
|
||||
|
||||
let content: ForwardedRoomKeyEventContent = export.try_into().unwrap();
|
||||
let content: ForwardedRoomKeyToDeviceEventContent = export.try_into().unwrap();
|
||||
|
||||
let mut event = ToDeviceEvent {
|
||||
sender: alice_id(),
|
||||
|
@ -855,7 +860,7 @@ mod test {
|
|||
.unwrap();
|
||||
let first_session = first_session.unwrap();
|
||||
|
||||
assert_eq!(first_session.first_known_index().await, 10);
|
||||
assert_eq!(first_session.first_known_index(), 10);
|
||||
|
||||
machine
|
||||
.store
|
||||
|
@ -886,7 +891,7 @@ mod test {
|
|||
|
||||
let export = session.export_at_index(15).await.unwrap();
|
||||
|
||||
let content: ForwardedRoomKeyEventContent = export.try_into().unwrap();
|
||||
let content: ForwardedRoomKeyToDeviceEventContent = export.try_into().unwrap();
|
||||
|
||||
let mut event = ToDeviceEvent {
|
||||
sender: alice_id(),
|
||||
|
@ -902,7 +907,7 @@ mod test {
|
|||
|
||||
let export = session.export_at_index(0).await.unwrap();
|
||||
|
||||
let content: ForwardedRoomKeyEventContent = export.try_into().unwrap();
|
||||
let content: ForwardedRoomKeyToDeviceEventContent = export.try_into().unwrap();
|
||||
|
||||
let mut event = ToDeviceEvent {
|
||||
sender: alice_id(),
|
||||
|
@ -914,7 +919,7 @@ mod test {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(second_session.unwrap().first_known_index().await, 0);
|
||||
assert_eq!(second_session.unwrap().first_known_index(), 0);
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
|
@ -1073,7 +1078,8 @@ mod test {
|
|||
.unwrap()
|
||||
.get(&DeviceIdOrAllDevices::AllDevices)
|
||||
.unwrap();
|
||||
let content: RoomKeyRequestEventContent = serde_json::from_str(content.get()).unwrap();
|
||||
let content: RoomKeyRequestToDeviceEventContent =
|
||||
serde_json::from_str(content.get()).unwrap();
|
||||
|
||||
drop(request);
|
||||
alice_machine
|
||||
|
@ -1241,7 +1247,8 @@ mod test {
|
|||
.unwrap()
|
||||
.get(&DeviceIdOrAllDevices::AllDevices)
|
||||
.unwrap();
|
||||
let content: RoomKeyRequestEventContent = serde_json::from_str(content.get()).unwrap();
|
||||
let content: RoomKeyRequestToDeviceEventContent =
|
||||
serde_json::from_str(content.get()).unwrap();
|
||||
|
||||
drop(request);
|
||||
alice_machine
|
||||
|
|
|
@ -1012,7 +1012,9 @@ impl OlmMachine {
|
|||
/// imported into our store. If we already have a better version of a key
|
||||
/// the key will *not* be imported.
|
||||
///
|
||||
/// Returns the number of sessions that were imported to the store.
|
||||
/// Returns a tuple of numbers that represent the number of sessions that
|
||||
/// were imported and the total number of sessions that were found in the
|
||||
/// key export.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```no_run
|
||||
|
@ -1028,32 +1030,47 @@ impl OlmMachine {
|
|||
/// machine.import_keys(exported_keys).await.unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn import_keys(&self, mut exported_keys: Vec<ExportedRoomKey>) -> StoreResult<usize> {
|
||||
pub async fn import_keys(
|
||||
&self,
|
||||
exported_keys: Vec<ExportedRoomKey>,
|
||||
) -> StoreResult<(usize, usize)> {
|
||||
struct ShallowSessions {
|
||||
inner: BTreeMap<Arc<RoomId>, u32>,
|
||||
}
|
||||
|
||||
impl ShallowSessions {
|
||||
fn has_better_session(&self, session: &InboundGroupSession) -> bool {
|
||||
self.inner
|
||||
.get(&session.room_id)
|
||||
.map(|existing| existing <= &session.first_known_index())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
let mut sessions = Vec::new();
|
||||
|
||||
for key in exported_keys.drain(..) {
|
||||
let existing_sessions = ShallowSessions {
|
||||
inner: self
|
||||
.store
|
||||
.get_inbound_group_sessions()
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|s| {
|
||||
let index = s.first_known_index();
|
||||
(s.room_id, index)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let total_sessions = exported_keys.len();
|
||||
|
||||
for key in exported_keys.into_iter() {
|
||||
let session = InboundGroupSession::from_export(key)?;
|
||||
|
||||
// Only import the session if we didn't have this session or if it's
|
||||
// a better version of the same session, that is the first known
|
||||
// index is lower.
|
||||
// TODO load all sessions so we don't do a thousand small loads.
|
||||
if let Some(existing_session) = self
|
||||
.store
|
||||
.get_inbound_group_session(
|
||||
&session.room_id,
|
||||
&session.sender_key,
|
||||
session.session_id(),
|
||||
)
|
||||
.await?
|
||||
{
|
||||
let first_index = session.first_known_index().await;
|
||||
let existing_index = existing_session.first_known_index().await;
|
||||
|
||||
if first_index < existing_index {
|
||||
sessions.push(session)
|
||||
}
|
||||
} else {
|
||||
if !existing_sessions.has_better_session(&session) {
|
||||
sessions.push(session)
|
||||
}
|
||||
}
|
||||
|
@ -1072,7 +1089,7 @@ impl OlmMachine {
|
|||
num_sessions
|
||||
);
|
||||
|
||||
Ok(num_sessions)
|
||||
Ok((num_sessions, total_sessions))
|
||||
}
|
||||
|
||||
/// Export the keys that match the given predicate.
|
||||
|
|
|
@ -34,8 +34,8 @@ pub use olm_rs::{
|
|||
|
||||
use matrix_sdk_common::{
|
||||
events::{
|
||||
forwarded_room_key::ForwardedRoomKeyEventContent, room::encrypted::EncryptedEventContent,
|
||||
AnySyncRoomEvent, SyncMessageEvent,
|
||||
forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
|
||||
room::encrypted::EncryptedEventContent, AnySyncRoomEvent, SyncMessageEvent,
|
||||
},
|
||||
identifiers::{DeviceKeyAlgorithm, EventEncryptionAlgorithm, RoomId},
|
||||
locks::Mutex,
|
||||
|
@ -57,6 +57,7 @@ use crate::error::{EventError, MegolmResult};
|
|||
pub struct InboundGroupSession {
|
||||
inner: Arc<Mutex<OlmInboundGroupSession>>,
|
||||
session_id: Arc<str>,
|
||||
first_known_index: u32,
|
||||
pub(crate) sender_key: Arc<str>,
|
||||
pub(crate) signing_key: Arc<BTreeMap<DeviceKeyAlgorithm, String>>,
|
||||
pub(crate) room_id: Arc<RoomId>,
|
||||
|
@ -89,6 +90,7 @@ impl InboundGroupSession {
|
|||
) -> Result<Self, OlmGroupSessionError> {
|
||||
let session = OlmInboundGroupSession::new(&session_key.0)?;
|
||||
let session_id = session.session_id();
|
||||
let first_known_index = session.first_known_index();
|
||||
|
||||
let mut keys: BTreeMap<DeviceKeyAlgorithm, String> = BTreeMap::new();
|
||||
keys.insert(DeviceKeyAlgorithm::Ed25519, signing_key.to_owned());
|
||||
|
@ -97,6 +99,7 @@ impl InboundGroupSession {
|
|||
inner: Arc::new(Mutex::new(session)),
|
||||
session_id: session_id.into(),
|
||||
sender_key: sender_key.to_owned().into(),
|
||||
first_known_index,
|
||||
signing_key: Arc::new(keys),
|
||||
room_id: Arc::new(room_id.clone()),
|
||||
forwarding_chains: Arc::new(Mutex::new(None)),
|
||||
|
@ -129,11 +132,12 @@ impl InboundGroupSession {
|
|||
/// to create the `InboundGroupSession`.
|
||||
pub(crate) fn from_forwarded_key(
|
||||
sender_key: &str,
|
||||
content: &mut ForwardedRoomKeyEventContent,
|
||||
content: &mut ForwardedRoomKeyToDeviceEventContent,
|
||||
) -> Result<Self, OlmGroupSessionError> {
|
||||
let key = Zeroizing::from(mem::take(&mut content.session_key));
|
||||
|
||||
let session = OlmInboundGroupSession::import(&key)?;
|
||||
let first_known_index = session.first_known_index();
|
||||
let mut forwarding_chains = content.forwarding_curve25519_key_chain.clone();
|
||||
forwarding_chains.push(sender_key.to_owned());
|
||||
|
||||
|
@ -147,6 +151,7 @@ impl InboundGroupSession {
|
|||
inner: Arc::new(Mutex::new(session)),
|
||||
session_id: content.session_id.as_str().into(),
|
||||
sender_key: content.sender_key.as_str().into(),
|
||||
first_known_index,
|
||||
signing_key: Arc::new(sender_claimed_key),
|
||||
room_id: Arc::new(content.room_id.clone()),
|
||||
forwarding_chains: Arc::new(Mutex::new(Some(forwarding_chains))),
|
||||
|
@ -178,7 +183,7 @@ impl InboundGroupSession {
|
|||
/// If only a limited part of this session should be exported use
|
||||
/// [`export_at_index()`](#method.export_at_index).
|
||||
pub async fn export(&self) -> ExportedRoomKey {
|
||||
self.export_at_index(self.first_known_index().await)
|
||||
self.export_at_index(self.first_known_index())
|
||||
.await
|
||||
.expect("Can't export at the first known index")
|
||||
}
|
||||
|
@ -221,12 +226,14 @@ impl InboundGroupSession {
|
|||
pickle_mode: PicklingMode,
|
||||
) -> Result<Self, OlmGroupSessionError> {
|
||||
let session = OlmInboundGroupSession::unpickle(pickle.pickle.0, pickle_mode)?;
|
||||
let first_known_index = session.first_known_index();
|
||||
let session_id = session.session_id();
|
||||
|
||||
Ok(InboundGroupSession {
|
||||
inner: Arc::new(Mutex::new(session)),
|
||||
session_id: session_id.into(),
|
||||
sender_key: pickle.sender_key.into(),
|
||||
first_known_index,
|
||||
signing_key: Arc::new(pickle.signing_key),
|
||||
room_id: Arc::new(pickle.room_id),
|
||||
forwarding_chains: Arc::new(Mutex::new(pickle.forwarding_chains)),
|
||||
|
@ -245,8 +252,8 @@ impl InboundGroupSession {
|
|||
}
|
||||
|
||||
/// Get the first message index we know how to decrypt.
|
||||
pub async fn first_known_index(&self) -> u32 {
|
||||
self.inner.lock().await.first_known_index()
|
||||
pub fn first_known_index(&self) -> u32 {
|
||||
self.first_known_index
|
||||
}
|
||||
|
||||
/// Decrypt the given ciphertext.
|
||||
|
@ -368,6 +375,7 @@ impl TryFrom<ExportedRoomKey> for InboundGroupSession {
|
|||
|
||||
fn try_from(key: ExportedRoomKey) -> Result<Self, Self::Error> {
|
||||
let session = OlmInboundGroupSession::import(&key.session_key.0)?;
|
||||
let first_known_index = session.first_known_index();
|
||||
|
||||
let forwarding_chains = if key.forwarding_curve25519_key_chain.is_empty() {
|
||||
None
|
||||
|
@ -379,6 +387,7 @@ impl TryFrom<ExportedRoomKey> for InboundGroupSession {
|
|||
inner: Arc::new(Mutex::new(session)),
|
||||
session_id: key.session_id.into(),
|
||||
sender_key: key.sender_key.into(),
|
||||
first_known_index,
|
||||
signing_key: Arc::new(key.sender_claimed_keys),
|
||||
room_id: Arc::new(key.room_id),
|
||||
forwarding_chains: Arc::new(Mutex::new(forwarding_chains)),
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
use matrix_sdk_common::{
|
||||
events::forwarded_room_key::ForwardedRoomKeyEventContent,
|
||||
events::forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
|
||||
identifiers::{DeviceKeyAlgorithm, EventEncryptionAlgorithm, RoomId},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -66,7 +66,7 @@ pub struct ExportedRoomKey {
|
|||
pub forwarding_curve25519_key_chain: Vec<String>,
|
||||
}
|
||||
|
||||
impl TryInto<ForwardedRoomKeyEventContent> for ExportedRoomKey {
|
||||
impl TryInto<ForwardedRoomKeyToDeviceEventContent> for ExportedRoomKey {
|
||||
type Error = ();
|
||||
|
||||
/// Convert an exported room key into a content for a forwarded room key
|
||||
|
@ -75,7 +75,7 @@ impl TryInto<ForwardedRoomKeyEventContent> for ExportedRoomKey {
|
|||
/// This will fail if the exported room key has multiple sender claimed keys
|
||||
/// or if the algorithm of the claimed sender key isn't
|
||||
/// `DeviceKeyAlgorithm::Ed25519`.
|
||||
fn try_into(self) -> Result<ForwardedRoomKeyEventContent, Self::Error> {
|
||||
fn try_into(self) -> Result<ForwardedRoomKeyToDeviceEventContent, Self::Error> {
|
||||
if self.sender_claimed_keys.len() != 1 {
|
||||
Err(())
|
||||
} else {
|
||||
|
@ -85,7 +85,7 @@ impl TryInto<ForwardedRoomKeyEventContent> for ExportedRoomKey {
|
|||
return Err(());
|
||||
}
|
||||
|
||||
Ok(ForwardedRoomKeyEventContent {
|
||||
Ok(ForwardedRoomKeyToDeviceEventContent {
|
||||
algorithm: self.algorithm,
|
||||
room_id: self.room_id,
|
||||
sender_key: self.sender_key,
|
||||
|
@ -98,9 +98,9 @@ impl TryInto<ForwardedRoomKeyEventContent> for ExportedRoomKey {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<ForwardedRoomKeyEventContent> for ExportedRoomKey {
|
||||
impl From<ForwardedRoomKeyToDeviceEventContent> for ExportedRoomKey {
|
||||
/// Convert the content of a forwarded room key into a exported room key.
|
||||
fn from(forwarded_key: ForwardedRoomKeyEventContent) -> Self {
|
||||
fn from(forwarded_key: ForwardedRoomKeyToDeviceEventContent) -> Self {
|
||||
let mut sender_claimed_keys: BTreeMap<DeviceKeyAlgorithm, String> = BTreeMap::new();
|
||||
sender_claimed_keys.insert(
|
||||
DeviceKeyAlgorithm::Ed25519,
|
||||
|
|
|
@ -40,7 +40,7 @@ pub(crate) mod test {
|
|||
use crate::olm::{InboundGroupSession, ReadOnlyAccount, Session};
|
||||
use matrix_sdk_common::{
|
||||
api::r0::keys::SignedKey,
|
||||
events::forwarded_room_key::ForwardedRoomKeyEventContent,
|
||||
events::forwarded_room_key::ForwardedRoomKeyToDeviceEventContent,
|
||||
identifiers::{room_id, user_id, DeviceId, UserId},
|
||||
};
|
||||
use olm_rs::session::OlmMessage;
|
||||
|
@ -213,7 +213,7 @@ pub(crate) mod test {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(0, inbound.first_known_index().await);
|
||||
assert_eq!(0, inbound.first_known_index());
|
||||
|
||||
assert_eq!(outbound.session_id(), inbound.session_id());
|
||||
|
||||
|
@ -237,7 +237,7 @@ pub(crate) mod test {
|
|||
.unwrap();
|
||||
|
||||
let export = inbound.export().await;
|
||||
let export: ForwardedRoomKeyEventContent = export.try_into().unwrap();
|
||||
let export: ForwardedRoomKeyToDeviceEventContent = export.try_into().unwrap();
|
||||
|
||||
let imported = InboundGroupSession::from_export(export).unwrap();
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use olm_rs::sas::OlmSas;
|
|||
use matrix_sdk_common::{
|
||||
api::r0::to_device::DeviceIdOrAllDevices,
|
||||
events::{
|
||||
key::verification::{cancel::CancelCode, mac::MacEventContent},
|
||||
key::verification::{cancel::CancelCode, mac::MacToDeviceEventContent},
|
||||
AnyToDeviceEventContent, EventType, ToDeviceEvent,
|
||||
},
|
||||
identifiers::{DeviceId, DeviceKeyAlgorithm, DeviceKeyId, UserId},
|
||||
|
@ -159,7 +159,7 @@ pub fn receive_mac_event(
|
|||
sas: &OlmSas,
|
||||
ids: &SasIds,
|
||||
flow_id: &str,
|
||||
event: &ToDeviceEvent<MacEventContent>,
|
||||
event: &ToDeviceEvent<MacToDeviceEventContent>,
|
||||
) -> Result<(Vec<ReadOnlyDevice>, Vec<UserIdentities>), CancelCode> {
|
||||
let mut verified_devices = Vec::new();
|
||||
let mut verified_identities = Vec::new();
|
||||
|
@ -270,7 +270,7 @@ fn extra_mac_info_send(ids: &SasIds, flow_id: &str) -> String {
|
|||
/// # Panics
|
||||
///
|
||||
/// 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: &str) -> MacEventContent {
|
||||
pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &str) -> MacToDeviceEventContent {
|
||||
let mut mac: BTreeMap<String, String> = BTreeMap::new();
|
||||
|
||||
let key_id = DeviceKeyId::from_parts(DeviceKeyAlgorithm::Ed25519, ids.account.device_id());
|
||||
|
@ -291,7 +291,7 @@ pub fn get_mac_content(sas: &OlmSas, ids: &SasIds, flow_id: &str) -> MacEventCon
|
|||
.calculate_mac(&keys.join(","), &format!("{}KEY_IDS", &info))
|
||||
.expect("Can't calculate SAS MAC");
|
||||
|
||||
MacEventContent {
|
||||
MacToDeviceEventContent {
|
||||
transaction_id: flow_id.to_owned(),
|
||||
keys,
|
||||
mac,
|
||||
|
|
|
@ -25,8 +25,8 @@ use matrix_sdk_common::{
|
|||
api::r0::keys::upload_signatures::Request as SignatureUploadRequest,
|
||||
events::{
|
||||
key::verification::{
|
||||
accept::AcceptEventContent, cancel::CancelCode, mac::MacEventContent,
|
||||
start::StartEventContent,
|
||||
accept::AcceptToDeviceEventContent, cancel::CancelCode, mac::MacToDeviceEventContent,
|
||||
start::StartToDeviceEventContent,
|
||||
},
|
||||
AnyToDeviceEvent, AnyToDeviceEventContent, ToDeviceEvent,
|
||||
},
|
||||
|
@ -122,7 +122,7 @@ impl Sas {
|
|||
other_device: ReadOnlyDevice,
|
||||
store: Arc<Box<dyn CryptoStore>>,
|
||||
other_identity: Option<UserIdentities>,
|
||||
) -> (Sas, StartEventContent) {
|
||||
) -> (Sas, StartToDeviceEventContent) {
|
||||
let (inner, content) = InnerSas::start(
|
||||
account.clone(),
|
||||
other_device.clone(),
|
||||
|
@ -158,7 +158,7 @@ impl Sas {
|
|||
private_identity: PrivateCrossSigningIdentity,
|
||||
other_device: ReadOnlyDevice,
|
||||
store: Arc<Box<dyn CryptoStore>>,
|
||||
event: &ToDeviceEvent<StartEventContent>,
|
||||
event: &ToDeviceEvent<StartToDeviceEventContent>,
|
||||
other_identity: Option<UserIdentities>,
|
||||
) -> Result<Sas, AnyToDeviceEventContent> {
|
||||
let inner = InnerSas::from_start_event(
|
||||
|
@ -554,7 +554,7 @@ impl InnerSas {
|
|||
account: ReadOnlyAccount,
|
||||
other_device: ReadOnlyDevice,
|
||||
other_identity: Option<UserIdentities>,
|
||||
) -> (InnerSas, StartEventContent) {
|
||||
) -> (InnerSas, StartToDeviceEventContent) {
|
||||
let sas = SasState::<Created>::new(account, other_device, other_identity);
|
||||
let content = sas.as_content();
|
||||
(InnerSas::Created(sas), content)
|
||||
|
@ -563,7 +563,7 @@ impl InnerSas {
|
|||
fn from_start_event(
|
||||
account: ReadOnlyAccount,
|
||||
other_device: ReadOnlyDevice,
|
||||
event: &ToDeviceEvent<StartEventContent>,
|
||||
event: &ToDeviceEvent<StartToDeviceEventContent>,
|
||||
other_identity: Option<UserIdentities>,
|
||||
) -> Result<InnerSas, AnyToDeviceEventContent> {
|
||||
match SasState::<Started>::from_start_event(account, other_device, event, other_identity) {
|
||||
|
@ -572,7 +572,7 @@ impl InnerSas {
|
|||
}
|
||||
}
|
||||
|
||||
fn accept(&self) -> Option<AcceptEventContent> {
|
||||
fn accept(&self) -> Option<AcceptToDeviceEventContent> {
|
||||
if let InnerSas::Started(s) = self {
|
||||
Some(s.as_content())
|
||||
} else {
|
||||
|
@ -610,7 +610,7 @@ impl InnerSas {
|
|||
(InnerSas::Canceled(sas), Some(content))
|
||||
}
|
||||
|
||||
fn confirm(self) -> (InnerSas, Option<MacEventContent>) {
|
||||
fn confirm(self) -> (InnerSas, Option<MacToDeviceEventContent>) {
|
||||
match self {
|
||||
InnerSas::KeyRecieved(s) => {
|
||||
let sas = s.confirm();
|
||||
|
|
|
@ -25,13 +25,13 @@ use matrix_sdk_common::{
|
|||
events::{
|
||||
key::verification::{
|
||||
accept::{
|
||||
AcceptEventContent, AcceptMethod, MSasV1Content as AcceptV1Content,
|
||||
AcceptMethod, AcceptToDeviceEventContent, MSasV1Content as AcceptV1Content,
|
||||
MSasV1ContentInit as AcceptV1ContentInit,
|
||||
},
|
||||
cancel::{CancelCode, CancelEventContent},
|
||||
key::KeyEventContent,
|
||||
mac::MacEventContent,
|
||||
start::{MSasV1Content, MSasV1ContentInit, StartEventContent, StartMethod},
|
||||
cancel::{CancelCode, CancelToDeviceEventContent},
|
||||
key::KeyToDeviceEventContent,
|
||||
mac::MacToDeviceEventContent,
|
||||
start::{MSasV1Content, MSasV1ContentInit, StartMethod, StartToDeviceEventContent},
|
||||
HashAlgorithm, KeyAgreementProtocol, MessageAuthenticationCode,
|
||||
ShortAuthenticationString, VerificationMethod,
|
||||
},
|
||||
|
@ -319,8 +319,8 @@ impl SasState<Created> {
|
|||
/// Get the content for the start event.
|
||||
///
|
||||
/// The content needs to be sent to the other device.
|
||||
pub fn as_content(&self) -> StartEventContent {
|
||||
StartEventContent {
|
||||
pub fn as_content(&self) -> StartToDeviceEventContent {
|
||||
StartToDeviceEventContent {
|
||||
transaction_id: self.verification_flow_id.to_string(),
|
||||
from_device: self.device_id().into(),
|
||||
method: StartMethod::MSasV1(
|
||||
|
@ -339,7 +339,7 @@ impl SasState<Created> {
|
|||
/// the other side.
|
||||
pub fn into_accepted(
|
||||
self,
|
||||
event: &ToDeviceEvent<AcceptEventContent>,
|
||||
event: &ToDeviceEvent<AcceptToDeviceEventContent>,
|
||||
) -> Result<SasState<Accepted>, SasState<Canceled>> {
|
||||
self.check_event(&event.sender, &event.content.transaction_id)
|
||||
.map_err(|c| self.clone().cancel(c))?;
|
||||
|
@ -386,7 +386,7 @@ impl SasState<Started> {
|
|||
pub fn from_start_event(
|
||||
account: ReadOnlyAccount,
|
||||
other_device: ReadOnlyDevice,
|
||||
event: &ToDeviceEvent<StartEventContent>,
|
||||
event: &ToDeviceEvent<StartToDeviceEventContent>,
|
||||
other_identity: Option<UserIdentities>,
|
||||
) -> Result<SasState<Started>, SasState<Canceled>> {
|
||||
if let StartMethod::MSasV1(content) = &event.content.method {
|
||||
|
@ -462,10 +462,10 @@ impl SasState<Started> {
|
|||
/// This should be sent out automatically if the SAS verification flow has
|
||||
/// been started because of a
|
||||
/// m.key.verification.request -> m.key.verification.ready flow.
|
||||
pub fn as_content(&self) -> AcceptEventContent {
|
||||
pub fn as_content(&self) -> AcceptToDeviceEventContent {
|
||||
let accepted_protocols = AcceptedProtocols::default();
|
||||
|
||||
AcceptEventContent {
|
||||
AcceptToDeviceEventContent {
|
||||
transaction_id: self.verification_flow_id.to_string(),
|
||||
method: AcceptMethod::MSasV1(
|
||||
AcceptV1ContentInit {
|
||||
|
@ -494,7 +494,7 @@ impl SasState<Started> {
|
|||
/// anymore.
|
||||
pub fn into_key_received(
|
||||
self,
|
||||
event: &mut ToDeviceEvent<KeyEventContent>,
|
||||
event: &mut ToDeviceEvent<KeyToDeviceEventContent>,
|
||||
) -> Result<SasState<KeyReceived>, SasState<Canceled>> {
|
||||
self.check_event(&event.sender, &event.content.transaction_id)
|
||||
.map_err(|c| self.clone().cancel(c))?;
|
||||
|
@ -535,7 +535,7 @@ impl SasState<Accepted> {
|
|||
/// anymore.
|
||||
pub fn into_key_received(
|
||||
self,
|
||||
event: &mut ToDeviceEvent<KeyEventContent>,
|
||||
event: &mut ToDeviceEvent<KeyToDeviceEventContent>,
|
||||
) -> Result<SasState<KeyReceived>, SasState<Canceled>> {
|
||||
self.check_event(&event.sender, &event.content.transaction_id)
|
||||
.map_err(|c| self.clone().cancel(c))?;
|
||||
|
@ -575,8 +575,8 @@ impl SasState<Accepted> {
|
|||
/// Get the content for the key event.
|
||||
///
|
||||
/// The content needs to be automatically sent to the other side.
|
||||
pub fn as_content(&self) -> KeyEventContent {
|
||||
KeyEventContent {
|
||||
pub fn as_content(&self) -> KeyToDeviceEventContent {
|
||||
KeyToDeviceEventContent {
|
||||
transaction_id: self.verification_flow_id.to_string(),
|
||||
key: self.inner.lock().unwrap().public_key(),
|
||||
}
|
||||
|
@ -588,8 +588,8 @@ impl SasState<KeyReceived> {
|
|||
///
|
||||
/// The content needs to be automatically sent to the other side if and only
|
||||
/// if we_started is false.
|
||||
pub fn as_content(&self) -> KeyEventContent {
|
||||
KeyEventContent {
|
||||
pub fn as_content(&self) -> KeyToDeviceEventContent {
|
||||
KeyToDeviceEventContent {
|
||||
transaction_id: self.verification_flow_id.to_string(),
|
||||
key: self.inner.lock().unwrap().public_key(),
|
||||
}
|
||||
|
@ -632,7 +632,7 @@ impl SasState<KeyReceived> {
|
|||
/// the other side.
|
||||
pub fn into_mac_received(
|
||||
self,
|
||||
event: &ToDeviceEvent<MacEventContent>,
|
||||
event: &ToDeviceEvent<MacToDeviceEventContent>,
|
||||
) -> Result<SasState<MacReceived>, SasState<Canceled>> {
|
||||
self.check_event(&event.sender, &event.content.transaction_id)
|
||||
.map_err(|c| self.clone().cancel(c))?;
|
||||
|
@ -688,7 +688,7 @@ impl SasState<Confirmed> {
|
|||
/// the other side.
|
||||
pub fn into_done(
|
||||
self,
|
||||
event: &ToDeviceEvent<MacEventContent>,
|
||||
event: &ToDeviceEvent<MacToDeviceEventContent>,
|
||||
) -> Result<SasState<Done>, SasState<Canceled>> {
|
||||
self.check_event(&event.sender, &event.content.transaction_id)
|
||||
.map_err(|c| self.clone().cancel(c))?;
|
||||
|
@ -718,7 +718,7 @@ impl SasState<Confirmed> {
|
|||
/// Get the content for the mac event.
|
||||
///
|
||||
/// The content needs to be automatically sent to the other side.
|
||||
pub fn as_content(&self) -> MacEventContent {
|
||||
pub fn as_content(&self) -> MacToDeviceEventContent {
|
||||
get_mac_content(
|
||||
&self.inner.lock().unwrap(),
|
||||
&self.ids,
|
||||
|
@ -780,7 +780,7 @@ impl SasState<Done> {
|
|||
///
|
||||
/// The content needs to be automatically sent to the other side if it
|
||||
/// wasn't already sent.
|
||||
pub fn as_content(&self) -> MacEventContent {
|
||||
pub fn as_content(&self) -> MacToDeviceEventContent {
|
||||
get_mac_content(
|
||||
&self.inner.lock().unwrap(),
|
||||
&self.ids,
|
||||
|
@ -829,7 +829,7 @@ impl Canceled {
|
|||
|
||||
impl SasState<Canceled> {
|
||||
pub fn as_content(&self) -> AnyToDeviceEventContent {
|
||||
AnyToDeviceEventContent::KeyVerificationCancel(CancelEventContent {
|
||||
AnyToDeviceEventContent::KeyVerificationCancel(CancelToDeviceEventContent {
|
||||
transaction_id: self.verification_flow_id.to_string(),
|
||||
reason: self.state.reason.to_string(),
|
||||
code: self.state.cancel_code.clone(),
|
||||
|
|
Loading…
Reference in a new issue