refactor(crypto): Use the vodozemac method to decide if a session is better

This patch delegates the decision making if a session is better to
vodozemac. Vodozemac has better insights if a group session can be
considered to be better.
This commit is contained in:
Damir Jelić
2022-08-02 14:53:06 +02:00
parent 3bdb2f22ea
commit f055e939e7
8 changed files with 39 additions and 54 deletions

View File

@@ -57,7 +57,7 @@ features = ["rt-multi-thread"]
[dependencies.vodozemac]
git = "https://github.com/matrix-org/vodozemac/"
rev = "18bcbc3359298894415931547ea41abb75af2d4a"
rev = "779e85258ec83b10ae62ec4d848188b188aa7b42"
[build-dependencies]
uniffi_build = { version = "0.18.0", features = ["builtin-bindgen"] }

View File

@@ -41,5 +41,5 @@ tracing-subscriber = { version = "0.3.14", default-features = false, features =
[dependencies.vodozemac]
git = "https://github.com/matrix-org/vodozemac/"
rev = "18bcbc3359298894415931547ea41abb75af2d4a"
rev = "779e85258ec83b10ae62ec4d848188b188aa7b42"
features = ["js"]

View File

@@ -36,7 +36,7 @@ tracing-subscriber = { version = "0.3", default-features = false, features = ["t
[dependencies.vodozemac]
git = "https://github.com/matrix-org/vodozemac/"
rev = "18bcbc3359298894415931547ea41abb75af2d4a"
rev = "779e85258ec83b10ae62ec4d848188b188aa7b42"
features = ["js"]
[build-dependencies]

View File

@@ -62,11 +62,11 @@ features = ["client-api-c", "rand", "canonical-json", "unstable-msc2676", "unsta
[target.'cfg(not(target_arch = "wasm32"))'.dependencies.vodozemac]
git = "https://github.com/matrix-org/vodozemac/"
rev = "18bcbc3359298894415931547ea41abb75af2d4a"
rev = "779e85258ec83b10ae62ec4d848188b188aa7b42"
[target.'cfg(target_arch = "wasm32")'.dependencies.vodozemac]
git = "https://github.com/matrix-org/vodozemac/"
rev = "18bcbc3359298894415931547ea41abb75af2d4a"
rev = "779e85258ec83b10ae62ec4d848188b188aa7b42"
features = ["js"]
[dev-dependencies]

View File

@@ -36,7 +36,7 @@ use ruma::{
OwnedUserId, RoomId, TransactionId, UserId,
};
use tracing::{debug, info, trace, warn};
use vodozemac::Curve25519PublicKey;
use vodozemac::{megolm::SessionOrdering, Curve25519PublicKey};
use super::{GossipRequest, KeyForwardDecision, RequestEvent, RequestInfo, SecretInfo, WaitQueue};
use crate::{
@@ -899,10 +899,7 @@ impl GossipMachine {
// 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();
let first_index = session.first_known_index();
if first_old_index > first_index {
if session.compare(&old_session).await == SessionOrdering::Better {
self.mark_as_done(info).await?;
Some(session)
} else {

View File

@@ -43,7 +43,7 @@ use ruma::{
};
use serde_json::{value::to_raw_value, Value};
use tracing::{debug, error, info, trace, warn};
use vodozemac::{Curve25519PublicKey, Ed25519Signature};
use vodozemac::{megolm::SessionOrdering, Curve25519PublicKey, Ed25519Signature};
#[cfg(feature = "backups_v1")]
use crate::backups::BackupMachine;
@@ -1330,45 +1330,18 @@ impl OlmMachine {
#[allow(unused_variables)] from_backup: bool,
progress_listener: impl Fn(usize, usize),
) -> StoreResult<RoomKeyImportResult> {
type SessionIdToIndexMap = BTreeMap<Arc<str>, u32>;
#[derive(Debug)]
struct ShallowSessions {
inner: BTreeMap<Arc<RoomId>, BTreeMap<String, SessionIdToIndexMap>>,
}
impl ShallowSessions {
fn has_better_session(&self, session: &InboundGroupSession) -> bool {
self.inner
.get(&session.room_id)
.and_then(|m| {
m.get(&session.sender_key.to_base64()).and_then(|m| {
m.get(&session.session_id)
.map(|existing| existing <= &session.first_known_index())
})
})
.unwrap_or(false)
}
}
let mut sessions = Vec::new();
let existing_sessions = ShallowSessions {
inner: self.store.get_inbound_group_sessions().await?.into_iter().fold(
BTreeMap::new(),
|mut acc, s| {
let index = s.first_known_index();
acc.entry(s.room_id)
.or_default()
.entry(s.sender_key.to_base64())
.or_default()
.insert(s.session_id, index);
acc
},
),
};
async fn new_session_better(
session: &InboundGroupSession,
old_session: Option<InboundGroupSession>,
) -> bool {
if let Some(old_session) = &old_session {
session.compare(old_session).await == SessionOrdering::Better
} else {
true
}
}
let total_count = exported_keys.len();
let mut keys = BTreeMap::new();
@@ -1376,10 +1349,18 @@ impl OlmMachine {
for (i, key) in exported_keys.into_iter().enumerate() {
match InboundGroupSession::from_export(&key) {
Ok(session) => {
// 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.
if !existing_sessions.has_better_session(&session) {
let old_session = self
.store
.get_inbound_group_session(
session.room_id(),
&session.sender_key.to_base64(),
session.session_id(),
)
.await?;
// Only import the session if we didn't have this session or
// if it's a better version of the same session.
if new_session_better(&session, old_session).await {
#[cfg(feature = "backups_v1")]
if from_backup {
session.mark_as_backed_up();

View File

@@ -35,7 +35,7 @@ use serde_json::Value;
use vodozemac::{
megolm::{
DecryptedMessage, DecryptionError, ExportedSessionKey, InboundGroupSession as InnerSession,
InboundGroupSessionPickle, MegolmMessage,
InboundGroupSessionPickle, MegolmMessage, SessionOrdering,
},
Curve25519PublicKey, PickleError,
};
@@ -330,6 +330,13 @@ impl InboundGroupSession {
self.first_known_index
}
/// Check if the `InboundGroupSession` is better than the given other
/// `InboundGroupSession`
pub async fn compare(&self, other: &InboundGroupSession) -> SessionOrdering {
let mut other = other.inner.lock().await;
self.inner.lock().await.compare(&mut other)
}
/// Decrypt the given ciphertext.
///
/// Returns the decrypted plaintext or an `DecryptionError` if

View File

@@ -30,4 +30,4 @@ thiserror = "1.0.30"
[dependencies.vodozemac]
git = "https://github.com/matrix-org/vodozemac/"
rev = "18bcbc3359298894415931547ea41abb75af2d4a"
rev = "779e85258ec83b10ae62ec4d848188b188aa7b42"