diff --git a/src/e2ee.rs b/src/e2ee.rs index e6332329e..e1c8f7c23 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -321,6 +321,11 @@ pub async fn ensure_secret_key_exists(context: &Context) -> Result { mod tests { use super::*; + use crate::chat; + use crate::constants::Viewtype; + use crate::contact::{Contact, Origin}; + use crate::message::Message; + use crate::param::Param; use crate::test_utils::*; mod ensure_secret_key_exists { @@ -381,4 +386,106 @@ Sent with my Delta Chat Messenger: https://delta.chat"; let data = b"blas"; assert_eq!(has_decrypted_pgp_armor(data), false); } + + #[async_std::test] + async fn test_encrypted_no_autocrypt() -> crate::error::Result<()> { + let alice = TestContext::new_alice().await; + let bob = TestContext::new_bob().await; + + let (contact_alice_id, _modified) = Contact::add_or_lookup( + &bob.ctx, + "Alice", + "alice@example.com", + Origin::ManuallyCreated, + ) + .await?; + let (contact_bob_id, _modified) = Contact::add_or_lookup( + &alice.ctx, + "Bob", + "bob@example.net", + Origin::ManuallyCreated, + ) + .await?; + + let chat_alice = chat::create_by_contact_id(&alice.ctx, contact_bob_id).await?; + let chat_bob = chat::create_by_contact_id(&bob.ctx, contact_alice_id).await?; + + // Alice sends unencrypted message to Bob + let mut msg = Message::new(Viewtype::Text); + chat::prepare_msg(&alice.ctx, chat_alice, &mut msg).await?; + chat::send_msg(&alice.ctx, chat_alice, &mut msg).await?; + let sent = alice.pop_sent_msg().await; + + // Bob receives unencrypted message from Alice + let msg = bob.parse_msg(&sent).await; + assert!(!msg.was_encrypted()); + + // Parsing a message is enough to update peerstate + let peerstate_alice = Peerstate::from_addr(&bob.ctx, "alice@example.com") + .await? + .expect("no peerstate found in the database"); + assert_eq!(peerstate_alice.prefer_encrypt, EncryptPreference::Mutual); + + // Bob sends encrypted message to Alice + let mut msg = Message::new(Viewtype::Text); + chat::prepare_msg(&bob.ctx, chat_bob, &mut msg).await?; + chat::send_msg(&bob.ctx, chat_bob, &mut msg).await?; + let sent = bob.pop_sent_msg().await; + + // Alice receives encrypted message from Bob + let msg = alice.parse_msg(&sent).await; + assert!(msg.was_encrypted()); + + let peerstate_bob = Peerstate::from_addr(&alice.ctx, "bob@example.net") + .await? + .expect("no peerstate found in the database"); + assert_eq!(peerstate_bob.prefer_encrypt, EncryptPreference::Mutual); + + // Now Alice and Bob have established keys. + + // Alice sends encrypted message without Autocrypt header. + let mut msg = Message::new(Viewtype::Text); + msg.param.set_int(Param::SkipAutocrypt, 1); + chat::prepare_msg(&alice.ctx, chat_alice, &mut msg).await?; + chat::send_msg(&alice.ctx, chat_alice, &mut msg).await?; + let sent = alice.pop_sent_msg().await; + + let msg = bob.parse_msg(&sent).await; + assert!(msg.was_encrypted()); + let peerstate_alice = Peerstate::from_addr(&bob.ctx, "alice@example.com") + .await? + .expect("no peerstate found in the database"); + assert_eq!(peerstate_alice.prefer_encrypt, EncryptPreference::Mutual); + + // Alice sends plaintext message with Autocrypt header. + let mut msg = Message::new(Viewtype::Text); + msg.param.set_int(Param::ForcePlaintext, 1); + chat::prepare_msg(&alice.ctx, chat_alice, &mut msg).await?; + chat::send_msg(&alice.ctx, chat_alice, &mut msg).await?; + let sent = alice.pop_sent_msg().await; + + let msg = bob.parse_msg(&sent).await; + assert!(!msg.was_encrypted()); + let peerstate_alice = Peerstate::from_addr(&bob.ctx, "alice@example.com") + .await? + .expect("no peerstate found in the database"); + assert_eq!(peerstate_alice.prefer_encrypt, EncryptPreference::Mutual); + + // Alice sends plaintext message without Autocrypt header. + let mut msg = Message::new(Viewtype::Text); + msg.param.set_int(Param::ForcePlaintext, 1); + msg.param.set_int(Param::SkipAutocrypt, 1); + chat::prepare_msg(&alice.ctx, chat_alice, &mut msg).await?; + chat::send_msg(&alice.ctx, chat_alice, &mut msg).await?; + let sent = alice.pop_sent_msg().await; + + let msg = bob.parse_msg(&sent).await; + assert!(!msg.was_encrypted()); + let peerstate_alice = Peerstate::from_addr(&bob.ctx, "alice@example.com") + .await? + .expect("no peerstate found in the database"); + assert_eq!(peerstate_alice.prefer_encrypt, EncryptPreference::Reset); + + Ok(()) + } }