Skip to content

Commit

Permalink
Added support for building boringssl with bindgen
Browse files Browse the repository at this point in the history
This allows building it without the bssl-sys crate. This is an alternative approach to fixing sfackler#1768 (in contrast to sfackler#1806).

This maintains support for using the bssl-sys crate.
  • Loading branch information
alex committed Mar 4, 2023
1 parent 278279f commit e43b137
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 46 deletions.
52 changes: 27 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ jobs:
- false
library:
- name: boringssl
version: 5697a9202615925696f8dc7f4e286d44d474769e
version: 93e8d4463d59d671e9c5c6171226341f04b07907
- name: openssl
version: vendored
- name: openssl
Expand Down Expand Up @@ -215,10 +215,6 @@ jobs:
library:
name: libressl
version: 3.7.0
exclude:
- library:
name: boringssl
bindgen: true
name: ${{ matrix.target }}-${{ matrix.library.name }}-${{ matrix.library.version }}-${{ matrix.bindgen }}
runs-on: ubuntu-latest
env:
Expand Down Expand Up @@ -311,24 +307,26 @@ jobs:
make install_sw
;;
"boringssl")
sed -i rust/CMakeLists.txt -e '1s%^%include_directories(../include)\n%'
cpu=`echo ${{ matrix.target }} | cut -d - -f 1`
echo "set(CMAKE_SYSTEM_NAME Linux)" > toolchain.cmake
echo "set(CMAKE_SYSTEM_PROCESSOR $cpu)" >> toolchain.cmake
echo "set(triple ${{ matrix.target }})" >> toolchain.cmake
echo 'set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} '$OS_FLAGS '" CACHE STRING "c++ flags")' >> toolchain.cmake
echo 'set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} '$OS_FLAGS '" CACHE STRING "c flags")' >> toolchain.cmake
echo 'set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} '$OS_FLAGS '" CACHE STRING "asm flags")' >> toolchain.cmake
cmake -DRUST_BINDINGS="${{ matrix.target }}" -B $OPENSSL_DIR -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake
make -C $OPENSSL_DIR
mkdir build
cd build
cmake .. -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DRUST_BINDINGS="${{ matrix.target }}" -DCMAKE_INSTALL_PREFIX="${OPENSSL_DIR}"
make -j "$(nproc)"
make install
# Copy stuff around so it's all as the build system expects.
cp -r rust/ "$OPENSSL_DIR/rust"
mkdir -p "$OPENSSL_DIR/crypto/"
mkdir -p "$OPENSSL_DIR/ssl/"
cp "$OPENSSL_DIR/lib/libcrypto.a" "$OPENSSL_DIR/crypto/"
cp "$OPENSSL_DIR/lib/libssl.a" "$OPENSSL_DIR/ssl/"
esac
if: matrix.library.version != 'vendored' && !steps.openssl-cache.outputs.cache-hit
- run: |
mkdir -p .cargo
echo '[patch.crates-io]' > .cargo/config.toml
echo 'bssl-sys = { path = "'$OPENSSL_DIR'/rust" }' >> .cargo/config.toml
if: matrix.library.name == 'boringssl'
if: matrix.library.name == 'boringssl' && !matrix.bindgen
- uses: actions/cache@v1
with:
path: ~/.cargo/registry/index
Expand All @@ -350,21 +348,25 @@ jobs:
if [[ "${{ matrix.library.version }}" == "vendored" ]]; then
features="--features vendored"
fi
if [[ "${{ matrix.bindgen }}" == "true" ]]; then
if [[ "${{ matrix.bindgen }}" == "true" && "${{ matrix.library.name }}" != "boringssl" ]]; then
features="$features --features bindgen"
fi
cargo run --manifest-path=systest/Cargo.toml --target ${{ matrix.target }} $features
if: matrix.library.name != 'boringssl'
- name: Test openssl
run: |
if [[ "${{ matrix.library.name }}" == "boringssl" ]]; then
features="--features unstable_boringssl"
fi
if [[ "${{ matrix.library.version }}" == "vendored" ]]; then
features="--features vendored"
fi
if [[ "${{ matrix.bindgen }}" == "true" ]]; then
features="$features --features bindgen"
if [[ "${{ matrix.library.name }}" == "boringssl" && "${{ matrix.bindgen }}" == "true" ]]; then
features="--features unstable_boringssl_bindgen"
else
if [[ "${{ matrix.library.name }}" == "boringssl" ]]; then
features="--features unstable_boringssl"
fi
if [[ "${{ matrix.library.version }}" == "vendored" ]]; then
features="--features vendored"
fi
if [[ "${{ matrix.bindgen }}" == "true" ]]; then
features="$features --features bindgen"
fi
fi
cargo test --manifest-path=openssl/Cargo.toml --target ${{ matrix.target }} $features
- name: Test openssl-errors
Expand Down
3 changes: 2 additions & 1 deletion openssl-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ edition = "2018"
[features]
vendored = ['openssl-src']
unstable_boringssl = ['bssl-sys']
unstable_boringssl_bindgen = ['bindgen']

