core icon indicating copy to clipboard operation
core copied to clipboard

Expire QR Codes

Open Hocuri opened this issue 2 years ago • 20 comments

Context

https://securejoin.readthedocs.io/en/latest/ explains the current protocol and the considerations that led to it. Delta Chat doesn't actually implement expiry yet, which this issue is about.

Motivation

  • prevent-online-leak

    The first attempt at prevent-online-leak https://github.com/deltachat/deltachat-core-rust/pull/4932 turned out to be quite hard to get right usability-wise, esp. concerning groups:

    This rises an UI question in case of someone trying to join the group using expired QR code. In Zoom users who are invited but not yet approved end up in some sort of lobby. If we open a new contact request when someone tries to join old group and ask to approve, user has no context to decide why they should approve the contact. Implementing approvals for joining the group is better, but would require UI changes on all platforms.

  • Usable-security-wise, it will give green checkmarks a clear meaning without any exceptions (like, it's guaranteed that there is no MitM EXCEPT if you published your QR code on your website, or you shared a greencheckmarked-group-invite in a large group, or any of the people that are in greencheckmarked groups with you did one of these things)

  • Finally, this would bring us closer to the securejoin spec.

Details

  • Bob should still get a one-directional verification if he already knows Alice's key.
  • In order to warn Bob that the QR code is expired, we need to add a new parameter to the QR code. This is possible in a backwards-compatible way.
  • We need to pick a date when all the existing QR codes without an expiry expire.
  • QR codes for bots should not expire (if that's hard to do technically, set the expiry date to something very far in the future for them).
  • QR codes contain 2 tokens today: INVITENUMBER and AUTH. When Alice receives the INVITENUMBER, she automatically replies with her public key. When Alice receives the AUTH (in an encrypted subsequent message), she marks Bob's public key as verified. We can select separate expiration intervals for them, e.g. 10 minutes or until for AUTH

Problems

  1. Group invites: An invite link to a g-e2ee group chat can not add the joiner device if the link expired.
  • Solution 1: simply not show the green checkmark as soon as someone's public key is not verified. I.e. to downgrade the group for some/many members in this case (@missytake), but not for the members who have everyone verified
  • Solution 2: Show a helpful error message:
    • Maybe "This QR code is expired. You can let Alice scan your QR code and then ask her her to add you to the group." with a button "Show my QR code" and "Other possibilities" where "Other possibilities" shows how Alice can clone the group to an opportunistic one
    • Or simply "This QR code is expired."
  1. You can't encrypt after scanning a QR code with expired INVITENUMBER, which poses a problem with Chatmail -> INVITENUBMER needs to be valid for a rather long time (≥ a day).
  2. We will have more cases where people accidentally have a verified group and now want to add someone they have not verified.
  3. Technical challenges:
  • The QR code only contains the fingerprint, no key, so we can't directly mark the key as 1-way verified, but instead have to remember the fingerprint and then mark the key as verified as soon as we receive it.
  • If Bob scans a QR code with his phone and then doesn't open DC on his PC for a while, the QR codes might have already expired by the time he opens DC on his PC -> We need to make sure that the contact is verified on the PC too, in this case.

Open Questions

  • Should we show a green checkmark for contacts with a verified public key who don't have us verified? (i.e. forward verified but not backwards verified)
  • Should we allow "opportunistic" key changes for contacts with a verified public key who don't have us verified?

Alternatives

  • Fix problem 2 (see "Problems" above) by including a key in the QR code so that Bob can encrypt to Alice without having to wait for her answer.
    • Discussed at https://github.com/deltachat/deltachat-core-rust/issues/5182
    • This brings us away from the SecureJoin protocol (OTOH, noone except us implements it, anyway).
    • Upsides: It makes the protocol run faster (2 instead of 4 messages), and all SecureJoin messages will be encrypted
    • Including the whole OpenPGP key will not work for v6/crypto-refresh, because we will eventually need to transmit two keys
    • Possibility 1: Create a ED25519 PGP key for each invite. The public key replaces the INVITENUMBER. Bob can use it to send AUTH encrypted in the first message already, and to encrypt messages before Alice answers with her actual PGP key.
      • Downside: Complexity.
    • Possibility 2: Put a passphrase for symmetric encryption into the QR code, which replaces AUTH.
      • Upside: Will not need adaptions for PQC.
      • We should still include the public key fingerprint in the QR code, so that the scanner can do a one-sided verification if AUTH is expired

More possible improvements:

Both these improvements would help with the usability problem brought up by @dkg that a verified-checkmark implies something about identity:

  • After securejoin completes, show a dialog asking the user to set a name for the contact. This way, the green checkmarks will mean something about identity because the user confirmed that this display name goes with the contact who just scanned the QR code.
    • This will require that we either let AUTH tokens expire as soon as the app is not in the foreground anymore, or that we show a notification receiving a vc-request-with-auth message if DC is in the background already.
    • Also, we need to figure out what to do for transitively verified contacts. WhatsApp shows all display names with a "~" until the user manually sets a name for this contact, and they show a prominent prompt to add a contact in the 1:1 chat)
  • Don't show green "verified" checkmarks, instead show a warning when messages are not guaranteed-end-to-end-encrypted, possibly in the message composition field, on the send button, and/or where the green checkmarks are today

Hocuri avatar Dec 22 '23 15:12 Hocuri

Bob should still show a one-directional verification if he already knows Alice's key.

We do not show one-directional verification anywhere. Contact.is_verified() still returns false if there is no backward verification. With https://github.com/deltachat/deltachat-core-rust/pull/5116 we will however mark 1:1 chat as verified very early on.

link2xt avatar Dec 22 '23 15:12 link2xt

Yes, I meant "get", I edited my original comment

Hocuri avatar Dec 22 '23 15:12 Hocuri

We need to pick an expiry time, we talked about something like 2 days. Thinking about it, I'd actually argue for something like 10 minutes, since that's enough to send a QR code via Signal if need be, but often not enough for Eve. If you want offline-verification, just scan the QR code in both ways.

This might be a problem if you want to setup contact via a friend using Signal or other messenger who you trust to resend QR code but nobody is online at the same time and Signal cannot be used as you don't want to share phone numbers directly. With chatmail this is a problem because you cannot even have forward verification and send a message. Scenario is constructed as chatmail is new, but I have seen this pattern of relaying Discord and similar messenger invitation links, SMS codes and so on.

Maybe "backward verification" (AUTH token) should expire in 10 minutes as it is important for verification security, but "forward verification" (INVITENUMBER token used to request the key) can take longer as it is just used to request the key and worst case leaks online presence. In any case we better talk about expiring these tokens rather than "expiring QR codes" which contain multiple tokens.

link2xt avatar Jan 14 '24 00:01 link2xt