aboutsummaryrefslogtreecommitdiff
path: root/spec/tor-spec/creating-circuits.md
blob: deb6b836ee20e9b647dad24457606a22c13744d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<a id="tor-spec.txt-5.3"></a>

# Creating circuits{#creating-circuits}

When creating a circuit through the network, the circuit creator
(OP) performs the following steps:

1. Choose an onion router as an end node (R_N):
   * N MAY be 1 for non-anonymous directory mirror, introduction point,
     or service rendezvous connections.
   * N SHOULD be 3 or more for anonymous connections.
   Some end nodes accept streams (see ["Opening streams"](./opening-streams.md)),
   others are introduction or rendezvous points (see the [Rendezvous Spec](../rend-spec/index.md)).

2. Choose a chain of (N-1) onion routers (R_1...R_N-1) to constitute
   the path, such that no router appears in the path twice.

3. If not already connected to the first router in the chain,
   open a new connection to that router.

4. Choose a circID not already in use on the connection with the
   first router in the chain; send a CREATE/CREATE2 cell along
   the connection, to be received by the first onion router.

5. Wait until a CREATED/CREATED2 cell is received; finish the
   handshake and extract the forward key Kf_1 and the backward
   key Kb_1.

6. For each subsequent onion router R (R_2 through R_N), extend
   the circuit to R.

To extend the circuit by a single onion router R_M, the OP performs
these steps:

1. Create an onion skin, encrypted to R_M's public onion key.

2. Send the onion skin in a relay EXTEND/EXTEND2 message along
   the circuit (see
   ["EXTEND and EXTENDED messages"](./create-created-cells.md#EXTEND)
   and ["Routing relay cells"](./routing-relay-cells.md#routing-relay-cells)).

3. When a relay EXTENDED/EXTENDED2 message is received, verify KH,
   and calculate the shared keys.  The circuit is now extended.

When an onion router receives an EXTEND relay message, it sends a CREATE
cell to the next onion router, with the enclosed onion skin as its
body.

When an onion router receives an EXTEND2 relay message, it sends a CREATE2
cell to the next onion router, with the enclosed HLEN, HTYPE, and HDATA
as its body. The initiating onion router chooses some circID not yet
used on the connection between the two onion routers. (But see section
["Choosing circuit IDs in create  cells"](./create-created-cells.md#choosing-circid))

As special cases, if the EXTEND/EXTEND2 message includes a legacy identity, or
identity fingerprint of all zeroes, or asks to extend back to the relay
that sent the extend cell, the circuit will fail and be torn down.

Ed25519 identity keys are not required in EXTEND2 messages, so all zero
keys SHOULD be accepted. If the extending relay knows the ed25519 key from
the consensus, it SHOULD also check that key. (See
[EXTEND and EXTENDED message](./create-created-cells.md#EXTEND))

If an EXTEND2 message contains the ed25519 key of the relay that sent the
EXTEND2 message, the circuit will fail and be torn down.

When an onion router receives a CREATE/CREATE2 cell, if it already has a
circuit on the given connection with the given circID, it drops the
cell. Otherwise, after receiving the CREATE/CREATE2 cell, it completes
the specified handshake, and replies with a CREATED/CREATED2 cell.

Upon receiving a CREATED/CREATED2 cell, an onion router packs its body
into an [EXTENDED/EXTENDED2](./create-created-cells.md#EXTEND) relay message, and sends
that message up the circuit. Upon receiving the EXTENDED/EXTENDED2 relay
message, the OP can retrieve the handshake material.

(As an optimization, OR implementations may delay processing onions
until a break in traffic allows time to do so without harming
network latency too greatly.)

<a id="tor-spec.txt-5.3.1"></a>

## Canonical connections{#canonical-connections}

It is possible for an attacker to launch a man-in-the-middle attack
against a connection by telling OR Alice to extend to OR Bob at some
address X controlled by the attacker.  The attacker cannot read the
encrypted traffic, but the attacker is now in a position to count all
bytes sent between Alice and Bob (assuming Alice was not already
connected to Bob.)

To prevent this, when an OR gets an extend request, it SHOULD use an
existing OR connection if the ID matches, and ANY of the following
conditions hold:

 - The IP matches the requested IP.
 - The OR knows that the IP of the connection it's using is canonical
   because it was listed in the NETINFO cell.

ORs SHOULD NOT check the IPs that are listed in the server descriptor.
Trusting server IPs makes it easier to covertly impersonate a relay, after
stealing its keys.