[dependencies]
libc = "0.2"
bssl-sys = { version = "0.1.0", optional = true }

[build-dependencies]
bindgen = { version = "0.60.1", optional = true }
bindgen = { version = "0.64.0", optional = true, features = ["experimental"] }
cc = "1.0"
openssl-src = { version = "111", optional = true }
pkg-config = "0.3.9"
Expand Down
26 changes: 20 additions & 6 deletions openssl-sys/build/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ mod cfgs;
mod find_normal;
#[cfg(feature = "vendored")]
mod find_vendored;
#[cfg(feature = "bindgen")]
#[cfg(any(feature = "bindgen", feature = "unstable_boringssl_bindgen"))]
mod run_bindgen;

#[derive(PartialEq)]
Expand All @@ -32,6 +32,7 @@ enum Version {
Openssl11x,
Openssl10x,
Libressl,
Boringssl,
}

fn env_inner(name: &str) -> Option<OsString> {
Expand Down Expand Up @@ -69,8 +70,6 @@ fn check_ssl_kind() {
println!("cargo:rustc-cfg=boringssl");
// BoringSSL does not have any build logic, exit early
std::process::exit(0);
} else {
println!("cargo:rustc-cfg=openssl");
}
}

Expand Down Expand Up @@ -146,8 +145,12 @@ fn check_rustc_versions() {
#[allow(clippy::let_and_return)]
fn postprocess(include_dirs: &[PathBuf]) -> Version {
let version = validate_headers(include_dirs);
#[cfg(feature = "bindgen")]
run_bindgen::run(&include_dirs);

// Never run bindgen for BoringSSL, if it was needed we already ran it.
if version != Version::Boringssl {
#[cfg(feature = "bindgen")]
run_bindgen::run(&include_dirs);
}

version
}
Expand Down Expand Up @@ -235,9 +238,20 @@ See rust-openssl documentation for more information:
}

if is_boringssl {
panic!("BoringSSL detected, but `unstable_boringssl` feature wasn't specified.")
if !cfg!(feature = "unstable_boringssl_bindgen") {
panic!("BoringSSL detected, neither the `unstable_boringssl` nor `unstable_boringssl_bindgen` features were specified.")
}
println!("cargo:rustc-cfg=boringssl");
println!("cargo:boringssl=true");
// Necessary for the compiler
#[cfg(feature = "unstable_boringssl_bindgen")]
run_bindgen::run_boringssl(include_dirs);
return Version::Boringssl;
}

// We set this for any non-BoringSSL lib.
println!("cargo:rustc-cfg=openssl");

for enabled in &enabled {
println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled);
}
Expand Down
60 changes: 55 additions & 5 deletions openssl-sys/build/run_bindgen.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use bindgen::callbacks::{MacroParsingBehavior, ParseCallbacks};
use bindgen::RustTarget;
use std::env;
use bindgen::{MacroTypeVariation, RustTarget};
use std::io::Write;
use std::path::PathBuf;
use std::{env, fs};

const INCLUDES: &str = "
#include <openssl/aes.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/comp.h>
#include <openssl/conf.h>
#include <openssl/crypto.h>
#include <openssl/dh.h>
Expand All @@ -17,7 +17,6 @@ const INCLUDES: &str = "
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/ocsp.h>
#include <openssl/opensslv.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
Expand All @@ -35,10 +34,15 @@ const INCLUDES: &str = "
// this must be included after ssl.h for libressl!
#include <openssl/srtp.h>
#if !defined(LIBRESSL_VERSION_NUMBER)
#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
#include <openssl/cms.h>
#endif
#if !defined(OPENSSL_IS_BORINGSSL)
#include <openssl/comp.h>
#include <openssl/ocsp.h>
#endif
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
#include <openssl/kdf.h>
#endif
Expand Down Expand Up @@ -94,6 +98,52 @@ pub fn run(include_dirs: &[PathBuf]) {
.unwrap();
}

pub fn run_boringssl(include_dirs: &[PathBuf]) {
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let mut builder = bindgen::builder()
.rust_target(RustTarget::Stable_1_47)
.ctypes_prefix("::libc")
.derive_default(false)
.enable_function_attribute_detection()
.size_t_is_usize(true)
.default_macro_constant_type(MacroTypeVariation::Signed)
.rustified_enum("point_conversion_form_t")
.allowlist_file(".*/openssl/[^/]+\\.h")
.wrap_static_fns(true)
.wrap_static_fns_path(out_dir.join("boring_static_wrapper").display().to_string())
.layout_tests(false)
.header_contents("includes.h", INCLUDES);

for include_dir in include_dirs {
builder = builder
.clang_arg("-I")
.clang_arg(include_dir.display().to_string());
}

builder
.generate()
.unwrap()
.write_to_file(out_dir.join("bindgen.rs"))
.unwrap();

fs::File::create(out_dir.join("boring_static_wrapper.h"))
.expect("Failed to create boring_static_wrapper.h")
.write_all(INCLUDES.as_bytes())
.expect("Failed to write contents to boring_static_wrapper.h");

cc::Build::new()
.file(out_dir.join("boring_static_wrapper.c"))
.includes(include_dirs)
.flag("-include")
.flag(
&out_dir
.join("boring_static_wrapper.h")
.display()
.to_string(),
)
.compile("boring_static_wrapper");
}

