diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7f92aacd1..ab80ae61e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -247,7 +247,7 @@ jobs: run: | case "${{ matrix.library.name }}" in "openssl") - url="https://openssl.org/source${{ matrix.library.dl-path }}/openssl-${{ matrix.library.version }}.tar.gz" + url="https://www.openssl.org/source${{ matrix.library.dl-path }}/openssl-${{ matrix.library.version }}.tar.gz" tar_flags="--strip-components=1" ;; "libressl") diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index 636a9c1072..ba024b68e6 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -2,6 +2,17 @@ ## [Unreleased] +## [v0.9.99] - 2024-01-19 + +### Added + +* On macOS added Homebrew's `openssl@3.0` to the list of candidates to build against. +* `NID_brainpoolP256r1`, `NID_brainpoolP320r1`, `NID_brainpoolP384r1`, and `NID_brainpoolP512r1` are now available on LibreSSL. + +### Changed + +* `X509_PURPOSE` is now opaque on LibreSSL 3.9.0+. + ## [v0.9.98] - 2023-12-22 ### Added @@ -567,7 +578,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.98..master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.99..master +[v0.9.99]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.98...openssl-sys-v0.9.99 [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 diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index 63c47fe4dd..11dc7f3466 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl-sys" -version = "0.9.98" +version = "0.9.99" authors = [ "Alex Crichton ", "Steven Fackler ", diff --git a/openssl-sys/build/find_normal.rs b/openssl-sys/build/find_normal.rs index 4d461039c2..ce278f5c76 100644 --- a/openssl-sys/build/find_normal.rs +++ b/openssl-sys/build/find_normal.rs @@ -32,7 +32,7 @@ pub fn get_openssl(target: &str) -> (Vec, PathBuf) { } fn resolve_with_wellknown_homebrew_location(dir: &str) -> Option { - let versions = ["openssl@3", "openssl@1.1"]; + let versions = ["openssl@3", "openssl@3.0", "openssl@1.1"]; // Check up default aarch 64 Homebrew installation location first // for quick resolution if possible. diff --git a/openssl-sys/src/handwritten/x509.rs b/openssl-sys/src/handwritten/x509.rs index 107e8182d1..15f527e651 100644 --- a/openssl-sys/src/handwritten/x509.rs +++ b/openssl-sys/src/handwritten/x509.rs @@ -687,16 +687,22 @@ extern "C" { pub fn X509_REQ_print(bio: *mut BIO, req: *mut X509_REQ) -> c_int; } -#[repr(C)] -pub struct X509_PURPOSE { - pub purpose: c_int, - pub trust: c_int, // Default trust ID - pub flags: c_int, - pub check_purpose: - Option c_int>, - pub name: *mut c_char, - pub sname: *mut c_char, - pub usr_data: *mut c_void, +cfg_if! { + if #[cfg(libressl390)] { + pub enum X509_PURPOSE {} + } else { + #[repr(C)] + pub struct X509_PURPOSE { + pub purpose: c_int, + pub trust: c_int, // Default trust ID + pub flags: c_int, + pub check_purpose: + Option c_int>, + pub name: *mut c_char, + pub sname: *mut c_char, + pub usr_data: *mut c_void, + } + } } const_ptr_api! { diff --git a/openssl-sys/src/obj_mac.rs b/openssl-sys/src/obj_mac.rs index b207da79d0..400f73388f 100644 --- a/openssl-sys/src/obj_mac.rs +++ b/openssl-sys/src/obj_mac.rs @@ -94,14 +94,27 @@ pub const NID_sect409k1: c_int = 731; pub const NID_sect409r1: c_int = 732; pub const NID_sect571k1: c_int = 733; pub const NID_sect571r1: c_int = 734; + #[cfg(ossl110)] pub const NID_brainpoolP256r1: c_int = 927; +#[cfg(libressl)] +pub const NID_brainpoolP256r1: c_int = 928; + #[cfg(ossl110)] pub const NID_brainpoolP320r1: c_int = 929; +#[cfg(libressl)] +pub const NID_brainpoolP320r1: c_int = 930; + #[cfg(ossl110)] pub const NID_brainpoolP384r1: c_int = 931; +#[cfg(libressl)] +pub const NID_brainpoolP384r1: c_int = 932; + #[cfg(ossl110)] pub const NID_brainpoolP512r1: c_int = 933; +#[cfg(libressl)] +pub const NID_brainpoolP512r1: c_int = 934; + pub const NID_wap_wsg_idm_ecid_wtls1: c_int = 735; pub const NID_wap_wsg_idm_ecid_wtls3: c_int = 736; pub const NID_wap_wsg_idm_ecid_wtls4: c_int = 737; diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index 3d37e64de3..8b34e48cab 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -2,6 +2,21 @@ ## [Unreleased] +## [v0.10.63] - 2024-01-19 + +### Added + +* Added `Pkcs7Ref::{type_,signed}`. +* Added `Pkcs7SignedRef::certificates`. +* Added `Cipher::{aes_256_xts,des_ede3_ecb,des_ede3_cfb8,des_ede3_ofb,camellia128_ofb,camellia192_ofb,camellia256_ofb,cast5_ofb,idea_ofb}` +* Added `PKey::from_dhx` +* Added `PKey::{public_key_from_pem_passphrase,public_key_from_pem_callback}`. + +### Changed + +* `Cipher::aes_128_ofb` is now available on BoringSSL +* `Nid::{BRAINPOOL_P256R1,BRAINPOOL_P320R1,BRAINPOOL_P384R1,BRAINPOOL_P512R1}` are now available on LibreSSL. + ## [v0.10.62] - 2023-12-22 ### Added @@ -869,7 +884,8 @@ Look at the [release tags] for information about older releases. -[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.62...master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.63...master +[v0.10.63]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.62...openssl-v0.10.63 [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 diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index 8846ca57d6..422142248a 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl" -version = "0.10.62" +version = "0.10.63" 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.98", path = "../openssl-sys" } +ffi = { package = "openssl-sys", version = "0.9.99", path = "../openssl-sys" } [dev-dependencies] hex = "0.3" diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index 801310d411..8618be0e92 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -166,7 +166,7 @@ impl Asn1Type { /// [`diff`]: struct.Asn1TimeRef.html#method.diff /// [`Asn1TimeRef`]: struct.Asn1TimeRef.html #[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] pub struct TimeDiff { /// Difference in days pub days: c_int, @@ -199,7 +199,7 @@ foreign_type_and_impl_send_sync! { impl Asn1TimeRef { /// Find difference between two times #[corresponds(ASN1_TIME_diff)] - #[cfg(ossl102)] + #[cfg(any(ossl102, boringssl))] pub fn diff(&self, compare: &Self) -> Result { let mut days = 0; let mut secs = 0; @@ -215,7 +215,7 @@ impl Asn1TimeRef { /// Compare two times #[corresponds(ASN1_TIME_compare)] - #[cfg(ossl102)] + #[cfg(any(ossl102, boringssl))] pub fn compare(&self, other: &Self) -> Result { let d = self.diff(other)?; if d.days > 0 || d.secs > 0 { @@ -229,7 +229,7 @@ impl Asn1TimeRef { } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl PartialEq for Asn1TimeRef { fn eq(&self, other: &Asn1TimeRef) -> bool { self.diff(other) @@ -238,7 +238,7 @@ impl PartialEq for Asn1TimeRef { } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl PartialEq for Asn1TimeRef { fn eq(&self, other: &Asn1Time) -> bool { self.diff(other) @@ -247,7 +247,7 @@ impl PartialEq for Asn1TimeRef { } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl<'a> PartialEq for &'a Asn1TimeRef { fn eq(&self, other: &Asn1Time) -> bool { self.diff(other) @@ -256,21 +256,21 @@ impl<'a> PartialEq for &'a Asn1TimeRef { } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl PartialOrd for Asn1TimeRef { fn partial_cmp(&self, other: &Asn1TimeRef) -> Option { self.compare(other).ok() } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl PartialOrd for Asn1TimeRef { fn partial_cmp(&self, other: &Asn1Time) -> Option { self.compare(other).ok() } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl<'a> PartialOrd for &'a Asn1TimeRef { fn partial_cmp(&self, other: &Asn1Time) -> Option { self.compare(other).ok() @@ -352,9 +352,9 @@ impl Asn1Time { /// Creates a new time corresponding to the specified X509 time string. /// - /// Requires OpenSSL 1.1.1 or newer. + /// Requires BoringSSL or OpenSSL 1.1.1 or newer. #[corresponds(ASN1_TIME_set_string_X509)] - #[cfg(ossl111)] + #[cfg(any(ossl111, boringssl))] pub fn from_str_x509(s: &str) -> Result { unsafe { let s = CString::new(s).unwrap(); @@ -367,7 +367,7 @@ impl Asn1Time { } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl PartialEq for Asn1Time { fn eq(&self, other: &Asn1Time) -> bool { self.diff(other) @@ -376,7 +376,7 @@ impl PartialEq for Asn1Time { } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl PartialEq for Asn1Time { fn eq(&self, other: &Asn1TimeRef) -> bool { self.diff(other) @@ -385,7 +385,7 @@ impl PartialEq for Asn1Time { } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl<'a> PartialEq<&'a Asn1TimeRef> for Asn1Time { fn eq(&self, other: &&'a Asn1TimeRef) -> bool { self.diff(other) @@ -394,21 +394,21 @@ impl<'a> PartialEq<&'a Asn1TimeRef> for Asn1Time { } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl PartialOrd for Asn1Time { fn partial_cmp(&self, other: &Asn1Time) -> Option { self.compare(other).ok() } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl PartialOrd for Asn1Time { fn partial_cmp(&self, other: &Asn1TimeRef) -> Option { self.compare(other).ok() } } -#[cfg(ossl102)] +#[cfg(any(ossl102, boringssl))] impl<'a> PartialOrd<&'a Asn1TimeRef> for Asn1Time { fn partial_cmp(&self, other: &&'a Asn1TimeRef) -> Option { self.compare(other).ok() @@ -809,7 +809,7 @@ mod tests { } #[test] - #[cfg(ossl102)] + #[cfg(any(ossl102, boringssl))] fn time_eq() { let a = Asn1Time::from_str("99991231235959Z").unwrap(); let b = Asn1Time::from_str("99991231235959Z").unwrap(); @@ -828,7 +828,7 @@ mod tests { } #[test] - #[cfg(ossl102)] + #[cfg(any(ossl102, boringssl))] fn time_ord() { let a = Asn1Time::from_str("99991231235959Z").unwrap(); let b = Asn1Time::from_str("99991231235959Z").unwrap(); diff --git a/openssl/src/cipher.rs b/openssl/src/cipher.rs index b5c82e8f68..c4cb260434 100644 --- a/openssl/src/cipher.rs +++ b/openssl/src/cipher.rs @@ -167,6 +167,10 @@ impl Cipher { } #[cfg(not(boringssl))] + pub fn aes_256_xts() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_xts() as *mut _) } + } + pub fn aes_128_ctr() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) } } @@ -195,7 +199,6 @@ impl Cipher { 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 _) } } @@ -364,15 +367,29 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) } } + pub fn des_ede3_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ecb() as *mut _) } + } + pub fn des_ede3_cbc() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) } } + #[cfg(not(boringssl))] + pub fn des_ede3_cfb8() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb8() as *mut _) } + } + #[cfg(not(boringssl))] pub fn des_ede3_cfb64() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) } } + #[cfg(not(boringssl))] + pub fn des_ede3_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ofb() as *mut _) } + } + #[cfg(not(osslconf = "OPENSSL_NO_RC4"))] pub fn rc4() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) } @@ -393,6 +410,11 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cbc() as *mut _) } } + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia128_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ofb() as *mut _) } + } + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] pub fn camellia192_cfb128() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) } @@ -408,6 +430,11 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cbc() as *mut _) } } + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia192_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ofb() as *mut _) } + } + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] pub fn camellia256_cfb128() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) } @@ -423,6 +450,11 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cbc() as *mut _) } } + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia256_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ofb() as *mut _) } + } + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] pub fn cast5_cfb64() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) } @@ -438,6 +470,11 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cbc() as *mut _) } } + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ofb() as *mut _) } + } + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] pub fn idea_cfb64() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) } @@ -453,6 +490,11 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_idea_cbc() as *mut _) } } + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_idea_ofb() as *mut _) } + } + #[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))] pub fn chacha20() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) } diff --git a/openssl/src/dh.rs b/openssl/src/dh.rs index d46b9ee466..c8d135f300 100644 --- a/openssl/src/dh.rs +++ b/openssl/src/dh.rs @@ -334,6 +334,8 @@ cfg_if! { mod tests { use crate::bn::BigNum; use crate::dh::Dh; + #[cfg(all(not(boringssl), ossl110))] + use crate::pkey::PKey; use crate::ssl::{SslContext, SslMethod}; #[test] @@ -382,6 +384,23 @@ mod tests { assert_eq!(dh.generator(), &generator); } + #[test] + #[cfg(all(not(boringssl), ossl110))] + fn test_from_dhx_serializes_q() { + let p = BigNum::from_hex_str("00ad107e1e9123a9d0d660faa79559c51fa20d64e5683b9fd1b54b1597b61d0a75e6fa141df95a56dbaf9a3c407ba1df15eb3d688a309c180e1de6b85a1274a0a66d3f8152ad6ac2129037c9edefda4df8d91e8fef55b7394b7ad5b7d0b6c12207c9f98d11ed34dbf6c6ba0b2c8bbc27be6a00e0a0b9c49708b3bf8a317091883681286130bc8985db1602e714415d9330278273c7de31efdc7310f7121fd5a07415987d9adc0a486dcdf93acc44328387315d75e198c641a480cd86a1b9e587e8be60e69cc928b2b9c52172e413042e9b23f10b0e16e79763c9b53dcf4ba80a29e3fb73c16b8e75b97ef363e2ffa31f71cf9de5384e71b81c0ac4dffe0c10e64f").unwrap(); + let g = BigNum::from_hex_str("00ac4032ef4f2d9ae39df30b5c8ffdac506cdebe7b89998caf74866a08cfe4ffe3a6824a4e10b9a6f0dd921f01a70c4afaab739d7700c29f52c57db17c620a8652be5e9001a8d66ad7c17669101999024af4d027275ac1348bb8a762d0521bc98ae247150422ea1ed409939d54da7460cdb5f6c6b250717cbef180eb34118e98d119529a45d6f834566e3025e316a330efbb77a86f0c1ab15b051ae3d428c8f8acb70a8137150b8eeb10e183edd19963ddd9e263e4770589ef6aa21e7f5f2ff381b539cce3409d13cd566afbb48d6c019181e1bcfe94b30269edfe72fe9b6aa4bd7b5a0f1c71cfff4c19c418e1f6ec017981bc087f2a7065b384b890d3191f2bfa").unwrap(); + let q = BigNum::from_hex_str("00801c0d34c58d93fe997177101f80535a4738cebcbf389a99b36371eb") + .unwrap(); + let y = BigNum::from_hex_str("0082c165bb576243ecf46d58c3d1501616955fca0320fa95ea11d2e6c1b9cf217676720dc1c08c85bf20c4d232b60a29a1e51c7b773bc645014587c525c86151b30d75486ec7b6c98efb5f74955b83116d01d0af1232af89213c2de574369d701aba9357300b920d3d8b98252d46c46952c16a5f33554b38317809c7b9add4701f5c158c1b7035e9fe39366ececb90d2896b78c523c4a577287ef5ba7a2663ed58aa20b5ec66e30f316610dfaa38583e495ab6af771c284387e660edbef4edb872e2e80e1d244ee95622e76d028e61c1e887c2aa792717362139f4dd26eafd49b2366eeb2350b01fe1b56022a2809e379559c37b375ba01c4eaacc14fd1b247837").unwrap(); + + let dh = Dh::from_params(p, g, q).unwrap(); + let dh = dh.set_public_key(y).unwrap(); + + // Verify that 'q' is serialized in the public key. + let pkey = PKey::from_dhx(dh).unwrap(); + assert_eq!(pkey.public_key_to_der().unwrap(), b"\x30\x82\x03\x44\x30\x82\x02\x36\x06\x07\x2a\x86\x48\xce\x3e\x02\x01\x30\x82\x02\x29\x02\x82\x01\x01\x00\xad\x10\x7e\x1e\x91\x23\xa9\xd0\xd6\x60\xfa\xa7\x95\x59\xc5\x1f\xa2\x0d\x64\xe5\x68\x3b\x9f\xd1\xb5\x4b\x15\x97\xb6\x1d\x0a\x75\xe6\xfa\x14\x1d\xf9\x5a\x56\xdb\xaf\x9a\x3c\x40\x7b\xa1\xdf\x15\xeb\x3d\x68\x8a\x30\x9c\x18\x0e\x1d\xe6\xb8\x5a\x12\x74\xa0\xa6\x6d\x3f\x81\x52\xad\x6a\xc2\x12\x90\x37\xc9\xed\xef\xda\x4d\xf8\xd9\x1e\x8f\xef\x55\xb7\x39\x4b\x7a\xd5\xb7\xd0\xb6\xc1\x22\x07\xc9\xf9\x8d\x11\xed\x34\xdb\xf6\xc6\xba\x0b\x2c\x8b\xbc\x27\xbe\x6a\x00\xe0\xa0\xb9\xc4\x97\x08\xb3\xbf\x8a\x31\x70\x91\x88\x36\x81\x28\x61\x30\xbc\x89\x85\xdb\x16\x02\xe7\x14\x41\x5d\x93\x30\x27\x82\x73\xc7\xde\x31\xef\xdc\x73\x10\xf7\x12\x1f\xd5\xa0\x74\x15\x98\x7d\x9a\xdc\x0a\x48\x6d\xcd\xf9\x3a\xcc\x44\x32\x83\x87\x31\x5d\x75\xe1\x98\xc6\x41\xa4\x80\xcd\x86\xa1\xb9\xe5\x87\xe8\xbe\x60\xe6\x9c\xc9\x28\xb2\xb9\xc5\x21\x72\xe4\x13\x04\x2e\x9b\x23\xf1\x0b\x0e\x16\xe7\x97\x63\xc9\xb5\x3d\xcf\x4b\xa8\x0a\x29\xe3\xfb\x73\xc1\x6b\x8e\x75\xb9\x7e\xf3\x63\xe2\xff\xa3\x1f\x71\xcf\x9d\xe5\x38\x4e\x71\xb8\x1c\x0a\xc4\xdf\xfe\x0c\x10\xe6\x4f\x02\x82\x01\x01\x00\xac\x40\x32\xef\x4f\x2d\x9a\xe3\x9d\xf3\x0b\x5c\x8f\xfd\xac\x50\x6c\xde\xbe\x7b\x89\x99\x8c\xaf\x74\x86\x6a\x08\xcf\xe4\xff\xe3\xa6\x82\x4a\x4e\x10\xb9\xa6\xf0\xdd\x92\x1f\x01\xa7\x0c\x4a\xfa\xab\x73\x9d\x77\x00\xc2\x9f\x52\xc5\x7d\xb1\x7c\x62\x0a\x86\x52\xbe\x5e\x90\x01\xa8\xd6\x6a\xd7\xc1\x76\x69\x10\x19\x99\x02\x4a\xf4\xd0\x27\x27\x5a\xc1\x34\x8b\xb8\xa7\x62\xd0\x52\x1b\xc9\x8a\xe2\x47\x15\x04\x22\xea\x1e\xd4\x09\x93\x9d\x54\xda\x74\x60\xcd\xb5\xf6\xc6\xb2\x50\x71\x7c\xbe\xf1\x80\xeb\x34\x11\x8e\x98\xd1\x19\x52\x9a\x45\xd6\xf8\x34\x56\x6e\x30\x25\xe3\x16\xa3\x30\xef\xbb\x77\xa8\x6f\x0c\x1a\xb1\x5b\x05\x1a\xe3\xd4\x28\xc8\xf8\xac\xb7\x0a\x81\x37\x15\x0b\x8e\xeb\x10\xe1\x83\xed\xd1\x99\x63\xdd\xd9\xe2\x63\xe4\x77\x05\x89\xef\x6a\xa2\x1e\x7f\x5f\x2f\xf3\x81\xb5\x39\xcc\xe3\x40\x9d\x13\xcd\x56\x6a\xfb\xb4\x8d\x6c\x01\x91\x81\xe1\xbc\xfe\x94\xb3\x02\x69\xed\xfe\x72\xfe\x9b\x6a\xa4\xbd\x7b\x5a\x0f\x1c\x71\xcf\xff\x4c\x19\xc4\x18\xe1\xf6\xec\x01\x79\x81\xbc\x08\x7f\x2a\x70\x65\xb3\x84\xb8\x90\xd3\x19\x1f\x2b\xfa\x02\x1d\x00\x80\x1c\x0d\x34\xc5\x8d\x93\xfe\x99\x71\x77\x10\x1f\x80\x53\x5a\x47\x38\xce\xbc\xbf\x38\x9a\x99\xb3\x63\x71\xeb\x03\x82\x01\x06\x00\x02\x82\x01\x01\x00\x82\xc1\x65\xbb\x57\x62\x43\xec\xf4\x6d\x58\xc3\xd1\x50\x16\x16\x95\x5f\xca\x03\x20\xfa\x95\xea\x11\xd2\xe6\xc1\xb9\xcf\x21\x76\x76\x72\x0d\xc1\xc0\x8c\x85\xbf\x20\xc4\xd2\x32\xb6\x0a\x29\xa1\xe5\x1c\x7b\x77\x3b\xc6\x45\x01\x45\x87\xc5\x25\xc8\x61\x51\xb3\x0d\x75\x48\x6e\xc7\xb6\xc9\x8e\xfb\x5f\x74\x95\x5b\x83\x11\x6d\x01\xd0\xaf\x12\x32\xaf\x89\x21\x3c\x2d\xe5\x74\x36\x9d\x70\x1a\xba\x93\x57\x30\x0b\x92\x0d\x3d\x8b\x98\x25\x2d\x46\xc4\x69\x52\xc1\x6a\x5f\x33\x55\x4b\x38\x31\x78\x09\xc7\xb9\xad\xd4\x70\x1f\x5c\x15\x8c\x1b\x70\x35\xe9\xfe\x39\x36\x6e\xce\xcb\x90\xd2\x89\x6b\x78\xc5\x23\xc4\xa5\x77\x28\x7e\xf5\xba\x7a\x26\x63\xed\x58\xaa\x20\xb5\xec\x66\xe3\x0f\x31\x66\x10\xdf\xaa\x38\x58\x3e\x49\x5a\xb6\xaf\x77\x1c\x28\x43\x87\xe6\x60\xed\xbe\xf4\xed\xb8\x72\xe2\xe8\x0e\x1d\x24\x4e\xe9\x56\x22\xe7\x6d\x02\x8e\x61\xc1\xe8\x87\xc2\xaa\x79\x27\x17\x36\x21\x39\xf4\xdd\x26\xea\xfd\x49\xb2\x36\x6e\xeb\x23\x50\xb0\x1f\xe1\xb5\x60\x22\xa2\x80\x9e\x37\x95\x59\xc3\x7b\x37\x5b\xa0\x1c\x4e\xaa\xcc\x14\xfd\x1b\x24\x78\x37"); + } + #[test] #[cfg(ossl102)] fn test_dh_stored_restored() { diff --git a/openssl/src/nid.rs b/openssl/src/nid.rs index a1f3b1e635..e50feb0683 100644 --- a/openssl/src/nid.rs +++ b/openssl/src/nid.rs @@ -215,13 +215,13 @@ impl Nid { pub const SECT409R1: Nid = Nid(ffi::NID_sect409r1); pub const SECT571K1: Nid = Nid(ffi::NID_sect571k1); pub const SECT571R1: Nid = Nid(ffi::NID_sect571r1); - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl))] pub const BRAINPOOL_P256R1: Nid = Nid(ffi::NID_brainpoolP256r1); - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl))] pub const BRAINPOOL_P320R1: Nid = Nid(ffi::NID_brainpoolP320r1); - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl))] pub const BRAINPOOL_P384R1: Nid = Nid(ffi::NID_brainpoolP384r1); - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl))] pub const BRAINPOOL_P512R1: Nid = Nid(ffi::NID_brainpoolP512r1); pub const WAP_WSG_IDM_ECID_WTLS1: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls1); pub const WAP_WSG_IDM_ECID_WTLS3: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls3); diff --git a/openssl/src/pkcs7.rs b/openssl/src/pkcs7.rs index a272c598b8..65a6e7318e 100644 --- a/openssl/src/pkcs7.rs +++ b/openssl/src/pkcs7.rs @@ -4,16 +4,31 @@ use libc::c_int; use std::mem; use std::ptr; +use crate::asn1::Asn1ObjectRef; use crate::bio::{MemBio, MemBioSlice}; use crate::error::ErrorStack; +use crate::nid::Nid; use crate::pkey::{HasPrivate, PKeyRef}; -use crate::stack::{Stack, StackRef}; +use crate::stack::{Stack, StackRef, Stackable}; use crate::symm::Cipher; +use crate::util::ForeignTypeRefExt; use crate::x509::store::X509StoreRef; use crate::x509::{X509Ref, X509}; use crate::{cvt, cvt_p}; use openssl_macros::corresponds; +foreign_type_and_impl_send_sync! { + type CType = ffi::PKCS7_SIGNER_INFO; + fn drop = ffi::PKCS7_SIGNER_INFO_free; + + pub struct Pkcs7SignerInfo; + pub struct Pkcs7SignerInfoRef; +} + +impl Stackable for Pkcs7SignerInfo { + type StackType = ffi::stack_st_PKCS7_SIGNER_INFO; +} + foreign_type_and_impl_send_sync! { type CType = ffi::PKCS7; fn drop = ffi::PKCS7_free; @@ -27,6 +42,19 @@ foreign_type_and_impl_send_sync! { pub struct Pkcs7Ref; } +foreign_type_and_impl_send_sync! { + type CType = ffi::PKCS7_SIGNED; + fn drop = ffi::PKCS7_SIGNED_free; + + /// A PKCS#7 signed data structure. + /// + /// Contains signed data. + pub struct Pkcs7Signed; + + /// Reference to `Pkcs7Signed` + pub struct Pkcs7SignedRef; +} + bitflags! { #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[repr(transparent)] @@ -281,11 +309,43 @@ impl Pkcs7Ref { Ok(stack) } } + + /// Return the type of a PKCS#7 structure as an Asn1Object + pub fn type_(&self) -> Option<&Asn1ObjectRef> { + unsafe { + let ptr = (*self.as_ptr()).type_; + Asn1ObjectRef::from_const_ptr_opt(ptr) + } + } + + /// Get the signed data of a PKCS#7 structure of type PKCS7_SIGNED + pub fn signed(&self) -> Option<&Pkcs7SignedRef> { + unsafe { + if self.type_().map(|x| x.nid()) != Some(Nid::PKCS7_SIGNED) { + return None; + } + let signed_data = (*self.as_ptr()).d.sign; + Pkcs7SignedRef::from_const_ptr_opt(signed_data) + } + } +} + +impl Pkcs7SignedRef { + /// Get the stack of certificates from the PKCS7_SIGNED object + pub fn certificates(&self) -> Option<&StackRef> { + unsafe { + self.as_ptr() + .as_ref() + .and_then(|x| x.cert.as_mut()) + .and_then(|x| StackRef::::from_const_ptr_opt(x)) + } + } } #[cfg(test)] mod tests { use crate::hash::MessageDigest; + use crate::nid::Nid; use crate::pkcs7::{Pkcs7, Pkcs7Flags}; use crate::pkey::PKey; use crate::stack::Stack; @@ -307,6 +367,10 @@ mod tests { let pkcs7 = Pkcs7::encrypt(&certs, message.as_bytes(), cipher, flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_ENVELOPED + ); let encrypted = pkcs7 .to_smime(message.as_bytes(), flags) @@ -340,6 +404,10 @@ mod tests { let pkcs7 = Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_SIGNED + ); let signed = pkcs7 .to_smime(message.as_bytes(), flags) @@ -384,6 +452,10 @@ mod tests { let pkcs7 = Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_SIGNED + ); let signed = pkcs7 .to_smime(message.as_bytes(), flags) @@ -421,6 +493,10 @@ mod tests { let pkcs7 = Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_SIGNED + ); let signed = pkcs7 .to_smime(message.as_bytes(), flags) @@ -445,4 +521,53 @@ mod tests { assert!(result.is_err()); } + + #[test] + fn signed_data_certificates() { + let cert = include_bytes!("../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let mut extra_certs = Stack::::new().unwrap(); + for cert in + X509::stack_from_pem(include_bytes!("../test/certs.pem")).expect("should succeed") + { + extra_certs.push(cert).expect("should succeed"); + } + + let message = "foo"; + let flags = Pkcs7Flags::STREAM; + let pkey = include_bytes!("../test/key.pem"); + let pkey = PKey::private_key_from_pem(pkey).unwrap(); + + let pkcs7 = Pkcs7::sign(&cert, &pkey, &extra_certs, message.as_bytes(), flags) + .expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_SIGNED + ); + let signed_data_certs = pkcs7.signed().and_then(|x| x.certificates()); + assert_eq!(signed_data_certs.expect("should succeed").len(), 3); + } + + #[test] + fn signed_data_certificates_no_signed_data() { + let cert = include_bytes!("../test/certs.pem"); + let cert = X509::from_pem(cert).unwrap(); + let mut certs = Stack::new().unwrap(); + certs.push(cert).unwrap(); + let message: String = String::from("foo"); + let cipher = Cipher::des_ede3_cbc(); + let flags = Pkcs7Flags::STREAM; + + // Use `Pkcs7::encrypt` since it populates the PKCS7_ENVELOPE struct rather than + // PKCS7_SIGNED + let pkcs7 = + Pkcs7::encrypt(&certs, message.as_bytes(), cipher, flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_ENVELOPED + ); + + let signed_data_certs = pkcs7.signed().and_then(|x| x.certificates()); + assert!(signed_data_certs.is_none()) + } } diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 8f0b5bdf70..7892e65cb1 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -443,6 +443,22 @@ impl PKey { } } + /// Creates a new `PKey` containing a Diffie-Hellman key with type DHX. + #[cfg(all(not(boringssl), ossl110))] + pub fn from_dhx(dh: Dh) -> Result, ErrorStack> { + unsafe { + let evp = cvt_p(ffi::EVP_PKEY_new())?; + let pkey = PKey::from_ptr(evp); + cvt(ffi::EVP_PKEY_assign( + pkey.0, + ffi::EVP_PKEY_DHX, + dh.as_ptr().cast(), + ))?; + mem::forget(dh); + Ok(pkey) + } + } + /// Creates a new `PKey` containing an elliptic curve key. #[corresponds(EVP_PKEY_assign_EC_KEY)] pub fn from_ec_key(ec_key: EcKey) -> Result, ErrorStack> { @@ -747,12 +763,22 @@ impl PKey { } impl PKey { - from_pem! { + private_key_from_pem! { /// Decodes a PEM-encoded SubjectPublicKeyInfo structure. /// /// The input should have a header of `-----BEGIN PUBLIC KEY-----`. #[corresponds(PEM_read_bio_PUBKEY)] public_key_from_pem, + + /// Decodes a PEM-encoded SubjectPublicKeyInfo structure. + #[corresponds(PEM_read_bio_PUBKEY)] + public_key_from_pem_passphrase, + + /// Decodes a PEM-encoded SubjectPublicKeyInfo structure. + /// + /// The callback should fill the password into the provided buffer and return its length. + #[corresponds(PEM_read_bio_PrivateKey)] + public_key_from_pem_callback, PKey, ffi::PEM_read_bio_PUBKEY } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index fe1e38649f..30fd23665d 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -654,8 +654,8 @@ impl SslVersion { /// TLSv1.3 /// - /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. - #[cfg(any(ossl111, libressl340))] + /// Requires BoringSSL or OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[cfg(any(ossl111, libressl340, boringssl))] pub const TLS1_3: SslVersion = SslVersion(ffi::TLS1_3_VERSION); /// DTLSv1.0 @@ -666,7 +666,7 @@ impl SslVersion { /// DTLSv1.2 /// /// DTLS 1.2 corresponds to TLS 1.2 to harmonize versions. There was never a DTLS 1.1. - #[cfg(any(ossl102, libressl332))] + #[cfg(any(ossl102, libressl332, boringssl))] pub const DTLS1_2: SslVersion = SslVersion(ffi::DTLS1_2_VERSION); } @@ -1147,9 +1147,9 @@ impl SslContextBuilder { /// A value of `None` will enable protocol versions down to the lowest version supported by /// OpenSSL. /// - /// Requires OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer. + /// Requires BoringSSL or OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer. #[corresponds(SSL_CTX_set_min_proto_version)] - #[cfg(any(ossl110, libressl261))] + #[cfg(any(ossl110, libressl261, boringssl))] pub fn set_min_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_min_proto_version( @@ -1165,9 +1165,9 @@ impl SslContextBuilder { /// A value of `None` will enable protocol versions up to the highest version supported by /// OpenSSL. /// - /// Requires OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer. + /// Requires BoringSSL or OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer. #[corresponds(SSL_CTX_set_max_proto_version)] - #[cfg(any(ossl110, libressl261))] + #[cfg(any(ossl110, libressl261, boringssl))] pub fn set_max_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_max_proto_version( @@ -1223,16 +1223,16 @@ impl SslContextBuilder { /// and `http/1.1` is encoded as `b"\x06spdy/1\x08http/1.1"`. The protocols are ordered by /// preference. /// - /// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. + /// Requires BoringSSL or OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. #[corresponds(SSL_CTX_set_alpn_protos)] - #[cfg(any(ossl102, libressl261))] + #[cfg(any(ossl102, libressl261, boringssl))] pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> { unsafe { assert!(protocols.len() <= c_uint::max_value() as usize); let r = ffi::SSL_CTX_set_alpn_protos( self.as_ptr(), protocols.as_ptr(), - protocols.len() as c_uint, + protocols.len() as _, ); // fun fact, SSL_CTX_set_alpn_protos has a reversed return code D: if r == 0 { @@ -2480,19 +2480,16 @@ impl SslRef { /// Like [`SslContextBuilder::set_alpn_protos`]. /// - /// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. + /// Requires BoringSSL or OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. /// /// [`SslContextBuilder::set_alpn_protos`]: struct.SslContextBuilder.html#method.set_alpn_protos #[corresponds(SSL_set_alpn_protos)] - #[cfg(any(ossl102, libressl261))] + #[cfg(any(ossl102, libressl261, boringssl))] pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> { unsafe { assert!(protocols.len() <= c_uint::max_value() as usize); - let r = ffi::SSL_set_alpn_protos( - self.as_ptr(), - protocols.as_ptr(), - protocols.len() as c_uint, - ); + let r = + ffi::SSL_set_alpn_protos(self.as_ptr(), protocols.as_ptr(), protocols.len() as _); // fun fact, SSL_set_alpn_protos has a reversed return code D: if r == 0 { Ok(()) @@ -2639,9 +2636,9 @@ impl SslRef { /// The protocol's name is returned is an opaque sequence of bytes. It is up to the client /// to interpret it. /// - /// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. + /// Requires BoringSSL or OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. #[corresponds(SSL_get0_alpn_selected)] - #[cfg(any(ossl102, libressl261))] + #[cfg(any(ossl102, libressl261, boringssl))] pub fn selected_alpn_protocol(&self) -> Option<&[u8]> { unsafe { let mut data: *const c_uchar = ptr::null(); @@ -3334,9 +3331,9 @@ impl SslRef { /// A value of `None` will enable protocol versions down to the lowest version supported by /// OpenSSL. /// - /// Requires OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer. + /// Requires BoringSSL or OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer. #[corresponds(SSL_set_min_proto_version)] - #[cfg(any(ossl110, libressl261))] + #[cfg(any(ossl110, libressl261, boringssl))] pub fn set_min_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_min_proto_version( @@ -3352,9 +3349,9 @@ impl SslRef { /// A value of `None` will enable protocol versions up to the highest version supported by /// OpenSSL. /// - /// Requires OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer. + /// Requires BoringSSL or OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer. #[corresponds(SSL_set_max_proto_version)] - #[cfg(any(ossl110, libressl261))] + #[cfg(any(ossl110, libressl261, boringssl))] pub fn set_max_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_max_proto_version( diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index 412c4a5dc6..a98bc5644d 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -552,7 +552,7 @@ fn test_alpn_server_select_none() { } #[test] -#[cfg(any(ossl102, libressl261))] +#[cfg(any(boringssl, ossl102, libressl261))] fn test_alpn_server_unilateral() { let server = Server::builder().build(); diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 115193ee05..cf3e3c76fb 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -480,7 +480,7 @@ impl X509Ref { /// Retrieves the path length extension from a certificate, if it exists. #[corresponds(X509_get_pathlen)] - #[cfg(ossl110)] + #[cfg(any(ossl110, boringssl))] pub fn pathlen(&self) -> Option { let v = unsafe { ffi::X509_get_pathlen(self.as_ptr()) }; u32::try_from(v).ok() @@ -488,7 +488,7 @@ impl X509Ref { /// Returns this certificate's subject key id, if it exists. #[corresponds(X509_get0_subject_key_id)] - #[cfg(ossl110)] + #[cfg(any(ossl110, boringssl))] pub fn subject_key_id(&self) -> Option<&Asn1OctetStringRef> { unsafe { let data = ffi::X509_get0_subject_key_id(self.as_ptr()); @@ -498,7 +498,7 @@ impl X509Ref { /// Returns this certificate's authority key id, if it exists. #[corresponds(X509_get0_authority_key_id)] - #[cfg(ossl110)] + #[cfg(any(ossl110, boringssl))] pub fn authority_key_id(&self) -> Option<&Asn1OctetStringRef> { unsafe { let data = ffi::X509_get0_authority_key_id(self.as_ptr()); @@ -756,12 +756,13 @@ impl X509 { ffi::PEM_read_bio_X509(bio.as_ptr(), ptr::null_mut(), None, ptr::null_mut()); if r.is_null() { 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 - { - break; + + if let Some(err) = e.errors().last() { + if err.library_code() == ffi::ERR_LIB_PEM as libc::c_int + && err.reason_code() == ffi::PEM_R_NO_START_LINE as libc::c_int + { + break; + } } return Err(e); diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 0444a067dd..7d66112811 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -172,7 +172,7 @@ fn test_subject_alt_name() { } #[test] -#[cfg(ossl110)] +#[cfg(any(ossl110, boringssl))] fn test_retrieve_pathlen() { let cert = include_bytes!("../../test/root-ca.pem"); let cert = X509::from_pem(cert).unwrap(); @@ -188,7 +188,7 @@ fn test_retrieve_pathlen() { } #[test] -#[cfg(ossl110)] +#[cfg(any(ossl110, boringssl))] fn test_subject_key_id() { let cert = include_bytes!("../../test/certv3.pem"); let cert = X509::from_pem(cert).unwrap(); @@ -201,7 +201,7 @@ fn test_subject_key_id() { } #[test] -#[cfg(ossl110)] +#[cfg(any(ossl110, boringssl))] fn test_authority_key_id() { let cert = include_bytes!("../../test/certv3.pem"); let cert = X509::from_pem(cert).unwrap(); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy