mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
179 lines
7.0 KiB
Plaintext
179 lines
7.0 KiB
Plaintext
|
Filename: xxx-v2-conn-protocol.txt
|
||
|
Title: Version 2 Tor connection protocol
|
||
|
Version: $Revision$
|
||
|
Last-Modified: $Date$
|
||
|
Author: Nick Mathewson
|
||
|
Created: 2007-10-25
|
||
|
Status: Draft
|
||
|
|
||
|
Overview:
|
||
|
|
||
|
This proposal describes the significant changes to be made in the v2
|
||
|
Tor connection protocol.
|
||
|
|
||
|
This proposal relates to other proposals as follows:
|
||
|
|
||
|
It refers to and supersedes:
|
||
|
Proposal 124: Blocking resistant TLS certificate usage
|
||
|
It refers to aspects of:
|
||
|
Proposal 105: Version negotiation for the Tor protocol
|
||
|
Proposal 110: Avoid infinite length circuits
|
||
|
|
||
|
|
||
|
In summary, The Tor connection protocol has been in need of a redesign
|
||
|
for a while. This proposal describes how we can add to the Tor
|
||
|
protocol:
|
||
|
|
||
|
- A new TLS handshake (to achieve blocking resistance without
|
||
|
breaking backward compatibility)
|
||
|
- Version negotiation (so that future connection protocol changes
|
||
|
can happen without breaking compatibility)
|
||
|
- The actual changes in the v2 Tor connection protocol.
|
||
|
|
||
|
Motivation:
|
||
|
|
||
|
For motivation, see proposal 124.
|
||
|
|
||
|
Proposal:
|
||
|
|
||
|
0. Terminology
|
||
|
|
||
|
The version of the Tor connection protocol implemented up to now is
|
||
|
"version 1". This proposal describes "version 2".
|
||
|
|
||
|
"Old" or "Older" versions of Tor are ones not aware of this protocol;
|
||
|
"New" or "Newer" versions are ones that are.
|
||
|
|
||
|
The connection initiator is referred to below as the Client; the
|
||
|
connection responder is referred to below as the Server.
|
||
|
|
||
|
1. The revised TLS handshake.
|
||
|
|
||
|
For motivation, see proposal 124. This is a simplified version of the
|
||
|
handshake that uses TLS's renegotiation capability in order to avoid
|
||
|
some of the extraneous steps in proposal 124.
|
||
|
|
||
|
The Client connects to the Server and, as in ordinary TLS, sends a
|
||
|
list of ciphers. Older versions of Tor will send only ciphers from
|
||
|
the list:
|
||
|
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
|
||
|
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|
||
|
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
|
||
|
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
|
||
|
Clients that support the revised handshake will send the recommended
|
||
|
list of ciphers from proposal 124, in order to emulate the behavior of
|
||
|
a web browser.
|
||
|
|
||
|
If the server notices that the list of ciphers contains only ciphers
|
||
|
from this list, it proceeds with Tor's version 1 TLS handshake as
|
||
|
documented in tor-spec.txt.
|
||
|
|
||
|
(The server may also notice cipher lists used by other implementations
|
||
|
of the Tor protocol (in particular, the BouncyCastle default cipher
|
||
|
list as used by some Java-based implementations), and whitelist them.)
|
||
|
|
||
|
On the other hand, if the server sees a list of ciphers that could not
|
||
|
have been sent from an older implementation (because it includes other
|
||
|
ciphers, and does not match any known-old list), the server sends a
|
||
|
reply containing a single connection certificate, constructed as for
|
||
|
the link certificate in the v1 Tor protocol. The subject names in
|
||
|
this certificate SHOULD NOT have any strings to identify them as
|
||
|
coming from a Tor server. The server does not ask the client for
|
||
|
certificates.
|
||
|
|
||
|
Old Servers will (mostly) ignore the cipher list respond as in the v1
|
||
|
protocol, and send back a two-certificate chain.
|
||
|
|
||
|
After the Client gets a response from the server, it checks for the
|
||
|
number of certificates. If there are two certificates, the client
|
||
|
assumes a V1 connection and proceeds as in tor-spec.txt. But if there
|
||
|
is only one certificate, the client assumes a V2 or later protocol and
|
||
|
continues.
|
||
|
|
||
|
At this point, the client has established a TLS connection with the
|
||
|
server, but the parties have not been authenticated: the server hasn't
|
||
|
sent its identity certificate, and the client hasn't sent any
|
||
|
certificates at all. To fix this, the client begins a TLS session
|
||
|
renegotiation. This time, the server continues with two certificates
|
||
|
as usual, and asks for certificates so that the client will send
|
||
|
certificates of its own. Because the TLS connection has been
|
||
|
established, all of this is encrypted.
|
||
|
|
||
|
The server MUST NOT write any data until the client has renegotiated.
|
||
|
|
||
|
Once the renegotiation is finished, the server and client check one
|
||
|
another's certificates as in V1. Now they are mutually authenticated.
|
||
|
|
||
|
1.1. Revised TLS handshake: implementation notes.
|
||
|
|
||
|
It isn't so easy to adjust server behavior based on the client's
|
||
|
ciphersuite list. Here's how we can do it using OpenSSL. This is a
|
||
|
bit of an abuse of the OpenSSL APIs, but it's the best we can do, and
|
||
|
we won't have to do it forever.
|
||
|
|
||
|
We can use OpenSSL's SSL_set_info_callback() to register a function to
|
||
|
be called when the state changes. The type/state tuple of
|
||
|
SSL_CB_ACCEPT_LOOP/SSL3_ST_SW_SRVR_HELLO_A
|
||
|
happens when we have completely parsed the client hello, and are about
|
||
|
to send a response. From this callback, we can check the cipherlist
|
||
|
and act accordingly:
|
||
|
|
||
|
* If the ciphersuite list indicates a v1 protocol, we set the
|
||
|
verify mode to SSL_VERIFY_NONE with a callback (so we get
|
||
|
certificates).
|
||
|
|
||
|
* If the ciphersuite list indicates a v2 protocol, we set the
|
||
|
verify mode to SSL_VERIFY_NONE with no callback (so we get
|
||
|
no certificates) and set the SSL_MODE_NO_AUTO_CHAIN flag (so that
|
||
|
we send only 1 certificate in the response.
|
||
|
|
||
|
Once the handshake is done, the server clears the
|
||
|
SSL_MODE_NO_AUTO_CHAIN flag and sets the callback as for the V1
|
||
|
protocol. It then starts reading.
|
||
|
|
||
|
|
||
|
The other problem to take care of is missing ciphers and OpenSSL's
|
||
|
cipher sorting algorithms. [XXXX more on this.]
|
||
|
|
||
|
|
||
|
1.2. Compatibility for clients using libraries less hackable than OpenSSL.
|
||
|
|
||
|
As discussed in proposal 105, servers advertise which protocol
|
||
|
versions they support in their router descriptors. Clients can simply
|
||
|
behave as v1 clients when connecting to servers that do not support
|
||
|
link version 2 or higher, and as v2 clients when connecting to servers
|
||
|
that do support link version 2 or higher.
|
||
|
|
||
|
(Servers can't use this strategy because we do not assume that servers
|
||
|
know one another's capabilities when connecting.)
|
||
|
|
||
|
2. Version negotiation.
|
||
|
|
||
|
Version negotiation proceeds as described in proposal 105, except as
|
||
|
follows:
|
||
|
|
||
|
* Version negotiation only happens if the TLS handshake as described
|
||
|
above completes.
|
||
|
|
||
|
* The TLS renegotiation must be finished before the client sends a
|
||
|
VERSIONS cell; the server sends its VERSIONS cell in response.
|
||
|
|
||
|
* The VERSIONS cell uses the following variable-width format:
|
||
|
Circuit [2 octets; set to 0]
|
||
|
Command [1 octet; set to 7 for VERSIONS]
|
||
|
Length [2 octets; big-endian]
|
||
|
Data [Length bytes]
|
||
|
|
||
|
The Data in the cell is a series of big-endian two-byte integers.
|
||
|
|
||
|
3. The rest of the "v2" protocol
|
||
|
|
||
|
Once a v2 protocol has been negotiated, NETINFO cells are exchanged
|
||
|
as in proposal 105, and communications begin as per tor-spec.txt.
|
||
|
|
||
|
RELAY_EARLY cells are accepted as in proposal 110, and treated as
|
||
|
RELAY cells except that they are relayed as RELAY_EARLY if the next
|
||
|
host in the circuit has negotiated v2 or later; otherwise, not.
|
||
|
Command value 9 is used for RELAY_EARLY.
|
||
|
|