Skip to content

Commit

Permalink
crypto: extract function that checks if session is shared too much
Browse files Browse the repository at this point in the history
  • Loading branch information
BillCarsonFr committed Aug 7, 2024
1 parent 1b05380 commit 2e7bb79
Showing 1 changed file with 40 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,33 +162,7 @@ pub(crate) async fn collect_session_recipients(
// of the devices in the session got deleted or blacklisted in the
// meantime. If so, we should also rotate the session.
if !should_rotate {
// Device IDs that should receive this session
let recipient_device_ids: BTreeSet<&DeviceId> =
recipients.iter().map(|d| d.device_id()).collect();

if let Some(shared) = outbound.shared_with_set.read().unwrap().get(user_id) {
// Devices that received this session
let shared: BTreeSet<OwnedDeviceId> = shared.keys().cloned().collect();
let shared: BTreeSet<&DeviceId> = shared.iter().map(|d| d.as_ref()).collect();

// The set difference between
//
// 1. Devices that had previously received the session, and
// 2. Devices that would now receive the session
//
// Represents newly deleted or blacklisted devices. If this
// set is non-empty, we must rotate.
let newly_deleted_or_blacklisted =
shared.difference(&recipient_device_ids).collect::<BTreeSet<_>>();

should_rotate = !newly_deleted_or_blacklisted.is_empty();
if should_rotate {
debug!(
"Rotating a room key due to these devices being deleted/blacklisted {:?}",
newly_deleted_or_blacklisted,
);
}
};
should_rotate = is_session_overshared_for_user(outbound, user_id, &recipients)
}

devices.entry(user_id.to_owned()).or_default().extend(recipients);
Expand All @@ -209,6 +183,45 @@ pub(crate) async fn collect_session_recipients(
Ok(CollectRecipientsResult { should_rotate, devices, withheld_devices })
}

// Checks if the session has been shared with a device that is not anymore in the
// pool of devices that should participate in the discussion.
fn is_session_overshared_for_user(
outbound: &OutboundGroupSession,
user_id: &UserId,
recipients: &Vec<DeviceData>,
) -> bool {
// Device IDs that should receive this session
let recipient_device_ids: BTreeSet<&DeviceId> =
recipients.iter().map(|d| d.device_id()).collect();

if let Some(shared) = outbound.shared_with_set.read().unwrap().get(user_id) {
// Devices that received this session
let shared: BTreeSet<OwnedDeviceId> = shared.keys().cloned().collect();
let shared: BTreeSet<&DeviceId> = shared.iter().map(|d| d.as_ref()).collect();

// The set difference between
//
// 1. Devices that had previously received the session, and
// 2. Devices that would now receive the session
//
// Represents newly deleted or blacklisted devices. If this
// set is non-empty, we must rotate.
let newly_deleted_or_blacklisted =
shared.difference(&recipient_device_ids).collect::<BTreeSet<_>>();

let should_rotate = !newly_deleted_or_blacklisted.is_empty();
if should_rotate {
debug!(
"Rotating a room key due to these devices being deleted/blacklisted {:?}",
newly_deleted_or_blacklisted,
);
}
should_rotate
} else {
false
}
}

struct RecipientDevices {
allowed_devices: Vec<DeviceData>,
denied_devices_with_code: Vec<(DeviceData, WithheldCode)>,
Expand Down

0 comments on commit 2e7bb79

Please sign in to comment.