From a328d8787aedde78c568a42ec5f16221ff9ab2df Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 14 Mar 2024 15:22:46 +0000 Subject: [PATCH] crypto: Log errors from Olm decryption (#3212) When we fail to decrypt an olm message, it is useful to know *why* it failed. Include the details of the failures in the warning message. --- crates/matrix-sdk-crypto/CHANGELOG.md | 3 ++ crates/matrix-sdk-crypto/src/olm/account.rs | 35 +++++++++++---------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/crates/matrix-sdk-crypto/CHANGELOG.md b/crates/matrix-sdk-crypto/CHANGELOG.md index d5392f44a..0dedf8903 100644 --- a/crates/matrix-sdk-crypto/CHANGELOG.md +++ b/crates/matrix-sdk-crypto/CHANGELOG.md @@ -10,6 +10,9 @@ Breaking changes: Additions: +- When Olm message decryption fails, report the error code(s) from the failure. + ([#3212](https://github.com/matrix-org/matrix-rust-sdk/pull/3212)) + - Expose new methods `OlmMachine::set_room_settings` and `OlmMachine::get_room_settings`. ([#3042](https://github.com/matrix-org/matrix-rust-sdk/pull/3042)) diff --git a/crates/matrix-sdk-crypto/src/olm/account.rs b/crates/matrix-sdk-crypto/src/olm/account.rs index 36bd37ed7..8773365eb 100644 --- a/crates/matrix-sdk-crypto/src/olm/account.rs +++ b/crates/matrix-sdk-crypto/src/olm/account.rs @@ -1136,32 +1136,33 @@ impl Account { match message { OlmMessage::Normal(_) => { - let session_ids = if let Some(sessions) = existing_sessions { + let mut errors_by_olm_session = Vec::new(); + + if let Some(sessions) = existing_sessions { let sessions = &mut *sessions.lock().await; // Try to decrypt the message using each Session we share with the // given curve25519 sender key. for session in sessions.iter_mut() { - if let Ok(p) = session.decrypt(message).await { - // success! - return Ok((SessionType::Existing(session.clone()), p)); - } else { - // An error here is completely normal, after all we don't know - // which session was used to encrypt a message. We will log a - // warning if no session was able to decrypt the message. - continue; + match session.decrypt(message).await { + Ok(p) => { + // success! + return Ok((SessionType::Existing(session.clone()), p)); + } + + Err(e) => { + // An error here is completely normal, after all we don't know + // which session was used to encrypt a message. + // We keep hold of the error, so that if *all* sessions fail to + // decrypt, we can log something useful. + errors_by_olm_session.push((session.session_id().to_owned(), e)); + } } } - - // decryption wasn't successful with any of the sessions. Collect a list of - // session IDs to log. - sessions.iter().map(|s| s.session_id().to_owned()).collect() - } else { - vec![] - }; + } warn!( - ?session_ids, + ?errors_by_olm_session, "Failed to decrypt a non-pre-key message with all available sessions" ); Err(OlmError::SessionWedged(sender.to_owned(), sender_key))