From dc6d48b01150b9f4a2c302403bd8ffb8d24f2bee Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 26 Mar 2024 22:23:26 +0100 Subject: [PATCH] test(olm): Add remaining mutation tests Relates to: #78 Signed-off-by: Johannes Marbach --- .cargo/mutants.toml | 5 ++++ src/olm/messages/mod.rs | 12 +++++++- src/olm/session/chain_key.rs | 22 +++++++++++++++ src/olm/session/mod.rs | 54 ++++++++++++++++++++++++++++++++++++ src/olm/session/ratchet.rs | 20 +++++++++++++ src/olm/session_config.rs | 12 ++++++++ 6 files changed, 124 insertions(+), 1 deletion(-) diff --git a/.cargo/mutants.toml b/.cargo/mutants.toml index f8c0f180..9ddea662 100644 --- a/.cargo/mutants.toml +++ b/.cargo/mutants.toml @@ -7,4 +7,9 @@ exclude_re = [ "src/olm/messages/message\\.rs.*replace \\+ with \\* in ::try_from", # Drop implementations perform zeroisation which cannot be tested in Rust "impl Drop", + # These cause olm/account tests to hang + "RemoteChainKey::chain_index", + "RemoteChainKey::advance", + # The constant value can't really be tested + "src/olm/account/one_time_keys\\.rs.*replace \\* with \\+$", ] diff --git a/src/olm/messages/mod.rs b/src/olm/messages/mod.rs index 33471177..39a75c5d 100644 --- a/src/olm/messages/mod.rs +++ b/src/olm/messages/mod.rs @@ -189,9 +189,17 @@ mod tests { eUppqmWqug4QASIgRhZ2cgZcIWQbIa23R7U4y1Mo1R/t\ LCaMU+xjzRV5smGsCrJ6AHwktg"; + const PRE_KEY_MESSAGE_CIPHERTEXT: [u8; 32] = [ + 70, 22, 118, 114, 6, 92, 33, 100, 27, 33, 173, 183, 71, 181, 56, 203, 83, 40, 213, 31, 237, + 44, 38, 140, 83, 236, 99, 205, 21, 121, 178, 97, + ]; + const MESSAGE: &str = "AwogI7JhE/UsMZqXKb3xV6kUZWoJc6jTm2+AIgWYmaETIR0QASIQ\ +X2zb7kEX/3JvoLspcNBcLWOFXYpV0nS"; + const MESSAGE_CIPHERTEXT: [u8; 16] = + [249, 125, 179, 111, 185, 4, 95, 253, 201, 190, 130, 236, 165, 195, 65, 112]; + #[test] fn message_type_from_usize() { assert_eq!( @@ -246,15 +254,17 @@ mod tests { MessageType::PreKey, "Expected message to be recognized as a pre-key Olm message." ); - + assert_eq!(message.message(), PRE_KEY_MESSAGE_CIPHERTEXT); assert_eq!(message.to_parts(), (0, PRE_KEY_MESSAGE.to_string()), "Roundtrip not identity."); let message = OlmMessage::from_parts(1, MESSAGE)?; + assert_matches!(message, OlmMessage::Normal(_)); assert_eq!( message.message_type(), MessageType::Normal, "Expected message to be recognized as a normal Olm message." ); + assert_eq!(message.message(), MESSAGE_CIPHERTEXT); assert_eq!(message.to_parts(), (1, MESSAGE.to_string()), "Roundtrip not identity."); OlmMessage::from_parts(3, PRE_KEY_MESSAGE) diff --git a/src/olm/session/chain_key.rs b/src/olm/session/chain_key.rs index e141d3bc..8518e3bf 100644 --- a/src/olm/session/chain_key.rs +++ b/src/olm/session/chain_key.rs @@ -121,3 +121,25 @@ impl ChainKey { message_key } } + +#[cfg(test)] +mod tests { + use super::ChainKey; + use crate::olm::session::chain_key::RemoteChainKey; + + #[test] + fn advancing_chain_key_increments_index() { + let mut key = ChainKey::new(Box::new(*b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); + assert_eq!(key.index(), 0); + key.advance(); + assert_eq!(key.index(), 1); + } + + #[test] + fn advancing_remote_chain_key_increments_index() { + let mut key = RemoteChainKey::new(Box::new(*b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); + assert_eq!(key.chain_index(), 0); + key.advance(); + assert_eq!(key.chain_index(), 1); + } +} diff --git a/src/olm/session/mod.rs b/src/olm/session/mod.rs index 3d55da0c..8b9a9f16 100644 --- a/src/olm/session/mod.rs +++ b/src/olm/session/mod.rs @@ -571,6 +571,26 @@ mod test { } } + #[test] + fn session_config() { + let (_, _, alice_session, _) = session_and_libolm_pair().unwrap(); + assert_eq!(alice_session.session_config(), SessionConfig::version_1()); + } + + #[test] + fn has_received_message() { + let (_, _, mut alice_session, bob_session) = session_and_libolm_pair().unwrap(); + assert!(!alice_session.has_received_message()); + assert!(!bob_session.has_received_message()); + let message = bob_session.encrypt("Message").into(); + assert_eq!( + "Message".as_bytes(), + alice_session.decrypt(&message).expect("Should be able to decrypt message") + ); + assert!(alice_session.has_received_message()); + assert!(!bob_session.has_received_message()); + } + #[test] fn out_of_order_decryption() { let (_, _, mut alice_session, bob_session) = session_and_libolm_pair().unwrap(); @@ -680,6 +700,40 @@ mod test { ); } + #[test] + fn pickle_default_config() { + let json = r#" + { + "receiving_chains": { + "inner": [] + }, + "sending_ratchet": { + "active_ratchet": { + "ratchet_key": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "root_key": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + }, + "parent_ratchet_key": null, + "ratchet_count": { + "Known": 1 + }, + "symmetric_key_ratchet": { + "index": 1, + "key": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] + }, + "type": "active" + }, + "session_keys": { + "base_key": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], + "identity_key": [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], + "one_time_key": [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6] + } + } + "#; + let pickle: SessionPickle = + serde_json::from_str(json).expect("Should be able to deserialize JSON"); + assert_eq!(pickle.config, SessionConfig::version_1()); + } + #[test] #[cfg(feature = "libolm-compat")] fn libolm_unpickling() { diff --git a/src/olm/session/ratchet.rs b/src/olm/session/ratchet.rs index 41b88a25..bea3a69c 100644 --- a/src/olm/session/ratchet.rs +++ b/src/olm/session/ratchet.rs @@ -144,3 +144,23 @@ impl Ratchet { &self.ratchet_key } } + +#[cfg(test)] +mod test { + use super::RatchetKey; + use crate::{olm::RatchetPublicKey, Curve25519SecretKey}; + + #[test] + fn ratchet_key_from_curve_25519_secret_key() { + let bytes = b"aaaaaaaaaaaaaaawaaaaaaaaaaaaaaaa"; + let key = RatchetKey::from(Curve25519SecretKey::from_slice(bytes)); + assert_eq!(key.0.to_bytes().as_ref(), bytes); + } + + #[test] + fn ratchet_public_key_from_bytes() { + let bytes = b"aaaaaaaaaaaaaaawaaaaaaaaaaaaaaaa"; + let key = RatchetPublicKey::from(*bytes); + assert_eq!(key.0.to_bytes().as_ref(), bytes); + } +} diff --git a/src/olm/session_config.rs b/src/olm/session_config.rs index 9310871c..62d9b923 100644 --- a/src/olm/session_config.rs +++ b/src/olm/session_config.rs @@ -53,3 +53,15 @@ impl Default for SessionConfig { Self::version_2() } } + +#[cfg(test)] +mod test { + use super::SessionConfig; + use crate::olm::session_config::Version; + + #[test] + fn version() { + assert_eq!(SessionConfig::version_1().version(), Version::V1 as u8); + assert_eq!(SessionConfig::version_2().version(), Version::V2 as u8); + } +}