This makes it possible for our bogo config.json to vary
between providers. That is achieved by -- with my sincere apologies --
applying the C preprocessor.
In an effort to reduce our feature list, this commit replaces the
`dangerous_configuration` feature flag with separate `danger` modules.
Cargo features are additive, which means transitive dependencies could
enable them for you without explicit opt-in. Using obviously named
modules will maintain the property that it's easy to grep for imports,
but avoids feature flag bloat and the additive downsides.
After discussion we've chosen to not include the webpki verifier and
helper functions as part of the dangerous API surface. Functionality for
setting a custom verifier, or implementing one to make assertions about
verification status, remain marked as dangerous via their module name.
Verification error is not always raised by bad certificate, especially
in user provided verifier. For example, they may raise HSM connection
error or dynamic certificate resolve error.
All of them is not about bad certificate. So send BadCertificateAlert is
not appropriate.
Prior to this commit the `fetch-and-build` script with newer `git`
versions would spit out an ANSI coloured warning about choosing an
initial branch name for the bogo test-suite checkout.
This commit simply specifies the `--initial-branch` to be `main` to
silence the unnecessary output.
Prior to this commit some helper scripts used hardcoded paths to
`/bin/sh` and `/bin/bash` in script shebangs. This will error on systems
that don't place `bash` in `/bin/` (e.g. NixOS).
This commit updates the scripts to use `/usr/bin/env` to find `bash`
based on the user's `$PATH`. This has better portability and allows the
scripts to run without err (or specifying an interpreter explicitly) on
systems with atypical `bash` installs.
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.