| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 | Filename: 169-eliminating-renegotiation.txtTitle: Eliminate TLS renegotiation for the Tor connection handshakeAuthor: Nick MathewsonCreated: 27-Jan-2010Status: DraftTarget: 0.2.21. 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. Design3.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.
 |