crypto: Hook up the key requesting to the main state machine.

master
Damir Jelić 2020-09-18 13:50:13 +02:00
parent c58cf71be1
commit 5d5d5bb141
1 changed files with 56 additions and 37 deletions

View File

@ -39,12 +39,13 @@ use matrix_sdk_common::{
assign, assign,
encryption::DeviceKeys, encryption::DeviceKeys,
events::{ events::{
forwarded_room_key::ForwardedRoomKeyEventContent, room::encrypted::EncryptedEventContent, room::encrypted::EncryptedEventContent, room_key::RoomKeyEventContent,
room_key::RoomKeyEventContent, room_key_request::RoomKeyRequestEventContent, room_key_request::RoomKeyRequestEventContent, AnyMessageEventContent, AnySyncRoomEvent,
AnyMessageEventContent, AnySyncRoomEvent, AnyToDeviceEvent, EventType, SyncMessageEvent, AnyToDeviceEvent, EventType, SyncMessageEvent, ToDeviceEvent,
ToDeviceEvent, },
identifiers::{
DeviceId, DeviceIdBox, DeviceKeyAlgorithm, EventEncryptionAlgorithm, RoomId, UserId,
}, },
identifiers::{DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, RoomId, UserId},
uuid::Uuid, uuid::Uuid,
Raw, Raw,
}; };
@ -57,6 +58,7 @@ use super::{
Device, MasterPubkey, OwnUserIdentity, ReadOnlyDevice, SelfSigningPubkey, UserDevices, Device, MasterPubkey, OwnUserIdentity, ReadOnlyDevice, SelfSigningPubkey, UserDevices,
UserIdentities, UserIdentity, UserSigningPubkey, UserIdentities, UserIdentity, UserSigningPubkey,
}, },
key_request::KeyRequestMachine,
olm::{ olm::{
Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys, Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys,
InboundGroupSession, OlmMessage, OutboundGroupSession, InboundGroupSession, OlmMessage, OutboundGroupSession,
@ -71,9 +73,9 @@ use super::{
#[derive(Clone)] #[derive(Clone)]
pub struct OlmMachine { pub struct OlmMachine {
/// The unique user id that owns this account. /// The unique user id that owns this account.
user_id: UserId, user_id: Arc<UserId>,
/// The unique device id of the device that holds this account. /// The unique device id of the device that holds this account.
device_id: Box<DeviceId>, device_id: Arc<Box<DeviceId>>,
/// Our underlying Olm Account holding our identity keys. /// Our underlying Olm Account holding our identity keys.
account: Account, account: Account,
/// Store for the encryption keys. /// Store for the encryption keys.
@ -85,6 +87,9 @@ pub struct OlmMachine {
/// A state machine that is responsible to handle and keep track of SAS /// A state machine that is responsible to handle and keep track of SAS
/// verification flows. /// verification flows.
verification_machine: VerificationMachine, verification_machine: VerificationMachine,
/// The state machine that is responsible to handle outgoing and incoming
/// key requests.
key_request_machine: KeyRequestMachine,
} }
#[cfg(not(tarpaulin_include))] #[cfg(not(tarpaulin_include))]
@ -115,14 +120,17 @@ impl OlmMachine {
let store: Box<dyn CryptoStore> = Box::new(MemoryStore::new()); let store: Box<dyn CryptoStore> = Box::new(MemoryStore::new());
let store = Store::new(store); let store = Store::new(store);
let account = Account::new(user_id, device_id); let account = Account::new(user_id, device_id);
let user_id = Arc::new(user_id.clone());
let device_id: Arc<DeviceIdBox> = Arc::new(device_id.into());
OlmMachine { OlmMachine {
user_id: user_id.clone(), user_id: user_id.clone(),
device_id: device_id.into(), device_id: device_id.clone(),
account: account.clone(), account: account.clone(),
store: store.clone(), store: store.clone(),
outbound_group_sessions: Arc::new(DashMap::new()), outbound_group_sessions: Arc::new(DashMap::new()),
verification_machine: VerificationMachine::new(account, store), verification_machine: VerificationMachine::new(account, store.clone()),
key_request_machine: KeyRequestMachine::new(user_id, device_id, store),
} }
} }
@ -163,6 +171,10 @@ impl OlmMachine {
let store = Store::new(store); let store = Store::new(store);
let verification_machine = VerificationMachine::new(account.clone(), store.clone()); let verification_machine = VerificationMachine::new(account.clone(), store.clone());
let user_id = Arc::new(user_id.clone());
let device_id: Arc<DeviceIdBox> = Arc::new(device_id.into());
let key_request_machine =
KeyRequestMachine::new(user_id.clone(), device_id.clone(), store.clone());
Ok(OlmMachine { Ok(OlmMachine {
user_id, user_id,
@ -171,6 +183,7 @@ impl OlmMachine {
store, store,
outbound_group_sessions: Arc::new(DashMap::new()), outbound_group_sessions: Arc::new(DashMap::new()),
verification_machine, verification_machine,
key_request_machine,
}) })
} }
@ -238,6 +251,7 @@ impl OlmMachine {
} }
requests.append(&mut self.outgoing_to_device_requests()); requests.append(&mut self.outgoing_to_device_requests());
requests.append(&mut self.key_request_machine.outgoing_to_device_requests());
requests requests
} }
@ -267,7 +281,7 @@ impl OlmMachine {
self.receive_keys_claim_response(response).await?; self.receive_keys_claim_response(response).await?;
} }
IncomingResponse::ToDevice(_) => { IncomingResponse::ToDevice(_) => {
self.mark_to_device_request_as_sent(&request_id); self.mark_to_device_request_as_sent(&request_id).await?;
} }
}; };
@ -500,7 +514,7 @@ impl OlmMachine {
for (device_id, device_keys) in device_map.iter() { for (device_id, device_keys) in device_map.iter() {
// We don't need our own device in the device store. // We don't need our own device in the device store.
if user_id == &self.user_id && device_id == &self.device_id { if user_id == self.user_id() && &**device_id == self.device_id() {
continue; continue;
} }
@ -881,7 +895,7 @@ impl OlmMachine {
.ok_or_else(|| EventError::MissingField("keys".to_string()))?, .ok_or_else(|| EventError::MissingField("keys".to_string()))?,
)?; )?;
if recipient != self.user_id || sender != &encrytped_sender { if &recipient != self.user_id() || sender != &encrytped_sender {
return Err(EventError::MissmatchedSender.into()); return Err(EventError::MissmatchedSender.into());
} }
@ -1192,16 +1206,6 @@ impl OlmMachine {
Ok(requests) Ok(requests)
} }
fn add_forwarded_room_key(
&self,
_sender_key: &str,
_signing_key: &str,
_event: &ToDeviceEvent<ForwardedRoomKeyEventContent>,
) -> OlmResult<()> {
Ok(())
// TODO
}
/// Receive and properly handle a decrypted to-device event. /// Receive and properly handle a decrypted to-device event.
/// ///
/// # Arguments /// # Arguments
@ -1228,8 +1232,11 @@ impl OlmMachine {
AnyToDeviceEvent::RoomKey(mut e) => { AnyToDeviceEvent::RoomKey(mut e) => {
Ok(self.add_room_key(sender_key, signing_key, &mut e).await?) Ok(self.add_room_key(sender_key, signing_key, &mut e).await?)
} }
AnyToDeviceEvent::ForwardedRoomKey(e) => { AnyToDeviceEvent::ForwardedRoomKey(mut e) => {
self.add_forwarded_room_key(sender_key, signing_key, &e)?; // TODO do the mem take dance to remove the key.
self.key_request_machine
.receive_forwarded_room_key(sender_key, &mut e)
.await?;
Ok(None) Ok(None)
} }
_ => { _ => {
@ -1255,8 +1262,13 @@ impl OlmMachine {
} }
/// Mark an outgoing to-device requests as sent. /// Mark an outgoing to-device requests as sent.
fn mark_to_device_request_as_sent(&self, request_id: &Uuid) { async fn mark_to_device_request_as_sent(&self, request_id: &Uuid) -> StoreResult<()> {
self.verification_machine.mark_request_as_sent(request_id); self.verification_machine.mark_request_as_sent(request_id);
self.key_request_machine
.mark_outgoing_request_as_sent(request_id)
.await?;
Ok(())
} }
/// Get a `Sas` verification object with the given flow id. /// Get a `Sas` verification object with the given flow id.
@ -1357,7 +1369,14 @@ impl OlmMachine {
.get_inbound_group_session(room_id, &content.sender_key, &content.session_id) .get_inbound_group_session(room_id, &content.sender_key, &content.session_id)
.await?; .await?;
// TODO check if the Olm session is wedged and re-request the key. // TODO check if the Olm session is wedged and re-request the key.
let session = session.ok_or(MegolmError::MissingSession)?; let session = if let Some(s) = session {
s
} else {
self.key_request_machine
.create_outgoing_key_request(room_id, &content.sender_key, &content.session_id)
.await?;
return Err(MegolmError::MissingSession);
};
// TODO check the message index. // TODO check the message index.
// TODO check if this is from a verified device. // TODO check if this is from a verified device.
@ -1774,10 +1793,10 @@ pub(crate) mod test {
let one_time_key = one_time_keys.iter().next().unwrap(); let one_time_key = one_time_keys.iter().next().unwrap();
let mut keys = BTreeMap::new(); let mut keys = BTreeMap::new();
keys.insert(one_time_key.0.clone(), one_time_key.1.clone()); keys.insert(one_time_key.0.clone(), one_time_key.1.clone());
bob_keys.insert(bob.device_id.clone(), keys); bob_keys.insert(bob.device_id().into(), keys);
let mut one_time_keys = BTreeMap::new(); let mut one_time_keys = BTreeMap::new();
one_time_keys.insert(bob.user_id.clone(), bob_keys); one_time_keys.insert(bob.user_id().clone(), bob_keys);
let response = claim_keys::Response::new(one_time_keys); let response = claim_keys::Response::new(one_time_keys);
@ -1795,7 +1814,7 @@ pub(crate) mod test {
.unwrap(); .unwrap();
let event = ToDeviceEvent { let event = ToDeviceEvent {
sender: alice.user_id.clone(), sender: alice.user_id().clone(),
content: bob_device content: bob_device
.encrypt(EventType::Dummy, json!({})) .encrypt(EventType::Dummy, json!({}))
.await .await
@ -2045,10 +2064,10 @@ pub(crate) mod test {
let one_time_key = one_time_keys.iter().next().unwrap(); let one_time_key = one_time_keys.iter().next().unwrap();
let mut keys = BTreeMap::new(); let mut keys = BTreeMap::new();
keys.insert(one_time_key.0.clone(), one_time_key.1.clone()); keys.insert(one_time_key.0.clone(), one_time_key.1.clone());
bob_keys.insert(bob_machine.device_id.clone(), keys); bob_keys.insert(bob_machine.device_id().into(), keys);
let mut one_time_keys = BTreeMap::new(); let mut one_time_keys = BTreeMap::new();
one_time_keys.insert(bob_machine.user_id.clone(), bob_keys); one_time_keys.insert(bob_machine.user_id().clone(), bob_keys);
let response = claim_keys::Response::new(one_time_keys); let response = claim_keys::Response::new(one_time_keys);
@ -2077,7 +2096,7 @@ pub(crate) mod test {
.unwrap(); .unwrap();
let event = ToDeviceEvent { let event = ToDeviceEvent {
sender: alice.user_id.clone(), sender: alice.user_id().clone(),
content: bob_device content: bob_device
.encrypt(EventType::Dummy, json!({})) .encrypt(EventType::Dummy, json!({}))
.await .await
@ -2092,7 +2111,7 @@ pub(crate) mod test {
.unwrap(); .unwrap();
if let AnyToDeviceEvent::Dummy(e) = event { if let AnyToDeviceEvent::Dummy(e) = event {
assert_eq!(e.sender, alice.user_id); assert_eq!(&e.sender, alice.user_id());
} else { } else {
panic!("Wrong event type found {:?}", event); panic!("Wrong event type found {:?}", event);
} }
@ -2107,14 +2126,14 @@ pub(crate) mod test {
let to_device_requests = alice let to_device_requests = alice
.share_group_session( .share_group_session(
&room_id, &room_id,
[bob.user_id.clone()].iter(), [bob.user_id().clone()].iter(),
EncryptionSettings::default(), EncryptionSettings::default(),
) )
.await .await
.unwrap(); .unwrap();
let event = ToDeviceEvent { let event = ToDeviceEvent {
sender: alice.user_id.clone(), sender: alice.user_id().clone(),
content: to_device_requests_to_content(to_device_requests), content: to_device_requests_to_content(to_device_requests),
}; };
@ -2128,7 +2147,7 @@ pub(crate) mod test {
.unwrap(); .unwrap();
if let AnyToDeviceEvent::RoomKey(event) = event { if let AnyToDeviceEvent::RoomKey(event) = event {
assert_eq!(event.sender, alice.user_id); assert_eq!(&event.sender, alice.user_id());
assert!(event.content.session_key.is_empty()); assert!(event.content.session_key.is_empty());
} else { } else {
panic!("expected RoomKeyEvent found {:?}", event); panic!("expected RoomKeyEvent found {:?}", event);
@ -2161,7 +2180,7 @@ pub(crate) mod test {
.unwrap(); .unwrap();
let event = ToDeviceEvent { let event = ToDeviceEvent {
sender: alice.user_id.clone(), sender: alice.user_id().clone(),
content: to_device_requests_to_content(to_device_requests), content: to_device_requests_to_content(to_device_requests),
}; };