Skip to content

Commit

Permalink
refactor(crypto): Start using our own event types when we encrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
poljar committed Aug 4, 2022
1 parent 2430d7f commit ddf8577
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 59 deletions.
22 changes: 11 additions & 11 deletions crates/matrix-sdk-crypto/src/gossiping/machine.rs
Expand Up @@ -28,13 +28,9 @@ use ruma::{
events::{
forwarded_room_key::{ToDeviceForwardedRoomKeyEvent, ToDeviceForwardedRoomKeyEventContent},
room_key_request::{Action, RequestedKeyInfo, ToDeviceRoomKeyRequestEvent},
secret::{
request::{
RequestAction, SecretName, ToDeviceSecretRequestEvent as SecretRequestEvent,
},
send::ToDeviceSecretSendEventContent as SecretSendEventContent,
secret::request::{
RequestAction, SecretName, ToDeviceSecretRequestEvent as SecretRequestEvent,
},
AnyToDeviceEventContent,
},
DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, OwnedDeviceId, OwnedTransactionId,
OwnedUserId, RoomId, TransactionId, UserId,
Expand All @@ -49,7 +45,10 @@ use crate::{
requests::{OutgoingRequest, ToDeviceRequest},
session_manager::GroupSessionCache,
store::{Changes, CryptoStoreError, SecretImportError, Store},
types::events::{secret_send::SecretSendEvent, EventType},
types::events::{
secret_send::{SecretSendContent, SecretSendEvent},
EventType,
},
Device,
};

Expand Down Expand Up @@ -238,7 +237,7 @@ impl GossipMachine {
};

let content = if let Some(secret) = self.store.export_secret(secret_name).await {
SecretSendEventContent::new(event.content.request_id.to_owned(), secret)
SecretSendContent::new(event.content.request_id.to_owned(), secret)
} else {
info!(?secret_name, "Can't serve a secret request, secret isn't found");
return Ok(None);
Expand Down Expand Up @@ -428,10 +427,11 @@ impl GossipMachine {
async fn share_secret(
&self,
device: &Device,
content: SecretSendEventContent,
content: SecretSendContent,
) -> OlmResult<Session> {
let (used_session, content) =
device.encrypt(AnyToDeviceEventContent::SecretSend(content)).await?;
let event_type = content.event_type();
let content = serde_json::to_value(content)?;
let (used_session, content) = device.encrypt(event_type, content).await?;

let request = ToDeviceRequest::new(
device.user_id(),
Expand Down
17 changes: 11 additions & 6 deletions crates/matrix-sdk-crypto/src/identities/device.rs
Expand Up @@ -28,13 +28,14 @@ use ruma::{
api::client::keys::upload_signatures::v3::Request as SignatureUploadRequest,
events::{
forwarded_room_key::ToDeviceForwardedRoomKeyEventContent,
key::verification::VerificationMethod, AnyToDeviceEventContent,
key::verification::VerificationMethod,
},
serde::Raw,
DeviceId, DeviceKeyAlgorithm, DeviceKeyId, EventEncryptionAlgorithm, OwnedDeviceId,
OwnedDeviceKeyId, UserId,
};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value;
use tracing::warn;
use vodozemac::{Curve25519PublicKey, Ed25519PublicKey};

Expand Down Expand Up @@ -257,9 +258,10 @@ impl Device {
/// * `content` - The content of the event that should be encrypted.
pub(crate) async fn encrypt(
&self,
content: AnyToDeviceEventContent,
event_type: &str,
content: Value,
) -> OlmResult<(Session, Raw<ToDeviceEncryptedEventContent>)> {
self.inner.encrypt(self.verification_machine.store.inner(), content).await
self.inner.encrypt(self.verification_machine.store.inner(), event_type, content).await
}

/// Encrypt the given inbound group session as a forwarded room key for this
Expand Down Expand Up @@ -288,7 +290,9 @@ impl Device {
);
};

self.encrypt(AnyToDeviceEventContent::ForwardedRoomKey(content)).await
let content = serde_json::to_value(content)?;

self.encrypt("m.forwarded_room_key", content).await
}
}

Expand Down Expand Up @@ -514,7 +518,8 @@ impl ReadOnlyDevice {
pub(crate) async fn encrypt(
&self,
store: &dyn CryptoStore,
content: AnyToDeviceEventContent,
event_type: &str,
content: Value,
) -> OlmResult<(Session, Raw<ToDeviceEncryptedEventContent>)> {
let sender_key = if let Some(k) = self.curve25519_key() {
k
Expand Down Expand Up @@ -548,7 +553,7 @@ impl ReadOnlyDevice {
return Err(OlmError::MissingSession);
};

let message = session.encrypt(self, content).await?;
let message = session.encrypt(self, event_type, content).await?;

Ok((session, message))
}
Expand Down
7 changes: 3 additions & 4 deletions crates/matrix-sdk-crypto/src/machine.rs
Expand Up @@ -1589,8 +1589,7 @@ pub(crate) mod tests {
message::{MessageType, RoomMessageEventContent},
},
AnyMessageLikeEvent, AnyMessageLikeEventContent, AnyRoomEvent, AnyToDeviceEvent,
AnyToDeviceEventContent, MessageLikeEvent, MessageLikeUnsigned,
OriginalMessageLikeEvent,
MessageLikeEvent, MessageLikeUnsigned, OriginalMessageLikeEvent,
},
room_id,
serde::Raw,
Expand Down Expand Up @@ -1717,7 +1716,7 @@ pub(crate) mod tests {
alice.get_device(&bob.user_id, &bob.device_id, None).await.unwrap().unwrap();

let (session, content) = bob_device
.encrypt(AnyToDeviceEventContent::Dummy(ToDeviceDummyEventContent::new()))
.encrypt("m.dummy", serde_json::to_value(ToDeviceDummyEventContent::new()).unwrap())
.await
.unwrap();
alice.store.save_sessions(&[session]).await.unwrap();
Expand Down Expand Up @@ -1945,7 +1944,7 @@ pub(crate) mod tests {
let event = ToDeviceEvent {
sender: alice.user_id().to_owned(),
content: bob_device
.encrypt(AnyToDeviceEventContent::Dummy(ToDeviceDummyEventContent::new()))
.encrypt("m.dummy", serde_json::to_value(ToDeviceDummyEventContent::new()).unwrap())
.await
.unwrap()
.1
Expand Down
8 changes: 6 additions & 2 deletions crates/matrix-sdk-crypto/src/olm/account.rs
Expand Up @@ -1094,7 +1094,7 @@ impl ReadOnlyAccount {
#[allow(dead_code)]
/// Testing only helper to create a session for the given Account
pub async fn create_session_for(&self, other: &ReadOnlyAccount) -> (Session, Session) {
use ruma::events::{dummy::ToDeviceDummyEventContent, AnyToDeviceEventContent};
use ruma::events::dummy::ToDeviceDummyEventContent;

other.generate_one_time_keys_helper(1).await;
let one_time = other.signed_one_time_keys().await;
Expand All @@ -1107,7 +1107,11 @@ impl ReadOnlyAccount {
other.mark_keys_as_published().await;

let message = our_session
.encrypt(&device, AnyToDeviceEventContent::Dummy(ToDeviceDummyEventContent::new()))
.encrypt(
&device,
"m.dummy",
serde_json::to_value(ToDeviceDummyEventContent::new()).unwrap(),
)
.await
.unwrap()
.deserialize()
Expand Down
29 changes: 15 additions & 14 deletions crates/matrix-sdk-crypto/src/olm/group_sessions/outbound.rs
Expand Up @@ -26,11 +26,7 @@ use std::{
use dashmap::DashMap;
use matrix_sdk_common::locks::Mutex;
use ruma::{
events::{
room::{encryption::RoomEncryptionEventContent, history_visibility::HistoryVisibility},
room_key::ToDeviceRoomKeyEventContent,
AnyToDeviceEventContent,
},
events::room::{encryption::RoomEncryptionEventContent, history_visibility::HistoryVisibility},
serde::Raw,
DeviceId, EventEncryptionAlgorithm, OwnedDeviceId, OwnedTransactionId, OwnedUserId, RoomId,
SecondsSinceUnixEpoch, TransactionId, UserId,
Expand All @@ -46,8 +42,11 @@ pub use vodozemac::{
};

use crate::{
types::events::room::encrypted::{
MegolmV1AesSha2Content, RoomEncryptedEventContent, RoomEventEncryptionScheme,
types::events::{
room::encrypted::{
MegolmV1AesSha2Content, RoomEncryptedEventContent, RoomEventEncryptionScheme,
},
room_key::{MegolmV1AesSha2Content as MegolmV1AesSha2RoomKeyContent, RoomKeyContent},
},
Device, ToDeviceRequest,
};
Expand Down Expand Up @@ -374,15 +373,17 @@ impl OutboundGroupSession {
session.message_index()
}

pub(crate) async fn as_content(&self) -> AnyToDeviceEventContent {
pub(crate) async fn as_content(&self) -> RoomKeyContent {
let session_key = self.session_key().await;

AnyToDeviceEventContent::RoomKey(ToDeviceRoomKeyEventContent::new(
EventEncryptionAlgorithm::MegolmV1AesSha2,
self.room_id().to_owned(),
self.session_id().to_owned(),
session_key.to_base64(),
))
RoomKeyContent::MegolmV1AesSha2(
MegolmV1AesSha2RoomKeyContent::new(
self.room_id().to_owned(),
self.session_id().to_owned(),
session_key,
)
.into(),
)
}

/// Has or will the session be shared with the given user/device pair.
Expand Down
13 changes: 4 additions & 9 deletions crates/matrix-sdk-crypto/src/olm/session.rs
Expand Up @@ -15,13 +15,9 @@
use std::{fmt, sync::Arc};

use matrix_sdk_common::locks::Mutex;
use ruma::{
events::{AnyToDeviceEventContent, EventContent},
serde::Raw,
DeviceId, SecondsSinceUnixEpoch, UserId,
};
use ruma::{serde::Raw, DeviceId, SecondsSinceUnixEpoch, UserId};
use serde::{Deserialize, Serialize};
use serde_json::json;
use serde_json::{json, Value};
use vodozemac::{
olm::{DecryptionError, OlmMessage, Session as InnerSession, SessionPickle},
Curve25519PublicKey,
Expand Down Expand Up @@ -117,13 +113,12 @@ impl Session {
pub async fn encrypt(
&mut self,
recipient_device: &ReadOnlyDevice,
content: AnyToDeviceEventContent,
event_type: &str,
content: Value,
) -> OlmResult<Raw<ToDeviceEncryptedEventContent>> {
let recipient_signing_key =
recipient_device.ed25519_key().ok_or(EventError::MissingSigningKey)?;

let event_type = content.event_type();

let payload = json!({
"sender": self.user_id.as_str(),
"sender_device": self.device_id.as_ref(),
Expand Down
18 changes: 10 additions & 8 deletions crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs
Expand Up @@ -35,7 +35,7 @@ use crate::{
error::{EventError, MegolmResult, OlmResult},
olm::{Account, InboundGroupSession, OutboundGroupSession, Session, ShareInfo, ShareState},
store::{Changes, Result as StoreResult, Store},
types::events::room::encrypted::RoomEncryptedEventContent,
types::events::{room::encrypted::RoomEncryptedEventContent, EventType},
Device, EncryptionSettings, OlmError, ToDeviceRequest,
};

Expand Down Expand Up @@ -216,7 +216,7 @@ impl GroupSessionManager {
/// Encrypt the given content for the given devices and create a to-device
/// requests that sends the encrypted content to them.
async fn encrypt_session_for(
content: AnyToDeviceEventContent,
content: OutboundGroupSession,
devices: Vec<Device>,
message_index: u32,
) -> OlmResult<(
Expand All @@ -237,11 +237,16 @@ impl GroupSessionManager {
let mut changed_sessions = Vec::new();
let mut share_infos = BTreeMap::new();

let encrypt = |device: Device, content: AnyToDeviceEventContent| async move {
let encrypt = |device: Device, session: OutboundGroupSession| async move {
let mut message = BTreeMap::new();
let mut share_info = BTreeMap::new();

let encrypted = device.encrypt(content.clone()).await;
let content = session.as_content().await;
let event_type = content.event_type();
let content =
serde_json::to_value(content).expect("We can always serialize our own room key");

let encrypted = device.encrypt(event_type, content).await;

let used_session = match encrypted {
Ok((session, encrypted)) => {
Expand Down Expand Up @@ -409,13 +414,12 @@ impl GroupSessionManager {

pub async fn encrypt_request(
chunk: Vec<Device>,
content: AnyToDeviceEventContent,
outbound: OutboundGroupSession,
message_index: u32,
being_shared: Arc<DashMap<OwnedTransactionId, OutboundGroupSession>>,
) -> OlmResult<Vec<Session>> {
let (id, request, share_infos, used_sessions) =
Self::encrypt_session_for(content.clone(), chunk, message_index).await?;
Self::encrypt_session_for(outbound.clone(), chunk, message_index).await?;

if !request.messages.is_empty() {
outbound.add_request(id.clone(), request.into(), share_infos);
Expand Down Expand Up @@ -499,7 +503,6 @@ impl GroupSessionManager {
})
.collect();

let key_content = outbound.as_content().await;
let message_index = outbound.message_index().await;

// If we have some recipients, log them here.
Expand Down Expand Up @@ -531,7 +534,6 @@ impl GroupSessionManager {
.map(|chunk| {
spawn(Self::encrypt_request(
chunk.to_vec(),
key_content.clone(),
outbound.clone(),
message_index,
self.sessions.sessions_being_shared.clone(),
Expand Down
6 changes: 3 additions & 3 deletions crates/matrix-sdk-crypto/src/session_manager/sessions.rs
Expand Up @@ -24,7 +24,7 @@ use ruma::{
Request as KeysClaimRequest, Response as KeysClaimResponse,
},
assign,
events::{dummy::ToDeviceDummyEventContent, AnyToDeviceEventContent},
events::dummy::ToDeviceDummyEventContent,
DeviceId, DeviceKeyAlgorithm, EventEncryptionAlgorithm, OwnedDeviceId, OwnedTransactionId,
OwnedUserId, SecondsSinceUnixEpoch, TransactionId, UserId,
};
Expand Down Expand Up @@ -140,8 +140,8 @@ impl SessionManager {
async fn check_if_unwedged(&self, user_id: &UserId, device_id: &DeviceId) -> OlmResult<()> {
if self.wedged_devices.get(user_id).and_then(|d| d.remove(device_id)).is_some() {
if let Some(device) = self.store.get_device(user_id, device_id).await? {
let content = AnyToDeviceEventContent::Dummy(ToDeviceDummyEventContent::new());
let (_, content) = device.encrypt(content).await?;
let content = serde_json::to_value(ToDeviceDummyEventContent::new())?;
let (_, content) = device.encrypt("m.dummy", content).await?;

let request = ToDeviceRequest::new(
device.user_id(),
Expand Down
7 changes: 7 additions & 0 deletions crates/matrix-sdk-crypto/src/types/events/room_key.rs
Expand Up @@ -110,6 +110,13 @@ pub struct MegolmV1AesSha2Content {
other: BTreeMap<String, Value>,
}

impl MegolmV1AesSha2Content {
/// Create a new `m.megolm.v1.aes-sha2` `m.room_key` content.
pub fn new(room_id: OwnedRoomId, session_id: String, session_key: SessionKey) -> Self {
Self { room_id, session_id, session_key, other: Default::default() }
}
}

impl std::fmt::Debug for MegolmV1AesSha2Content {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MegolmV1AesSha2Content")
Expand Down
11 changes: 9 additions & 2 deletions crates/matrix-sdk-crypto/src/types/events/secret_send.rs
Expand Up @@ -16,7 +16,7 @@

use std::collections::BTreeMap;

use ruma::events::secret::request::SecretName;
use ruma::{events::secret::request::SecretName, OwnedTransactionId};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use zeroize::Zeroize;
Expand All @@ -34,7 +34,7 @@ pub type SecretSendEvent = ToDeviceEvent<SecretSendContent>;
#[derive(Serialize, Deserialize)]
pub struct SecretSendContent {
/// The ID of the request that this a response to.
pub request_id: String,
pub request_id: OwnedTransactionId,
/// The contents of the secret.
pub secret: String,
/// The name of the secret, typically not part of the event but can be
Expand All @@ -47,6 +47,13 @@ pub struct SecretSendContent {
other: BTreeMap<String, Value>,
}

impl SecretSendContent {
/// Create a new `m.secret.send` content.
pub fn new(request_id: OwnedTransactionId, secret: String) -> Self {
Self { request_id, secret, secret_name: None, other: Default::default() }
}
}

impl Zeroize for SecretSendContent {
fn zeroize(&mut self) {
self.secret.zeroize();
Expand Down

0 comments on commit ddf8577

Please sign in to comment.