From e610c0fe013b60c8bb6c438ba6a655588308a232 Mon Sep 17 00:00:00 2001 From: Benjamin Brittain Date: Mon, 22 Nov 2021 13:34:23 -0500 Subject: [PATCH 1/4] Adds support for linking against boringssl The boringssl-sys crate is specific to the revision of boringssl you are using, so you will need to generate it from a boringssl build tree and point the openssl crate at it via cargo source replacement, or place the build tree next to rust-openssl while building. Co-authored-by: Matthew Maurer --- openssl-sys/Cargo.toml | 2 + openssl-sys/build/main.rs | 12 ++ openssl-sys/src/handwritten/mod.rs | 64 +++--- openssl-sys/src/lib.rs | 306 +++++++++++++++-------------- openssl/Cargo.toml | 2 + openssl/build.rs | 5 + openssl/src/aes.rs | 60 ++++-- openssl/src/base64.rs | 10 +- openssl/src/bio.rs | 1 + openssl/src/bn.rs | 17 +- openssl/src/cipher.rs | 23 ++- openssl/src/cipher_ctx.rs | 15 +- openssl/src/conf.rs | 98 ++++----- openssl/src/dsa.rs | 10 +- openssl/src/ec.rs | 6 +- openssl/src/ecdsa.rs | 12 +- openssl/src/error.rs | 24 ++- openssl/src/hash.rs | 8 +- openssl/src/lib.rs | 12 +- openssl/src/macros.rs | 3 +- openssl/src/md.rs | 3 + openssl/src/md_ctx.rs | 56 +++--- openssl/src/nid.rs | 2 + openssl/src/pkcs12.rs | 44 +++-- openssl/src/pkey.rs | 11 +- openssl/src/pkey_ctx.rs | 50 +++-- openssl/src/rand.rs | 6 +- openssl/src/rsa.rs | 10 +- openssl/src/sign.rs | 64 +++--- openssl/src/srtp.rs | 16 +- openssl/src/ssl/callbacks.rs | 5 +- openssl/src/ssl/connector.rs | 22 ++- openssl/src/ssl/mod.rs | 165 +++++++++++----- openssl/src/ssl/test/mod.rs | 17 +- openssl/src/stack.rs | 18 +- openssl/src/string.rs | 11 ++ openssl/src/symm.rs | 72 +++++-- openssl/src/version.rs | 6 +- openssl/src/x509/mod.rs | 36 +++- openssl/src/x509/store.rs | 11 +- openssl/src/x509/tests.rs | 5 +- systest/build.rs | 2 + 42 files changed, 845 insertions(+), 477 deletions(-) diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index 4f0d64d7ef..1a23a40e3d 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -15,9 +15,11 @@ build = "build/main.rs" [features] vendored = ['openssl-src'] +unstable_boringssl = ['bssl-sys'] [dependencies] libc = "0.2" +bssl-sys = { version = "0.1.0", optional = true } [build-dependencies] bindgen = { version = "0.59.2", optional = true } diff --git a/openssl-sys/build/main.rs b/openssl-sys/build/main.rs index 2290e8c44e..a8911e7b14 100644 --- a/openssl-sys/build/main.rs +++ b/openssl-sys/build/main.rs @@ -60,9 +60,21 @@ fn find_openssl(target: &str) -> (Vec, PathBuf) { find_normal::get_openssl(target) } +fn check_ssl_kind() { + if cfg!(feature = "unstable_boringssl") { + println!("cargo:rustc-cfg=boringssl"); + // BoringSSL does not have any build logic, exit early + std::process::exit(0); + } else { + println!("cargo:rustc-cfg=openssl"); + } +} + fn main() { check_rustc_versions(); + check_ssl_kind(); + let target = env::var("TARGET").unwrap(); let (lib_dirs, include_dir) = find_openssl(&target); diff --git a/openssl-sys/src/handwritten/mod.rs b/openssl-sys/src/handwritten/mod.rs index cc4cf1cd1d..28aa4aecd0 100644 --- a/openssl-sys/src/handwritten/mod.rs +++ b/openssl-sys/src/handwritten/mod.rs @@ -1,35 +1,35 @@ -pub use handwritten::aes::*; -pub use handwritten::asn1::*; -pub use handwritten::bio::*; -pub use handwritten::bn::*; -pub use handwritten::cms::*; -pub use handwritten::conf::*; -pub use handwritten::crypto::*; -pub use handwritten::dh::*; -pub use handwritten::dsa::*; -pub use handwritten::ec::*; -pub use handwritten::err::*; -pub use handwritten::evp::*; -pub use handwritten::hmac::*; -pub use handwritten::kdf::*; -pub use handwritten::object::*; -pub use handwritten::ocsp::*; -pub use handwritten::pem::*; -pub use handwritten::pkcs12::*; -pub use handwritten::pkcs7::*; -pub use handwritten::provider::*; -pub use handwritten::rand::*; -pub use handwritten::rsa::*; -pub use handwritten::safestack::*; -pub use handwritten::sha::*; -pub use handwritten::srtp::*; -pub use handwritten::ssl::*; -pub use handwritten::stack::*; -pub use handwritten::tls1::*; -pub use handwritten::types::*; -pub use handwritten::x509::*; -pub use handwritten::x509_vfy::*; -pub use handwritten::x509v3::*; +pub use self::aes::*; +pub use self::asn1::*; +pub use self::bio::*; +pub use self::bn::*; +pub use self::cms::*; +pub use self::conf::*; +pub use self::crypto::*; +pub use self::dh::*; +pub use self::dsa::*; +pub use self::ec::*; +pub use self::err::*; +pub use self::evp::*; +pub use self::hmac::*; +pub use self::kdf::*; +pub use self::object::*; +pub use self::ocsp::*; +pub use self::pem::*; +pub use self::pkcs12::*; +pub use self::pkcs7::*; +pub use self::provider::*; +pub use self::rand::*; +pub use self::rsa::*; +pub use self::safestack::*; +pub use self::sha::*; +pub use self::srtp::*; +pub use self::ssl::*; +pub use self::stack::*; +pub use self::tls1::*; +pub use self::types::*; +pub use self::x509::*; +pub use self::x509_vfy::*; +pub use self::x509v3::*; mod aes; mod asn1; diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 2cf9c13276..1d36a104fe 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -13,162 +13,174 @@ #![recursion_limit = "128"] // configure fixed limit across all rust versions extern crate libc; +pub use libc::*; + +#[cfg(boringssl)] +extern crate bssl_sys; +#[cfg(boringssl)] +pub use bssl_sys::*; + +#[cfg(openssl)] +#[path = "."] +mod openssl { + use libc::*; + + #[cfg(feature = "bindgen")] + include!(concat!(env!("OUT_DIR"), "/bindgen.rs")); + + pub use self::aes::*; + pub use self::asn1::*; + pub use self::bio::*; + pub use self::bn::*; + pub use self::cms::*; + pub use self::crypto::*; + pub use self::dtls1::*; + pub use self::ec::*; + pub use self::err::*; + pub use self::evp::*; + #[cfg(not(feature = "bindgen"))] + pub use self::handwritten::*; + pub use self::obj_mac::*; + pub use self::ocsp::*; + pub use self::pem::*; + pub use self::pkcs7::*; + pub use self::rsa::*; + pub use self::sha::*; + pub use self::srtp::*; + pub use self::ssl::*; + pub use self::ssl3::*; + pub use self::tls1::*; + pub use self::types::*; + pub use self::x509::*; + pub use self::x509_vfy::*; + pub use self::x509v3::*; + + #[macro_use] + mod macros; + + mod aes; + mod asn1; + mod bio; + mod bn; + mod cms; + mod crypto; + mod dtls1; + mod ec; + mod err; + mod evp; + #[cfg(not(feature = "bindgen"))] + mod handwritten; + mod obj_mac; + mod ocsp; + mod pem; + mod pkcs7; + mod rsa; + mod sha; + mod srtp; + mod ssl; + mod ssl3; + mod tls1; + mod types; + mod x509; + mod x509_vfy; + mod x509v3; + + // FIXME remove + pub type PasswordCallback = unsafe extern "C" fn( + buf: *mut c_char, + size: c_int, + rwflag: c_int, + user_data: *mut c_void, + ) -> c_int; + + #[cfg(ossl110)] + pub fn init() { + use std::ptr; + use std::sync::Once; + + // explicitly initialize to work around https://github.com/openssl/openssl/issues/3505 + static INIT: Once = Once::new(); + + #[cfg(not(ossl111b))] + let init_options = OPENSSL_INIT_LOAD_SSL_STRINGS; + #[cfg(ossl111b)] + let init_options = OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_NO_ATEXIT; + + INIT.call_once(|| unsafe { + OPENSSL_init_ssl(init_options, ptr::null_mut()); + }) + } -use libc::*; - -#[cfg(feature = "bindgen")] -include!(concat!(env!("OUT_DIR"), "/bindgen.rs")); - -pub use aes::*; -pub use asn1::*; -pub use bio::*; -pub use bn::*; -pub use cms::*; -pub use crypto::*; -pub use dtls1::*; -pub use ec::*; -pub use err::*; -pub use evp::*; -#[cfg(not(feature = "bindgen"))] -pub use handwritten::*; -pub use obj_mac::*; -pub use ocsp::*; -pub use pem::*; -pub use pkcs7::*; -pub use rsa::*; -pub use sha::*; -pub use srtp::*; -pub use ssl::*; -pub use ssl3::*; -pub use tls1::*; -pub use types::*; -pub use x509::*; -pub use x509_vfy::*; -pub use x509v3::*; - -#[macro_use] -mod macros; - -mod aes; -mod asn1; -mod bio; -mod bn; -mod cms; -mod crypto; -mod dtls1; -mod ec; -mod err; -mod evp; -#[cfg(not(feature = "bindgen"))] -mod handwritten; -mod obj_mac; -mod ocsp; -mod pem; -mod pkcs7; -mod rsa; -mod sha; -mod srtp; -mod ssl; -mod ssl3; -mod tls1; -mod types; -mod x509; -mod x509_vfy; -mod x509v3; - -// FIXME remove -pub type PasswordCallback = unsafe extern "C" fn( - buf: *mut c_char, - size: c_int, - rwflag: c_int, - user_data: *mut c_void, -) -> c_int; - -#[cfg(ossl110)] -pub fn init() { - use std::ptr; - use std::sync::Once; - - // explicitly initialize to work around https://github.com/openssl/openssl/issues/3505 - static INIT: Once = Once::new(); - - #[cfg(not(ossl111b))] - let init_options = OPENSSL_INIT_LOAD_SSL_STRINGS; - #[cfg(ossl111b)] - let init_options = OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_NO_ATEXIT; - - INIT.call_once(|| unsafe { - OPENSSL_init_ssl(init_options, ptr::null_mut()); - }) -} - -#[cfg(not(ossl110))] -pub fn init() { - use std::io::{self, Write}; - use std::mem; - use std::process; - use std::sync::{Mutex, MutexGuard, Once}; - - static mut MUTEXES: *mut Vec> = 0 as *mut Vec>; - static mut GUARDS: *mut Vec>> = - 0 as *mut Vec>>; - - unsafe extern "C" fn locking_function( - mode: c_int, - n: c_int, - _file: *const c_char, - _line: c_int, - ) { - let mutex = &(*MUTEXES)[n as usize]; - - if mode & ::CRYPTO_LOCK != 0 { - (*GUARDS)[n as usize] = Some(mutex.lock().unwrap()); - } else { - if let None = (*GUARDS)[n as usize].take() { - let _ = writeln!( - io::stderr(), - "BUG: rust-openssl lock {} already unlocked, aborting", - n - ); - process::abort(); + #[cfg(not(ossl110))] + pub fn init() { + use std::io::{self, Write}; + use std::mem; + use std::process; + use std::sync::{Mutex, MutexGuard, Once}; + + static mut MUTEXES: *mut Vec> = 0 as *mut Vec>; + static mut GUARDS: *mut Vec>> = + 0 as *mut Vec>>; + + unsafe extern "C" fn locking_function( + mode: c_int, + n: c_int, + _file: *const c_char, + _line: c_int, + ) { + let mutex = &(*MUTEXES)[n as usize]; + + if mode & ::CRYPTO_LOCK != 0 { + (*GUARDS)[n as usize] = Some(mutex.lock().unwrap()); + } else { + if let None = (*GUARDS)[n as usize].take() { + let _ = writeln!( + io::stderr(), + "BUG: rust-openssl lock {} already unlocked, aborting", + n + ); + process::abort(); + } } } - } - cfg_if! { - if #[cfg(unix)] { - fn set_id_callback() { - unsafe extern "C" fn thread_id() -> c_ulong { - ::libc::pthread_self() as c_ulong - } + cfg_if! { + if #[cfg(unix)] { + fn set_id_callback() { + unsafe extern "C" fn thread_id() -> c_ulong { + ::libc::pthread_self() as c_ulong + } - unsafe { - CRYPTO_set_id_callback__fixed_rust(Some(thread_id)); + unsafe { + CRYPTO_set_id_callback__fixed_rust(Some(thread_id)); + } } + } else { + fn set_id_callback() {} } - } else { - fn set_id_callback() {} } - } - static INIT: Once = Once::new(); + static INIT: Once = Once::new(); - INIT.call_once(|| unsafe { - SSL_library_init(); - SSL_load_error_strings(); - OPENSSL_add_all_algorithms_noconf(); + INIT.call_once(|| unsafe { + SSL_library_init(); + SSL_load_error_strings(); + OPENSSL_add_all_algorithms_noconf(); - let num_locks = ::CRYPTO_num_locks(); - let mut mutexes = Box::new(Vec::new()); - for _ in 0..num_locks { - mutexes.push(Mutex::new(())); - } - MUTEXES = mem::transmute(mutexes); - let guards: Box>>> = - Box::new((0..num_locks).map(|_| None).collect()); - GUARDS = mem::transmute(guards); - - CRYPTO_set_locking_callback__fixed_rust(Some(locking_function)); - set_id_callback(); - }) + let num_locks = ::CRYPTO_num_locks(); + let mut mutexes = Box::new(Vec::new()); + for _ in 0..num_locks { + mutexes.push(Mutex::new(())); + } + MUTEXES = mem::transmute(mutexes); + let guards: Box>>> = + Box::new((0..num_locks).map(|_| None).collect()); + GUARDS = mem::transmute(guards); + + CRYPTO_set_locking_callback__fixed_rust(Some(locking_function)); + set_id_callback(); + }) + } } +#[cfg(openssl)] +pub use openssl::*; diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index 51f73e98fb..3425943072 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -19,6 +19,8 @@ v111 = [] vendored = ['ffi/vendored'] bindgen = ['ffi/bindgen'] +unstable_boringssl = ["ffi/unstable_boringssl"] +default = [] [dependencies] bitflags = "1.0" diff --git a/openssl/build.rs b/openssl/build.rs index 96ab615e58..81bae9d9bf 100644 --- a/openssl/build.rs +++ b/openssl/build.rs @@ -7,6 +7,11 @@ fn main() { println!("cargo:rustc-cfg=libressl"); } + if env::var("CARGO_FEATURE_UNSTABLE_BORINGSSL").is_ok() { + println!("cargo:rustc-cfg=boringssl"); + return; + } + if let Ok(v) = env::var("DEP_OPENSSL_LIBRESSL_VERSION") { println!("cargo:rustc-cfg=libressl{}", v); } diff --git a/openssl/src/aes.rs b/openssl/src/aes.rs index 3407199c59..440dd05723 100644 --- a/openssl/src/aes.rs +++ b/openssl/src/aes.rs @@ -21,22 +21,27 @@ //! [`Cipher`]: ../symm/struct.Cipher.html //! //! # Examples -//! -//! ## AES IGE -//! ```rust -//! use openssl::aes::{AesKey, aes_ige}; -//! use openssl::symm::Mode; -//! -//! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; -//! let plaintext = b"\x12\x34\x56\x78\x90\x12\x34\x56\x12\x34\x56\x78\x90\x12\x34\x56"; -//! let mut iv = *b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\ -//! \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; -//! -//! let key = AesKey::new_encrypt(key).unwrap(); -//! let mut output = [0u8; 16]; -//! aes_ige(plaintext, &mut output, &key, &mut iv, Mode::Encrypt); -//! assert_eq!(output, *b"\xa6\xad\x97\x4d\x5c\xea\x1d\x36\xd2\xf3\x67\x98\x09\x07\xed\x32"); -//! ``` + +#![cfg_attr( + not(boringssl), + doc = r#"\ +## AES IGE +```rust +use openssl::aes::{AesKey, aes_ige}; +use openssl::symm::Mode; + +let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +let plaintext = b"\x12\x34\x56\x78\x90\x12\x34\x56\x12\x34\x56\x78\x90\x12\x34\x56"; +let mut iv = *b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\ + \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; + + let key = AesKey::new_encrypt(key).unwrap(); + let mut output = [0u8; 16]; + aes_ige(plaintext, &mut output, &key, &mut iv, Mode::Encrypt); + assert_eq!(output, *b"\xa6\xad\x97\x4d\x5c\xea\x1d\x36\xd2\xf3\x67\x98\x09\x07\xed\x32"); +```"# +)] + //! //! ## Key wrapping //! ```rust @@ -55,10 +60,12 @@ //! assert_eq!(&orig_key[..], &key_to_wrap[..]); //! ``` //! +use cfg_if::cfg_if; use libc::{c_int, c_uint}; use std::mem::MaybeUninit; use std::ptr; +#[cfg(not(boringssl))] use crate::symm::Mode; use openssl_macros::corresponds; @@ -69,6 +76,16 @@ pub struct KeyError(()); /// The key used to encrypt or decrypt cipher blocks. pub struct AesKey(ffi::AES_KEY); +cfg_if! { + if #[cfg(boringssl)] { + type AesBitType = c_uint; + type AesSizeType = usize; + } else { + type AesBitType = c_int; + type AesSizeType = c_uint; + } +} + impl AesKey { /// Prepares a key for encryption. /// @@ -83,7 +100,7 @@ impl AesKey { let mut aes_key = MaybeUninit::uninit(); let r = ffi::AES_set_encrypt_key( key.as_ptr() as *const _, - key.len() as c_int * 8, + key.len() as AesBitType * 8, aes_key.as_mut_ptr(), ); if r == 0 { @@ -107,7 +124,7 @@ impl AesKey { let mut aes_key = MaybeUninit::uninit(); let r = ffi::AES_set_decrypt_key( key.as_ptr() as *const _, - key.len() as c_int * 8, + key.len() as AesBitType * 8, aes_key.as_mut_ptr(), ); @@ -138,6 +155,7 @@ impl AesKey { /// /// Panics if `in_` is not the same length as `out`, if that length is not a multiple of 16, or if /// `iv` is not at least 32 bytes. +#[cfg(not(boringssl))] #[corresponds(AES_ige_encrypt)] pub fn aes_ige(in_: &[u8], out: &mut [u8], key: &AesKey, iv: &mut [u8], mode: Mode) { unsafe { @@ -189,7 +207,7 @@ pub fn wrap_key( .map_or(ptr::null(), |iv| iv.as_ptr() as *const _), out.as_ptr() as *mut _, in_.as_ptr() as *const _, - in_.len() as c_uint, + in_.len() as AesSizeType, ); if written <= 0 { Err(KeyError(())) @@ -228,7 +246,7 @@ pub fn unwrap_key( .map_or(ptr::null(), |iv| iv.as_ptr() as *const _), out.as_ptr() as *mut _, in_.as_ptr() as *const _, - in_.len() as c_uint, + in_.len() as AesSizeType, ); if written <= 0 { @@ -244,10 +262,12 @@ mod test { use hex::FromHex; use super::*; + #[cfg(not(boringssl))] use crate::symm::Mode; // From https://www.mgp25.com/AESIGE/ #[test] + #[cfg(not(boringssl))] fn ige_vector_1() { let raw_key = "000102030405060708090A0B0C0D0E0F"; let raw_iv = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"; diff --git a/openssl/src/base64.rs b/openssl/src/base64.rs index d53c0c05ab..bfa8cbcf8d 100644 --- a/openssl/src/base64.rs +++ b/openssl/src/base64.rs @@ -1,6 +1,6 @@ //! Base64 encoding support. -use crate::cvt_n; use crate::error::ErrorStack; +use crate::{cvt_n, LenType}; use libc::c_int; use openssl_macros::corresponds; @@ -12,7 +12,7 @@ use openssl_macros::corresponds; #[corresponds(EVP_EncodeBlock)] pub fn encode_block(src: &[u8]) -> String { assert!(src.len() <= c_int::max_value() as usize); - let src_len = src.len() as c_int; + let src_len = src.len() as LenType; let len = encoded_len(src_len).unwrap(); let mut out = Vec::with_capacity(len as usize); @@ -43,7 +43,7 @@ pub fn decode_block(src: &str) -> Result, ErrorStack> { } assert!(src.len() <= c_int::max_value() as usize); - let src_len = src.len() as c_int; + let src_len = src.len() as LenType; let len = decoded_len(src_len).unwrap(); let mut out = Vec::with_capacity(len as usize); @@ -72,7 +72,7 @@ pub fn decode_block(src: &str) -> Result, ErrorStack> { Ok(out) } -fn encoded_len(src_len: c_int) -> Option { +fn encoded_len(src_len: LenType) -> Option { let mut len = (src_len / 3).checked_mul(4)?; if src_len % 3 != 0 { @@ -84,7 +84,7 @@ fn encoded_len(src_len: c_int) -> Option { Some(len) } -fn decoded_len(src_len: c_int) -> Option { +fn decoded_len(src_len: LenType) -> Option { let mut len = (src_len / 4).checked_mul(3)?; if src_len % 4 != 0 { diff --git a/openssl/src/bio.rs b/openssl/src/bio.rs index 717ccd0556..6a72552adc 100644 --- a/openssl/src/bio.rs +++ b/openssl/src/bio.rs @@ -67,6 +67,7 @@ impl MemBio { } } + #[cfg(not(boringssl))] pub unsafe fn from_ptr(bio: *mut ffi::BIO) -> MemBio { MemBio(bio) } diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs index 80cfd04229..5de7f7cb38 100644 --- a/openssl/src/bn.rs +++ b/openssl/src/bn.rs @@ -33,7 +33,7 @@ use std::{fmt, ptr}; use crate::asn1::Asn1Integer; use crate::error::ErrorStack; use crate::string::OpensslString; -use crate::{cvt, cvt_n, cvt_p}; +use crate::{cvt, cvt_n, cvt_p, LenType}; use openssl_macros::corresponds; cfg_if! { @@ -43,6 +43,8 @@ cfg_if! { BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096, BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative, }; + } else if #[cfg(boringssl)] { + use ffi::BN_is_negative; } else { use ffi::{ get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024, @@ -839,7 +841,7 @@ impl BigNumRef { /// # use openssl::bn::BigNum; /// let s = -BigNum::from_u32(0x99ff).unwrap(); /// - /// assert_eq!(&**s.to_hex_str().unwrap(), "-99FF"); + /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF"); /// ``` #[corresponds(BN_bn2hex)] pub fn to_hex_str(&self) -> Result { @@ -946,6 +948,7 @@ impl BigNum { /// /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21 #[corresponds(BN_get_rfc2409_prime_768)] + #[cfg(not(boringssl))] pub fn get_rfc2409_prime_768() -> Result { unsafe { ffi::init(); @@ -959,6 +962,7 @@ impl BigNum { /// /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21 #[corresponds(BN_get_rfc2409_prime_1024)] + #[cfg(not(boringssl))] pub fn get_rfc2409_prime_1024() -> Result { unsafe { ffi::init(); @@ -972,6 +976,7 @@ impl BigNum { /// /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3 #[corresponds(BN_get_rfc3526_prime_1536)] + #[cfg(not(boringssl))] pub fn get_rfc3526_prime_1536() -> Result { unsafe { ffi::init(); @@ -985,6 +990,7 @@ impl BigNum { /// /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3 #[corresponds(BN_get_rfc3526_prime_2048)] + #[cfg(not(boringssl))] pub fn get_rfc3526_prime_2048() -> Result { unsafe { ffi::init(); @@ -998,6 +1004,7 @@ impl BigNum { /// /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4 #[corresponds(BN_get_rfc3526_prime_3072)] + #[cfg(not(boringssl))] pub fn get_rfc3526_prime_3072() -> Result { unsafe { ffi::init(); @@ -1011,6 +1018,7 @@ impl BigNum { /// /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4 #[corresponds(BN_get_rfc3526_prime_4096)] + #[cfg(not(boringssl))] pub fn get_rfc3526_prime_4096() -> Result { unsafe { ffi::init(); @@ -1024,6 +1032,7 @@ impl BigNum { /// /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6 #[corresponds(BN_get_rfc3526_prime_6114)] + #[cfg(not(boringssl))] pub fn get_rfc3526_prime_6144() -> Result { unsafe { ffi::init(); @@ -1037,6 +1046,7 @@ impl BigNum { /// /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6 #[corresponds(BN_get_rfc3526_prime_8192)] + #[cfg(not(boringssl))] pub fn get_rfc3526_prime_8192() -> Result { unsafe { ffi::init(); @@ -1061,9 +1071,10 @@ impl BigNum { unsafe { ffi::init(); assert!(n.len() <= c_int::max_value() as usize); + cvt_p(ffi::BN_bin2bn( n.as_ptr(), - n.len() as c_int, + n.len() as LenType, ptr::null_mut(), )) .map(|p| BigNum::from_ptr(p)) diff --git a/openssl/src/cipher.rs b/openssl/src/cipher.rs index 4c49620b43..0e5d85dd15 100644 --- a/openssl/src/cipher.rs +++ b/openssl/src/cipher.rs @@ -16,7 +16,7 @@ use std::ffi::CString; use std::ptr; cfg_if! { - if #[cfg(any(ossl110, libressl273))] { + if #[cfg(any(boringssl, ossl110, libressl273))] { use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; } else { use libc::c_int; @@ -145,34 +145,42 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cbc() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_128_xts() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_xts() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_128_ctr() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_128_cfb1() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb1() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_128_cfb128() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb128() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_128_cfb8() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_128_gcm() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_gcm() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_128_ccm() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_128_ofb() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ofb() as *mut _) } } @@ -195,6 +203,7 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ctr() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_192_cfb1() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) } } @@ -203,6 +212,7 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_192_cfb8() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb8() as *mut _) } } @@ -211,6 +221,7 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_gcm() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_192_ccm() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ccm() as *mut _) } } @@ -237,6 +248,7 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ctr() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_256_cfb1() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) } } @@ -245,6 +257,7 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_256_cfb8() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb8() as *mut _) } } @@ -253,6 +266,7 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_gcm() as *mut _) } } + #[cfg(not(boringssl))] pub fn aes_256_ccm() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ccm() as *mut _) } } @@ -278,11 +292,13 @@ impl Cipher { } #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + #[cfg(not(boringssl))] pub fn bf_cfb64() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) } } #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + #[cfg(not(boringssl))] pub fn bf_ofb() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) } } @@ -303,6 +319,7 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) } } + #[cfg(not(boringssl))] pub fn des_ede3_cfb64() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) } } @@ -322,21 +339,25 @@ impl Cipher { } #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(boringssl))] pub fn seed_cbc() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) } } #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(boringssl))] pub fn seed_cfb128() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) } } #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(boringssl))] pub fn seed_ecb() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) } } #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(boringssl))] pub fn seed_ofb() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) } } diff --git a/openssl/src/cipher_ctx.rs b/openssl/src/cipher_ctx.rs index 1084a8aa57..46492566f9 100644 --- a/openssl/src/cipher_ctx.rs +++ b/openssl/src/cipher_ctx.rs @@ -52,13 +52,14 @@ use crate::cipher::CipherRef; use crate::error::ErrorStack; +#[cfg(not(boringssl))] use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef}; use crate::{cvt, cvt_p}; use cfg_if::cfg_if; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_int, c_uchar}; use openssl_macros::corresponds; -use std::convert::TryFrom; +use std::convert::{TryFrom, TryInto}; use std::ptr; cfg_if! { @@ -182,6 +183,7 @@ impl CipherCtxRef { /// Panics if `pub_keys` is not the same size as `encrypted_keys`, the IV buffer is smaller than the cipher's IV /// size, or if an IV is provided before the cipher. #[corresponds(EVP_SealInit)] + #[cfg(not(boringssl))] pub fn seal_init( &mut self, type_: Option<&CipherRef>, @@ -238,6 +240,7 @@ impl CipherCtxRef { /// Panics if the IV buffer is smaller than the cipher's required IV size or if the IV is provided before the /// cipher. #[corresponds(EVP_OpenInit)] + #[cfg(not(boringssl))] pub fn open_init( &mut self, type_: Option<&CipherRef>, @@ -311,6 +314,7 @@ impl CipherCtxRef { /// /// [`EVP_CIPHER_CTX_rand_key`]: https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_CTX_rand_key.html #[corresponds(EVP_CIPHER_CTX_rand_key)] + #[cfg(not(boringssl))] pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> { assert!(buf.len() >= self.key_length()); @@ -335,10 +339,11 @@ impl CipherCtxRef { pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> { self.assert_cipher(); - let len = c_int::try_from(len).unwrap(); - unsafe { - cvt(ffi::EVP_CIPHER_CTX_set_key_length(self.as_ptr(), len))?; + cvt(ffi::EVP_CIPHER_CTX_set_key_length( + self.as_ptr(), + len.try_into().unwrap(), + ))?; } Ok(()) @@ -584,9 +589,11 @@ impl CipherCtxRef { mod test { use super::*; use crate::cipher::Cipher; + #[cfg(not(boringssl))] use std::slice; #[test] + #[cfg(not(boringssl))] fn seal_open() { let private_pem = include_bytes!("../test/rsa.pem"); let public_pem = include_bytes!("../test/rsa.pem.pub"); diff --git a/openssl/src/conf.rs b/openssl/src/conf.rs index add95f7b48..2c54cf28d0 100644 --- a/openssl/src/conf.rs +++ b/openssl/src/conf.rs @@ -1,38 +1,5 @@ //! Interface for processing OpenSSL configuration files. -use crate::cvt_p; -use crate::error::ErrorStack; -use openssl_macros::corresponds; - -pub struct ConfMethod(*mut ffi::CONF_METHOD); - -impl ConfMethod { - /// Retrieve handle to the default OpenSSL configuration file processing function. - #[corresponds(NCONF_default)] - pub fn default() -> ConfMethod { - unsafe { - ffi::init(); - // `NCONF` stands for "New Conf", as described in crypto/conf/conf_lib.c. This is - // a newer API than the "CONF classic" functions. - ConfMethod(ffi::NCONF_default()) - } - } - - /// Construct from raw pointer. - /// - /// # Safety - /// - /// The caller must ensure that the pointer is valid. - pub unsafe fn from_ptr(ptr: *mut ffi::CONF_METHOD) -> ConfMethod { - ConfMethod(ptr) - } - - /// Convert to raw pointer. - pub fn as_ptr(&self) -> *mut ffi::CONF_METHOD { - self.0 - } -} - foreign_type_and_impl_send_sync! { type CType = ffi::CONF; fn drop = ffi::NCONF_free; @@ -41,18 +8,57 @@ foreign_type_and_impl_send_sync! { pub struct ConfRef; } -impl Conf { - /// Create a configuration parser. - /// - /// # Examples - /// - /// ``` - /// use openssl::conf::{Conf, ConfMethod}; - /// - /// let conf = Conf::new(ConfMethod::default()); - /// ``` - #[corresponds(NCONF_new)] - pub fn new(method: ConfMethod) -> Result { - unsafe { cvt_p(ffi::NCONF_new(method.as_ptr())).map(Conf) } +#[cfg(not(boringssl))] +mod methods { + use super::Conf; + use crate::cvt_p; + use crate::error::ErrorStack; + use openssl_macros::corresponds; + + pub struct ConfMethod(*mut ffi::CONF_METHOD); + + impl ConfMethod { + /// Retrieve handle to the default OpenSSL configuration file processing function. + #[corresponds(NCONF_default)] + pub fn default() -> ConfMethod { + unsafe { + ffi::init(); + // `NCONF` stands for "New Conf", as described in crypto/conf/conf_lib.c. This is + // a newer API than the "CONF classic" functions. + ConfMethod(ffi::NCONF_default()) + } + } + + /// Construct from raw pointer. + /// + /// # Safety + /// + /// The caller must ensure that the pointer is valid. + pub unsafe fn from_ptr(ptr: *mut ffi::CONF_METHOD) -> ConfMethod { + ConfMethod(ptr) + } + + /// Convert to raw pointer. + pub fn as_ptr(&self) -> *mut ffi::CONF_METHOD { + self.0 + } + } + + impl Conf { + /// Create a configuration parser. + /// + /// # Examples + /// + /// ``` + /// use openssl::conf::{Conf, ConfMethod}; + /// + /// let conf = Conf::new(ConfMethod::default()); + /// ``` + #[corresponds(NCONF_new)] + pub fn new(method: ConfMethod) -> Result { + unsafe { cvt_p(ffi::NCONF_new(method.as_ptr())).map(Conf) } + } } } +#[cfg(not(boringssl))] +pub use methods::*; diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs index 9fa5ff9bd0..78fa1c25dc 100644 --- a/openssl/src/dsa.rs +++ b/openssl/src/dsa.rs @@ -178,6 +178,10 @@ where } } } +#[cfg(boringssl)] +type BitType = libc::c_uint; +#[cfg(not(boringssl))] +type BitType = c_int; impl Dsa { /// Generate a DSA key pair. @@ -195,7 +199,7 @@ impl Dsa { let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); cvt(ffi::DSA_generate_parameters_ex( dsa.0, - bits as c_int, + bits as BitType, ptr::null(), 0, ptr::null_mut(), @@ -344,8 +348,11 @@ cfg_if! { mod test { use super::*; use crate::bn::BigNumContext; + #[cfg(not(boringssl))] use crate::hash::MessageDigest; + #[cfg(not(boringssl))] use crate::pkey::PKey; + #[cfg(not(boringssl))] use crate::sign::{Signer, Verifier}; #[test] @@ -397,6 +404,7 @@ mod test { } #[test] + #[cfg(not(boringssl))] fn test_signature() { const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; let dsa_ref = Dsa::generate(1024).unwrap(); diff --git a/openssl/src/ec.rs b/openssl/src/ec.rs index e84a1682d5..d768612c74 100644 --- a/openssl/src/ec.rs +++ b/openssl/src/ec.rs @@ -174,7 +174,7 @@ impl EcGroupRef { /// a term in the polynomial. It will be set to 3 `1`s or 5 `1`s depending on /// using a trinomial or pentanomial. #[corresponds(EC_GROUP_get_curve_GF2m)] - #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_EC2M")))] pub fn components_gf2m( &self, p: &mut BigNumRef, @@ -539,7 +539,7 @@ impl EcPointRef { /// Places affine coordinates of a curve over a binary field in the provided /// `x` and `y` `BigNum`s #[corresponds(EC_POINT_get_affine_coordinates_GF2m)] - #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_EC2M")))] pub fn affine_coordinates_gf2m( &self, group: &EcGroupRef, @@ -1209,7 +1209,7 @@ mod test { } #[test] - #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_EC2M")))] fn is_on_curve() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let mut ctx = BigNumContext::new().unwrap(); diff --git a/openssl/src/ecdsa.rs b/openssl/src/ecdsa.rs index c1ea016e33..0a960e7b9e 100644 --- a/openssl/src/ecdsa.rs +++ b/openssl/src/ecdsa.rs @@ -11,7 +11,7 @@ use crate::ec::EcKeyRef; use crate::error::ErrorStack; use crate::pkey::{HasPrivate, HasPublic}; use crate::util::ForeignTypeRefExt; -use crate::{cvt_n, cvt_p}; +use crate::{cvt_n, cvt_p, LenType}; use openssl_macros::corresponds; foreign_type_and_impl_send_sync! { @@ -35,7 +35,7 @@ impl EcdsaSig { assert!(data.len() <= c_int::max_value() as usize); let sig = cvt_p(ffi::ECDSA_do_sign( data.as_ptr(), - data.len() as c_int, + data.len() as LenType, eckey.as_ptr(), ))?; Ok(EcdsaSig::from_ptr(sig)) @@ -80,7 +80,7 @@ impl EcdsaSigRef { assert!(data.len() <= c_int::max_value() as usize); cvt_n(ffi::ECDSA_do_verify( data.as_ptr(), - data.len() as c_int, + data.len() as LenType, self.as_ptr(), eckey.as_ptr(), )) @@ -160,7 +160,7 @@ mod test { #[test] #[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)] fn sign_and_verify() { - let group = EcGroup::from_curve_name(Nid::X9_62_PRIME192V1).unwrap(); + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let private_key = EcKey::generate(&group).unwrap(); let public_key = get_public_key(&group, &private_key).unwrap(); @@ -188,7 +188,7 @@ mod test { #[test] #[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)] fn check_private_components() { - let group = EcGroup::from_curve_name(Nid::X9_62_PRIME192V1).unwrap(); + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let private_key = EcKey::generate(&group).unwrap(); let public_key = get_public_key(&group, &private_key).unwrap(); let data = String::from("hello"); @@ -208,7 +208,7 @@ mod test { #[test] #[cfg_attr(osslconf = "OPENSSL_NO_EC2M", ignore)] fn serialize_deserialize() { - let group = EcGroup::from_curve_name(Nid::SECP256K1).unwrap(); + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let private_key = EcKey::generate(&group).unwrap(); let public_key = get_public_key(&group, &private_key).unwrap(); diff --git a/openssl/src/error.rs b/openssl/src/error.rs index ab974aa2d9..58b4d70a38 100644 --- a/openssl/src/error.rs +++ b/openssl/src/error.rs @@ -16,8 +16,10 @@ //! } //! ``` use cfg_if::cfg_if; -use libc::{c_char, c_int, c_ulong}; +use libc::{c_char, c_int}; use std::borrow::Cow; +#[cfg(boringssl)] +use std::convert::TryInto; use std::error; use std::ffi::CStr; use std::fmt; @@ -25,6 +27,11 @@ use std::io; use std::ptr; use std::str; +#[cfg(not(boringssl))] +type ErrType = libc::c_ulong; +#[cfg(boringssl)] +type ErrType = libc::c_uint; + /// Collection of [`Error`]s from OpenSSL. /// /// [`Error`]: struct.Error.html @@ -91,7 +98,7 @@ impl From for fmt::Error { /// An error reported from OpenSSL. #[derive(Clone)] pub struct Error { - code: c_ulong, + code: ErrType, file: ShimStr, line: c_int, func: Option, @@ -120,11 +127,14 @@ impl Error { let data = if flags & ffi::ERR_TXT_STRING != 0 { let bytes = CStr::from_ptr(data as *const _).to_bytes(); let data = str::from_utf8(bytes).unwrap(); + #[cfg(not(boringssl))] let data = if flags & ffi::ERR_TXT_MALLOCED != 0 { Cow::Owned(data.to_string()) } else { Cow::Borrowed(data) }; + #[cfg(boringssl)] + let data = Cow::Borrowed(data); Some(data) } else { None @@ -198,19 +208,23 @@ impl Error { #[cfg(not(ossl300))] fn put_error(&self) { + #[cfg(not(boringssl))] + let line = self.line; + #[cfg(boringssl)] + let line = self.line.try_into().unwrap(); unsafe { ffi::ERR_put_error( ffi::ERR_GET_LIB(self.code), ffi::ERR_GET_FUNC(self.code), ffi::ERR_GET_REASON(self.code), self.file.as_ptr(), - self.line, + line, ); } } /// Returns the raw OpenSSL error code for this error. - pub fn code(&self) -> c_ulong { + pub fn code(&self) -> ErrType { self.code } @@ -340,7 +354,7 @@ cfg_if! { func: *mut *const c_char, data: *mut *const c_char, flags: *mut c_int, - ) -> c_ulong { + ) -> ErrType { let code = ffi::ERR_get_error_line_data(file, line, data, flags); *func = ffi::ERR_func_error_string(code); code diff --git a/openssl/src/hash.rs b/openssl/src/hash.rs index ea886f1aed..fd83869c9a 100644 --- a/openssl/src/hash.rs +++ b/openssl/src/hash.rs @@ -65,6 +65,7 @@ impl MessageDigest { } } + #[cfg(not(boringssl))] pub fn null() -> MessageDigest { unsafe { MessageDigest(ffi::EVP_md_null()) } } @@ -123,7 +124,7 @@ impl MessageDigest { unsafe { MessageDigest(ffi::EVP_shake256()) } } - #[cfg(not(osslconf = "OPENSSL_NO_RMD160"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_RMD160")))] pub fn ripemd160() -> MessageDigest { unsafe { MessageDigest(ffi::EVP_ripemd160()) } } @@ -285,7 +286,10 @@ impl Hasher { self.init()?; } unsafe { + #[cfg(not(boringssl))] let mut len = ffi::EVP_MAX_MD_SIZE; + #[cfg(boringssl)] + let mut len = ffi::EVP_MAX_MD_SIZE as u32; let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize]; cvt(ffi::EVP_DigestFinal_ex( self.ctx, @@ -706,6 +710,8 @@ mod tests { } #[test] + #[cfg(not(boringssl))] + #[cfg_attr(ossl300, ignore)] fn test_ripemd160() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index 71221adecc..7b4f1ee1a5 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -139,7 +139,7 @@ pub mod base64; pub mod bn; pub mod cipher; pub mod cipher_ctx; -#[cfg(all(not(libressl), not(osslconf = "OPENSSL_NO_CMS")))] +#[cfg(all(not(boringssl), not(libressl), not(osslconf = "OPENSSL_NO_CMS")))] pub mod cms; pub mod conf; pub mod derive; @@ -148,6 +148,7 @@ pub mod dsa; pub mod ec; pub mod ecdsa; pub mod encrypt; +#[cfg(not(boringssl))] pub mod envelope; pub mod error; pub mod ex_data; @@ -160,10 +161,12 @@ pub mod md; pub mod md_ctx; pub mod memcmp; pub mod nid; -#[cfg(not(osslconf = "OPENSSL_NO_OCSP"))] +#[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_OCSP")))] pub mod ocsp; pub mod pkcs12; +#[cfg(not(boringssl))] pub mod pkcs5; +#[cfg(not(boringssl))] pub mod pkcs7; pub mod pkey; pub mod pkey_ctx; @@ -181,6 +184,11 @@ pub mod symm; pub mod version; pub mod x509; +#[cfg(boringssl)] +type LenType = libc::size_t; +#[cfg(not(boringssl))] +type LenType = libc::c_int; + #[inline] fn cvt_p(r: *mut T) -> Result<*mut T, ErrorStack> { if r.is_null() { diff --git a/openssl/src/macros.rs b/openssl/src/macros.rs index c448bcd6ef..671a11b82d 100644 --- a/openssl/src/macros.rs +++ b/openssl/src/macros.rs @@ -106,10 +106,11 @@ macro_rules! from_der { ($(#[$m:meta])* $n:ident, $t:ty, $f:path) => { $(#[$m])* pub fn $n(der: &[u8]) -> Result<$t, crate::error::ErrorStack> { + use std::convert::TryInto; unsafe { ffi::init(); let len = ::std::cmp::min(der.len(), ::libc::c_long::max_value() as usize) as ::libc::c_long; - crate::cvt_p($f(::std::ptr::null_mut(), &mut der.as_ptr(), len)) + crate::cvt_p($f(::std::ptr::null_mut(), &mut der.as_ptr(), len.try_into().unwrap())) .map(|p| ::foreign_types::ForeignType::from_ptr(p)) } } diff --git a/openssl/src/md.rs b/openssl/src/md.rs index 922521e9f6..b9297e29a7 100644 --- a/openssl/src/md.rs +++ b/openssl/src/md.rs @@ -113,6 +113,7 @@ impl Md { } #[inline] + #[cfg(not(boringssl))] pub fn null() -> &'static MdRef { unsafe { MdRef::from_ptr(ffi::EVP_md_null() as *mut _) } } @@ -185,12 +186,14 @@ impl Md { #[cfg(not(osslconf = "OPENSSL_NO_RMD160"))] #[inline] + #[cfg(not(boringssl))] pub fn ripemd160() -> &'static MdRef { unsafe { MdRef::from_ptr(ffi::EVP_ripemd160() as *mut _) } } #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))] #[inline] + #[cfg(not(boringssl))] pub fn sm3() -> &'static MdRef { unsafe { MdRef::from_ptr(ffi::EVP_sm3() as *mut _) } } diff --git a/openssl/src/md_ctx.rs b/openssl/src/md_ctx.rs index 1106460e98..c4d3f06b94 100644 --- a/openssl/src/md_ctx.rs +++ b/openssl/src/md_ctx.rs @@ -50,31 +50,37 @@ //! assert!(valid); //! ``` //! -//! Compute and verify an HMAC-SHA256 -//! -//! ``` -//! use openssl::md::Md; -//! use openssl::md_ctx::MdCtx; -//! use openssl::memcmp; -//! use openssl::pkey::PKey; -//! -//! // Create a key with the HMAC secret. -//! let key = PKey::hmac(b"my secret").unwrap(); -//! -//! let text = b"Some Crypto Text"; -//! -//! // Compute the HMAC. -//! let mut ctx = MdCtx::new().unwrap(); -//! ctx.digest_sign_init(Some(Md::sha256()), &key).unwrap(); -//! ctx.digest_sign_update(text).unwrap(); -//! let mut hmac = vec![]; -//! ctx.digest_sign_final_to_vec(&mut hmac).unwrap(); -//! -//! // Verify the HMAC. You can't use MdCtx to do this; instead use a constant time equality check. -//! # let target = hmac.clone(); -//! let valid = memcmp::eq(&hmac, &target); -//! assert!(valid); -//! ``` + +#![cfg_attr( + not(boringssl), + doc = r#"\ +Compute and verify an HMAC-SHA256 + +``` +use openssl::md::Md; +use openssl::md_ctx::MdCtx; +use openssl::memcmp; +use openssl::pkey::PKey; + +// Create a key with the HMAC secret. +let key = PKey::hmac(b"my secret").unwrap(); + +let text = b"Some Crypto Text"; + +// Compute the HMAC. +let mut ctx = MdCtx::new().unwrap(); +ctx.digest_sign_init(Some(Md::sha256()), &key).unwrap(); +ctx.digest_sign_update(text).unwrap(); +let mut hmac = vec![]; +ctx.digest_sign_final_to_vec(&mut hmac).unwrap(); + +// Verify the HMAC. You can't use MdCtx to do this; instead use a constant time equality check. +# let target = hmac.clone(); +let valid = memcmp::eq(&hmac, &target); +assert!(valid); +```"# +)] + use crate::error::ErrorStack; use crate::md::MdRef; use crate::pkey::{HasPrivate, HasPublic, PKeyRef}; diff --git a/openssl/src/nid.rs b/openssl/src/nid.rs index 68174e679c..355bba10ee 100644 --- a/openssl/src/nid.rs +++ b/openssl/src/nid.rs @@ -120,9 +120,11 @@ impl Nid { pub const UNDEF: Nid = Nid(ffi::NID_undef); pub const ITU_T: Nid = Nid(ffi::NID_itu_t); + #[cfg(not(boringssl))] pub const CCITT: Nid = Nid(ffi::NID_ccitt); pub const ISO: Nid = Nid(ffi::NID_iso); pub const JOINT_ISO_ITU_T: Nid = Nid(ffi::NID_joint_iso_itu_t); + #[cfg(not(boringssl))] pub const JOINT_ISO_CCITT: Nid = Nid(ffi::NID_joint_iso_ccitt); pub const MEMBER_BODY: Nid = Nid(ffi::NID_member_body); pub const IDENTIFIED_ORGANIZATION: Nid = Nid(ffi::NID_identified_organization); diff --git a/openssl/src/pkcs12.rs b/openssl/src/pkcs12.rs index 3bc4749e01..d4e19dc9f3 100644 --- a/openssl/src/pkcs12.rs +++ b/openssl/src/pkcs12.rs @@ -6,6 +6,7 @@ use std::ffi::CString; use std::ptr; use crate::error::ErrorStack; +#[cfg(not(boringssl))] use crate::hash::MessageDigest; use crate::nid::Nid; use crate::pkey::{HasPrivate, PKey, PKeyRef, Private}; @@ -76,7 +77,7 @@ impl Pkcs12 { /// * `nid_cert` - `AES_256_CBC` (3.0.0+) or `PBE_WITHSHA1AND40BITRC2_CBC` /// * `iter` - `2048` /// * `mac_iter` - `2048` - /// * `mac_md` - `SHA-256` (3.0.0+) or `SHA-1` + /// * `mac_md` - `SHA-256` (3.0.0+) or `SHA-1` (`SHA-1` only for BoringSSL) pub fn builder() -> Pkcs12Builder { ffi::init(); @@ -85,6 +86,7 @@ impl Pkcs12 { nid_cert: Nid::UNDEF, iter: ffi::PKCS12_DEFAULT_ITER, mac_iter: ffi::PKCS12_DEFAULT_ITER, + #[cfg(not(boringssl))] mac_md: None, ca: None, } @@ -102,6 +104,7 @@ pub struct Pkcs12Builder { nid_cert: Nid, iter: c_int, mac_iter: c_int, + #[cfg(not(boringssl))] mac_md: Option, ca: Option>, } @@ -135,6 +138,7 @@ impl Pkcs12Builder { } /// MAC message digest type + #[cfg(not(boringssl))] pub fn mac_md(&mut self, md: MessageDigest) -> &mut Self { self.mac_md = Some(md); self @@ -178,10 +182,6 @@ impl Pkcs12Builder { .unwrap_or(ptr::null_mut()); let nid_key = self.nid_key.as_raw(); let nid_cert = self.nid_cert.as_raw(); - let md_type = self - .mac_md - .map(|md_type| md_type.as_ptr()) - .unwrap_or(ptr::null()); // According to the OpenSSL docs, keytype is a non-standard extension for MSIE, // It's values are KEY_SIG or KEY_EX, see the OpenSSL docs for more information: @@ -197,20 +197,30 @@ impl Pkcs12Builder { nid_key, nid_cert, self.iter, - -1, + self.mac_iter, keytype, )) .map(Pkcs12)?; - cvt(ffi::PKCS12_set_mac( - pkcs12.as_ptr(), - pass.as_ptr(), - -1, - ptr::null_mut(), - 0, - self.mac_iter, - md_type, - ))?; + #[cfg(not(boringssl))] + // BoringSSL does not support overriding the MAC and will always + // use SHA-1 + { + let md_type = self + .mac_md + .map(|md_type| md_type.as_ptr()) + .unwrap_or(ptr::null()); + + cvt(ffi::PKCS12_set_mac( + pkcs12.as_ptr(), + pass.as_ptr(), + -1, + ptr::null_mut(), + 0, + self.mac_iter, + md_type, + ))?; + } Ok(pkcs12) } @@ -259,7 +269,9 @@ mod test { let der = include_bytes!("../test/keystore-empty-chain.p12"); let pkcs12 = Pkcs12::from_der(der).unwrap(); let parsed = pkcs12.parse("cassandra").unwrap(); - assert!(parsed.chain.is_none()); + if let Some(stack) = parsed.chain { + assert_eq!(stack.len(), 0); + } } #[test] diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 604843b1e0..1e09b77b54 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -78,7 +78,9 @@ pub struct Id(c_int); impl Id { pub const RSA: Id = Id(ffi::EVP_PKEY_RSA); + #[cfg(not(boringssl))] pub const HMAC: Id = Id(ffi::EVP_PKEY_HMAC); + #[cfg(not(boringssl))] pub const CMAC: Id = Id(ffi::EVP_PKEY_CMAC); pub const DSA: Id = Id(ffi::EVP_PKEY_DSA); pub const DH: Id = Id(ffi::EVP_PKEY_DH); @@ -347,6 +349,7 @@ impl fmt::Debug for PKey { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let alg = match self.id() { Id::RSA => "RSA", + #[cfg(not(boringssl))] Id::HMAC => "HMAC", Id::DSA => "DSA", Id::DH => "DH", @@ -441,6 +444,7 @@ impl PKey { /// /// To compute HMAC values, use the `sign` module. #[corresponds(EVP_PKEY_new_mac_key)] + #[cfg(not(boringssl))] pub fn hmac(key: &[u8]) -> Result, ErrorStack> { unsafe { assert!(key.len() <= c_int::max_value() as usize); @@ -461,7 +465,7 @@ impl PKey { /// # Note /// /// To compute CMAC values, use the `sign` module. - #[cfg(ossl110)] + #[cfg(all(not(boringssl), ossl110))] #[allow(clippy::trivially_copy_pass_by_ref)] pub fn cmac(cipher: &Cipher, key: &[u8]) -> Result, ErrorStack> { let mut ctx = PkeyCtx::new_id(Id::CMAC)?; @@ -681,7 +685,7 @@ impl PKey { } cfg_if! { - if #[cfg(any(ossl110, libressl270))] { + if #[cfg(any(boringssl, ossl110, libressl270))] { use ffi::EVP_PKEY_up_ref; } else { #[allow(bad_style)] @@ -765,6 +769,7 @@ impl TryFrom> for Dh { mod tests { use std::convert::TryInto; + #[cfg(not(boringssl))] use crate::dh::Dh; use crate::dsa::Dsa; use crate::ec::EcKey; @@ -881,6 +886,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_dh_accessor() { let dh = include_bytes!("../test/dhparams.pem"); let dh = Dh::params_from_pem(dh).unwrap(); @@ -929,6 +935,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_dh_conversion() { let dh_params = include_bytes!("../test/dhparams.pem"); let dh_params = Dh::params_from_pem(dh_params).unwrap(); diff --git a/openssl/src/pkey_ctx.rs b/openssl/src/pkey_ctx.rs index 52be72f1a8..f79372fb11 100644 --- a/openssl/src/pkey_ctx.rs +++ b/openssl/src/pkey_ctx.rs @@ -19,20 +19,25 @@ //! let mut ciphertext = vec![]; //! ctx.encrypt_to_vec(data, &mut ciphertext).unwrap(); //! ``` -//! -//! Generate a CMAC key -//! -//! ``` -//! use openssl::pkey_ctx::PkeyCtx; -//! use openssl::pkey::Id; -//! use openssl::cipher::Cipher; -//! -//! let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap(); -//! ctx.keygen_init().unwrap(); -//! ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap(); -//! ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap(); -//! let cmac_key = ctx.keygen().unwrap(); -//! ``` + +#![cfg_attr( + not(boringssl), + doc = r#"\ +Generate a CMAC key + +``` +use openssl::pkey_ctx::PkeyCtx; +use openssl::pkey::Id; +use openssl::cipher::Cipher; + +let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap(); +ctx.keygen_init().unwrap(); +ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap(); +ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap(); +let cmac_key = ctx.keygen().unwrap(); +```"# +)] + //! //! Sign and verify data with RSA //! @@ -59,6 +64,7 @@ //! let valid = ctx.verify(text, &signature).unwrap(); //! assert!(valid); //! ``` +#[cfg(not(boringssl))] use crate::cipher::CipherRef; use crate::error::ErrorStack; use crate::md::MdRef; @@ -66,6 +72,7 @@ use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private}; use crate::rsa::Padding; use crate::{cvt, cvt_n, cvt_p}; use foreign_types::{ForeignType, ForeignTypeRef}; +#[cfg(not(boringssl))] use libc::c_int; use openssl_macros::corresponds; use std::convert::TryFrom; @@ -396,15 +403,20 @@ impl PkeyCtxRef { /// /// This is only useful for RSA keys. #[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)] - #[cfg(any(ossl102, libressl310))] + #[cfg(any(ossl102, libressl310, boringssl))] pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> { - let len = c_int::try_from(label.len()).unwrap(); + use crate::LenType; + let len = LenType::try_from(label.len()).unwrap(); unsafe { let p = ffi::OPENSSL_malloc(label.len() as _); ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len()); - let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label(self.as_ptr(), p, len)); + let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label( + self.as_ptr(), + p as *mut _, + len, + )); if r.is_err() { ffi::OPENSSL_free(p); } @@ -415,6 +427,7 @@ impl PkeyCtxRef { } /// Sets the cipher used during key generation. + #[cfg(not(boringssl))] #[corresponds(EVP_PKEY_CTX_ctrl)] #[inline] pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> { @@ -433,6 +446,7 @@ impl PkeyCtxRef { } /// Sets the key MAC key used during key generation. + #[cfg(not(boringssl))] #[corresponds(EVP_PKEY_CTX_ctrl)] #[inline] pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> { @@ -587,6 +601,7 @@ impl PkeyCtxRef { #[cfg(test)] mod test { use super::*; + #[cfg(not(boringssl))] use crate::cipher::Cipher; use crate::ec::{EcGroup, EcKey}; #[cfg(any(ossl102, libressl310))] @@ -663,6 +678,7 @@ mod test { } #[test] + #[cfg(not(boringssl))] fn cmac_keygen() { let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap(); ctx.keygen_init().unwrap(); diff --git a/openssl/src/rand.rs b/openssl/src/rand.rs index 3a54b33f04..8317951f81 100644 --- a/openssl/src/rand.rs +++ b/openssl/src/rand.rs @@ -12,8 +12,8 @@ //! ``` use libc::c_int; -use crate::cvt; use crate::error::ErrorStack; +use crate::{cvt, LenType}; use openssl_macros::corresponds; /// Fill buffer with cryptographically strong pseudo-random bytes. @@ -33,7 +33,7 @@ pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> { unsafe { ffi::init(); assert!(buf.len() <= c_int::max_value() as usize); - cvt(ffi::RAND_bytes(buf.as_mut_ptr(), buf.len() as c_int)).map(|_| ()) + cvt(ffi::RAND_bytes(buf.as_mut_ptr(), buf.len() as LenType)).map(|_| ()) } } @@ -44,7 +44,7 @@ pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> { #[cfg(ossl111)] pub fn keep_random_devices_open(keep: bool) { unsafe { - ffi::RAND_keep_random_devices_open(keep as c_int); + ffi::RAND_keep_random_devices_open(keep as LenType); } } diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 1ccce25087..b5d096744a 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -34,7 +34,7 @@ use crate::bn::{BigNum, BigNumRef}; use crate::error::ErrorStack; use crate::pkey::{HasPrivate, HasPublic, Private, Public}; use crate::util::ForeignTypeRefExt; -use crate::{cvt, cvt_n, cvt_p}; +use crate::{cvt, cvt_n, cvt_p, LenType}; use openssl_macros::corresponds; /// Type of encryption padding to use. @@ -134,7 +134,7 @@ where unsafe { let len = cvt_n(ffi::RSA_private_decrypt( - from.len() as c_int, + from.len() as LenType, from.as_ptr(), to.as_mut_ptr(), self.as_ptr(), @@ -162,7 +162,7 @@ where unsafe { let len = cvt_n(ffi::RSA_private_encrypt( - from.len() as c_int, + from.len() as LenType, from.as_ptr(), to.as_mut_ptr(), self.as_ptr(), @@ -305,7 +305,7 @@ where unsafe { let len = cvt_n(ffi::RSA_public_decrypt( - from.len() as c_int, + from.len() as LenType, from.as_ptr(), to.as_mut_ptr(), self.as_ptr(), @@ -332,7 +332,7 @@ where unsafe { let len = cvt_n(ffi::RSA_public_encrypt( - from.len() as c_int, + from.len() as LenType, from.as_ptr(), to.as_mut_ptr(), self.as_ptr(), diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index d813623530..457ff1228d 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -34,33 +34,39 @@ //! verifier.update(data2).unwrap(); //! assert!(verifier.verify(&signature).unwrap()); //! ``` -//! -//! Compute an HMAC: -//! -//! ```rust -//! use openssl::hash::MessageDigest; -//! use openssl::memcmp; -//! use openssl::pkey::PKey; -//! use openssl::sign::Signer; -//! -//! // Create a PKey -//! let key = PKey::hmac(b"my secret").unwrap(); -//! -//! let data = b"hello, world!"; -//! let data2 = b"hola, mundo!"; -//! -//! // Compute the HMAC -//! let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap(); -//! signer.update(data).unwrap(); -//! signer.update(data2).unwrap(); -//! let hmac = signer.sign_to_vec().unwrap(); -//! -//! // `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead -//! // -//! // Do not simply check for equality with `==`! -//! # let target = hmac.clone(); -//! assert!(memcmp::eq(&hmac, &target)); -//! ``` + +#![cfg_attr( + not(boringssl), + doc = r#"\ + +Compute an HMAC: + +```rust +use openssl::hash::MessageDigest; +use openssl::memcmp; +use openssl::pkey::PKey; +use openssl::sign::Signer; + +// Create a PKey +let key = PKey::hmac(b"my secret").unwrap(); + +let data = b"hello, world!"; +let data2 = b"hola, mundo!"; + +// Compute the HMAC +let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap(); +signer.update(data).unwrap(); +signer.update(data2).unwrap(); +let hmac = signer.sign_to_vec().unwrap(); + +// `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead +// +// Do not simply check for equality with `==`! +# let target = hmac.clone(); +assert!(memcmp::eq(&hmac, &target)); +```"# +)] + use cfg_if::cfg_if; use foreign_types::ForeignTypeRef; use libc::c_int; @@ -637,6 +643,7 @@ unsafe fn EVP_DigestVerifyFinal( #[cfg(test)] mod test { use hex::{self, FromHex}; + #[cfg(not(boringssl))] use std::iter; use crate::ec::{EcGroup, EcKey}; @@ -700,6 +707,7 @@ mod test { assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap()); } + #[cfg(not(boringssl))] fn test_hmac(ty: MessageDigest, tests: &[(Vec, Vec, Vec)]) { for &(ref key, ref data, ref res) in tests.iter() { let pkey = PKey::hmac(key).unwrap(); @@ -710,6 +718,7 @@ mod test { } #[test] + #[cfg(not(boringssl))] fn hmac_md5() { // test vectors from RFC 2202 let tests: [(Vec, Vec, Vec); 7] = [ @@ -756,6 +765,7 @@ mod test { } #[test] + #[cfg(not(boringssl))] fn hmac_sha1() { // test vectors from RFC 2202 let tests: [(Vec, Vec, Vec); 7] = [ diff --git a/openssl/src/srtp.rs b/openssl/src/srtp.rs index bddddaf49b..7ed3135963 100644 --- a/openssl/src/srtp.rs +++ b/openssl/src/srtp.rs @@ -36,12 +36,16 @@ impl SrtpProtectionProfileRef { pub struct SrtpProfileId(c_ulong); impl SrtpProfileId { - pub const SRTP_AES128_CM_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_80); - pub const SRTP_AES128_CM_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_32); - pub const SRTP_AES128_F8_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_80); - pub const SRTP_AES128_F8_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_32); - pub const SRTP_NULL_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_80); - pub const SRTP_NULL_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_32); + pub const SRTP_AES128_CM_SHA1_80: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_80 as c_ulong); + pub const SRTP_AES128_CM_SHA1_32: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_32 as c_ulong); + pub const SRTP_AES128_F8_SHA1_80: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_80 as c_ulong); + pub const SRTP_AES128_F8_SHA1_32: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_32 as c_ulong); + pub const SRTP_NULL_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_80 as c_ulong); + pub const SRTP_NULL_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_32 as c_ulong); #[cfg(ossl110)] pub const SRTP_AEAD_AES_128_GCM: SrtpProfileId = SrtpProfileId(ffi::SRTP_AEAD_AES_128_GCM); #[cfg(ossl110)] diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs index f33f6ec0aa..45760dc66a 100644 --- a/openssl/src/ssl/callbacks.rs +++ b/openssl/src/ssl/callbacks.rs @@ -388,7 +388,7 @@ pub unsafe extern "C" fn raw_remove_session( } cfg_if! { - if #[cfg(any(ossl110, libressl280))] { + if #[cfg(any(ossl110, libressl280, boringssl))] { type DataPtr = *const c_uchar; } else { type DataPtr = *mut c_uchar; @@ -486,6 +486,7 @@ where (*callback)(ssl, slice) as c_int } +#[cfg(not(boringssl))] pub extern "C" fn raw_cookie_generate( ssl: *mut ffi::SSL, cookie: *mut c_uchar, @@ -517,6 +518,7 @@ where } } +#[cfg(not(boringssl))] cfg_if! { if #[cfg(any(ossl110, libressl280))] { type CookiePtr = *const c_uchar; @@ -525,6 +527,7 @@ cfg_if! { } } +#[cfg(not(boringssl))] pub extern "C" fn raw_cookie_verify( ssl: *mut ffi::SSL, cookie: CookiePtr, diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index e398458010..1039425f80 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -27,15 +27,19 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== fn ctx(method: SslMethod) -> Result { let mut ctx = SslContextBuilder::new(method)?; - let mut opts = SslOptions::ALL - | SslOptions::NO_COMPRESSION - | SslOptions::NO_SSLV2 - | SslOptions::NO_SSLV3 - | SslOptions::SINGLE_DH_USE - | SslOptions::SINGLE_ECDH_USE; - opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS; - - ctx.set_options(opts); + cfg_if! { + if #[cfg(not(boringssl))] { + let mut opts = SslOptions::ALL + | SslOptions::NO_COMPRESSION + | SslOptions::NO_SSLV2 + | SslOptions::NO_SSLV3 + | SslOptions::SINGLE_DH_USE + | SslOptions::SINGLE_ECDH_USE; + opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS; + + ctx.set_options(opts); + } + } let mut mode = SslMode::AUTO_RETRY | SslMode::ACCEPT_MOVING_WRITE_BUFFER | SslMode::ENABLE_PARTIAL_WRITE; diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 0ca6814a77..1325a86991 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -134,6 +134,8 @@ pub fn cipher_name(std_name: &str) -> &'static str { cfg_if! { if #[cfg(ossl300)] { type SslOptionsRepr = u64; + } else if #[cfg(boringssl)] { + type SslOptionsRepr = u32; } else { type SslOptionsRepr = libc::c_ulong; } @@ -143,88 +145,92 @@ bitflags! { /// Options controlling the behavior of an `SslContext`. pub struct SslOptions: SslOptionsRepr { /// Disables a countermeasure against an SSLv3/TLSv1.0 vulnerability affecting CBC ciphers. - const DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + const DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS as SslOptionsRepr; /// A "reasonable default" set of options which enables compatibility flags. - const ALL = ffi::SSL_OP_ALL; + #[cfg(not(boringssl))] + const ALL = ffi::SSL_OP_ALL as SslOptionsRepr; /// Do not query the MTU. /// /// Only affects DTLS connections. - const NO_QUERY_MTU = ffi::SSL_OP_NO_QUERY_MTU; + const NO_QUERY_MTU = ffi::SSL_OP_NO_QUERY_MTU as SslOptionsRepr; /// Enables Cookie Exchange as described in [RFC 4347 Section 4.2.1]. /// /// Only affects DTLS connections. /// /// [RFC 4347 Section 4.2.1]: https://tools.ietf.org/html/rfc4347#section-4.2.1 - const COOKIE_EXCHANGE = ffi::SSL_OP_COOKIE_EXCHANGE; + #[cfg(not(boringssl))] + const COOKIE_EXCHANGE = ffi::SSL_OP_COOKIE_EXCHANGE as SslOptionsRepr; /// Disables the use of session tickets for session resumption. - const NO_TICKET = ffi::SSL_OP_NO_TICKET; + const NO_TICKET = ffi::SSL_OP_NO_TICKET as SslOptionsRepr; /// Always start a new session when performing a renegotiation on the server side. + #[cfg(not(boringssl))] const NO_SESSION_RESUMPTION_ON_RENEGOTIATION = - ffi::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; + ffi::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION as SslOptionsRepr; /// Disables the use of TLS compression. - const NO_COMPRESSION = ffi::SSL_OP_NO_COMPRESSION; + #[cfg(not(boringssl))] + const NO_COMPRESSION = ffi::SSL_OP_NO_COMPRESSION as SslOptionsRepr; /// Allow legacy insecure renegotiation with servers or clients that do not support secure /// renegotiation. const ALLOW_UNSAFE_LEGACY_RENEGOTIATION = - ffi::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; + ffi::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION as SslOptionsRepr; /// Creates a new key for each session when using ECDHE. /// /// This is always enabled in OpenSSL 1.1.0. - const SINGLE_ECDH_USE = ffi::SSL_OP_SINGLE_ECDH_USE; + const SINGLE_ECDH_USE = ffi::SSL_OP_SINGLE_ECDH_USE as SslOptionsRepr; /// Creates a new key for each session when using DHE. /// /// This is always enabled in OpenSSL 1.1.0. - const SINGLE_DH_USE = ffi::SSL_OP_SINGLE_DH_USE; + const SINGLE_DH_USE = ffi::SSL_OP_SINGLE_DH_USE as SslOptionsRepr; /// Use the server's preferences rather than the client's when selecting a cipher. /// /// This has no effect on the client side. - const CIPHER_SERVER_PREFERENCE = ffi::SSL_OP_CIPHER_SERVER_PREFERENCE; + const CIPHER_SERVER_PREFERENCE = ffi::SSL_OP_CIPHER_SERVER_PREFERENCE as SslOptionsRepr; /// Disables version rollback attach detection. - const TLS_ROLLBACK_BUG = ffi::SSL_OP_TLS_ROLLBACK_BUG; + const TLS_ROLLBACK_BUG = ffi::SSL_OP_TLS_ROLLBACK_BUG as SslOptionsRepr; /// Disables the use of SSLv2. - const NO_SSLV2 = ffi::SSL_OP_NO_SSLv2; + const NO_SSLV2 = ffi::SSL_OP_NO_SSLv2 as SslOptionsRepr; /// Disables the use of SSLv3. - const NO_SSLV3 = ffi::SSL_OP_NO_SSLv3; + const NO_SSLV3 = ffi::SSL_OP_NO_SSLv3 as SslOptionsRepr; /// Disables the use of TLSv1.0. - const NO_TLSV1 = ffi::SSL_OP_NO_TLSv1; + const NO_TLSV1 = ffi::SSL_OP_NO_TLSv1 as SslOptionsRepr; /// Disables the use of TLSv1.1. - const NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1; + const NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1 as SslOptionsRepr; /// Disables the use of TLSv1.2. - const NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2; + const NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2 as SslOptionsRepr; /// Disables the use of TLSv1.3. /// /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. - #[cfg(any(ossl111, libressl340))] - const NO_TLSV1_3 = ffi::SSL_OP_NO_TLSv1_3; + #[cfg(any(boringssl, ossl111, libressl340))] + const NO_TLSV1_3 = ffi::SSL_OP_NO_TLSv1_3 as SslOptionsRepr; /// Disables the use of DTLSv1.0 /// /// Requires OpenSSL 1.0.2 or LibreSSL 3.3.2 or newer. - #[cfg(any(ossl102, ossl110, libressl332))] - const NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1; + #[cfg(any(boringssl, ossl102, ossl110, libressl332))] + const NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1 as SslOptionsRepr; /// Disables the use of DTLSv1.2. /// /// Requires OpenSSL 1.0.2 or LibreSSL 3.3.2 or newer. - #[cfg(any(ossl102, ossl110, libressl332))] - const NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2; + #[cfg(any(boringssl, ossl102, ossl110, libressl332))] + const NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2 as SslOptionsRepr; /// Disables the use of all (D)TLS protocol versions. /// @@ -242,20 +248,20 @@ bitflags! { /// let options = SslOptions::NO_SSL_MASK & !SslOptions::NO_TLSV1_2; /// ``` #[cfg(any(ossl102, ossl110))] - const NO_SSL_MASK = ffi::SSL_OP_NO_SSL_MASK; + const NO_SSL_MASK = ffi::SSL_OP_NO_SSL_MASK as SslOptionsRepr; /// Disallow all renegotiation in TLSv1.2 and earlier. /// /// Requires OpenSSL 1.1.0h or newer. - #[cfg(ossl110h)] - const NO_RENEGOTIATION = ffi::SSL_OP_NO_RENEGOTIATION; + #[cfg(any(boringssl, ossl110h))] + const NO_RENEGOTIATION = ffi::SSL_OP_NO_RENEGOTIATION as SslOptionsRepr; /// Enable TLSv1.3 Compatibility mode. /// /// Requires OpenSSL 1.1.1 or newer. This is on by default in 1.1.1, but a future version /// may have this disabled by default. #[cfg(ossl111)] - const ENABLE_MIDDLEBOX_COMPAT = ffi::SSL_OP_ENABLE_MIDDLEBOX_COMPAT; + const ENABLE_MIDDLEBOX_COMPAT = ffi::SSL_OP_ENABLE_MIDDLEBOX_COMPAT as SslOptionsRepr; /// Prioritize ChaCha ciphers when preferred by clients. /// @@ -269,13 +275,13 @@ bitflags! { /// /// [`SslOptions::CIPHER_SERVER_PREFERENCE`]: struct.SslOptions.html#associatedconstant.CIPHER_SERVER_PREFERENCE #[cfg(ossl111)] - const PRIORITIZE_CHACHA = ffi::SSL_OP_PRIORITIZE_CHACHA; + const PRIORITIZE_CHACHA = ffi::SSL_OP_PRIORITIZE_CHACHA as SslOptionsRepr; } } bitflags! { /// Options controlling the behavior of an `SslContext`. - pub struct SslMode: c_long { + pub struct SslMode: SslBitType { /// Enables "short writes". /// /// Normally, a write in OpenSSL will always write out all of the requested data, even if it @@ -392,9 +398,19 @@ bitflags! { } } +#[cfg(boringssl)] +type SslBitType = c_int; +#[cfg(not(boringssl))] +type SslBitType = c_long; + +#[cfg(boringssl)] +type SslTimeTy = u64; +#[cfg(not(boringssl))] +type SslTimeTy = c_long; + bitflags! { /// Options controlling the behavior of session caching. - pub struct SslSessionCacheMode: c_long { + pub struct SslSessionCacheMode: SslBitType { /// No session caching for the client or server takes place. const OFF = ffi::SSL_SESS_CACHE_OFF; @@ -630,6 +646,20 @@ impl SslVersion { pub const TLS1_3: SslVersion = SslVersion(ffi::TLS1_3_VERSION); } +cfg_if! { + if #[cfg(boringssl)] { + type SslCacheTy = i64; + type SslCacheSize = libc::c_ulong; + type MtuTy = u32; + type SizeTy = usize; + } else { + type SslCacheTy = i64; + type SslCacheSize = c_long; + type MtuTy = c_long; + type SizeTy = u32; + } +} + /// A standard implementation of protocol selection for Application Layer Protocol Negotiation /// (ALPN). /// @@ -736,7 +766,9 @@ impl SslContextBuilder { // still stored in ex data to manage the lifetime. let arg = self.set_ex_data_inner(SslContext::cached_ex_index::(), callback); ffi::SSL_CTX_set_tlsext_servername_arg(self.as_ptr(), arg); - + #[cfg(boringssl)] + ffi::SSL_CTX_set_tlsext_servername_callback(self.as_ptr(), Some(raw_sni::)); + #[cfg(not(boringssl))] ffi::SSL_CTX_set_tlsext_servername_callback__fixed_rust( self.as_ptr(), Some(raw_sni::), @@ -787,7 +819,7 @@ impl SslContextBuilder { #[corresponds(SSL_CTX_set_read_ahead)] pub fn set_read_ahead(&mut self, read_ahead: bool) { unsafe { - ffi::SSL_CTX_set_read_ahead(self.as_ptr(), read_ahead as c_long); + ffi::SSL_CTX_set_read_ahead(self.as_ptr(), read_ahead as SslBitType); } } @@ -795,7 +827,7 @@ impl SslContextBuilder { #[corresponds(SSL_CTX_set_mode)] pub fn set_mode(&mut self, mode: SslMode) -> SslMode { unsafe { - let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits()); + let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits() as MtuTy) as SslBitType; SslMode { bits } } } @@ -819,7 +851,11 @@ impl SslContextBuilder { { unsafe { self.set_ex_data(SslContext::cached_ex_index::(), callback); + + #[cfg(not(boringssl))] ffi::SSL_CTX_set_tmp_dh_callback__fixed_rust(self.as_ptr(), Some(raw_tmp_dh::)); + #[cfg(boringssl)] + ffi::SSL_CTX_set_tmp_dh_callback(self.as_ptr(), Some(raw_tmp_dh::)); } } @@ -909,7 +945,7 @@ impl SslContextBuilder { cvt(ffi::SSL_CTX_set_session_id_context( self.as_ptr(), sid_ctx.as_ptr(), - sid_ctx.len() as c_uint, + sid_ctx.len() as SizeTy, )) .map(|_| ()) } @@ -1062,21 +1098,23 @@ impl SslContextBuilder { /// `clear_options` for that. #[corresponds(SSL_CTX_set_options)] pub fn set_options(&mut self, option: SslOptions) -> SslOptions { - let bits = unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) }; + let bits = + unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) } as SslOptionsRepr; SslOptions { bits } } /// Returns the options used by the context. #[corresponds(SSL_CTX_get_options)] pub fn options(&self) -> SslOptions { - let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) }; + let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) } as SslOptionsRepr; SslOptions { bits } } /// Clears the options used by the context, returning the old set. #[corresponds(SSL_CTX_clear_options)] pub fn clear_options(&mut self, option: SslOptions) -> SslOptions { - let bits = unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) }; + let bits = + unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) } as SslOptionsRepr; SslOptions { bits } } @@ -1478,6 +1516,7 @@ impl SslContextBuilder { /// The callback will be called with the SSL context and a slice into which the cookie /// should be written. The callback should return the number of bytes written. #[corresponds(SSL_CTX_set_cookie_generate_cb)] + #[cfg(not(boringssl))] pub fn set_cookie_generate_cb(&mut self, callback: F) where F: Fn(&mut SslRef, &mut [u8]) -> Result + 'static + Sync + Send, @@ -1493,6 +1532,7 @@ impl SslContextBuilder { /// The callback will be called with the SSL context and the cookie supplied by the /// client. It should return true if and only if the cookie is valid. #[corresponds(SSL_CTX_set_cookie_verify_cb)] + #[cfg(not(boringssl))] pub fn set_cookie_verify_cb(&mut self, callback: F) where F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, @@ -1617,7 +1657,9 @@ impl SslContextBuilder { #[corresponds(SSL_CTX_sess_set_cache_size)] #[allow(clippy::useless_conversion)] pub fn set_session_cache_size(&mut self, size: i32) -> i64 { - unsafe { ffi::SSL_CTX_sess_set_cache_size(self.as_ptr(), size.into()).into() } + unsafe { + ffi::SSL_CTX_sess_set_cache_size(self.as_ptr(), size as SslCacheSize) as SslCacheTy + } } /// Sets the context's supported signature algorithms. @@ -1708,6 +1750,9 @@ impl SslContext { { unsafe { ffi::init(); + #[cfg(boringssl)] + let idx = cvt_n(get_new_idx(Some(free_data_box::)))?; + #[cfg(not(boringssl))] let idx = cvt_n(get_new_idx(free_data_box::))?; Ok(Index::from_raw(idx)) } @@ -1824,7 +1869,7 @@ impl SslContextRef { #[corresponds(SSL_CTX_sess_get_cache_size)] #[allow(clippy::useless_conversion)] pub fn session_cache_size(&self) -> i64 { - unsafe { ffi::SSL_CTX_sess_get_cache_size(self.as_ptr()).into() } + unsafe { ffi::SSL_CTX_sess_get_cache_size(self.as_ptr()) as i64 } } /// Returns the verify mode that was set on this context from [`SslContextBuilder::set_verify`]. @@ -2059,8 +2104,8 @@ impl SslSessionRef { /// Returns the time at which the session was established, in seconds since the Unix epoch. #[corresponds(SSL_SESSION_get_time)] #[allow(clippy::useless_conversion)] - pub fn time(&self) -> i64 { - unsafe { ffi::SSL_SESSION_get_time(self.as_ptr()).into() } + pub fn time(&self) -> SslTimeTy { + unsafe { ffi::SSL_SESSION_get_time(self.as_ptr()) } } /// Returns the sessions timeout, in seconds. @@ -2128,6 +2173,9 @@ impl Ssl { { unsafe { ffi::init(); + #[cfg(boringssl)] + let idx = cvt_n(get_new_ssl_idx(Some(free_data_box::)))?; + #[cfg(not(boringssl))] let idx = cvt_n(get_new_ssl_idx(free_data_box::))?; Ok(Index::from_raw(idx)) } @@ -2298,6 +2346,9 @@ 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(callback)); + #[cfg(boringssl)] + ffi::SSL_set_tmp_dh_callback(self.as_ptr(), Some(raw_tmp_dh_ssl::)); + #[cfg(not(boringssl))] ffi::SSL_set_tmp_dh_callback__fixed_rust(self.as_ptr(), Some(raw_tmp_dh_ssl::)); } } @@ -2784,6 +2835,7 @@ impl SslRef { /// Returns the server's OCSP response, if present. #[corresponds(SSL_get_tlsext_status_ocsp_resp)] + #[cfg(not(boringssl))] pub fn ocsp_status(&self) -> Option<&[u8]> { unsafe { let mut p = ptr::null_mut(); @@ -2799,6 +2851,7 @@ impl SslRef { /// Sets the OCSP response to be returned to the client. #[corresponds(SSL_set_tlsext_status_oscp_resp)] + #[cfg(not(boringssl))] pub fn set_ocsp_status(&mut self, response: &[u8]) -> Result<(), ErrorStack> { unsafe { assert!(response.len() <= c_int::max_value() as usize); @@ -3019,7 +3072,7 @@ impl SslRef { /// Sets the MTU used for DTLS connections. #[corresponds(SSL_set_mtu)] pub fn set_mtu(&mut self, mtu: u32) -> Result<(), ErrorStack> { - unsafe { cvt(ffi::SSL_set_mtu(self.as_ptr(), mtu as c_long) as c_int).map(|_| ()) } + unsafe { cvt(ffi::SSL_set_mtu(self.as_ptr(), mtu as MtuTy) as c_int).map(|_| ()) } } /// Returns the PSK identity hint used during connection setup. @@ -3721,7 +3774,7 @@ bitflags! { } cfg_if! { - if #[cfg(any(ossl110, libressl273))] { + if #[cfg(any(boringssl, ossl110, libressl273))] { use ffi::{SSL_CTX_up_ref, SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server}; } else { #[allow(bad_style)] @@ -3779,7 +3832,7 @@ cfg_if! { } } cfg_if! { - if #[cfg(any(ossl110, libressl291))] { + if #[cfg(any(boringssl, ossl110, libressl291))] { use ffi::{TLS_method, DTLS_method, TLS_client_method, TLS_server_method}; } else { use ffi::{ @@ -3818,20 +3871,38 @@ cfg_if! { // hack around https://rt.openssl.org/Ticket/Display.html?id=3710&user=guest&pass=guest static ONCE: Once = Once::new(); ONCE.call_once(|| { - ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, None); + cfg_if! { + if #[cfg(not(boringssl))] { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, None); + } else { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, None); + } + } }); - ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) + cfg_if! { + if #[cfg(not(boringssl))] { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) + } else { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, f) + } + } } unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int { // hack around https://rt.openssl.org/Ticket/Display.html?id=3710&user=guest&pass=guest static ONCE: Once = Once::new(); ONCE.call_once(|| { + #[cfg(not(boringssl))] ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, None); + #[cfg(boringssl)] + ffi::SSL_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, None); }); - ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) + #[cfg(not(boringssl))] + return ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)); + #[cfg(boringssl)] + return ffi::SSL_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, f); } } } diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index de64a3e020..cbee17ac12 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -17,6 +17,7 @@ use std::time::Duration; use crate::dh::Dh; use crate::error::ErrorStack; use crate::hash::MessageDigest; +#[cfg(not(boringssl))] use crate::ocsp::{OcspResponse, OcspResponseStatus}; use crate::pkey::PKey; use crate::srtp::SrtpProfileId; @@ -247,6 +248,7 @@ fn set_ctx_options() { } #[test] +#[cfg(not(boringssl))] fn clear_ctx_options() { let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_options(SslOptions::ALL); @@ -294,7 +296,10 @@ fn state() { let server = Server::builder().build(); let s = server.client().connect(); + #[cfg(not(boringssl))] assert_eq!(s.ssl().state_string().trim(), "SSLOK"); + #[cfg(boringssl)] + assert_eq!(s.ssl().state_string(), "!!!!!!"); assert_eq!( s.ssl().state_string_long(), "SSL negotiation finished successfully" @@ -838,7 +843,7 @@ fn cert_store() { } #[test] -#[cfg_attr(all(libressl321, not(libressl340)), ignore)] +#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)] fn tmp_dh_callback() { static CALLED_BACK: AtomicBool = AtomicBool::new(false); @@ -886,7 +891,7 @@ fn tmp_ecdh_callback() { } #[test] -#[cfg_attr(all(libressl321, not(libressl340)), ignore)] +#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)] fn tmp_dh_callback_ssl() { static CALLED_BACK: AtomicBool = AtomicBool::new(false); @@ -963,6 +968,7 @@ fn active_session() { } #[test] +#[cfg(not(boringssl))] fn status_callbacks() { static CALLED_BACK_SERVER: AtomicBool = AtomicBool::new(false); static CALLED_BACK_CLIENT: AtomicBool = AtomicBool::new(false); @@ -1305,7 +1311,7 @@ fn stateless() { #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] #[test] fn psk_ciphers() { - const CIPHER: &str = "PSK-AES128-CBC-SHA"; + const CIPHER: &str = "PSK-AES256-CBC-SHA"; const PSK: &[u8] = b"thisisaverysecurekey"; const CLIENT_IDENT: &[u8] = b"thisisaclient"; static CLIENT_CALLED: AtomicBool = AtomicBool::new(false); @@ -1324,7 +1330,7 @@ fn psk_ciphers() { let mut client = server.client(); // This test relies on TLS 1.2 suites - #[cfg(ossl111)] + #[cfg(any(boringssl, ossl111))] client.ctx().set_options(super::SslOptions::NO_TLSV1_3); client.ctx().set_cipher_list(CIPHER).unwrap(); client @@ -1339,7 +1345,8 @@ fn psk_ciphers() { client.connect(); - assert!(CLIENT_CALLED.load(Ordering::SeqCst) && SERVER_CALLED.load(Ordering::SeqCst)); + assert!(SERVER_CALLED.load(Ordering::SeqCst)); + assert!(CLIENT_CALLED.load(Ordering::SeqCst)); } #[test] diff --git a/openssl/src/stack.rs b/openssl/src/stack.rs index 82d89c279d..416efd5ade 100644 --- a/openssl/src/stack.rs +++ b/openssl/src/stack.rs @@ -11,7 +11,7 @@ use std::ops::{Deref, DerefMut, Index, IndexMut, Range}; use crate::error::ErrorStack; use crate::util::ForeignTypeExt; -use crate::{cvt, cvt_p}; +use crate::{cvt, cvt_p, LenType}; cfg_if! { if #[cfg(ossl110)] { @@ -80,7 +80,7 @@ impl iter::IntoIterator for Stack { fn into_iter(self) -> IntoIter { let it = IntoIter { stack: self.0, - idxs: 0..self.len() as c_int, + idxs: 0..self.len() as LenType, }; mem::forget(self); it @@ -135,7 +135,7 @@ impl DerefMut for Stack { pub struct IntoIter { stack: *mut T::StackType, - idxs: Range, + idxs: Range, } impl Drop for IntoIter { @@ -204,13 +204,13 @@ impl StackRef { pub fn iter(&self) -> Iter<'_, T> { Iter { stack: self, - idxs: 0..self.len() as c_int, + idxs: 0..self.len() as LenType, } } pub fn iter_mut(&mut self) -> IterMut<'_, T> { IterMut { - idxs: 0..self.len() as c_int, + idxs: 0..self.len() as LenType, stack: self, } } @@ -242,7 +242,7 @@ impl StackRef { /// Pushes a value onto the top of the stack. pub fn push(&mut self, data: T) -> Result<(), ErrorStack> { unsafe { - cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _))?; + cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _) as c_int)?; mem::forget(data); Ok(()) } @@ -257,7 +257,7 @@ impl StackRef { } unsafe fn _get(&self, idx: usize) -> *mut T::CType { - OPENSSL_sk_value(self.as_stack(), idx as c_int) as *mut _ + OPENSSL_sk_value(self.as_stack(), idx as LenType) as *mut _ } } @@ -314,7 +314,7 @@ impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack { /// An iterator over the stack's contents. pub struct Iter<'a, T: Stackable> { stack: &'a StackRef, - idxs: Range, + idxs: Range, } impl<'a, T: Stackable> Iterator for Iter<'a, T> { @@ -348,7 +348,7 @@ impl<'a, T: Stackable> ExactSizeIterator for Iter<'a, T> {} /// A mutable iterator over the stack's contents. pub struct IterMut<'a, T: Stackable> { stack: &'a mut StackRef, - idxs: Range, + idxs: Range, } impl<'a, T: Stackable> Iterator for IterMut<'a, T> { diff --git a/openssl/src/string.rs b/openssl/src/string.rs index 2b5823b8bc..e344cd8c49 100644 --- a/openssl/src/string.rs +++ b/openssl/src/string.rs @@ -80,6 +80,17 @@ impl fmt::Debug for OpensslStringRef { } #[inline] +#[cfg(not(boringssl))] unsafe fn free(buf: *mut c_char) { ffi::OPENSSL_free(buf as *mut c_void); } + +#[inline] +#[cfg(boringssl)] +unsafe fn free(buf: *mut c_char) { + ffi::CRYPTO_free( + buf as *mut c_void, + concat!(file!(), "\0").as_ptr() as *const c_char, + line!() as ::libc::c_int, + ); +} diff --git a/openssl/src/symm.rs b/openssl/src/symm.rs index 6f9bbd7bbd..c75bbc0c4a 100644 --- a/openssl/src/symm.rs +++ b/openssl/src/symm.rs @@ -105,6 +105,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_128_cbc()) } } + #[cfg(not(boringssl))] pub fn aes_128_xts() -> Cipher { unsafe { Cipher(ffi::EVP_aes_128_xts()) } } @@ -113,6 +114,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_128_ctr()) } } + #[cfg(not(boringssl))] pub fn aes_128_cfb1() -> Cipher { unsafe { Cipher(ffi::EVP_aes_128_cfb1()) } } @@ -121,6 +123,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_128_cfb128()) } } + #[cfg(not(boringssl))] pub fn aes_128_cfb8() -> Cipher { unsafe { Cipher(ffi::EVP_aes_128_cfb8()) } } @@ -129,6 +132,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_128_gcm()) } } + #[cfg(not(boringssl))] pub fn aes_128_ccm() -> Cipher { unsafe { Cipher(ffi::EVP_aes_128_ccm()) } } @@ -155,6 +159,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_192_ctr()) } } + #[cfg(not(boringssl))] pub fn aes_192_cfb1() -> Cipher { unsafe { Cipher(ffi::EVP_aes_192_cfb1()) } } @@ -163,6 +168,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_192_cfb128()) } } + #[cfg(not(boringssl))] pub fn aes_192_cfb8() -> Cipher { unsafe { Cipher(ffi::EVP_aes_192_cfb8()) } } @@ -171,6 +177,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_192_gcm()) } } + #[cfg(not(boringssl))] pub fn aes_192_ccm() -> Cipher { unsafe { Cipher(ffi::EVP_aes_192_ccm()) } } @@ -193,6 +200,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_256_cbc()) } } + #[cfg(not(boringssl))] pub fn aes_256_xts() -> Cipher { unsafe { Cipher(ffi::EVP_aes_256_xts()) } } @@ -201,6 +209,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_256_ctr()) } } + #[cfg(not(boringssl))] pub fn aes_256_cfb1() -> Cipher { unsafe { Cipher(ffi::EVP_aes_256_cfb1()) } } @@ -209,6 +218,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_256_cfb128()) } } + #[cfg(not(boringssl))] pub fn aes_256_cfb8() -> Cipher { unsafe { Cipher(ffi::EVP_aes_256_cfb8()) } } @@ -217,6 +227,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_256_gcm()) } } + #[cfg(not(boringssl))] pub fn aes_256_ccm() -> Cipher { unsafe { Cipher(ffi::EVP_aes_256_ccm()) } } @@ -241,12 +252,12 @@ impl Cipher { unsafe { Cipher(ffi::EVP_bf_ecb()) } } - #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))] pub fn bf_cfb64() -> Cipher { unsafe { Cipher(ffi::EVP_bf_cfb64()) } } - #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_BF")))] pub fn bf_ofb() -> Cipher { unsafe { Cipher(ffi::EVP_bf_ofb()) } } @@ -267,6 +278,7 @@ impl Cipher { unsafe { Cipher(ffi::EVP_des_ede3_cbc()) } } + #[cfg(not(boringssl))] pub fn des_ede3_cfb64() -> Cipher { unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) } } @@ -287,22 +299,22 @@ impl Cipher { unsafe { Cipher(ffi::EVP_chacha20_poly1305()) } } - #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))] pub fn seed_cbc() -> Cipher { unsafe { Cipher(ffi::EVP_seed_cbc()) } } - #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))] pub fn seed_cfb128() -> Cipher { unsafe { Cipher(ffi::EVP_seed_cfb128()) } } - #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))] pub fn seed_ecb() -> Cipher { unsafe { Cipher(ffi::EVP_seed_ecb()) } } - #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED")))] pub fn seed_ofb() -> Cipher { unsafe { Cipher(ffi::EVP_seed_ofb()) } } @@ -377,11 +389,17 @@ impl Cipher { } /// Determines whether the cipher is using CCM mode + #[cfg(not(boringssl))] fn is_ccm(self) -> bool { // NOTE: OpenSSL returns pointers to static structs, which makes this work as expected self == Cipher::aes_128_ccm() || self == Cipher::aes_256_ccm() } + #[cfg(boringssl)] + fn is_ccm(self) -> bool { + false + } + /// Determines whether the cipher is using OCB mode #[cfg(ossl110)] fn is_ocb(self) -> bool { @@ -757,23 +775,23 @@ pub fn decrypt_aead( } cfg_if! { - if #[cfg(any(ossl110, libressl273))] { + if #[cfg(any(boringssl, ossl110, libressl273))] { use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; } else { - use libc::c_int; + use crate::LenType; #[allow(bad_style)] - pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int { + pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> LenType { (*ptr).iv_len } #[allow(bad_style)] - pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int { + pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> LenType { (*ptr).block_size } #[allow(bad_style)] - pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int { + pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> LenType { (*ptr).key_len } } @@ -903,6 +921,7 @@ mod tests { } } + #[cfg(not(boringssl))] fn cipher_test_nopad(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) { let pt = Vec::from_hex(pt).unwrap(); let ct = Vec::from_hex(ct).unwrap(); @@ -948,6 +967,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes256_xts() { // Test case 174 from // http://csrc.nist.gov/groups/STM/cavp/documents/aes/XTSTestVectors.zip @@ -975,6 +995,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes128_cfb1() { // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf @@ -987,6 +1008,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes128_cfb128() { let pt = "6bc1bee22e409f96e93d7e117393172a"; let ct = "3b3fd92eb72dad20333449f8e83cfb4a"; @@ -997,6 +1019,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes128_cfb8() { let pt = "6bc1bee22e409f96e93d7e117393172aae2d"; let ct = "3b79424c9c0dd436bace9e0ed4586a4f32b9"; @@ -1031,6 +1054,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes192_cfb1() { // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf @@ -1043,6 +1067,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes192_cfb128() { // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf @@ -1055,6 +1080,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes192_cfb8() { // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf @@ -1079,6 +1105,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes256_cfb1() { let pt = "6bc1"; let ct = "9029"; @@ -1089,6 +1116,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes256_cfb128() { let pt = "6bc1bee22e409f96e93d7e117393172a"; let ct = "dc7e84bfda79164b7ecd8486985d3860"; @@ -1099,6 +1127,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes256_cfb8() { let pt = "6bc1bee22e409f96e93d7e117393172aae2d"; let ct = "dc1f1a8520a64db55fcc8ac554844e889700"; @@ -1121,6 +1150,8 @@ mod tests { } #[test] + #[cfg_attr(ossl300, ignore)] + #[cfg(not(boringssl))] fn test_bf_cbc() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); @@ -1136,6 +1167,8 @@ mod tests { } #[test] + #[cfg_attr(ossl300, ignore)] + #[cfg(not(boringssl))] fn test_bf_ecb() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); @@ -1149,6 +1182,8 @@ mod tests { } #[test] + #[cfg_attr(ossl300, ignore)] + #[cfg(not(boringssl))] fn test_bf_cfb64() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); @@ -1162,6 +1197,8 @@ mod tests { } #[test] + #[cfg_attr(ossl300, ignore)] + #[cfg(not(boringssl))] fn test_bf_ofb() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); @@ -1221,6 +1258,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_des_ede3_cfb64() { let pt = "2b1773784b5889dc788477367daa98ad"; let ct = "6f2867cfefda048a4046ef7e556c7132"; @@ -1267,6 +1305,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes128_ccm() { let key = "3ee186594f110fb788a8bf8aa8be5d4a"; let nonce = "44f705d52acf27b7f17196aa9b"; @@ -1303,6 +1342,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes128_ccm_verify_fail() { let key = "3ee186594f110fb788a8bf8aa8be5d4a"; let nonce = "44f705d52acf27b7f17196aa9b"; @@ -1323,6 +1363,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes256_ccm() { let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d"; let nonce = "dde2a362ce81b2b6913abc3095"; @@ -1359,6 +1400,7 @@ mod tests { } #[test] + #[cfg(not(boringssl))] fn test_aes256_ccm_verify_fail() { let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d"; let nonce = "dde2a362ce81b2b6913abc3095"; @@ -1491,7 +1533,7 @@ mod tests { } #[test] - #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))] fn test_seed_cbc() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); @@ -1505,7 +1547,7 @@ mod tests { } #[test] - #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))] fn test_seed_cfb128() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); @@ -1519,7 +1561,7 @@ mod tests { } #[test] - #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))] fn test_seed_ecb() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); @@ -1533,7 +1575,7 @@ mod tests { } #[test] - #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + #[cfg(not(any(boringssl, osslconf = "OPENSSL_NO_SEED", ossl300)))] fn test_seed_ofb() { #[cfg(ossl300)] let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); diff --git a/openssl/src/version.rs b/openssl/src/version.rs index 17799e1d01..da9d24e9fc 100644 --- a/openssl/src/version.rs +++ b/openssl/src/version.rs @@ -109,7 +109,7 @@ fn test_versions() { println!("Platform: '{}'", platform()); println!("Dir: '{}'", dir()); - #[cfg(not(libressl))] + #[cfg(not(any(libressl, boringssl)))] fn expected_name() -> &'static str { "OpenSSL" } @@ -117,6 +117,10 @@ fn test_versions() { fn expected_name() -> &'static str { "LibreSSL" } + #[cfg(boringssl)] + fn expected_name() -> &'static str { + "BoringSSL" + } assert!(number() > 0); assert!(version().starts_with(expected_name())); diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 7605c035ba..edd54aa840 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -9,7 +9,7 @@ use cfg_if::cfg_if; use foreign_types::{ForeignType, ForeignTypeRef}; -use libc::{c_int, c_long}; +use libc::{c_int, c_long, c_uint}; use std::cmp::{self, Ordering}; use std::error::Error; use std::ffi::{CStr, CString}; @@ -369,6 +369,11 @@ foreign_type_and_impl_send_sync! { pub struct X509Ref; } +#[cfg(boringssl)] +type X509LenTy = c_uint; +#[cfg(not(boringssl))] +type X509LenTy = c_int; + impl X509Ref { /// Returns this certificate's subject name. #[corresponds(X509_get_subject_name)] @@ -460,7 +465,7 @@ impl X509Ref { buf: [0; ffi::EVP_MAX_MD_SIZE as usize], len: ffi::EVP_MAX_MD_SIZE as usize, }; - let mut len = ffi::EVP_MAX_MD_SIZE; + let mut len = ffi::EVP_MAX_MD_SIZE as c_uint; cvt(ffi::X509_digest( self.as_ptr(), hash_type.as_ptr(), @@ -673,7 +678,7 @@ impl X509 { ffi::PEM_read_bio_X509(bio.as_ptr(), ptr::null_mut(), None, ptr::null_mut()); if r.is_null() { let err = ffi::ERR_peek_last_error(); - if ffi::ERR_GET_LIB(err) == ffi::ERR_LIB_PEM + if ffi::ERR_GET_LIB(err) as X509LenTy == ffi::ERR_LIB_PEM && ffi::ERR_GET_REASON(err) == ffi::PEM_R_NO_START_LINE { ffi::ERR_clear_error(); @@ -1467,8 +1472,13 @@ impl GeneralNameRef { return None; } - let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _); - let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _); + #[cfg(boringssl)] + let d = (*self.as_ptr()).d.ptr; + #[cfg(not(boringssl))] + let d = (*self.as_ptr()).d; + + let ptr = ASN1_STRING_get0_data(d as *mut _); + let len = ffi::ASN1_STRING_length(d as *mut _); let slice = slice::from_raw_parts(ptr as *const u8, len as usize); // IA5Strings are stated to be ASCII (specifically IA5). Hopefully @@ -1499,9 +1509,13 @@ impl GeneralNameRef { if (*self.as_ptr()).type_ != ffi::GEN_IPADD { return None; } + #[cfg(boringssl)] + let d: *const ffi::ASN1_STRING = std::mem::transmute((*self.as_ptr()).d); + #[cfg(not(boringssl))] + let d = (*self.as_ptr()).d; - let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _); - let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _); + let ptr = ASN1_STRING_get0_data(d as *mut _); + let len = ffi::ASN1_STRING_length(d as *mut _); Some(slice::from_raw_parts(ptr as *const u8, len as usize)) } @@ -1600,7 +1614,7 @@ impl Stackable for X509Object { } cfg_if! { - if #[cfg(any(ossl110, libressl273))] { + if #[cfg(any(boringssl, ossl110, libressl273))] { use ffi::{X509_getm_notAfter, X509_getm_notBefore, X509_up_ref, X509_get0_signature}; } else { #[allow(bad_style)] @@ -1641,7 +1655,7 @@ cfg_if! { } cfg_if! { - if #[cfg(any(ossl110, libressl350))] { + if #[cfg(any(boringssl, ossl110, libressl350))] { use ffi::{ X509_ALGOR_get0, ASN1_STRING_get0_data, X509_STORE_CTX_get0_chain, X509_set1_notAfter, X509_set1_notBefore, X509_REQ_get_version, X509_REQ_get_subject_name, @@ -1681,7 +1695,7 @@ cfg_if! { } cfg_if! { - if #[cfg(any(ossl110, libressl270))] { + if #[cfg(any(ossl110, boringssl, libressl270))] { use ffi::X509_OBJECT_get0_X509; } else { #[allow(bad_style)] @@ -1698,6 +1712,8 @@ cfg_if! { cfg_if! { if #[cfg(any(ossl110, libressl350))] { use ffi::X509_OBJECT_free; + } else if #[cfg(boringssl)] { + use ffi::X509_OBJECT_free_contents as X509_OBJECT_free; } else { #[allow(bad_style)] unsafe fn X509_OBJECT_free(x: *mut ffi::X509_OBJECT) { diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs index a4d2444970..a08d1e2ef9 100644 --- a/openssl/src/x509/store.rs +++ b/openssl/src/x509/store.rs @@ -8,6 +8,7 @@ //! ```rust //! use openssl::x509::store::{X509StoreBuilder, X509Store}; //! use openssl::x509::{X509, X509Name}; +//! use openssl::asn1::Asn1Time; //! use openssl::pkey::PKey; //! use openssl::hash::MessageDigest; //! use openssl::rsa::Rsa; @@ -20,11 +21,16 @@ //! name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com").unwrap(); //! let name = name.build(); //! +//! // Sep 27th, 2016 +//! let sample_time = Asn1Time::from_unix(1474934400).unwrap(); +//! //! let mut builder = X509::builder().unwrap(); //! builder.set_version(2).unwrap(); //! builder.set_subject_name(&name).unwrap(); //! builder.set_issuer_name(&name).unwrap(); //! builder.set_pubkey(&pkey).unwrap(); +//! builder.set_not_before(&sample_time); +//! builder.set_not_after(&sample_time); //! builder.sign(&pkey, MessageDigest::sha256()).unwrap(); //! //! let certificate: X509 = builder.build(); @@ -40,6 +46,7 @@ use foreign_types::ForeignTypeRef; use std::mem; use crate::error::ErrorStack; +#[cfg(not(boringssl))] use crate::ssl::SslFiletype; use crate::stack::StackRef; #[cfg(any(ossl102, libressl261))] @@ -47,6 +54,7 @@ use crate::x509::verify::X509VerifyFlags; use crate::x509::{X509Object, X509}; use crate::{cvt, cvt_p}; use openssl_macros::corresponds; +#[cfg(not(boringssl))] use std::ffi::CString; foreign_type_and_impl_send_sync! { @@ -143,6 +151,7 @@ impl X509Lookup { } } +#[cfg(not(boringssl))] impl X509LookupRef { /// Specifies a directory from which certificates and CRLs will be loaded /// on-demand. Must be used with `X509Lookup::hash_dir`. @@ -189,7 +198,7 @@ impl X509StoreRef { } cfg_if! { - if #[cfg(any(ossl110, libressl270))] { + if #[cfg(any(boringssl, ossl110, libressl270))] { use ffi::X509_STORE_get0_objects; } else { #[allow(bad_style)] diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index db18777974..fcca2c7bf1 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -41,6 +41,9 @@ fn test_debug() { let cert = include_bytes!("../../test/cert.pem"); let cert = X509::from_pem(cert).unwrap(); let debugged = format!("{:#?}", cert); + #[cfg(boringssl)] + assert!(debugged.contains(r#"serial_number: "8771f7bdee982fa5""#)); + #[cfg(not(boringssl))] assert!(debugged.contains(r#"serial_number: "8771F7BDEE982FA5""#)); assert!(debugged.contains(r#"signature_algorithm: sha256WithRSAEncryption"#)); assert!(debugged.contains(r#"countryName = "AU""#)); @@ -282,7 +285,7 @@ fn x509_req_builder() { let name = name.build(); let mut builder = X509Req::builder().unwrap(); - builder.set_version(2).unwrap(); + builder.set_version(0).unwrap(); builder.set_subject_name(&name).unwrap(); builder.set_pubkey(&pkey).unwrap(); diff --git a/systest/build.rs b/systest/build.rs index 86c82fa8e8..2618a05b97 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -34,6 +34,8 @@ fn main() { .ok() .map(|v| u64::from_str_radix(&v, 16).unwrap()); + cfg.cfg("openssl", None); + for c in cfgs::get(openssl_version, libressl_version) { cfg.cfg(c, None); } From 46e931483046328fdd845980cdb18389ba9041d0 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Thu, 21 Jul 2022 15:00:45 -0700 Subject: [PATCH 2/4] Add boringssl to CI * BoringSSL does not use the bindgen feature, since it generates the crate separately. * BoringSSL shouldn't run the systest tests (maintained out of tree) or the openssl-errors tests (BoringSSL doesn't support external errors) * Adds both master and a known-working revision to CI. The master build should be made non-blocking. --- .github/workflows/ci.yml | 54 ++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75a21129fa..decfe7200b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -149,6 +149,10 @@ jobs: - true - false library: + - name: boringssl + version: master + - name: boringssl + version: 5697a9202615925696f8dc7f4e286d44d474769e - name: openssl version: vendored - name: openssl @@ -197,6 +201,10 @@ jobs: library: name: libressl version: 3.5.2 + exclude: + - library: + name: boringssl + bindgen: true name: ${{ matrix.target }}-${{ matrix.library.name }}-${{ matrix.library.version }}-${{ matrix.bindgen }} runs-on: ubuntu-latest env: @@ -217,10 +225,10 @@ jobs: exit 0 ;; "i686-unknown-linux-gnu") - packages="gcc-multilib" + packages="gcc-multilib g++-multilib" ;; "arm-unknown-linux-gnueabihf") - packages="gcc-arm-linux-gnueabihf qemu-user" + packages="gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf qemu-user" ;; esac @@ -233,14 +241,24 @@ jobs: key: openssl-${{ matrix.target }}-${{ matrix.library.name }}-${{ matrix.library.version }}-2 if: matrix.library.version != 'vendored' id: openssl-cache + - run: | + echo "RUST_TEST_THREADS=1" >> $GITHUB_ENV + echo BINDGEN_EXTRA_CLANG_ARGS="--sysroot /usr/arm-linux-gnueabihf" >> $GITHUB_ENV + if: matrix.target == 'arm-unknown-linux-gnueabihf' - name: Build OpenSSL run: | case "${{ matrix.library.name }}" in "openssl") url="https://openssl.org/source${{ matrix.library.dl-path }}/openssl-${{ matrix.library.version }}.tar.gz" + tar_flags="--strip-components=1" ;; "libressl") url="https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-${{ matrix.library.version }}.tar.gz" + tar_flags="--strip-components=1" + ;; + "boringssl") + url="https://boringssl.googlesource.com/boringssl/+archive/${{ matrix.library.version }}.tar.gz" + tar_flags="" ;; esac @@ -258,30 +276,45 @@ jobs: OS_FLAGS="" export AR=arm-linux-gnueabihf-ar export CC=arm-linux-gnueabihf-gcc + export CXX=arm-linux-gnueabihf-g++ ;; esac mkdir /tmp/build cd /tmp/build - curl -L $url | tar --strip-components=1 -xzf - + curl -L $url | tar $tar_flags -xzf - case "${{ matrix.library.name }}" in "openssl") ./Configure --prefix=$OPENSSL_DIR --libdir=lib $OS_COMPILER -fPIC -g $OS_FLAGS no-shared + make + make install_sw ;; "libressl") ./configure --prefix=$OPENSSL_DIR --disable-shared --with-pic + make + 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 esac - make - make install_sw if: matrix.library.version != 'vendored' && !steps.openssl-cache.outputs.cache-hit - run: | - echo "RUST_TEST_THREADS=1" >> $GITHUB_ENV - echo BINDGEN_EXTRA_CLANG_ARGS="--sysroot /usr/arm-linux-gnueabihf" >> $GITHUB_ENV - if: matrix.target == 'arm-unknown-linux-gnueabihf' + 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' - uses: actions/cache@v1 with: path: ~/.cargo/registry/index @@ -307,8 +340,12 @@ jobs: 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 @@ -325,3 +362,4 @@ jobs: features="$features --features openssl-sys/bindgen" fi cargo test --manifest-path=openssl-errors/Cargo.toml --target ${{ matrix.target }} $features + if: matrix.library.name != 'boringssl' From c26bdb3ec9aa579af1aa7d6145d2dc1c71a8e062 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Thu, 22 Sep 2022 18:30:49 -0700 Subject: [PATCH 3/4] Fix new compiler lints (explicit drop for Boxes) --- openssl/src/ssl/bio.rs | 4 ++-- openssl/src/ssl/mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs index 3ace35e6d9..29e8e81e23 100644 --- a/openssl/src/ssl/bio.rs +++ b/openssl/src/ssl/bio.rs @@ -183,7 +183,7 @@ unsafe extern "C" fn destroy(bio: *mut BIO) -> c_int { let data = BIO_get_data(bio); assert!(!data.is_null()); - Box::>::from_raw(data as *mut _); + drop(Box::>::from_raw(data as *mut _)); BIO_set_data(bio, ptr::null_mut()); BIO_set_init(bio, 0); 1 @@ -257,7 +257,7 @@ cfg_if! { impl Drop for BIO_METHOD { fn drop(&mut self) { unsafe { - Box::::from_raw(self.0); + drop(Box::::from_raw(self.0)); } } } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 1325a86991..ca5c2555c9 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -558,7 +558,7 @@ unsafe extern "C" fn free_data_box( _argp: *mut c_void, ) { if !ptr.is_null() { - Box::::from_raw(ptr as *mut T); + drop(Box::::from_raw(ptr as *mut T)); } } From f5cb75198e60f076d190f3d2b36a5ef814e5e55a Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Thu, 22 Sep 2022 18:35:04 -0700 Subject: [PATCH 4/4] Fix new clippy lints * Needless borrow * Explicit auto-deref --- openssl/src/ssl/connector.rs | 4 ++-- openssl/src/ssl/test/mod.rs | 20 ++++++++++---------- openssl/src/string.rs | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 1039425f80..39f729df90 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -107,7 +107,7 @@ impl SslConnector { /// Returns a shared reference to the inner raw `SslContext`. pub fn context(&self) -> &SslContextRef { - &*self.0 + &self.0 } } @@ -334,7 +334,7 @@ impl SslAcceptor { /// Returns a shared reference to the inner raw `SslContext`. pub fn context(&self) -> &SslContextRef { - &*self.0 + &self.0 } } diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index cbee17ac12..ab8d79aab4 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -204,7 +204,7 @@ fn verify_callback() { CALLED_BACK.store(true, Ordering::SeqCst); let cert = x509.current_cert().unwrap(); let digest = cert.digest(MessageDigest::sha1()).unwrap(); - assert_eq!(hex::encode(&digest), expected); + assert_eq!(hex::encode(digest), expected); true }); @@ -226,7 +226,7 @@ fn ssl_verify_callback() { CALLED_BACK.store(true, Ordering::SeqCst); let cert = x509.current_cert().unwrap(); let digest = cert.digest(MessageDigest::sha1()).unwrap(); - assert_eq!(hex::encode(&digest), expected); + assert_eq!(hex::encode(digest), expected); true }); @@ -319,9 +319,9 @@ fn test_connect_with_srtp_ctx() { let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") .unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) + ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM) .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) + ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM) .unwrap(); let mut ssl = Ssl::new(&ctx.build()).unwrap(); ssl.set_mtu(1500).unwrap(); @@ -375,9 +375,9 @@ fn test_connect_with_srtp_ssl() { let guard = thread::spawn(move || { let stream = listener.accept().unwrap().0; let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) + ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM) .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) + ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM) .unwrap(); let mut ssl = Ssl::new(&ctx.build()).unwrap(); ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") @@ -1073,9 +1073,9 @@ fn keying_export() { let guard = thread::spawn(move || { let stream = listener.accept().unwrap().0; let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) + ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM) .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) + ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM) .unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); let mut stream = ssl.accept(stream).unwrap(); @@ -1271,10 +1271,10 @@ fn stateless() { let mut server_ctx = SslContext::builder(SslMethod::tls()).unwrap(); server_ctx - .set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) + .set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM) .unwrap(); server_ctx - .set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) + .set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM) .unwrap(); const COOKIE: &[u8] = b"chocolate chip"; server_ctx.set_stateless_cookie_generate_cb(|_tls, buf| { diff --git a/openssl/src/string.rs b/openssl/src/string.rs index e344cd8c49..95494b567e 100644 --- a/openssl/src/string.rs +++ b/openssl/src/string.rs @@ -34,7 +34,7 @@ impl Stackable for OpensslString { impl AsRef for OpensslString { fn as_ref(&self) -> &str { - &**self + self } }