From 902c2007dc8db79e9f156d810a79be467731ac6b Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 21 Dec 2019 22:20:02 +0000 Subject: [PATCH] docs: update connection diagram to include user-server authentication and encryption --- diagrams/connection.mmd | 70 +++++++--- diagrams/connection.svg | 286 ++++++++++++++++++++-------------------- readme.md | 29 +++- 3 files changed, 221 insertions(+), 164 deletions(-) diff --git a/diagrams/connection.mmd b/diagrams/connection.mmd index 850d726125..bf1dd971d3 100644 --- a/diagrams/connection.mmd +++ b/diagrams/connection.mmd @@ -1,24 +1,58 @@ sequenceDiagram participant Alice - participant App A - participant Server A - participant Server B - participant App B + participant App A as Alice's app + participant Server A as Alice's server + participant Server B as Bob's server + participant App B as Bob's app participant Bob - Alice ->> App A: Alice shows as QR code on the screen
(Alice's public key for Bob's eyes only) - Bob ->> App B: Bob requests app to add connection - App A ->> App B: Bob's app reads via the camera - App B ->> Server B: Bob's app encrypts "connection request" (including and Bob's profile) and sends it to Bob's servers
{from: , to: , message: } - Server B ->> Server A: Bob's servers use to locate Alice's servers
and forward encrypted message to all Alice's servers (when they are different from Bob's servers) - Server A ->> App A: Alice's servers send the message to Alice's app - App A ->> Alice: Alice's app matches with shown QR code
and decrypts Bob's profile with to show it + + Alice ->> App A: Alice requests app to initiate adding connection + Note over App A: App generates:

+ App A ->> Server A: App registers on Alice's servers associated with (for recepient) + App A ->> Server A: App subsribes to receive messages from anyone sent to
(request is signed with ) + + Note over App A: App shows QR code
for
and Alice's servers + + App A -->> Bob: Alice shows to Bob and her servers as QR code on the screen
(Alice's public key for Bob only and servers she currently uses) + Bob ->> App B: Bob requests app to read connection QR code + App A -->> App B: Bob's app reads QR code with and Alice's current servers via the camera + + Note over App B: App generates

+ + App B ->> Server B: App registers on Bob's server associated with (for recepient) + App B ->> Server B: App subsribes to receive messages from anyone sent to
(request is signed with ) + + Note over App A, App B: Now both Alice's and Bob's apps are subscribed to receive each other's messages on their servers + + Note over App B: App generates

for Alice's servers
and creates
connection request
including:
-
- Bob's profile
- Bob's servers
- + App B ->> Server A: Bob's app encrypts "connection request" with and sends it to Alice's servers
{to: , message: } + Server A ->> App A: Alice's servers send "connection request" to Alice's app
(as allows messages from anyone) + App A ->> Alice: Alice's app matches with
and decrypts Bob's profile with to show it Alice ->> App A: Alice identifies Bob's profile and accepts the connection
(Bob is now added to Alice's list of connections as "pending") - App A ->> Server A: Alice's app creates "connection accepted" message (including Alice's profile) and sends it to Alice's servers
{from: , to: , message: } - Server A ->> Server B: Alice's servers use to locate Bob's servers
and forward encrypted message to all Bob's servers (when they are different from Alice's servers) + App A ->> Server A: App registers on Alice's servers associated with (for sender) + + Note over Server A, Bob: Now only Bob's app can send messages for to Alice's servers
1) signed using
2) encrypted using
3) signed/encrypted using + + Note over App A: App generates

