From 2437d19ccf52e299b74d879dadafa3d58f580467 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 5 May 2022 11:44:26 -0400 Subject: attic: Move onion service v2 spec to attic Deprecated. Not supported by the network anymore. Signed-off-by: David Goulet --- attic/rend-spec-v2.txt | 1087 ++++++++++++++++++++++++++++++++++++++++++++++++ rend-spec-v2.txt | 1087 ------------------------------------------------ 2 files changed, 1087 insertions(+), 1087 deletions(-) create mode 100644 attic/rend-spec-v2.txt delete mode 100644 rend-spec-v2.txt diff --git a/attic/rend-spec-v2.txt b/attic/rend-spec-v2.txt new file mode 100644 index 0000000..0306f4b --- /dev/null +++ b/attic/rend-spec-v2.txt @@ -0,0 +1,1087 @@ + + Tor Rendezvous Specification + +0. Overview and preliminaries + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL + NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and + "OPTIONAL" in this document are to be interpreted as described in + RFC 2119. + + Read + https://svn.torproject.org/svn/projects/design-paper/tor-design.html#sec:rendezvous + before you read this specification. It will make more sense. + + Rendezvous points provide location-hidden services (server + anonymity) for the onion routing network. With rendezvous points, + Bob can offer a TCP service (say, a webserver) via the onion + routing network, without revealing the IP of that service. + + Bob does this by anonymously advertising a public key for his + service, along with a list of onion routers to act as "Introduction + Points" for his service. He creates forward circuits to those + introduction points, and tells them about his service. To + connect to Bob, Alice first builds a circuit to an OR to act as + her "Rendezvous Point." She then connects to one of Bob's chosen + introduction points, and asks it to tell him about her Rendezvous + Point (RP). If Bob chooses to answer, he builds a circuit to her + RP, and tells it to connect him to Alice. The RP joins their + circuits together, and begins relaying cells. Alice's 'BEGIN' + cells are received directly by Bob's OP, which passes data to + and from the local server implementing Bob's service. + + Below we describe a network-level specification of this service, + along with interfaces to make this process transparent to Alice + (so long as she is using an OP). + +0.1. Notation, conventions and prerequisites + + In the specifications below, we use the same notation and terminology + as in "tor-spec.txt". The service specified here also requires the + existence of an onion routing network as specified in that file. + + H(x) is a SHA1 digest of x. + PKSign(SK,x) is a PKCS.1-padded RSA signature of x with SK. + PKEncrypt(SK,x) is a PKCS.1-padded RSA encryption of x with SK. + Public keys are all RSA, and encoded in ASN.1. + All integers are stored in network (big-endian) order. + All symmetric encryption uses AES in counter mode, except where + otherwise noted. + + In all discussions, "Alice" will refer to a user connecting to a + location-hidden service, and "Bob" will refer to a user running a + location-hidden service. + + An OP is (as defined elsewhere) an "Onion Proxy" or Tor client. + + An OR is (as defined elsewhere) an "Onion Router" or Tor server. + + An "Introduction point" is a Tor server chosen to be Bob's medium-term + 'meeting place'. A "Rendezvous point" is a Tor server chosen by Alice to + be a short-term communication relay between her and Bob. All Tor servers + potentially act as introduction and rendezvous points. + +0.2. Protocol outline + + 1. Bob->Bob's OP: "Offer IP:Port as public-key-name:Port". [configuration] + (We do not specify this step; it is left to the implementor of + Bob's OP.) + + 2. Bob's OP generates a long-term keypair. + + 3. Bob's OP->Introduction point via Tor: [introduction setup] + "This public key is (currently) associated to me." + + 4. Bob's OP->directory service via Tor: publishes Bob's service descriptor + [advertisement] + "Meet public-key X at introduction point A, B, or C." (signed) + + 5. Out of band, Alice receives a z.onion:port address. + She opens a SOCKS connection to her OP, and requests z.onion:port. + + 6. Alice's OP retrieves Bob's descriptor via Tor. [descriptor lookup.] + + 7. Alice's OP chooses a rendezvous point, opens a circuit to that + rendezvous point, and establishes a rendezvous circuit. [rendezvous + setup.] + + 8. Alice connects to the Introduction point via Tor, and tells it about + her rendezvous point. (Encrypted to Bob.) [Introduction 1] + + 9. The Introduction point passes this on to Bob's OP via Tor, along the + introduction circuit. [Introduction 2] + + 10. Bob's OP decides whether to connect to Alice, and if so, creates a + circuit to Alice's RP via Tor. Establishes a shared circuit. + [Rendezvous 1] + + 11. The Rendezvous point forwards Bob's confirmation to Alice's OP. + [Rendezvous 2] + + 12. Alice's OP sends begin cells to Bob's OP. [Connection] + +0.3. Constants and new cell types + + Relay cell types + + 32 -- RELAY_COMMAND_ESTABLISH_INTRO + 33 -- RELAY_COMMAND_ESTABLISH_RENDEZVOUS + 34 -- RELAY_COMMAND_INTRODUCE1 + 35 -- RELAY_COMMAND_INTRODUCE2 + 36 -- RELAY_COMMAND_RENDEZVOUS1 + 37 -- RELAY_COMMAND_RENDEZVOUS2 + 38 -- RELAY_COMMAND_INTRO_ESTABLISHED + 39 -- RELAY_COMMAND_RENDEZVOUS_ESTABLISHED + 40 -- RELAY_COMMAND_INTRODUCE_ACK + +0.4. Version overview + + There are several parts in the hidden service protocol that have + changed over time, each of them having its own version number, whereas + other parts remained the same. The following list of potentially + versioned protocol parts should help reduce some confusion: + + - Hidden service descriptor: the binary-based v0 was the default for a + long time, and an ASCII-based v2 has been added by proposal 114. The + v0 descriptor format has been deprecated in 0.2.2.1-alpha. See 1.3. + + - Hidden service descriptor propagation mechanism: currently related to + the hidden service descriptor version -- v0 publishes to the original + hs directory authorities, whereas v2 publishes to a rotating subset + of relays with the "HSDir" flag; see 1.4 and 1.6. + + - Introduction protocol for how to generate an introduction cell: + v0 specified a nickname for the rendezvous point and assumed the + relay would know about it, whereas v2 now specifies IP address, + port, and onion key so the relay doesn't need to already recognize + it. See 1.8. + +1. The Protocol + +1.1. Bob configures his local OP. + + We do not specify a format for the OP configuration file. However, + OPs SHOULD allow Bob to provide more than one advertised service + per OP, and MUST allow Bob to specify one or more virtual ports per + service. Bob provides a mapping from each of these virtual ports + to a local IP:Port pair. + +1.2. Bob's OP establishes his introduction points. + + The first time the OP provides an advertised service, it generates + a public/private keypair (stored locally). + + The OP chooses a small number of Tor servers as introduction points. + The OP establishes a new introduction circuit to each introduction + point. These circuits MUST NOT be used for anything but hidden service + introduction. To establish the introduction, Bob sends a + RELAY_COMMAND_ESTABLISH_INTRO cell, containing: + + KL Key length [2 octets] + PK Bob's public key or service key [KL octets] + HS Hash of session info [20 octets] + SIG Signature of above information [variable] + + KL is the length of PK, in octets. + + To prevent replay attacks, the HS field contains a SHA-1 hash based on the + shared secret KH between Bob's OP and the introduction point, as + follows: + + HS = H(KH | "INTRODUCE") + + That is: + + HS = H(KH | [49 4E 54 52 4F 44 55 43 45]) + + (KH, as specified in tor-spec.txt, is H(g^xy | [00]) .) + + Upon receiving such a cell, the OR first checks that the signature is + correct with the included public key. If so, it checks whether HS is + correct given the shared state between Bob's OP and the OR. If either + check fails, the OP discards the cell; otherwise, it associates the + circuit with Bob's public key, and dissociates any other circuits + currently associated with PK. On success, the OR sends Bob a + RELAY_COMMAND_INTRO_ESTABLISHED cell with an empty payload. + + Bob's OP uses either Bob's public key or a freshly generated, single-use + service key in the RELAY_COMMAND_ESTABLISH_INTRO cell, depending on the + configured hidden service descriptor version. The public key is used for + v0 descriptors, the service key for v2 descriptors. In the latter case, the + service keys of all introduction points are included in the v2 hidden + service descriptor together with the other introduction point information. + The reason is that the introduction point does not need to and therefore + should not know for which hidden service it works, so as to prevent it from + tracking the hidden service's activity. If the hidden service is configured + to publish both v0 and v2 descriptors, two separate sets of introduction + points are established. + +1.3. Bob's OP generates service descriptors. + + For versions before 0.2.2.1-alpha, Bob's OP periodically generates and + publishes a descriptor of type "V0". + + The "V0" descriptor contains: + + KL Key length [2 octets] + PK Bob's public key [KL octets] + TS A timestamp [4 octets] + NI Number of introduction points [2 octets] + Ipt A list of NUL-terminated ORs [variable] + SIG Signature of above fields [variable] + + TS is the number of seconds elapsed since Jan 1, 1970. + + The members of Ipt may be either (a) nicknames, or (b) identity key + digests, encoded in hex, and prefixed with a '$'. Clients must + accept both forms. Services must only generate the second form. + Once 0.0.9.x is obsoleted, we can drop the first form. + + [It's ok for Bob to advertise 0 introduction points. He might want + to do that if he previously advertised some introduction points, + and now he doesn't have any. -RD] + + Beginning with 0.2.0.10-alpha, Bob's OP encodes "V2" descriptors in + addition to (or instead of) "V0" descriptors. The format of a "V2" + descriptor is as follows: + + "rendezvous-service-descriptor" SP descriptor-id NL + + [At start, exactly once] + [No extra arguments] + + Indicates the beginning of the descriptor. "descriptor-id" is a + periodically changing identifier of 160 bits formatted as 32 base32 + chars that is calculated by the hidden service and its clients. The + "descriptor-id" is calculated by performing the following operation: + + descriptor-id = + H(permanent-id | H(time-period | descriptor-cookie | replica)) + + "permanent-id" is the permanent identifier of the hidden service, + consisting of 80 bits. It can be calculated by computing the hash value + of the public hidden service key and truncating after the first 80 bits: + + permanent-id = H(public-key)[:10] + + Note: If Bob's OP has "stealth" authorization enabled (see Section 2.2), + it uses the client key in place of the public hidden service key. + + "H(time-period | descriptor-cookie | replica)" is the (possibly + secret) id part that is necessary to verify that the hidden service is + the true originator of this descriptor and that is therefore contained + in the descriptor, too. The descriptor ID can only be created by the + hidden service and its clients, but the "signature" below can only be + created by the service. + + "time-period" changes periodically as a function of time and + "permanent-id". The current value for "time-period" can be calculated + using the following formula: + + time-period = (current-time + permanent-id-byte * 86400 / 256) + / 86400 + + "current-time" contains the current system time in seconds since + 1970-01-01 00:00, e.g. 1188241957. "permanent-id-byte" is the first + (unsigned) byte of the permanent identifier (which is in network + order), e.g. 143. Adding the product of "permanent-id-byte" and + 86400 (seconds per day), divided by 256, prevents "time-period" from + changing for all descriptors at the same time of the day. The result + of the overall operation is a (network-ordered) 32-bit integer, e.g. + 13753 or 0x000035B9 with the example values given above. + + "descriptor-cookie" is an optional secret password of 128 bits that + is shared between the hidden service provider and its clients. If the + descriptor-cookie is left out, the input to the hash function is 128 + bits shorter. [No extra arguments] + + "replica" denotes the number of the replica. A service publishes + multiple descriptors with different descriptor IDs in order to + distribute them to different places on the ring. + + "version" SP version-number NL + + [Exactly once] + [No extra arguments] + + The version number of this descriptor's format. Version numbers are a + positive integer. + + "permanent-key" NL a public key in PEM format + + [Exactly once] + [No extra arguments] + + The public key of the hidden service which is required to verify the + "descriptor-id" and the "signature". + + "secret-id-part" SP secret-id-part NL + + [Exactly once] + [No extra arguments] + + The result of the following operation as explained above, formatted as + 32 base32 chars. Using this secret id part, everyone can verify that + the signed descriptor belongs to "descriptor-id". + + secret-id-part = H(time-period | descriptor-cookie | replica) + + "publication-time" SP YYYY-MM-DD HH:MM:SS NL + + [Exactly once] + + A timestamp when this descriptor has been created. It should be + rounded down to the nearest hour. + + "protocol-versions" SP version-string NL + + [Exactly once] + [No extra arguments] + + A comma-separated list of recognized and permitted version numbers + for use in INTRODUCE cells; these versions are described in section + 1.8 below. Version numbers are positive integers. + + "introduction-points" NL encrypted-string + + [At most once] + [No extra arguments] + + A list of introduction points. If the optional "descriptor-cookie" is + used, this list is encrypted with AES in CTR mode with a random + initialization vector of 128 bits that is written to + the beginning of the encrypted string, and the "descriptor-cookie" as + secret key of 128 bits length. + + The string containing the introduction point data (either encrypted + or not) is encoded in base64, and surrounded with + "-----BEGIN MESSAGE-----" and "-----END MESSAGE-----". + + A maximum of 10 introduction point entries may follow, each containing + the following data: + + "introduction-point" SP identifier NL + + [At start, exactly once] + [No extra arguments] + + The identifier of this introduction point: the base32 encoded + hash of this introduction point's identity key. + + "ip-address" SP ip4 NL + + [Exactly once] + [No extra arguments] + + The IP address of this introduction point. + + "onion-port" SP port NL + + [Exactly once] + [No extra arguments] + + The TCP port on which the introduction point is listening for + incoming onion requests. + + "onion-key" NL a public key in PEM format + + [Exactly once] + [No extra arguments] + + The public key that can be used to encrypt messages to this + introduction point. + + "service-key" NL a public key in PEM format + + [Exactly once] + [No extra arguments] + + The public key that can be used to encrypt messages to the hidden + service. + + "intro-authentication" auth-type auth-data NL + + [Any number] + + The introduction-point-specific authentication data can be used + to perform client authentication. This data depends on the + selected introduction point as opposed to "service-authentication" + above. The format of auth-data (base64-encoded or PEM format) + depends on auth-type. See section 2 of this document for details + on auth mechanisms. + + (This ends the fields in the encrypted portion of the descriptor.) + + [It's ok for Bob to advertise 0 introduction points. He might want + to do that if he previously advertised some introduction points, + and now he doesn't have any. -RD] + + "signature" NL signature-string + + [At end, exactly once] + [No extra arguments] + + A signature of all fields above including '"signature" NL' with + the private key of the hidden service. + +1.3.1. Other descriptor formats we don't use. + + Support for the V0 descriptor format was dropped in 0.2.2.0-alpha-dev: + + KL Key length [2 octets] + PK Bob's public key [KL octets] + TS A timestamp [4 octets] + NI Number of introduction points [2 octets] + Ipt A list of NUL-terminated ORs [variable] + SIG Signature of above fields [variable] + + KL is the length of PK, in octets. + TS is the number of seconds elapsed since Jan 1, 1970. + + The members of Ipt may be either (a) nicknames, or (b) identity key + digests, encoded in hex, and prefixed with a '$'. + + The V1 descriptor format was understood and accepted from + 0.1.1.5-alpha-cvs to 0.2.0.6-alpha-dev, but no Tors generated it and + it was removed: + + V Format byte: set to 255 [1 octet] + V Version byte: set to 1 [1 octet] + KL Key length [2 octets] + PK Bob's public key [KL octets] + TS A timestamp [4 octets] + PROTO Protocol versions: bitmask [2 octets] + NI Number of introduction points [2 octets] + For each introduction point: (as in INTRODUCE2 cells) + IP Introduction point's address [4 octets] + PORT Introduction point's OR port [2 octets] + ID Introduction point identity ID [20 octets] + KLEN Length of onion key [2 octets] + KEY Introduction point onion key [KLEN octets] + SIG Signature of above fields [variable] + + A hypothetical "V1" descriptor, that has never been used but might + be useful for historical reasons, contains: + + V Format byte: set to 255 [1 octet] + V Version byte: set to 1 [1 octet] + KL Key length [2 octets] + PK Bob's public key [KL octets] + TS A timestamp [4 octets] + PROTO Rendezvous protocol versions: bitmask [2 octets] + NA Number of auth mechanisms accepted [1 octet] + For each auth mechanism: + AUTHT The auth type that is supported [2 octets] + AUTHL Length of auth data [1 octet] + AUTHD Auth data [variable] + NI Number of introduction points [2 octets] + For each introduction point: (as in INTRODUCE2 cells) + ATYPE An address type (typically 4) [1 octet] + ADDR Introduction point's IP address [4 or 16 octets] + PORT Introduction point's OR port [2 octets] + AUTHT The auth type that is supported [2 octets] + AUTHL Length of auth data [1 octet] + AUTHD Auth data [variable] + ID Introduction point identity ID [20 octets] + KLEN Length of onion key [2 octets] + KEY Introduction point onion key [KLEN octets] + SIG Signature of above fields [variable] + + AUTHT specifies which authentication/authorization mechanism is + required by the hidden service or the introduction point. AUTHD + is arbitrary data that can be associated with an auth approach. + Currently only AUTHT of [00 00] is supported, with an AUTHL of 0. + See section 2 of this document for details on auth mechanisms. + +1.4. Bob's OP advertises his service descriptor(s). + + Bob's OP advertises his service descriptor to a fixed set of v0 hidden + service directory servers and/or a changing subset of all v2 hidden service + directories. + + For versions before 0.2.2.1-alpha, Bob's OP opens a stream to each v0 + directory server's directory port via Tor. (He may re-use old circuits for + this.) Over this stream, Bob's OP makes an HTTP 'POST' request, to a URL + "/tor/rendezvous/publish" relative to the directory server's root, + containing as its body Bob's service descriptor. + + Upon receiving a descriptor, the directory server checks the signature, + and discards the descriptor if the signature does not match the enclosed + public key. Next, the directory server checks the timestamp. If the + timestamp is more than 24 hours in the past or more than 1 hour in the + future, or the directory server already has a newer descriptor with the + same public key, the server discards the descriptor. Otherwise, the + server discards any older descriptors with the same public key and + version format, and associates the new descriptor with the public key. + The directory server remembers this descriptor for at least 24 hours + after its timestamp. At least every 18 hours, Bob's OP uploads a + fresh descriptor. + + If Bob's OP is configured to publish v2 descriptors, it does so to a + changing subset of all v2 hidden service directories instead of the + authoritative directory servers. Therefore, Bob's OP opens a stream via + Tor to each responsible hidden service directory. (He may re-use old + circuits for this.) Over this stream, Bob's OP makes an HTTP 'POST' + request to a URL "/tor/rendezvous2/publish" relative to the hidden service + directory's root, containing as its body Bob's service descriptor. + + [XXX022 Reusing old circuits for HS dir posts is very bad. Do we really + do that? --RR] + + At any time, there are 6 hidden service directories responsible for + keeping replicas of a descriptor; they consist of 2 sets of 3 hidden + service directories with consecutive onion IDs. Bob's OP learns about + the complete list of hidden service directories by filtering the + consensus status document received from the directory authorities. A + hidden service directory is deemed responsible for a descriptor ID if + it has the HSDir flag and its identity digest is one of the first three + identity digests of HSDir relays following the descriptor ID in a + circular list. A hidden service directory will only accept a descriptor + whose timestamp is no more than three days before or one day after the + current time according to the directory's clock. + + Bob's OP publishes a new v2 descriptor once an hour or whenever its + content changes. V2 descriptors can be found by clients within a given + time period of 24 hours, after which they change their ID as described + under 1.3. If a published descriptor would be valid for less than 60 + minutes (= 2 x 30 minutes to allow the server to be 30 minutes behind + and the client 30 minutes ahead), Bob's OP publishes the descriptor + under the ID of both, the current and the next publication period. + +1.5. Alice receives a z.onion address. + + When Alice receives a pointer to a location-hidden service, it is as a + hostname of the form "z.onion", where z is a base32 encoding of a + 10-octet hash of Bob's service's public key, computed as follows: + + 1. Let H = H(PK). + 2. Let H' = the first 80 bits of H, considering each octet from + most significant bit to least significant bit. + 3. Generate a 16-character encoding of H', using base32 as defined + in RFC 4648. + + (We only use 80 bits instead of the 160 bits from SHA1 because we + don't need to worry about arbitrary collisions, and because it will + make handling the url's more convenient.) + + [Yes, numbers are allowed at the beginning. See RFC 1123. -NM] + +1.6. Alice's OP retrieves a service descriptor. + + Alice's OP fetches the service descriptor from the fixed set of v0 hidden + service directory servers and/or a changing subset of all v2 hidden service + directories. + + For versions before 0.2.2.1-alpha, Alice's OP opens a stream to a directory + server via Tor, and makes an HTTP GET request for the document + '/tor/rendezvous/', where '' is replaced with the encoding of Bob's + public key as described above. (She may re-use old circuits for this.) The + directory replies with a 404 HTTP response if it does not recognize , + and otherwise returns Bob's most recently uploaded service descriptor. + + If Alice's OP receives a 404 response, it tries the other directory + servers, and only fails the lookup if none recognize the public key hash. + + Upon receiving a service descriptor, Alice verifies with the same process + as the directory server uses, described above in section 1.4. + + The directory server gives a 400 response if it cannot understand Alice's + request. + + Alice should cache the descriptor locally, but should not use + descriptors that are more than 24 hours older than their timestamp. + [Caching may make her partitionable, but she fetched it anonymously, + and we can't very well *not* cache it. -RD] + + If Alice's OP is running 0.2.1.10-alpha or higher, it fetches v2 hidden + service descriptors. Versions before 0.2.2.1-alpha are fetching both v0 and + v2 descriptors in parallel. Similar to the description in section 1.4, + Alice's OP fetches a v2 descriptor from a randomly chosen hidden service + directory out of the changing subset of 6 nodes. If the request is + unsuccessful, Alice retries the other remaining responsible hidden service + directories in a random order. Alice relies on Bob to care about a potential + clock skew between the two by possibly storing two sets of descriptors (see + end of section 1.4). + + Alice's OP opens a stream via Tor to the chosen v2 hidden service + directory. (She may re-use old circuits for this.) Over this stream, + Alice's OP makes an HTTP 'GET' request for the document + "/tor/rendezvous2/", where z is replaced with the encoding of the + descriptor ID. The directory replies with a 404 HTTP response if it does + not recognize , and otherwise returns Bob's most recently uploaded + service descriptor. + +1.7. Alice's OP establishes a rendezvous point. + + When Alice requests a connection to a given location-hidden service, + and Alice's OP does not have an established circuit to that service, + the OP builds a rendezvous circuit. It does this by establishing + a circuit to a randomly chosen OR, and sending a + RELAY_COMMAND_ESTABLISH_RENDEZVOUS cell to that OR. The body of that cell + contains: + + RC Rendezvous cookie [20 octets] + + The rendezvous cookie is an arbitrary 20-byte value, chosen randomly by + Alice's OP. Alice SHOULD choose a new rendezvous cookie for each new + connection attempt. + + Upon receiving a RELAY_COMMAND_ESTABLISH_RENDEZVOUS cell, the OR associates + the RC with the circuit that sent it. It replies to Alice with an empty + RELAY_COMMAND_RENDEZVOUS_ESTABLISHED cell to indicate success. + + Alice's OP MUST NOT use the circuit which sent the cell for any purpose + other than rendezvous with the given location-hidden service. + +1.8. Introduction: from Alice's OP to Introduction Point + + Alice builds a separate circuit to one of Bob's chosen introduction + points, and sends it a RELAY_COMMAND_INTRODUCE1 cell containing: + + Cleartext + PK_ID Identifier for Bob's PK [20 octets] + Encrypted to Bob's PK: (in the v0 intro protocol) + RP Rendezvous point's nickname [20 octets] + RC Rendezvous cookie [20 octets] + g^x Diffie-Hellman data, part 1 [128 octets] + OR (in the v1 intro protocol) + VER Version byte: set to 1. [1 octet] + RP Rendezvous point nick or ID [42 octets] + RC Rendezvous cookie [20 octets] + g^x Diffie-Hellman data, part 1 [128 octets] + OR (in the v2 intro protocol) + VER Version byte: set to 2. [1 octet] + IP Rendezvous point's address [4 octets] + PORT Rendezvous point's OR port [2 octets] + ID Rendezvous point identity ID [20 octets] + KLEN Length of onion key [2 octets] + KEY Rendezvous point onion key [KLEN octets] + RC Rendezvous cookie [20 octets] + g^x Diffie-Hellman data, part 1 [128 octets] + OR (in the v3 intro protocol) + VER Version byte: set to 3. [1 octet] + AUTHT The auth type that is used [1 octet] + If AUTHT != [00]: + AUTHL Length of auth data [2 octets] + AUTHD Auth data [variable] + TS A timestamp [4 octets] + IP Rendezvous point's address [4 octets] + PORT Rendezvous point's OR port [2 octets] + ID Rendezvous point identity ID [20 octets] + KLEN Length of onion key [2 octets] + KEY Rendezvous point onion key [KLEN octets] + RC Rendezvous cookie [20 octets] + g^x Diffie-Hellman data, part 1 [128 octets] + + PK_ID is the hash of Bob's public key or the service key, depending on the + hidden service descriptor version. In case of a v0 descriptor, Alice's OP + uses Bob's public key. If Alice has downloaded a v2 descriptor, she uses + the contained public key ("service-key"). + + RP is NUL-padded and terminated. In version 0 of the intro protocol, RP + must contain a nickname. In version 1, it must contain EITHER a nickname or + an identity key digest that is encoded in hex and prefixed with a '$'. + + The hybrid encryption to Bob's PK works just like the hybrid + encryption in CREATE cells (see tor-spec, section 0.4). Thus the + payload of the version 0 RELAY_COMMAND_INTRODUCE1 cell on the + wire will contain 20+42+16+20+20+128=246 bytes, and the version 1 + and version 2 introduction formats have other sizes. + + Through Tor 0.2.0.6-alpha, clients only generated the v0 introduction + format, whereas hidden services have understood and accepted v0, + v1, and v2 since 0.1.1.x. As of Tor 0.2.0.7-alpha and 0.1.2.18, + clients switched to using the v2 intro format. + + The Timestamp (TS) field is no longer used in Tor 0.2.3.9-alpha and + later. Clients MAY refrain from sending it; see the + "Support022HiddenServices" parameter in dir-spec.txt. Clients SHOULD + NOT send a precise timestamp, and should instead round to the nearest + 10 minutes. + +1.9. Introduction: From the Introduction Point to Bob's OP + + If the Introduction Point recognizes PK_ID as a public key which has + established a circuit for introductions as in 1.2 above, it sends the body + of the cell in a new RELAY_COMMAND_INTRODUCE2 cell down the corresponding + circuit. (If the PK_ID is unrecognized, the RELAY_COMMAND_INTRODUCE1 cell is + discarded.) + + After sending the RELAY_COMMAND_INTRODUCE2 cell to Bob, the OR replies to + Alice with an empty RELAY_COMMAND_INTRODUCE_ACK cell. If no + RELAY_COMMAND_INTRODUCE2 cell can be sent, the OR replies to Alice with a + non-empty cell to indicate an error. (The semantics of the cell body may be + determined later; the current implementation sends a single '1' byte on + failure.) + + When Bob's OP receives the RELAY_COMMAND_INTRODUCE2 cell, it first + checks for a replay. Because of the (undesirable!) malleability of + the legacy hybrid encryption algorithm, Bob's OP should only check + whether the RSA-encrypted part is replayed. It does this by keeping, + for each introduction key, a list of cryptographic digests of all the + RSA-encrypted parts of the INTRODUCE2 cells that it's seen, and + dropping any INTRODUCE2 cell whose RSA-encrypted part it has seen + before. When Bob's OP stops using a given introduction key, it drops + the replay cache corresponding to that key. + + (Versions of Tor before 0.2.3.9-alpha used the timestamp in the INTRODUCE2 + cell to limit the lifetime of entries in the replay cache. This proved to + be fragile, due to insufficiently synchronized clients.) + + Assuming that the cell has not been replayed, Bob's server decrypts it + with the private key for the corresponding hidden service, and extracts the + rendezvous point's nickname, the rendezvous cookie, and the value of g^x + chosen by Alice. + +1.10. Rendezvous + + Bob's OP builds a new Tor circuit ending at Alice's chosen rendezvous + point, and sends a RELAY_COMMAND_RENDEZVOUS1 cell along this circuit, + containing: + + RC Rendezvous cookie [20 octets] + g^y Diffie-Hellman [128 octets] + KH Handshake digest [20 octets] + + (Bob's OP MUST NOT use this circuit for any other purpose.) + + (By default, Bob builds a circuit of at least three hops, *not including* + Alice's chosen rendezvous point.) + + If the RP recognizes RC, it relays the rest of the cell down the + corresponding circuit in a RELAY_COMMAND_RENDEZVOUS2 cell, containing: + + g^y Diffie-Hellman [128 octets] + KH Handshake digest [20 octets] + + (If the RP does not recognize the RC, it discards the cell and + tears down the circuit.) + + Rendezvous points running Tor version 0.2.9.1-alpha and later are + willing to pass on RENDEZVOUS2 cells so long as they contain at least + the 20 bytes of cookie. Prior to 0.2.9.1-alpha, the RP refused the + cell if it had a payload length different from 20+128+20. + + When Alice's OP receives a RELAY_COMMAND_RENDEZVOUS2 cell on a circuit which + has sent a RELAY_COMMAND_ESTABLISH_RENDEZVOUS cell but which has not yet + received a reply, it uses g^y and H(g^xy) to complete the handshake as in + the Tor circuit extend process: they establish a 60-octet string as + + K = SHA1(g^xy | [00]) | SHA1(g^xy | [01]) | SHA1(g^xy | [02]) + + and generate KH, Df, Db, Kf, and Kb as in the KDF-TOR key derivation + approach documented in tor-spec.txt. + + As in the TAP handshake, if the KH value derived from KDF-Tor does not + match the value in the RENDEZVOUS2 cell, the client must close the + circuit. + + 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. + +1.11. Creating streams + + To open TCP connections to Bob's location-hidden service, Alice's OP sends + a RELAY_COMMAND_BEGIN cell along the established circuit, using the special + address "", and a chosen port. Bob's OP chooses a destination IP and + port, based on the configuration of the service connected to the circuit, + and opens a TCP stream. From then on, Bob's OP treats the stream as an + ordinary exit connection. + [ Except he doesn't include addr in the connected cell or the end + cell. -RD] + + Alice MAY send multiple RELAY_COMMAND_BEGIN cells along the circuit, to open + multiple streams to Bob. Alice SHOULD NOT send RELAY_COMMAND_BEGIN cells + for any other address along her circuit to Bob; if she does, Bob MUST reject + them. + +1.12. Closing streams + + The payload of a RELAY_END cell begins with a single 'reason' byte to + describe why the stream is closing, plus optional data (depending on the + reason.) These can be found in section 6.3 of tor-spec. The following + describes some of the hidden service related reasons. + + 1 -- REASON_MISC + + Catch-all for unlisted reasons. Shouldn't happen much in practice. + + 2 -- REASON_RESOLVEFAILED + + Tor tried to fetch the hidden service descriptor from the hsdirs but + none of them had it. This implies that the hidden service has not + been running in the past 24 hours. + + 3 -- REASON_CONNECTREFUSED + + Every step of the rendezvous worked great, and that the hidden + service is indeed up and running and configured to use the virtual + port you asked for, but there was nothing listening on the other end + of that virtual port. For example, the HS's Tor client is running + fine but its apache service is down. + + 4 -- REASON_EXITPOLICY + + The destination port that you tried is not configured on the hidden + service side. That is, the hidden service was up and reachable, but + it isn't listening on this port. Since Tor 0.2.6.2-alpha and later + hidden service don't send this error code; instead they send back an + END cell with reason DONE reason then close the circuit on you. This + behavior can be controlled by a config option. + + 5 -- REASON_DESTROY + + The circuit closed before you could get a response back -- transient + failure, e.g. a relay went down unexpectedly. Trying again might + work. + + 6 -- REASON_DONE + + Anonymized TCP connection was closed. If you get an END cell with + reason DONE, *before* you've gotten your CONNECTED cell, that + indicates a similar situation to EXITPOLICY, but the hidden service + is running 0.2.6.2-alpha or later, and it has now closed the circuit + on you. + + 7 -- REASON_TIMEOUT + + Either like CONNECTREFUSED above but connect() got the ETIMEDOUT + errno, or the client-side timeout of 120 seconds kicked in and we + gave up. + + 8 -- REASON_NOROUTE + + Like CONNECTREFUSED except the errno at the hidden service when + trying to connect() to the service was ENETUNREACH, EHOSTUNREACH, + EACCES, or EPERM. + + 10 -- REASON_INTERNAL + + Internal error inside the Tor client -- hopefully you will not see + this much. Please report if you do! + + 12 -- REASON_CONNRESET + + Like CONNECTREFUSED except the errno at the hidden service when + trying to connect() to the service was ECONNRESET. + +2. Authentication and authorization. + + The rendezvous protocol as described in Section 1 provides a few options + for implementing client-side authorization. There are two steps in the + rendezvous protocol that can be used for performing client authorization: + when downloading and decrypting parts of the hidden service descriptor and + at Bob's Tor client before contacting the rendezvous point. A service + provider can restrict access to his service at these two points to + authorized clients only. + + There are currently two authorization protocols specified that are + described in more detail below: + + 1. The first protocol allows a service provider to restrict access + to clients with a previously received secret key only, but does not + attempt to hide service activity from others. + + 2. The second protocol, albeit being feasible for a limited set of about + 16 clients, performs client authorization and hides service activity + from everyone but the authorized clients. + +2.1. Service with large-scale client authorization + + The first client authorization protocol aims at performing access control + while consuming as few additional resources as possible. This is the "basic" + authorization protocol. A service provider should be able to permit access + to a large number of clients while denying access for everyone else. + However, the price for scalability is that the service won't be able to hide + its activity from unauthorized or formerly authorized clients. + + The main idea of this protocol is to encrypt the introduction-point part + in hidden service descriptors to authorized clients using symmetric keys. + This ensures that nobody else but authorized clients can learn which + introduction points a service currently uses, nor can someone send a + valid INTRODUCE1 message without knowing the introduction key. Therefore, + a subsequent authorization at the introduction point is not required. + + A service provider generates symmetric "descriptor cookies" for his + clients and distributes them outside of Tor. The suggested key size is + 128 bits, so that descriptor cookies can be encoded in 22 base64 chars + (which can hold up to 22 * 6 = 132 bits, leaving 4 bits to encode the + authorization type (here: "0") and allow a client to distinguish this + authorization protocol from others like the one proposed below). + Typically, the contact information for a hidden service using this + authorization protocol looks like this: + + v2cbb2l4lsnpio4q.onion Ll3X7Xgz9eHGKCCnlFH0uz + + When generating a hidden service descriptor, the service encrypts the + introduction-point part with a single randomly generated symmetric + 128-bit session key using AES-CTR as described for v2 hidden service + descriptors in rend-spec. Afterwards, the service encrypts the session + key to all descriptor cookies using AES. Authorized client should be able + to efficiently find the session key that is encrypted for him/her, so + that 4 octet long client ID are generated consisting of descriptor cookie + and initialization vector. Descriptors always contain a number of + encrypted session keys that is a multiple of 16 by adding fake entries. + Encrypted session keys are ordered by client IDs in order to conceal + addition or removal of authorized clients by the service provider. + + ATYPE Authorization type: set to 1. [1 octet] + ALEN Number of clients := 1 + ((clients - 1) div 16) [1 octet] + + for each symmetric descriptor cookie: + + ID Client ID: H(descriptor cookie | IV)[:4] [4 octets] + SKEY Session key encrypted with descriptor cookie [16 octets] + + (end of client-specific part) + + RND Random data [(15 - ((clients - 1) mod 16)) * 20 octets] + IV AES initialization vector [16 octets] + IPOS Intro points, encrypted with session key [remaining octets] + + An authorized client needs to configure Tor to use the descriptor cookie + when accessing the hidden service. Therefore, a user adds the contact + information that she received from the service provider to her torrc + file. Upon downloading a hidden service descriptor, Tor finds the + encrypted introduction-point part and attempts to decrypt it using the + configured descriptor cookie. (In the rare event of two or more client + IDs being equal a client tries to decrypt all of them.) + + Upon sending the introduction, the client includes her descriptor cookie + as auth type "1" in the INTRODUCE2 cell that she sends to the service. + The hidden service checks whether the included descriptor cookie is + authorized to access the service and either responds to the introduction + request, or not. + +2.2. Authorization for limited number of clients + + A second, more sophisticated client authorization protocol goes the extra + mile of hiding service activity from unauthorized clients. This is the + "stealth" authorization protocol. With all else being equal to the preceding + authorization protocol, the second protocol publishes hidden service + descriptors for each user separately and gets along with encrypting the + introduction-point part of descriptors to a single client. This allows the + service to stop publishing descriptors for removed clients. As long as a + removed client cannot link descriptors issued for other clients to the + service, it cannot derive service activity any more. The downside of this + approach is limited scalability. Even though the distributed storage of + descriptors (cf. proposal 114) tackles the problem of limited scalability to + a certain extent, this protocol should not be used for services with more + than 16 clients. (In fact, Tor should refuse to advertise services for more + than this number of clients.) + + A hidden service generates an asymmetric "client key" and a symmetric + "descriptor cookie" for each client. The client key is used as + replacement for the service's permanent key, so that the service uses a + different identity for each of his clients. The descriptor cookie is used + to store descriptors at changing directory nodes that are unpredictable + for anyone but service and client, to encrypt the introduction-point + part, and to be included in INTRODUCE2 cells. Once the service has + created client key and descriptor cookie, he tells them to the client + outside of Tor. The contact information string looks similar to the one + used by the preceding authorization protocol (with the only difference + that it has "1" encoded as auth-type in the remaining 4 of 132 bits + instead of "0" as before). + + When creating a hidden service descriptor for an authorized client, the + hidden service uses the client key and descriptor cookie to compute + secret ID part and descriptor ID: + + secret-id-part = H(time-period | descriptor-cookie | replica) + + descriptor-id = H(client-key[:10] | secret-id-part) + + The hidden service also replaces permanent-key in the descriptor with + client-key and encrypts introduction-points with the descriptor cookie. + + ATYPE Authorization type: set to 2. [1 octet] + IV AES initialization vector [16 octets] + IPOS Intro points, encr. with descriptor cookie [remaining octets] + + When uploading descriptors, the hidden service needs to make sure that + descriptors for different clients are not uploaded at the same time (cf. + Section 1.1) which is also a limiting factor for the number of clients. + + When a client is requested to establish a connection to a hidden service + it looks up whether it has any authorization data configured for that + service. If the user has configured authorization data for authorization + protocol "2", the descriptor ID is determined as described in the last + paragraph. Upon receiving a descriptor, the client decrypts the + introduction-point part using its descriptor cookie. Further, the client + includes its descriptor cookie as auth-type "2" in INTRODUCE2 cells that + it sends to the service. + +2.3. Hidden service configuration + + A hidden service that is meant to perform client authorization adds a + new option HiddenServiceAuthorizeClient to its hidden service + configuration. This option contains the authorization type which is + either "basic" for the protocol described in 2.1 or "stealth" for the + protocol in 2.2 and a comma-separated list of human-readable client + names, so that Tor can create authorization data for these clients: + + HiddenServiceAuthorizeClient auth-type client-name,client-name,... + + If this option is configured, HiddenServiceVersion is automatically + reconfigured to contain only version numbers of 2 or higher. There is + a maximum of 512 client names for basic auth and a maximum of 16 for + stealth auth. + + Tor stores all generated authorization data for the authorization + protocols described in Sections 2.1 and 2.2 in a new file using the + following file format: + + "client-name" human-readable client identifier NL + "descriptor-cookie" 128-bit key ^= 22 base64 chars NL + + If the authorization protocol of Section 2.2 is used, Tor also generates + and stores the following data: + + "client-key" NL a private key in PEM format + [No extra arguments] + +2.4. Client configuration + + To specify the cookie to use to access a given hidden service, + clients use the following syntax: + + HidServAuth onion-address auth-cookie [service-name]: + + Valid onion addresses contain 16 characters in a-z2-7 plus + ".onion", and valid auth cookies contain 22 characters in + A-Za-z0-9+/. The service name is only used for internal purposes, + e.g., for Tor controllers; nothing in Tor itself requires or uses + it. + +3. Hidden service directory operation + + This section has been introduced with the v2 hidden service descriptor + format. It describes all operations of the v2 hidden service descriptor + fetching and propagation mechanism that are required for the protocol + described in section 1 to succeed with v2 hidden service descriptors. + +3.1. Configuring as hidden service directory + + Every onion router that has its directory port open can decide whether it + wants to store and serve hidden service descriptors. An onion router which + is configured as such includes the "hidden-service-dir" flag in its router + descriptors that it sends to directory authorities. + + The directory authorities include a new flag "HSDir" for routers that + decided to provide storage for hidden service descriptors and that + have been running for at least 96 hours. + +3.2. Accepting publish requests + + Hidden service directory nodes accept publish requests for v2 hidden service + descriptors and store them to their local memory. (It is not necessary to + make descriptors persistent, because after restarting, the onion router + would not be accepted as a storing node anyway, because it has not been + running for at least 24 hours.) All requests and replies are formatted as + HTTP messages. Requests are initiated via BEGIN_DIR cells directed to + the router's directory port, and formatted as HTTP POST requests to the URL + "/tor/rendezvous2/publish" relative to the hidden service directory's root, + containing as its body a v2 service descriptor. + + A hidden service directory node parses every received descriptor and only + stores it when it thinks that it is responsible for storing that descriptor + based on its own routing table. See section 1.4 for more information on how + to determine responsibility for a certain descriptor ID. + +3.3. Processing fetch requests + + Hidden service directory nodes process fetch requests for hidden service + descriptors by looking them up in their local memory. (They do not need to + determine if they are responsible for the passed ID, because it does no harm + if they deliver a descriptor for which they are not (any more) responsible.) + All requests and replies are formatted as HTTP messages. Requests are + initiated via BEGIN_DIR cells directed to the router's directory port, + and formatted as HTTP GET requests for the document "/tor/rendezvous2/", + where z is replaced with the encoding of the descriptor ID. + diff --git a/rend-spec-v2.txt b/rend-spec-v2.txt deleted file mode 100644 index 0306f4b..0000000 --- a/rend-spec-v2.txt +++ /dev/null @@ -1,1087 +0,0 @@ - - Tor Rendezvous Specification - -0. Overview and preliminaries - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL - NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and - "OPTIONAL" in this document are to be interpreted as described in - RFC 2119. - - Read - https://svn.torproject.org/svn/projects/design-paper/tor-design.html#sec:rendezvous - before you read this specification. It will make more sense. - - Rendezvous points provide location-hidden services (server - anonymity) for the onion routing network. With rendezvous points, - Bob can offer a TCP service (say, a webserver) via the onion - routing network, without revealing the IP of that service. - - Bob does this by anonymously advertising a public key for his - service, along with a list of onion routers to act as "Introduction - Points" for his service. He creates forward circuits to those - introduction points, and tells them about his service. To - connect to Bob, Alice first builds a circuit to an OR to act as - her "Rendezvous Point." She then connects to one of Bob's chosen - introduction points, and asks it to tell him about her Rendezvous - Point (RP). If Bob chooses to answer, he builds a circuit to her - RP, and tells it to connect him to Alice. The RP joins their - circuits together, and begins relaying cells. Alice's 'BEGIN' - cells are received directly by Bob's OP, which passes data to - and from the local server implementing Bob's service. - - Below we describe a network-level specification of this service, - along with interfaces to make this process transparent to Alice - (so long as she is using an OP). - -0.1. Notation, conventions and prerequisites - - In the specifications below, we use the same notation and terminology - as in "tor-spec.txt". The service specified here also requires the - existence of an onion routing network as specified in that file. - - H(x) is a SHA1 digest of x. - PKSign(SK,x) is a PKCS.1-padded RSA signature of x with SK. - PKEncrypt(SK,x) is a PKCS.1-padded RSA encryption of x with SK. - Public keys are all RSA, and encoded in ASN.1. - All integers are stored in network (big-endian) order. - All symmetric encryption uses AES in counter mode, except where - otherwise noted. - - In all discussions, "Alice" will refer to a user connecting to a - location-hidden service, and "Bob" will refer to a user running a - location-hidden service. - - An OP is (as defined elsewhere) an "Onion Proxy" or Tor client. - - An OR is (as defined elsewhere) an "Onion Router" or Tor server. - - An "Introduction point" is a Tor server chosen to be Bob's medium-term - 'meeting place'. A "Rendezvous point" is a Tor server chosen by Alice to - be a short-term communication relay between her and Bob. All Tor servers - potentially act as introduction and rendezvous points. - -0.2. Protocol outline - - 1. Bob->Bob's OP: "Offer IP:Port as public-key-name:Port". [configuration] - (We do not specify this step; it is left to the implementor of - Bob's OP.) - - 2. Bob's OP generates a long-term keypair. - - 3. Bob's OP->Introduction point via Tor: [introduction setup] - "This public key is (currently) associated to me." - - 4. Bob's OP->directory service via Tor: publishes Bob's service descriptor - [advertisement] - "Meet public-key X at introduction point A, B, or C." (signed) - - 5. Out of band, Alice receives a z.onion:port address. - She opens a SOCKS connection to her OP, and requests z.onion:port. - - 6. Alice's OP retrieves Bob's descriptor via Tor. [descriptor lookup.] - - 7. Alice's OP chooses a rendezvous point, opens a circuit to that - rendezvous point, and establishes a rendezvous circuit. [rendezvous - setup.] - - 8. Alice connects to the Introduction point via Tor, and tells it about - her rendezvous point. (Encrypted to Bob.) [Introduction 1] - - 9. The Introduction point passes this on to Bob's OP via Tor, along the - introduction circuit. [Introduction 2] - - 10. Bob's OP decides whether to connect to Alice, and if so, creates a - circuit to Alice's RP via Tor. Establishes a shared circuit. - [Rendezvous 1] - - 11. The Rendezvous point forwards Bob's confirmation to Alice's OP. - [Rendezvous 2] - - 12. Alice's OP sends begin cells to Bob's OP. [Connection] - -0.3. Constants and new cell types - - Relay cell types - - 32 -- RELAY_COMMAND_ESTABLISH_INTRO - 33 -- RELAY_COMMAND_ESTABLISH_RENDEZVOUS - 34 -- RELAY_COMMAND_INTRODUCE1 - 35 -- RELAY_COMMAND_INTRODUCE2 - 36 -- RELAY_COMMAND_RENDEZVOUS1 - 37 -- RELAY_COMMAND_RENDEZVOUS2 - 38 -- RELAY_COMMAND_INTRO_ESTABLISHED - 39 -- RELAY_COMMAND_RENDEZVOUS_ESTABLISHED - 40 -- RELAY_COMMAND_INTRODUCE_ACK - -0.4. Version overview - - There are several parts in the hidden service protocol that have - changed over time, each of them having its own version number, whereas - other parts remained the same. The following list of potentially - versioned protocol parts should help reduce some confusion: - - - Hidden service descriptor: the binary-based v0 was the default for a - long time, and an ASCII-based v2 has been added by proposal 114. The - v0 descriptor format has been deprecated in 0.2.2.1-alpha. See 1.3. - - - Hidden service descriptor propagation mechanism: currently related to - the hidden service descriptor version -- v0 publishes to the original - hs directory authorities, whereas v2 publishes to a rotating subset - of relays with the "HSDir" flag; see 1.4 and 1.6. - - - Introduction protocol for how to generate an introduction cell: - v0 specified a nickname for the rendezvous point and assumed the - relay would know about it, whereas v2 now specifies IP address, - port, and onion key so the relay doesn't need to already recognize - it. See 1.8. - -1. The Protocol - -1.1. Bob configures his local OP. - - We do not specify a format for the OP configuration file. However, - OPs SHOULD allow Bob to provide more than one advertised service - per OP, and MUST allow Bob to specify one or more virtual ports per - service. Bob provides a mapping from each of these virtual ports - to a local IP:Port pair. - -1.2. Bob's OP establishes his introduction points. - - The first time the OP provides an advertised service, it generates - a public/private keypair (stored locally). - - The OP chooses a small number of Tor servers as introduction points. - The OP establishes a new introduction circuit to each introduction - point. These circuits MUST NOT be used for anything but hidden service - introduction. To establish the introduction, Bob sends a - RELAY_COMMAND_ESTABLISH_INTRO cell, containing: - - KL Key length [2 octets] - PK Bob's public key or service key [KL octets] - HS Hash of session info [20 octets] - SIG Signature of above information [variable] - - KL is the length of PK, in octets. - - To prevent replay attacks, the HS field contains a SHA-1 hash based on the - shared secret KH between Bob's OP and the introduction point, as - follows: - - HS = H(KH | "INTRODUCE") - - That is: - - HS = H(KH | [49 4E 54 52 4F 44 55 43 45]) - - (KH, as specified in tor-spec.txt, is H(g^xy | [00]) .) - - Upon receiving such a cell, the OR first checks that the signature is - correct with the included public key. If so, it checks whether HS is - correct given the shared state between Bob's OP and the OR. If either - check fails, the OP discards the cell; otherwise, it associates the - circuit with Bob's public key, and dissociates any other circuits - currently associated with PK. On success, the OR sends Bob a - RELAY_COMMAND_INTRO_ESTABLISHED cell with an empty payload. - - Bob's OP uses either Bob's public key or a freshly generated, single-use - service key in the RELAY_COMMAND_ESTABLISH_INTRO cell, depending on the - configured hidden service descriptor version. The public key is used for - v0 descriptors, the service key for v2 descriptors. In the latter case, the - service keys of all introduction points are included in the v2 hidden - service descriptor together with the other introduction point information. - The reason is that the introduction point does not need to and therefore - should not know for which hidden service it works, so as to prevent it from - tracking the hidden service's activity. If the hidden service is configured - to publish both v0 and v2 descriptors, two separate sets of introduction - points are established. - -1.3. Bob's OP generates service descriptors. - - For versions before 0.2.2.1-alpha, Bob's OP periodically generates and - publishes a descriptor of type "V0". - - The "V0" descriptor contains: - - KL Key length [2 octets] - PK Bob's public key [KL octets] - TS A timestamp [4 octets] - NI Number of introduction points [2 octets] - Ipt A list of NUL-terminated ORs [variable] - SIG Signature of above fields [variable] - - TS is the number of seconds elapsed since Jan 1, 1970. - - The members of Ipt may be either (a) nicknames, or (b) identity key - digests, encoded in hex, and prefixed with a '$'. Clients must - accept both forms. Services must only generate the second form. - Once 0.0.9.x is obsoleted, we can drop the first form. - - [It's ok for Bob to advertise 0 introduction points. He might want - to do that if he previously advertised some introduction points, - and now he doesn't have any. -RD] - - Beginning with 0.2.0.10-alpha, Bob's OP encodes "V2" descriptors in - addition to (or instead of) "V0" descriptors. The format of a "V2" - descriptor is as follows: - - "rendezvous-service-descriptor" SP descriptor-id NL - - [At start, exactly once] - [No extra arguments] - - Indicates the beginning of the descriptor. "descriptor-id" is a - periodically changing identifier of 160 bits formatted as 32 base32 - chars that is calculated by the hidden service and its clients. The - "descriptor-id" is calculated by performing the following operation: - - descriptor-id = - H(permanent-id | H(time-period | descriptor-cookie | replica)) - - "permanent-id" is the permanent identifier of the hidden service, - consisting of 80 bits. It can be calculated by computing the hash value - of the public hidden service key and truncating after the first 80 bits: - - permanent-id = H(public-key)[:10] - - Note: If Bob's OP has "stealth" authorization enabled (see Section 2.2), - it uses the client key in place of the public hidden service key. - - "H(time-period | descriptor-cookie | replica)" is the (possibly - secret) id part that is necessary to verify that the hidden service is - the true originator of this descriptor and that is therefore contained - in the descriptor, too. The descriptor ID can only be created by the - hidden service and its clients, but the "signature" below can only be - created by the service. - - "time-period" changes periodically as a function of time and - "permanent-id". The current value for "time-period" can be calculated - using the following formula: - - time-period = (current-time + permanent-id-byte * 86400 / 256) - / 86400 - - "current-time" contains the current system time in seconds since - 1970-01-01 00:00, e.g. 1188241957. "permanent-id-byte" is the first - (unsigned) byte of the permanent identifier (which is in network - order), e.g. 143. Adding the product of "permanent-id-byte" and - 86400 (seconds per day), divided by 256, prevents "time-period" from - changing for all descriptors at the same time of the day. The result - of the overall operation is a (network-ordered) 32-bit integer, e.g. - 13753 or 0x000035B9 with the example values given above. - - "descriptor-cookie" is an optional secret password of 128 bits that - is shared between the hidden service provider and its clients. If the - descriptor-cookie is left out, the input to the hash function is 128 - bits shorter. [No extra arguments] - - "replica" denotes the number of the replica. A service publishes - multiple descriptors with different descriptor IDs in order to - distribute them to different places on the ring. - - "version" SP version-number NL - - [Exactly once] - [No extra arguments] - - The version number of this descriptor's format. Version numbers are a - positive integer. - - "permanent-key" NL a public key in PEM format - - [Exactly once] - [No extra arguments] - - The public key of the hidden service which is required to verify the - "descriptor-id" and the "signature". - - "secret-id-part" SP secret-id-part NL - - [Exactly once] - [No extra arguments] - - The result of the following operation as explained above, formatted as - 32 base32 chars. Using this secret id part, everyone can verify that - the signed descriptor belongs to "descriptor-id". - - secret-id-part = H(time-period | descriptor-cookie | replica) - - "publication-time" SP YYYY-MM-DD HH:MM:SS NL - - [Exactly once] - - A timestamp when this descriptor has been created. It should be - rounded down to the nearest hour. - - "protocol-versions" SP version-string NL - - [Exactly once] - [No extra arguments] - - A comma-separated list of recognized and permitted version numbers - for use in INTRODUCE cells; these versions are described in section - 1.8 below. Version numbers are positive integers. - - "introduction-points" NL encrypted-string - - [At most once] - [No extra arguments] - - A list of introduction points. If the optional "descriptor-cookie" is - used, this list is encrypted with AES in CTR mode with a random - initialization vector of 128 bits that is written to - the beginning of the encrypted string, and the "descriptor-cookie" as - secret key of 128 bits length. - - The string containing the introduction point data (either encrypted - or not) is encoded in base64, and surrounded with - "-----BEGIN MESSAGE-----" and "-----END MESSAGE-----". - - A maximum of 10 introduction point entries may follow, each containing - the following data: - - "introduction-point" SP identifier NL - - [At start, exactly once] - [No extra arguments] - - The identifier of this introduction point: the base32 encoded - hash of this introduction point's identity key. - - "ip-address" SP ip4 NL - - [Exactly once] - [No extra arguments] - - The IP address of this introduction point. - - "onion-port" SP port NL - - [Exactly once] - [No extra arguments] - - The TCP port on which the introduction point is listening for - incoming onion requests. - - "onion-key" NL a public key in PEM format - - [Exactly once] - [No extra arguments] - - The public key that can be used to encrypt messages to this - introduction point. - - "service-key" NL a public key in PEM format - - [Exactly once] - [No extra arguments] - - The public key that can be used to encrypt messages to the hidden - service. - - "intro-authentication" auth-type auth-data NL - - [Any number] - - The introduction-point-specific authentication data can be used - to perform client authentication. This data depends on the - selected introduction point as opposed to "service-authentication" - above. The format of auth-data (base64-encoded or PEM format) - depends on auth-type. See section 2 of this document for details - on auth mechanisms. - - (This ends the fields in the encrypted portion of the descriptor.) - - [It's ok for Bob to advertise 0 introduction points. He might want - to do that if he previously advertised some introduction points, - and now he doesn't have any. -RD] - - "signature" NL signature-string - - [At end, exactly once] - [No extra arguments] - - A signature of all fields above including '"signature" NL' with - the private key of the hidden service. - -1.3.1. Other descriptor formats we don't use. - - Support for the V0 descriptor format was dropped in 0.2.2.0-alpha-dev: - - KL Key length [2 octets] - PK Bob's public key [KL octets] - TS A timestamp [4 octets] - NI Number of introduction points [2 octets] - Ipt A list of NUL-terminated ORs [variable] - SIG Signature of above fields [variable] - - KL is the length of PK, in octets. - TS is the number of seconds elapsed since Jan 1, 1970. - - The members of Ipt may be either (a) nicknames, or (b) identity key - digests, encoded in hex, and prefixed with a '$'. - - The V1 descriptor format was understood and accepted from - 0.1.1.5-alpha-cvs to 0.2.0.6-alpha-dev, but no Tors generated it and - it was removed: - - V Format byte: set to 255 [1 octet] - V Version byte: set to 1 [1 octet] - KL Key length [2 octets] - PK Bob's public key [KL octets] - TS A timestamp [4 octets] - PROTO Protocol versions: bitmask [2 octets] - NI Number of introduction points [2 octets] - For each introduction point: (as in INTRODUCE2 cells) - IP Introduction point's address [4 octets] - PORT Introduction point's OR port [2 octets] - ID Introduction point identity ID [20 octets] - KLEN Length of onion key [2 octets] - KEY Introduction point onion key [KLEN octets] - SIG Signature of above fields [variable] - - A hypothetical "V1" descriptor, that has never been used but might - be useful for historical reasons, contains: - - V Format byte: set to 255 [1 octet] - V Version byte: set to 1 [1 octet] - KL Key length [2 octets] - PK Bob's public key [KL octets] - TS A timestamp [4 octets] - PROTO Rendezvous protocol versions: bitmask [2 octets] - NA Number of auth mechanisms accepted [1 octet] - For each auth mechanism: - AUTHT The auth type that is supported [2 octets] - AUTHL Length of auth data [1 octet] - AUTHD Auth data [variable] - NI Number of introduction points [2 octets] - For each introduction point: (as in INTRODUCE2 cells) - ATYPE An address type (typically 4) [1 octet] - ADDR Introduction point's IP address [4 or 16 octets] - PORT Introduction point's OR port [2 octets] - AUTHT The auth type that is supported [2 octets] - AUTHL Length of auth data [1 octet] - AUTHD Auth data [variable] - ID Introduction point identity ID [20 octets] - KLEN Length of onion key [2 octets] - KEY Introduction point onion key [KLEN octets] - SIG Signature of above fields [variable] - - AUTHT specifies which authentication/authorization mechanism is - required by the hidden service or the introduction point. AUTHD - is arbitrary data that can be associated with an auth approach. - Currently only AUTHT of [00 00] is supported, with an AUTHL of 0. - See section 2 of this document for details on auth mechanisms. - -1.4. Bob's OP advertises his service descriptor(s). - - Bob's OP advertises his service descriptor to a fixed set of v0 hidden - service directory servers and/or a changing subset of all v2 hidden service - directories. - - For versions before 0.2.2.1-alpha, Bob's OP opens a stream to each v0 - directory server's directory port via Tor. (He may re-use old circuits for - this.) Over this stream, Bob's OP makes an HTTP 'POST' request, to a URL - "/tor/rendezvous/publish" relative to the directory server's root, - containing as its body Bob's service descriptor. - - Upon receiving a descriptor, the directory server checks the signature, - and discards the descriptor if the signature does not match the enclosed - public key. Next, the directory server checks the timestamp. If the - timestamp is more than 24 hours in the past or more than 1 hour in the - future, or the directory server already has a newer descriptor with the - same public key, the server discards the descriptor. Otherwise, the - server discards any older descriptors with the same public key and - version format, and associates the new descriptor with the public key. - The directory server remembers this descriptor for at least 24 hours - after its timestamp. At least every 18 hours, Bob's OP uploads a - fresh descriptor. - - If Bob's OP is configured to publish v2 descriptors, it does so to a - changing subset of all v2 hidden service directories instead of the - authoritative directory servers. Therefore, Bob's OP opens a stream via - Tor to each responsible hidden service directory. (He may re-use old - circuits for this.) Over this stream, Bob's OP makes an HTTP 'POST' - request to a URL "/tor/rendezvous2/publish" relative to the hidden service - directory's root, containing as its body Bob's service descriptor. - - [XXX022 Reusing old circuits for HS dir posts is very bad. Do we really - do that? --RR] - - At any time, there are 6 hidden service directories responsible for - keeping replicas of a descriptor; they consist of 2 sets of 3 hidden - service directories with consecutive onion IDs. Bob's OP learns about - the complete list of hidden service directories by filtering the - consensus status document received from the directory authorities. A - hidden service directory is deemed responsible for a descriptor ID if - it has the HSDir flag and its identity digest is one of the first three - identity digests of HSDir relays following the descriptor ID in a - circular list. A hidden service directory will only accept a descriptor - whose timestamp is no more than three days before or one day after the - current time according to the directory's clock. - - Bob's OP publishes a new v2 descriptor once an hour or whenever its - content changes. V2 descriptors can be found by clients within a given - time period of 24 hours, after which they change their ID as described - under 1.3. If a published descriptor would be valid for less than 60 - minutes (= 2 x 30 minutes to allow the server to be 30 minutes behind - and the client 30 minutes ahead), Bob's OP publishes the descriptor - under the ID of both, the current and the next publication period. - -1.5. Alice receives a z.onion address. - - When Alice receives a pointer to a location-hidden service, it is as a - hostname of the form "z.onion", where z is a base32 encoding of a - 10-octet hash of Bob's service's public key, computed as follows: - - 1. Let H = H(PK). - 2. Let H' = the first 80 bits of H, considering each octet from - most significant bit to least significant bit. - 3. Generate a 16-character encoding of H', using base32 as defined - in RFC 4648. - - (We only use 80 bits instead of the 160 bits from SHA1 because we - don't need to worry about arbitrary collisions, and because it will - make handling the url's more convenient.) - - [Yes, numbers are allowed at the beginning. See RFC 1123. -NM] - -1.6. Alice's OP retrieves a service descriptor. - - Alice's OP fetches the service descriptor from the fixed set of v0 hidden - service directory servers and/or a changing subset of all v2 hidden service - directories. - - For versions before 0.2.2.1-alpha, Alice's OP opens a stream to a directory - server via Tor, and makes an HTTP GET request for the document - '/tor/rendezvous/', where '' is replaced with the encoding of Bob's - public key as described above. (She may re-use old circuits for this.) The - directory replies with a 404 HTTP response if it does not recognize , - and otherwise returns Bob's most recently uploaded service descriptor. - - If Alice's OP receives a 404 response, it tries the other directory - servers, and only fails the lookup if none recognize the public key hash. - - Upon receiving a service descriptor, Alice verifies with the same process - as the directory server uses, described above in section 1.4. - - The directory server gives a 400 response if it cannot understand Alice's - request. - - Alice should cache the descriptor locally, but should not use - descriptors that are more than 24 hours older than their timestamp. - [Caching may make her partitionable, but she fetched it anonymously, - and we can't very well *not* cache it. -RD] - - If Alice's OP is running 0.2.1.10-alpha or higher, it fetches v2 hidden - service descriptors. Versions before 0.2.2.1-alpha are fetching both v0 and - v2 descriptors in parallel. Similar to the description in section 1.4, - Alice's OP fetches a v2 descriptor from a randomly chosen hidden service - directory out of the changing subset of 6 nodes. If the request is - unsuccessful, Alice retries the other remaining responsible hidden service - directories in a random order. Alice relies on Bob to care about a potential - clock skew between the two by possibly storing two sets of descriptors (see - end of section 1.4). - - Alice's OP opens a stream via Tor to the chosen v2 hidden service - directory. (She may re-use old circuits for this.) Over this stream, - Alice's OP makes an HTTP 'GET' request for the document - "/tor/rendezvous2/", where z is replaced with the encoding of the - descriptor ID. The directory replies with a 404 HTTP response if it does - not recognize , and otherwise returns Bob's most recently uploaded - service descriptor. - -1.7. Alice's OP establishes a rendezvous point. - - When Alice requests a connection to a given location-hidden service, - and Alice's OP does not have an established circuit to that service, - the OP builds a rendezvous circuit. It does this by establishing - a circuit to a randomly chosen OR, and sending a - RELAY_COMMAND_ESTABLISH_RENDEZVOUS cell to that OR. The body of that cell - contains: - - RC Rendezvous cookie [20 octets] - - The rendezvous cookie is an arbitrary 20-byte value, chosen randomly by - Alice's OP. Alice SHOULD choose a new rendezvous cookie for each new - connection attempt. - - Upon receiving a RELAY_COMMAND_ESTABLISH_RENDEZVOUS cell, the OR associates - the RC with the circuit that sent it. It replies to Alice with an empty - RELAY_COMMAND_RENDEZVOUS_ESTABLISHED cell to indicate success. - - Alice's OP MUST NOT use the circuit which sent the cell for any purpose - other than rendezvous with the given location-hidden service. - -1.8. Introduction: from Alice's OP to Introduction Point - - Alice builds a separate circuit to one of Bob's chosen introduction - points, and sends it a RELAY_COMMAND_INTRODUCE1 cell containing: - - Cleartext - PK_ID Identifier for Bob's PK [20 octets] - Encrypted to Bob's PK: (in the v0 intro protocol) - RP Rendezvous point's nickname [20 octets] - RC Rendezvous cookie [20 octets] - g^x Diffie-Hellman data, part 1 [128 octets] - OR (in the v1 intro protocol) - VER Version byte: set to 1. [1 octet] - RP Rendezvous point nick or ID [42 octets] - RC Rendezvous cookie [20 octets] - g^x Diffie-Hellman data, part 1 [128 octets] - OR (in the v2 intro protocol) - VER Version byte: set to 2. [1 octet] - IP Rendezvous point's address [4 octets] - PORT Rendezvous point's OR port [2 octets] - ID Rendezvous point identity ID [20 octets] - KLEN Length of onion key [2 octets] - KEY Rendezvous point onion key [KLEN octets] - RC Rendezvous cookie [20 octets] - g^x Diffie-Hellman data, part 1 [128 octets] - OR (in the v3 intro protocol) - VER Version byte: set to 3. [1 octet] - AUTHT The auth type that is used [1 octet] - If AUTHT != [00]: - AUTHL Length of auth data [2 octets] - AUTHD Auth data [variable] - TS A timestamp [4 octets] - IP Rendezvous point's address [4 octets] - PORT Rendezvous point's OR port [2 octets] - ID Rendezvous point identity ID [20 octets] - KLEN Length of onion key [2 octets] - KEY Rendezvous point onion key [KLEN octets] - RC Rendezvous cookie [20 octets] - g^x Diffie-Hellman data, part 1 [128 octets] - - PK_ID is the hash of Bob's public key or the service key, depending on the - hidden service descriptor version. In case of a v0 descriptor, Alice's OP - uses Bob's public key. If Alice has downloaded a v2 descriptor, she uses - the contained public key ("service-key"). - - RP is NUL-padded and terminated. In version 0 of the intro protocol, RP - must contain a nickname. In version 1, it must contain EITHER a nickname or - an identity key digest that is encoded in hex and prefixed with a '$'. - - The hybrid encryption to Bob's PK works just like the hybrid - encryption in CREATE cells (see tor-spec, section 0.4). Thus the - payload of the version 0 RELAY_COMMAND_INTRODUCE1 cell on the - wire will contain 20+42+16+20+20+128=246 bytes, and the version 1 - and version 2 introduction formats have other sizes. - - Through Tor 0.2.0.6-alpha, clients only generated the v0 introduction - format, whereas hidden services have understood and accepted v0, - v1, and v2 since 0.1.1.x. As of Tor 0.2.0.7-alpha and 0.1.2.18, - clients switched to using the v2 intro format. - - The Timestamp (TS) field is no longer used in Tor 0.2.3.9-alpha and - later. Clients MAY refrain from sending it; see the - "Support022HiddenServices" parameter in dir-spec.txt. Clients SHOULD - NOT send a precise timestamp, and should instead round to the nearest - 10 minutes. - -1.9. Introduction: From the Introduction Point to Bob's OP - - If the Introduction Point recognizes PK_ID as a public key which has - established a circuit for introductions as in 1.2 above, it sends the body - of the cell in a new RELAY_COMMAND_INTRODUCE2 cell down the corresponding - circuit. (If the PK_ID is unrecognized, the RELAY_COMMAND_INTRODUCE1 cell is - discarded.) - - After sending the RELAY_COMMAND_INTRODUCE2 cell to Bob, the OR replies to - Alice with an empty RELAY_COMMAND_INTRODUCE_ACK cell. If no - RELAY_COMMAND_INTRODUCE2 cell can be sent, the OR replies to Alice with a - non-empty cell to indicate an error. (The semantics of the cell body may be - determined later; the current implementation sends a single '1' byte on - failure.) - - When Bob's OP receives the RELAY_COMMAND_INTRODUCE2 cell, it first - checks for a replay. Because of the (undesirable!) malleability of - the legacy hybrid encryption algorithm, Bob's OP should only check - whether the RSA-encrypted part is replayed. It does this by keeping, - for each introduction key, a list of cryptographic digests of all the - RSA-encrypted parts of the INTRODUCE2 cells that it's seen, and - dropping any INTRODUCE2 cell whose RSA-encrypted part it has seen - before. When Bob's OP stops using a given introduction key, it drops - the replay cache corresponding to that key. - - (Versions of Tor before 0.2.3.9-alpha used the timestamp in the INTRODUCE2 - cell to limit the lifetime of entries in the replay cache. This proved to - be fragile, due to insufficiently synchronized clients.) - - Assuming that the cell has not been replayed, Bob's server decrypts it - with the private key for the corresponding hidden service, and extracts the - rendezvous point's nickname, the rendezvous cookie, and the value of g^x - chosen by Alice. - -1.10. Rendezvous - - Bob's OP builds a new Tor circuit ending at Alice's chosen rendezvous - point, and sends a RELAY_COMMAND_RENDEZVOUS1 cell along this circuit, - containing: - - RC Rendezvous cookie [20 octets] - g^y Diffie-Hellman [128 octets] - KH Handshake digest [20 octets] - - (Bob's OP MUST NOT use this circuit for any other purpose.) - - (By default, Bob builds a circuit of at least three hops, *not including* - Alice's chosen rendezvous point.) - - If the RP recognizes RC, it relays the rest of the cell down the - corresponding circuit in a RELAY_COMMAND_RENDEZVOUS2 cell, containing: - - g^y Diffie-Hellman [128 octets] - KH Handshake digest [20 octets] - - (If the RP does not recognize the RC, it discards the cell and - tears down the circuit.) - - Rendezvous points running Tor version 0.2.9.1-alpha and later are - willing to pass on RENDEZVOUS2 cells so long as they contain at least - the 20 bytes of cookie. Prior to 0.2.9.1-alpha, the RP refused the - cell if it had a payload length different from 20+128+20. - - When Alice's OP receives a RELAY_COMMAND_RENDEZVOUS2 cell on a circuit which - has sent a RELAY_COMMAND_ESTABLISH_RENDEZVOUS cell but which has not yet - received a reply, it uses g^y and H(g^xy) to complete the handshake as in - the Tor circuit extend process: they establish a 60-octet string as - - K = SHA1(g^xy | [00]) | SHA1(g^xy | [01]) | SHA1(g^xy | [02]) - - and generate KH, Df, Db, Kf, and Kb as in the KDF-TOR key derivation - approach documented in tor-spec.txt. - - As in the TAP handshake, if the KH value derived from KDF-Tor does not - match the value in the RENDEZVOUS2 cell, the client must close the - circuit. - - 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. - -1.11. Creating streams - - To open TCP connections to Bob's location-hidden service, Alice's OP sends - a RELAY_COMMAND_BEGIN cell along the established circuit, using the special - address "", and a chosen port. Bob's OP chooses a destination IP and - port, based on the configuration of the service connected to the circuit, - and opens a TCP stream. From then on, Bob's OP treats the stream as an - ordinary exit connection. - [ Except he doesn't include addr in the connected cell or the end - cell. -RD] - - Alice MAY send multiple RELAY_COMMAND_BEGIN cells along the circuit, to open - multiple streams to Bob. Alice SHOULD NOT send RELAY_COMMAND_BEGIN cells - for any other address along her circuit to Bob; if she does, Bob MUST reject - them. - -1.12. Closing streams - - The payload of a RELAY_END cell begins with a single 'reason' byte to - describe why the stream is closing, plus optional data (depending on the - reason.) These can be found in section 6.3 of tor-spec. The following - describes some of the hidden service related reasons. - - 1 -- REASON_MISC - - Catch-all for unlisted reasons. Shouldn't happen much in practice. - - 2 -- REASON_RESOLVEFAILED - - Tor tried to fetch the hidden service descriptor from the hsdirs but - none of them had it. This implies that the hidden service has not - been running in the past 24 hours. - - 3 -- REASON_CONNECTREFUSED - - Every step of the rendezvous worked great, and that the hidden - service is indeed up and running and configured to use the virtual - port you asked for, but there was nothing listening on the other end - of that virtual port. For example, the HS's Tor client is running - fine but its apache service is down. - - 4 -- REASON_EXITPOLICY - - The destination port that you tried is not configured on the hidden - service side. That is, the hidden service was up and reachable, but - it isn't listening on this port. Since Tor 0.2.6.2-alpha and later - hidden service don't send this error code; instead they send back an - END cell with reason DONE reason then close the circuit on you. This - behavior can be controlled by a config option. - - 5 -- REASON_DESTROY - - The circuit closed before you could get a response back -- transient - failure, e.g. a relay went down unexpectedly. Trying again might - work. - - 6 -- REASON_DONE - - Anonymized TCP connection was closed. If you get an END cell with - reason DONE, *before* you've gotten your CONNECTED cell, that - indicates a similar situation to EXITPOLICY, but the hidden service - is running 0.2.6.2-alpha or later, and it has now closed the circuit - on you. - - 7 -- REASON_TIMEOUT - - Either like CONNECTREFUSED above but connect() got the ETIMEDOUT - errno, or the client-side timeout of 120 seconds kicked in and we - gave up. - - 8 -- REASON_NOROUTE - - Like CONNECTREFUSED except the errno at the hidden service when - trying to connect() to the service was ENETUNREACH, EHOSTUNREACH, - EACCES, or EPERM. - - 10 -- REASON_INTERNAL - - Internal error inside the Tor client -- hopefully you will not see - this much. Please report if you do! - - 12 -- REASON_CONNRESET - - Like CONNECTREFUSED except the errno at the hidden service when - trying to connect() to the service was ECONNRESET. - -2. Authentication and authorization. - - The rendezvous protocol as described in Section 1 provides a few options - for implementing client-side authorization. There are two steps in the - rendezvous protocol that can be used for performing client authorization: - when downloading and decrypting parts of the hidden service descriptor and - at Bob's Tor client before contacting the rendezvous point. A service - provider can restrict access to his service at these two points to - authorized clients only. - - There are currently two authorization protocols specified that are - described in more detail below: - - 1. The first protocol allows a service provider to restrict access - to clients with a previously received secret key only, but does not - attempt to hide service activity from others. - - 2. The second protocol, albeit being feasible for a limited set of about - 16 clients, performs client authorization and hides service activity - from everyone but the authorized clients. - -2.1. Service with large-scale client authorization - - The first client authorization protocol aims at performing access control - while consuming as few additional resources as possible. This is the "basic" - authorization protocol. A service provider should be able to permit access - to a large number of clients while denying access for everyone else. - However, the price for scalability is that the service won't be able to hide - its activity from unauthorized or formerly authorized clients. - - The main idea of this protocol is to encrypt the introduction-point part - in hidden service descriptors to authorized clients using symmetric keys. - This ensures that nobody else but authorized clients can learn which - introduction points a service currently uses, nor can someone send a - valid INTRODUCE1 message without knowing the introduction key. Therefore, - a subsequent authorization at the introduction point is not required. - - A service provider generates symmetric "descriptor cookies" for his - clients and distributes them outside of Tor. The suggested key size is - 128 bits, so that descriptor cookies can be encoded in 22 base64 chars - (which can hold up to 22 * 6 = 132 bits, leaving 4 bits to encode the - authorization type (here: "0") and allow a client to distinguish this - authorization protocol from others like the one proposed below). - Typically, the contact information for a hidden service using this - authorization protocol looks like this: - - v2cbb2l4lsnpio4q.onion Ll3X7Xgz9eHGKCCnlFH0uz - - When generating a hidden service descriptor, the service encrypts the - introduction-point part with a single randomly generated symmetric - 128-bit session key using AES-CTR as described for v2 hidden service - descriptors in rend-spec. Afterwards, the service encrypts the session - key to all descriptor cookies using AES. Authorized client should be able - to efficiently find the session key that is encrypted for him/her, so - that 4 octet long client ID are generated consisting of descriptor cookie - and initialization vector. Descriptors always contain a number of - encrypted session keys that is a multiple of 16 by adding fake entries. - Encrypted session keys are ordered by client IDs in order to conceal - addition or removal of authorized clients by the service provider. - - ATYPE Authorization type: set to 1. [1 octet] - ALEN Number of clients := 1 + ((clients - 1) div 16) [1 octet] - - for each symmetric descriptor cookie: - - ID Client ID: H(descriptor cookie | IV)[:4] [4 octets] - SKEY Session key encrypted with descriptor cookie [16 octets] - - (end of client-specific part) - - RND Random data [(15 - ((clients - 1) mod 16)) * 20 octets] - IV AES initialization vector [16 octets] - IPOS Intro points, encrypted with session key [remaining octets] - - An authorized client needs to configure Tor to use the descriptor cookie - when accessing the hidden service. Therefore, a user adds the contact - information that she received from the service provider to her torrc - file. Upon downloading a hidden service descriptor, Tor finds the - encrypted introduction-point part and attempts to decrypt it using the - configured descriptor cookie. (In the rare event of two or more client - IDs being equal a client tries to decrypt all of them.) - - Upon sending the introduction, the client includes her descriptor cookie - as auth type "1" in the INTRODUCE2 cell that she sends to the service. - The hidden service checks whether the included descriptor cookie is - authorized to access the service and either responds to the introduction - request, or not. - -2.2. Authorization for limited number of clients - - A second, more sophisticated client authorization protocol goes the extra - mile of hiding service activity from unauthorized clients. This is the - "stealth" authorization protocol. With all else being equal to the preceding - authorization protocol, the second protocol publishes hidden service - descriptors for each user separately and gets along with encrypting the - introduction-point part of descriptors to a single client. This allows the - service to stop publishing descriptors for removed clients. As long as a - removed client cannot link descriptors issued for other clients to the - service, it cannot derive service activity any more. The downside of this - approach is limited scalability. Even though the distributed storage of - descriptors (cf. proposal 114) tackles the problem of limited scalability to - a certain extent, this protocol should not be used for services with more - than 16 clients. (In fact, Tor should refuse to advertise services for more - than this number of clients.) - - A hidden service generates an asymmetric "client key" and a symmetric - "descriptor cookie" for each client. The client key is used as - replacement for the service's permanent key, so that the service uses a - different identity for each of his clients. The descriptor cookie is used - to store descriptors at changing directory nodes that are unpredictable - for anyone but service and client, to encrypt the introduction-point - part, and to be included in INTRODUCE2 cells. Once the service has - created client key and descriptor cookie, he tells them to the client - outside of Tor. The contact information string looks similar to the one - used by the preceding authorization protocol (with the only difference - that it has "1" encoded as auth-type in the remaining 4 of 132 bits - instead of "0" as before). - - When creating a hidden service descriptor for an authorized client, the - hidden service uses the client key and descriptor cookie to compute - secret ID part and descriptor ID: - - secret-id-part = H(time-period | descriptor-cookie | replica) - - descriptor-id = H(client-key[:10] | secret-id-part) - - The hidden service also replaces permanent-key in the descriptor with - client-key and encrypts introduction-points with the descriptor cookie. - - ATYPE Authorization type: set to 2. [1 octet] - IV AES initialization vector [16 octets] - IPOS Intro points, encr. with descriptor cookie [remaining octets] - - When uploading descriptors, the hidden service needs to make sure that - descriptors for different clients are not uploaded at the same time (cf. - Section 1.1) which is also a limiting factor for the number of clients. - - When a client is requested to establish a connection to a hidden service - it looks up whether it has any authorization data configured for that - service. If the user has configured authorization data for authorization - protocol "2", the descriptor ID is determined as described in the last - paragraph. Upon receiving a descriptor, the client decrypts the - introduction-point part using its descriptor cookie. Further, the client - includes its descriptor cookie as auth-type "2" in INTRODUCE2 cells that - it sends to the service. - -2.3. Hidden service configuration - - A hidden service that is meant to perform client authorization adds a - new option HiddenServiceAuthorizeClient to its hidden service - configuration. This option contains the authorization type which is - either "basic" for the protocol described in 2.1 or "stealth" for the - protocol in 2.2 and a comma-separated list of human-readable client - names, so that Tor can create authorization data for these clients: - - HiddenServiceAuthorizeClient auth-type client-name,client-name,... - - If this option is configured, HiddenServiceVersion is automatically - reconfigured to contain only version numbers of 2 or higher. There is - a maximum of 512 client names for basic auth and a maximum of 16 for - stealth auth. - - Tor stores all generated authorization data for the authorization - protocols described in Sections 2.1 and 2.2 in a new file using the - following file format: - - "client-name" human-readable client identifier NL - "descriptor-cookie" 128-bit key ^= 22 base64 chars NL - - If the authorization protocol of Section 2.2 is used, Tor also generates - and stores the following data: - - "client-key" NL a private key in PEM format - [No extra arguments] - -2.4. Client configuration - - To specify the cookie to use to access a given hidden service, - clients use the following syntax: - - HidServAuth onion-address auth-cookie [service-name]: - - Valid onion addresses contain 16 characters in a-z2-7 plus - ".onion", and valid auth cookies contain 22 characters in - A-Za-z0-9+/. The service name is only used for internal purposes, - e.g., for Tor controllers; nothing in Tor itself requires or uses - it. - -3. Hidden service directory operation - - This section has been introduced with the v2 hidden service descriptor - format. It describes all operations of the v2 hidden service descriptor - fetching and propagation mechanism that are required for the protocol - described in section 1 to succeed with v2 hidden service descriptors. - -3.1. Configuring as hidden service directory - - Every onion router that has its directory port open can decide whether it - wants to store and serve hidden service descriptors. An onion router which - is configured as such includes the "hidden-service-dir" flag in its router - descriptors that it sends to directory authorities. - - The directory authorities include a new flag "HSDir" for routers that - decided to provide storage for hidden service descriptors and that - have been running for at least 96 hours. - -3.2. Accepting publish requests - - Hidden service directory nodes accept publish requests for v2 hidden service - descriptors and store them to their local memory. (It is not necessary to - make descriptors persistent, because after restarting, the onion router - would not be accepted as a storing node anyway, because it has not been - running for at least 24 hours.) All requests and replies are formatted as - HTTP messages. Requests are initiated via BEGIN_DIR cells directed to - the router's directory port, and formatted as HTTP POST requests to the URL - "/tor/rendezvous2/publish" relative to the hidden service directory's root, - containing as its body a v2 service descriptor. - - A hidden service directory node parses every received descriptor and only - stores it when it thinks that it is responsible for storing that descriptor - based on its own routing table. See section 1.4 for more information on how - to determine responsibility for a certain descriptor ID. - -3.3. Processing fetch requests - - Hidden service directory nodes process fetch requests for hidden service - descriptors by looking them up in their local memory. (They do not need to - determine if they are responsible for the passed ID, because it does no harm - if they deliver a descriptor for which they are not (any more) responsible.) - All requests and replies are formatted as HTTP messages. Requests are - initiated via BEGIN_DIR cells directed to the router's directory port, - and formatted as HTTP GET requests for the document "/tor/rendezvous2/", - where z is replaced with the encoding of the descriptor ID. - -- cgit v1.2.3-54-g00ecf