Save and restore errors when ignoring ssl_send_alert result.

Out-of-band errors, the UNIX gift that keeps on giving...

We almost always ignore the result of ssl_send_alert, treating it as
largely a "best effort". Sending an alert is the only place in the TLS
stack where we call back to user code with state in the error queue. (If
we've put something in the error queue, it means we are in the process
of failing an operation.) That user code may mess up state by, say,
calling ERR_clear_error.

In particular, if the underlying BIO is implemented with SSL_write, as
in TLS tunneled over an HTTPS proxy, the call to SSL_write will
ERR_clear_error and clobber our error state. (SSL_write must
ERR_clear_error so that SSL_get_error works. This is one of the few
places we are sensitive to clearing the error queue.)

Split ssl_send_alert into a low-level ssl_send_alert_impl (for the two
places we do honor the return value) an ssl_send_alert wrapper which
saves and restores the error queue across the call, more explicitly
ignoring the return value.

This is intended as a minimal fix to https://crbug.com/959305, in case
we need to merge it to a release branch. As a follow-up, I plan to
rework the handshake state machine so it never calls ssl_send_alert,
instead returning the alert as part of the error. This is the last bit
of I/O still in the handshake. (We have the out_alert calling
convention, but I'm thinking it's worth a small sum type where the error
branch has an alert so we don't forget to supply one everywhere.

Update-Note: This changes our behavior when sending an alert fails.
Bug: chromium:959305
Change-Id: I24033205ad0f7ebd1797964489e4d46414a3e7ec
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/35904
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
4 files changed
tree: 59758b81eb6daac7a6991875149869926d6ed2e0
  1. .github/
  2. crypto/
  3. decrepit/
  4. fipstools/
  5. fuzz/
  6. include/
  7. ssl/
  8. third_party/
  9. tool/
  10. util/
  11. .clang-format
  12. .gitignore
  13. API-CONVENTIONS.md
  14. BREAKING-CHANGES.md
  15. BUILDING.md
  16. CMakeLists.txt
  17. codereview.settings
  18. CONTRIBUTING.md
  19. FUZZING.md
  20. go.mod
  21. INCORPORATING.md
  22. LICENSE
  23. PORTING.md
  24. README.md
  25. sources.cmake
  26. 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.

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