Overwrite boringSSL's default key exchange preferences with safe
defaults using feature flags:
* "kx-pq-supported" enables support for PQ key exchange algorithms.
Classical key exchange is still preferred, but will be upgraded to PQ
if requested.
* "kx-pq-preferred" enables preference for PQ key exchange,
with fallback to classical key exchange if requested.
* "kx-nist-required" disables non-NIST key exchange.
Each feature implies "kx-safe-default". When this feature is enabled,
don't compile bindings for `SSL_CTX_set1_curves()` and `SslCurve`. This
is to prevent the feature flags from silently overriding curve
preferences chosen by the user.
Ideally we'd allow both: that is, use "kx-*" to set defaults, but still
allow the user to manually override them. However, this doesn't work
because by the time the `SSL_CTX` is constructed, we don't yet know
whether we're the client or server. (The "kx-*" features set different
preferences for each.) If "kx-sfe-default" is set, then the curve
preferences are set just before initiating a TLS handshake
(`SslStreamBuilder::connect()`) or waiting for a TLS handshake
(`SslStreamBuilder::accept()`).
This commit modifies the Cargo `include` field for `boring-sys` to
include all the files necessary to actually build the FIPS-certified
revision of BoringSSL. Currently, some of these files are missing (see
#157 for details on this).
This branch improves on my previous approach in PR #158, which switched
from using a Cargo `include` to a Cargo `exclude`. Using `exclude`
rather than `include` resulted in a much larger crates.io package, but
at the time, I thought this was less likely to result in breakage in the
future, because I was concerned about the inability to verify that the
set of excludes/includes can build a new pinned `boringssl` git revision
without having to actually publish a crates.io release.
However, as @nox pointed out in [this comment][1], `cargo package` can
be used to verify a build with the `exclude`s/`include`s applied. This
branch therefore adds `cargo package` steps to CI that check that the
package can actually be built. This way, we are able to make a much
smaller change to the included files, resulting in a smaller package
published to crates.io.
On this branch, the package is 6.7MiB compressed, which is not much
larger than it was previously:
```
Finished dev [unoptimized + debuginfo] target(s) in 55.65s
Packaged 1851 files, 33.7MiB (6.7MiB compressed)
```
Fixes#157Closes#158
[1]: https://github.com/cloudflare/boring/pull/158#issuecomment-1693067112,
This was originally going to be fixed by #101, however that PR was closed and superseded by #117, which was missing this fix.
The original problem was caused by #97, which updated boringssl to a version that included [a change that removed hmac.h from ssl.h](05b360d797).
This PR adds an include for hmac.h, so it is again available through boring-sys.
Previously we were building from the deps directory with submodules. For publishing we were copying files in sumbodules into the package. With this we were making the package directory dirty with build artifacts and applied patches.
This commit change the build script's behaviour: sources are now copied to the output directory and then boringssl is built from there.
In addition, this commit adds files that were missing from the package for building with patches.
This longer path (inside the prebuilt toolchain included in the NDK)
has been the preferred sysroot since NDK r19. Newer NDKs no longer
have a top-level "sysroot" directory at all.
Cross-compiling to AArch64 Linux can be done with a CMake toolchain
file, along with setting the correct compiler and include paths in the
environment.
Cross-compiling from X64 Windows to ARM64 Windows doesn't look at the
toolchain at all, because CMake + Visual Studio can already
cross-compile. Unfortunately, the Visual Studio CMake generator
doesn't set CMAKE_SYSTEM_PROCESSOR, which is what the BoringSSL
CMakeLists.txt is looking at to choose the architecture. For now,
disable the use of assembly when cross-compiling on Windows (assuming
that the Visual Studio generator will be used there).
As pointed out in the comment, bindgen generates tests that cause
compiler warnings about misaligned references. bindgen people are
aware of the issue, but we have to deal with our warnings that are
treated as errors. For the time being, suppress alignment tests
on platforms that are known to be triggering UB.
I suspect that other non-x86 platforms are affected as well, but I can't
get the tests to compile for those tests at the moment, so I'm not sure.
Dealing with the issues one platform at a time.
cfg!() is evaluated for the host OS executing build.rs script.
What we need here is to look whether we are building *for* macOS.
Otherwise, for example, builds for iOS on macOS will try to add this
flag, causing warnings since rustc does not build cdylibs on iOS.
When bindgen generates bindings for iOS, it must be told to use iOS
sysroot with all the standard C headers. Otherwise it tries using
the host macOS headers and fails miserably.
The architecture alone is not enough. aarch64-apple-ios and
aarch-apple-ios-sim are both building for aarch64, but they need
slightly different CMake flags.
* Add rerun-if-env-changed instructions for BORING_* variables
* Use X509_get0_notBefore() and X509_get0_notAfter() instead of X509_getm_notBefore() and X509_getm_notAfter().
According to
https://www.openssl.org/docs/man1.1.0/man3/X509_getm_notBefore.html,
"X509_getm_notBefore() and X509_getm_notAfter() are similar to
X509_get0_notBefore() and X509_get0_notAfter() except they return
non-constant mutable references to the associated date field of the
certificate".
* Only update boringssl submodule if BORING_BSSL_PATH not provided
* Allow BORING_BSSL_LIB_PATH to control link search
* Add fips feature
* Use X509_set_notAfter unconditionally for FIPS compatibility
This is equivalent according to
https://boringssl.googlesource.com/boringssl/+/c947efabcbc38dcf93e8ad0e6a76206cf0ec8072
The version of boringssl that's FIPS-certified doesn't have `X509_set1_notAfter`.
The only difference between that and `X509_set_notAfter` is whether they're const-correct,
which doesn't seem worth having two different code-paths.
* Check out fips commit automatically
* Verify the version of the compiler used for building boringssl
NIST specifies that it needs to be 7.0.1; I originally tried building with clang 10 and it failed.
Theoretically this should check the versions of Go and Ninja too, but they haven't given me trouble in practice.
Example error:
```
Compiling boring-sys v1.1.1 (/home/jnelson/work/boring/boring-sys)
error: failed to run custom build command for `boring-sys v1.1.1 (/home/jnelson/work/boring/boring-sys)`
Caused by:
process didn't exit successfully: `/home/jnelson/work/boring/target/debug/build/boring-sys-31b8ce53031cfd83/build-script-build` (exit status: 101)
--- stdout
cargo:rerun-if-env-changed=BORING_BSSL_PATH
--- stderr
warning: missing clang-7, trying other compilers: Permission denied (os error 13)
warning: FIPS requires clang version 7.0.1, skipping incompatible version "clang version 10.0.0-4ubuntu1 "
thread 'main' panicked at 'unsupported clang version "cc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0": FIPS requires clang 7.0.1', boring-sys/build.rs:216:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
* Add Github actions workflow testing FIPS
Co-authored-by: Joshua Nelson <jnelson@cloudflare.com>