Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/receive_imf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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?;
}
}
}
Expand Down
37 changes: 25 additions & 12 deletions src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
13 changes: 10 additions & 3 deletions src/tests/verified_chats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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);
Expand Down
Loading