Add a test for a subtle corner of 0-RTT and version tracking

This is a huge mess. I was trying to simplify our version state to be:

- Version not known
- Version not known but sending 0-RTT at V
- Version known to be V

But it turns out we can actually have both early version and true
versions existing and at different values. There are two cases:

1. We send TLS 1.3 early data and get back a TLS 1.2 ServerHello. We
   will return an error but, at least right now, we continue to present
   a self-consistent TLS 1.3 picture, even though we send the
   protocol_version alert at TLS 1.2.

2. [Does not exist yet] We send TLS 1.4 early data and get back a TLS
   1.3 ServerHello. This isn't even fatal to the connection, so we
   especially should keep reporting the early session until
   SSL_reset_early_Data_reject.

Case 2 is extra weird because we won't actually immediately flag the
mismatch as a 0-RTT reject! Right now we don't run the reject ceremony
until we read EncryptedExtensions, but at that point we'll have even
decrypted a record under the other version.

But this case also doesn't exist today. There is an analogous thing that
does exist today with the cipher suite. For both the version and the
cipher suite, we get around this right now by having the SSLAEADContext
hold on to this information, so we pull it out of there.

We could instead run the rejection ceremony at multiple points in the
handshake, as soon as we detect any kind of inconsistency. Not sure
which is best. Either way, let's test this case.

Change-Id: I333175b25ba35261e1dd7d02e9ec1d9f1d43ff73
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/71531
Reviewed-by: Nick Harper <nharper@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
2 files changed
tree: 77ea104da01877545b1287dca9e2d6db5eeb2f98
  1. .bcr/
  2. .github/
  3. cmake/
  4. crypto/
  5. decrepit/
  6. docs/
  7. fuzz/
  8. gen/
  9. include/
  10. pki/
  11. rust/
  12. ssl/
  13. third_party/
  14. tool/
  15. util/
  16. .bazelignore
  17. .bazelrc
  18. .clang-format
  19. .gitignore
  20. API-CONVENTIONS.md
  21. BREAKING-CHANGES.md
  22. BUILD.bazel
  23. build.json
  24. BUILDING.md
  25. CMakeLists.txt
  26. codereview.settings
  27. CONTRIBUTING.md
  28. FUZZING.md
  29. go.mod
  30. go.sum
  31. INCORPORATING.md
  32. LICENSE
  33. MODULE.bazel
  34. MODULE.bazel.lock
  35. PORTING.md
  36. PrivacyInfo.xcprivacy
  37. README.md
  38. SANDBOXING.md
  39. STYLE.md
README.md

BoringSSL

BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.

Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.

Programs ship their own copies of BoringSSL when they use it and we update everything as needed when deciding to make API changes. This allows us to mostly avoid compromises in the name of compatibility. It works for us, but it may not work for you.

BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved in maintaining all these patches in multiple places was growing steadily.

Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the NDK) and a number of other apps/programs.

Project links:

To file a security issue, use the Chromium process and mention in the report this is for BoringSSL. You can ignore the parts of the process that are specific to Chromium/Chrome.

There are other files in this directory which might be helpful: