From 59b475a5cd7482bd801c01cd6f756812d12efe8a Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Sat, 10 Oct 2020 21:47:17 +0100 Subject: [PATCH] unify and simplify SMP (#38) * unify and simplify SMP * use cameCase in ABNFs * update diagrams * update ABNF RFC * update protocol syntax * table of contents --- .prettierrc.json | 5 + .../simplex-messaging-impl/simplex-op.svg | 498 ----------- .../simplex-messaging/simplex-creating.mmd | 20 +- .../simplex-messaging/simplex-creating.svg | 506 +---------- .../simplex-op.mmd | 4 +- diagrams/simplex-messaging/simplex-op.svg | 1 + diagrams/simplex-messaging/simplex-using.mmd | 10 +- diagrams/simplex-messaging/simplex-using.svg | 506 +---------- diagrams/simplex-messaging/simplex.mmd | 6 +- diagrams/simplex-messaging/simplex.svg | 506 +---------- readme.md | 209 +++-- simplex-messaging-api.md | 199 ----- simplex-messaging-implementation.md | 403 --------- simplex-messaging.md | 814 ++++++++++++++++-- 14 files changed, 905 insertions(+), 2782 deletions(-) create mode 100644 .prettierrc.json delete mode 100644 diagrams/simplex-messaging-impl/simplex-op.svg rename diagrams/{simplex-messaging-impl => simplex-messaging}/simplex-op.mmd (90%) create mode 100644 diagrams/simplex-messaging/simplex-op.svg delete mode 100644 simplex-messaging-api.md delete mode 100644 simplex-messaging-implementation.md diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..5f2796d3cd --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "bracketSpacing": false, + "printWidth": 80, + "proseWrap": "always" +} diff --git a/diagrams/simplex-messaging-impl/simplex-op.svg b/diagrams/simplex-messaging-impl/simplex-op.svg deleted file mode 100644 index 55af1592d4..0000000000 --- a/diagrams/simplex-messaging-impl/simplex-op.svg +++ /dev/null @@ -1,498 +0,0 @@ -sender (client)APIpubsubpublisherreceiver (client)sign subscription (1)subscribe to messagesverify subscriber (1)subscribereject subscriptionalt[ subscriber verified? ]sign message (2)send messageverify sender (2)queue messagereject messagealt[ sender verified? ]take messagedeliver messagesender (client)APIpubsubpublisherreceiver (client) \ No newline at end of file diff --git a/diagrams/simplex-messaging/simplex-creating.mmd b/diagrams/simplex-messaging/simplex-creating.mmd index 4a395b25a3..b04d3d6b6b 100644 --- a/diagrams/simplex-messaging/simplex-creating.mmd +++ b/diagrams/simplex-messaging/simplex-creating.mmd @@ -1,20 +1,20 @@ sequenceDiagram participant B as Bob (sender) - participant S as server (conn. RU) + participant S as server (conn. RID) participant A as Alice (recipient) - note over A: creating connection
("public" key RK
for msg retrieval) + note over A: creating connection
("public" key RK
for msg retrieval) A ->> S: 1. create connection - S ->> A: respond with connection URIs + S ->> A: respond with connection's RID and SID - note over A: out-of-band msg
(sender conn. URI
and "public" key EK
to encrypt msgs) + note over A: out-of-band msg
(sender's conn. SID
and "public" key EK
to encrypt msgs) A -->> B: 2. send out-of-band message - note over B: accept connection
("public" key SK for
sending messages
and any optional
info encrypted with
"public" key EK) - B ->> S: 3. confirm connection (req not signed) + note over B: confirm connection
("public" key SK for
sending messages
and any optional
info encrypted with
"public" key EK) + B ->> S: 3. confirm connection (command not signed) - S ->> A: 4. retrieve Bob's message (RK-signed req) - note over A: decrypt message
("private" key EK) - A ->> S: 5. secure connection + S ->> A: 4. deliver Bob's message + note over A: decrypt message
("private" key EK) + A ->> S: 5. secure connection (RK-signed) - note over S: 6. secure
connection RU
is established! + note over S: 6. simplex
connection RID
is established! diff --git a/diagrams/simplex-messaging/simplex-creating.svg b/diagrams/simplex-messaging/simplex-creating.svg index e547359caa..6bd2e68635 100644 --- a/diagrams/simplex-messaging/simplex-creating.svg +++ b/diagrams/simplex-messaging/simplex-creating.svg @@ -1,505 +1 @@ -Bob (sender)server (conn. RU)Alice (recipient)creating connection ("public" key RK for msg retrieval)1. create connectionrespond with connection URIsout-of-band msg (sender conn. URI and "public" key EK to encrypt msgs)2. send out-of-band messageaccept connection ("public" key SK for sending messages and any optional info encrypted with "public" key EK)3. confirm connection (req not signed)4. retrieve Bob's message (RK-signed req)decrypt message ("private" key EK)5. secure connection6. secure connection RU is established!Bob (sender)server (conn. RU)Alice (recipient) \ No newline at end of file +Bob (sender)server (conn. RID)Alice (recipient)creating connection("public" key RKfor msg retrieval)1. create connectionrespond with connection's RID and SIDout-of-band msg(sender's conn. SIDand "public" key EKto encrypt msgs)2. send out-of-band messageconfirm connection("public" key SK forsending messagesand any optionalinfo encrypted with"public" key EK)3. confirm connection (command not signed)4. deliver Bob's messagedecrypt message("private" key EK)5. secure connection (RK-signed)6. simplexconnection RIDis established!Bob (sender)server (conn. RID)Alice (recipient) \ No newline at end of file diff --git a/diagrams/simplex-messaging-impl/simplex-op.mmd b/diagrams/simplex-messaging/simplex-op.mmd similarity index 90% rename from diagrams/simplex-messaging-impl/simplex-op.mmd rename to diagrams/simplex-messaging/simplex-op.mmd index 47842dab46..cacdaa38c4 100644 --- a/diagrams/simplex-messaging-impl/simplex-op.mmd +++ b/diagrams/simplex-messaging/simplex-op.mmd @@ -1,8 +1,8 @@ sequenceDiagram participant S as sender (client) - participant A as API + participant A as transport participant Q as pubsub - participant P as publisher + participant P as transport participant R as receiver (client) note over R: sign subscription (1) R ->> P: subscribe to messages diff --git a/diagrams/simplex-messaging/simplex-op.svg b/diagrams/simplex-messaging/simplex-op.svg new file mode 100644 index 0000000000..1d69dad4d7 --- /dev/null +++ b/diagrams/simplex-messaging/simplex-op.svg @@ -0,0 +1 @@ +sender (client)transportpubsubtransportreceiver (client)sign subscription (1)subscribe to messagesverify subscriber (1)subscribereject subscriptionalt[subscriber verified?]sign message (2)send messageverify sender (2)queue messagereject messagealt[sender verified?]take messagedeliver messagesender (client)transportpubsubtransportreceiver (client) \ No newline at end of file diff --git a/diagrams/simplex-messaging/simplex-using.mmd b/diagrams/simplex-messaging/simplex-using.mmd index d23567b424..6125f87115 100644 --- a/diagrams/simplex-messaging/simplex-using.mmd +++ b/diagrams/simplex-messaging/simplex-using.mmd @@ -1,10 +1,10 @@ sequenceDiagram participant B as Bob (sender) - participant S as server (conn. RU) + participant S as server (conn. RID) participant A as Alice (recipient) - note over B: encrypt message
("public" key EK) - B ->> S: 1. send message to SU (SK-signed req) + note over B: encrypt message
("public" key EK) + B ->> S: 1. send message to SID (SK-signed command) - S ->> A: 2. retrieve messages from RU (RK-signed req) - note over A: decrypt message
("private" key EK) + S ->> A: 2. retrieve messages from RID (RK-signed subscription) + note over A: decrypt message
("private" key EK) diff --git a/diagrams/simplex-messaging/simplex-using.svg b/diagrams/simplex-messaging/simplex-using.svg index 9200f2756c..49023e16f7 100644 --- a/diagrams/simplex-messaging/simplex-using.svg +++ b/diagrams/simplex-messaging/simplex-using.svg @@ -1,505 +1 @@ -Bob (sender)server (conn. RU)Alice (recipient)encrypt message ("public" key EK)1. send message to SU (SK-signed req)2. retrieve messages from RU (RK-signed req)decrypt message ("private" key EK)Bob (sender)server (conn. RU)Alice (recipient) \ No newline at end of file +Bob (sender)server (conn. RID)Alice (recipient)encrypt message("public" key EK)1. send message to SID (SK-signed command)2. retrieve messages from RID (RK-signed subscription)decrypt message("private" key EK)Bob (sender)server (conn. RID)Alice (recipient) \ No newline at end of file diff --git a/diagrams/simplex-messaging/simplex.mmd b/diagrams/simplex-messaging/simplex.mmd index c9d4c64caa..c8cbad02b7 100644 --- a/diagrams/simplex-messaging/simplex.mmd +++ b/diagrams/simplex-messaging/simplex.mmd @@ -3,9 +3,9 @@ graph LR VR{{"verify recipient (RK)"}} S(sender) -->|msg| VS - subgraph "server (connection RU)" + subgraph "server (connection RID)" VS --> DB[("storage")] DB --> VR end - R(recipient) -->|"1) req"| VR - VR -->|"2) msg"| R \ No newline at end of file + R(recipient) -->|"1) sub"| VR + VR -->|"2) msg"| R diff --git a/diagrams/simplex-messaging/simplex.svg b/diagrams/simplex-messaging/simplex.svg index ea99794770..e560e6e09b 100644 --- a/diagrams/simplex-messaging/simplex.svg +++ b/diagrams/simplex-messaging/simplex.svg @@ -1,505 +1 @@ -
server (connection RU)
msg
1) req
2) msg
storage
verify sender (SK)
verify recipient (RK)
sender
recipient
\ No newline at end of file +
server (connection RID)
msg
1) sub
2) msg
storage
verify sender (SK)
verify recipient (RK)
sender
recipient
\ No newline at end of file diff --git a/readme.md b/readme.md index 19438c79a7..2274af1894 100644 --- a/readme.md +++ b/readme.md @@ -2,92 +2,162 @@ ## Problems -Existing chat platforms and protocols have some or all of the following problems: -- lack of privacy of the conversation, partially caused by [E2EE][1] implementations. +Existing chat platforms and protocols have some or all of the following +problems: + +- lack of privacy of the conversation, partially caused by [E2EE][1] + implementations. - lack of privacy of the user profile and connections. - unsolicited messages (spam and abuse). - lack of data ownership and protection. -- complexity of usage for all non-centralised protocols to all non-technical users +- complexity of usage for all non-centralised protocols to all non-technical + users -Some of these problems are covered in more details in the proposed protocols on which this chat system will be based on: -- [simplex messaging][6] - low level client-server protocol for asynchronous distributed unidirectional messaging -- [graph-chat][8] - high level chat protocol for client applications that communicate via simplex messaging protocol +Some of these problems are covered in more details in the proposed protocols on +which this chat system will be based on: -Even though EU-wide GDPR legislation to ensure users' privacy and data protection was adopted, the centralisation of the communication in a small number of platforms makes resolving these problems quite difficult. +- [simplex messaging][6] - low level client-server protocol for asynchronous + distributed unidirectional messaging. +- [graph-chat][8] - high level chat protocol for client applications that + communicate via simplex messaging protocol. +Even though EU-wide GDPR legislation to ensure users' privacy and data +protection was adopted, the centralisation of the communication in a small +number of platforms makes resolving these problems quite difficult. # Comparison with [P2P][9] messaging protocols -There are several P2P chat/messaging protocols and implementations that aim to solve privacy and centralisation problem, but they have their own set of problems that makes them less reliable than the proposed chat system design, more complex to implement and analyse and more vulnerable to attacks. - -1. [P2P][9] networks either have some centralised component, which makes them highly vulnerable, or, more commonly, use some variant of [DHT][10] to route messages/requests through the network. DHT implementations have complex designs that have to balance reliability, delivery guarantee and latency, and also have some other problems. The proposed chat system design has both high delivery guarantee and low latency (the message is passed multiple times in parallel, through one node each time, using servers chosen by the recipient, while in P2P networks the message is passed through `O(log N)` nodes sequentially, using nodes chosen by the algorithm). -2. The proposed design, unlike most P2P networks, has no global identity of any form, even temporary. -3. P2P itself does not solve [MITM attack][2] problem, but most existing solutions do not use out-of-band messages for the initial key exchange. The proposed design uses out-of-band messages or, in some cases, pre-existing secure and trusted connections for the initial key exchange. -4. P2P implementations can be blocked by some Internet providers (like [BitTorrent][11]). The proposed design uses standard web protocols, and the servers can be deployed on the same domains as existing public websites. -5. All known P2P networks are likely to be vulnerable to [Sybil attack][12], because each node is discoverable, and the network operates as a whole. Known measures to reduce the probability of the Sybil attack problem either require a vulnerable centralised component or expensive [proof of work][13]. The proposed design, on the opposite, has no server discoverability - servers are not connected, not known to each other and to all clients. The chat network is fragmented and operates as multiple isolated networks. It makes Sybil attack on the whole chat network impossible - even if some servers are compromised, other parts of the network can operate normally, and affected clients can always switch to using other servers without losing contacts or messages. -6. P2P networks are likely to be vulnerable to [DRDoS attack][14]. In the proposed design clients only relay traffic from known trusted connection and cannot be used to reflect and amplify the traffic in the whole network. +There are several P2P chat/messaging protocols and implementations that aim to +solve privacy and centralisation problem, but they have their own set of +problems that makes them less reliable than the proposed chat system design, +more complex to implement and analyse and more vulnerable to attacks. +1. [P2P][9] networks either have some centralised component, which makes them + highly vulnerable, or, more commonly, use some variant of [DHT][10] to route + messages/requests through the network. DHT implementations have complex + designs that have to balance reliability, delivery guarantee and latency, and + also have some other problems. The proposed chat system design has both + higher delivery guarantee and low latency (the message is passed multiple + times in parallel, through one node each time, using servers chosen by the + recipient, while in P2P networks the message is passed through `O(log N)` + nodes sequentially, using nodes chosen by the algorithm). +2. The proposed design, unlike most P2P networks, has no global identity of any + form, even temporary. +3. P2P itself does not solve [MITM attack][2] problem, but most existing + solutions do not use out-of-band messages for the initial key exchange. The + proposed design uses out-of-band messages or, in some cases, pre-existing + secure and trusted connections for the initial key exchange. +4. P2P implementations can be blocked by some Internet providers (like + [BitTorrent][11]). The proposed design is transport agnostic - it can work + over standard web protocols, and the servers can be deployed on the same + domains as the existing public websites. +5. All known P2P networks are likely to be vulnerable to [Sybil attack][12], + because each node is discoverable, and the network operates as a whole. Known + measures to reduce the probability of the Sybil attack either require a + vulnerable centralised component or expensive [proof of work][13]. The + proposed design, on the opposite, has no server discoverability - servers are + not connected, not known to each other and to all clients. The chat network + is fragmented and operates as multiple isolated connections. It makes Sybil + attack on the whole simplex messaging network impossible - even if some + servers are compromised, other parts of the network can operate normally, and + affected clients can always switch to using other servers without losing + contacts or messages. +6. P2P networks are likely to be vulnerable to [DRDoS attack][14]. In the + proposed design clients only relay traffic from known trusted connection and + cannot be used to reflect and amplify the traffic in the whole network. ## Privacy requirements -- User profile is only visible to the profile connections, but not to the chat network +- User profile is only visible to the profile connections, but not to the chat + network - User profile is not stored on the servers. - Profile connections are not stored on the server. -- It should not be possible to construct the list of user connections by analysing server database or any logs. -- It should not be possible, other than by compromising the client, to send messages from another user profile. -- It should not be possible, other than by compromising all servers the user is connected to, to prevent message delivery to a user. +- It should not be possible to construct the list of user connections by + analysing server database or any logs. +- It should not be possible, other than by compromising the client, to send + messages from another user profile. +- It should not be possible, other than by compromising all servers the user is + connected to, to prevent message delivery to a user. - All participants of the conversation should be able to: - prove that the received messages were actually sent by another party. - prove that the sent messages were received by another party. - ## Chat scenarios Any advanced chat system needs to support several main chat scenarios: + - direct messaging. - group chat. - broadcasts. In addition to that, there are other important chat scenarios: + - [OTR messaging][3] - multiple user devices sharing contacts and conversation histories. - introductions -While it is not required to be supported in the v1 of the protocol, it is important to have clarity on how all these scenarios can be supported in the future. - +While it is not required to be supported in the v1 of the protocol, it is +important to have clarity on how all these scenarios can be supported in the +future. ## Chat system features -- No user identity known to system servers - no phone numbers, user names and no DNS are used to identify the users to the system. -- Each user can be connected to multiple servers to ensure message delivery, even if some of the servers are compromised. -- Uses standard asymmetric cryptographic protocols, so that system users can create independent server and client implementations complying with the protocols. -- Open-source server implementations that can be easily deployed by any user with minimal technical expertise (e.g. on Heroku via web UI). -- Open-source mobile client implementations (including web client) so that system users can independently assess system security model. -- Only client applications store user profiles, contacts of other user profiles, messages; servers do NOT have access to any of this information and (unless compromised) do NOT store encrypted messages or any logs. -- Multiple client applications and devices can be used by each user profile to communicate and to share connections and message history - the devices are not known to the servers. -- Initial key exchange and establishing connections between user profiles is done by sharing QR code via any independent communication channel (or directly via screen and camera), system servers are NOT used for key exchange - to reduce risk of key substitution in [MITM attack][2]. QR code contains the connection-specific public key and other information needed to establish connection. -- Connections between users can be established via shared trusted connections to simplify key exchange. -- Servers do NOT communicate with each other, they only communicate with client applications. +- No user identity known to system servers - no phone numbers, user names and no + DNS are needed to identify the users to the system. +- Each user can be connected to multiple servers to ensure message delivery, + even if some of the servers are compromised. +- Uses standard asymmetric cryptographic protocols, so that system users can + create independent server and client implementations complying with the + protocols. +- Open-source server implementations that can be easily deployed by any user + with minimal technical expertise (e.g. on Heroku via web UI). +- Open-source client implementations so that system users can independently + assess system security model. +- Only client applications store user profiles, contacts of other user profiles, + messages; servers do NOT have access to any of this information and (unless + compromised) do NOT store encrypted messages or any logs. +- Multiple client applications and devices can be used by each user profile to + communicate and to share connections and message history - the devices are not + known to the servers. +- Initial key exchange and establishing connections between user profiles is + done by sharing QR code via any independent communication channel (or directly + via screen and camera), system servers are NOT used for key exchange - to + reduce risk of key substitution in [MITM attack][2]. QR code contains the + connection-specific public key and other information needed to establish the + connection. +- Connections between users can be established via shared trusted connections to + simplify key exchange. +- Servers do NOT communicate with each other, they only communicate with client + applications. - Unique public key is used for each user profile connection in order to: - reduce the risk of attacker posing as user's connection - avoid exposing all user connections to the servers -- Unique public key is used to identify each connection participant to each server. -- Public keys used between connections are regularly rotated to prevent decryption of the full message history ([forward secrecy][4]) in case when some servers or middlemen 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 and trust. -- 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. -- 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. - +- Unique public key is used to identify each connection participant to each + server. +- Public keys used between connections are regularly rotated to prevent + decryption of the full message history ([forward secrecy][4]) in case when + some servers or middlemen 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 and trust. +- 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. +- 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. ## System components - simplex messaging servers -- graph-chat client applications (using simplex messaging protocol to communicate with the servers) - +- graph-chat client applications (using simplex messaging protocol to + communicate with the servers) ### Chat servers -Simplex messaging servers can be either available to all users or only to users who have a valid URI to create connections (see [simplex messaging protocol][6]). - +Simplex messaging servers can be either available to all users or only to users +who have a valid URI to create connections (see [simplex messaging +protocol][6]). ### Chat client application @@ -97,54 +167,65 @@ Client apps should provide the following features: - create and manage user profiles - support multiple user profiles. -- share access to all or selected user profiles with other devices (optionally including existing connections and message histories). +- share access to all or selected user profiles with other devices (optionally + including existing connections and message histories). - for each user profile: - - generate and show QR code with connection-specific public key and other information that can be shown on the screen and/or sent via alternative channel. + - generate and show QR code with connection-specific public key and other + information that can be shown on the screen and/or sent via alternative + channel. - read QR code (via the camera) to establish connection with another user. - receive and accept connection requests. - exchange user profiles once connection is accepted. - send messages to connected user profiles. - receive messages from connected user profile. - define the servers to use. - - store history of all conversations encrypted using user client app key with passphrase (or some other device specific encryption method). - + - store history of all conversations encrypted using user client app key with + passphrase (or some other device specific encryption method). ## System design -The chat system design is based on 2 protocols, each with the generic part, describing protocol flow and logic, and implementation part, describing protocol transports, data structures and algorithms. +The chat system design is based on 2 protocols, each with the generic part, +describing protocol flow and logic, and implementation part, describing protocol +transports, data structures and algorithms. -1. [simplex messaging protocol][6] - a low level generic messaging protocol that defines establishing and using a simplex connection between chat participants on a single server. While this protocol is designed to support graph-chat client protocol (below), it can be used for other messaging scenarios, not limited to chats. -2. [simplex messaging protocol implementation][7] - requirements to clients and servers implementing simplex messaging protocol, including: - - cryptographic algorithms to sign/verify requests and to encrypt/decrypt messages. - - privacy requirements to the servers. - - REST API for connections and messages. - - WebSocket API to subscribe to connections and receive new messages. - - other requirements for simplex messaging servers. -3. [graph-chat protocol][8] - a high level generic chat protocol for client applications (graph vertices) that communicate via simplex connections created using simplex messaging protocol. This protocol defines connection and message types and semantics for: - - various chat elements (user profiles, direct chats, chat groups, broadcasts, etc.). - - other communication scenarios - e.g. introduction, off-the-record chat, etc. +1. [simplex messaging protocol][6] - a low level messaging protocol that defines + establishing and using a simplex connection between chat participants on a + single server. While this protocol is designed to support graph-chat client + protocol (below), it can be used for other messaging scenarios, not limited + to chats. +2. [graph-chat protocol][8] - a high level generic chat protocol for client + applications (graph vertices) that communicate via simplex connections + created using simplex messaging protocol. This protocol defines connection + and message types and semantics for: + - various chat elements (user profiles, direct chats, chat groups, + broadcasts, etc.). + - other communication scenarios - e.g. introduction, off-the-record chat, + etc. - using multiple servers to ensure message delivery. - sharing user profiles, contacts and chats across multiple client devices. - - changing cryptographic keys and servers used to send and receive messages using simplex messaging server protocol. - - sending and receiving out-of-band messages between client applications using "visual code". -4. graph-chat client application protocol (TODO) - a high level specific chat protocol for client applications. This protocol specifies: + - changing cryptographic keys and servers used to send and receive messages + using simplex messaging server protocol. + - sending and receiving out-of-band messages between client applications + using "visual code". +3. graph-chat client application protocol (TODO) - a high level specific chat + protocol for client applications. This protocol specifies: - data structures for sending and receiving messages of all types. - - process to send and receive out-of-band messages between client applications. + - process to send and receive out-of-band messages between client + applications. - other requirements for graph-chat client applications. - defines a specific "visual code" format to send an out-of-band message. - [1]: https://en.wikipedia.org/wiki/End-to-end_encryption [2]: https://en.wikipedia.org/wiki/Man-in-the-middle_attack [3]: https://en.wikipedia.org/wiki/Off-the-Record_Messaging [4]: https://en.wikipedia.org/wiki/Forward_secrecy [5]: https://mermaid-js.github.io/mermaid-live-editor [6]: simplex-messaging.md -[7]: simplex-messaging-implementation.md [8]: graph-chat.md [9]: https://en.wikipedia.org/wiki/Peer-to-peer [10]: https://en.wikipedia.org/wiki/Distributed_hash_table [11]: https://en.wikipedia.org/wiki/BitTorrent [12]: https://en.wikipedia.org/wiki/Sybil_attack [13]: https://en.wikipedia.org/wiki/Proof_of_work -[14]: https://www.usenix.org/conference/woot15/workshop-program/presentation/p2p-file-sharing-hell-exploiting-bittorrent +[14]: + https://www.usenix.org/conference/woot15/workshop-program/presentation/p2p-file-sharing-hell-exploiting-bittorrent diff --git a/simplex-messaging-api.md b/simplex-messaging-api.md deleted file mode 100644 index e122fa8730..0000000000 --- a/simplex-messaging-api.md +++ /dev/null @@ -1,199 +0,0 @@ -## Simplex messaging protocol REST API - -This document lists all required REST endpoints of simplex messaging API. - -Also see [Simplex messaging protocol implementation](simplex-messaging-implementation.md) for more details. - -## POST /connection - -### Create connection - - -### Request: - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript -{"recipientKey":"BODbZxmtKUUF1l8pj4nVjQ"} -``` - -### Response: - -- Status code 201 -- Headers: [] - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript -{"senderId":"N9pA3g","recipientId":"Qxz93A"} -``` - -## DELETE /connection/:connectionId - -### Delete connection - - -### Captures: - -- *connectionId*: Recipient connection ID - unique connection ID to be used by connection recipient - -### Response: - -- Status code 200 -- Headers: [] - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript - -``` - -## PUT /connection/:connectionId - -### Secure connection - - -### Captures: - -- *connectionId*: Recipient connection ID - unique connection ID to be used by connection recipient - -### Request: - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript -{"senderKey":"XPaVEVNunkYKqqK0dnAT5Q"} -``` - -### Response: - -- Status code 200 -- Headers: [] - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript - -``` - -## GET /connection/:connectionId/messages - -### Get messages - - -### Captures: - -- *connectionId*: Recipient connection ID - unique connection ID to be used by connection recipient - -### GET Parameters: - -- fromMessageId - - **Values**: *message ID, e.g., `p8PCiGPZ`* - - **Description**: if set, the server will respond with the messages received starting from the message with server message ID (unique per server) passed in this parameter. - - -### Response: - -- Status code 200 -- Headers: [] - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript -{"messages":[{"ts":"2020-03-15T19:58:33.695Z","msg":"OQLMXoEA4iv-aR46puPJuY1Rdoc1KY0gfq8oElJwtAs","msgId":"p8PCiGPZ"}],"nextMessageId":null} -``` - -## DELETE /connection/:connectionId/messages/:messageId - -### Delete message - - -### Captures: - -- *connectionId*: Recipient connection ID - unique connection ID to be used by connection recipient -- *messageId*: Message ID - unique message ID to be used by connection recipient - -### Response: - -- Status code 200 -- Headers: [] - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript - -``` - -## POST /connection/:senderConnectionId/messages - -### Send message - - -### Captures: - -- *senderConnectionId*: Sender connection ID - unique connection ID to be used by connection sender - -### Request: - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript -{"msg":"OQLMXoEA4iv-aR46puPJuY1Rdoc1KY0gfq8oElJwtAs"} -``` - -### Response: - -- Status code 201 -- Headers: [] - -- Supported content types are: - - - `application/json;charset=utf-8` - - `application/json` - -- Example (`application/json;charset=utf-8`, `application/json`): - -```javascript - -``` - diff --git a/simplex-messaging-implementation.md b/simplex-messaging-implementation.md deleted file mode 100644 index d11dbc221a..0000000000 --- a/simplex-messaging-implementation.md +++ /dev/null @@ -1,403 +0,0 @@ -# Simplex messaging protocol implementation - -This document defines specific elements to be used by client and server implementations of simplex messaging protocol. This protocol relies on the connection creation and messaging flows defined in generic [simplex messaging protocol][1]. - -This document defines: -- [cryptographic algorithms](#cryptographic-algorithms) to sign/verify requests and to encrypt/decrypt messages. -- [connection URIs](#connection-uris) generation by the servers. -- [privacy requirements](#privacy-requirements) to the servers. -- [REST API](#rest-api): - - to create and to secure connections. - - to send, to retrieve and to delete messages. -- [WebSockets API](#websockets-api): - - to subscribe to connections. - - to receive the new messages. -- any other requirements for simplex messaging servers - - -## Cryptographic algorithms - -Simplex messaging clients need to cryptographically sign requests: -- with the recipient's key `RK` (server to verify): - - to create connections. - - to subscribe to connection. - - to change connection attributes. - - to delete the connection. - - to retrieve messages from the connection -- with the sender's key `SK`: - - to send the initial request including public key `SK` (connection recipient to verify). - - to send messages (server to verify). - -To sign and verify requests, clients and servers MUST use RSA-PSS algorythm defined in [RFC3447][2]. - -To optinally sign and verify messages, clients SHOULD use RSA-PSS algorythm. - -To encrypt and decrypt messages, clients SHOULD use RSA-OAEP algorythm defined in [RFC3447][2]. - -The reasons to support these algorithms: -- they are supported by WebCrypto API. -- they are newer versions than RSA-PKCS1-v1_5 encryption and signature schemes. -- they are more widely supported than ECC algorithms - -Future versions of the protocol may allow different algorithms. - - -## Connection URIs - -Simplex messaging servers MUST generate 2 different URIs for each new connection - for recipient (that created the connection) and for sender. It is REQUIRED that: -- these URIs are different. -- based on 64-bit number generated with cryptographically strong pseudo-random number generator. - -Coonection URIs can be: -- server domain, path used to create connection and random string (e.g. `https://example.com/connection/aZ...9f), e.g. base-64 encoded 64-bit random number. -- any unique URI that server recognises. - - -## Privacy requirements - -Simplex messaging server implementations MUST NOT create, store or send to any other servers: -- logs of the client requests in the production environment. -- history of deleted connections or retrieved (and removed) messages. -- snapshots of the database they use to store connections and messages (instead simplex messaging clients must manage redundancy by using more than one simplex messaging server, e.g., as described in [graph-chat protocol][3]). -- any other information that may compromise privacy or [forward secrecy][4] of communication between clients using simplex messaging server. - - -## REST API - -### General API considerations - -Simplex messaging server MUST provide REST API via HTTPS protocol. It MAY operate on the same domain as any other web application. It is RECOMMENDED that the endpoint to create connections and all connection URIs start from the same path, to avoid namespace conflicts with other applications. - -All request parameters and properties of the request body are required, unless specified as optional. The server MUST reject the request with HTTP status code 400 (Bad Request) in the following cases: -- missing required parameter. -- additional unknown parameter. -- incorrect type/value of the parameter. -- not empty request body when request body is not specified in the API description. -- any cookie in the request. - -"Parameter" in the list above includes URI path component, query string request parameter and any property or sub-property of the request body. - -> **NOTE**: To prevent timing attacks response time for all syntactically correct requests of one type is REQUIRED to be the same. In case of any failure caused by bad request values (e.g. non existant URI or message ID, wrong signature or lack of one), server MUST always reject the request with the same HTTP status code and MUST aim to make response time to be the same regardless of failure cause. - -Below examples of API endpoints use: -- server `https://example.com` -- path `/connection` - - -### Request headers - -All server requests MUST use JSON object as request body and MUST use HTTP header `Content-Type: application/json`. - -... client protocol version - -TODO - - -### Request authorization - -All server requests MUST be signed with the relevant key and the digital signature MUST be passed in HTTP header `Authorization`. - -In case of signature verification failure, server MUST reject the request with HTTP status code 401 (Unauthorized). - -TODO Authorization header format - - -### Response headers - -... server protocol version - -... server timestamp - -... CORS headers - -... OPTION requests - -TODO - - -### REST API endpoints - -Simplex messaging server MUST provide the API endpoints for the recipient and for the sender. The list of endpoints below is exhaustive and servers MUST NOT implement any other endpoints. The actual API URI schemes can differ between implementations from the below examples, and between deployments, based on server configuration. - -URI scheme provides an additional layer of security to access the connection for both the sender and the recipient, and allows to implement and deploy private simplex messaging servers. - -`/messages` path segment is REQUIRED in all endpoints to retrieve, delete and send messages and MUST NOT be changed by any implementation or deployment. - -Endpoints for the recipient: -- [Create connection](#create-connection): POST `create URI` (e.g. `https://example.com/connection`) -- [Secure connection](#secure-connection): PUT `` (e.g. `https://example.com/connection/aZ9f`) -- [Delete connection](#delete-connection): DELETE `` (e.g. `https://example.com/connection/aZ9f`) -- [Retrieve messages](#retrieve-messages): GET `/messages[?fromMessageId=]` (e.g. `https://example.com/connection/aZ9f/messages`) -- [Retrieve message](#retrieve-message): GET `/messages/` (e.g. `https://example.com/connection/aZ9f/messages/1234`) -- [Delete message](#delete-message): DELETE `/messages/` (e.g. `https://example.com/connection/aZ9f/messages/1234`) - -Endpoints for the sender: -- [Send message](#send-message): POST `/messages` (e.g. `https://example.com/connection/bY1h/messages`) - -__Please note__: the server MUST NOT allow the sender to delete or modify the messages after they are sent via any endpoints or any other means. - - -### REST API endpoints for the connection recipients - -#### Create connection - -POST: `CREATE_CONNECTION` URI as defined by server configuration, can be different per server user. - -Example: POST `https://example.com/connection` - -Server MUST define a single endpoint to create connections. This endpoint can be: -- server domain without any path, if the domain is not shared with other web application. -- server domain and path used for all connection URIs. -- server domain, path and secure token(s) (possibly user-specific), if the server owner wants to restrict access to creating connections (for private or commercial servers). -- any other, potentially undiscoverable, URI that server recognises. - -To create a connection, simplex messaging client MUST send POST request to this endpoint. The request MUST be signed with the key `RK`. - -Request body should be sent as JSON object with the following properties: -- `recipient` (string): public key `RK` to verify digital signature of the recipient. - -REQUIRED server responses: if the connection creation succeeded, the server MUST respond with HTTP status code 201 (Created) and the response body MUST be a JSON object with the following properties: -- `recipientURI` (string): recipient URI `RU` of the connection that MUST be used as the endpoint for requests to retrieve the messages, to update connection attributes and to delete the connection. Clients MUST NOT share this URI with the sender. -- `senderURI` (string): sender URI `SU` of the connection that MUST be used as the endpoint for requests to send the messages. - - -#### Secure connection - -PUT: recipient connection URI `` - -Example: PUT `https://example.com/connection/aZ9f` - -To secure the connection, simplex messaging client MUST send PUT request to the recipient connection URI `RU` (returned by the server when creating the connection). The request MUST be signed with the key `RK`. - -Request body should be sent as JSON object with the following properties: -- `sender` (string): public key `SK` to verify digital signature of the sender. - -REQUIRED server responses: -- success - HTTP status code 200 (OK) with body `"OK"`. -- failure - HTTP status code 401 (Unauthorized) with body `"Unauthorized"` in the following cases: - - the connection `RU` was previously secured and the sender key is already set. - - the request is unsigned or signed with the wrong key. - - the connection `RU` does not exist. - -In case of failure the server MUST aim to respond in the same time to prevent timing attacks - it can be achieved by verifying a signature even if the connection does not exist. - - -#### Delete connection - -DELETE: recipient connection URI `` - -Example: DELETE `https://example.com/connection/aZ9f` - -To delete the connection, simplex messaging client MUST send DELETE request to the recipient connection URI `RU` (returned by the server when creating the connection), signed with the key `RK`. - -Server MUST permanently delete the connection and all unretrieved messages without preserving any copy of the connection or messages. - -REQUIRED server responses: -- success - HTTP status code 200 (OK) with body `"OK"`. -- failure - HTTP status code 401 (Unauthorized) with body `"Unauthorized"` in the following cases: - - the request is unsigned or signed with the wrong key. - - the connection `RU` does not exist. - -In case of failure the server MUST aim to respond in the same time to prevent timing attacks - it can be achieved by verifying a signature even if the connection does not exist. - -All further requests to the recipient and sender connection URIs MUST fail. - - -#### Retrieve messages - -GET: `/messages[?fromMessageId=]` - -Example: GET `https://example.com/connection/aZ9f/messages` - -To retrieve messages from the connection, simplex messaging client MUST send POST request to the recipient connection URI `RU` (returned by the server when creating the connection) with the REQUIRED appended string `/messages` (it MUST NOT be changed by any implementation or deployment). The request MUST be signed with the key `RK`. - -Optional query string parameter can be used for pagination: -- `fromMessageId` (string, optional): if set, the server will retrieve the messages received starting from the message with server message ID (unique per server) passed in this parameter. - -Simplex messaging server will NOT delete the messages when this endpoint is called, to remove messages once retrieved [Delete message](#delete-message) MUST be called. - -__Please note__: server implementations MUST NOT track in any form how many times or whether the messages were retrieved. - -If the request is successful, the server MUST respond with HTTP status code (200) returning as response body not more than `PAGE_SIZE` (as configured in the server) of the earliest sent messages with the following properties: -- `messages` (array): retrieved messages. Each retrieved message is an object with the following properties: - - `id` (string): server-generated unique ID allowing to identify messages (until they are deleted from the server) and to paginate responses. - - `ts`(string) : server timestamp of the time when the message was received from the sender. - - `size` (number): message size, in bytes. - - `msg` (string, optional): encrypted message body, that the recipient should be able to decrypt with the key `EK`. This field is not returned if the message is larger than `LARGE_MESSAGE` (configured in the server), large messages can be retrieved via [Retrieve message](#retrieve_message) endpoint. -- `nextMessageID` (string, optional): if server has more messages available it MUST return this parameter with the ID of the next available message - it can be used by the next request in `fromMessageId` query string parameter. - -Server MUST respond with HTTP status code 401 (Unauthorized) with body `"Unauthorized"` in the following request failure scenarios: - - the request is unsigned or signed with the wrong key. - - the connection `RU` does not exist. - - the message with ID `fromMessageId` does not exist. - -In case of failure the server MUST aim to respond in the same time to prevent timing attacks - it can be achieved by verifying a signature even if the connection does not exist. - - -#### Retrieve message - -GET: `/messages/` - -Example: GET `https://example.com/connection/aZ9f/messages/1234` - -To retrieve single message from the connection (e.g. large message), simplex messaging client MUST send POST request to the recipient connection URI `RU` (returned by the server when creating the connection) with the REQUIRED appended string `/messages/` (it MUST NOT be changed by any implementation or deployment). The request MUST be signed with the key `RK`. - -Simplex messaging server will NOT delete the message when this endpoint is called, to remove the message once retrieved [Delete message](#delete-message) MUST be called. - -__Please note__: server implementations MUST NOT track in any form how many times or whether the messages were retrieved. - -If the request is successful, the server MUST respond with HTTP status code (200) returning as response body the requested message with the following properties: -- `id` (string): server-generated unique ID allowing to identify messages (until they are deleted from the server) and to paginate responses. -- `ts` (string): server timestamp of the time when the message was received from the sender. -- `size` (number): message size, in bytes. -- `msg` (string): encrypted message body, that the recipient should be able to decrypt with the key `EK`. - -Server MUST respond with HTTP status code 401 (Unauthorized) with body `"Unauthorized"` in the following request failure scenarios: - - the request is unsigned or signed with the wrong key. - - the connection `RU` does not exist. - - the message with ID `messageId` does not exist. - -In case of failure the server MUST aim to respond in the same time to prevent timing attacks - it can be achieved by verifying a signature even if the connection does not exist. - - -#### Delete message - -DELETE: `/messages/` - -Example: DELETE `https://example.com/connection/aZ9f/messages/1234` - -To delete a single message from the connection, simplex messaging client MUST send DELETE request to the recipient connection URI `RU` (returned by the server when creating the connection) with the REQUIRED appended string `/messages` and message ID. The request MUST be signed with the key `RK`. - -Simplex messaging clients MUST use this endpoint to delete the previously retrived and stored (or processed) large messages. - -Simplex messaging server MUST permanently remove the message. - -REQUIRED server responses: -- success - HTTP status code 200 (OK) with body `"OK"`. -- failure - HTTP status code 401 (Unauthorized) with body `"Unauthorized"` in the following cases: - - the request is unsigned or signed with the wrong key. - - the connection `RU` does not exist. - - the message with ID `messageId` does not exist. - -In case of failure the server MUST aim to respond in the same time to prevent timing attacks - it can be achieved by verifying a signature even if the connection does not exist. - - -### REST API endpoints for the connection sender - -#### Send message - -POST: `/messages` - -Example: POST `https://example.com/connection/bY1h/messages` - -To send message to the connection, simplex messaging client MUST send POST request to the sender connection URI `SU` (returned by the server when creating the connection) with the REQUIRED appended string `/messages` (it MUST NOT be changed by any implementation or deployment), signed with the key `SK`. - -Request body MUST be sent as JSON object with the following properties: -- `msg` (string): encrypted message body, that the recipient should be able to decrypt with the key `EK`. Any message meta-data (client timestamp, ID, etc.) MUST be inside the encrypted message and MUST NOT passed via additional properties. - -REQUIRED server responses: -- success - HTTP status code 200 (OK) with body `"OK"`. -- failure - HTTP status code 401 (Unauthorized) with body `"Unauthorized"` in the following cases: - - the request is unsigned or signed with the wrong key. - - the connection `SU` does not exist. - -In case of failure the server MUST aim to respond in the same time to prevent timing attacks - it can be achieved by verifying a signature even if the connection does not exist. - - -## WebSockets API - -Simplex messaging servers MUST provide WebSocket API on the same URI as creating connection but with secure WebSocket protocol. For example, if the URI to create a new connection is `https://example.com/connection` then WebSocket API MUST be available on `wss://example.com/connection`. - -WebSocket API is only intended for connection recipients to subscribe to connections in order to receive and to delete messages from the connections. - -Data of the messages sent both from the client and from the server MUST be an object type in JSON format. - - -### Subscribe to the connection - -Client message properties: - -- `id` (string): request ID, MUST be unique for WebSocket session. -- `type` (string): MUST be `"subscribe"` -- `recipientURI` (string): recipient connection URI -- `auth` (string): digital signature of the message object without `auth` property, serialised without whitespace, signed with the "private" key `RK` (counterpart of the "public" key in `recipient` parameter of connection creation request). - -Server response message properties: - -- `id` (string): client request ID. -- `type` (string): MUST be `"subscribe"` -- `recipientURI` (string): recipient connection URI -- `ok` (boolean): subscription success. Subcription can fail in case connection URI does not exist or in case signature verification fails. The server MUST process the response in the same time in both cases to prevent timing attacks - it can be achieved by verifying a digital signature of a sample data. - - -### Unsubscribe from the connection - -#### Client message properties: - -- `id` (string): request ID, MUST be random and unique for WebSocket session. -- `type` (string): MUST be `"unsubscribe"` -- `recipientURI` (string): recipient connection URI - -#### Server response message: - -- `id` (string): client request ID. -- `type` (string): MUST be `"unsubscribe"` -- `recipientURI` (string): recipient connection URI -- `ok` (boolean): unsubscription success. Subcription can fail in case connection URI does not exist or in case the client did not previously subscribe to this connection in the same WebSocket session. The server MUST process the response in the same time in both cases to prevent timing attacks. - - -### Receive and delete messages - -Server will send messages sent to all the simplex connections that the recepient is subscribed to via the current WebSocket connection. Server MUST send the messages in the same order as they arrive. - -#### Server message properties: - -- `type` (string): MUST be `"message"`. -- `recipientURI` (string): recipient connection URI that the message is received from. -- `message` (object): it has properties: - - `id` (string): server-generated unique ID allowing to identify messages until they are deleted from the server and to paginate responses. - - `ts`(string) : server timestamp of the time when the message was received from the sender. - - `size` (number): message size, in bytes. - - `msg` (string, optional): encrypted message body, that the recipient should be able to decrypt with the key `EK`. This field is not returned if the message is larger than `LARGE_MESSAGE` (configured in the server), large messages can be retrieved via [Retrieve message](#retrieve_message) endpoint. - -#### Client response message properties: - -This message MUST be sent to the server once the message is stored in the client. Large messages not sent over WebSocket have to be downloaded via REST API before they are deleted. - -- `id` (string): request ID, MUST be random and unique for WebSocket session -- `type` (string): MUST be `"delete_message"` -- `recipientURI` (string): recipient connection URI that the message is deleted from. -- `messageId` (string): server-generated unique per simplex connection message ID. - -#### Server response message: - -This message MUST be sent to the client once the message is deleted from the server. - -- `id`: client request ID. -- `type`: MUST be `"delete_message"` -- `recipientURI` (string): recipient connection URI that the message is deleted from. -- `messageId` (string): server-generated unique per simplex sonnection message ID. -- `ok` (boolean): deletion success. Deletion can fail in case connection URI or message ID does not exist, or in case the client did not previously subscribe to this connection in the same WebSocket session. The server MUST process the response in the same time in all cases to prevent timing attacks. - - -### Invalid client messages - -When a client sends the messages with unknown `type`, missing or additional properties, the server MUST respond with the message: - -- `id`: client request ID. -- `type`: `"invalid"`. -- `error` (string): JSON pointer ([RFC6901][5]) to the first incorrect property in the client message. The property is "incorrect" if it's either unallowed type or value, missing required property or present additional property. If the whole message data is incorrect (e.g. it is not an object or it is bigger than `MAX_WEBSOCKET_MESSAGE` server config parameter), this JSON pointer MUST point to the whole object and is an empty string, as defined in RFC6901. - - -**Simplex connection operation:** - -![Simplex connection operations](/diagrams/simplex-messaging-impl/simplex-op.svg) - -Sequence diagram does not show E2EE - connection itself knows nothing about encryption between sender and receiver. - - -[1]: simplex-messaging.md -[2]: https://tools.ietf.org/html/rfc3447 -[3]: graph-chat.md -[4]: https://en.wikipedia.org/wiki/Forward_secrecy -[5]: https://tools.ietf.org/html/rfc6901 diff --git a/simplex-messaging.md b/simplex-messaging.md index 1e9960c183..c7cf8fde0a 100644 --- a/simplex-messaging.md +++ b/simplex-messaging.md @@ -1,142 +1,788 @@ -# Simplex messaging protocol +# Simplex messaging protocol (SMP) -A generic client-server protocol for asynchronous distributed unidirectional messaging +## Table of contents -## Problems of the existing messaging protocols +- [Abstract](#abstract) +- [Introduction](#introduction) +- [SMP Model](#smp-model) +- [Out-of-band messages](#out-of-band-messages) +- [Simplex connection](#simplex-connection) +- [SMP procedure](#smp-procedure) +- [SMP elements](#smp-elements) +- [SMP qualities and features](#smp-qualities-and-features) +- [Cryptographic algorithms](#cryptographic-algorithms) +- [Simplex connection IDs](#simplex-connection-ids) +- [Server privacy requirements](#server-privacy-requirements) +- [SMP commands](#smp-commands) + - [Correlating responses with commands](#correlating-responses-with-commands) + - [Command authentication](#command-authentication) + - [Recipient commands](#recipient-commands) + - [Create connection command](#create-connection-command) + - [Subscribe to connection](#subscribe-to-connection) + - [Secure connection command](#secure-connection-command) + - [Delete message command](#delete-message-command) + - [Suspend connection](#suspend-connection) + - [Delete connection](#delete-connection) + - [Sender commands](#sender-commands) + - [Send message command](#send-message-command) + - [Server messages](#server-messages) + - [New connection response](#new-connection-response) + - [Deliver connection message](#deliver-connection-message) + - [Error responses](#error-responses) + - [OK response](#ok-response) +- [Appendices](#appendices) + - [Appendix A. Transport connection with the SMP server](#appendix-a) + - [Appendix B. Sending out-of-band message](#appendix-b) + +## Abstract + +Simplex messaging protocol is a transport agnostic client-server protocol for +asynchronous distributed secure unidirectional message transmission. + +It's designed with the focus on communication security and integrity, under the +assumption that any part of the message transmission network can be compromised. + +It addresses the problems of existing communication protocols that undermine +communication security and privacy: - Identity related problems: + - visibility of user contacts to anybody observing messages - unsolicited messages (spam and abuse) - trademark issues (when usernames are used) - privacy issues (when phone numbers are used) + - Participants' identities are known to the network. Depending on the identity + type (e.g., phone number, DNS-based, username, uuid, public key, etc.) it + creates different problems, but in all cases it exposes participants and + their contacts graph to the network and also allows for unsolicited messages + (spam and abuse). - Participants' identities are known to the network. Depending on the identity type (e.g., phone number, DNS-based, username, uuid, public key, etc.) it creates different problems, but in all cases it exposes participants and their contacts graph to the network and also allows for unsolicited messages (spam and abuse). +- [MITM attack][1]. Any mechanism of the encryption key exchange via the same + network is prone to this type of attack when the public keys of the + participants are substituted with the public keys of the attacker intercepting + communication. While some solutions have been proposed that complicate MITM + attack (social millionaire, OTR), if the attacker understands the protocol and + has intercepted and can substitute all information exchanged between the + participants, it is still possible to substitute encryption keys. It means + that the existing [E2EE][2] implementations in messaging protocols and + platforms can be compromised by the attacked who compromised the server or + communication channel. -- [MITM attack][1]. Any mechanism of the key exchange via the same network is prone to this type of attack when the public keys of the participants are substituted with the public keys of the attacker intercepting communication. While some solutions have been proposed that complicate MITM attack (social millionaire, OTR), if the attacker understands the protocol and has intercepted and can substitute all information exchanged between the participants, it is still possible to substitute encryption keys. It means that the existing [E2EE][2] implementations in messaging protocols and platforms can be compromised by the attacked who either compromised the server or communication channel. +## Introduction +The objective of Simplex Messaging Protocol (SMP) is to facilitate the secure +and private unidirectional transfer of messages from senders to recipients. -## Simplex messaging protocol abstract +SMP is independent of the particular transmission system and requires only a +reliable ordered data stream channel. While this document describes transport +over TCP, other transports are also possible. -The proposed "simplex messaging protocol" removes the need for participants' identities and provides [E2EE][2] without the possibility of [MITM attack][1] attack under one assumption: participants have an existing alternative communication channel that they trust and can use to pass one small binary message to initiate the connection (out-of-band message). +The protocol describes the set of commands that recipient and sender can +exchange with the SMP server to create and to operate a unidirectional +"connection" (a data abstraction identifying one of many communication channels +managed by the server) and to send messages from the sender to the recipient via +the SMP server. -The out-of band message is sent via some trusted alternative channel by the connection recipient to the connection sender. This message is used to share the encryption (a.k.a. "public") key and connection URI requried to establish a unidirectional (simplex) connection: -- the sender of the connection (who received out-of-band message) will use it to send messages to the server using connection URI, signing the message by sender key. -- the recepient of the connection (who created the connection and who sent out-of-band message) will use it to retrieve messages from the server, signing the requests by the recepient key. -- participant identities are not shared with the server, as completely new keys and connection URI are used for each connection. +More complex communication scenarios can be designed using multiple +connections - for example, a duplex communication channel can be made of 2 +simplex connections. -This simplex connection is the main building block of the network that is used to build application level primitives (in graph-chat protocol) that are only known to system participants in their client applications (graph vertices) - user profiles, contacts, conversations, groups and broadcasts. At the same time, system servers are only aware of the low-level simplex connections. In this way a high level of privacy and security of the conversations is provided. Application level chat primitives defined in graph-chat protocol are not in scope of this simplex messaging protocol. +Protocol is designed with the focus on privacy and security, to some extent +deprioritizing reliability by requiring that SMP servers only store messages +until they are delivered to the recipients and, in any case, for a limited +period of time. For communication scenarios requiring more reliable transmission +the users should use several SMP servers to pass each message and implement some +additional protocol (e.g., based on blockchain) to ensure that messages are not +removed, inserted or re-ordered - this is out of scope of this document. -This approach is based on the concepts of [unidirectional networks][4] that are used for applications with high level of information security. +SMP removes the need for participants' identities and provides [E2EE][2] without +the possibility of [MITM attack][1] attack relying on two pre-requisites: -Defining the approach to out-of-band message passing is out of scope of this simplex messaging protocol. For practical purposes, and from the graph-chat client application point of view, various solutions can be used, e.g. one of the versions or the analogues of [QR code][3] (or their sequence) that is read via the camera, either directly from the chat participant's device or via the video call. Although a video call still allows for a highly sophisticated MITM attack, it requires that in addition to compromising simplex connection to intercept messages, the attacker also identifies and compromises the video connection in another channel and substitutes the video in real time - it seems extremely unlikely. +- the users can establish a secure encrypted transport connection with the SMP + server. [Appendix A](#appendix-a) has a possible simple protocol of such + transport connection over TCP, but any other transport connection encryption + protocol can be used. +- the recipient can pass a single message to the sender via pre-existing secure + and private communication channel (out-of-band message) - the information in + this message is used to establish the connection via SMP server that the + sender will use to send the encrypted messages to the recipient. +## SMP Model -## Simplex connection - the main unit of protocol design +The SMP model has three communication participants: the recipient, the message +broker (SMP server) that is chosen and, possibly, controlled by the recipient, +and the sender. -The network consists of multiple "simplex connections" (i.e. unidirectional, non-duplex). Access to each connection is controlled with unique (not shared with other connections) assymetric key pairs, separate for sender and the receiver. The sender and the receiver have private keys, and the server has associated public keys to verify participants. +SMP server manages multiple "simplex connections" - data records on the server +that identify communication channels from the senders to the recipients. The +same communicating party that is the sender in one connection, can be the +recipient in another - without exposing this fact to the server. -The messages sent into the connection are encrypted and decrypted using another key pair - the recepient has the private key and the sender has the associated public key. +The connection record consists of 2 unique random IDs generated by the server, +one for the recipient and another for the sender, and 2 keys to authenticate the +recipient and the sender respectively. The users of SMP protocol must use a +unique key for each connection, to avoid the possibility of aggregating and +analysing their connections in case SMP server is compromised. + +Creating and using this connection requires sending commands to the SMP server +from the recipient and the sender - they are described in detail in +[SMP commands](#smp-commands) section. + +## Out-of-band messages + +The out-of band invitation message is sent via some trusted alternative channel +by the recipient to the sender. This message is used to share the encryption +(a.k.a. "public") key that the sender will use to encrypt the messages (to be +decrypted by the recipient), sender connection ID, server address and any other +information necessary to establish secure encrypted connection with SMP server +(see [Appendix A](#appendix-a) for a simple transport protocol example). + +The syntax of the message defined with [ABNF][8] is: + +``` +outOfBandMsg = "(" connId "," serverHost "," transportInfo ")" +connId = encoded ; defined below +serverHost = DQUOTE hostname DQUOTE ; RFC 1123, section 2.1 +transportInfo = JSON ; for example, TCP port number and encryption key fingerprint +``` + +Defining the approach to out-of-band message passing is out of scope of the +simplex messaging protocol. See [Appendix B](#appendix-b) for one of the +possible practical approaches to passing out-of-band message. + +## Simplex connection + +The simplex connection is the main unit of SMP protocol. It is used by: + +- the sender of the connection (who received out-of-band message) to send + messages to the server using connection ID, signed by sender's key. +- the recepient of the connection (who created the connection and who sent + out-of-band message) will use it to retrieve messages from the server, signing + the commands by the recepient key. +- participant identities are not shared with the server - new unique keys and + connection IDs are used for each connection. + +This simplex connection can serve as a building block for more complex +communication network. For example, two (or more, for redundancy) simplex +connections can be used to create a duplex communication channel. Higher level +primitives that are only known to system participants in their client +applications can be created as well - user profiles, contacts, conversations, +groups and broadcasts. Simplex messaging servers have have the information about +the low-level simplex connections. In this way a high level of privacy and +security of the conversations is provided. Application level primitives are not +in scope of the simplex messaging protocol. + +This approach is based on the concept of [unidirectional networks][4] that are +used for applications with high level of information security. + +Access to each connection is controlled with unique (not shared with other +connections) assymetric key pairs, separate for sender and the recipient. The +sender and the receiver have private keys, and the server has associated public +keys to authnticate participants' commands by verifying the signatures. + +The messages sent into the connection are encrypted and decrypted using another +key pair - the recepient has the private key and the sender has the associated +public key. **Simplex connection diagram:** ![Simplex connection](/diagrams/simplex-messaging/simplex.svg) -Connection is defined by recipient URI `RU` unique to the server. It also has a different unique sender URI `SU`. Sender key (`SK`) is used by the server to verify sender's requests (made via `SU`) to send messages. Recipient key (`RK`) is used by the server to verify recipient's requests (made via `RU`) to retrieve messages. +Connection is defined by recipient ID `RID` unique for the server. It also has a +different unique sender ID `SID`. Sender key (`SK`) is used by the server to +verify sender's commands (identified by `SID`) to send messages. Recipient key +(`RK`) is used by the server to verify recipient's commands (identified by +`SID`) to retrieve messages. -The protocol uses different URIs for sender and recipient in order to provide an additional connection privacy by complicating correlation of senders and recipients. +The protocol uses different IDs for sender and recipient in order to provide an +additional connection privacy by complicating correlation of senders and +recipients commands sent over the network - even though they are encrypted using +server's public key, in case this key is compromised it would still be difficult +to correlate senders and recipients, it would require access to connections +records on the server. +## SMP procedure -## How Alice and Bob use simplex messaging protocol +The SMP procedure of creating a simplex connection on SMP server is explained +using participants Alice (the recipient) who wants to receive the messages from +Bob (the sender). -Alice (recipient) wants to receive the messages from Bob (sender). - -To do it Alice and Bob follow these steps: +To create a simpelex connection Alice and Bob follow these steps: 1. Alice creates a simplex connection on the server: - 1. she decides which simplex messaging server to use (can be the same or different server that Alice uses for other connections). - 2. she generates a new random public/private key pair (encryption key - `EK`) that she did not use before for Bob to encrypt the messages. - 3. she generates another new random public/private key pair (recepient key - `RK`) that she did not use before for her to sign requests to retrieve the messages from the server. - 4. she requests from the server to create a simplex connection. The request to create the connection is un-authenticated and anonymous. This connection request contains previouisly generated uniqie "public" key `RK` that will be used to: - - verify the requests to retrieve the messages as signed by the same person who created the connection. - - update the connection, e.g. by setting the key required to send the messages (initially Alice creates the connection that accepts unsigned requests to send messages, so anybody could send the message via this connection if they knew the connection URI). - 5. The server responds with connection URIs: - - recipient URI `RU` for Alice to manage the connection and to retrieve messages from the connection. - - sender URI `SU` for Bob to send messages to the connection. -2. Alice sends an out-of-band message to Bob via the alternative channel that both Alice and Bob trust (see [Simplex messaging protocol abstract](#simplex-messaging-protocol-abstract) above). The message includes: - - the unique "public" key (`EK`) that Bob should use to encrypt messages. - - the sender connection URI `SU` for Bob to use. -3. Bob, having received the out-of-band message from Alice, accepts the connection: - 1. he generates a new random public/private key pair (sender key - `SK`) that he did not use before for him to sign requests to Alice's server to send the messages. - 2. he prepares the first message for Alice to confirm the connection. This message includes: - - previously generated "public" key `SK` that will be used by Alice's server to verify Bob's requests to send messages. - - optionally, any information that allows Alice to identify Bob (e.g., in [graph-chat protocol][7] it is Bob's chat profile, but it can be any other information). - - optionally, any other additional information (e.g., Bob could pass the details of another connection including sender connection URI and a new "public" encryption key for Alice to send reply messages to Bob, also see [graph-chat protocol][7]). - 3. he encrypts the message by the "public" key `EK` (that Alice provided via the out-of-band message). - 4. he sends the encrypted message to the connection URI `SU` to confirm the connection (that Alice provided via the out-of-band message). This request to send the first message does not need to be signed. -4. Alice retrieves Bob's message from the server via recipient connection URI `RU`: - 1. she decrypts retrieved message with "private" key `EK`. - 2. even though anybody could have sent the message to the connection with URI `SU` before it is secured (e.g. if communication is compromised), Alice would ignore all messages until the decryption succeeds (i.e. the result contains the expected message structure). Optionally, she also may identify Bob using the information provided, but it is not required by this protocol. -5. Alice secures the connection `RU` so only Bob can send messages to it: - 1. she sends the request to `RU` signed with "private" key `RK` to update the connection to only accept requests signed by "private" key `SK` provided by Bob. - 2. From this moment the server will accept only signed requests, and only Bob will be able to send messages to the `SU` corresponding to connection `RU`. -6. The simplex connection `RU` is now established on the server. + 1. decides which SMP server to use (can be the same or different server that + Alice uses for other connections) and opens secure encrypted transport + connection to the chosen SMP server (see [Appendix A](#appendix-a)). + 2. generates a new random public/private key pair (encryption key - `EK`) + that she did not use before for Bob to encrypt the messages. + 3. generates another new random public/private key pair (recepient key - + `RK`) that she did not use before for her to sign commands and to decrypt + the transmissions received from the server. + 4. sends the command to the server to create a simplex connection (see + `create` in [Create connection command](#create-connection-command)). This + command can either be anonymous or the server can be configured to use the + signature field to authenticate the users who are allowed to create + connections. This connection command contains previouisly generated uniqie + "public" key `RK` that will be used to sign the following commands related + to the same connection, for example to subscribe to the messages received + to this connection or to update the connection, e.g. by setting the key + required to send the messages (initially Alice creates the connection that + accepts unsigned commands to send messages, so anybody could send the + message via this connection if they knew the connection ID and server + address). + 5. The server responds with connection IDs (`connResp`): + - recipient ID `RID` for Alice to manage the connection and to receive the + messages. + - sender ID `SID` for Bob to send messages to the connection. +2. Alice sends an out-of-band message to Bob via the alternative channel that + both Alice and Bob trust (see + [Simplex messaging protocol abstract](#simplex-messaging-protocol-abstract) + and [Appendix B](#appendix-b)). The message must include: + - the unique "public" key (`EK`) that Bob must use to encrypt messages. + - SMP server address and information to open secure encrypted transport + connection (see [Appendix A](#appendix-a)) + - the sender connection ID `SID` for Bob to use. +3. Bob, having received the out-of-band message from Alice, accepts the + connection: + 1. generates a new random public/private key pair (sender key - `SK`) that he + did not use before for him to sign commands to Alice's server to send the + messages. + 2. prepares the confirmation message for Alice to secure the connection. This + message includes: + - previously generated "public" key `SK` that will be used by Alice's + server to authenticate Bob's commands to send messages, once the + connection is secured. + - optionally, any additional information (application specific, e.g. Bob's + profile name and details). + 3. encrypts the confirmation body with the "public" key `EK` (that Alice + provided via the out-of-band message). + 4. sends the encrypted message to the server with connection ID `SID` (see + `send` in [Send message command](#send-message-command)) to confirm the + connection. This message to confirm the connection must not be signed - + signed messages will be rejected until Alice secures the connection + (below). +4. Alice receives Bob's message from the server using recipient connection ID + `RID` (possibly, via the same transport connection she already has opened - + see `message` in [Deliver connection message](#deliver-connection-message)): + 1. she decrypts received message with "private" key `EK`. + 2. even though anybody could have sent the message to the connection with ID + `SID` before it is secured (e.g. if communication is compromised), Alice + would ignore all messages until the decryption succeeds (i.e. the result + contains the expected message format). Optionally, in the client + application, she also may identify Bob using the information provided, but + it is out of scope of SMP protocol. +5. Alice secures the connection `RID` so only Bob can send messages to it (see + `secure` in [Secure connection command](#secure-connection-command)): + 1. she sends the command with `RID` signed with "private" key `RK` to update + the connection to only accept requests signed by "private" key `SK` + provided by Bob. + 2. From this moment the server will accept only signed commands to `SID`, so + only Bob will be able to send messages to the connection `SID` + (corresponding to `RID` that Alice has). + 3. Once connection is secured, Alice deletes `SID` and `SK` - even if Alice's + client is compromosed in the future, the attacker would not be able to + send messages pretending to be Bob. +6. The simplex connection `RID` is now established on the server. + +This flow is shown on the sequence diagram below. **Creating simplex connection from Bob to Alice:** ![Creating connection](/diagrams/simplex-messaging/simplex-creating.svg) - -Bob now can securely send messages to Alice. +Bob now can securely send messages to Alice: 1. Bob sends the message: - 1. he encrypts the message to Alice with "public" key `EK` (provided by Alice, only known to Alice and Bob, used only for one simplex connection). - 2. he signs the request to the server (via `SU`) using the "private" key `SK` (that only he knows, used only for this connection). - 3. he sends the request to the server, that the server will verify using the "public" key SK (that Alice provided to the server). -2. Alice retrieves the message(s): - 1. she signs request to the server with the "private" key `RK` (that only she has, used only for this connection) and sends it to `RU`. - 2. the server, having verified Alice's request with the "public" key `RK` that she provided, responds with Bob's message(s). - 3. she decrypts Bob's message(s) with the "private" key `EK` (that only she has). + 1. he encrypts the message to Alice with "public" key `EK` (provided by + Alice, only known to Alice and Bob, used only for one simplex connection). + 2. he signs the command to the server connection `SID` using the "private" + key `SK` (that only he knows, used only for this connection). + 3. he sends the command to the server (see `send` in + [Send message command](#send-message-command)), that the server will + authenticate using the "public" key `SK` (that Alice earlier provided to + the server). +2. Alice receives the message(s): + 1. she signs the command to the server to subscribe to the connection `RID` + with the "private" key `RK` (see `subscribeCmd` in + [Subscribe to connection](#subscribe-to-connection)). + 2. the server, having authenticated Alice's command with the "public" key + `RK` that she provided, delivers Bob's message(s) (see `message` in + [Deliver connection message](#deliver-connection-message)). + 3. she decrypts Bob's message(s) with the "private" key `EK` (that only she + has). + +This flow is show on sequence diagram below. **Sending messages from Bob to Alice via simplex connection:** ![Using connection](/diagrams/simplex-messaging/simplex-using.svg) +**Simplex connection operation:** -A higher level protocol (e.g., [graph-chat][7]) defines the semantics that allow to use two simplex connections (or two sets of connections for redundancy) for the bi-directional messaging chat and for any other communication scenarios. +![Simplex connection operations](/diagrams/simplex-messaging/simplex-op.svg) -The simplex messaging protocol is intentionally sipmlex - it provides no answer to how Bob will know that the process succeeded, and whether Alice received any messages. There may be a situation when Alice wants to securely receive the messages from Bob, but she does not want Bob to have any proof that she received any messages - this low-level simplex messaging protocol can be used in this scenario, as all Bob knows as a fact is that he was able to send one unsigned message to the server that Alice provided, and now can only send messages signed with the key `SK` that he sent to the server - it does not prove that any message was received by Alice. +Sequence diagram does not show E2EE - connection itself knows nothing about +encryption between sender and receiver. -For practical purposes of bi-directional conversation, now that Bob can securely send encrypted messages to Alice, Bob can establish the second simplex connection that will allow Alice to send messages to Bob in the same way. If both Alice and Bob have their respective uniqie "public" keys (Alice's and Bob's `EK`s of two separate connections), the conversation can be both encrypted and signed. +A higher level protocol application protocol should define the semantics that +allow to use two simplex connections (or two sets of connections for redundancy) +for the bi-directional chat and for any other communication scenarios. -The established connection can also be used to change the encryption keys providing [forward secrecy][5]. +The SMP is intentionally unidirectional - it provides no answer to how Bob will +know that the transmission succeeded, and whether Alice received any messages. +There may be a situation when Alice wants to securely receive the messages from +Bob, but she does not want Bob to have any proof that she received any +messages - this low-level simplex messaging protocol can be used in this +scenario, as all Bob knows as a fact is that he was able to send one unsigned +message to the server that Alice provided, and now can only send messages signed +with the key `SK` that he sent to the server - it does not prove that any +message was received by Alice. -This protocol also can be used for off-the-record messaging, as Alice and Bob can have multiple connections established between them and only information they pass to each other allows proving their identity, so if they want to share anything off-the-record they can initiate a new connection without linking it to any other information they exchanged. As a result, this protocol provides better anonymity and better protection from [MITM][1] than [OTR][6] protocol. +For practical purposes of bi-directional conversation, now that Bob can securely +send encrypted messages to Alice, Bob can establish the second simplex +connection that will allow Alice to send messages to Bob in the same way. If +both Alice and Bob have their respective uniqie "public" keys (Alice's and Bob's +`EK`s of two separate connections), the conversation can be both encrypted and +signed. -How simplex connections are used by the participants (graph vertices) is defined by graph-chat protocol and is not in scope of this low level simplex messaging protocol. +The established connections can also be used to change the encryption keys +providing [forward secrecy][5]. +This protocol also can be used for off-the-record messaging, as Alice and Bob +can have multiple connections established between them and only information they +pass to each other allows proving their identity, so if they want to share +anything off-the-record they can initiate a new connection without linking it to +any other information they exchanged. As a result, this protocol provides better +anonymity and better protection from [MITM][1] than [OTR][6] protocol. -## Elements of the generic simplex messaging protocol +How simplex connections are used by the participants is not in scope of this low +level simplex messaging protocol. + +## SMP qualities and features + +The simplex messaging protocol: - defines only message-passing protocol: - - transport agnostic - the protocol does not define how clients connect to the servers and does not require persistent connections. While a generic term "request" is used, it can be implemented in various ways - HTTP requests, messages over (web)sockets, etc. This is defined by simplex messaging server protocol. - - not semantic - the protocol does not assign any meaning to connections and messages. While on the application level the connections and messages can have different meaning (e.g., for messages: text or image chat message, message acknowledgement, participant profile information, status updates, changing "public" key to encrypt messages, changing servers, etc.), on the simplex messaging protocol level all the messages are binary and their meaning can only be interpreted by client applications and not by the servers - this interpretation is in scope of graph-chat protocol and out of scope of this simplex messaging protocol. + - transport agnostic - the protocol does not define how clients connect to the + servers and does not require persistent connections. While a generic term + "command" is used, it can be implemented in various ways - TCP connection, + HTTP requests, messages over (web)sockets, etc.. + - not semantic - the protocol does not assign any meaning to connections and + messages. While on the application level the connections and messages can + have different meaning (e.g., for messages: text or image chat message, + message acknowledgement, participant profile information, status updates, + changing "public" key to encrypt messages, changing servers, etc.), on the + simplex messaging protocol level all the messages are binary and their + meaning can only be interpreted by client applications and not by the + servers - this interpretation is in scope of application level protocol and + out of scope of this simplex messaging protocol. - client-server architecture: - - multiple servers, that can be deployed by the system users, can be used to send and retrieve messages. - - servers do not communicate with each other and do not even "know" about other servers. - - clients only communicate with servers (excluding the initial out-of-band message), so the message passing is asynchronous. - - for each connection, the message recipient defines the server through which the sender should send messages. - - while multiple servers and multiple connections can be used to pass each chat message, it is in scope of graph-chat protocol, and out of scope of this simplex messaging protocol. - - servers store messages only until they are retrieved by the recipients - - servers are not supposed to store any message history or delivery log, but even if the server is compromised, it does not allow to decrypt the messages or to determine the list of connections established by any participant - this information is only stored on client devices. -- the only element provided by simplex messaging servers is simplex connections: + - multiple servers, that can be deployed by the system users, can be used to + send and retrieve messages. + - servers do not communicate with each other and do not even "know" about + other servers. + - clients only communicate with servers (excluding the initial out-of-band + message), so the message passing is asynchronous. + - for each connection, the message recipient defines the server through which + the sender should send messages. + - while multiple servers and multiple connections can be used to pass each + message, it is in scope of application level protocol(s), and out of scope + of this simplex messaging protocol. + - servers store messages only until they are retrieved by the recipients, and + in any case, for a limited time. + - servers are required to NOT store any message history or delivery log, but + even if the server is compromised, it does not allow to decrypt the messages + or to determine the list of connections established by any participant - + this information is only stored on client devices. +- the only element provided by SMP servers is simplex connections: - each connection is created and managed by the connection recipient. - - assymetric encryption is used to sign and verify the requests to send and receive the messages. - - one unique "public" key is used for the servers to authenticate requests to send the messages into the connection, and another unique "public" key - to retrieve the messages from the connection. "Unique" here means that each "public" key is used only for one connection and is not used for any other context - effectively this key is not public and does not represent any participant identity. - - both "public" keys are provided to the server by the connection recepient when the connection is established. - - the "public" keys known to the server and used to authenticate requests from the participants are unrelated to the keys used to encrypt and decrypt the messages - the latter keys are also unique per each connection but they are only known to participants, not to the servers. - - messaging graph can be asymmetric: Bob's ability to send messages to Alice does not automatically lead to the Alice's ability to send messages to Bob. - - connections are identified by sender and recipient server URIs. + - assymetric encryption is used to sign and verify the requests to send and + receive the messages. + - one unique "public" key is used for the servers to authenticate requests to + send the messages into the connection, and another unique "public" key - to + retrieve the messages from the connection. "Unique" here means that each + "public" key is used only for one connection and is not used for any other + context - effectively this key is not public and does not represent any + participant identity. + - both "public" keys are provided to the server by the connection recepient + when the connection is established. + - the "public" keys known to the server and used to authenticate commands from + the participants are unrelated to the keys used to encrypt and decrypt the + messages - the latter keys are also unique per each connection but they are + only known to participants, not to the servers. + - messaging graph can be asymmetric: Bob's ability to send messages to Alice + does not automatically lead to the Alice's ability to send messages to Bob. + - connections are identified by sender and recipient server IDs. +## Cryptographic algorithms + +Simplex messaging clients need to cryptographically sign commands: + +- with the recipient's key `RK` (server to verify): + - to subscribe to connection. + - to secure the connection. + - to delete received messages. + - to suspend the connection. + - to delete the connection. +- with the sender's key `SK`: + - to send messages (server to verify). + +To sign and verify commands, clients and servers MUST use RSA-PSS algorythm +defined in [RFC3447][2]. + +To optinally sign and verify messages, clients SHOULD use RSA-PSS algorythm. + +To encrypt and decrypt messages, clients and servers SHOULD use RSA-OAEP +algorythm defined in [RFC3447][2]. + +The reasons to use these algorithms: + +- they are supported by WebCrypto API. +- they are newer versions than RSA-PKCS1-v1_5 encryption and signature schemes. +- they are more widely supported than ECC algorithms + +Future versions of the protocol may allow different algorithms. + +## Simplex connection IDs + +Simplex messaging servers MUST generate 2 different IDs for each new +connection - for recipient (that created the connection) and for sender. It is +REQUIRED that: + +- these IDs are different and unique within the server. +- based on 128-bit integers generated with cryptographically strong + pseudo-random number generator. + +## Server privacy requirements + +Simplex messaging server implementations MUST NOT create, store or send to any +other servers: + +- logs of the client commands and transport connections in the production + environment. +- history of deleted connections, retrieved or removed messages. +- snapshots of the database they use to store connections and messages (instead + simplex messaging clients must manage redundancy by using more than one + simplex messaging server. +- any other information that may compromise privacy or [forward secrecy][4] of + communication between clients using simplex messaging servers. + +## SMP commands + +Commands syntax below is provided using [ABNF][8]. + +Each transmission between the client and the server must have this format/syntax +(after the decryption): + +```abnf +transmission = signed CRLF signature CRLF +signed = connId CRLF msg +msg = recipientCmd / send / serverMsg +recipientCmd = create / subscribe / secure / deleteMsg / suspend / delete +serverMsg = conn / ok / error / message +connId = (encoded " ") / "" ; empty connection ID is used with "create" command +signature = encoded / "" ; empty signature can be used with "create" and "send" commands +encoded = base64 +``` + +`base64` encoding should be used with padding, as defined in section 4 of [RFC +4648][9] + +The syntax of specific commands and responses is defined below. + +### Correlating responses with commands + +The server must send `conn`, `error` and `ok` responses in the same order within +each connection ID as the commands received in the transport connection, so that +they can be correlated by the clients. + +If the transport connection is closed before some responses are sent, these +responses should be discarded. + +### Command authentication + +The SMP servers must athenticate all transmissions (excluding `create` and +`send` commands sent with empty signatures) by verifying the provided +signatures. Signature should be the hash of the first part `signed` (including +CRLF characters) of `transmission`, encrypted with the key associated with the +connection ID (sender's or recepient's, depending on which connection ID is +used). + +### Recipient commands + +Sending any of the commands in this section (other than `create`, that is sent +without connection ID) is only allowed with recipient's ID (`RID`). If sender's +ID is used the server must respond with `"ERROR AUTH"` response (see +[Error responses](#error-responses)). + +#### Create connection command + +This command is sent by the recipient to the SMP server to create the new +connection. The syntax is: + +```abnf +create = %s"CREATE " recipientKey +recipientKey = encoded +``` + +If the connection is created successfully, the server must send `conn` response +with the recipient's and sender's connection IDs: + +```abnf +conn = %s"CONN " recipientId " " senderId +recipientId = encoded +senderId = encoded +``` + +Once the connection is created, the recipient gets automatically subscribed to +receive the messages from that connection, until the transport connection is +closed. The `subscribe` command is needed only to start receiving the messages +from the existing connection when the new transport connection is opened. + +`signature` part of `transmission` should an empty string; SMP servers can also +use it to authenticate users who are allowed to create simplex connections. + +#### Subscribe to connection + +When the simplex connection was not created in the current transport connection, +the recipient must use this command to start receiving messages from it: + +```abnf +subscribe = %s"SUB" +``` + +If subscription is successful (`ok` response) the recipient will be receiving +the messages from this connection until the transport connection is closed - +there is no command to unsubscribe. + +#### Secure connection command + +This command is sent by the recipient to the server to add sender's key to the +connection: + +``` +secure = %s"SECURE " senderKey +senderKey = encoded +``` + +`senderKey` is received from the sender as part of the first message - see +[Send Message Command](#send-message-command). + +Once the connection is secured only signed messages can be sent to it. + +#### Delete message command + +The recipient should send this command once the message was stored in the +client, to notify the server that the message should be deleted: + +```abnf +deleteMsg = %s"DELMSG " msgId +msgId = encoded +``` + +Even if this command is not sent by the recipient, the servers should limit the +time of message storage, whether it was delivered to the recipient or not. + +#### Suspend connection + +The recipient can suspend connection prior to deleting it to make sure no +messages are lost: + +```abnf +suspendCmd = %s"SUSPEND" +``` + +The server must respond with `"ERROR AUTH"` to any messages sent after the +connection was suspended (see [Error responses](#error-responses)). + +The server must respond `ok` to this command only after all messages related to +the connection were delivered. + +This command can be sent multiple times (in case transport connection was +interrupted and the response was not delivered), the server should still respond +`ok` even if the connection is already suspended. + +There is no command to unsuspend the connection. Servers must delete suspended +connections that were not deleted after some period of time. + +#### Delete connection + +The recipient can delete the connection, whether it was suspended or not. + +All undelivered messages will not be delivered - they will be deleted as soon as +command is received, before the response is sent. + +```abnf +deleteCmd = %s"DELETE" +``` + +### Sender commands + +Currently SMP defines only one command that can be used by sender - `send` +message. This command must be used with sender's ID, if recipient's ID is used +the server must respond with `"ERROR AUTH"` response (see +[Error responses](#error-responses)). + +#### Send message command + +This command is sent to the server by the sender both to confirm the connection +after the sender received out-of-band message from the recipient and to send +messages after the connection is secured: + +```abnf +send = %s"SEND " msgBody +msgBody = stringMsg | binaryMsg +stringMsg = ":" string ; until CRLF in the transmission +string = *(%x01-09 / %x0B-0C / %x0E-FF %) ; any characters other than NUL, CR and LF +binaryMsg = size CRLF msgBody CRLF ; the last CRLF is in addition to CRLF + ; in the transmission +size = 1*DIGIT ; size in bytes +msgBody = *OCTET ; any content of specified size - safe for binary +``` + +`stringMsg` is allowed primarily to test SMP servers, e.g. via telnet. + +The signature with this command must be empty, otherwise it must result in +`ERROR SYNTAX` response. + +The first message is sent to confirm the connection - it should contain sender's +server key (see decrypted message syntax below) - this message must be sent +without signature. + +Once connection is secured (see +[Secure connection command](#secure-connection-command)), messages must be sent +with signature. + +The server must respond with `"ERROR AUTH"` response in the following cases: + +- connection does not exist or suspended, +- connection is secured but the transmission does NOT have a signature, +- connection is NOT secured but the transmission has a signature. + +Until the connection is secured, the server should accept any number of unsigned +messages - it both enables the legimate sender to resend the confirmation in +case of failure and also allows the simplex messaging client to ignore any +confirmation messages that may be sent by the attackers (assuming they could +have intercepted the connection ID in the server response, but do not have a +correct encryption key passed to sender in out-of-band message). + +The body should be encrypted with the recipient's "public" key (`EK`); once +decrypted it must have this format: + +```abnf +decryptedBody = reserved CRLF clientBody CRLF +reserved = senderKeyMsg / *VCHAR +senderKeyMsg = "KEY " senderKey +senderKey = encoded +clientBody = *OCTET +``` + +`reserved` for the initial unsigned message is used to transmit sender's server +key and can be used in future revision of the protocol for other purposes. + +### Server messages + +#### New connection response + +Server must respond with this message when the new connection is created. + +See its syntax in [Create connection command](#create-connection-command) + +#### Deliver connection message + +The server must deliver messages to all subscribed simplex connections on the +currently open transport connection. The syntax for the message delivery is: + +```abnf +message = %s"MSG " msgId " " timestamp " " msgBody +msgId = encoded +timestamp = date-time; RFC3339 +``` + +`msgId` - a unique within the server message ID based on 128-bit +cryptographically random integer. + +`timestamp` - the UTC time when the server received the message from the sender, +must be in date-time format defined by [RFC 3339][10] + +`msgBody` - string or binary message, see syntax in +[Send message command](#send-message-command) + +#### Error responses + +The server can respond with an error response in the following cases: + +- unknown command name (`"CMD"`), +- incorrect command or transmission syntax (`"SYNTAX"`) - wrong format, number + of parameters or incorrect format of parameters , +- authentication error (`"AUTH"`) - incorrect signature, unknown or suspended + connection, sender's ID is used in place of recipient's and vice versa, and + some other cases (see [Send message command](#send-message-command)) +- internal server error (`"INTERNAL"`). + +The syntax for error responses: + +```abnf +error = %s"ERROR " errorType +errorType = %s"CMD" / %s"SYNTAX" / %s"AUTH" / %s"INTERNAL" +``` + +Server implementations must aim to respond within the same time for each command +in all cases when `"ERROR AUTH"` response is required to prevent timing attacks +(e.g., the server should execute signature verification even when the connection +does not exist on the server). + +### OK response + +When the command is successfully executed by the server, it should respond with +OK response: + +```abnf +ok = %s"OK" +``` + +## Appendices + +### Appendix A. + +Secure encrypted transport connection with the SMP server. + +Both the recipient and the sender can use TCP or some other (possibly higher +level) transport protocol to communicate with the server. + +Some protocol should be used to ecrypt the connection traffic - one simple +option that does not require any cetralized certificate authority is below. + +When the connection is established, the server sends the binary encryption key +that the client should match with key or fingerprint available to them - if they +do not match, they should terminate the connection. + +The client should respond with the symmetric key that will be used by both the +client and the server to encrypt all traffic in the connection - this key should +be encrypted with the public key initially sent by the server. + +After the symmetric key is sent to the server, all communication should happen +in encrypted binary chunks having a fixed size of 4096 bytes irrespective of the +size of the command/message that should be sent. Smaller messages should be +padded, multiple commands/messages can be packed into a single chunk. If the +application using SMP needs to transmit a file or a larger message, it should be +broken down into fragments. The format of application level messages within SMP +commands is out of scope of this protocol. + +### Appendix B. + +Sending out-of-band message. + +SMP does not prescribe the channel to pass out-of-band message - it should be +agreed by the client applications. + +For practical purposes various solutions can be used, e.g. one of the versions +or the analogues of [QR code][3] (or their sequence) that is read via the +camera, either directly from the participant's device or via the video call. +Although a video call still allows for a highly sophisticated MITM attack, it +would require that in addition to compromising simplex connection to intercept +messages, the attacker also identifies and compromises the video connection in +another channel and substitutes the video in real time. [1]: https://en.wikipedia.org/wiki/Man-in-the-middle_attack [2]: https://en.wikipedia.org/wiki/End-to-end_encryption @@ -144,4 +790,6 @@ How simplex connections are used by the participants (graph vertices) is defined [4]: https://en.wikipedia.org/wiki/Unidirectional_network [5]: https://en.wikipedia.org/wiki/Forward_secrecy [6]: https://en.wikipedia.org/wiki/Off-the-Record_Messaging -[7]: graph-chat.md +[8]: https://tools.ietf.org/html/rfc5234 +[9]: https://tools.ietf.org/html/rfc4648#section-4 +[10]: https://tools.ietf.org/html/rfc3339