for Bob's servers
and creates
"conn. accepted"
message including:
- Alice's profile
- + + App A ->> Server B: Alice's app signs "connection accepted" with , encrypts it with and sends it to Bob's servers
{to: , message: } Server B ->> App B: Bob's servers send the message to Bob's app - App B ->> Bob: Bob's app matches with read QR code
and decrypts the Alice's profile with Bob's - App B ->> Bob: Bob's app adds Alice to the list of connections - App B ->> Server B: "connection acknowledgement" message - Server B ->> Server A: "connection acknowledgement" message - Server A ->> App A: "connection acknowledgement" message + App B ->> Bob: Bob's app matches with
and decrypts the Alice's profile with Bob's + App B ->> Bob: Bob's app shows Alice's profile and adds it to the connections
(as pending) + App B ->> Server B: App registers on Bob's servers associated with (for sender) + + Note over Alice, Server B: Now only Alice's app can send messages for to Bob's servers
1) signed using
2) encrypted using
3) signed/encrypted using + + Note over App B: App creates
"connection
acknowledged" + + App B ->> Server A: Bob's app signs "connection acknowledged" with , encrypts it with and sends it to Alices's servers
{to: , message: } (also signed/encrypted with B_AB server private/public keys) + Server A ->> App A: Alice's servers send to app "connection acknowledged" App A ->> Alice: Bob is now in the Alice's list of connections as "established" + + Note over App A: App creates
"connection
acknowledged" + + App A ->> Server B: Alice's app signs "connection acknowledged" with , encrypts it with and sends it to Bob's servers
{to: , message: } (also signed/encrypted with A_BA server private/public keys) + Server B ->> App B: Bob's servers send to app "connection acknowledged" + App B ->> Bob: Alice is now in the Bob's list of connections as "established" + + Note over Alice, Bob: Now Alice and Bob can exchange messages with each other, including key rotations and changes of servers they use
- Alice can send messages to Bob's servers to (Bob's servers allow Alice to send messages relying on A_BA keys)
- Bob can subscribe to messages on his servers sent to (Bob's servers allow Bob to receive messages relying on B_BA keys)

- Bob can send messages to Alice's servers to (Alice's servers allow Bob to send messages relying on B_AB keys)
- Alice can subscribe to messages on her servers sent to (ALice's servers allow Alice to receive messages relying on A_AB keys) diff --git a/diagrams/connection.svg b/diagrams/connection.svg index 42af48d5c7..176b66c9e2 100644 --- a/diagrams/connection.svg +++ b/diagrams/connection.svg @@ -1,49 +1,49 @@ -AliceAlice's appAlice's serverBob's serverBob's appBobAlice requests app to initiate adding connectionApp generates:<AB connection key><A_AB server keys>App registers on Alice's servers <AB public key hash> associated with <A_AB server public keys> (for recepient)App subsribes to receive messages from anyone sent to <AB public key hash>(request is signed with <A_AB server private keys>)App shows QR codefor <AB public key>and Alice's serversAlice shows to Bob <AB public key> and her servers as QR code on the screen(Alice's public key for Bob only and servers she currently uses)Bob requests app to read connection QR codeBob's app reads QR code with <AB public key> and Alice's current servers via the cameraApp generates<BA connection key><B_BA server keys>App registers on Bob's server <BA public key hash> associated with <B_BA server public keys> (for recepient)App subsribes to receive messages from anyone sent to <BA public key hash>(request is signed with <B_BA server private key>)Now both Alice's and Bob's apps are subscribed to receive each other's messages on their serversApp generates<B_AB server keys>for Alice's serversand createsconnection requestincluding:- <BA public key>- Bob's profile- Bob's servers- <B_AB public keys>Bob's app encrypts "connection request" with <AB public key> and sends it to Alice's servers{to: <AB public key hash>, message: <request encrypted with AB public key>}Alice's servers send "connection request" to Alice's app(as <AB public key hash> allows messages from anyone)Alice's app matches <AB public key hash> with <AB public key>and decrypts Bob's profile with <AB private key> to show itAlice identifies Bob's profile and accepts the connection(Bob is now added to Alice's list of connections as "pending")App registers on Alice's servers <AB public key hash> associated with <B_AB server public keys> (for sender)Now only Bob's app can send messages for <AB public key hash> to Alice's servers1) signed using <BA private key>2) encrypted using <AB public key>3) signed/encrypted using <B_AB server private/public keys>App generates<A_BA server keys>for Bob's serversand creates"conn. accepted"message including:- Alice's profile- <A_BA public keys>Alice's app signs "connection accepted" with <AB private key>, encrypts it with <BA public key> and sends it to Bob's servers{to: <BA public key hash>, message: <encrypted with BA public key>}Bob's servers send the message to Bob's appBob's app matches <BA public key hash> with <BA public key>and decrypts the Alice's profile with Bob's <BA private key>Bob's app shows Alice's profile and adds it to the connections(as pending)App registers on Bob's servers <BA public key hash> associated with <A_BA server public keys> (for sender)Now only Alice's app can send messages for <BA public key hash> to Bob's servers1) signed using <AB private key>2) encrypted using <BA public key>3) signed/encrypted using <A_BA server private/public keys>App creates"connectionacknowledged"Bob's app signs "connection acknowledged" with <BA private key>, encrypts it with <AB public key> and sends it to Alices's servers{to: <AB public key hash>, message: <encrypted with AB public key>} (also signed/encrypted with B_AB server private/public keys)Alice's servers send to app "connection acknowledged"Bob is now in the Alice's list of connections as "established"App creates"connectionacknowledged"Alice's app signs "connection acknowledged" with <AB private key>, encrypts it with <BA public key> and sends it to Bob's servers{to: <BA public key hash>, message: <encrypted with BA public key>} (also signed/encrypted with A_BA server private/public keys)Bob's servers send to app "connection acknowledged"Alice is now in the Bob's list of connections as "established"Now Alice and Bob can exchange messages with each other, including key rotations and changes of servers they use- Alice can send messages to Bob's servers to <BA public key hash> (Bob's servers allow Alice to send messages relying on A_BA keys)- Bob can subscribe to messages on his servers sent to <BA public key hash> (Bob's servers allow Bob to receive messages relying on B_BA keys)- Bob can send messages to Alice's servers to <AB public key hash> (Alice's servers allow Bob to send messages relying on B_AB keys)- Alice can subscribe to messages on her servers sent to <AB public key hash> (ALice's servers allow Alice to receive messages relying on A_AB keys)AliceAlice's appAlice's serverBob's serverBob's appBob \ No newline at end of file diff --git a/readme.md b/readme.md index c2a28191dc..2cdc79b866 100644 --- a/readme.md +++ b/readme.md @@ -27,7 +27,7 @@ The problems of existing chat solutions this system intends to solve: - Public keys used between connections are regularly updated to prevent decryption of the full message history in case when some servers or middle-men preserve message history and the current key is compromised. - Users can repeat key exchange using QR code and alternative channel at any point to increase communication security. - No single server in the system has visibility of all connections or messages of any user, as user profiles are identified by multiple rotating public keys, using separate key for each profile connection. -- Servers only store hashes of public keys, so that nobody can encrypt messages from a user profile connection, other than the user who has this public key (effectively making it a signature of the connected user). (Question: maybe connection key pair used to encrypt should be different from the key pair used to sign?) +- Servers only store hashes of public keys, so that nobody can encrypt messages from a user profile connection, other than the user who has this public key (effectively making it a signature of the connected user). - User profile (meta-data of the user including non-unique name / handle and optional additional data, e.g. avatar and status) is stored in the client apps and is shared only with accepted user profile connections. @@ -73,14 +73,37 @@ Client apps should provide the following: - store history of all conversations encrypted using user client app password (or some other device specific encryption mechanism). -## Sequence diagrams +## System design Prepared with [mermaid-js](https://mermaid-js.github.io/mermaid-live-editor) -### Adding connection + +### Connections between user profiles + +The system uses connections between user profiles (no information identifying user is stored on the servers) to send and to receive messages. Each connection is one-directional, from sender to recepient, without any correlation between connections and user profiles, and between 2 connections used to send and to receive messages between the same participants. + +This design aims to reduce the risk of correlating communication of a user profile with other user profiles (to keep the list of connections private), and of correlating sent and received messages between the same participants. + +Sockets used to send and receive connections can be used by an attacker for such correlation; to avoid it user profiles can be configured to use separate sockets for each one-directional connection (and in case of limited number of sockets, they can be closed and new sockets can be opened to avoid the possibility of any correlation, other than on network level). The probability of network level correlation can be further reduced with onion routing of messages. + +Each one-directional connection is identified by two key pairs for each participant. Each connection participant registers on the server \ and \ for each connection. + +All keys are generated by the user. Server keys are used for communication between server and user (for server to encrypt AND for user to sign). Connection keys are used for E2EE between users (for sender to encrypt using recepient's connection-specific public key and to sign using sender's connection-specific private key). For all keys, client app sends to all user's servers \ and \. + +Each connection can be used as inbound or as outbound - from the database point of view they look the same (to make any analysis more difficult for the attacker). Only the client app determines how each connection is used - as inbound or as outbound. + +For each inbound connection two keys allow to subscribe to receive messages from connection (by sending \ signed by \ - server will be able to match it with connections database and accept such request to deliver messages from connection via the subscribed socket) and to decrypt server-side encryption of messages sent from (and separately encrypted by) connection using the \. + +Each key tuple for outbound connetion will allow user to send messages to connection (by signing messages, including \, with \ - server will be able to match it with connections database and accept such messages) and to decrypt any service messages and responses using the \. + +In this way the server will only have the list of connections via which messages can be sent or received (identified by \), associated public keys to authenticate senders and recievers (\), with a separate server public key for each connection participant. The attacker will not be able to establish that any list of connections belongs to the same user (other than by analysing socket or network traffic). + + +### Establishing connection between user profiles ![Adding connection](/diagrams/connection.svg) + ### Sending message ![Sending message](/diagrams/message.svg)