hs-overview.md
1 # How do onion services work? 2 3 Here's an interaction diagram, since I hear you like those. (It's in something 4 called "mermaid", but apparently gitlab can render that, and so can rustdoc 5 (with the appropriate plugin).) 6 7 8 ```mermaid 9 sequenceDiagram 10 autonumber 11 participant Service 12 participant IntroPt 13 participant HsDir 14 participant RendPt 15 participant Client 16 note over IntroPt: Chosen randomly by Service 17 Service-->>IntroPt: EstablishIntro: Sign(IntroIdKey, CircBinding) 18 IntroPt-->>Service: IntroEstablished. 19 note over HsDir: At position chosen by hash ring 20 Service-->>HsDir: HTTP POST blinded_id Descriptor(Sign(BlindId, Seq, Enc(IntroPt, IntroIdKey, IntroEncKey))) 21 HsDir-->>Service: 200 OK 22 note over Client: Client decides to connect to `id.onion` 23 note over RendPt: Chosen randomly by Client 24 par 25 Client-->>RendPt: EstablishRendezvous(RendCookie) 26 RendPt-->>Client: RendezvousEstablished 27 and 28 Client-->>HsDir: HTTP GET BlindId 29 HsDir-->>Client: 200 OK Descriptor(...) 30 end 31 Client-->>IntroPt: Introduce1(IntroIdKey, Enc(RendPt, RendCookie, NtorHandshake1])) 32 IntroPt-->>Client: IntroduceAck 33 IntroPt-->>Service: Introduce2(IntroIdKey, [...]) 34 Service-->>RendPt: Rendezvous1([RendCookie, NtorHandshake2]) 35 RendPt-->>Client: Rendezvous2(NtorHandshake2) 36 ``` 37 38 Note 1: All communications are done over anonymous Tor circuits. 39 40 Note 2: In reality, each onion service establishes multiple introduction points 41 at a time, and uploads its descriptor to multiple HsDirs. The diagram above is 42 simplified. 43 44 Note 3: The actual data formats are slightly simplified here; in reality, there 45 is typically room for extensions, more kinds of keys, and so on. 46 47 48 49 Before we begin: 50 51 * The onion service has made an ed25519 "identity key" that is encoded in its 52 address as `id.onion`. 53 * It has computed, for the current time period, a "blinded identity key" that 54 can be derived through a one-way process from the original ID key and the 55 current time period. 56 * It has made, for the current time period, a "descriptor signing key" that is 57 authenticated via a certificate issued by the blinded identity key. 58 59 60 Now we get to the communications steps in the diagram: 61 62 1. The onion service wants to advertise itself. It chooses a random 63 introduction point on the network. For this introduction point, it creates a 64 random ed25519 "introduction id key" (to identify it with this introduction 65 point), and a random curve25519 "introduction encryption key" (for clients to 66 use when talking to it via this introduction point). 67 68 The onion service tells the introduction point to make a given circuit an 69 introduction circuit for the given "introduction id key". It authenticates 70 this method with the introduction ID key itself. To prevent replays, the 71 message also includes a "circuit binding" token derived from when the circuit 72 was constructed. 73 74 2. The introduction point replies to report success. 75 76 Note that the introduction point knows only the introduction id key for its 77 associated circuit; it does not know any other keys. 78 79 3. The onion service generates a descriptor and uploads it to a HsDir. The 80 HsDir is determined by a position on the hash ring derived from the blinded key identity, the current time period, and the current shared random value. 81 82 The descriptor is signed by the descriptor signing key. It contains: 83 * The blinded identity key. 84 * The certificate signed by the blinded identity key, certifying 85 the descriptor signing key. 86 * A sequence number to prevent rollbacks 87 * A section encrypted with a symmetric key derived from the service's true identity, containing: 88 * A list of introduction points and their associated keys. 89 90 91 4. The HsDir verifies that the certificate and descriptor are well-signed, and 92 that the correctly proves ownership of the descriptor using the blinded 93 identity key. It verifies that it does not have any other descriptor for the 94 same blinded identity key with a higher sequence number. Finally, the HsDir 95 stores the descriptor indexed at the blinded id, replying with 200 OK. 96 97 Note that the HSDir has learned only the blinded id for the service. Unless 98 it knows the true identity from some other mechanism, it cannot determine the 99 introduction points or their associated keys. 100 101 At this point the onion service is running; it keeps its circuit open to the 102 introduction point and waits to hear more. 103 104 Now a client comes along. It is told to connect to `id.onion`, and computes the 105 blinded id key (and the corresponding location on the hash ring) using the same 106 logic as the service. 107 108 5. If the client does not already have one ready, it opens a circuit to a 109 randomly chosen rendezvous point, and tells it to wait for another party 110 presenting the same rendezvous cookie. 111 112 6. The rendezvous point replies with "rendezvous established." 113 114 7. In parallel with steps 5 and 6 if needed, the client connects to the HsDir and 115 fetches the descriptor, indexed by the blinded ID. 116 117 8. The HsDir replies with the latest descriptor for the given service. 118 119 The client validates the descriptor, decrypts the signed portion of the 120 descriptor, and learns the service's current introduction points and keys. 121 122 9. The client contacts the introduction point, and sends it an Introduce1 message. 123 The outer portion of the cell just says which onion service (by introduction 124 id key) should receive the inner portion; the inner portion is encrypted 125 using the introduction encryption key (which the introduction point does not 126 know). 127 128 The encrypted inner portion contains: 129 * the rendezvous cookie 130 * information about the rendezvous point 131 * the start of a cryptographic handshake with the service. 132 133 10. The introduction point acknowledges the client. 134 135 11. The introduction point delivers the inner portion of the Introduce1 message 136 to the service, on the circuit that was established in step 1. 137 138 12. The service decrypts and validates the material from the client, to learn 139 the rendezvous point and the rendezvous cookie. (It also computes the 140 second part of the cryptographic handshake, along with a set of associated 141 key material.) 142 143 The service checks for replays. It needs to maintain a separate replay cache for 144 each introduction id key. 145 146 The service builds a circuit to the rendezvous point and presents the 147 rendezvous cookie, along with its half of the handshake. 148 149 13. If the cookie matches n a circuit that the rendezvous point knows about, 150 it relays the service's handshake back to the client, over the circuit that the 151 client established in step 5. 152 153 The rendezvous point also now joins the client's circuit from step 5 and 154 the service's circuit from step 12, so that future messages will be relayed 155 between them. 156 157 Now, at last, the client has received the service's handshake over the expected 158 circuit. The client completes the handshake, to get a set of shared encryption 159 keys with the service. Now the client and service have a pair of joined 160 circuits, and a set of encryption material to use to communicate. 161 162 163 ## Well hang on, what about authentication? 164 165 There are two places where authentication can be added to the protocol above. 166 167 The first instance is when encrypting the descriptor: The service can encrypt 168 the list of introduction points in the descriptor so that only a client holding 169 one of several curve25519 keys can decrypt it. This requires storage space 170 proportional to the number of supported clients, so the upper limit is bounded. 171 172 The second instance is when receiving the introduce2 request: The client can 173 include a random value in the introduce2 message, signed with an ed25519 signing 174 key, to prove its identity. 175 176 > Aside: It would be a good thing to have a better authentication method that 177 > signs more of the introduce2 request (like the rendezvous cookie, the intro 178 > point public key, the X value from the ntor handshake, etc) in order to make 179 > replays less feasible. 180