diff options
author | Nick Mathewson <nickm@torproject.org> | 2023-11-07 16:14:55 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2023-11-08 09:09:04 -0500 |
commit | 31a1873ce07d5a093fa2fd3901f1a6d4c1d28c5f (patch) | |
tree | 68d1f25b043cdd33000c599e1b0b7a8084f7c07d | |
parent | fd59c8762ceff63b6bde214daa8fcaeccec21b0b (diff) | |
download | torspec-31a1873ce07d5a093fa2fd3901f1a6d4c1d28c5f.tar.gz torspec-31a1873ce07d5a093fa2fd3901f1a6d4c1d28c5f.zip |
Continue rewrite of channel handshake stuff
This is mainly a rewrite of channels-tls, which has proven to be
a less necessary file than I had thought: Nearly all of its content
has moved to a new "obsolete handshakes" document.
-rw-r--r-- | spec/SUMMARY.md | 3 | ||||
-rw-r--r-- | spec/tor-spec/cell-packet-format.md | 12 | ||||
-rw-r--r-- | spec/tor-spec/channels-tls.md | 241 | ||||
-rw-r--r-- | spec/tor-spec/channels.md | 46 | ||||
-rw-r--r-- | spec/tor-spec/obsolete-channels.md | 160 | ||||
-rw-r--r-- | spec/tor-spec/relay-keys.md | 5 |
6 files changed, 232 insertions, 235 deletions
diff --git a/spec/SUMMARY.md b/spec/SUMMARY.md index d3b77ed..bd7eaad 100644 --- a/spec/SUMMARY.md +++ b/spec/SUMMARY.md @@ -10,7 +10,8 @@ - [System overview](./tor-spec/system-overview.md) - [Relay keys and identities](./tor-spec/relay-keys.md) - [Channels](./tor-spec/channels.md) - - [The TLS handshake](./tor-spec/channels-tls.md) + - [Channels and TLS](./tor-spec/channels-tls.md) + - [Obsolete channel negotiation handshakes](./tor-spec/obsolete-channels.md) - [Negotiating and initializing channels](./tor-spec/negotiating-channels.md) - [Cells (messages on channels)](./tor-spec/cell-packet-format.md) - [Circuit management](./tor-spec/circuit-management.md) diff --git a/spec/tor-spec/cell-packet-format.md b/spec/tor-spec/cell-packet-format.md index 96acbfc..7251db0 100644 --- a/spec/tor-spec/cell-packet-format.md +++ b/spec/tor-spec/cell-packet-format.md @@ -3,7 +3,17 @@ # Cells (messages on channels) {#cell-packet-format} The basic unit of communication for onion routers and onion -proxies is a fixed-width "cell". +proxies is a "cell". + +Once a TLS connection is established, the two sides send cells +to one another. Cells are sent serially. Standard +cells are CELL_LEN(link_proto) bytes long, but variable-length cells +also exist. + +Cells may be sent embedded in TLS records +of any size or divided across TLS records, but the framing of TLS +records MUST NOT leak information about the type or contents of the +cells. On a version 1 connection, each cell contains the following fields: diff --git a/spec/tor-spec/channels-tls.md b/spec/tor-spec/channels-tls.md index b0da826..21087ca 100644 --- a/spec/tor-spec/channels-tls.md +++ b/spec/tor-spec/channels-tls.md @@ -1,232 +1,41 @@ -# The TLS handshake +# Channels and TLS {#tls} -<!-- TODO: Revise the rest of this section. --> +Here we describe the primary TLS behavior +used by Tor relays and clients. +There are older versions of these handshakes, +which we describe in [another section](./obsolete-channels.md). -Connections between two Tor relays, or between a client and a relay, -use TLS/SSLv3 for link authentication and encryption. All -implementations MUST support the SSLv3 ciphersuite -"TLS_DHE_RSA_WITH_AES_128_CBC_SHA" if it is available. They SHOULD -support better ciphersuites if available. +## The "in-protocol" or "v3" handshake {#in-protocol} -There are three ways to perform TLS handshakes with a Tor server. In -the first way, "certificates-up-front", both the initiator and -responder send a two-certificate chain as part of their initial -handshake. (This is supported in all Tor versions.) In the second -way, "renegotiation", the responder provides a single certificate, -and the initiator immediately performs a TLS renegotiation. (This is -supported in Tor 0.2.0.21 and later.) And in the third way, -"in-protocol", the initial TLS negotiation completes, and the -parties bootstrap themselves to mutual authentication via use of the -Tor protocol without further TLS handshaking. (This is supported in -0.2.3.6-alpha and later.) +To select this handshake, +the initiator ensures that their ciphersuite list contains +at least one ciphersuite other than +[those that indicate the obsolete v1 handshake](./obsolete-channels.md#v1-ciphersuite-list). +(This is trivially achieved +by using any modern TLS implementation, +and most implementations will not need to worry about it.) -Each of these options provides a way for the parties to learn it is -available: a client does not need to know the version of the Tor -server in order to connect to it properly. +Once the TLS handshake is completed, +the initiator proceeds to negotiate a protocol version +and perform authentication +by using a series of in-channel cells, +described in the [next section](./negotiating-channels.md). -In "certificates up-front" (a.k.a "the v1 handshake"), -the connection initiator always sends a -two-certificate chain, consisting of an X.509 certificate using a -short-term connection public key and a second, self-signed X.509 -certificate containing its identity key. The other party sends a similar -certificate chain. The initiator's ClientHello MUST NOT include any -ciphersuites other than: - -```text - TLS_DHE_RSA_WITH_AES_256_CBC_SHA - TLS_DHE_RSA_WITH_AES_128_CBC_SHA - SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA -``` - -In "renegotiation" (a.k.a. "the v2 handshake"), -the connection initiator sends no certificates, and -the responder sends a single connection certificate. Once the TLS -handshake is complete, the initiator renegotiates the handshake, with each -party sending a two-certificate chain as in "certificates up-front". -The initiator's ClientHello MUST include at least one ciphersuite not in -the list above -- that's how the initiator indicates that it can -handle this handshake. For other considerations on the initiator's -ClientHello, see [Picking TLS ciphersuites](#picking-tls-ciphersuites}. - -In "in-protocol" (a.k.a. "the v3 handshake"), the initiator sends no -certificates, and the -responder sends a single connection certificate. The choice of -ciphersuites must be as in a "renegotiation" handshake. There are -additionally a set of constraints on the connection certificate, -which the initiator can use to learn that the in-protocol handshake -is in use. Specifically, at least one of these properties must be -true of the certificate: - -```text - * The certificate is self-signed - * Some component other than "commonName" is set in the subject or - issuer DN of the certificate. - * The commonName of the subject or issuer of the certificate ends - with a suffix other than ".net". - * The certificate's public key modulus is longer than 1024 bits. -``` - -The initiator then sends a VERSIONS cell to the responder, which then -replies with a VERSIONS cell; they have then negotiated a Tor -protocol version. Assuming that the version they negotiate is 3 or higher -(the only ones specified for use with this handshake right now), the -responder sends a CERTS cell, an AUTH_CHALLENGE cell, and a NETINFO -cell to the initiator, which may send either CERTS, AUTHENTICATE, -NETINFO if it wants to authenticate, or just NETINFO if it does not. - -For backward compatibility between later handshakes and "certificates -up-front", the ClientHello of an initiator that supports a later -handshake MUST include at least one ciphersuite other than those listed -above. The connection responder examines the initiator's ciphersuite list -to see whether it includes any ciphers other than those included in the -list above. If extra ciphers are included, the responder proceeds as in -"renegotiation" and "in-protocol": it sends a single certificate and -does not request -client certificates. Otherwise (in the case that no extra ciphersuites -are included in the ClientHello) the responder proceeds as in -"certificates up-front": it requests client certificates, and sends a -two-certificate chain. In either case, once the responder has sent its -certificate or certificates, the initiator counts them. If two -certificates have been sent, it proceeds as in "certificates up-front"; -otherwise, it proceeds as in "renegotiation" or "in-protocol". - -To decide whether to do "renegotiation" or "in-protocol", the -initiator checks whether the responder's initial certificate matches -the criteria listed above. - -All new relay implementations of the Tor protocol MUST support -backwards-compatible renegotiation; clients SHOULD do this too. If -this is not possible, new client implementations MUST support both -"renegotiation" and "in-protocol" and use the router's -published link protocols list (see dir-spec.txt on the "protocols" entry) -to decide which to use. - -In all of the above handshake variants, certificates sent in the clear -SHOULD NOT include any strings to identify the host as a Tor relay. In -the "renegotiation" and "backwards-compatible renegotiation" steps, the -initiator SHOULD choose a list of ciphersuites and TLS extensions -to mimic one used by a popular web browser. - -Even though the connection protocol is identical, we will think of the -initiator as either an onion router (OR) if it is willing to relay -traffic for other Tor users, or an onion proxy (OP) if it only handles -local requests. Onion proxies SHOULD NOT provide long-term-trackable -identifiers in their handshakes. - -In all handshake variants, once all certificates are exchanged, all -parties receiving certificates must confirm that the identity key is as -expected. If the key is not as expected, the party must close the -connection. - -(When initiating a connection, if a reasonably live consensus is -available, then the expected identity key is taken from that -consensus. But when initiating a connection otherwise, the expected -identity key is the one given in the hard-coded authority or -fallback list. Finally, when creating a connection because of an -EXTEND/EXTEND2 cell, the expected identity key is the one given in -the cell.) - -When connecting to an OR, all parties SHOULD reject the connection if that -OR has a malformed or missing certificate. When accepting an incoming -connection, an OR SHOULD NOT reject incoming connections from parties with -malformed or missing certificates. (However, an OR should not believe -that an incoming connection is from another OR unless the certificates -are present and well-formed.) - -\[Before version 0.1.2.8-rc, ORs rejected incoming connections from ORs and -OPs alike if their certificates were missing or malformed.\] - -Once a TLS connection is established, the two sides send cells -(specified below) to one another. Cells are sent serially. Standard -cells are CELL_LEN(link_proto) bytes long, but variable-length cells -also exist; see [Cell Packet format](./cell-packet-format.md#cell-packet-format). -Cells may be sent embedded in TLS records -of any size or divided across TLS records, but the framing of TLS -records MUST NOT leak information about the type or contents of the -cells. - -TLS connections are not permanent. Either side MAY close a connection -if there are no circuits running over it and an amount of time -(KeepalivePeriod, defaults to 5 minutes) has passed since the last time -any traffic was transmitted over the TLS connection. Clients SHOULD -also hold a TLS connection with no circuits open, if it is likely that a -circuit will be built soon using that connection. - -Client-only Tor instances are encouraged to avoid using handshake -variants that include certificates, if those certificates provide -any persistent tags to the relays they contact. If clients do use -certificates, they SHOULD NOT keep using the same certificates when -their IP address changes. Clients MAY send certificates using any -of the above handshake variants. - -<a id="tor-spec.txt-2.1"></a> - -## Picking TLS ciphersuites {#picking-tls-ciphersuites} - -Clients SHOULD send a ciphersuite list chosen to emulate some popular -web browser or other program common on the internet. Clients may send -the "Fixed Cipheruite List" below. If they do not, they MUST NOT -advertise any ciphersuite that they cannot actually support, unless that -cipher is one not supported by OpenSSL 1.0.1. - -The fixed ciphersuite list is: - -```text - TLS1_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - TLS1_ECDHE_RSA_WITH_AES_256_CBC_SHA - TLS1_DHE_RSA_WITH_AES_256_SHA - TLS1_DHE_DSS_WITH_AES_256_SHA - TLS1_ECDH_RSA_WITH_AES_256_CBC_SHA - TLS1_ECDH_ECDSA_WITH_AES_256_CBC_SHA - TLS1_RSA_WITH_AES_256_SHA - TLS1_ECDHE_ECDSA_WITH_RC4_128_SHA - TLS1_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - TLS1_ECDHE_RSA_WITH_RC4_128_SHA - TLS1_ECDHE_RSA_WITH_AES_128_CBC_SHA - TLS1_DHE_RSA_WITH_AES_128_SHA - TLS1_DHE_DSS_WITH_AES_128_SHA - TLS1_ECDH_RSA_WITH_RC4_128_SHA - TLS1_ECDH_RSA_WITH_AES_128_CBC_SHA - TLS1_ECDH_ECDSA_WITH_RC4_128_SHA - TLS1_ECDH_ECDSA_WITH_AES_128_CBC_SHA - SSL3_RSA_RC4_128_MD5 - SSL3_RSA_RC4_128_SHA - TLS1_RSA_WITH_AES_128_SHA - TLS1_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA - TLS1_ECDHE_RSA_WITH_DES_192_CBC3_SHA - SSL3_EDH_RSA_DES_192_CBC3_SHA - SSL3_EDH_DSS_DES_192_CBC3_SHA - TLS1_ECDH_RSA_WITH_DES_192_CBC3_SHA - TLS1_ECDH_ECDSA_WITH_DES_192_CBC3_SHA - SSL3_RSA_FIPS_WITH_3DES_EDE_CBC_SHA - SSL3_RSA_DES_192_CBC3_SHA - [*] The "extended renegotiation is supported" ciphersuite, 0x00ff, is - not counted when checking the list of ciphersuites. -``` - -If the client sends the Fixed Ciphersuite List, the responder MUST NOT -select any ciphersuite besides TLS_DHE_RSA_WITH_AES_256_CBC_SHA, -TLS_DHE_RSA_WITH_AES_128_CBC_SHA, and SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: -such ciphers might not actually be supported by the client. - -If the client sends a v2+ ClientHello with a list of ciphers other then -the Fixed Ciphersuite List, the responder can trust that the client -supports every cipher advertised in that list, so long as that ciphersuite -is also supported by OpenSSL 1.0.1. - -Responders MUST NOT select any TLS ciphersuite that lacks ephemeral keys, -or whose symmetric keys are less then KEY_LEN bits, or whose digests are -less than HASH_LEN bits. Responders SHOULD NOT select any SSLv3 -ciphersuite other than the DHE+3DES suites listed above. +Once that negotiation is complete, +the channel is Open and regular cells may be sent. <a id="tor-spec.txt-2.2"></a> ## TLS security considerations -Implementations MUST NOT allow TLS session resumption -- it can +(Standard TLS security guarantees apply; +this is not a comprehensive guide.) + +Implementations SHOULD NOT allow TLS session resumption -- it can exacerbate some attacks (e.g. the "Triple Handshake" attack from Feb 2013), and it plays havoc with forward secrecy guarantees. Implementations SHOULD NOT allow TLS compression -- although we don't know a way to apply a CRIME-style attack to current Tor directly, it's a waste of resources. + diff --git a/spec/tor-spec/channels.md b/spec/tor-spec/channels.md index 8daa3c4..dc05506 100644 --- a/spec/tor-spec/channels.md +++ b/spec/tor-spec/channels.md @@ -43,20 +43,38 @@ and will reject the channel if the target relay cannot cryptographically prove ownership of those identities. -Opening a channel is a two-step process. -First, the initiator opens -a new TLS session with certain properties, -and the responding relay checks and enforces those properties. -Then, the initiator and responder -exchange messages over this TLS session -in order to establish their identity or identities. +> (When initiating a connection, if a reasonably live consensus is +> available, then the expected identity key is taken from that +> consensus. But when initiating a connection otherwise, the expected +> identity key is the one given in the hard-coded authority or +> fallback list. Finally, when creating a connection because of an +> EXTEND/EXTEND2 cell, the expected identity key is the one given in +> the cell.) -> Historical note: -> In this section we will describe only the current handshake, -> called the "v3" or "in-protocol" handshake, -> first introduced in Tor 0.2.3.6-alpha. -> There are two earlier variations, -> now obsolete, -> which we will explain [elsewhere](#XXXX). +<!-- TODO: Integrate that paragraph better, or put it in a better place. --> + +Opening a channel is multi-step process: + +1. The initiator opens + a new TLS session with certain properties, + and the responding relay checks and enforces those properties. +2. Both parties + exchange messages over this TLS session + in order to establish their identity or identities. +3. Both parties verify that the identities that they received + are the ones that they expected. + (If any expected key is missing or not as expected, + the party MUST close the connection.) + +Once this is done, the channel is Open, +and regular cells can be exchanged. +## Channel lifetime +Channels are not permanent. +Either side MAY close a channel if there are no circuits running on it +and an amount of time (KeepalivePeriod, defaults to 5 minutes) +has passed since the last time any traffic was transmitted over it. +Clients SHOULD +also hold a TLS connection with no circuits open, if it is likely that a +circuit will be built soon using that connection. diff --git a/spec/tor-spec/obsolete-channels.md b/spec/tor-spec/obsolete-channels.md new file mode 100644 index 0000000..dd432c7 --- /dev/null +++ b/spec/tor-spec/obsolete-channels.md @@ -0,0 +1,160 @@ +# Obsolete channel handshakes + +These handshake variants are no longer in use. +Channel initiators MUST NOT send them. +Relays MAY detect and reject them. + +> If you are experienced with TLS, +> you will find some aspects of this handshake +> strange or obfuscated. +> Several historical factors led to its current state. +> +> First, before the development of +> [pluggable transports](../pt-spec/), +> Tor tried to avoid censorship by mimicking the behavior +> of a web client negotiating HTTPS with a web server. +> If we wanted a secure option that was not in common use, +> we had to hide our use of that option. +> +> Second, prior to the introduction of +> [TLS 1.3](https://datatracker.ietf.org/doc/html/rfc8446), +> many more aspects of the handshake +> (such as the number and nature of certificates sent by each party) +> were sent in the clear, +> and were easy to distinguish. +> +> Third, prior to the introduction of TLS 1.3, +> there was no good encrypted signalling mechanism +> that a client could use to declare +> how it wanted the rest of the TLS handshake to proceed. +> Thus, we wound up using the client's list +> of supported ciphersuites +> to send a signal about which variation of the handshake is in use. + + +### Version 1, or "certificates up front" {#v1-handshake} + +With this obsolete handshake, +the responding relay proves ownership of an RSA identity (`KP_relayid_rsa`), +and the initiator also proves ownership of an RSA identity. + +(If the initiator does not have an RSA identity to prove, +it invents one and throws it away afterwards.) + +To select this handshake, +the initiator starts a TLS handshake +containing no ciphersuites other than these: + +<a id="v1-ciphersuite-list"></a> +```text + TLS_DHE_RSA_WITH_AES_256_CBC_SHA + TLS_DHE_RSA_WITH_AES_128_CBC_SHA + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA +``` + +> Note that because of this list, +> it is impossible to use this obsolete handshake +> with TLS 1.3. + + +As part of the TLS handshake, +the initiator sends a two-certificate chain, +consisting of an X.509 certificate +for its short-term connection public key (`KP_legacy_conn_tls`) +signed by `KP_relayid_rsa`, and +a second self-signed X.509 certificate containing `KP_relayid_rsa`. +The responder sends a similar +certificate chain. + +Once the TLS handshake is done, +both parties validate each other's certificate chains. +If they are valid, +then the connection is Open, +and both parties may start exchanging [cells](./cell-packet-format.md). + +## Version 2, or "renegotiation" {#v2-handshake} + +In "renegotiation" (a.k.a. "the v2 handshake"), +the connection initiator selects at least one ciphersuite +not in the [list above](#v1-ciphersuite-list). +The initiator sends no certificates, and +the responder sends a single connection certificate in return. + +(If the responder sends a certificate chain, +the initiator assumes that it only knows about the v1 handshake.) + +Once this initial TLS handshake is complete, +the initiator renegotiates the session. +During the renegotiation, +each party sends a two-certificate chain +as in the ["certificates up front"](#v1-handshake) handshake above. + +## Indicating support for the in-protocol handshake + +When the in-protocol handshake was new, +we placed a set of constraints on the certificate that the responder would send +to indicate that it supported the v3 handshake. + +Specifically, if at least one of these properties +was true of the responders's certificate, +the initiator could be sure that the responder supported +the in-protocol handshake: + +- The certificate is self-signed +- Some component other than "commonName" is set in the subject or + issuer DN of the certificate. +- The commonName of the subject or issuer of the certificate ends + with a suffix other than ".net". +- The certificate's public key modulus is longer than 1024 bits. + +Otherwise, the initiator would assume +that only the v2 protocol was in use. + +## Fixed ciphersuite list {#fixed-cipehrsuite-list} + +For a long time, clients would advertise +a certain "fixed ciphersuite list" +regardless of whether they actually supported those ciphers. + +That list is: + +```text + TLS1_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + TLS1_ECDHE_RSA_WITH_AES_256_CBC_SHA + TLS1_DHE_RSA_WITH_AES_256_SHA + TLS1_DHE_DSS_WITH_AES_256_SHA + TLS1_ECDH_RSA_WITH_AES_256_CBC_SHA + TLS1_ECDH_ECDSA_WITH_AES_256_CBC_SHA + TLS1_RSA_WITH_AES_256_SHA + TLS1_ECDHE_ECDSA_WITH_RC4_128_SHA + TLS1_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + TLS1_ECDHE_RSA_WITH_RC4_128_SHA + TLS1_ECDHE_RSA_WITH_AES_128_CBC_SHA + TLS1_DHE_RSA_WITH_AES_128_SHA + TLS1_DHE_DSS_WITH_AES_128_SHA + TLS1_ECDH_RSA_WITH_RC4_128_SHA + TLS1_ECDH_RSA_WITH_AES_128_CBC_SHA + TLS1_ECDH_ECDSA_WITH_RC4_128_SHA + TLS1_ECDH_ECDSA_WITH_AES_128_CBC_SHA + SSL3_RSA_RC4_128_MD5 + SSL3_RSA_RC4_128_SHA + TLS1_RSA_WITH_AES_128_SHA + TLS1_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA + TLS1_ECDHE_RSA_WITH_DES_192_CBC3_SHA + SSL3_EDH_RSA_DES_192_CBC3_SHA + SSL3_EDH_DSS_DES_192_CBC3_SHA + TLS1_ECDH_RSA_WITH_DES_192_CBC3_SHA + TLS1_ECDH_ECDSA_WITH_DES_192_CBC3_SHA + SSL3_RSA_FIPS_WITH_3DES_EDE_CBC_SHA + SSL3_RSA_DES_192_CBC3_SHA + [*] The "extended renegotiation is supported" ciphersuite, 0x00ff, is + not counted when checking the list of ciphersuites. +``` + +When encountering this list, +a responder would not select any ciphersuites +besides the mandatory-to-implement +TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, +and SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA. + +Clients no longer report ciphers that they do not support. diff --git a/spec/tor-spec/relay-keys.md b/spec/tor-spec/relay-keys.md index 6434b78..cca5a2f 100644 --- a/spec/tor-spec/relay-keys.md +++ b/spec/tor-spec/relay-keys.md @@ -132,7 +132,7 @@ There are two current kinds of circuit extension keys: circuit extension handshake. -## Channel authentication +## Channel authentication {#auth} There are other keys that relays use to authenticate as part of their [./channels.md](channel negotiation handshakes). @@ -145,11 +145,10 @@ and SHOULD rotate them frequently—typically, at least once a day. handshake distinction. As it stands I'm not at all sure I can describe them correctly. --> -- `KP_conn_tls`, `KS_conn_tls`: +- `KP_legacy_conn_tls`, `KS_legacy_conn_tls`: A short-term RSA "Connection key" used to negotiate TLS connections. Tor implementations MAY rotate this key as often as they like, and SHOULD rotate this key at least once a day. - `KP_conn_tls`, `KS_conn_tls`. - `KP_link_ed`, `KS_link_ed`. A short-term Ed25519 "link authentication" key, used to authenticate |