A generic chat protocol for client applications that communicate via simplex messaging protocol
- Dependency on a single company/server to access and use chat. That creates implications for chat privacy, user profile resilience and data ownership.
- Visiblity of user profile information to chat system and other chat users. Chat users have limited control as to who can see and find their profile.
- Visibility of user contacts graph to chat server.
- E2EE can be compromised by MITM attack (see simplex messaging protocol).
- Identity related problems (also see simplex messaging protocol).
TODO
Majority of chat scenarios requires duplex (bi-directional) connections between participants. Graph-chat protocol uses multiple simplex (unidirectional) connections created on multiple simplex messaging servers to implement duplex connections.
Each duplex connection consists of one or multiple, for redundancy, pairs of simplex connections to connect chat participants or devices of the same participant - it is used for "contacts", "devices", "group participants", etc. For practical purposes of redundancy, chat clients can use 2-4 pairs of simplex connections.
The process described below establishes a duplex connection between Alice and Bob that has n
simplex connections CAi
(where 1 <= i <= n
) from Bob to Alice (created by Alice on her servers) and n
simplex connections CBi
(where 1 <= i <= n
) from Alice to Bob (created by Bob on his servers).
The following symbols are used below:
- simplex connections:
CAi
- Alice's simplex connection numberi
(out ofn
) allowing Bob to send messages to Alice.CBi
- Bob's simplex connection numberi
(out ofn
) allowing Alice to send messages to Bob.
- keys created for Alice's connections:
RUAi
- server-generated recipient connection URI ofCAi
(to be used by Alice to retrieve messages).EKAi
- Alice's assymetric key pair used:- by Bob to encrypt and by Alice to decrypt messages from Bob sent via
CAi
. - by Alice to sign and Bob to verify messages from Alice sent via
CBi
.
- by Bob to encrypt and by Alice to decrypt messages from Bob sent via
SUAi
- server-generated sender connection URI ofCAi
(to be used by Bob to send messages).RKAi
- Alice's recipient key ofCAi
.SKAi
- Bob's sender key ofCAi
.
- keys created for Bob's connections
RUBi
- server-generated recipient connection URI ofCBi
(to be used by Bob to retrive messages).EKBi
- Bob's assymetric key pair used for:- Alice to encrypt and Bob to decrypt messages from Alice sent via
CBi
. - Bob to sign and Alice to verify messages from Bob sent via
CAi
.
- Alice to encrypt and Bob to decrypt messages from Alice sent via
SUBi
- server-generated sender connection URI ofCBi
(to be used by Alice to send messages).RKBi
- Bob's recipient key ofCBi
.SKBi
- Alice's sender key ofCBi
.
To create a duplex connection initiated by Alice, Alice's and Bob's apps follow these steps:
- Alice's app initiates duplex connection:
- it creates
n
simplex connectionsCAi
(step 1 in simplex messaging) that are defined by recipient URIsRUAi
and have:- client-generated:
- Alice's asymmetric key pairs
EKAi
to encrypt messages. - recipient keys
RKAi
.
- Alice's asymmetric key pairs
- server-generated:
- sender URIs
SUAi
.
- sender URIs
- client-generated:
- optionally, Alice's app subsribes to receive messages from these new connections
CAi
(simplex messaging protocol implementation defines protocol to be used for subscriptions).
- it creates
- Alice's app sends a secure message to Bob's app (step 2 in simplex messaging):
- it prepares the message with the information needed to establish all connections
CAi
, including all encryption keysEKAi
and sender connection URIs (SUAi
). - depending on the communication scenario, Alice's app sends this message to Bob's app in one of available secure ways (either out-of-band or via available secure duplex connection(s) - see Duplex connection security level), depending on communication scenario:
- if Bob is a new contact, the information is presented as a visual code (e.g. QR code(s)) to Bob's app - as out-of-band message needed to establish connections
CAi
(see simplex messaging protocol and Adding direct contact). - if Bob is added to group chat with Alice by some contact of Alice or Bob, this information can be passed through all possible chains of contacts between Alice and Bob in the group (to minimise the risk of MITM attack) (see Group chat).
- if Alice adds Bob as a contact via Bob's trusted contact John, who also has Alice as a trusted contact, this information will be passed via John (who has secure duplex connections with both Alice and Bob), in the same way as with Group chat (see Trusted contacts).
- if Alice already has Bob as a contact, and she wants to create a separate off-the-record chat with him, this information will be passed via their existing connection (see Off-the-record chat).
- etc. In all cases, the protocol defines the most secure possible way to pass the out-of-band (from the point of view of the new connections) message required by simplex messaging protocol to create simplex connections.
- if Bob is a new contact, the information is presented as a visual code (e.g. QR code(s)) to Bob's app - as out-of-band message needed to establish connections
- it prepares the message with the information needed to establish all connections
- Bob's app accepts duplex connection with Alice:
- it receives the message from Alice's app, in a way defined by a specific chat scenario.
- it interprets the received information as simplex messaging protocol out-of-band messages to accept all simplex connections
CAi
. - it creates
n
new simplex connectionsCBi
on Bob's servers defined by recipient URIsRUBi
and have:- client-generated:
- Bob's asymmetric key pairs
EKBi
to encrypt messages. - recipient keys
RKBi
.
- Bob's asymmetric key pairs
- server-generated:
- sender URIs
SUBi
.
- sender URIs
- client-generated:
- optionally, Bob's app subsribes to receive messages from these new connection
CBi
(see simplex messaging protocol implementation). - it proceeds with accepting Alice's app connections
CAi
(step 3 in simplex messaging protocol). - in response to each connection
CAi
, as optional information, Bob's app includes:- Bob's user profile (that is only stored in graph-chat client and not visible to any server)
- information to establish connection
CBi
:- encryption key
EKBi
. - sender connection URIs (
SUBi
).
- encryption key
- his app now sends the unsigned requests to Alice's connections
CAi
(step 3.4 in simplex messaging protocol), to both confirm the connectionsCAi
and to propose the new connectionsCBi
. As each message is encrypted by the keyEKAi
of the connectionCAi
that only Alice can decrypt, it is safe to send it - from simplex messaging server point of view it is an out-of-band message.
- Alice's app adds Bob's duplex connection:
- it receives the messages from Bob via connections
CAi
(step 4 in simplex messaging protocol). - depending on chat scenario, Bob is identified and confirmed:
- for new contact, Alice may visually identify Bob's user profile and accepts Bob as a contact.
- for group participant, Alice's app will match known Bob's user profile ID with received user profile ID (that is only visible to the clients apps that have this profile).
- it secures the connections
CAi
with keysSKAi
received from Bob - the connections are now established (step 5 in simplex messaging protocol). - it accepts the connections
CBi
, including in the response to Bob's server Alice's user profile and (as the additional information) the confirmation that the connectionsCAi
are secured and can be used (step 3 in simplex messaging protocol). - it sends the unsigned messages via connections
CBi
. - it adds Bob's duplex connection to the list of available duplex connections as "pending" (Alice cannot yet send messages to Bob, but Bob already can send messages to Alice). Possibly, the status of duplex connection can indicate that Bob already can send messages to Alice.
- it receives the messages from Bob via connections
- Bob's app adds duplex connection with Alice:
- it receives the initial messages via connections
CBi
. - it secures the connections
CBi
- they are now established as well (step 5 in simplex messaging protocol). - it adds duplex connection with Alice in the list of available duplex connections as "pending" (to indicate that Alice cannot yet send messages). Possibly, the status of duplex connection can indicate that Bob already can send messages to Alice.
- it sends a special message (message type "welcome") to Alice's app via duplex connection (i.e., via all connections
CAi
) to confirm that adding Alice's contact is completed (see Sending messages via duplex connection).
- it receives the initial messages via connections
- Alice's app finalises adding duplex connection with Bob:
- it receives "welcome" message from Bob's app via duplex connection.
- it changes Bob's duplex connection status to "established".
- it sends a special "welcome" message to Bob's app via duplex connection.
- Bob's app finalises adding duplex connection with Alice:
- it receives "welcome" message from Alice's app via duplex connection.
- it changes Alice's duplex connection status "established".
Creating duplex connection between Alice and Bob:
When Alice sends the message to Bob via the duplex connection, they follow these steps:
- Alice sends the message to Bob in the app:
- her app prepares the message, including:
- client-generated message ID (unique per duplex connection).
- client timestamp.
- message body.
- her app prepares a separate version of the message for each connection
CBi
, by signing each version of the message with the corresponding keyEKAi
and encrypting it withEKBi
. - her app sends all copies of the message to corresponding connections
CBi
.
- her app prepares the message, including:
- Bob's app receives the message from Alice:
- it retrieves all versions of the message via all connections
CBi
(they can arrive at different time and possibly out of order with other messages). - it decrypts each version with
EKBi
and verifies the signature withEKAi
. - the first successfully decrypted message version is added to the Bob's chat with Alice and notification can be shown to Bob; if message verification failed it is marked as "unverified" in the chat.
- all subsequently decrypted and verified copies are discarded.
- if some of the decryptions or verifications fail, the corresponding connection is marked as "possibly compromised" and has to be replaced by the app with another connection.
- if decryption or verification fails for all connections
CBi
, Alice's contact is marked as "compromised".
- it retrieves all versions of the message via all connections
- Bob's app sends "message received" to Alice's app:
- it prepares a special "message received" message, including:
- client-generated message ID (unique per duplex connection).
- correlation ID of the message received from Alice.
- client timestamp of the message reception.
- it prepares a separate version of the message for each connection
CAi
, by signing each version of the message with the corresponding keyEKBi
and encrypting it withEKAi
. - it sends all copies of the message to corresponding connections
CAi
.
- it prepares a special "message received" message, including:
- Alice's app receives "message received" from Bob's app:
- it retrieves all versions of the "message received" message via all connections
CAi
(they can arrive at different time and possibly out of order with other messages). - it decrypts each version with
EKAi
and verifies the signature withEKBi
. - once the first version is successfully decrypted and verified, the previosly sent message in the Alice's chat with Bob is marked as delivered.
- all subsequently decrypted and verified copies are discarded.
- if some of the decryptions or verifications fail, the corresponding connection is marked as "possibly compromised" and has to be replaced by the app with another connection.
- if decryption or verification fails for all connections
CAi
, Bob's contact is marked as "compromised".
- it retrieves all versions of the "message received" message via all connections
Sending message from Alice to Bob via duplex connection:
"Direct contact" is a term used for a duplex connection with another chat user established directly, not via another user. Establishing contact requires sending an out-of-band message - "visual code" (e.g. QR code(s)) is used for this purpose.
For example, Alice and Bob want to have a conversation in chat app, exchanging messages with each other. They both have graph-chat client and access to several simplex messaging servers (see simplex messaging protocol) that they can use to receive messages, and their graph-chat clients are configured to use these servers.
To chat in the app Alice needs to add Bob as "direct contact" to her contacts in the app.
- Alice initiates adding "direct contact" in her graph-chat client app.
- Alice shares "visual code" (e.g. QR code(s)) with Bob:
- her app prepares secure message to establish duplex connection with Bob's app (step 1 in Creating duplex connection).
- her app prepares and displays a visual code with this message (step 2 in Creating duplex connection).
- Alice now can share this visual code with Bob, either in person or via a video call (see simplex messaging protocol).
- Bob reads "visual code" that Alice prepared via his app:
- he initiates adding "direct contact" via visual code in his graph-chat client app.
- his app interprets this visual code as secure message required to accept duplex connection with Alice and proceeds with creating duplex connection (step 3 in Creating duplex connection).
- Alice's app adds Bob as "direct contact":
- it proceeds with creating duplex connection.
- once "pending" duplex connection with Bob's app is created in Alice's app, Bob is added as "direct contact" with the status "pending" in Alice's app (step 4 in Creating duplex connection).
- Bob's app adds Alice as "direct contact":
- it proceeds with creating duplex connection.
- once "pending" duplex connection with Alice's app is created in Bob's app, Alice is added as "direct contact" with the status "pending" in Bob's app (step 5 in Creating duplex connection).
- Alice's app finalises adding Bob as "direct contact":
- it finalises adding duplex connection with Bob's app (step 6 in Creating duplex connection).
- it changes Bob's "direct contact" status to "established".
- Bob's app finalises adding Alice as "direct contact":
- it finalises adding duplex connection with Alice's app (step 7 in Creating duplex connection).
- it changes Alice's "direct contact" status to "established".
TODO
- "contact" - can be of type "person", "bot", "device", "organisation".
- "group-participant" - connection to another group participant that was established via the chain of other contacts in the group.
- "broadcast" - duplex connection from broadcast subscriber to publisher; client apps should only allow to receive messages and send back control messages, but not the content messages. Profile of the subscriber is not shared with the publisher.
- "broadcast-subscriber" - duplex connection from broadcast publisher to subscriber.
Control messages:
- "welcome" - sent and recieved by both participants when duplex connection is being established.
- "receipt" - acknowledging message receipt.
- "contact: update" - changing "contact" profile .
- "profile" - changing "contact
- "gm: add" - sent to add simplex connection to graph-chat duplex connection.
- "gm: remove" - sent to remove simplex connection from graph-chat duplex connection.
Content messages:
- "text"
- "image"