#[derive(Debug)]
struct OpensslCallbacks;

Expand Down
18 changes: 16 additions & 2 deletions openssl-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,25 @@
extern crate libc;
pub use libc::*;

#[cfg(boringssl)]
#[cfg(feature = "unstable_boringssl")]
extern crate bssl_sys;
#[cfg(boringssl)]
#[cfg(feature = "unstable_boringssl")]
pub use bssl_sys::*;

#[cfg(all(feature = "unstable_boringssl_bindgen", boringssl))]
#[path = "."]
mod boringssl {
include!(concat!(env!("OUT_DIR"), "/bindgen.rs"));

pub fn init() {
unsafe {
CRYPTO_library_init();
}
}
}
#[cfg(all(feature = "unstable_boringssl_bindgen", boringssl))]
pub use boringssl::*;

#[cfg(openssl)]
#[path = "."]
mod openssl {
Expand Down
1 change: 1 addition & 0 deletions openssl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ v111 = []
vendored = ['ffi/vendored']
bindgen = ['ffi/bindgen']
unstable_boringssl = ["ffi/unstable_boringssl"]
unstable_boringssl_bindgen = ["ffi/unstable_boringssl_bindgen"]
default = []

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion openssl/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn main() {
println!("cargo:rustc-cfg=libressl");
}

if env::var("CARGO_FEATURE_UNSTABLE_BORINGSSL").is_ok() {
if env::var("DEP_OPENSSL_BORINGSSL").is_ok() {
println!("cargo:rustc-cfg=boringssl");
return;
}
Expand Down
4 changes: 2 additions & 2 deletions openssl/src/bio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl<'a> MemBioSlice<'a> {
let bio = unsafe {
cvt_p(BIO_new_mem_buf(
buf.as_ptr() as *const _,
buf.len() as c_int,
buf.len() as crate::SLenType,
))?
};

Expand Down Expand Up @@ -74,7 +74,7 @@ impl MemBio {
}

cfg_if! {
if #[cfg(ossl102)] {
if #[cfg(any(ossl102, boringssl))] {
use ffi::BIO_new_mem_buf;
} else {
#[allow(bad_style)]
Expand Down
2 changes: 1 addition & 1 deletion openssl/src/dh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ where
}

cfg_if! {
if #[cfg(any(ossl110, libressl270))] {
if #[cfg(any(ossl110, libressl270, boringssl))] {
use ffi::{DH_set0_pqg, DH_get0_pqg, DH_get0_key, DH_set0_key};
} else {
#[allow(bad_style)]
Expand Down
11 changes: 8 additions & 3 deletions openssl/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,19 +297,24 @@ impl fmt::Debug for Error {
}

impl fmt::Display for Error {
// On BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on
// OpenSSL/LibreSSL they're safe.
#[allow(unused_unsafe)]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "error:{:08X}", self.code())?;
match self.library() {
Some(l) => write!(fmt, ":{}", l)?,
None => write!(fmt, ":lib({})", ffi::ERR_GET_LIB(self.code()))?,
None => write!(fmt, ":lib({})", unsafe { ffi::ERR_GET_LIB(self.code()) })?,
}
match self.function() {
Some(f) => write!(fmt, ":{}", f)?,
None => write!(fmt, ":func({})", ffi::ERR_GET_FUNC(self.code()))?,
None => write!(fmt, ":func({})", unsafe { ffi::ERR_GET_FUNC(self.code()) })?,
}
match self.reason() {
Some(r) => write!(fmt, ":{}", r)?,
None => write!(fmt, ":reason({})", ffi::ERR_GET_REASON(self.code()))?,
None => write!(fmt, ":reason({})", unsafe {
ffi::ERR_GET_REASON(self.code())
})?,
}
write!(
fmt,
Expand Down
5 changes: 5 additions & 0 deletions openssl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ type LenType = libc::size_t;
#[cfg(not(boringssl))]
type LenType = libc::c_int;

#[cfg(boringssl)]
type SLenType = libc::ssize_t;
#[cfg(not(boringssl))]
type SLenType = libc::c_int;

#[inline]
fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
if r.is_null() {
Expand Down

0 comments on commit e43b137

Please sign in to comment.