aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2023-11-11 21:57:53 -0500
committerNick Mathewson <nickm@torproject.org>2023-11-11 22:05:07 -0500
commit46f947115f4cce14b7b2368a414c765fc18e86b4 (patch)
treeb0c69346efa722a145ed9bcb6e88a96c489880dd
parenta602166da2fffe55e882dd7879ecd82994996a45 (diff)
downloadtorspec-46f947115f4cce14b7b2368a414c765fc18e86b4.tar.gz
torspec-46f947115f4cce14b7b2368a414c765fc18e86b4.zip
Finish revising the channel handshake
-rw-r--r--spec/tor-spec/negotiating-channels.md280
-rw-r--r--spec/tor-spec/obsolete-channels.md53
-rw-r--r--spec/tor-spec/preliminaries.md2
-rw-r--r--spec/tor-spec/subprotocol-versioning.md2
4 files changed, 211 insertions, 126 deletions
diff --git a/spec/tor-spec/negotiating-channels.md b/spec/tor-spec/negotiating-channels.md
index cf559a4..dfe82df 100644
--- a/spec/tor-spec/negotiating-channels.md
+++ b/spec/tor-spec/negotiating-channels.md
@@ -265,7 +265,6 @@ then any relay which can prove it has the the identity `KP_relayid_ed`
also has the legacy identity `KP_relayid_rsa`.
-
<a id="tor-spec.txt-4.3"></a>
## AUTH_CHALLENGE cells{#AUTH-CHALLENGE-cells}
@@ -279,157 +278,158 @@ fields:
| N_Methods | 2 octets
| Methods | 2 * N_Methods octets
-It is sent from the responder to the initiator. Initiators MUST
-ignore unexpected bytes at the end of the cell. Responders MUST
-generate every challenge independently using a strong RNG or PRNG.
+It is sent from the responder to the initiator.
+Initiators MUST ignore unexpected bytes at the end of the cell.
+Responders MUST generate every challenge independently.
+
+The Challenge field is
+a [randomly generated](./preliminaries.md#random-values)
+binary string that the initiator must sign (a hash of)
+as part of their [AUTHENTICATE cell](#AUTHENTICATE-cells).
+
+The Methods are a list of authentication methods
+that the responder will accept.
+These methods are defined:
+
+| Type | Method |
+| --------- | ------ |
+| `[00 01]` | [RSA-SHA256-TLSSecret] (Obsolete) |
+| `[00 02]` | (Historical, never implemented) |
+| `[00 03]` | [Ed25519-SHA256-RFC5705] |
+
-The Challenge field is a randomly generated string that the
-initiator must sign (a hash of) as part of authenticating. The
-methods are the authentication methods that the responder will
-accept. Only two authentication methods are defined right now:
-see [RSA-SHA256-TLSSecret](#RSA-SHA256-TLSSecret) and
-[Ed25519-SHA256-RFC570](#Ed25519-SHA256-RFC5705) below.
+[RSA-SHA256-TLSSecret]: ./obsolete-channels.md#RSA-SHA256-TLSSecret
+[Ed25519-SHA256-RFC5705]: #Ed25519-SHA256-RFC5705
<a id="tor-spec.txt-4.4"></a>
## AUTHENTICATE cells{#AUTHENTICATE-cells}
-If an initiator wants to authenticate, it responds to the
-AUTH_CHALLENGE cell with a CERTS cell and an AUTHENTICATE cell.
-The CERTS cell is as a server would send, except that instead of
-sending a CertType 1 (and possibly CertType 5) certs for arbitrary link
-certificates, the initiator sends a CertType 3 (and possibly
-CertType 6) cert for an RSA/Ed25519 AUTHENTICATE key.
+If an initiator wants to authenticate,
+it responds to the AUTH_CHALLENGE cell
+with a CERTS cell and an AUTHENTICATE cell.
-This difference is because we allow any link key type on a TLS
-link, but the protocol described here will only work for specific key
-types as described in
-[RSA-SHA256-TLSSecret](#RSA-SHA256-TLSSecret) and
-[Ed25519-SHA256-RFC570](#Ed25519-SHA256-RFC5705) below.
+([As discussed above](#validate-initiator-certs),
+the initiator's CERTS cell differs slightly
+from what a responder would send.)
An AUTHENTICATE cell contains the following:
| Field | Size
| ----- | ----
-| AuthType | 2 octets
-| AuthLen | 2 octets
-| Authentication | AuthLen octets
+| AuthType | 2
+| AuthLen | 2
+| Authentication | AuthLen
Responders MUST ignore extra bytes at the end of an AUTHENTICATE
-cell. Recognized AuthTypes are 1 and 3, described in the next
-two sections.
-
-Initiators MUST NOT send an AUTHENTICATE cell before they have
-verified the certificates presented in the responder's CERTS
-cell, and authenticated the responder.
-
-<a id="tor-spec.txt-4.4.1"></a>
-
-### Link authentication type 1: RSA-SHA256-TLSSecret {#RSA-SHA256-TLSSecret}
-
-If AuthType is 1 (meaning "RSA-SHA256-TLSSecret"), then the
-Authentication field of the AUTHENTICATE cell contains the following:
-
-* TYPE: The characters "AUTH0001" \[8 octets\]
-* CID: A SHA256 hash of the initiator's RSA1024 identity key \[32 octets\]
-* SID: A SHA256 hash of the responder's RSA1024 identity key \[32 octets\]
-* SLOG: A SHA256 hash of all bytes sent from the responder to the
- initiator as part of the negotiation up to and including the
- AUTH_CHALLENGE cell; that is, the VERSIONS cell, the CERTS cell,
- the AUTH_CHALLENGE cell, and any padding cells. \[32 octets\]
-* CLOG: A SHA256 hash of all bytes sent from the initiator to the
- responder as part of the negotiation so far; that is, the
- VERSIONS cell and the CERTS cell and any padding cells. \[32
- octets\]
-* SCERT: A SHA256 hash of the responder's TLS link certificate. \[32
- octets\]
-* TLSSECRETS: A SHA256 HMAC, using the TLS master secret as the
- secret key, of the following:
- - client_random, as sent in the TLS Client Hello
- - server_random, as sent in the TLS Server Hello
- - the NUL terminated ASCII string:
- "Tor V3 handshake TLS cross-certification"
- \[32 octets\]
-* RAND: A 24 byte value, randomly chosen by the initiator. (In an
- imitation of SSL3's gmt_unix_time field, older versions of Tor
- sent an 8-byte timestamp as the first 8 bytes of this field;
- new implementations should not do that.) \[24 octets\]
-* SIG: A signature of a SHA256 hash of all the previous fields
- using the initiator's "Authenticate" key as presented. (As
- always in Tor, we use OAEP-MGF1 padding; see [Ciphers](./preliminaries.md#ciphers))
- \[variable length\]
-
-To check the AUTHENTICATE cell, a responder checks that all fields
-from TYPE through TLSSECRETS contain their unique
-correct values as described above, and then verifies the signature.
-The server MUST ignore any extra bytes in the signed data after
-the RAND field.
+cell.
-Responders MUST NOT accept this AuthType if the initiator has
-claimed to have an Ed25519 identity.
+The `AuthType` value corresponds to one of the
+authentication methods.
+The initiator MUST NOT send an AUTHENTICATE cell
+whose AuthType was not contained
+in the responder's AUTH_CHALLENGE.
-(There is no AuthType 2: It was reserved but never implemented.)
+An initiator MUST NOT send an AUTHENTICATE
+cell before it has verified the certificates
+presented in the responder's CERTS cell,
+and authenticated the responder.
<a id="tor-spec.txt-4.4.2"></a>
### Link authentication type 3: Ed25519-SHA256-RFC5705 {#Ed25519-SHA256-RFC5705}
-If AuthType is 3, meaning "Ed25519-SHA256-RFC5705", the
-Authentication field of the AuthType cell is as below:
+If AuthType is `[00 03]`,
+meaning "Ed25519-SHA256-RFC5705",
+the Authentication field of the AUTHENTICE cell is as follows
Modified values and new fields below are marked with asterisks.
-* TYPE: The characters "AUTH0003" \[8 octets\]
-* CID: A SHA256 hash of the initiator's RSA1024 identity key \[32 octets\]
-* SID: A SHA256 hash of the responder's RSA1024 identity key \[32 octets\]
-* CID_ED: The initiator's Ed25519 identity key \[32 octets\]
-* SID_ED: The responder's Ed25519 identity key, or all-zero. \[32 octets\]
-* SLOG: A SHA256 hash of all bytes sent from the responder to the
- initiator as part of the negotiation up to and including the
- AUTH_CHALLENGE cell; that is, the VERSIONS cell, the CERTS cell,
- the AUTH_CHALLENGE cell, and any padding cells. \[32 octets\]
-* CLOG: A SHA256 hash of all bytes sent from the initiator to the
- responder as part of the negotiation so far; that is, the
- VERSIONS cell and the CERTS cell and any padding cells. \[32
- octets\]
-* SCERT: A SHA256 hash of the responder's TLS link certificate. \[32
- octets\]
-* TLSSECRETS: The output of an RFC5705 Exporter function on the
- TLS session, using as its inputs:
- - The label string "EXPORTER FOR TOR TLS CLIENT BINDING AUTH0003"
- - The context value equal to the initiator's Ed25519 identity key.
- - The length 32.
- \[32 octets\]
-* RAND: A 24 byte value, randomly chosen by the initiator. \[24 octets\]
-* SIG: A signature of all previous fields using the initiator's
- Ed25519 authentication key (as in the cert with CertType 6).
- \[variable length\]
-
-To check the AUTHENTICATE cell, a responder checks that all fields
-from TYPE through TLSSECRETS contain their unique
-correct values as described above, and then verifies the signature.
-The server MUST ignore any extra bytes in the signed data after
+| Field | Size | Description |
+| --------- | ---- | ----------- |
+| `TYPE` | 8 | The nonterminated string `AUTH0003` |
+| `CID` | 32 | `SHA256(KP_relayid_rsa)` for initiator |
+| `SID` | 32 | `SHA256(KP_relayid_rsa)` for responder |
+| `CID_ED` | 32 | `KP_relayid_ed` for initiator |
+| `SID_ED` | 32 | `KP_relayid_ed` for responder |
+| `SLOG` | 32 | SHA256 of responder transcript |
+| `CLOG` | 32 | SHA256 of initiator transcript |
+| `SCERT` | 32 | SHA256 of responder's TLS certificate |
+| `TLSSECRETS`|32 | RFC5705 information |
+| `RAND` | 24 | [Random bytes] |
+| `SIG` | 64 | Ed25519 signature |
+
+Notes:
+
+- For `CID` and `SID`, the SHA256 digest of an RSA key
+ is computed as the SHA256 digest of its asn.1 encoding.
+- The `SLOG` field is computed
+ as the SHA256 digest
+ of all bytes sent within the TLS channel up to and including
+ the AUTH_CHALLENGE cell.
+ - This includes the VERSIONS cell,
+ the CERTS cell,
+ the AUTH_CHALLENGE cell,
+ and any padding cells.
+- The `CLOG` field is computed
+ as the SHA256 digest
+ of all bytes sent within the TLS channel up to but not including
+ the AUTHENTICATE cell.
+ - This includes the VERSIONS cell,
+ the CERTS cell, and any padding cells.
+- The `TLSSECRETS` field is computed
+ as the output of a Keying Material Exporter function
+ on the TLS section.
+ - The parameters for this exporter are:
+ - Label string: "EXPORTER FOR TOR TLS CLIENT BINDING AUTH0003"
+ - Context value: The initiator's `KP_relayid_ed`.
+ - Length: 32.
+ - For keying material exporters on TLS 1.3,
+ see [RFC 8446 Section 7.5].
+ - For keying material exporters on older TLS versions,
+ see [RFC5705].
+- The `SIG` field is an Ed25519 signature
+ of all earlier members in the Authentication
+ (from `TYPE` through `RAND`)
+ using `KS_link_ed`.
+
+
+[Random bytes]: ./preliminaries.md#random-values
+[RFC 8446 Section 7.5]: https://datatracker.ietf.org/doc/html/rfc8446#section-7.5
+[RFC5705]: https://datatracker.ietf.org/doc/html/rfc5705.
+
+
+To check an AUTHENTICATE cell,
+a responder checks that all fields from TYPE through TLSSECRETS
+contain their unique correct values as described above,
+and then verifies the signature.
+The responder MUST ignore any extra bytes in the signed data after
the RAND field.
+<!-- TODO: We should consider removing that last sentence. -->
+
<a id="tor-spec.txt-4.5"></a>
## NETINFO cells {#NETINFO-cells}
-If version 2 or higher is negotiated, each party sends the other a
-NETINFO cell. The cell's payload is:
+To finish the handshake,
+each party sends the other
+a NETINFO cell.
+
+The cell's payload is:
| Field | Description | Size
| ----- | ----------- | ----
| TIME | Timestamp | 4 bytes
-| OTHERADDR: | Other OR's address |
+| OTHERADDR: | Other party's address |
| - ATYPE | Address type | 1 byte
| - ALEN | Address length | 1 byte
-| - AVAL | Address value in NBO | ALEN bytes
-| NMYADDR | Number of this OR's addresses | 1 byte
+| - AVAL | Address value | ALEN bytes
+| NMYADDR | Number of this party's addresses | 1 byte
| NMYADDR times: | |
| - ATYPE | Address type | 1 byte
| - ALEN | Address length | 1 byte
-| - AVAL | Address value in NBO | ALEN bytes
+| - AVAL | Address value | ALEN bytes
Recognized address types (ATYPE) are:
@@ -438,22 +438,52 @@ Recognized address types (ATYPE) are:
| 0x04 | IPv4
| 0x06 | IPv6
-ALEN MUST be 4 when ATYPE is 0x04 (IPv4) and 16 when ATYPE is 0x06
-(IPv6). If the ALEN value is wrong for the given ATYPE value, then
+Implementations SHOULD ignore addresses with unrecognized types.
+
+ALEN MUST be 4 when ATYPE is 0x04 (IPv4)
+and 16 when ATYPE is 0x06 (IPv6).
+If the ALEN value is wrong for the given ATYPE value, then
the provided address should be ignored.
-The timestamp is a big-endian unsigned integer number of seconds
-since the Unix epoch. Implementations MUST ignore unexpected bytes
-at the end of the cell. Clients SHOULD send "0" as their timestamp, to
-avoid fingerprinting.
+When sending `OTHERADDR`,
+implementations SHOULD use the actual IP address
+they have observed for the other party.
+
+> (This is typically the address passed to `connect()`
+> when acting as the channel initiator,
+> or the address received from `accept()`
+> when acting as the channel responder.)
+
+When sending the party's own addresses,
+relays SHOULD send the addresses that they have advertised
+in their router descriptors.
+Bridges and clients SHOULD send none of their own addresses.
+
+For the `TIME` field,
+relays send a (big-endian) integer
+holding the number of seconds since the Unix epoch.
+Clients SHOULD send `[00 00 00 00]` as their timestamp,
+to avoid fingerprinting.
+
+> See [proposal 338](../proposals/338-netinfo-y2038.md)
+> for a proposal to extend the timestamp to 8 bytes.
+
+Implementations MUST ignore unexpected bytes at the end of the NETINFO cell.
+
+### Using information from NETINFO cells {#using-netinfo}
Implementations MAY use the timestamp value to help decide if their
-clocks are skewed. Initiators MAY use "other OR's address" to help
-learn which address their connections may be originating from, if they do
-not know it; and to learn whether the peer will treat the current
-connection as canonical. Implementations SHOULD NOT trust these
-values unconditionally, especially when they come from non-authorities,
-since the other party can lie about the time or IP addresses it sees.
+clocks are skewed.
+
+Initiators MAY use "other OR's address" field
+to help learn which address their connections may be originating from,
+if they do not know it;
+and to learn whether the peer will treat the current connection as canonical.
+
+Implementations SHOULD NOT trust these values unconditionally,
+especially when they come from non-authorities,
+since the other party can lie about the time
+or the IP addresses it sees.
Initiators SHOULD use "this OR's address" to make sure
that they have connected to another OR at its canonical address.
diff --git a/spec/tor-spec/obsolete-channels.md b/spec/tor-spec/obsolete-channels.md
index 33874d4..52e716f 100644
--- a/spec/tor-spec/obsolete-channels.md
+++ b/spec/tor-spec/obsolete-channels.md
@@ -214,3 +214,56 @@ it would need to verify that:
not expired,
and not before their `validAfter` dates.
+
+<a id="tor-spec.txt-4.4.1"></a>
+
+## Link authentication type 1: RSA-SHA256-TLSSecret {#RSA-SHA256-TLSSecret}
+
+This is an obsolete authentication method
+used before RFC5705 support was ubiquitous.
+It is nearly the same as
+[Ed25519-SHA256-RFC5705](./negotiating-channels.md#Ed25519-SHA256-RFC5705),
+but lacks support for Ed25519,
+and does not use keying material exporters
+(which were not widely supported at the time it as used.
+
+If AuthType is `[00 01]` (meaning "RSA-SHA256-TLSSecret"),
+then the authentication field of the AUTHENTICATE
+cell contains the following:
+
+| Field | Size | Description |
+| --------- | ---- | ----------- |
+| `TYPE` | 8 | The nonterminated string `AUTH0001` |
+| `CID` | 32 | `SHA256(KP_relayid_rsa)` for initiator |
+| `SID` | 32 | `SHA256(KP_relayid_rsa)` for responder |
+| `SLOG` | 32 | SHA256 of responder transcript |
+| `CLOG` | 32 | SHA256 of initiator transcript |
+| `SCERT` | 32 | SHA256 of responder's TLS certificate |
+| `TLSSECRETS`|32 | An ad-hoc HMAC output |
+| `RAND` | 24 | [Random bytes] |
+| `SIG` | Variable | RSA signature |
+
+
+Notes are as for [Ed25519-SHA256-RFC5705],
+except as follows:
+
+
+- The `TLSSECRETS` fields holds a SHA256 HMAC,
+ using the TLS master secret as the secret key,
+ of the following concatenated fields:
+ - `client_random`, as sent in the TLS Client Hello
+ - `server_random`, as sent in the TLS Server Hello
+ - the NUL terminated ASCII string:
+ `"Tor V3 handshake TLS cross-certification"`
+* The `SIG` fields holds an RSA signature of a SHA256 hash
+ of all the previous fields
+ (that is, `TYPE` through `RAND`),
+ using the initiator's `KS_legacy_linkauth_rsa`.
+ This field extends through the end of the Authenticate message.
+
+[Random bytes]: ./preliminaries.md#random-values
+[Ed25519-SHA256-RFC5705]: ./negotiating-channels.md#Ed25519-SHA256-RFC5705
+
+Responders MUST NOT accept this AuthType if the initiator has
+claimed to have an Ed25519 identity.
+
diff --git a/spec/tor-spec/preliminaries.md b/spec/tor-spec/preliminaries.md
index 78e6e80..b8e558f 100644
--- a/spec/tor-spec/preliminaries.md
+++ b/spec/tor-spec/preliminaries.md
@@ -107,9 +107,11 @@ When we refer to "the hash of a public key", unless otherwise
specified, we mean the SHA-1 hash of the DER encoding of an ASN.1 RSA
public key (as specified in PKCS.1).
+<span id="random-values">
All "random" values MUST be generated with a cryptographically
strong pseudorandom number generator seeded from a strong entropy
source, unless otherwise noted.
+</span>
<a id="tor-spec.txt-0.4"></a>
diff --git a/spec/tor-spec/subprotocol-versioning.md b/spec/tor-spec/subprotocol-versioning.md
index 82b25c4..c9a9c76 100644
--- a/spec/tor-spec/subprotocol-versioning.md
+++ b/spec/tor-spec/subprotocol-versioning.md
@@ -83,7 +83,7 @@ the v3+ link protocols.
Current versions are:
- * "1" is the RSA link authentication described in [Link authentication type 1: RSA-SHA256-TLSSecret](./negotiating-channels.md#RSA-SHA256-TLSSecret).
+ * "1" is the RSA link authentication described in [Link authentication type 1: RSA-SHA256-TLSSecret](./obsolete-channels.md#RSA-SHA256-TLSSecret).
* "2" is unused, and reserved by proposal 244.