Builds on the previous commit, and prepares for the ability to discard
unused key exchange algorithms at link-time.
This varies some server error handling -- the precise errors aren't
specified by the standard.
This fixes the TLS13SessionID-TLS13 Bogo test, so enable it.
Inline `random_sessionid_for_ticket` into its caller so all the
session ID calculation is in one spot.
Fix the "build bogo_shim if it doesn't exist" logic; it was broken even
on Linux as newer versions of Rust don't allow `--features` to be used
at workspace level.
I had to bootstrap Go on a Linux machine using the procedure at
https://github.com/golang/go/issues/42684#issuecomment-731821237:
```
git clone https://go.googlesource.com/go
cd go
git fetch https://go.googlesource.com/go refs/changes/58/272258/1 && git checkout FETCH_HEAD
cd src
GOOS=darwin GOARCH=arm64 ./bootstrap.bash
```
This version of Go required me to have a go.mod file. Change the way Bogo is
downloaded from BoringSSL's repo to get this to work. The script now uses a
sparse checkout with depth 1, which seems pretty fast. In particular, avoid
`wget` since my Mac doesn't have `wget` available.
Remove two of the patches to Bogo that seem to not be necessary if using a
newer version of Go. Patch the remaining patch to work with the new directory
structure.
I verified that ./runme runs the tests and spits out "PASS" at the end on both macOS
and Linux.
This affects TLS1.3 client and server sessions. It does not
affect TLS1.2 sessions.
Discussion
==========
RFC8446 says of the "Middlebox Compatibility Mode" feature:
Either side can send change_cipher_spec at any time during
the handshake, as they must be ignored by the peer
This unnecessary flexibility meant we can't weave an
optional receipt of a CCS into our state machine (like we did for TLS1.2),
so we just drop CCS messages received after negotiating TLS1.3.
That's a problem, though: CCS messages are 6 bytes long, and many
can be delivered in a single TCP segment. Each one results in a
small but non-zero amount of processing.
However, this code path is fast: in benchmarks rustls can drop ~4 million
CCSs per second, per core. In the PoC code graciously provided by the
reporter, ~168Mbps of traffic needs to pass over lo to saturate a single
CPU core (you'll note these measurements agree with each other, to an order
of magnitude).
It's really likely that a better overall DoS vector is *just sending ClientHellos*,
where each core can only process ~thousands per second, for the cost of ~200 bytes;
ie 250Kbps (as an order of magnitude) to saturate one core. This is especially
powerful if TFO is supported by both hosts. But it's also more noisy.
So while this vulnerability is not thought to be serious, we can fix it
at negligible cost: only allow a maximum of one CCS per TLS1.3 handshake.
Thanks to Lenny Wang of Tencent Security Xuanwu Lab for the report.
- disable SHA1 invalid signature tests
- test for golang sending an internal error alert when
we don't offer its selected signature algorithm
- also look for 'no common signature algorithms' in SHA1 tests
- bogo_shim needs quic feature
- provide/check quic transport params in bogo_shim
- reject servers that handshake at TLS1.2, but include a quic transport
params extension.
- don't expose quic transport params extension for TLS1.2 clients.
These last two match BoringSSL.