diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 577cc7f0b4..d7f92aacd1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -154,7 +154,7 @@ jobs: - false library: - name: boringssl - version: f78fe19fc98e0e6f760e05c6b9d48725004700d0 + version: e6489902b7fb692875341b8ab5e57f0515f47bc1 - name: openssl version: vendored - name: openssl diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index e37cdc63da..636a9c1072 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -2,6 +2,18 @@ ## [Unreleased] +## [v0.9.98] - 2023-12-22 + +### Added + +* Added `RAND_priv_bytes`. +* Added `NID_brainpoolP320r1`. + +### Changed + +* `X509_PURPOSE_get0` now returns a `const` pointer on LibreSSL 3.9.0+. +* `X509V3_EXT_add_alias` is removed on LibreSSL 3.9.0+. + ## [v0.9.97] - 2023-12-04 ### Changed @@ -555,7 +567,8 @@ Fixed builds against OpenSSL built with `no-cast`. * Added `X509_verify` and `X509_REQ_verify`. * Added `EVP_MD_type` and `EVP_GROUP_get_curve_name`. -[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.97..master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.98..master +[v0.9.98]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.97...openssl-sys-v0.9.98 [v0.9.97]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.96...openssl-sys-v0.9.97 [v0.9.96]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.95...openssl-sys-v0.9.96 [v0.9.95]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.94...openssl-sys-v0.9.95 diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index 4b3ce6c8d1..63c47fe4dd 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl-sys" -version = "0.9.97" +version = "0.9.98" authors = [ "Alex Crichton ", "Steven Fackler ", diff --git a/openssl-sys/build/cfgs.rs b/openssl-sys/build/cfgs.rs index 2454ef66a4..91cb734c34 100644 --- a/openssl-sys/build/cfgs.rs +++ b/openssl-sys/build/cfgs.rs @@ -62,6 +62,9 @@ pub fn get(openssl_version: Option, libressl_version: Option) -> Vec<& if libressl_version >= 0x3_08_02_00_0 { cfgs.push("libressl382"); } + if libressl_version >= 0x3_09_00_00_0 { + cfgs.push("libressl390"); + } } else { let openssl_version = openssl_version.unwrap(); diff --git a/openssl-sys/src/handwritten/rand.rs b/openssl-sys/src/handwritten/rand.rs index 3bf9da5921..df553bd144 100644 --- a/openssl-sys/src/handwritten/rand.rs +++ b/openssl-sys/src/handwritten/rand.rs @@ -3,6 +3,9 @@ use libc::*; extern "C" { pub fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int; + #[cfg(ossl111)] + pub fn RAND_priv_bytes(buf: *mut u8, num: c_int) -> c_int; + #[cfg(ossl111)] pub fn RAND_keep_random_devices_open(keep: c_int); diff --git a/openssl-sys/src/handwritten/x509.rs b/openssl-sys/src/handwritten/x509.rs index a93142cd2a..107e8182d1 100644 --- a/openssl-sys/src/handwritten/x509.rs +++ b/openssl-sys/src/handwritten/x509.rs @@ -703,11 +703,9 @@ const_ptr_api! { extern "C" { pub fn X509_PURPOSE_get_by_sname(sname: #[const_ptr_if(any(ossl110, libressl280))] c_char) -> c_int; pub fn X509_PURPOSE_get_id(purpose: #[const_ptr_if(any(ossl110, libressl280))] X509_PURPOSE) -> c_int; + pub fn X509_PURPOSE_get0(idx: c_int) -> #[const_ptr_if(libressl390)] X509_PURPOSE; } } -extern "C" { - pub fn X509_PURPOSE_get0(idx: c_int) -> *mut X509_PURPOSE; -} extern "C" { pub fn X509_ATTRIBUTE_new() -> *mut X509_ATTRIBUTE; diff --git a/openssl-sys/src/handwritten/x509v3.rs b/openssl-sys/src/handwritten/x509v3.rs index 2f59bf6663..1a548c0e25 100644 --- a/openssl-sys/src/handwritten/x509v3.rs +++ b/openssl-sys/src/handwritten/x509v3.rs @@ -84,6 +84,7 @@ const_ptr_api! { } extern "C" { + #[cfg(not(libressl390))] pub fn X509V3_EXT_add_alias(nid_to: c_int, nid_from: c_int) -> c_int; pub fn X509V3_EXT_d2i(ext: *mut X509_EXTENSION) -> *mut c_void; pub fn X509V3_EXT_i2d(ext_nid: c_int, crit: c_int, ext: *mut c_void) -> *mut X509_EXTENSION; diff --git a/openssl-sys/src/obj_mac.rs b/openssl-sys/src/obj_mac.rs index 2c4b6aaeb9..b207da79d0 100644 --- a/openssl-sys/src/obj_mac.rs +++ b/openssl-sys/src/obj_mac.rs @@ -97,6 +97,8 @@ pub const NID_sect571r1: c_int = 734; #[cfg(ossl110)] pub const NID_brainpoolP256r1: c_int = 927; #[cfg(ossl110)] +pub const NID_brainpoolP320r1: c_int = 929; +#[cfg(ossl110)] pub const NID_brainpoolP384r1: c_int = 931; #[cfg(ossl110)] pub const NID_brainpoolP512r1: c_int = 933; diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index a37da48a9e..3d37e64de3 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -2,6 +2,17 @@ ## [Unreleased] +## [v0.10.62] - 2023-12-22 + +### Added + +* Added `Nid::BRAINPOOL_P320R1` +* Added `rand_priv_bytes` + +### Fixed + +* Fixed building on the latest version of BoringSSL + ## [v0.10.61] - 2023-12-04 ### Changed @@ -858,7 +869,8 @@ Look at the [release tags] for information about older releases. -[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.61...master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.62...master +[v0.10.62]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.61...openssl-v0.10.62 [v0.10.61]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.60...openssl-v0.10.61 [v0.10.60]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.59...openssl-v0.10.60 [v0.10.59]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.58...openssl-v0.10.59 diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index 61e3e83053..8846ca57d6 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl" -version = "0.10.61" +version = "0.10.62" authors = ["Steven Fackler "] license = "Apache-2.0" description = "OpenSSL bindings" @@ -30,7 +30,7 @@ libc = "0.2" once_cell = "1.5.2" openssl-macros = { version = "0.1.0", path = "../openssl-macros" } -ffi = { package = "openssl-sys", version = "0.9.97", path = "../openssl-sys" } +ffi = { package = "openssl-sys", version = "0.9.98", path = "../openssl-sys" } [dev-dependencies] hex = "0.3" diff --git a/openssl/build.rs b/openssl/build.rs index 87a9fa06f5..7677abc086 100644 --- a/openssl/build.rs +++ b/openssl/build.rs @@ -72,6 +72,9 @@ fn main() { if version >= 0x3_08_02_00_0 { println!("cargo:rustc-cfg=libressl382"); } + if version >= 0x3_09_00_00_0 { + println!("cargo:rustc-cfg=libressl390"); + } } if let Ok(vars) = env::var("DEP_OPENSSL_CONF") { diff --git a/openssl/src/cms.rs b/openssl/src/cms.rs index d11443b5ce..a946230a5a 100644 --- a/openssl/src/cms.rs +++ b/openssl/src/cms.rs @@ -475,14 +475,10 @@ mod test { // check verification result - this is an invalid signature // defined in openssl crypto/cms/cms.h const CMS_R_CERTIFICATE_VERIFY_ERROR: i32 = 100; - match res { - Err(es) => { - let error_array = es.errors(); - assert_eq!(1, error_array.len()); - let code = error_array[0].code(); - assert_eq!(ffi::ERR_GET_REASON(code), CMS_R_CERTIFICATE_VERIFY_ERROR); - } - _ => panic!("expected CMS verification error, got Ok()"), - } + let es = res.unwrap_err(); + let error_array = es.errors(); + assert_eq!(1, error_array.len()); + let code = error_array[0].reason_code(); + assert_eq!(code, CMS_R_CERTIFICATE_VERIFY_ERROR); } } diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index aadc76ec97..a73dbea4cb 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -208,6 +208,15 @@ fn cvt_p(r: *mut T) -> Result<*mut T, ErrorStack> { } } +#[inline] +fn cvt_p_const(r: *const T) -> Result<*const T, ErrorStack> { + if r.is_null() { + Err(ErrorStack::get()) + } else { + Ok(r) + } +} + #[inline] fn cvt(r: c_int) -> Result { if r <= 0 { diff --git a/openssl/src/nid.rs b/openssl/src/nid.rs index a5bd93ca42..a1f3b1e635 100644 --- a/openssl/src/nid.rs +++ b/openssl/src/nid.rs @@ -218,6 +218,8 @@ impl Nid { #[cfg(ossl110)] pub const BRAINPOOL_P256R1: Nid = Nid(ffi::NID_brainpoolP256r1); #[cfg(ossl110)] + pub const BRAINPOOL_P320R1: Nid = Nid(ffi::NID_brainpoolP320r1); + #[cfg(ossl110)] pub const BRAINPOOL_P384R1: Nid = Nid(ffi::NID_brainpoolP384r1); #[cfg(ossl110)] pub const BRAINPOOL_P512R1: Nid = Nid(ffi::NID_brainpoolP512r1); diff --git a/openssl/src/provider.rs b/openssl/src/provider.rs index 147fadfdbc..01b5820af5 100644 --- a/openssl/src/provider.rs +++ b/openssl/src/provider.rs @@ -55,6 +55,10 @@ impl Provider { retain_fallbacks as _, ))?; + // OSSL_PROVIDER_try_load seems to leave errors on the stack, even + // when it succeeds. + let _ = ErrorStack::get(); + Ok(Provider::from_ptr(p)) } } diff --git a/openssl/src/rand.rs b/openssl/src/rand.rs index 8317951f81..ef0f7685cc 100644 --- a/openssl/src/rand.rs +++ b/openssl/src/rand.rs @@ -37,6 +37,31 @@ pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> { } } +/// Fill buffer with cryptographically strong pseudo-random bytes. It is +/// intended to be used for generating values that should remain private. +/// +/// # Examples +/// +/// To generate a buffer with cryptographically strong random bytes: +/// +/// ``` +/// use openssl::rand::rand_priv_bytes; +/// +/// let mut buf = [0; 256]; +/// rand_priv_bytes(&mut buf).unwrap(); +/// ``` +/// +/// Requires OpenSSL 1.1.1 or newer. +#[corresponds(RAND_priv_bytes)] +#[cfg(ossl111)] +pub fn rand_priv_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> { + unsafe { + ffi::init(); + assert!(buf.len() <= c_int::max_value() as usize); + cvt(ffi::RAND_priv_bytes(buf.as_mut_ptr(), buf.len() as LenType)).map(|_| ()) + } +} + /// Controls random device file descriptor behavior. /// /// Requires OpenSSL 1.1.1 or newer. @@ -50,11 +75,16 @@ pub fn keep_random_devices_open(keep: bool) { #[cfg(test)] mod tests { - use super::rand_bytes; - #[test] fn test_rand_bytes() { let mut buf = [0; 32]; - rand_bytes(&mut buf).unwrap(); + super::rand_bytes(&mut buf).unwrap(); + } + + #[test] + #[cfg(ossl111)] + fn test_rand_priv_bytes() { + let mut buf = [0; 32]; + super::rand_priv_bytes(&mut buf).unwrap(); } } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 8458e7313d..115193ee05 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -38,7 +38,7 @@ use crate::ssl::SslRef; use crate::stack::{Stack, StackRef, Stackable}; use crate::string::OpensslString; use crate::util::{ForeignTypeExt, ForeignTypeRefExt}; -use crate::{cvt, cvt_n, cvt_p}; +use crate::{cvt, cvt_n, cvt_p, cvt_p_const}; use openssl_macros::corresponds; #[cfg(any(ossl102, libressl261))] @@ -383,11 +383,6 @@ 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)] @@ -760,15 +755,16 @@ impl X509 { let r = 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) as X509LenTy == ffi::ERR_LIB_PEM - && ffi::ERR_GET_REASON(err) == ffi::PEM_R_NO_START_LINE + let e = ErrorStack::get(); + let errors = e.errors(); + if !errors.is_empty() + && errors[0].library_code() == ffi::ERR_LIB_PEM as libc::c_int + && errors[0].reason_code() == ffi::PEM_R_NO_START_LINE as libc::c_int { - ffi::ERR_clear_error(); break; } - return Err(ErrorStack::get()); + return Err(e); } else { certs.push(X509(r)); } @@ -1022,6 +1018,7 @@ impl X509Extension { /// # Safety /// /// This method modifies global state without locking and therefore is not thread safe + #[cfg(not(libressl390))] #[corresponds(X509V3_EXT_add_alias)] #[deprecated( note = "Use x509::extension types or new_from_der and then this is not necessary", @@ -2552,8 +2549,8 @@ impl X509PurposeRef { #[corresponds(X509_PURPOSE_get0)] pub fn from_idx(idx: c_int) -> Result<&'static X509PurposeRef, ErrorStack> { unsafe { - let ptr = cvt_p(ffi::X509_PURPOSE_get0(idx))?; - Ok(X509PurposeRef::from_ptr(ptr)) + let ptr = cvt_p_const(ffi::X509_PURPOSE_get0(idx))?; + Ok(X509PurposeRef::from_const_ptr(ptr)) } } diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs index c6cd4f12d5..944a2803e6 100644 --- a/openssl/src/x509/store.rs +++ b/openssl/src/x509/store.rs @@ -51,6 +51,7 @@ use crate::ssl::SslFiletype; #[cfg(ossl300)] use crate::stack::Stack; use crate::stack::StackRef; +use crate::util::ForeignTypeRefExt; #[cfg(any(ossl102, libressl261))] use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef}; use crate::x509::{X509Object, X509PurposeId, X509}; @@ -165,9 +166,7 @@ impl X509Lookup { /// directory. #[corresponds(X509_LOOKUP_hash_dir)] pub fn hash_dir() -> &'static X509LookupMethodRef { - // `*mut` cast is needed because BoringSSL returns a `*const`. This is - // ok because we only return an immutable reference. - unsafe { X509LookupMethodRef::from_ptr(ffi::X509_LOOKUP_hash_dir() as *mut _) } + unsafe { X509LookupMethodRef::from_const_ptr(ffi::X509_LOOKUP_hash_dir()) } } } @@ -199,9 +198,7 @@ impl X509Lookup { /// into memory at the time the file is added as a lookup source. #[corresponds(X509_LOOKUP_file)] pub fn file() -> &'static X509LookupMethodRef { - // `*mut` cast is needed because BoringSSL returns a `*const`. This is - // ok because we only return an immutable reference. - unsafe { X509LookupMethodRef::from_ptr(ffi::X509_LOOKUP_file() as *mut _) } + unsafe { X509LookupMethodRef::from_const_ptr(ffi::X509_LOOKUP_file()) } } }