Skip to content

Conversation

link2xt
Copy link
Collaborator

@link2xt link2xt commented Aug 16, 2025

Since key-contacts cannot change their keys and having "verification" is less important for contact identification than having a chat history or shared chats with a contact, UIs have stopped displaying green checkmarks everywhere (deltachat/deltachat-android#3828).

This PR removes protected chats and replaces old mechanism of propagating verifications via protected chat messages marked with Chat-Verified: 1 header with a new _verified attribute of Autocrypt-Gossip headers.

Receiving _verified attribute in Autocrypt-Gossip is already supported in 2.13.0 release. This PR switches from using Chat-Verified header to Autocrypt-Gossip.

Closes #7080 (replace verification gossip mechanism with a new one that works using Autocrypt-Gossip header and is independent of "protected chats").

It also makes authentication tokens in QR codes expire and closes #7111
As a preparation for expiring QR codes it takes into account sync item timestamps (closes #7182) for QR code tokens, so synced QR code tokens have a timestamp of sync messages and when token removal is synchronized tokens newer than the sync item are not removed.

Also closes #7112 (removing deprecated and unneeded APIs)

Finally, this PR adds a migration that resets all indirect verifications. There was a bug #7107 (closed in #7113) that resulted in updating "verified by" information for already verified contacts, so the information about "verifiers" is lost and overwritten with incorrect indirect verifiers.
Expiring auth tokens also make new direct verifications more meaningful, but I have decided not to reset direct verifications as they are not affected by bugs that accidentally result in verifying someone directly. If the user did not publicly share the invite link, then verifications are valuable and resetting all of them will likely not be received well.

As we reset indirect verifications at the same time as we change the mechanism used to propagate verifications, old incorrect verifications will not propagate to new versions even though users do not upgrade at the same time.

We can also allow to remove verification from contacts (https://support.delta.chat/t/how-would-i-remove-the-verified-checkmarks-from-one-invite-code-in-retrospect/3403) as it will not break "protected" chats anymore, but this is out of scope for this PR.

What this PR does:

  • Remove is_protection_broken APIs. (moved to Various protected group changes #7146)
  • Remove is_profile_verified API. (moved to Various protected group changes #7146)
  • Stop indirectly verifying contacts via messages with a Chat-Verified: 1 header.
  • Add new _verified attribute for Autocrypt-Gossip and use it to indirectly verify key-contacts when such attribute is received from a verified contact (whether directly verified or not).
  • Make sure that direct verifications cannot happen via "gossip" from self via outgoing messages sent by other devices. This is another reason to reset existing verifications, apparently existing "direct" verifications may be not actually direct but gossiped by own devices.
  • Remove error paths from add_parts that result in "The message was sent by non-verified contact" messages. We likely don't need to pass verified_encryption around, it is only used to decide whether we want to accept verification gossip from the contact.
  • Remove Chat.is_protected() APIs.
  • Remove API to create new protected groups
  • Update dc_contact_is_verified documentation.
  • Expiring auth tokens
  • Fix Take sync message timestamp into account for QR tokens #7182 so just synced tokens are expired if sync message is old.
  • Reset existing verifications via migration. We should do this at the same time as we switch to the new gossiping mechanism, so it should be part of this PR.

@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch from c7e6f1c to e180d7f Compare August 16, 2025 02:32
-----BEGIN PGP MESSAGE-----

wU4D5tq63hTeebASAQdATHbs7R5uRADpjsyAvrozHqQ/9nSrspwbLN6XJKuR3xcg
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Payload here is replaced to have no Chat-Verified header inside and have _verified=1 in gossip headers. Payload got larger likely because rsop does not do compression and I had to reencrypt the payload.

@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch 4 times, most recently from 867c2ba to 780ca50 Compare August 17, 2025 02:31
@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch 3 times, most recently from 53d6a2d to a6301b9 Compare August 17, 2025 06:22
@link2xt link2xt changed the title feat: verify contacts via Autocrypt-Gossip Verification v2 Aug 17, 2025
@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch 11 times, most recently from 88700f4 to 5b31b5d Compare August 19, 2025 21:16
@link2xt link2xt changed the title Verification v2 Remove protected chats Aug 20, 2025
@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch from 6b67844 to 6052d1a Compare August 20, 2025 03:33
@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch from 6052d1a to 4e956bd Compare August 28, 2025 06:47
@link2xt link2xt marked this pull request as ready for review August 28, 2025 08:37
@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch from f1389dd to 701dafe Compare August 28, 2025 08:48
@iequidoo iequidoo self-requested a review September 10, 2025 06:21
let chat = Chat::load_from_db(context, chat_id).await?;
if chat.is_encrypted(context).await?
&& !chat.param.exists(Param::Devicetalk)
&& !chat.param.exists(Param::Selftalk)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but probably https://delta.chat/en/help#save should say that saved messages are encrypted (if they are sent of course, e.g. in a multi-device case)

@adbenitez
Copy link
Collaborator

something blocking this? #7204 depends on this now because some migration thing and @iequidoo was told to rebase on this one

@link2xt
Copy link
Collaborator Author

link2xt commented Sep 30, 2025

This is blocked by not having a 2.13 release on all platforms. Android, iOS and Desktop are using core 2.11 currently, which means they don't support _verified attribute yet.

@adbenitez
Copy link
Collaborator

then I don't think the other PR should be blocked by this one, should just use main, if someone tried this PR with production device which they shouldn't they can restore from another device

@iequidoo
Copy link
Collaborator

iequidoo commented Oct 1, 2025

This is blocked by not having a 2.13 release on all platforms. Android, iOS and Desktop are using core 2.11 currently, which means they don't support _verified attribute yet.

How much time are we going to wait so that most users get updated to 2.13? Or are we going to break verification through groups for not updated users?

This mechanism replaces `Chat-Verified` header.
New parameter `_verified=1` in `Autocrypt-Gossip`
header marks that the sender has the gossiped key
verified.

Using `_verified=1` instead of `_verified`
because it is less likely to cause troubles
with existing Autocrypt header parsers.
This is also how https://www.rfc-editor.org/rfc/rfc2045
defines parameter syntax.
Create unprotected group in test_create_protected_grp_multidev
The test is renamed accordingly.

SystemMessage::ChatE2ee is added in encrypted groups
regardless of whether they are protected or not.
Previously new encrypted unprotected groups
had no message saying that messages are end-to-end encrypted
at all.
@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch from f6c2ada to a70866e Compare October 16, 2025 23:01
@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch from a70866e to e60632e Compare October 16, 2025 23:06
@link2xt link2xt force-pushed the link2xt/ykltkokxntvk branch from e60632e to 9abbe7a Compare October 16, 2025 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

4 participants