From a first look at 176 it looks good. Some comments and suggestions inline:
Terminological note: I use "client" below to mean the Tor instance (a client or a bridge or a relay) that initiates a TLS connection, and "server" to mean the Tor instance (a bridge or a relay) that accepts it.
There are still some initiator/responder below, which I've pointed out.
* Allow responder authentication or bidirectional authentication.
responder -> server
In other words, V2-supporting initiator behavior currently looks like this:
initiator -> client
And V2-supporting responder behavior now looks like this:
responder -> server
And the cell-based part of the V3 handshake, in summary, is:
C<->S: TLS handshake where S sends a "v3 certificate" In TLS: C->S: VERSIONS cell
I would be concerned that at some later point in the arms race, someone will block connections where the first application record doesn't look like a HTTP request. I'd therefore suggest that we permit variable length padding cells at all points, especially after the first VERSIONS cell. Then the client could pad out the first application record to a convincing length before flushing.
To check the AUTHENTICATE cell, a server checks that all fields containing a hash contain the correct value, then verifies the signature. The server MUST ignore any extra bytes in the signed data after the SHA256 hash.
I'd suggest expanding on what "correct value" means for each of the fields. Some might be obvious but others are not (e.g. TIME, which I see later on is not currently checked).
If we allow padding cells then I think we should probably include them in SLOG and CLOG.
[If we want to avoid the empty application record trick to fix the CBC vulnerability in TLS 1.0 then we could use padding cells with random data before every application record.]
A server SHOULD NOT send any sequence of cells when starting a v3 negotiation other than "VERSIONS, CERT, AUTH_CHALLENGE, NETINFO". A client SHOULD drop a CERT, AUTH_CHALLENGE, or NETINFO cell that appears at any other time or out of sequence.
A client should not begin a v3 negotiation with any sequence other than "VERSIONS, NETINFO" or "VERSIONS, CERT, AUTHENTICATE, NETINFO". A server SHOULD drop a CERT, AUTH_CHALLENGE, or NETINFO cell that appears at any other time or out of sequence.
Padding cells should be permitted.
If the client was not able to include a non-zero TLSSECRET component, or the server can't check it, the answer is a little trickier. The server knows that it is not getting a replayed AUTHENTICATE cell, since the cell authenticates (among other stuff) the server's AUTH_CHALLENGE cell, which it has never used before. The server knows that it is not getting a MITM'd AUTHENTICATE cell, since the cell includes a hash of the server's link certificate, which nobody else should have been able to use in a successful TLS negotiation.
Is a zero TLSSECRET permitted anymore?
A signature of the TLSSECRET element on its own should be sufficient to prevent the attacks we care about, but because we don't necessarily have access to the TLS master secret when using a non-C TLS library, we can't depend on it. I added it anyway so that, if there is some problem with the rest of the protocol, clients and servers that _are_ written in C (that is, the official Tor implementation) can still be secure.
Again, it looks like TLSSECRET is now mandatory.
Steven.