fix: Auto-restore 1:1 chat protection if contact is only forward verified

Follow-up to 3f1dfef0e7. Forward verification is sufficient to have
the 1:1 chat protected, backwards verification is needed to add the contact to verified groups.
This commit is contained in:
iequidoo
2024-10-26 19:05:56 -03:00
parent 19dc16d9d3
commit 00a4e96a36
3 changed files with 36 additions and 16 deletions

View File

@@ -1010,7 +1010,7 @@ async fn add_parts(
&& peerstate.prefer_encrypt == EncryptPreference::Mutual
// Check that the contact still has the Autocrypt key same as the
// verified key, see also `Peerstate::is_using_verified_key()`.
&& contact.is_verified(context).await?;
&& contact.is_forward_verified(context).await?;
}
}
}

View File

@@ -1171,29 +1171,42 @@ fn print_logevent(logevent: &LogEvent) {
}
/// Saves the other account's public key as verified
/// and peerstate as backwards verified.
pub(crate) async fn mark_as_verified(this: &TestContext, other: &TestContext) {
/// and peerstate as backwards verified / not verified.
pub(crate) async fn mark_as_verified_ex(
this: &TestContext,
other: &TestContext,
last_seen: i64,
backward: bool,
) {
let mut peerstate = Peerstate::from_header(
&EncryptHelper::new(other).await.unwrap().get_aheader(),
// We have to give 0 as the time, not the current time:
// The time is going to be saved in peerstate.last_seen.
// The code in `peerstate.rs` then compares `if message_time > self.last_seen`,
// and many similar checks in peerstate.rs, and doesn't allow changes otherwise.
// Giving the current time would mean that message_time == peerstate.last_seen,
// so changes would not be allowed.
// This might lead to flaky tests.
0,
last_seen,
);
peerstate.verified_key.clone_from(&peerstate.public_key);
peerstate
.verified_key_fingerprint
.clone_from(&peerstate.public_key_fingerprint);
peerstate.backward_verified_key_id = Some(this.get_config_i64(Config::KeyId).await.unwrap());
peerstate.backward_verified_key_id = match backward {
true => Some(this.get_config_i64(Config::KeyId).await.unwrap()),
false => None,
};
peerstate.save_to_db(&this.sql).await.unwrap();
}
/// Saves the other account's public key as verified
/// and peerstate as backwards verified.
pub(crate) async fn mark_as_verified(this: &TestContext, other: &TestContext) {
// We have to give 0 as the time, not the current time: The time is going to be saved in
// peerstate.last_seen. The code in `peerstate.rs` then compares `if message_time >
// self.last_seen`, and many similar checks in peerstate.rs, and doesn't allow changes
// otherwise. Giving the current time would mean that message_time == peerstate.last_seen, so
// changes would not be allowed. This might lead to flaky tests.
let last_seen = 0;
let backward = true;
mark_as_verified_ex(this, other, last_seen, backward).await
}
/// Pops a sync message from alice0 and receives it on alice1. Should be used after an action on
/// alice0's side that implies sending a sync message.
pub(crate) async fn sync(alice0: &TestContext, alice1: &TestContext) {

View File

@@ -11,8 +11,10 @@ use crate::mimefactory::MimeFactory;
use crate::mimeparser::SystemMessage;
use crate::receive_imf::receive_imf;
use crate::stock_str;
use crate::test_utils::{get_chat_msg, mark_as_verified, TestContext, TestContextManager};
use crate::tools::SystemTime;
use crate::test_utils::{
get_chat_msg, mark_as_verified, mark_as_verified_ex, TestContext, TestContextManager,
};
use crate::tools::{time, SystemTime};
use crate::{e2ee, message};
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
@@ -754,11 +756,16 @@ async fn test_message_from_old_dc_setup() -> Result<()> {
tcm.send_recv(bob, alice, "Now i have it!").await;
assert_verified(alice, bob, ProtectionStatus::Protected).await;
// Forward verification should be sufficient to keep the chat protected.
let backward = false;
mark_as_verified_ex(alice, bob, time() - 1, backward).await;
let msg = alice.recv_msg(&sent_old).await;
assert!(!msg.get_showpadlock());
let contact = alice.add_or_lookup_contact(bob).await;
// The outdated Bob's Autocrypt header isn't applied, so the verification preserves.
assert!(contact.is_verified(alice).await.unwrap());
assert!(contact.is_forward_verified(alice).await.unwrap());
assert!(!contact.is_verified(alice).await.unwrap());
let chat = alice.get_chat(bob).await;
assert!(chat.is_protected());
assert_eq!(chat.is_protection_broken(), false);