refactorings/preparations for introduce asymetrically encrypted keyupdates - #8620
refactorings/preparations for introduce asymetrically encrypted keyupdates #8620hpk42 wants to merge 3 commits into
Conversation
a871291 to
7c7c14e
Compare
| // and nothing else should come out of it: no contact, no chat, | ||
| // and no `last_seen` update lighting up an online dot. | ||
| info!(context, "Report without message reference (TRASH)."); | ||
| return trash().await; |
There was a problem hiding this comment.
not strictly neccessary but a short-cut to simplify reasoning about keyupdates in the future, to ensure the subsequent receive_imf code never sees this empty MDN.
There was a problem hiding this comment.
This code is only for users who upgraded, so we still need to check that nothing really bad happens on versions that don't have this code (contacts/chats appearing etc., not just the green dot). Having this code before key updates may hide problems if something other than green dot on the address-contact appears as a result.
EDIT: it is tested with test_keyupdate_against_core_2_48_march_2026 in #8621
7c7c14e to
715e1cc
Compare
|
|
||
| /// Returns the protected headers shared by encrypted messages | ||
| /// that are not part of a chat. | ||
| async fn non_chat_protected_headers( |
There was a problem hiding this comment.
All headers are protected in some way except for Chat-Is-Post-Message, so not sure what protected means here.
There was a problem hiding this comment.
I guess the function should be renamed too, then? To non_chat_headers or headers_for_non_chat_msg?
There was a problem hiding this comment.
I actually meant the function name, it is still _protected_. It's fine, i just don't know why it has _protected_ in the name.
| Ok(mime_parser) => mime_parser, | ||
| }; | ||
|
|
||
| if !mime_parser.mdn_reports.is_empty() |
There was a problem hiding this comment.
I tried commenting this out (if false &&), the test test_mdn_without_message_reference fails then but only because a contact is created that is not visible.
Without this "address-contact" probably still gets a green dot, not a problem because the user needs to create a visible address-contact chat first to even see this contact.
No functional changes: Add a relay_addrs helper, share the protected headers and self-key rendering of non-chat messages, and move insert_into_smtp from securejoin to smtp.
…ages An unsigned message carries no intended recipient fingerprints, so recipients of an encrypted unsigned message learn nothing about other recipients from the PGP packets.
A report referencing no message can never be applied to one, so it must not create a contact, a chat or a `last_seen` update on its way to the trash.
715e1cc to
36c0231
Compare
| } | ||
|
|
||
| /// Returns the protected headers shared by encrypted messages | ||
| /// that are not part of a chat. |
There was a problem hiding this comment.
I didn't understand this comment until I looked at what the function is used for
| /// that are not part of a chat. | |
| /// Returns the protected headers shared by | |
| /// encrypted messages that are not part of a chat, | |
| /// i.e. key update messages and | |
| /// symmetrically encrypted securejoin messages. |
There was a problem hiding this comment.
This is outdated, comment is already changed: #8620 (comment)
| /// Tests that a message encrypted without a signing key has no signature, | ||
| /// and therefore no intended recipient fingerprints naming the other recipients. | ||
| #[tokio::test(flavor = "multi_thread", worker_threads = 2)] | ||
| async fn test_encrypt_unsigned() { |
There was a problem hiding this comment.
This test is tautological, and doesn't test anything - it tests that if you don't pass any signing key to pk_encrypt, then it doesn't sign the message. And even if pk_encrypt somehow managed to sign the message with some dummy key (and include intended recipients), then the test would still pass, because pk_decrypt_and_validate ignores any signature that does not validate against sig_check_keyring.
I think the test can just be removed. I'm not sure if rpgp exposes a way to check if there is any signature inside a message; if so, then such a check could go into test_send_and_receive_keyupdate.
There was a problem hiding this comment.
There was a problem hiding this comment.
test_send_and_receive_keyupdate already has this test, there is this code:
// A keyupdate is trashed on old cores because it's unsigned MDN
// without a message reference. See also cross-core Python tests.
let mail = mailparse::parse_mail(keyupdate.payload.as_bytes())?;
let (mut decrypted, _fingerprint) = decrypt(bob, &mail).await?.unwrap();
// The next line is important: A key update message must NOT be signed,
// as the signature might contain intended recipient fingerprints,
// leaking all of the sender's contacts to all the other contacts.
assert!(!decrypted.is_signed());decrypted is a pgp::composed::Message
| /// Tests that an MDN referencing no message is trashed early: | ||
| /// there is nothing it could ever be applied to, | ||
| /// so it must not create a contact or a chat on the way. | ||
| #[tokio::test(flavor = "multi_thread", worker_threads = 2)] | ||
| async fn test_mdn_without_message_reference() -> Result<()> { |
There was a problem hiding this comment.
Just from looking at the test and its documentation, it's unclear why we need this test, i.e. why it's important that an MDN referencing no message is trashed early.
I see two options:
- adapt the test documentation to explain that this is important for key update messages
- or replace it with a test testing that a key update message from an unknown contact doesn't create a contact or chat.
There was a problem hiding this comment.
Just from looking at the test and its documentation, it's unclear why we need this test, i.e. why it's important that an MDN referencing no message is trashed early.
User-visible effect is that "last seen" is not updated for address-contact and address-contact does not get a green dot.
See also #8620 (comment)
|
|
||
| /// Returns the protected headers shared by encrypted messages | ||
| /// that are not part of a chat. | ||
| async fn non_chat_protected_headers( |
There was a problem hiding this comment.
I guess the function should be renamed too, then? To non_chat_headers or headers_for_non_chat_msg?
This PR does not change any behaviour for code on main but contains the refactoring parts for introducing asynchronously encrypted key updates in #8621
IT should not be merged without also merging the actual keyupdate branch.