From a94e2f06eea5ded3d7271e3351dcf6c8abb0c307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 16 Jun 2023 15:27:38 +0200 Subject: [PATCH] Ensure that we're not creating the same session twice Usually it's impossible to create a Olm session from a pre-key message twice. The one-time key that should be used for the 3DH step will be used up and we're going to throw a `MissingOneTimeKey` error. This used to be true and unproblematic until we added fallback keys, these keys will not get discarded immediately after they have been used once. This means that a pre-key message, for which we already have a Session, but decryption for it fails, might create a new Session overwriting the existing one which will essentially reset the ratchet. --- crates/matrix-sdk-crypto/src/olm/account.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/matrix-sdk-crypto/src/olm/account.rs b/crates/matrix-sdk-crypto/src/olm/account.rs index 67117e54cdb..db38237952e 100644 --- a/crates/matrix-sdk-crypto/src/olm/account.rs +++ b/crates/matrix-sdk-crypto/src/olm/account.rs @@ -273,6 +273,24 @@ impl Account { if let Ok(p) = session.decrypt(message).await { decrypted = Some((session.clone(), p)); break; + } else if let OlmMessage::PreKey(message) = message { + if message.session_id() == session.session_id() { + // The message was intended for this session, but we weren't able to decrypt it. + // + // We're going to return early here since no other session will be able to + // decrypt this message, nor should we try to create a new one since we already + // created a `Session` with such a pre-key message. + // + // Creating a new session will likely fail since the one-time key that should be + // used to establish the session will be used up. + // + // The one exception where creating a new session won't fail is if a fallback + // key was used for this `Session`. + return Err(OlmError::SessionWedged( + session.user_id.to_owned(), + session.sender_key(), + )); + } } 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