From ddc6319bf6d2ffdea211b17a99b7d3193116cea1 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Thu, 6 Apr 2017 13:52:26 -0700 Subject: [PATCH] protocol docs fixups --- docs/client-protocol.md | 20 +++++++++-------- docs/server-protocol.md | 50 +++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/docs/client-protocol.md b/docs/client-protocol.md index 037d69b..331ccf6 100644 --- a/docs/client-protocol.md +++ b/docs/client-protocol.md @@ -31,9 +31,10 @@ similar negotiation. At this stage, the client knows the supposed shared key, but has not yet seen evidence that the peer knows it too. When the first peer message arrives (i.e. the first message with a `.side` that does not equal our own), it will -be decrypted: if this decryption succeeds, then we're confident that -*somebody* used the same wormhole code as us. This event pushes the client -mood from "lonely" to "happy". +be decrypted: we use authenticated encryption (`nacl.SecretBox`), so if this +decryption succeeds, then we're confident that *somebody* used the same +wormhole code as us. This event pushes the client mood from "lonely" to +"happy". This might be triggered by the peer's `version` message, but if we had to re-establish the Rendezvous Server connection, we might get peer messages out @@ -46,14 +47,15 @@ strictly in-order: if we see phases 3 then 2 then 1, all three will be delivered in sequence after phase 1 is received. If any message cannot be successfully decrypted, the mood is set to "scary", -and the wormhole is closed. All pending Deferreds will be errbacked with some -kind of WormholeError, the nameplate/mailbox will be released, and the -WebSocket connection will be dropped. If the application calls `close()`, the -resulting Deferred will not fire until deallocation has finished and the -WebSocket is closed, and then it will fire with an errback. +and the wormhole is closed. All pending Deferreds will be errbacked with a +`WrongPasswordError` (a subclass of `WormholeError`), the nameplate/mailbox +will be released, and the WebSocket connection will be dropped. If the +application calls `close()`, the resulting Deferred will not fire until +deallocation has finished and the WebSocket is closed, and then it will fire +with an errback. Both `version` and all numeric (app-specific) phases are encrypted. The -message body will be the hex-encoded output of a NACL SecretBox, keyed by a +message body will be the hex-encoded output of a NaCl `SecretBox`, keyed by a phase+side -specific key (computed with HKDF-SHA256, using the shared PAKE key as the secret input, and `wormhole:phase:%s%s % (SHA256(side), SHA256(phase))` as the CTXinfo), with a random nonce. diff --git a/docs/server-protocol.md b/docs/server-protocol.md index de52cd5..3afb967 100644 --- a/docs/server-protocol.md +++ b/docs/server-protocol.md @@ -50,23 +50,23 @@ the server and both clients, to identify protocol slowdowns and guide optimization efforts. To support this, the client/server messages include additional keys. Client->Server messages include a random `id` key, which is copied into the `ack` that is immediately sent back to the client for all -commands (and is ignored except for the timing tool). Some client->server -messages (`list`, `allocate`, `claim`, `release`, `close`, `ping`) provoke a -direct response by the server: for these, `id` is copied into the response. -This helps the tool correlate the command and response. All server->client -messages have a `server_tx` timestamp (seconds since epoch, as a float), -which records when the message left the server. Direct responses include a -`server_rx` timestamp, to record when the client's command was received. The -tool combines these with local timestamps (recorded by the client and not -shared with the server) to build a full picture of network delays and -round-trip times. +commands (logged for the timing tool but otherwise ignored). Some +client->server messages (`list`, `allocate`, `claim`, `release`, `close`, +`ping`) provoke a direct response by the server: for these, `id` is copied +into the response. This helps the tool correlate the command and response. +All server->client messages have a `server_tx` timestamp (seconds since +epoch, as a float), which records when the message left the server. Direct +responses include a `server_rx` timestamp, to record when the client's +command was received. The tool combines these with local timestamps (recorded +by the client and not shared with the server) to build a full picture of +network delays and round-trip times. All messages are serialized as JSON, encoded to UTF-8, and the resulting bytes sent as a single "binary-mode" WebSocket payload. Servers can signal `error` for any message type it does not recognize. Clients and Servers must ignore unrecognized keys in otherwise-recognized -messages. +messages. Clients must ignore unrecognized message types from the Server. ## Connection-Specific (Client-to-Server) Messages @@ -74,8 +74,8 @@ The first thing each client sends to the server, immediately after the WebSocket connection is established, is a `bind` message. This specifies the AppID and side (in keys `appid` and `side`, respectively) that all subsequent messages will be scoped to. While technically each message could be -independent, I thought it would be less confusing to use exactly one -WebSocket per logical wormhole connection. +independent (with its own `appid` and `side`), I thought it would be less +confusing to use exactly one WebSocket per logical wormhole connection. The first thing the server sends to each client is the `welcome` message. This is intended to deliver important status information to the client that @@ -123,7 +123,7 @@ all nameplates, even ones which they've allocated themselves. Nameplates (on the server) must live until the second client has learned about the associated mailbox, after which point they can be reused by other clients. So if two clients connect quickly, but then maintain a long-lived -wormhole connection, the do not need to consume the limited spare of short +wormhole connection, the do not need to consume the limited space of short nameplates for that whole time. The `allocate` command allocates a nameplate (the server returns one that is @@ -133,7 +133,9 @@ with all allocated nameplates for the bound AppID: this helps the code-input tab-completion feature know which prefixes to offer. The `nameplates` response returns a list of dictionaries, one per claimed nameplate, with at least an `id` key in each one (with the nameplate string). Future versions -may record additional attributes in the nameplate records. +may record additional attributes in the nameplate records, specifically a +wordlist identifier and a code length (again to help with code-completion on +the receiver). ## Mailboxes @@ -162,17 +164,17 @@ interaction. The server records the mood in its "usage" record, so the server operator can get a sense of how many connections are succeeding and failing. The moods currently recognized by the Rendezvous Server are: -* happy (default): the PAKE key-establishment worked, and the client saw a - valid encrypted message from its peer -* lonely: the client gave up without hearing anything from its peer -* scary: the client saw an invalid encrypted message from its peer, +* `happy` (default): the PAKE key-establishment worked, and the client saw at + least one valid encrypted message from its peer +* `lonely`: the client gave up without hearing anything from its peer +* `scary`: the client saw an invalid encrypted message from its peer, indicating that either the wormhole code was typed in wrong, or an attacker tried (and failed) to guess the code -* errory: the client encountered some other error: protocol problem or +* `errory`: the client encountered some other error: protocol problem or internal error -The server will also record "pruney" if it deleted the mailbox due to -inactivity, or "crowded" if more than two sides tried to access the mailbox. +The server will also record `pruney` if it deleted the mailbox due to +inactivity, or `crowded` if more than two sides tried to access the mailbox. When clients use the `add` command to add a client-to-client message, they will put the body (a bytestring) into the command as a hex-encoded string in @@ -223,7 +225,7 @@ any), and which ones provoke direct responses: The server stores all messages in a database, so it should not lose any information when it is restarted. The server will not send a direct response until any side-effects (such as the message being added to the -mailbox) being safely committed to the database. +mailbox) have been safely committed to the database. The client library knows how to resume the protocol after a reconnection event, assuming the client process itself continues to run. @@ -232,4 +234,4 @@ Clients which terminate entirely between messages (e.g. a secure chat application, which requires multiple wormhole messages to exchange address-book entries, and which must function even if the two apps are never both running at the same time) can use "Journal Mode" to ensure forward -progress is made: see "api.md" (Journal Mode) for details. +progress is made: see "journal.md" for details.