H(x) = SHA1 digest of x. 1. Create service 2. generate service descriptors: -first-time: generate private/public key pair -encode "V2" descriptors -- at start once: "rendezvous-service-descriptor" descriptor-id NL - indicates beginning - descriptor-id: a periodically changing identifier of 160 bits formatted as 32 base32 chars that is calculated by the hidden service and its clients. - descriptor-id = H(permanent-id | H(time-period | descriptor-cookie | replica)) - (optional) descripter-cookie: is an optional secret password of 128 bits that is shared between the hidden service provider and its clients. - permanent-id = H(public-key)[:10] (hash value of public-key up to 80 bits) - "replica" denotes the number of the non-consecutive replica. (wtf?) - The "time-period" changes periodically depending on the global time and as a function of "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 (unix format) -- "version" version-number NL -- "permanent-key" NL a public key in PEM format [once] - The public key of the hidden service which is required to verify the "descriptor-id" and the "signature". -- "secret-id-part" secret-id-part NL [once] - - secret-id-part = H(time-period | descriptor-cookie | replica) -- "publication-time" YYYY-MM-DD HH:MM:SS NL -- "protocol-versions" version-string NL -- "introduction-points" NL encrypted-string (encrypted or not depending on descriptor-cookie) [At most once] - encrypted -is encoded in base64, and surrounded with - "-----BEGIN MESSAGE-----" and "-----END MESSAGE-----". - unecrypteded - "service-authentication" auth-type NL auth-data ... reserved OR - "introduction-point" identifier NL - "ip-address" ip-address NL - "onion-port" port NL - "onion-key" NL a public key in PEM format - "service-key" NL a public key in PEM format - "intro-authentication" auth-type NL auth-data ... reserved - (The introduction-point-specific authentication data can be used to perform client authentication.) (This ends the fields in the encrypted portion of the descriptor.) - "signature" NL signature-string (at end, exactly once) 3. Establish the introduction point. - new introduction circuit to each introduction point. - done through RELAY_ESTABLISH_INTRO cell. KL Key length [2 octets] PK Introduction public key [KL octets] HS Hash of session info [20 octets] SIG Signature of above information [variable] - HS = H(KH | "INTRODUCE") - Upon receiving - OR first checks that the signature is correct with the included public key. - checks whether HS is correct given the shared state between Bob's OP and the OR. - 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_INTRO_ESTABLISHED cell with an empty payload. 4. Bob's OP advertises his service descriptor - Bob's OP opens a stream to each directory server's directory port via Tor. - 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. - Bob should upload a service descriptor for each version format that is supported in the current Tor network. - At least every 18 hours, Bob's OP uploads a fresh descriptor. - Bob's OP publishes v2 descriptors to a changing subset of all v2 hidden service directories. - opens a stream via Tor to each responsible hidden service directory - 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. - 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.2. 5. Alice recieves onion address - form of "z.onion" y.z.onion or x.y.z.onion - where z is a base-32 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 3548. - x, if present, is the base-32 encoding of the authentication/authorization required by the introduction point. - y, if present, is the base-32 encoding of the authentication/authorization required by the hidden service. 6. Alice retrieves a service descriptor. - fetches a v2 descriptor from a randomly chosen hidden service directory out of the changing subset of 6 nodes. - if unsuccessful Alice retries the other remaining responsible hidden service directories in a random order. - potential clock skew between the two by possibly storing two sets of descriptors (Bob's side) - Alice's OP opens a stream via Tor to the chosen v2 hidden service directory. - Alice's OP makes an HTTP 'GET' request for the document "/tor/rendezvous2/", where z is replaced with the encoding of the descriptor ID. -if 404 - 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. - When receiving the service, Alice verifies with the same process as the directory server uses, described above in section 1.4. - Alice should cache the descriptor locally, but should not use descriptors that are more than 24 hours older than their timestamp. 7. Alice's OP establishes a rendezvous point. - If no established circuit to the RP (no connection to hidden service) and If 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_ESTABLISH_RENDEZVOUS cell to that OR. The body of that cell contains: HiddenServiceConnection (Alice) - cell contains: RC Rendezvous cookie [20 octets] -The rendezvous cookie is an arbitrary 20-byte value, chosen randomly by Alice's OP. HiddenServiceConnection (Alice) - HiddenServiceConnection(String onionAddres) - parseOnionAddress() - fetchServiceDescripter() - rendezvous() - Circuit(s) opened to rendevous points RendevouzPoint - rendezvouscookie HiddenService (Bob)(instantiated w/ portrange and(optional) existing keypair) - PortRange portrange; - GenerateKeys() - GenerateServiceDescripter() - AdvertiseDescriptor() ServiceDescriptor (V2Descriptor) - descripterID - descripterCookie IntroductionPoint (point bob wants to advertise for others to establish their circuit) - "introductionPoint" identifier NL - "ip-address" ip-address NL - "onion-port" port NL - "onion-key" NL a public key in PEM format - "service-key" NL a public key in PEM format - "intro-authentication" auth-type NL auth-data