crypto: Move the megolm decryption logic into the session.
parent
8e19c583c6
commit
ac264918b8
|
@ -1344,6 +1344,8 @@ impl OlmMachine {
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `event` - The event that should be decrypted.
|
/// * `event` - The event that should be decrypted.
|
||||||
|
///
|
||||||
|
/// * `room_id` - The ID of the room where the event was sent to.
|
||||||
pub async fn decrypt_room_event(
|
pub async fn decrypt_room_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: &MessageEventStub<EncryptedEventContent>,
|
event: &MessageEventStub<EncryptedEventContent>,
|
||||||
|
@ -1361,35 +1363,10 @@ impl OlmMachine {
|
||||||
// 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 = session.ok_or(MegolmError::MissingSession)?;
|
||||||
|
|
||||||
let (plaintext, _) = session.decrypt(content.ciphertext.clone()).await?;
|
|
||||||
// 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.
|
||||||
|
let (decrypted_event, _) = session.decrypt(event).await?;
|
||||||
|
|
||||||
// TODO move this logic into the group session.
|
|
||||||
let mut decrypted_value = serde_json::from_str::<Value>(&plaintext)?;
|
|
||||||
let decrypted_object = decrypted_value
|
|
||||||
.as_object_mut()
|
|
||||||
.ok_or(EventError::NotAnObject)?;
|
|
||||||
|
|
||||||
// TODO better number conversion here.
|
|
||||||
let server_ts = event
|
|
||||||
.origin_server_ts
|
|
||||||
.duration_since(std::time::SystemTime::UNIX_EPOCH)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.as_millis();
|
|
||||||
let server_ts: i64 = server_ts.try_into().unwrap_or_default();
|
|
||||||
|
|
||||||
decrypted_object.insert("sender".to_owned(), event.sender.to_string().into());
|
|
||||||
decrypted_object.insert("event_id".to_owned(), event.event_id.to_string().into());
|
|
||||||
decrypted_object.insert("origin_server_ts".to_owned(), server_ts.into());
|
|
||||||
|
|
||||||
decrypted_object.insert(
|
|
||||||
"unsigned".to_owned(),
|
|
||||||
serde_json::to_value(&event.unsigned).unwrap_or_default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let decrypted_event =
|
|
||||||
serde_json::from_value::<EventJson<AnyRoomEventStub>>(decrypted_value)?;
|
|
||||||
trace!("Successfully decrypted Megolm event {:?}", decrypted_event);
|
trace!("Successfully decrypted Megolm event {:?}", decrypted_event);
|
||||||
// TODO set the encryption info on the event (is it verified, was it
|
// TODO set the encryption info on the event (is it verified, was it
|
||||||
// decrypted, sender key...)
|
// decrypted, sender key...)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use matrix_sdk_common::instant::Instant;
|
use matrix_sdk_common::instant::Instant;
|
||||||
|
use std::convert::TryInto;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -31,6 +32,7 @@ use olm_rs::outbound_group_session::OlmOutboundGroupSession;
|
||||||
use olm_rs::session::OlmSession;
|
use olm_rs::session::OlmSession;
|
||||||
use olm_rs::PicklingMode;
|
use olm_rs::PicklingMode;
|
||||||
|
|
||||||
|
use crate::error::{EventError, MegolmResult};
|
||||||
pub use olm_rs::{
|
pub use olm_rs::{
|
||||||
session::{OlmMessage, PreKeyMessage},
|
session::{OlmMessage, PreKeyMessage},
|
||||||
utility::OlmUtility,
|
utility::OlmUtility,
|
||||||
|
@ -44,7 +46,7 @@ use matrix_sdk_common::{
|
||||||
encrypted::{EncryptedEventContent, MegolmV1AesSha2Content},
|
encrypted::{EncryptedEventContent, MegolmV1AesSha2Content},
|
||||||
message::MessageEventContent,
|
message::MessageEventContent,
|
||||||
},
|
},
|
||||||
Algorithm, EventType,
|
Algorithm, AnyRoomEventStub, EventJson, EventType, MessageEventStub,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -642,9 +644,56 @@ impl InboundGroupSession {
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `message` - The message that should be decrypted.
|
/// * `message` - The message that should be decrypted.
|
||||||
pub async fn decrypt(&self, message: String) -> Result<(String, u32), OlmGroupSessionError> {
|
pub async fn decrypt_helper(
|
||||||
|
&self,
|
||||||
|
message: String,
|
||||||
|
) -> Result<(String, u32), OlmGroupSessionError> {
|
||||||
self.inner.lock().await.decrypt(message)
|
self.inner.lock().await.decrypt(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decrypt an event from a room timeline.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `event` - The event that should be decrypted.
|
||||||
|
pub async fn decrypt(
|
||||||
|
&self,
|
||||||
|
event: &MessageEventStub<EncryptedEventContent>,
|
||||||
|
) -> MegolmResult<(EventJson<AnyRoomEventStub>, u32)> {
|
||||||
|
let content = match &event.content {
|
||||||
|
EncryptedEventContent::MegolmV1AesSha2(c) => c,
|
||||||
|
_ => return Err(EventError::UnsupportedAlgorithm.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let (plaintext, message_index) = self.decrypt_helper(content.ciphertext.clone()).await?;
|
||||||
|
|
||||||
|
let mut decrypted_value = serde_json::from_str::<Value>(&plaintext)?;
|
||||||
|
let decrypted_object = decrypted_value
|
||||||
|
.as_object_mut()
|
||||||
|
.ok_or(EventError::NotAnObject)?;
|
||||||
|
|
||||||
|
// TODO better number conversion here.
|
||||||
|
let server_ts = event
|
||||||
|
.origin_server_ts
|
||||||
|
.duration_since(std::time::SystemTime::UNIX_EPOCH)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.as_millis();
|
||||||
|
let server_ts: i64 = server_ts.try_into().unwrap_or_default();
|
||||||
|
|
||||||
|
decrypted_object.insert("sender".to_owned(), event.sender.to_string().into());
|
||||||
|
decrypted_object.insert("event_id".to_owned(), event.event_id.to_string().into());
|
||||||
|
decrypted_object.insert("origin_server_ts".to_owned(), server_ts.into());
|
||||||
|
|
||||||
|
decrypted_object.insert(
|
||||||
|
"unsigned".to_owned(),
|
||||||
|
serde_json::to_value(&event.unsigned).unwrap_or_default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
serde_json::from_value::<EventJson<AnyRoomEventStub>>(decrypted_value)?,
|
||||||
|
message_index,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg_attr(tarpaulin, skip)]
|
// #[cfg_attr(tarpaulin, skip)]
|
||||||
|
@ -996,6 +1045,9 @@ pub(crate) mod test {
|
||||||
let plaintext = "This is a secret to everybody".to_owned();
|
let plaintext = "This is a secret to everybody".to_owned();
|
||||||
let ciphertext = outbound.encrypt_helper(plaintext.clone()).await;
|
let ciphertext = outbound.encrypt_helper(plaintext.clone()).await;
|
||||||
|
|
||||||
assert_eq!(plaintext, inbound.decrypt(ciphertext).await.unwrap().0);
|
assert_eq!(
|
||||||
|
plaintext,
|
||||||
|
inbound.decrypt_helper(ciphertext).await.unwrap().0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue