diff --git a/Cargo.toml b/Cargo.toml index 2784e6c8..ba1ac68f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ bindgen = { version = "0.66.1", default-features = false, features = ["runtime"] cmake = "0.1" fs_extra = "1.3.0" fslock = "0.2" -bitflags = "1.0" +bitflags = "2.4" foreign-types = "0.5" libc = "0.2" hex = "0.4" diff --git a/boring-sys/Cargo.toml b/boring-sys/Cargo.toml index 1b938fd2..063c2f9b 100644 --- a/boring-sys/Cargo.toml +++ b/boring-sys/Cargo.toml @@ -51,7 +51,7 @@ rustdoc-args = ["--cfg", "docsrs"] fips = [] # Link with precompiled FIPS-validated `bcm.o` module. -fips-link-precompiled = ["fips"] +fips-link-precompiled = [] # Enables Raw public key API (https://datatracker.ietf.org/doc/html/rfc7250) rpk = [] diff --git a/boring-sys/build.rs b/boring-sys/build.rs index 69c8fa77..75191996 100644 --- a/boring-sys/build.rs +++ b/boring-sys/build.rs @@ -117,9 +117,9 @@ fn get_apple_sdk_name() -> &'static str { /// Returns an absolute path to the BoringSSL source. fn get_boringssl_source_path() -> String { - #[cfg(all(feature = "fips", not(feature = "fips-link-precompiled")))] + #[cfg(feature = "fips")] const SUBMODULE_DIR: &str = "boringssl-fips"; - #[cfg(any(not(feature = "fips"), feature = "fips-link-precompiled"))] + #[cfg(not(feature = "fips"))] const SUBMODULE_DIR: &str = "boringssl"; static COPY_SOURCES: Once = Once::new(); @@ -518,10 +518,7 @@ fn build_boring_from_sources() -> String { .cxxflag("-DBORINGSSL_UNSAFE_FUZZER_MODE"); } - if cfg!(all( - feature = "fips", - not(feature = "fips-link-precompiled") - )) { + if cfg!(feature = "fips") { let (clang, clangxx) = verify_fips_clang_version(); cfg.define("CMAKE_C_COMPILER", clang); cfg.define("CMAKE_CXX_COMPILER", clangxx); @@ -589,19 +586,21 @@ fn main() { let bssl_dir = env::var("BORING_BSSL_PATH"); - if bssl_dir.is_ok() && cfg!(any(feature = "rpk", feature = "pq-experimental")) { - panic!("precompiled BoringSSL was provided, optional patches can't be applied to it"); - } - - if bssl_dir.is_ok() && cfg!(feature = "fips") { - panic!("precompiled BoringSSL was provided, so FIPS configuration can't be applied"); + if bssl_dir.is_ok() + && cfg!(any( + feature = "fips", + feature = "fips-link-precompiled", + feature = "rpk", + feature = "pq-experimental" + )) + { + panic!("precompiled BoringSSL was provided, so FIPS configuration or optional patches can't be applied"); } let bssl_dir = bssl_dir.unwrap_or_else(|_| build_boring_from_sources()); - let build_path = get_boringssl_platform_output_path(); - if cfg!(feature = "fips") { + if cfg!(any(feature = "fips", feature = "fips-link-precompiled")) { println!( "cargo:rustc-link-search=native={}/build/crypto/{}", bssl_dir, build_path diff --git a/boring/Cargo.toml b/boring/Cargo.toml index 568a53ad..af1a20cf 100644 --- a/boring/Cargo.toml +++ b/boring/Cargo.toml @@ -20,7 +20,7 @@ rustdoc-args = ["--cfg", "docsrs"] fips = ["boring-sys/fips"] # Link with precompiled FIPS-validated `bcm.o` module. -fips-link-precompiled = ["fips", "boring-sys/fips-link-precompiled"] +fips-link-precompiled = ["boring-sys/fips-link-precompiled"] # Enables Raw public key API (https://datatracker.ietf.org/doc/html/rfc7250) rpk = ["boring-sys/rpk"] diff --git a/boring/src/bio.rs b/boring/src/bio.rs index 55870ded..adb119b8 100644 --- a/boring/src/bio.rs +++ b/boring/src/bio.rs @@ -19,9 +19,9 @@ impl<'a> Drop for MemBioSlice<'a> { impl<'a> MemBioSlice<'a> { pub fn new(buf: &'a [u8]) -> Result, ErrorStack> { - #[cfg(not(feature = "fips"))] + #[cfg(not(any(feature = "fips", feature = "fips-link-precompiled")))] type BufLen = isize; - #[cfg(feature = "fips")] + #[cfg(any(feature = "fips", feature = "fips-link-precompiled"))] type BufLen = libc::c_int; ffi::init(); diff --git a/boring/src/fips.rs b/boring/src/fips.rs index baf044f7..05e40a4b 100644 --- a/boring/src/fips.rs +++ b/boring/src/fips.rs @@ -23,8 +23,8 @@ pub fn enabled() -> bool { #[test] fn is_enabled() { - #[cfg(feature = "fips")] + #[cfg(any(feature = "fips", feature = "fips-link-precompiled"))] assert!(enabled()); - #[cfg(not(feature = "fips"))] + #[cfg(not(any(feature = "fips", feature = "fips-link-precompiled")))] assert!(!enabled()); } diff --git a/boring/src/ssl/callbacks.rs b/boring/src/ssl/callbacks.rs index b60a243e..e87b151f 100644 --- a/boring/src/ssl/callbacks.rs +++ b/boring/src/ssl/callbacks.rs @@ -75,7 +75,7 @@ where // Give the callback mutable slices into which it can write the identity and psk. let identity_sl = unsafe { slice::from_raw_parts_mut(identity as *mut u8, max_identity_len as usize) }; - let psk_sl = unsafe { slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize) }; + let psk_sl = unsafe { slice::from_raw_parts_mut(psk, max_psk_len as usize) }; let ssl_context = ssl.ssl_context().to_owned(); let callback = ssl_context @@ -114,7 +114,7 @@ where }; // Give the callback mutable slices into which it can write the psk. - let psk_sl = unsafe { slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize) }; + let psk_sl = unsafe { slice::from_raw_parts_mut(psk, max_psk_len as usize) }; let ssl_context = ssl.ssl_context().to_owned(); let callback = ssl_context @@ -199,7 +199,7 @@ where { // SAFETY: boring provides valid inputs. let ssl = unsafe { SslRef::from_ptr_mut(ssl) }; - let protos = unsafe { slice::from_raw_parts(inbuf as *const u8, inlen as usize) }; + let protos = unsafe { slice::from_raw_parts(inbuf, inlen as usize) }; let out = unsafe { &mut *out }; let outlen = unsafe { &mut *outlen }; @@ -333,7 +333,7 @@ where { // SAFETY: boring provides valid inputs. let ssl = unsafe { SslRef::from_ptr_mut(ssl) }; - let data = unsafe { slice::from_raw_parts(data as *const u8, len as usize) }; + let data = unsafe { slice::from_raw_parts(data, len as usize) }; let copy = unsafe { &mut *copy }; let callback = ssl diff --git a/boring/src/ssl/mod.rs b/boring/src/ssl/mod.rs index 67e16b18..aec7508b 100644 --- a/boring/src/ssl/mod.rs +++ b/boring/src/ssl/mod.rs @@ -109,6 +109,7 @@ mod test; bitflags! { /// Options controlling the behavior of an `SslContext`. + #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] pub struct SslOptions: c_uint { /// Disables a countermeasure against an SSLv3/TLSv1.0 vulnerability affecting CBC ciphers. const DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS as _; @@ -181,6 +182,7 @@ bitflags! { bitflags! { /// Options controlling the behavior of an `SslContext`. + #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] pub struct SslMode: c_uint { /// Enables "short writes". /// @@ -291,6 +293,7 @@ unsafe impl Send for SslMethod {} bitflags! { /// Options controling the behavior of certificate verification. + #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] pub struct SslVerifyMode: i32 { /// Verifies that the peer's certificate is trusted. /// @@ -313,6 +316,7 @@ bitflags! { bitflags! { /// Options controlling the behavior of session caching. + #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] pub struct SslSessionCacheMode: c_int { /// No session caching for the client or server takes place. const OFF = ffi::SSL_SESS_CACHE_OFF; @@ -630,7 +634,7 @@ impl SslCurve { pub const X25519: SslCurve = SslCurve(ffi::NID_X25519); - #[cfg(not(feature = "fips"))] + #[cfg(not(any(feature = "fips", feature = "fips-link-precompiled")))] pub const X25519_KYBER768_DRAFT00: SslCurve = SslCurve(ffi::NID_X25519Kyber768Draft00); #[cfg(feature = "pq-experimental")] @@ -801,7 +805,7 @@ impl SslContextBuilder { assert!(!self.is_rpk, "This API is not supported for RPK"); unsafe { - ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits as c_int, None); + ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits() as c_int, None); } } @@ -824,7 +828,7 @@ impl SslContextBuilder { unsafe { self.set_ex_data(SslContext::cached_ex_index::(), verify); - ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits as c_int, Some(raw_verify::)); + ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits() as c_int, Some(raw_verify::)); } } @@ -930,7 +934,7 @@ impl SslContextBuilder { pub fn set_mode(&mut self, mode: SslMode) -> SslMode { unsafe { let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits()); - SslMode { bits } + SslMode::from_bits_retain(bits) } } @@ -1189,7 +1193,7 @@ impl SslContextBuilder { /// [`SSL_CTX_set_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html pub fn set_options(&mut self, option: SslOptions) -> SslOptions { let bits = unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) }; - SslOptions { bits } + SslOptions::from_bits_retain(bits) } /// Returns the options used by the context. @@ -1199,7 +1203,7 @@ impl SslContextBuilder { /// [`SSL_CTX_get_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html pub fn options(&self) -> SslOptions { let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) }; - SslOptions { bits } + SslOptions::from_bits_retain(bits) } /// Clears the options used by the context, returning the old set. @@ -1209,7 +1213,7 @@ impl SslContextBuilder { /// [`SSL_CTX_clear_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html pub fn clear_options(&mut self, option: SslOptions) -> SslOptions { let bits = unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) }; - SslOptions { bits } + SslOptions::from_bits_retain(bits) } /// Sets the minimum supported protocol version. @@ -1298,7 +1302,10 @@ impl SslContextBuilder { /// [`SSL_CTX_set_alpn_protos`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_alpn_protos.html pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> { unsafe { - #[cfg_attr(not(feature = "fips"), allow(clippy::unnecessary_cast))] + #[cfg_attr( + not(any(feature = "fips", feature = "fips-link-precompiled")), + allow(clippy::unnecessary_cast) + )] { assert!(protocols.len() <= ProtosLen::max_value() as usize); } @@ -1596,7 +1603,7 @@ impl SslContextBuilder { pub fn set_session_cache_mode(&mut self, mode: SslSessionCacheMode) -> SslSessionCacheMode { unsafe { let bits = ffi::SSL_CTX_set_session_cache_mode(self.as_ptr(), mode.bits()); - SslSessionCacheMode { bits } + SslSessionCacheMode::from_bits_retain(bits) } } @@ -1930,9 +1937,9 @@ impl SslContextRef { } } -#[cfg(not(feature = "fips"))] +#[cfg(not(any(feature = "fips", feature = "fips-link-precompiled")))] type ProtosLen = usize; -#[cfg(feature = "fips")] +#[cfg(any(feature = "fips", feature = "fips-link-precompiled"))] type ProtosLen = libc::c_uint; /// Information about the state of a cipher. @@ -2167,7 +2174,7 @@ impl SslSessionRef { unsafe { let mut len = 0; let p = ffi::SSL_SESSION_get_id(self.as_ptr(), &mut len); - slice::from_raw_parts(p as *const u8, len as usize) + slice::from_raw_parts(p, len as usize) } } @@ -2406,7 +2413,7 @@ impl SslRef { "This API is not supported for RPK" ); - unsafe { ffi::SSL_set_verify(self.as_ptr(), mode.bits as c_int, None) } + unsafe { ffi::SSL_set_verify(self.as_ptr(), mode.bits() as c_int, None) } } /// Returns the verify mode that was set using `set_verify`. @@ -2444,7 +2451,11 @@ impl SslRef { unsafe { // this needs to be in an Arc since the callback can register a new callback! self.set_ex_data(Ssl::cached_ex_index(), Arc::new(verify)); - ffi::SSL_set_verify(self.as_ptr(), mode.bits as c_int, Some(ssl_raw_verify::)); + ffi::SSL_set_verify( + self.as_ptr(), + mode.bits() as c_int, + Some(ssl_raw_verify::), + ); } } @@ -2475,7 +2486,10 @@ impl SslRef { /// [`SSL_set_alpn_protos`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_alpn_protos.html pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> { unsafe { - #[cfg_attr(not(feature = "fips"), allow(clippy::unnecessary_cast))] + #[cfg_attr( + not(any(feature = "fips", feature = "fips-link-precompiled")), + allow(clippy::unnecessary_cast) + )] { assert!(protocols.len() <= ProtosLen::max_value() as usize); } @@ -2984,7 +2998,7 @@ impl SslRef { if len == 0 { None } else { - Some(slice::from_raw_parts(p as *const u8, len)) + Some(slice::from_raw_parts(p, len)) } } } @@ -3304,7 +3318,7 @@ impl SslStream { pub fn get_shutdown(&mut self) -> ShutdownState { unsafe { let bits = ffi::SSL_get_shutdown(self.ssl.as_ptr()); - ShutdownState { bits } + ShutdownState::from_bits_retain(bits) } } @@ -3594,6 +3608,7 @@ pub enum ShutdownResult { bitflags! { /// The shutdown state of a session. + #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] pub struct ShutdownState: c_int { /// A close notify message has been sent to the peer. const SENT = ffi::SSL_SENT_SHUTDOWN; diff --git a/boring/src/x509/mod.rs b/boring/src/x509/mod.rs index a3b3a044..71458ab3 100644 --- a/boring/src/x509/mod.rs +++ b/boring/src/x509/mod.rs @@ -966,9 +966,9 @@ impl X509NameBuilder { } } -#[cfg(not(feature = "fips"))] +#[cfg(not(any(feature = "fips", feature = "fips-link-precompiled")))] type ValueLen = isize; -#[cfg(feature = "fips")] +#[cfg(any(feature = "fips", feature = "fips-link-precompiled"))] type ValueLen = i32; foreign_type_and_impl_send_sync! { @@ -1494,7 +1494,7 @@ impl GeneralNameRef { let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d.ia5 as *mut _); let len = ffi::ASN1_STRING_length((*self.as_ptr()).d.ia5 as *mut _); - let slice = slice::from_raw_parts(ptr as *const u8, len as usize); + let slice = slice::from_raw_parts(ptr, len as usize); // IA5Strings are stated to be ASCII (specifically IA5). Hopefully // OpenSSL checks that when loading a certificate but if not we'll // use this instead of from_utf8_unchecked just in case. @@ -1527,7 +1527,7 @@ impl GeneralNameRef { let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d.ip as *mut _); let len = ffi::ASN1_STRING_length((*self.as_ptr()).d.ip as *mut _); - Some(slice::from_raw_parts(ptr as *const u8, len as usize)) + Some(slice::from_raw_parts(ptr, len as usize)) } } } diff --git a/boring/src/x509/verify.rs b/boring/src/x509/verify.rs index 43249100..8bc17a58 100644 --- a/boring/src/x509/verify.rs +++ b/boring/src/x509/verify.rs @@ -8,6 +8,7 @@ use crate::error::ErrorStack; bitflags! { /// Flags used to check an `X509` certificate. + #[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)] pub struct X509CheckFlags: c_uint { const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT as _; const NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS as _; @@ -37,7 +38,7 @@ impl X509VerifyParamRef { /// [`X509_VERIFY_PARAM_set_hostflags`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_hostflags.html pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { unsafe { - ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); + ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits()); } } diff --git a/hyper-boring/Cargo.toml b/hyper-boring/Cargo.toml index 9775ae78..9396c25c 100644 --- a/hyper-boring/Cargo.toml +++ b/hyper-boring/Cargo.toml @@ -23,7 +23,7 @@ runtime = ["hyper/runtime"] fips = ["tokio-boring/fips"] # Link with precompiled FIPS-validated `bcm.o` module. -fips-link-precompiled = ["fips", "tokio-boring/fips-link-precompiled"] +fips-link-precompiled = ["tokio-boring/fips-link-precompiled"] # Enables Raw public key API (https://datatracker.ietf.org/doc/html/rfc7250) rpk = ["tokio-boring/rpk"] diff --git a/tokio-boring/Cargo.toml b/tokio-boring/Cargo.toml index 009dd580..15220348 100644 --- a/tokio-boring/Cargo.toml +++ b/tokio-boring/Cargo.toml @@ -20,7 +20,7 @@ rustdoc-args = ["--cfg", "docsrs"] fips = ["boring/fips", "boring-sys/fips"] # Link with precompiled FIPS-validated `bcm.o` module. -fips-link-precompiled = ["fips", "boring/fips-link-precompiled", "boring-sys/fips-link-precompiled"] +fips-link-precompiled = ["boring/fips-link-precompiled", "boring-sys/fips-link-precompiled"] # Enables Raw public key API (https://datatracker.ietf.org/doc/html/rfc7250) rpk = ["boring/rpk"]