From cdd1ccb45886a77dada8bdbd27b73699d7911720 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Sat, 5 Sep 2020 21:11:19 +0300 Subject: [PATCH] Ignore reordered autocrypt headers This commit fixes condition which ignores reordered autocrypt messages. If a plaintext message resetting peerstate has been received, autocrypt header should only be applied if it has higher timestamp. Previously, timestamp of the last received autocrypt header was used, which may be lower than last_seen timestamp. # Conflicts: # src/peerstate.rs --- src/peerstate.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/peerstate.rs b/src/peerstate.rs index 09fab2b92..890c17818 100644 --- a/src/peerstate.rs +++ b/src/peerstate.rs @@ -290,7 +290,7 @@ impl<'a> Peerstate<'a> { return; } - if message_time > self.last_seen_autocrypt { + if message_time > self.last_seen { self.last_seen = message_time; self.last_seen_autocrypt = message_time; self.to_save = Some(ToSave::Timestamps); @@ -634,4 +634,45 @@ mod tests { assert_eq!(peerstate.gossip_key_fingerprint, None); assert_eq!(peerstate.verified_key_fingerprint, None); } + + #[async_std::test] + async fn test_peerstate_degrade_reordering() { + let context = crate::test_utils::TestContext::new().await.ctx; + let addr = "example@example.org"; + let pub_key = alice_keypair().public; + let header = Aheader::new(addr.to_string(), pub_key, EncryptPreference::Mutual); + + let mut peerstate = Peerstate { + context: &context, + addr: addr.to_string(), + last_seen: 0, + last_seen_autocrypt: 0, + prefer_encrypt: EncryptPreference::NoPreference, + public_key: None, + public_key_fingerprint: None, + gossip_key: None, + gossip_timestamp: 0, + gossip_key_fingerprint: None, + verified_key: None, + verified_key_fingerprint: None, + to_save: None, + fingerprint_changed: false, + }; + assert_eq!(peerstate.prefer_encrypt, EncryptPreference::NoPreference); + + peerstate.apply_header(&header, 100); + assert_eq!(peerstate.prefer_encrypt, EncryptPreference::Mutual); + + peerstate.degrade_encryption(300); + assert_eq!(peerstate.prefer_encrypt, EncryptPreference::Reset); + + // This has message time 200, while encryption was degraded at timestamp 300. + // Because of reordering, header should not be applied. + peerstate.apply_header(&header, 200); + assert_eq!(peerstate.prefer_encrypt, EncryptPreference::Reset); + + // Same header will be applied in the future. + peerstate.apply_header(&header, 400); + assert_eq!(peerstate.prefer_encrypt, EncryptPreference::Mutual); + } }