123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- Filename: 169-eliminating-renegotiation.txt
- Title: Eliminate TLS renegotiation for the Tor connection handshake
- Author: Nick Mathewson
- Created: 27-Jan-2010
- Status: Draft
- Target: 0.2.2
- 1. Overview
- I propose a backward-compatible change to the Tor connection
- establishment protocol to avoid the use of TLS renegotiation.
- Rather than doing a TLS renegotiation to exchange certificates
- and authenticate the original handshake, this proposal takes an
- approach similar to Steven Murdoch's proposal 124, and uses Tor
- cells to finish authenticating the parties' identities once the
- initial TLS handshake is finished.
- Terminological note: I use "client" below to mean the Tor
- instance (a client or a relay) that initiates a TLS connection,
- and "server" to mean the Tor instance (a relay) that accepts it.
- 2. Motivation and history
- In the original Tor TLS connection handshake protocol ("V1", or
- "two-cert"), parties that wanted to authenticate provided a
- two-cert chain of X.509 certificates during the handshake setup
- phase. Every party that wanted to authenticate sent these
- certificates.
- In the current Tor TLS connection handshake protocol ("V2", or
- "renegotiating"), the parties begin with a single certificate
- sent from the server (responder) to the client (initiator), and
- then renegotiate to a two-certs-from-each-authenticating party.
- We made this change to make Tor's handshake look like a browser
- speaking SSL to a webserver. (See proposal 130, and
- tor-spec.txt.) To tell whether to use the V1 or V2 handshake,
- servers look at the list of ciphers sent by the client. (This is
- ugly, but there's not much else in the ClientHello that they can
- look at.) If the list contains any cipher not used by the V1
- protocol, the server sends back a single cert and expects a
- renegotiation. If the client gets back a single cert, then it
- withholds its own certificates until the TLS renegotiation phase.
- In other words, initiator behavior now looks like this:
- - Begin TLS negotiation with V2 cipher list; wait for
- certificate(s).
- - If we get a certificate chain:
- - Then we are using the V1 handshake. Send our own
- certificate chain as part of this initial TLS handshake
- if we want to authenticate; otherwise, send no
- certificates. When the handshake completes, check
- certificates. We are now mutually authenticated.
- Otherwise, if we get just a single certificate:
- - Then we are using the V2 handshake. Do not send any
- certificates during this handshake.
- - When the handshake is done, immediately start a TLS
- renegotiation. During the renegotiation, expect
- a certificate chain from the server; send a certificate
- chain of our own if we want to authenticate ourselves.
- - After the renegotiation, check the certificates. Then
- send (and expect) a VERSIONS cell from the other side to
- establish the link protocol version.
- And V2 responder behavior now looks like this:
- - When we get a TLS ClientHello request, look at the cipher
- list.
- - If the cipher list contains only the V1 ciphersuites:
- - Then we're doing a V1 handshake. Send a certificate
- chain. Expect a possible client certificate chain in
- response.
- Otherwise, if we get other ciphersuites:
- - We're using the V2 handshake. Send back a single
- certificate and let the handshake complete.
- - Do not accept any data until the client has renegotiated.
- - When the client is renegotiating, send a certificate
- chain, and expect (possibly multiple) certificates in
- reply.
- - Check the certificates when the renegotiation is done.
- Then exchange VERSIONS cells.
- Late in 2009, researchers found a flaw in most applications' use
- of TLS renegotiation: Although TLS renegotiation does not
- reauthenticate any information exchanged before the renegotiation
- takes place, many applications were treating it as though it did,
- and assuming that data sent _before_ the renegotiation was
- authenticated with the credentials negotiated _during_ the
- renegotiation. This problem was exacerbated by the fact that
- most TLS libraries don't actually give you an obvious good way to
- tell where the renegotiation occurred relative to the datastream.
- Tor wasn't directly affected by this vulnerability, but its
- aftermath hurts us in a few ways:
- 1) OpenSSL has disabled renegotiation by default, and created
- a "yes we know what we're doing" option we need to set to
- turn it back on. (Two options, actually: one for openssl
- 0.9.8l and one for 0.9.8m and later.)
- 2) Some vendors have removed all renegotiation support from
- their versions of OpenSSL entirely, forcing us to tell
- users to either replace their versions of OpenSSL or to
- link Tor against a hand-built one.
- 3) Because of 1 and 2, I'd expect TLS renegotiation to become
- rarer and rarer in the wild, making our own use stand out
- more.
- 3. Design
- 3.1. The view in the large
- Taking a cue from Steven Murdoch's proposal 124, I propose that
- we move the work currently done by the TLS renegotiation step
- (that is, authenticating the parties to one another) and do it
- with Tor cells instead of with TLS.
- Using _yet another_ variant response from the responder (server),
- we allow the client to learn that it doesn't need to rehandshake
- and can instead use a cell-based authentication system. Once the
- TLS handshake is done, the client and server exchange VERSIONS
- cells to determine link protocol version (including
- handshake version). If they're using the handshake version
- specified here, the client and server arrive at link protocol
- version 3 (or higher), and use cells to exchange further
- authentication information.
- 3.2. New TLS handshake variant
- We already used the list of ciphers from the clienthello to
- indicate whether the client can speak the V2 ("renegotiating")
- handshake or later, so we can't encode more information there.
- We can, however, change the DN in the certificate passed by the
- server back to the client. Currently, all V2 certificates are
- generated with CN values ending with ".net". I propose that we
- have the ".net" commonName ending reserved to indicate the V2
- protocol, and use commonName values ending with ".com" to
- indicate the V3 ("minimal") handshake described herein.
- Now, once the initial TLS handshake is done, the client can look
- at the server's certificate(s). If there is a certificate chain,
- the handshake is V1. If there is a single certificate whose
- subject commonName ends in ".net", the handshake is V2 and the
- client should try to renegotiate as it would currently.
- Otherwise, the client should assume that the handshake is V3+.
- [Servers should _only_ send ".com" addesses, to allow room for
- more signaling in the future.]
- 3.3. Authenticating inside Tor
- Once the TLS handshake is finished, if the client renegotiates,
- then the server should go on as it does currently.
- If the client implements this proposal, however, and the server
- has shown it can understand the V3+ handshake protocol, the
- client immediately sends a VERSIONS cell to the server
- and waits to receive a VERSIONS cell in return. We negotiate
- the Tor link protocol version _before_ we proceed with the
- negotiation, in case we need to change the authentication
- protocol in the future.
- Once either party has seen the VERSIONS cell from the other, it
- knows which version they will pick (that is, the highest version
- shared by both parties' VERSIONS cells). All Tor instances using
- the handshake protocol described in 3.2 MUST support at least
- link protocol version 3 as described here.
- On learning the link protocol, the server then sends the client a
- CERT cell and a NETINFO cell. If the client wants to
- authenticate to the server, it sends a CERT cell, an AUTHENTICATE
- cell, and a NETINFO cell, or it may simply send a NETINFO cell if
- it does not want to authenticate.
- The CERT cell describes the keys that a Tor instance is claiming
- to have. It is a variable-length cell. Its payload format is:
- N: Number of certs in cell [1 octet]
- N times:
- CLEN [2 octets]
- Certificate [CLEN octets]
- Any extra octets at the end of a CERT cell MUST be ignored.
- Each certificate has the form:
- CertType [1 octet]
- CertPurpose [1 octet]
- PublicKeyLen [2 octets]
- PublicKey [PublicKeyLen octets]
- NotBefore [4 octets]
- NotAfter [4 octets]
- SignerID [HASH256_LEN octets]
- SignatureLen [2 octets]
- Signature [SignatureLen octets]
- where CertType is 1 (meaning "RSA/SHA256")
- CertPurpose is 1 (meaning "link certificate")
- PublicKey is the DER encoding of the ASN.1 representation
- of the RSA key of the subject of this certificate,
- NotBefore is a time in HOURS since January 1, 1970, 00:00
- UTC before which this certificate should not be
- considered valid.
- NotAfter is a time in HOURS since January 1, 1970, 00:00
- UTC after which this certificate should not be
- considered valid.
- SignerID is the SHA-256 digest of the public key signing
- this certificate
- and Signature is the signature of the all other fields in
- this certificate, using SHA256 as described in proposal
- 158.
- While authenticating, a server need send only a self-signed
- certificate for its identity key. (Its TLS certificate already
- contains its link key signed by its identity key.) A client that
- wants to authenticate MUST send two certificates: one containing
- a public link key signed by its identity key, and one self-signed
- cert for its identity.
- Tor instances MUST ignore any certificate with an unrecognized
- CertType or CertPurpose, and MUST ignore extra bytes in the cert.
- The AUTHENTICATE cell proves to the server that the client with
- whom it completed the initial TLS handshake is the one possessing
- the link public key in its certificate. It is a variable-length
- cell. Its contents are:
- SignatureType [2 octets]
- SignatureLen [2 octets]
- Signature [SignatureLen octets]
- where SignatureType is 1 (meaning "RSA-SHA256") and Signature is
- an RSA-SHA256 signature of the HMAC-SHA256, using the TLS master
- secret key as its key, of the following elements:
- - The SignatureType field (0x00 0x01)
- - The NUL terminated ASCII string: "Tor certificate verification"
- - client_random, as sent in the Client Hello
- - server_random, as sent in the Server Hello
- Once the above handshake is complete, the client knows (from the
- initial TLS handshake) that it has a secure connection to an
- entity that controls a given link public key, and knows (from the
- CERT cell) that the link public key is a valid public key for a
- given Tor identity.
- If the client authenticates, the server learns from the CERT cell
- that a given Tor identity has a given current public link key.
- From the AUTHENTICATE cell, it knows that an entity with that
- link key knows the master secret for the TLS connection, and
- hence must be the party with whom it's talking, if TLS works.
- 3.4. Security checks
- If the TLS handshake indicates a V2 or V3+ connection, the server
- MUST reject any connection from the client that does not begin
- with either a renegotiation attempt or a VERSIONS cell containing
- at least link protocol version "3". If the TLS handshake
- indicates a V3+ connection, the client MUST reject any connection
- where the server sends anything before the client has sent a
- VERSIONS cell, and any connection where the VERSIONS cell does
- not contain at least link protocol version "3".
- If link protocol version 3 is chosen:
- Clients and servers MUST check that all digests and signatures
- on the certificates in CERT cells they are given are as
- described above.
- After the VERSIONS cell, clients and servers MUST close the
- connection if anything besides a CERT or AUTH cell is sent
- before the
- CERT or AUTHENTICATE cells anywhere after the first NETINFO
- cell must be rejected.
- ... [write more here. What else?] ...
- 3.5. Summary
- We now revisit the protocol outlines from section 2 to incorporate
- our changes. New or modified steps are marked with a *.
- The new initiator behavior now looks like this:
- - Begin TLS negotiation with V2 cipher list; wait for
- certificate(s).
- - If we get a certificate chain:
- - Then we are using the V1 handshake. Send our own
- certificate chain as part of this initial TLS handshake
- if we want to authenticate; otherwise, send no
- certificates. When the handshake completes, check
- certificates. We are now mutually authenticated.
- Otherwise, if we get just a single certificate:
- - Then we are using the V2 or the V3+ handshake. Do not
- send any certificates during this handshake.
- * When the handshake is done, look at the server's
- certificate's subject commonName.
- * If it ends with ".net", we're doing a V2 handshake:
- - Immediately start a TLS renegotiation. During the
- renegotiation, expect a certificate chain from the
- server; send a certificate chain of our own if we
- want to authenticate ourselves.
- - After the renegotiation, check the certificates. Then
- send (and expect) a VERSIONS cell from the other side
- to establish the link protocol version.
- * If it ends with anything else, assume a V3 or later
- handshake:
- * Send a VERSIONS cell, and wait for a VERSIONS cell
- from the server.
- * If we are authenticating, send CERT and AUTHENTICATE
- cells.
- * Send a NETINFO cell. Wait for a CERT and a NETINFO
- cell from the server.
- * If the CERT cell contains a valid self-identity cert,
- and the identity key in the cert can be used to check
- the signature on the x.509 certificate we got during
- the TLS handshake, then we know we connected to the
- server with that identity. If any of these checks
- fail, or the identity key was not what we expected,
- then we close the connection.
- * Once the NETINFO cell arrives, continue as before.
- And V3+ responder behavior now looks like this:
- - When we get a TLS ClientHello request, look at the cipher
- list.
- - If the cipher list contains only the V1 ciphersuites:
- - Then we're doing a V1 handshake. Send a certificate
- chain. Expect a possible client certificate chain in
- response.
- Otherwise, if we get other ciphersuites:
- - We're using the V2 handshake. Send back a single
- certificate whose subject commonName ends with ".com",
- and let the handshake complete.
- * If the client does anything besides renegotiate or send a
- VERSIONS cell, drop the connection.
- - If the client renegotiates immediately, it's a V2
- connection:
- - When the client is renegotiating, send a certificate
- chain, and expect (possibly multiple certificates in
- reply).
- - Check the certificates when the renegotiation is done.
- Then exchange VERSIONS cells.
- * Otherwise we got a VERSIONS cell and it's a V3 handshake.
- * Send a VERSIONS cell, a CERT cell, an AUTHENTICATE
- cell, and a NETINFO cell.
- * Wait for the client to send cells in reply. If the
- client sends a CERT and an AUTHENTICATE and a NETINFO,
- use them to authenticate the client. If the client
- sends a NETINFO, it is unauthenticated. If it sends
- anything else before its NETINFO, it's rejected.
- 4. Numbers to assign
- We need a version number for this link protocol. I've been
- calling it "3".
- We need to reserve command numbers for CERT and AUTH cells. I
- suggest that in link protocol 3 and higher, we reserve command
- numbers 128..240 for variable-length cells. (241-256 we can hold
- for future extensions.
- 5. Efficiency
- This protocol add a round-trip step when the client sends a
- VERSIONS cell to the server, and waits for the {VERSIONS, CERT,
- NETINFO} response in turn. (The server then waits for the
- client's {NETINFO} or {CERT, AUTHENTICATE, NETINFO} reply,
- but it would have already been waiting for the client's NETINFO,
- so that's not an additional wait.)
- This is actually fewer round-trip steps than required before for
- TLS renegotiation, so that's a win.
- 6. Open questions:
- - Should we use X.509 certificates instead of the certificate-ish
- things we describe here? They are more standard, but more ugly.
- - May we cache which certificates we've already verified? It
- might leak in timing whether we've connected with a given server
- before, and how recently.
- - Is there a better secret than the master secret to use in the
- AUTHENTICATE cell? Say, a portable one? Can we get at it for
- other libraries besides OpenSSL?
- - Does using the client_random and server_random data in the
- AUTHENTICATE message actually help us? How hard is it to pull
- them out of the OpenSSL data structure?
- - Can we give some way for clients to signal "I want to use the
- V3 protocol if possible, but I can't renegotiate, so don't give
- me the V2"? Clients currently have a fair idea of server
- versions, so they could potentially do the V3+ handshake with
- servers that support it, and fall back to V1 otherwise.
- - What should servers that don't have TLS renegotiation do? For
- now, I think they should just get it. Eventually we can
- deprecate the V2 handshake as we did with the V1 handshake.
|