From bb5b97f1684808f0adf775e1da55bea2371427c9 Mon Sep 17 00:00:00 2001 From: link2xt Date: Thu, 9 Nov 2023 23:43:01 +0000 Subject: [PATCH] docs: add a draft of a proposed simplified acpeerstates table --- draft/keymanagement.md | 131 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 draft/keymanagement.md diff --git a/draft/keymanagement.md b/draft/keymanagement.md new file mode 100644 index 000000000..0fc1a4d5f --- /dev/null +++ b/draft/keymanagement.md @@ -0,0 +1,131 @@ +# New acpeerstates table + +A proposal to replace `acpeerstates` table, +which has columns +- `id` +- `addr` +- `prefer_encrypted` +- `last_seen` +- `last_seen_autocrypt` +- `public_key` +- `public_key_fingrprint` +- `gossip_timestamp` +- `gossip_key` +- `gossip_key_fingerprint` +- `verified_key` +- `verified_key_fingerprint` +- `verifier` +- `secondary_verified_key` +- `secondary_verified_key_fingerprint` +- `secondary_verifier` +with a new `public_keys` table with columns +- `id` +- `addr` - address of the contact which is supposed to have the private key +- `public_key` - a blob with the OpenPGP public key +- `public_key_fingerprint` - public key fingerprint +- `introduced_by` - address of the contact if received directly in `Autocrypt` header, address of `Autocrypt-Gossip` sender otherwise +- `is_verified` - boolean flag indicating if the key was received in a verified group or not +- `timestamp` - timestamp of the most recent row update + +The table has consraints `UNIQUE(addr, introduced_by)`. +Note that there may be multiple rows with the same fingerprint, +e.g. if multiple peers gossiped the same key for a contact they all are introducers of the key. + +`prefer_encrypted` is moved to the `contacts` table. + +Maybe fingerprint is the primary key, at least there should be an index. + + +## Using the table to select the keys + +### Sending a message to 1:1 chat + +When sending a message to the contact in a 1:1 chat, +encrypt to the key where `introduced_by` equals `addr`: +``` +SELECT * +FROM public_keys +WHERE addr=? AND introduced_by=addr +``` +This row is guaranteed to be unique if it exists. + +If direct Autocrypt key does not exist, +use the most recent one according to the timestamp key gossiped for this contact: +``` +SELECT * +FROM public_keys +WHERE addr=? +ORDER BY timestamp DESC LIMIT 1 +``` + +If the table contains a row with selected key and `is_verified` flag set, +display a green checkmark and "Introduced by " in the 1:1 chat/contact profile. +Note that row with verification may be older than the most recent gossip. + +### Sending a message to unprotected group chat + +When sending a message to the contact in a non-verified group chat, +encrypt to the same key as used in 1:1 chat +and (NEW!) one or more most recent gossiped keys introduced by chat members: +``` +SELECT public_key +FROM public_keys +WHERE addr=? AND introduced_by IN () +ORDER BY timestamp DESC +``` +It does not matter if the gossiped key has `is_verified` flag. + +### Sending a message to protected group chat + +When sending a message in a protected group chat, +construct a list of candidate keys for each contact +the same way as in an unprotected chat, +but then filter out the keys which do not have `is_verified` flag. + + +## Updating the table + +When executing "setup contact" protocol +with the contact, +set the row with `addr` and `introduced_by` being equal +to the contact address and `is_verified` is true. +In this case the contact becomes directly verified. + +When receiving a message, +first process the `Autocrypt` key, +then check verification properties to detect if gossip is signed with a verified key, +then process `Autocrypt-Gossip` key. + +### 1. Processing the Autocrypt header + +Take the key from the Autocrypt header +and insert or update the row +identified by `addr` and `introduced_by` being equal to the `From:` address. +Notify about setup change and reset `is_verified` flag if the key fingerprint has changed. +Always update the timestamp. + +Update `prefer_encrypted` in the contacts table as needed +based on the `Autocrypt` header parameters, +whether the message is signed etc. + +### 2. Check verification + +Determine whether the green checkmark should now be displayed +on the 1:1 chat and update it accordingly, +insert system messages, +get it into broken state or out of it. + +Now we know if the message is signed with a verified key. + +### 3. Process `Autocrypt-Gossip` + +Insert or update gossip keys +``` +INSERT INTO public_keys (addr, public_key, public_key_fingerprint, introduced_by, is_verified, timestamp) +VALUES (?, ?, ?, , ?, ) +ON CONFLICT +DO UPDATE SET public_key=excluded.public_key, public_key_fingerprint=excluded.public_key_fingerprint +``` + +`is_verified` should be set if the message is signed with a verified key, +independently of whether the key was gossiped in a protected chat or not.