aboutsummaryrefslogtreecommitdiff
path: root/spec/rend-spec/rendezvous-protocol.md
diff options
context:
space:
mode:
Diffstat (limited to 'spec/rend-spec/rendezvous-protocol.md')
-rw-r--r--spec/rend-spec/rendezvous-protocol.md138
1 files changed, 138 insertions, 0 deletions
diff --git a/spec/rend-spec/rendezvous-protocol.md b/spec/rend-spec/rendezvous-protocol.md
new file mode 100644
index 0000000..0f6d4e9
--- /dev/null
+++ b/spec/rend-spec/rendezvous-protocol.md
@@ -0,0 +1,138 @@
+<a id="rend-spec-v3.txt-4"></a>
+
+# The rendezvous protocol
+
+Before connecting to a hidden service, the client first builds a
+circuit to an arbitrarily chosen Tor node (known as the rendezvous
+point), and sends an ESTABLISH_RENDEZVOUS message. The hidden service
+later connects to the same node and sends a RENDEZVOUS message. Once
+this has occurred, the relay forwards the contents of the RENDEZVOUS
+message to the client, and joins the two circuits together.
+
+Single Onion Services attempt to build a non-anonymous single-hop circuit,
+but use an anonymous 3-hop circuit if:
+
+```text
+ * the rend point is on an address that is configured as unreachable via
+ a direct connection, or
+ * the initial attempt to connect to the rend point over a single-hop
+ circuit fails, and they are retrying the rend point connection.
+```
+
+<a id="rend-spec-v3.txt-4.1"></a>
+
+## Establishing a rendezvous point {#EST_REND_POINT}
+
+The client sends the rendezvous point a RELAY_COMMAND_ESTABLISH_RENDEZVOUS
+message containing a 20-byte value.
+
+RENDEZVOUS_COOKIE \[20 bytes\]
+
+Rendezvous points MUST ignore any extra bytes in an
+ESTABLISH_RENDEZVOUS message. (Older versions of Tor did not.)
+
+The rendezvous cookie is an arbitrary 20-byte value, chosen randomly
+by the client. The client SHOULD choose a new rendezvous cookie for
+each new connection attempt. If the rendezvous cookie is already in
+use on an existing circuit, the rendezvous point should reject it and
+destroy the circuit.
+
+Upon receiving an ESTABLISH_RENDEZVOUS message, the rendezvous point associates
+the cookie with the circuit on which it was sent. It replies to the client
+with an empty RENDEZVOUS_ESTABLISHED message to indicate success. Clients MUST
+ignore any extra bytes in a RENDEZVOUS_ESTABLISHED message.
+
+The client MUST NOT use the circuit which sent the message for any
+purpose other than rendezvous with the given location-hidden service.
+
+The client should establish a rendezvous point BEFORE trying to
+connect to a hidden service.
+
+<a id="rend-spec-v3.txt-4.2"></a>
+
+## Joining to a rendezvous point {#JOIN_REND}
+
+To complete a rendezvous, the hidden service host builds a circuit to
+the rendezvous point and sends a RENDEZVOUS1 message containing:
+
+```text
+ RENDEZVOUS_COOKIE [20 bytes]
+ HANDSHAKE_INFO [variable; depends on handshake type
+ used.]
+```
+
+where RENDEZVOUS_COOKIE is the cookie suggested by the client during the
+introduction (see \[PROCESS_INTRO2\]) and HANDSHAKE_INFO is defined in
+\[NTOR-WITH-EXTRA-DATA\].
+
+If the cookie matches the rendezvous cookie set on any
+not-yet-connected circuit on the rendezvous point, the rendezvous
+point connects the two circuits, and sends a RENDEZVOUS2 message to the
+client containing the HANDSHAKE_INFO field of the RENDEZVOUS1 message.
+
+Upon receiving the RENDEZVOUS2 message, the client verifies that HANDSHAKE_INFO
+correctly completes a handshake. To do so, the client parses SERVER_PK from
+HANDSHAKE_INFO and reverses the final operations of section
+\[NTOR-WITH-EXTRA-DATA\] as shown here:
+
+```text
+ rend_secret_hs_input = EXP(Y,x) | EXP(B,x) | AUTH_KEY | B | X | Y | PROTOID
+ NTOR_KEY_SEED = MAC(rend_secret_hs_input, t_hsenc)
+ verify = MAC(rend_secret_hs_input, t_hsverify)
+ auth_input = verify | AUTH_KEY | B | Y | X | PROTOID | "Server"
+ AUTH_INPUT_MAC = MAC(auth_input, t_hsmac)
+```
+
+Finally the client verifies that the received AUTH field of HANDSHAKE_INFO
+is equal to the computed AUTH_INPUT_MAC.
+
+Now both parties use the handshake output to derive shared keys for use on
+the circuit as specified in the section below:
+
+<a id="rend-spec-v3.txt-4.2.1"></a>
+
+### Key expansion
+
+The hidden service and its client need to derive crypto keys from the
+NTOR_KEY_SEED part of the handshake output. To do so, they use the KDF
+construction as follows:
+
+K = KDF(NTOR_KEY_SEED | m_hsexpand, HASH_LEN *2 + S_KEY_LEN* 2)
+
+The first HASH_LEN bytes of K form the forward digest Df; the next HASH_LEN
+bytes form the backward digest Db; the next S_KEY_LEN bytes form Kf, and the
+final S_KEY_LEN bytes form Kb. Excess bytes from K are discarded.
+
+Subsequently, the rendezvous point passes RELAY cells, unchanged, from each
+of the two circuits to the other. When Alice's OP sends RELAY cells along
+the circuit, it authenticates with Df, and encrypts them with the Kf, then
+with all of the keys for the ORs in Alice's side of the circuit; and when
+Alice's OP receives RELAY cells from the circuit, it decrypts them with the
+keys for the ORs in Alice's side of the circuit, then decrypts them with Kb,
+and checks integrity with Db. Bob's OP does the same, with Kf and Kb
+interchanged.
+
+\[TODO: Should we encrypt HANDSHAKE_INFO as we did INTRODUCE2
+contents? It's not necessary, but it could be wise. Similarly, we
+should make it extensible.\]
+
+<a id="rend-spec-v3.txt-4.3"></a>
+
+## Using legacy hosts as rendezvous points {#legacy-rend-hosts}
+
+\[This section is obsolete and refers to a workaround for now-obsolete Tor
+relay versions. It is included for historical reasons.\]
+
+The behavior of ESTABLISH_RENDEZVOUS is unchanged from older versions
+of this protocol, except that relays should now ignore unexpected
+bytes at the end.
+
+Old versions of Tor required that RENDEZVOUS message bodies be exactly
+168 bytes long. All shorter rendezvous bodies should be padded to
+this length with random bytes, to make them difficult to distinguish from
+older protocols at the rendezvous point.
+
+Relays older than 0.2.9.1 should not be used for rendezvous points by next
+generation onion services because they enforce too-strict length checks to
+RENDEZVOUS messages. Hence the "HSRend" protocol from proposal#264 should be
+used to select relays for rendezvous points.