diff options
Diffstat (limited to 'vendor/openssl/src')
-rw-r--r-- | vendor/openssl/src/bn.rs | 60 | ||||
-rw-r--r-- | vendor/openssl/src/cipher.rs | 57 | ||||
-rw-r--r-- | vendor/openssl/src/cipher_ctx.rs | 188 | ||||
-rw-r--r-- | vendor/openssl/src/cms.rs | 2 | ||||
-rw-r--r-- | vendor/openssl/src/ec.rs | 63 | ||||
-rw-r--r-- | vendor/openssl/src/encrypt.rs | 6 | ||||
-rw-r--r-- | vendor/openssl/src/lib.rs | 2 | ||||
-rw-r--r-- | vendor/openssl/src/ocsp.rs | 2 | ||||
-rw-r--r-- | vendor/openssl/src/pkcs7.rs | 14 | ||||
-rw-r--r-- | vendor/openssl/src/pkey_ctx.rs | 205 | ||||
-rw-r--r-- | vendor/openssl/src/sign.rs | 2 | ||||
-rw-r--r-- | vendor/openssl/src/ssl/callbacks.rs | 9 | ||||
-rw-r--r-- | vendor/openssl/src/ssl/mod.rs | 37 | ||||
-rw-r--r-- | vendor/openssl/src/symm.rs | 4 | ||||
-rw-r--r-- | vendor/openssl/src/x509/mod.rs | 2 | ||||
-rw-r--r-- | vendor/openssl/src/x509/verify.rs | 33 |
16 files changed, 648 insertions, 38 deletions
diff --git a/vendor/openssl/src/bn.rs b/vendor/openssl/src/bn.rs index 5cfe4b375..c75fac1d7 100644 --- a/vendor/openssl/src/bn.rs +++ b/vendor/openssl/src/bn.rs @@ -335,6 +335,20 @@ impl BigNumRef { unsafe { BN_is_negative(self.as_ptr()) == 1 } } + /// Returns `true` is `self` is even. + #[corresponds(BN_is_even)] + #[cfg(any(ossl110, boringssl, libressl350))] + pub fn is_even(&self) -> bool { + !self.is_odd() + } + + /// Returns `true` is `self` is odd. + #[corresponds(BN_is_odd)] + #[cfg(any(ossl110, boringssl, libressl350))] + pub fn is_odd(&self) -> bool { + unsafe { ffi::BN_is_odd(self.as_ptr()) == 1 } + } + /// Returns the number of significant bits in `self`. #[corresponds(BN_num_bits)] #[allow(clippy::unnecessary_cast)] @@ -639,6 +653,26 @@ impl BigNumRef { } } + /// Places into `self` the modular square root of `a` such that `self^2 = a (mod p)` + #[corresponds(BN_mod_sqrt)] + #[cfg(ossl110)] + pub fn mod_sqrt( + &mut self, + a: &BigNumRef, + p: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt_p(ffi::BN_mod_sqrt( + self.as_ptr(), + a.as_ptr(), + p.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + /// Places the result of `a^p` in `self`. #[corresponds(BN_exp)] pub fn exp( @@ -1455,4 +1489,30 @@ mod tests { b.set_const_time(); assert!(b.is_const_time()) } + + #[cfg(ossl110)] + #[test] + fn test_mod_sqrt() { + let mut ctx = BigNumContext::new().unwrap(); + + let s = BigNum::from_hex_str("47A8DD7626B9908C80ACD7E0D3344D69").unwrap(); + let p = BigNum::from_hex_str("81EF47265B58BCE5").unwrap(); + let mut out = BigNum::new().unwrap(); + + out.mod_sqrt(&s, &p, &mut ctx).unwrap(); + assert_eq!(out, BigNum::from_hex_str("7C6D179E19B97BDD").unwrap()); + } + + #[test] + #[cfg(any(ossl110, boringssl, libressl350))] + fn test_odd_even() { + let a = BigNum::from_u32(17).unwrap(); + let b = BigNum::from_u32(18).unwrap(); + + assert!(a.is_odd()); + assert!(!b.is_odd()); + + assert!(!a.is_even()); + assert!(b.is_even()); + } } diff --git a/vendor/openssl/src/cipher.rs b/vendor/openssl/src/cipher.rs index 87f7660cd..2b8986136 100644 --- a/vendor/openssl/src/cipher.rs +++ b/vendor/openssl/src/cipher.rs @@ -12,6 +12,7 @@ use foreign_types::{ForeignTypeRef, Opaque}; use openssl_macros::corresponds; #[cfg(ossl300)] use std::ffi::CString; +use std::ops::{Deref, DerefMut}; #[cfg(ossl300)] use std::ptr; @@ -41,7 +42,6 @@ cfg_if! { cfg_if! { if #[cfg(ossl300)] { use foreign_types::ForeignType; - use std::ops::{Deref, DerefMut}; type Inner = *mut ffi::EVP_CIPHER; @@ -90,6 +90,22 @@ cfg_if! { } } else { enum Inner {} + + impl Deref for Cipher { + type Target = CipherRef; + + #[inline] + fn deref(&self) -> &Self::Target { + match self.0 {} + } + } + + impl DerefMut for Cipher { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + match self.0 {} + } + } } } @@ -170,7 +186,6 @@ impl Cipher { 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 _) } } @@ -191,6 +206,18 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) } } + /// Requires OpenSSL 1.0.2 or newer. + #[cfg(ossl102)] + pub fn aes_128_wrap() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(ossl110)] + pub fn aes_128_wrap_pad() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap_pad() as *mut _) } + } + pub fn aes_192_ecb() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) } } @@ -236,6 +263,18 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) } } + /// Requires OpenSSL 1.0.2 or newer. + #[cfg(ossl102)] + pub fn aes_192_wrap() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(ossl110)] + pub fn aes_192_wrap_pad() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap_pad() as *mut _) } + } + pub fn aes_256_ecb() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) } } @@ -281,6 +320,18 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) } } + /// Requires OpenSSL 1.0.2 or newer. + #[cfg(ossl102)] + pub fn aes_256_wrap() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(ossl110)] + pub fn aes_256_wrap_pad() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap_pad() as *mut _) } + } + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] pub fn bf_cbc() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) } @@ -384,7 +435,7 @@ impl Cipher { unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) } } - #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))] + #[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))] pub fn chacha20_poly1305() -> &'static CipherRef { unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) } } diff --git a/vendor/openssl/src/cipher_ctx.rs b/vendor/openssl/src/cipher_ctx.rs index 216c09e5b..f9031d297 100644 --- a/vendor/openssl/src/cipher_ctx.rs +++ b/vendor/openssl/src/cipher_ctx.rs @@ -55,6 +55,8 @@ use crate::error::ErrorStack; #[cfg(not(boringssl))] use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef}; use crate::{cvt, cvt_p}; +#[cfg(ossl102)] +use bitflags::bitflags; use cfg_if::cfg_if; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_int, c_uchar}; @@ -80,6 +82,15 @@ foreign_type_and_impl_send_sync! { pub struct CipherCtxRef; } +#[cfg(ossl102)] +bitflags! { + /// Flags for `EVP_CIPHER_CTX`. + pub struct CipherCtxFlags : c_int { + /// The flag used to opt into AES key wrap ciphers. + const FLAG_WRAP_ALLOW = ffi::EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; + } +} + impl CipherCtx { /// Creates a new context. #[corresponds(EVP_CIPHER_CTX_new)] @@ -94,6 +105,14 @@ impl CipherCtx { } impl CipherCtxRef { + #[corresponds(EVP_CIPHER_CTX_copy)] + pub fn copy(&mut self, src: &CipherCtxRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_CIPHER_CTX_copy(self.as_ptr(), src.as_ptr()))?; + Ok(()) + } + } + /// Initializes the context for encryption. /// /// Normally this is called once to set all of the cipher, key, and IV. However, this process can be split up @@ -509,6 +528,17 @@ impl CipherCtxRef { Ok(()) } + /// Set ctx flags. + /// + /// This function is currently used to enable AES key wrap feature supported by OpenSSL 1.0.2 or newer. + #[corresponds(EVP_CIPHER_CTX_set_flags)] + #[cfg(ossl102)] + pub fn set_flags(&mut self, flags: CipherCtxFlags) { + unsafe { + ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits()); + } + } + /// Writes data into the context. /// /// Providing no output buffer will cause the input to be considered additional authenticated data (AAD). @@ -915,4 +945,162 @@ mod test { ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1])) .unwrap(); } + + #[cfg(ossl102)] + fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) { + let pt = hex::decode(pt).unwrap(); + let key = hex::decode(key).unwrap(); + let expected = hex::decode(ct).unwrap(); + let iv = iv.map(|v| hex::decode(v).unwrap()); + let padding = 8 - pt.len() % 8; + let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2]; + let mut ctx = CipherCtx::new().unwrap(); + + ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW); + ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref()) + .unwrap(); + + let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap(); + let rest = ctx.cipher_final(&mut computed[count..]).unwrap(); + computed.truncate(count + rest); + + if computed != expected { + println!("Computed: {}", hex::encode(&computed)); + println!("Expected: {}", hex::encode(&expected)); + if computed.len() != expected.len() { + println!( + "Lengths differ: {} in computed vs {} expected", + computed.len(), + expected.len() + ); + } + panic!("test failure"); + } + } + + #[test] + #[cfg(ossl102)] + fn test_aes128_wrap() { + let pt = "00112233445566778899aabbccddeeff"; + let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes128_wrap_default_iv() { + let pt = "00112233445566778899aabbccddeeff"; + let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + + cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes128_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes128_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + + cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl102)] + fn test_aes192_wrap() { + let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b"; + let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes192_wrap_default_iv() { + let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b"; + let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + + cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes192_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes192_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + + cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl102)] + fn test_aes256_wrap() { + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"; + let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes256_wrap_default_iv() { + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"; + let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + + cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes256_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes256_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + + cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None); + } } diff --git a/vendor/openssl/src/cms.rs b/vendor/openssl/src/cms.rs index 6b6aa9fd8..d11443b5c 100644 --- a/vendor/openssl/src/cms.rs +++ b/vendor/openssl/src/cms.rs @@ -20,6 +20,8 @@ use crate::{cvt, cvt_p}; use openssl_macros::corresponds; bitflags! { + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct CMSOptions : c_uint { const TEXT = ffi::CMS_TEXT; const CMS_NOCERTS = ffi::CMS_NOCERTS; diff --git a/vendor/openssl/src/ec.rs b/vendor/openssl/src/ec.rs index b648aec33..d541ddfc2 100644 --- a/vendor/openssl/src/ec.rs +++ b/vendor/openssl/src/ec.rs @@ -15,6 +15,7 @@ //! [`EcGroup`]: struct.EcGroup.html //! [`Nid`]: ../nid/struct.Nid.html //! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography +use cfg_if::cfg_if; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::c_int; use std::fmt; @@ -28,6 +29,13 @@ use crate::util::ForeignTypeRefExt; use crate::{cvt, cvt_n, cvt_p, init}; use openssl_macros::corresponds; +cfg_if! { + if #[cfg(not(boringssl))] { + use std::ffi::CString; + use crate::string::OpensslString; + } +} + /// Compressed or Uncompressed conversion /// /// Conversion from the binary value of the point on the curve is performed in one of @@ -463,6 +471,26 @@ impl EcPointRef { } } + /// Serializes the point to a hexadecimal string representation. + #[corresponds(EC_POINT_point2hex)] + #[cfg(not(boringssl))] + pub fn to_hex_str( + &self, + group: &EcGroupRef, + form: PointConversionForm, + ctx: &mut BigNumContextRef, + ) -> Result<OpensslString, ErrorStack> { + unsafe { + let buf = cvt_p(ffi::EC_POINT_point2hex( + group.as_ptr(), + self.as_ptr(), + form.0, + ctx.as_ptr(), + ))?; + Ok(OpensslString::from_ptr(buf)) + } + } + /// Creates a new point on the specified curve with the same value. #[corresponds(EC_POINT_dup)] pub fn to_owned(&self, group: &EcGroupRef) -> Result<EcPoint, ErrorStack> { @@ -631,6 +659,27 @@ impl EcPoint { } Ok(point) } + + /// Creates point from a hexadecimal string representation + #[corresponds(EC_POINT_hex2point)] + #[cfg(not(boringssl))] + pub fn from_hex_str( + group: &EcGroupRef, + s: &str, + ctx: &mut BigNumContextRef, + ) -> Result<EcPoint, ErrorStack> { + let point = EcPoint::new(group)?; + unsafe { + let c_str = CString::new(s.as_bytes()).unwrap(); + cvt_p(ffi::EC_POINT_hex2point( + group.as_ptr(), + c_str.as_ptr() as *const _, + point.as_ptr(), + ctx.as_ptr(), + ))?; + } + Ok(point) + } } generic_foreign_type_and_impl_send_sync! { @@ -1122,6 +1171,20 @@ mod test { } #[test] + #[cfg(not(boringssl))] + fn point_hex_str() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + let point = key.public_key(); + let mut ctx = BigNumContext::new().unwrap(); + let hex = point + .to_hex_str(&group, PointConversionForm::COMPRESSED, &mut ctx) + .unwrap(); + let point2 = EcPoint::from_hex_str(&group, &hex, &mut ctx).unwrap(); + assert!(point.eq(&group, &point2, &mut ctx).unwrap()); + } + + #[test] fn point_owned() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let key = EcKey::generate(&group).unwrap(); diff --git a/vendor/openssl/src/encrypt.rs b/vendor/openssl/src/encrypt.rs index d3db0fd41..4522146f8 100644 --- a/vendor/openssl/src/encrypt.rs +++ b/vendor/openssl/src/encrypt.rs @@ -40,7 +40,7 @@ //! assert_eq!(&*decrypted, data); //! ``` #[cfg(any(ossl102, libressl310))] -use libc::{c_int, c_void}; +use libc::c_int; use std::{marker::PhantomData, ptr}; use crate::error::ErrorStack; @@ -174,7 +174,7 @@ impl<'a> Encrypter<'a> { cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label( self.pctx, - p as *mut c_void, + p, label.len() as c_int, )) .map(|_| ()) @@ -378,7 +378,7 @@ impl<'a> Decrypter<'a> { cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label( self.pctx, - p as *mut c_void, + p, label.len() as c_int, )) .map(|_| ()) diff --git a/vendor/openssl/src/lib.rs b/vendor/openssl/src/lib.rs index c2c390cc1..fe29d0229 100644 --- a/vendor/openssl/src/lib.rs +++ b/vendor/openssl/src/lib.rs @@ -44,7 +44,7 @@ //! $ sudo apt-get install pkg-config libssl-dev //! //! # Fedora -//! $ sudo dnf install pkg-config openssl-devel +//! $ sudo dnf install pkg-config perl-FindBin openssl-devel //! //! # Alpine Linux //! $ apk add pkgconfig openssl-dev diff --git a/vendor/openssl/src/ocsp.rs b/vendor/openssl/src/ocsp.rs index 7506d34fb..93a5d36b7 100644 --- a/vendor/openssl/src/ocsp.rs +++ b/vendor/openssl/src/ocsp.rs @@ -15,6 +15,8 @@ use crate::{cvt, cvt_p}; use openssl_macros::corresponds; bitflags! { + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct OcspFlag: c_ulong { const NO_CERTS = ffi::OCSP_NOCERTS; const NO_INTERN = ffi::OCSP_NOINTERN; diff --git a/vendor/openssl/src/pkcs7.rs b/vendor/openssl/src/pkcs7.rs index ae4571db8..a272c598b 100644 --- a/vendor/openssl/src/pkcs7.rs +++ b/vendor/openssl/src/pkcs7.rs @@ -28,6 +28,8 @@ foreign_type_and_impl_send_sync! { } bitflags! { + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct Pkcs7Flags: c_int { const TEXT = ffi::PKCS7_TEXT; const NOCERTS = ffi::PKCS7_NOCERTS; @@ -111,7 +113,7 @@ impl Pkcs7 { certs.as_ptr(), input_bio.as_ptr(), cipher.as_ptr(), - flags.bits, + flags.bits(), )) .map(Pkcs7) } @@ -141,7 +143,7 @@ impl Pkcs7 { pkey.as_ptr(), certs.as_ptr(), input_bio.as_ptr(), - flags.bits, + flags.bits(), )) .map(Pkcs7) } @@ -159,7 +161,7 @@ impl Pkcs7Ref { output.as_ptr(), self.as_ptr(), input_bio.as_ptr(), - flags.bits, + flags.bits(), )) .map(|_| output.get_buf().to_owned()) } @@ -205,7 +207,7 @@ impl Pkcs7Ref { pkey.as_ptr(), cert.as_ptr(), output.as_ptr(), - flags.bits, + flags.bits(), )) .map(|_| output.get_buf().to_owned()) } @@ -241,7 +243,7 @@ impl Pkcs7Ref { store.as_ptr(), indata_bio_ptr, out_bio.as_ptr(), - flags.bits, + flags.bits(), )) .map(|_| ())? } @@ -265,7 +267,7 @@ impl Pkcs7Ref { let ptr = cvt_p(ffi::PKCS7_get0_signers( self.as_ptr(), certs.as_ptr(), - flags.bits, + flags.bits(), ))?; // The returned stack is owned by the caller, but the certs inside are not! Our stack interface can't deal diff --git a/vendor/openssl/src/pkey_ctx.rs b/vendor/openssl/src/pkey_ctx.rs index aba8a66a3..4ac32a851 100644 --- a/vendor/openssl/src/pkey_ctx.rs +++ b/vendor/openssl/src/pkey_ctx.rs @@ -70,7 +70,8 @@ use crate::error::ErrorStack; use crate::md::MdRef; use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private}; use crate::rsa::Padding; -use crate::{cvt, cvt_n, cvt_p}; +use crate::sign::RsaPssSaltlen; +use crate::{cvt, cvt_p}; use foreign_types::{ForeignType, ForeignTypeRef}; #[cfg(not(boringssl))] use libc::c_int; @@ -164,6 +165,17 @@ where Ok(()) } + /// Prepares the context for signature recovery using the public key. + #[corresponds(EVP_PKEY_verify_recover_init)] + #[inline] + pub fn verify_recover_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_verify_recover_init(self.as_ptr()))?; + } + + Ok(()) + } + /// Encrypts data using the public key. /// /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be @@ -209,16 +221,54 @@ where #[inline] pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> { unsafe { - let r = cvt_n(ffi::EVP_PKEY_verify( + let r = ffi::EVP_PKEY_verify( self.as_ptr(), sig.as_ptr(), sig.len(), data.as_ptr(), data.len(), - ))?; + ); + // `EVP_PKEY_verify` is not terribly consistent about how it, + // reports errors. It does not clearly distinguish between 0 and + // -1, and may put errors on the stack in both cases. If there's + // errors on the stack, we return `Err()`, else we return + // `Ok(false)`. + if r <= 0 { + let errors = ErrorStack::get(); + if !errors.errors().is_empty() { + return Err(errors); + } + } + Ok(r == 1) } } + + /// Recovers the original data signed by the private key. You almost + /// always want `verify` instead. + /// + /// Returns the number of bytes written to `to`, or the number of bytes + /// that would be written, if `to` is `None. + #[corresponds(EVP_PKEY_verify_recover)] + #[inline] + pub fn verify_recover( + &mut self, + sig: &[u8], + to: Option<&mut [u8]>, + ) -> Result<usize, ErrorStack> { + let mut written = to.as_ref().map_or(0, |b| b.len()); + unsafe { + cvt(ffi::EVP_PKEY_verify_recover( + self.as_ptr(), + to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut written, + sig.as_ptr(), + sig.len(), + ))?; + } + + Ok(written) + } } impl<T> PkeyCtxRef<T> @@ -351,6 +401,22 @@ impl<T> PkeyCtxRef<T> { Ok(()) } + /// Sets which algorithm was used to compute the digest used in a + /// signature. With RSA signatures this causes the signature to be wrapped + /// in a `DigestInfo` structure. This is almost always what you want with + /// RSA signatures. + #[corresponds(EVP_PKEY_CTX_set_signature_md)] + #[inline] + pub fn set_signature_md(&self, md: &MdRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_signature_md( + self.as_ptr(), + md.as_ptr(), + ))?; + } + Ok(()) + } + /// Returns the RSA padding mode in use. /// /// This is only useful for RSA keys. @@ -381,6 +447,21 @@ impl<T> PkeyCtxRef<T> { Ok(()) } + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)] + #[inline] + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.as_ptr(), + len.as_raw(), + )) + .map(|_| ()) + } + } + /// Sets the RSA MGF1 algorithm. /// /// This is only useful for RSA keys. @@ -401,7 +482,7 @@ impl<T> PkeyCtxRef<T> { /// /// This is only useful for RSA keys. #[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)] - #[cfg(any(ossl102, libressl310))] + #[cfg(any(ossl102, libressl310, boringssl))] #[inline] pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> { unsafe { @@ -641,11 +722,12 @@ mod test { #[cfg(not(boringssl))] use crate::cipher::Cipher; use crate::ec::{EcGroup, EcKey}; - #[cfg(any(ossl102, libressl310, boringssl))] + use crate::hash::{hash, MessageDigest}; use crate::md::Md; use crate::nid::Nid; use crate::pkey::PKey; use crate::rsa::Rsa; + use crate::sign::Verifier; #[test] fn rsa() { @@ -671,7 +753,7 @@ mod test { } #[test] - #[cfg(any(ossl102, libressl310))] + #[cfg(any(ossl102, libressl310, boringssl))] fn rsa_oaep() { let key = include_bytes!("../test/rsa.pem"); let rsa = Rsa::private_key_from_pem(key).unwrap(); @@ -699,6 +781,53 @@ mod test { } #[test] + fn rsa_sign() { + let key = include_bytes!("../test/rsa.pem"); + let rsa = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + + let mut ctx = PkeyCtx::new(&pkey).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + ctx.set_signature_md(Md::sha384()).unwrap(); + + let msg = b"hello world"; + let digest = hash(MessageDigest::sha384(), msg).unwrap(); + let mut signature = vec![]; + ctx.sign_to_vec(&digest, &mut signature).unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap(); + verifier.update(msg).unwrap(); + assert!(matches!(verifier.verify(&signature), Ok(true))); + } + + #[test] + fn rsa_sign_pss() { + let key = include_bytes!("../test/rsa.pem"); + let rsa = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + + let mut ctx = PkeyCtx::new(&pkey).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + ctx.set_signature_md(Md::sha384()).unwrap(); + ctx.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)).unwrap(); + + let msg = b"hello world"; + let digest = hash(MessageDigest::sha384(), msg).unwrap(); + let mut signature = vec![]; + ctx.sign_to_vec(&digest, &mut signature).unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap(); + verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + verifier + .set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)) + .unwrap(); + verifier.update(msg).unwrap(); + assert!(matches!(verifier.verify(&signature), Ok(true))); + } + + #[test] fn derive() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let key1 = EcKey::generate(&group).unwrap(); @@ -807,7 +936,67 @@ mod test { let bad_data = b"Some Crypto text"; ctx.verify_init().unwrap(); - let valid = ctx.verify(bad_data, &signature).unwrap(); - assert!(!valid); + let valid = ctx.verify(bad_data, &signature); + assert!(matches!(valid, Ok(false) | Err(_))); + assert!(ErrorStack::get().errors().is_empty()); + } + + #[test] + fn verify_fail_ec() { + let key1 = + EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap(); + let key1 = PKey::from_ec_key(key1).unwrap(); + + let data = b"Some Crypto Text"; + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.verify_init().unwrap(); + assert!(matches!(ctx.verify(data, &[0; 64]), Ok(false) | Err(_))); + assert!(ErrorStack::get().errors().is_empty()); + } + + #[test] + fn test_verify_recover() { + let key = Rsa::generate(2048).unwrap(); + let key = PKey::from_rsa(key).unwrap(); + + let digest = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + ]; + + let mut ctx = PkeyCtx::new(&key).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + ctx.set_signature_md(Md::sha256()).unwrap(); + let mut signature = vec![]; + ctx.sign_to_vec(&digest, &mut signature).unwrap(); + + // Attempt recovery of just the digest. + let mut ctx = PkeyCtx::new(&key).unwrap(); + ctx.verify_recover_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + ctx.set_signature_md(Md::sha256()).unwrap(); + let length = ctx.verify_recover(&signature, None).unwrap(); + let mut result_buf = vec![0; length]; + let length = ctx + .verify_recover(&signature, Some(&mut result_buf)) + .unwrap(); + assert_eq!(length, digest.len()); + // result_buf contains the digest + assert_eq!(result_buf[..length], digest); + + // Attempt recovery of teh entire DigestInfo + let mut ctx = PkeyCtx::new(&key).unwrap(); + ctx.verify_recover_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + let length = ctx.verify_recover(&signature, None).unwrap(); + let mut result_buf = vec![0; length]; + let length = ctx + .verify_recover(&signature, Some(&mut result_buf)) + .unwrap(); + // 32-bytes of SHA256 digest + the ASN.1 DigestInfo structure == 51 bytes + assert_eq!(length, 51); + // The digest is the end of the DigestInfo structure. + assert_eq!(result_buf[length - digest.len()..length], digest); } } diff --git a/vendor/openssl/src/sign.rs b/vendor/openssl/src/sign.rs index a32f5c914..1c770d18b 100644 --- a/vendor/openssl/src/sign.rs +++ b/vendor/openssl/src/sign.rs @@ -93,7 +93,7 @@ pub struct RsaPssSaltlen(c_int); impl RsaPssSaltlen { /// Returns the integer representation of `RsaPssSaltlen`. - fn as_raw(&self) -> c_int { + pub(crate) fn as_raw(&self) -> c_int { self.0 } diff --git a/vendor/openssl/src/ssl/callbacks.rs b/vendor/openssl/src/ssl/callbacks.rs index 091b1fb77..c6414fb51 100644 --- a/vendor/openssl/src/ssl/callbacks.rs +++ b/vendor/openssl/src/ssl/callbacks.rs @@ -86,6 +86,7 @@ where }; // Give the callback mutable slices into which it can write the identity and psk. let identity_sl = slice::from_raw_parts_mut(identity as *mut u8, max_identity_len as usize); + #[allow(clippy::unnecessary_cast)] let psk_sl = slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize); match (*callback)(ssl, hint, identity_sl, psk_sl) { Ok(psk_len) => psk_len as u32, @@ -124,6 +125,7 @@ where Some(CStr::from_ptr(identity).to_bytes()) }; // Give the callback mutable slices into which it can write the psk. + #[allow(clippy::unnecessary_cast)] let psk_sl = slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize); match (*callback)(ssl, identity, psk_sl) { Ok(psk_len) => psk_len as u32, @@ -194,6 +196,7 @@ where .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: alpn callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize); match (*callback)(ssl, protos) { @@ -412,6 +415,7 @@ where .expect("BUG: session context missing") .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: get session callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] let data = slice::from_raw_parts(data as *const u8, len as usize); match (*callback)(ssl, data) { @@ -455,6 +459,7 @@ where .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: stateless cookie generate callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize); match (*callback)(ssl, slice) { Ok(len) => { @@ -482,6 +487,7 @@ where .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: stateless cookie verify callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len); (*callback)(ssl, slice) as c_int } @@ -503,6 +509,7 @@ where .expect("BUG: cookie generate callback missing") as *const F; // We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for // compatibility. See comments in dtls1.h. + #[allow(clippy::unnecessary_cast)] let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::DTLS1_COOKIE_LENGTH as usize - 1); match (*callback)(ssl, slice) { @@ -542,6 +549,7 @@ where .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: cookie verify callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize); (*callback)(ssl, slice) as c_int @@ -654,6 +662,7 @@ where .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: custom ext parse callback missing") as *const F; let ectx = ExtensionContext::from_bits_truncate(context); + #[allow(clippy::unnecessary_cast)] let slice = slice::from_raw_parts(input as *const u8, inlen); let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) { Some((chainidx, X509Ref::from_ptr(x))) diff --git a/vendor/openssl/src/ssl/mod.rs b/vendor/openssl/src/ssl/mod.rs index 27e817f30..bdfbfc14f 100644 --- a/vendor/openssl/src/ssl/mod.rs +++ b/vendor/openssl/src/ssl/mod.rs @@ -143,6 +143,8 @@ cfg_if! { bitflags! { /// Options controlling the behavior of an `SslContext`. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] 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 as SslOptionsRepr; @@ -281,6 +283,8 @@ bitflags! { bitflags! { /// Options controlling the behavior of an `SslContext`. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct SslMode: SslBitType { /// Enables "short writes". /// @@ -378,6 +382,8 @@ unsafe impl Send for SslMethod {} bitflags! { /// Options controlling the behavior of certificate verification. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct SslVerifyMode: i32 { /// Verifies that the peer's certificate is trusted. /// @@ -410,6 +416,8 @@ type SslTimeTy = c_long; bitflags! { /// Options controlling the behavior of session caching. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct SslSessionCacheMode: SslBitType { /// No session caching for the client or server takes place. const OFF = ffi::SSL_SESS_CACHE_OFF; @@ -447,6 +455,8 @@ bitflags! { #[cfg(ossl111)] bitflags! { /// Which messages and under which conditions an extension should be added or expected. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct ExtensionContext: c_uint { /// This extension is only allowed in TLS const TLS_ONLY = ffi::SSL_EXT_TLS_ONLY; @@ -735,7 +745,7 @@ impl SslContextBuilder { #[corresponds(SSL_CTX_set_verify)] pub fn set_verify(&mut self, mode: SslVerifyMode) { unsafe { - ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits as c_int, None); + ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits() as c_int, None); } } @@ -752,7 +762,7 @@ impl SslContextBuilder { { unsafe { self.set_ex_data(SslContext::cached_ex_index::<F>(), verify); - ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits as c_int, Some(raw_verify::<F>)); + ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits() as c_int, Some(raw_verify::<F>)); } } @@ -839,7 +849,7 @@ impl SslContextBuilder { pub fn set_mode(&mut self, mode: SslMode) -> SslMode { unsafe { let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits() as MtuTy) as SslBitType; - SslMode { bits } + SslMode::from_bits_retain(bits) } } @@ -1111,14 +1121,14 @@ impl SslContextBuilder { pub fn set_options(&mut self, option: SslOptions) -> SslOptions { let bits = unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) } as SslOptionsRepr; - SslOptions { bits } + SslOptions::from_bits_retain(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()) } as SslOptionsRepr; - SslOptions { bits } + SslOptions::from_bits_retain(bits) } /// Clears the options used by the context, returning the old set. @@ -1126,7 +1136,7 @@ impl SslContextBuilder { pub fn clear_options(&mut self, option: SslOptions) -> SslOptions { let bits = unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) } as SslOptionsRepr; - SslOptions { bits } + SslOptions::from_bits_retain(bits) } /// Sets the minimum supported protocol version. @@ -1475,7 +1485,7 @@ impl SslContextBuilder { pub fn set_session_cache_mode(&mut self, mode: SslSessionCacheMode) -> SslSessionCacheMode { unsafe { let bits = ffi::SSL_CTX_set_session_cache_mode(self.as_ptr(), mode.bits()); - SslSessionCacheMode { bits } + SslSessionCacheMode::from_bits_retain(bits) } } @@ -2122,6 +2132,7 @@ impl SslSessionRef { unsafe { let mut len = 0; let p = ffi::SSL_SESSION_get_id(self.as_ptr(), &mut len); + #[allow(clippy::unnecessary_cast)] slice::from_raw_parts(p as *const u8, len as usize) } } @@ -2350,7 +2361,7 @@ impl SslRef { /// [`SslContextBuilder::set_verify`]: struct.SslContextBuilder.html#method.set_verify #[corresponds(SSL_set_verify)] pub fn set_verify(&mut self, mode: SslVerifyMode) { - unsafe { ffi::SSL_set_verify(self.as_ptr(), mode.bits as c_int, None) } + unsafe { ffi::SSL_set_verify(self.as_ptr(), mode.bits() as c_int, None) } } /// Returns the verify mode that was set using `set_verify`. @@ -2371,7 +2382,11 @@ impl SslRef { unsafe { // this needs to be in an Arc since the callback can register a new callback! self.set_ex_data(Ssl::cached_ex_index(), Arc::new(verify)); - ffi::SSL_set_verify(self.as_ptr(), mode.bits as c_int, Some(ssl_raw_verify::<F>)); + ffi::SSL_set_verify( + self.as_ptr(), + mode.bits() as c_int, + Some(ssl_raw_verify::<F>), + ); } } @@ -3718,7 +3733,7 @@ impl<S: Read + Write> SslStream<S> { pub fn get_shutdown(&mut self) -> ShutdownState { unsafe { let bits = ffi::SSL_get_shutdown(self.ssl.as_ptr()); - ShutdownState { bits } + ShutdownState::from_bits_retain(bits) } } @@ -4051,6 +4066,8 @@ pub enum ShutdownResult { bitflags! { /// The shutdown state of a session. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct ShutdownState: c_int { /// A close notify message has been sent to the peer. const SENT = ffi::SSL_SENT_SHUTDOWN; diff --git a/vendor/openssl/src/symm.rs b/vendor/openssl/src/symm.rs index c1dbdfee7..7ebb70338 100644 --- a/vendor/openssl/src/symm.rs +++ b/vendor/openssl/src/symm.rs @@ -295,7 +295,7 @@ impl Cipher { } /// Requires OpenSSL 1.1.0 or newer. - #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_CHACHA")))] + #[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))] pub fn chacha20_poly1305() -> Cipher { unsafe { Cipher(ffi::EVP_chacha20_poly1305()) } } @@ -1493,7 +1493,7 @@ mod tests { } #[test] - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl360))] fn test_chacha20_poly1305() { let key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"; let iv = "070000004041424344454647"; diff --git a/vendor/openssl/src/x509/mod.rs b/vendor/openssl/src/x509/mod.rs index 4325b132e..24605df80 100644 --- a/vendor/openssl/src/x509/mod.rs +++ b/vendor/openssl/src/x509/mod.rs @@ -2102,6 +2102,7 @@ impl GeneralNameRef { let ptr = ASN1_STRING_get0_data(d as *mut _); let len = ffi::ASN1_STRING_length(d as *mut _); + #[allow(clippy::unnecessary_cast)] let slice = slice::from_raw_parts(ptr as *const u8, len as usize); // IA5Strings are stated to be ASCII (specifically IA5). Hopefully // OpenSSL checks that when loading a certificate but if not we'll @@ -2155,6 +2156,7 @@ impl GeneralNameRef { let ptr = ASN1_STRING_get0_data(d as *mut _); let len = ffi::ASN1_STRING_length(d as *mut _); + #[allow(clippy::unnecessary_cast)] Some(slice::from_raw_parts(ptr as *const u8, len as usize)) } } diff --git a/vendor/openssl/src/x509/verify.rs b/vendor/openssl/src/x509/verify.rs index e8481c551..541cd8266 100644 --- a/vendor/openssl/src/x509/verify.rs +++ b/vendor/openssl/src/x509/verify.rs @@ -11,6 +11,8 @@ use openssl_macros::corresponds; bitflags! { /// Flags used to check an `X509` certificate. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct X509CheckFlags: c_uint { const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT; const NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS; @@ -28,6 +30,8 @@ bitflags! { bitflags! { /// Flags used to verify an `X509` certificate chain. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] pub struct X509VerifyFlags: c_ulong { const CB_ISSUER_CHECK = ffi::X509_V_FLAG_CB_ISSUER_CHECK; const USE_CHECK_TIME = ffi::X509_V_FLAG_USE_CHECK_TIME; @@ -87,14 +91,20 @@ impl X509VerifyParamRef { #[corresponds(X509_VERIFY_PARAM_set_hostflags)] pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { unsafe { - ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); + ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits()); } } /// Set verification flags. #[corresponds(X509_VERIFY_PARAM_set_flags)] pub fn set_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> { - unsafe { cvt(ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits)).map(|_| ()) } + unsafe { + cvt(ffi::X509_VERIFY_PARAM_set_flags( + self.as_ptr(), + flags.bits(), + )) + .map(|_| ()) + } } /// Clear verification flags. @@ -103,7 +113,7 @@ impl X509VerifyParamRef { unsafe { cvt(ffi::X509_VERIFY_PARAM_clear_flags( self.as_ptr(), - flags.bits, + flags.bits(), )) .map(|_| ()) } @@ -113,7 +123,7 @@ impl X509VerifyParamRef { #[corresponds(X509_VERIFY_PARAM_get_flags)] pub fn flags(&mut self) -> X509VerifyFlags { let bits = unsafe { ffi::X509_VERIFY_PARAM_get_flags(self.as_ptr()) }; - X509VerifyFlags { bits } + X509VerifyFlags::from_bits_retain(bits) } /// Set the expected DNS hostname. @@ -131,6 +141,21 @@ impl X509VerifyParamRef { } } + /// Set the expected email address. + #[corresponds(X509_VERIFY_PARAM_set1_email)] + pub fn set_email(&mut self, email: &str) -> Result<(), ErrorStack> { + unsafe { + // len == 0 means "run strlen" :( + let raw_email = if email.is_empty() { "\0" } else { email }; + cvt(ffi::X509_VERIFY_PARAM_set1_email( + self.as_ptr(), + raw_email.as_ptr() as *const _, + email.len(), + )) + .map(|_| ()) + } + } + /// Set the expected IPv4 or IPv6 address. #[corresponds(X509_VERIFY_PARAM_set1_ip)] pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> { |