Commit 67801c7b authored by David Benjamin's avatar David Benjamin
Browse files

Fix building with latest BoringSSL

This required two fixes. First,
test_verify_param_set_depth_fails_verification needed to be updated. The
history here is that OpenSSL 1.1.0 made a backwards-incompatible change
to the semantics of the depth limit. Ideally, rust-openssl would have
documented the semantics of its own APIs and normalized the behavior,
but it instead silently picked up the semantics change.

BoringSSL aligned with OpenSSL's new behavior in
b251d813ec615e7ef01d82073f94960eb13b1e0a, but since then rust-openssl
has codified the old behavior in tests. We need to update some cfgs to
reflect this.

Second, BoringSSL requires a C++ runtime (we have required a C++
compiler for a long time). This reveals a problem in Cargo's
dependency management strategy for externally-built static libraries.
Work around this by making some guesses about what library to link in,
but see the comment for why this is unsafe. This unsafety appears to be
inherent to Cargo and the choice of having Cargo drive cross-language
builds, rather than providing hooks for an integrated build system.
parent af91e4ea
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ jobs:
            - false
          library:
            - name: boringssl
              version: e6489902b7fb692875341b8ab5e57f0515f47bc1
              version: 2db0eb3f96a5756298dcd7f9319e56a98585bd10
            - name: openssl
              version: vendored
            - name: openssl
+28 −0
Original line number Diff line number Diff line
@@ -132,6 +132,34 @@ fn main() {
        println!("cargo:rustc-link-lib={}={}", kind, lib);
    }

    // libssl in BoringSSL requires the C++ runtime, and static libraries do
    // not carry dependency information. On unix-like platforms, the C++
    // runtime and standard library are typically picked up by default via the
    // C++ compiler, which has a platform-specific default. (See implementations
    // of `GetDefaultCXXStdlibType` in Clang.) Builds may also choose to
    // override this and specify their own with `-nostdinc++` and `-nostdlib++`
    // flags. Some compilers also provide options like `-stdlib=libc++`.
    //
    // Typically, such information is carried all the way up the build graph,
    // but Cargo is not an integrated cross-language build system, so it cannot
    // safely handle any of these situations. As a result, we need to make
    // guesses. Getting this wrong may result in symbol conflicts and memory
    // errors, but this unsafety is inherent to driving builds with
    // externally-built libraries using Cargo.
    //
    // For now, we guess that the build was made with the defaults. This too is
    // difficult because Rust does not expose this information from Clang, but
    // try to match the behavior for common platforms. For a more robust option,
    // this likely needs to be deferred to the caller with an environment
    // variable.
    if version == Version::Boringssl && kind == "static" && env::var("CARGO_CFG_UNIX").is_ok() {
        let cpp_lib = match env::var("CARGO_CFG_TARGET_OS").unwrap().as_ref() {
            "macos" => "c++",
            _ => "stdc++",
        };
        println!("cargo:rustc-link-lib={}", cpp_lib);
    }

    // https://github.com/openssl/openssl/pull/15086
    if version == Version::Openssl3xx
        && kind == "static"
+1 −1
Original line number Diff line number Diff line
@@ -944,7 +944,7 @@ fn test_verify_param_set_depth_fails_verification() {
    store_bldr.add_cert(ca).unwrap();
    let mut verify_params = X509VerifyParam::new().unwrap();
    // OpenSSL 1.1.0+ considers the root certificate to not be part of the chain, while 1.0.2 and LibreSSL do
    let expected_depth = if cfg!(any(ossl110)) { 0 } else { 1 };
    let expected_depth = if cfg!(any(ossl110, boringssl)) { 0 } else { 1 };
    verify_params.set_depth(expected_depth);
    store_bldr.set_param(&verify_params).unwrap();
    let store = store_bldr.build();