mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
refactor: remove code to send messages without intended recipient fingerprint
This commit is contained in:
@@ -128,13 +128,7 @@ pub async fn pk_encrypt(
|
|||||||
hashed.push(Subpacket::critical(SubpacketData::SignatureCreationTime(
|
hashed.push(Subpacket::critical(SubpacketData::SignatureCreationTime(
|
||||||
pgp::types::Timestamp::now(),
|
pgp::types::Timestamp::now(),
|
||||||
))?);
|
))?);
|
||||||
// Test "elena" uses old Delta Chat.
|
|
||||||
let skip = private_key_for_signing.dc_fingerprint().hex()
|
|
||||||
== "B86586B6DEF437D674BFAFC02A6B2EBC633B9E82";
|
|
||||||
for key in &public_keys_for_encryption {
|
for key in &public_keys_for_encryption {
|
||||||
if skip {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let data = SubpacketData::IntendedRecipientFingerprint(key.fingerprint());
|
let data = SubpacketData::IntendedRecipientFingerprint(key.fingerprint());
|
||||||
let subpkt = match private_key_for_signing.version() < KeyVersion::V6 {
|
let subpkt = match private_key_for_signing.version() < KeyVersion::V6 {
|
||||||
true => Subpacket::regular(data)?,
|
true => Subpacket::regular(data)?,
|
||||||
|
|||||||
@@ -5108,97 +5108,75 @@ async fn test_dont_verify_by_verified_by_unknown() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests that second device assigns outgoing encrypted messages
|
||||||
|
/// to 1:1 chat with key-contact even if the key of the contact is unknown.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_recv_outgoing_msg_before_securejoin() -> Result<()> {
|
async fn test_recv_outgoing_msg_before_securejoin() -> Result<()> {
|
||||||
let mut tcm = TestContextManager::new();
|
let mut tcm = TestContextManager::new();
|
||||||
let bob = &tcm.bob().await;
|
let bob = &tcm.bob().await;
|
||||||
let a0 = &tcm.elena().await;
|
|
||||||
let a1 = &tcm.elena().await;
|
|
||||||
|
|
||||||
tcm.execute_securejoin(bob, a0).await;
|
|
||||||
let chat_id_a0_bob = a0.create_chat_id(bob).await;
|
|
||||||
let sent_msg = a0.send_text(chat_id_a0_bob, "Hi").await;
|
|
||||||
bob.recv_msg(&sent_msg).await;
|
|
||||||
let msg_a1 = a1.recv_msg(&sent_msg).await;
|
|
||||||
assert!(msg_a1.get_showpadlock());
|
|
||||||
let chat_a1 = Chat::load_from_db(a1, msg_a1.chat_id).await?;
|
|
||||||
assert_eq!(chat_a1.typ, Chattype::Group);
|
|
||||||
assert!(!chat_a1.is_encrypted(a1).await?);
|
|
||||||
assert_eq!(
|
|
||||||
chat::get_chat_contacts(a1, chat_a1.id).await?,
|
|
||||||
[a1.add_or_lookup_address_contact_id(bob).await]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
chat_a1.why_cant_send(a1).await?,
|
|
||||||
Some(CantSendReason::NotAMember)
|
|
||||||
);
|
|
||||||
|
|
||||||
let sent_msg = a0.send_text(chat_id_a0_bob, "Hi again").await;
|
|
||||||
bob.recv_msg(&sent_msg).await;
|
|
||||||
let msg_a1 = a1.recv_msg(&sent_msg).await;
|
|
||||||
assert!(msg_a1.get_showpadlock());
|
|
||||||
assert_eq!(msg_a1.chat_id, chat_a1.id);
|
|
||||||
let chat_a1 = Chat::load_from_db(a1, msg_a1.chat_id).await?;
|
|
||||||
assert_eq!(
|
|
||||||
chat_a1.why_cant_send(a1).await?,
|
|
||||||
Some(CantSendReason::NotAMember)
|
|
||||||
);
|
|
||||||
|
|
||||||
let msg_a1 = tcm.send_recv(bob, a1, "Hi back").await;
|
|
||||||
assert!(msg_a1.get_showpadlock());
|
|
||||||
let chat_a1 = Chat::load_from_db(a1, msg_a1.chat_id).await?;
|
|
||||||
assert_eq!(chat_a1.typ, Chattype::Single);
|
|
||||||
assert!(chat_a1.is_encrypted(a1).await?);
|
|
||||||
// Weird, but fine, anyway the bigger problem is the conversation split into two chats.
|
|
||||||
assert_eq!(
|
|
||||||
chat_a1.why_cant_send(a1).await?,
|
|
||||||
Some(CantSendReason::ContactRequest)
|
|
||||||
);
|
|
||||||
|
|
||||||
let a0 = &tcm.alice().await;
|
let a0 = &tcm.alice().await;
|
||||||
let a1 = &tcm.alice().await;
|
let a1 = &tcm.alice().await;
|
||||||
|
|
||||||
tcm.execute_securejoin(bob, a0).await;
|
tcm.execute_securejoin(bob, a0).await;
|
||||||
let chat_id_a0_bob = a0.create_chat_id(bob).await;
|
let chat_id_a0_bob = a0.create_chat_id(bob).await;
|
||||||
let sent_msg = a0.send_text(chat_id_a0_bob, "Hi").await;
|
let sent_msg = a0.send_text(chat_id_a0_bob, "Hi").await;
|
||||||
bob.recv_msg(&sent_msg).await;
|
|
||||||
|
// Device a1 does not have Bob's key.
|
||||||
|
// Message is still received in an encrypted 1:1 chat with Bob.
|
||||||
|
// a1 learns the fingerprint of Bob from the Intended Recipient Fingerprint packet,
|
||||||
|
// but not the key.
|
||||||
let msg_a1 = a1.recv_msg(&sent_msg).await;
|
let msg_a1 = a1.recv_msg(&sent_msg).await;
|
||||||
assert!(msg_a1.get_showpadlock());
|
assert!(msg_a1.get_showpadlock());
|
||||||
let chat_a1 = Chat::load_from_db(a1, msg_a1.chat_id).await?;
|
let chat_a1 = Chat::load_from_db(a1, msg_a1.chat_id).await?;
|
||||||
assert_eq!(chat_a1.typ, Chattype::Single);
|
assert_eq!(chat_a1.typ, Chattype::Single);
|
||||||
assert!(chat_a1.is_encrypted(a1).await?);
|
assert!(chat_a1.is_encrypted(a1).await?);
|
||||||
|
|
||||||
|
// Cannot send because a1 does not have Bob's key.
|
||||||
|
assert!(!chat_a1.can_send(a1).await?);
|
||||||
|
assert_eq!(
|
||||||
|
chat_a1.why_cant_send(a1).await?,
|
||||||
|
Some(CantSendReason::MissingKey)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
chat::get_chat_contacts(a1, chat_a1.id).await?,
|
chat::get_chat_contacts(a1, chat_a1.id).await?,
|
||||||
[a1.add_or_lookup_contact_id(bob).await]
|
[a1.add_or_lookup_contact_id_no_key(bob).await]
|
||||||
);
|
);
|
||||||
assert!(chat_a1.can_send(a1).await?);
|
assert!(!chat_a1.can_send(a1).await?);
|
||||||
|
|
||||||
|
let a1_chat_id = a1.create_chat_id(bob).await;
|
||||||
|
assert_eq!(a1_chat_id, msg_a1.chat_id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests that outgoing message cannot be assigned to 1:1 chat
|
||||||
|
/// without the intended recipient fingerprint.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_recv_outgoing_msg_before_having_key_and_after() -> Result<()> {
|
async fn test_recv_outgoing_msg_no_intended_recipient_fingerprint() -> Result<()> {
|
||||||
let mut tcm = TestContextManager::new();
|
let mut tcm = TestContextManager::new();
|
||||||
let a0 = &tcm.elena().await;
|
let alice = &tcm.alice().await;
|
||||||
let a1 = &tcm.elena().await;
|
|
||||||
let bob = &tcm.bob().await;
|
|
||||||
|
|
||||||
tcm.execute_securejoin(bob, a0).await;
|
let payload = include_bytes!(
|
||||||
let chat_id_a0_bob = a0.create_chat_id(bob).await;
|
"../../test-data/message/alice_to_bob_no_intended_recipient_fingerprint.eml"
|
||||||
let sent_msg = a0.send_text(chat_id_a0_bob, "Hi").await;
|
);
|
||||||
let msg_a1 = a1.recv_msg(&sent_msg).await;
|
|
||||||
assert!(msg_a1.get_showpadlock());
|
// Alice does not have Bob's key.
|
||||||
let chat_a1 = Chat::load_from_db(a1, msg_a1.chat_id).await?;
|
// Message is encrypted, but is received in ad hoc group with Bob's address.
|
||||||
assert_eq!(chat_a1.typ, Chattype::Group);
|
let rcvd_msg = receive_imf(alice, payload, false).await?.unwrap();
|
||||||
assert!(!chat_a1.is_encrypted(a1).await?);
|
let msg_alice = Message::load_from_db(alice, rcvd_msg.msg_ids[0]).await?;
|
||||||
|
|
||||||
|
assert!(msg_alice.get_showpadlock());
|
||||||
|
let chat_alice = Chat::load_from_db(alice, msg_alice.chat_id).await?;
|
||||||
|
assert_eq!(chat_alice.typ, Chattype::Group);
|
||||||
|
assert!(!chat_alice.is_encrypted(alice).await?);
|
||||||
|
|
||||||
|
// Cannot send because Bob's key is unknown.
|
||||||
|
assert!(!chat_alice.can_send(alice).await?);
|
||||||
|
assert_eq!(
|
||||||
|
chat_alice.why_cant_send(alice).await?,
|
||||||
|
Some(CantSendReason::NotAMember)
|
||||||
|
);
|
||||||
|
|
||||||
// Device a1 somehow learns Bob's key and creates the corresponding chat. However, this doesn't
|
|
||||||
// help because we only look up key contacts by address in a particular chat and the new chat
|
|
||||||
// isn't referenced by the received message. This is fixed by sending and receiving Intended
|
|
||||||
// Recipient Fingerprint subpackets which elena doesn't send.
|
|
||||||
a1.create_chat_id(bob).await;
|
|
||||||
let sent_msg = a0.send_text(chat_id_a0_bob, "Hi again").await;
|
|
||||||
let msg_a1 = a1.recv_msg(&sent_msg).await;
|
|
||||||
assert!(msg_a1.get_showpadlock());
|
|
||||||
assert_eq!(msg_a1.chat_id, chat_a1.id);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,6 @@ impl TestContextManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns new elena's "device".
|
/// Returns new elena's "device".
|
||||||
/// Elena doesn't send Intended Recipient Fingerprint subpackets to simulate old Delta Chat.
|
|
||||||
pub async fn elena(&mut self) -> TestContext {
|
pub async fn elena(&mut self) -> TestContext {
|
||||||
TestContext::builder()
|
TestContext::builder()
|
||||||
.configure_elena()
|
.configure_elena()
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
Content-Type: multipart/encrypted; protocol="application/pgp-encrypted";
|
||||||
|
boundary="189f5bdd65baabe1_1081b3a339e9a68e_ec024374690079d2"
|
||||||
|
MIME-Version: 1.0
|
||||||
|
From: <alice@example.org>
|
||||||
|
To: "hidden-recipients": ;
|
||||||
|
Subject: [...]
|
||||||
|
Date: Wed, 18 Mar 2026 14:03:13 +0000
|
||||||
|
Message-ID: <4bc40798-0029-42ef-b34a-77866db439a5@localhost>
|
||||||
|
Chat-Version: 1.0
|
||||||
|
|
||||||
|
|
||||||
|
--189f5bdd65baabe1_1081b3a339e9a68e_ec024374690079d2
|
||||||
|
Content-Type: application/pgp-encrypted; charset="utf-8"
|
||||||
|
Content-Description: PGP/MIME version identification
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
Version: 1
|
||||||
|
|
||||||
|
--189f5bdd65baabe1_1081b3a339e9a68e_ec024374690079d2
|
||||||
|
Content-Type: application/octet-stream; name="encrypted.asc";
|
||||||
|
charset="utf-8"
|
||||||
|
Content-Description: OpenPGP encrypted message
|
||||||
|
Content-Disposition: inline; filename="encrypted.asc";
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
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
|
||||||
|
VEJ9Mqz+YT5A4e+3inYfrmfVdNHNmF4y
|
||||||
|
=2p4+
|
||||||
|
-----END PGP MESSAGE-----
|
||||||
|
|
||||||
|
|
||||||
|
--189f5bdd65baabe1_1081b3a339e9a68e_ec024374690079d2--
|
||||||
Reference in New Issue
Block a user