aboutsummaryrefslogtreecommitdiff
path: root/spec/rend-spec/protocol-overview.md
blob: 9f7c96ff28e1f63ab1caf34ae0cd2873b325349f (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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
<a id="rend-spec-v3.txt-1"></a>

# Protocol overview

In this section, we outline the hidden service protocol. This section
omits some details in the name of simplicity; those are given more
fully below, when we specify the protocol in more detail.

<a id="rend-spec-v3.txt-1.1"></a>

## View from 10,000 feet {#10000-feet}

A hidden service host prepares to offer a hidden service by choosing
several Tor nodes to serve as its introduction points. It builds
circuits to those nodes, and tells them to forward introduction
requests to it using those circuits.

Once introduction points have been picked, the host builds a set of
documents called "hidden service descriptors" (or just "descriptors"
for short) and uploads them to a set of HSDir nodes. These documents
list the hidden service's current introduction points and describe
how to make contact with the hidden service.

When a client wants to connect to a hidden service, it first chooses
a Tor node at random to be its "rendezvous point" and builds a
circuit to that rendezvous point. If the client does not have an
up-to-date descriptor for the service, it contacts an appropriate
HSDir and requests such a descriptor.

The client then builds an anonymous circuit to one of the hidden
service's introduction points listed in its descriptor, and gives the
introduction point an introduction request to pass to the hidden
service. This introduction request includes the target rendezvous
point and the first part of a cryptographic handshake.

Upon receiving the introduction request, the hidden service host
makes an anonymous circuit to the rendezvous point and completes the
cryptographic handshake. The rendezvous point connects the two
circuits, and the cryptographic handshake gives the two parties a
shared key and proves to the client that it is indeed talking to the
hidden service.

Once the two circuits are joined, the client can use Tor relay cells
to deliver relay messages to the server:
Whenever the rendezvous point receives as relay cell from one of
the circuits, it transmits it to the other.
(It accepts both RELAY and RELAY_EARLY cells,
and retransmits them all as RELAY cells.)

The two parties use these relay messages to implement Tor's
usual application stream protocol:
RELAY_BEGIN messages open streams to an external process
or processes configured by the server; RELAY_DATA messages are used to
communicate data on those streams, and so forth.

<a id="rend-spec-v3.txt-1.2"></a>

## In more detail: naming hidden services {#NAMING}

A hidden service's name is its long term master identity key.  This is
encoded as a hostname by encoding the entire key in Base 32, including a
version byte and a checksum, and then appending the string ".onion" at the
end. The result is a 56-character domain name.

(This is a change from older versions of the hidden service protocol,
where we used an 80-bit truncated SHA1 hash of a 1024 bit RSA key.)

The names in this format are distinct from earlier names because of
their length. An older name might look like:

```text
        unlikelynamefora.onion
        yyhws9optuwiwsns.onion

   And a new name following this specification might look like:

        l5satjgud6gucryazcyvyvhuxhr74u6ygigiuyixe3a6ysis67ororad.onion

   Please see section [ONIONADDRESS] for the encoding specification.
```

<a id="rend-spec-v3.txt-1.3"></a>

## In more detail: Access control {#IMD:AC}

Access control for a hidden service is imposed at multiple points through
the process above. Furthermore, there is also the option to impose
additional client authorization access control using pre-shared secrets
exchanged out-of-band between the hidden service and its clients.

The first stage of access control happens when downloading HS descriptors.
Specifically, in order to download a descriptor, clients must know which
blinded signing key was used to sign it. (See the next section for more info
on key blinding.)

To learn the introduction points, clients must decrypt the body of the
hidden service descriptor. To do so, clients must know the _unblinded_
public key of the service, which makes the descriptor unusable by entities
without that knowledge (e.g. HSDirs that don't know the onion address).

Also, if optional client authorization is enabled, hidden service
descriptors are superencrypted using each authorized user's identity x25519
key, to further ensure that unauthorized entities cannot decrypt it.

In order to make the introduction point send a rendezvous request to the
service, the client needs to use the per-introduction-point authentication
key found in the hidden service descriptor.

The final level of access control happens at the server itself, which may
decide to respond or not respond to the client's request depending on the
contents of the request. The protocol is extensible at this point: at a
minimum, the server requires that the client demonstrate knowledge of the
contents of the encrypted portion of the hidden service descriptor. If
optional client authorization is enabled, the service may additionally
require the client to prove knowledge of a pre-shared private key.

<a id="rend-spec-v3.txt-1.4"></a>

## In more detail: Distributing hidden service descriptors. {#IMD:DIST}

Periodically, hidden service descriptors become stored at different
locations to prevent a single directory or small set of directories
from becoming a good DoS target for removing a hidden service.

For each period, the Tor directory authorities agree upon a
collaboratively generated random value. (See section 2.3 for a
description of how to incorporate this value into the voting
practice; generating the value is described in other proposals,
including \[SHAREDRANDOM-REFS\].) That value, combined with hidden service
directories' public identity keys, determines each HSDir's position
in the hash ring for descriptors made in that period.

Each hidden service's descriptors are placed into the ring in
positions based on the key that was used to sign them. Note that
hidden service descriptors are not signed with the services' public
keys directly. Instead, we use a key-blinding system \[KEYBLIND\] to
create a new key-of-the-day for each hidden service. Any client that
knows the hidden service's public identity key can derive these blinded
signing keys for a given period. It should be impossible to derive
the blinded signing key lacking that knowledge.

This is achieved using two nonces:

```text
    * A "credential", derived from the public identity key KP_hs_id.
      N_hs_cred.

    * A "subcredential", derived from the credential N_hs_cred
      and information which various with the current time period.
      N_hs_subcred.
```

The body of each descriptor is also encrypted with a key derived from
the public signing key.

To avoid a "thundering herd" problem where every service generates
and uploads a new descriptor at the start of each period, each
descriptor comes online at a time during the period that depends on
its blinded signing key. The keys for the last period remain valid
until the new keys come online.

<a id="rend-spec-v3.txt-1.5"></a>

## In more detail: Scaling to multiple hosts {#imd-scaling}

This design is compatible with our current approaches for scaling hidden
services. Specifically, hidden service operators can use onionbalance to
achieve high availability between multiple nodes on the HSDir
layer. Furthermore, operators can use proposal 255 to load balance their
hidden services on the introduction layer. See \[SCALING-REFS\] for further
discussions on this topic and alternative designs.

```text
1.6. In more detail: Backward compatibility with older hidden service
      protocols
```

This design is incompatible with the clients, server, and hsdir node
protocols from older versions of the hidden service protocol as
described in rend-spec.txt. On the other hand, it is designed to
enable the use of older Tor nodes as rendezvous points and
introduction points.

<a id="rend-spec-v3.txt-1.7"></a>

## In more detail: Keeping crypto keys offline {#imd-offline-keys}

In this design, a hidden service's secret identity key may be
stored offline.  It's used only to generate blinded signing keys,
which are used to sign descriptor signing keys.

In order to operate a hidden service, the operator can generate in
advance a number of blinded signing keys and descriptor signing
keys (and their credentials; see \[DESC-OUTER\] and \[HS-DESC-ENC\]
below), and their corresponding descriptor encryption keys, and
export those to the hidden service hosts.

As a result, in the scenario where the Hidden Service gets
compromised, the adversary can only impersonate it for a limited
period of time (depending on how many signing keys were generated
in advance).

It's important to not send the private part of the blinded signing
key to the Hidden Service since an attacker can derive from it the
secret master identity key. The secret blinded signing key should
only be used to create credentials for the descriptor signing keys.

(NOTE: although the protocol allows them, offline keys are not
implemented as of 0.3.2.1-alpha.)

<a id="rend-spec-v3.txt-1.8"></a>

## In more detail: Encryption Keys And Replay Resistance {#imd-encryption-keys}

To avoid replays of an introduction request by an introduction point,
a hidden service host must never accept the same request
twice. Earlier versions of the hidden service design used an
authenticated timestamp here, but including a view of the current
time can create a problematic fingerprint. (See proposal 222 for more
discussion.)

<a id="rend-spec-v3.txt-1.9"></a>

## In more detail: A menagerie of keys {#imd-key-menagerie}

\[In the text below, an "encryption keypair" is roughly "a keypair you
can do Diffie-Hellman with" and a "signing keypair" is roughly "a
keypair you can do ECDSA with."\]

Public/private keypairs defined in this document:

<a id="hs_id"></a>
```text
      Master (hidden service) identity key -- A master signing keypair
        used as the identity for a hidden service.  This key is long
        term and not used on its own to sign anything; it is only used
        to generate blinded signing keys as described in [KEYBLIND]
        and [SUBCRED]. The public key is encoded in the ".onion"
        address according to [NAMING].
        KP_hs_id, KS_hs_id.
```

<a id="hs_blind_id"></a>
```text
      Blinded signing key -- A keypair derived from the identity key,
        used to sign descriptor signing keys. It changes periodically for
        each service. Clients who know a 'credential' consisting of the
        service's public identity key and an optional secret can derive
        the public blinded identity key for a service.  This key is used
        as an index in the DHT-like structure of the directory system
        (see [SUBCRED]).
        KP_hs_blind_id, KS_hs_blind_id.

```

<a id="hs_desc_sign"></a>
```text
      Descriptor signing key -- A key used to sign hidden service
        descriptors.  This is signed by blinded signing keys. Unlike
        blinded signing keys and master identity keys, the secret part
        of this key must be stored online by hidden service hosts. The
        public part of this key is included in the unencrypted section
        of HS descriptors (see [DESC-OUTER]).
        KP_hs_desc_sign, KS_hs_desc_sign.
```

<a id="hs_ipt_sid"></a>
```text
      Introduction point authentication key -- A short-term signing
        keypair used to identify a hidden service's session at a given
        introduction point. The service makes a fresh keypair for each
        introduction point; these are used to sign the request that a
        hidden service host makes when establishing an introduction
        point, so that clients who know the public component of this key
        can get their introduction requests sent to the right
        service. No keypair is ever used with more than one introduction
        point. (previously called a "service key" in rend-spec.txt)
        KP_hs_ipt_sid, KS_hs_ipt_sid
        ("hidden service introduction point session id").
```

<a id="hss_ntor"></a>
```text
      Introduction point encryption key -- A short-term encryption
        keypair used when establishing connections via an introduction
        point. Plays a role analogous to Tor nodes' onion keys. The service
        makes a fresh keypair for each introduction point.
        KP_hss_ntor, KS_hss_ntor.
```

<a id="hss_desc_enc"></a>
```text
      Ephemeral descriptor encryption key -- A short-lived encryption
        keypair made by the service, and used to encrypt the inner layer
        of hidden service descriptors when client authentication is in
        use.
        KP_hss_desc_enc, KS_hss_desc_enc
```

```text
   Nonces defined in this document:

      N_hs_desc_enc -- a nonce used to derive keys to decrypt the inner
        encryption layer of hidden service descriptors.  This is
        sometimes also called a "descriptor cookie".

   Public/private keypairs defined elsewhere:

      Onion key -- Short-term encryption keypair (KS_ntor, KP_ntor).

      (Node) identity key (KP_relayid).

   Symmetric key-like things defined elsewhere:

      KH from circuit handshake -- An unpredictable value derived as
      part of the Tor circuit extension handshake, used to tie a request
      to a particular circuit.
```

<a id="rend-spec-v3.txt-1.9.1"></a>

### In even more detail: Client authorization keys {#CLIENT-AUTH}

When client authorization is enabled, each authorized client of a hidden
service has two more asymmetric keypairs which are shared with the hidden
service. An entity without those keys is not able to use the hidden
service. Throughout this document, we assume that these pre-shared keys are
exchanged between the hidden service and its clients in a secure out-of-band
fashion.

Specifically, each authorized client possesses:

```text
   - An x25519 keypair used to compute decryption keys that allow the client to
     decrypt the hidden service descriptor. See [HS-DESC-ENC].  This is
     the client's counterpart to KP_hss_desc_enc.
     KP_hsc_desc_enc, KS_hsd_desc_enc.

   - An ed25519 keypair which allows the client to compute signatures which
     prove to the hidden service that the client is authorized. These
     signatures are inserted into the INTRODUCE1 message, and without them the
     introduction to the hidden service cannot be completed. See [INTRO-AUTH].
     KP_hsc_intro_auth, KS_hsc_intro_auth.
```

The right way to exchange these keys is to have the client generate keys and
send the corresponding public keys to the hidden service out-of-band. An
easier but less secure way of doing this exchange would be to have the
hidden service generate the keypairs and pass the corresponding private keys
to its clients. See section \[CLIENT-AUTH-MGMT\] for more details on how these
keys should be managed.

\[TODO: Also specify stealth client authorization.\]

(NOTE: client authorization is implemented as of 0.3.5.1-alpha.)