From 0106165088d13635cd2ead04b1d20375546e376a Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Thu, 10 Nov 2022 10:33:31 +0100 Subject: [PATCH 01/38] Expose `num` parameter of the cipher --- openssl-sys/src/evp.rs | 5 +++++ openssl-sys/src/handwritten/evp.rs | 3 +++ openssl/src/cipher_ctx.rs | 16 ++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/openssl-sys/src/evp.rs b/openssl-sys/src/evp.rs index 1e1a4dd93d..fc3003f7bd 100644 --- a/openssl-sys/src/evp.rs +++ b/openssl-sys/src/evp.rs @@ -97,6 +97,11 @@ cfg_if! { pub unsafe fn EVP_CIPHER_CTX_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int { EVP_CIPHER_CTX_get_iv_length(ctx) } + + #[inline] + pub unsafe fn EVP_CIPHER_CTX_num(ctx: *const EVP_CIPHER_CTX) -> c_int { + EVP_CIPHER_CTX_get_num(ctx) + } } else { pub unsafe fn EVP_MD_CTX_size(ctx: *const EVP_MD_CTX) -> c_int { EVP_MD_size(EVP_MD_CTX_md(ctx)) diff --git a/openssl-sys/src/handwritten/evp.rs b/openssl-sys/src/handwritten/evp.rs index ffb0a0819d..a85d628ade 100644 --- a/openssl-sys/src/handwritten/evp.rs +++ b/openssl-sys/src/handwritten/evp.rs @@ -26,6 +26,7 @@ cfg_if! { pub fn EVP_CIPHER_CTX_get_key_length(ctx: *const EVP_CIPHER_CTX) -> c_int; pub fn EVP_CIPHER_CTX_get_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int; pub fn EVP_CIPHER_CTX_get_tag_length(ctx: *const EVP_CIPHER_CTX) -> c_int; + pub fn EVP_CIPHER_CTX_get_num(ctx: *const EVP_CIPHER_CTX) -> c_int; } } else { extern "C" { @@ -44,6 +45,8 @@ cfg_if! { pub fn EVP_CIPHER_CTX_block_size(ctx: *const EVP_CIPHER_CTX) -> c_int; pub fn EVP_CIPHER_CTX_key_length(ctx: *const EVP_CIPHER_CTX) -> c_int; pub fn EVP_CIPHER_CTX_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int; + #[cfg(ossl110)] + pub fn EVP_CIPHER_CTX_num(ctx: *const EVP_CIPHER_CTX) -> c_int; } } } diff --git a/openssl/src/cipher_ctx.rs b/openssl/src/cipher_ctx.rs index 8e017115b1..a4d1c461c5 100644 --- a/openssl/src/cipher_ctx.rs +++ b/openssl/src/cipher_ctx.rs @@ -363,6 +363,22 @@ impl CipherCtxRef { unsafe { ffi::EVP_CIPHER_CTX_iv_length(self.as_ptr()) as usize } } + /// Returns the `num` parameter of the cipher. + /// + /// Built-in ciphers typically use this to track how much of the + /// current underlying block has been "used" already. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + #[corresponds(EVP_CIPHER_CTX_num)] + #[cfg(ossl110)] + pub fn num(&self) -> usize { + self.assert_cipher(); + + unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize } + } + /// Sets the length of the IV expected by this context. /// /// Only some ciphers support configurable IV lengths. From 5ecff30dfecf35777e1ff7e7307e3d3a2414955e Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Mon, 14 Nov 2022 10:43:11 +0100 Subject: [PATCH 02/38] Make `CipherCtx::cipher_update` more flexible This change relaxes constraints on the output buffer size when it can be safely determined how many bytes will be put in the output buffer. For supported cryptographic backends (OpenSSL >= 1.1) the cipher's `num` parameter will be consulted for the number of bytes in the block cache. For unsupported backends the behavior will not change (the code will assume full block in the cache). For callers that do the check themselves and want to use other backends (e.g. BoringSSL or LibreSSL) and unsafe `cipher_update_unchecked` function is added. Additionally a `CipherCtx::minimal_output_size` function is added for letting the callers know how big should the output buffer be for the next `cipher_update` call. Fixes #1729. See: https://mta.openssl.org/pipermail/openssl-users/2022-November/015623.html --- openssl/src/cipher_ctx.rs | 304 +++++++++++++++++++++++++++++++++++--- 1 file changed, 286 insertions(+), 18 deletions(-) diff --git a/openssl/src/cipher_ctx.rs b/openssl/src/cipher_ctx.rs index a4d1c461c5..c0377d969b 100644 --- a/openssl/src/cipher_ctx.rs +++ b/openssl/src/cipher_ctx.rs @@ -379,6 +379,49 @@ impl CipherCtxRef { unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize } } + /// Returns number of bytes cached in partial block update. + #[cfg(ossl110)] + fn used_block_size(&self) -> usize { + self.num() + } + + /// Returns maximum number of bytes that could be cached. + #[cfg(not(ossl110))] + fn used_block_size(&self) -> usize { + self.block_size() + } + + /// Calculate the minimal size of the output buffer given the + /// input buffer size. + /// + /// For streaming ciphers the minimal output size is the same as + /// the input size. For block ciphers the minimal output size + /// additionally depends on the partial blocks that might have + /// been written in previous calls to [`Self::cipher_update`]. + /// + /// This function takes into account the number of partially + /// written blocks for block ciphers for supported targets + /// (OpenSSL >= 1.1). For unsupported targets the number of + /// partially written bytes is assumed to contain one full block + /// (pessimistic case). + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + pub fn minimal_output_size(&self, inlen: usize) -> usize { + let block_size = self.block_size(); + if block_size > 1 { + // block cipher + let num = self.used_block_size(); + let total_size = inlen + num; + let num_blocks = total_size / block_size; + num_blocks * block_size + } else { + // streaming cipher + inlen + } + } + /// Sets the length of the IV expected by this context. /// /// Only some ciphers support configurable IV lengths. @@ -517,33 +560,61 @@ impl CipherCtxRef { /// /// # Panics /// - /// Panics if `output.len()` is less than `input.len()` plus the cipher's block size. + /// Panics if `output` doesn't contain enough space for data to be + /// written as specified by [`Self::minimal_output_size`]. #[corresponds(EVP_CipherUpdate)] pub fn cipher_update( &mut self, input: &[u8], output: Option<&mut [u8]>, ) -> Result { - let inlen = c_int::try_from(input.len()).unwrap(); - if let Some(output) = &output { - let mut block_size = self.block_size(); - if block_size == 1 { - block_size = 0; - } - assert!(output.len() >= input.len() + block_size); + let min_output_size = self.minimal_output_size(input.len()); + assert!( + output.len() >= min_output_size, + "Output buffer size should be at least {} bytes.", + min_output_size + ); } + unsafe { self.cipher_update_unchecked(input, output) } + } + + /// Writes data into the context. + /// + /// Providing no output buffer will cause the input to be considered additional authenticated data (AAD). + /// + /// Returns the number of bytes written to `output`. + /// + /// This function is the same as [`Self::cipher_update`] but with the + /// output size check removed. It can be used when the exact + /// buffer size control is maintained by the caller and the + /// underlying cryptographic library doesn't expose exact block + /// cache data (e.g. OpenSSL < 1.1, BoringSSL, LibreSSL). + /// + /// SAFETY: The caller is expected to provide `output` buffer + /// large enough to contain correct number of bytes. For streaming + /// ciphers the output buffer size should be at least as big as + /// the input buffer. For block ciphers the size of the output + /// buffer depends on the state of partially updated blocks (see + /// [`Self::minimal_output_size`]). + #[corresponds(EVP_CipherUpdate)] + pub unsafe fn cipher_update_unchecked( + &mut self, + input: &[u8], + output: Option<&mut [u8]>, + ) -> Result { + let inlen = c_int::try_from(input.len()).unwrap(); + let mut outlen = 0; - unsafe { - cvt(ffi::EVP_CipherUpdate( - self.as_ptr(), - output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), - &mut outlen, - input.as_ptr(), - inlen, - ))?; - } + + cvt(ffi::EVP_CipherUpdate( + self.as_ptr(), + output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut outlen, + input.as_ptr(), + inlen, + ))?; Ok(outlen as usize) } @@ -604,7 +675,7 @@ impl CipherCtxRef { #[cfg(test)] mod test { use super::*; - use crate::cipher::Cipher; + use crate::{cipher::Cipher, rand::rand_bytes}; #[cfg(not(boringssl))] use std::slice; @@ -685,4 +756,201 @@ mod test { let cipher = Cipher::aes_128_cbc(); aes_128_cbc(cipher); } + + #[test] + #[cfg(ossl110)] + fn partial_block_updates() { + test_block_cipher_for_partial_block_updates(Cipher::aes_128_cbc()); + test_block_cipher_for_partial_block_updates(Cipher::aes_256_cbc()); + test_block_cipher_for_partial_block_updates(Cipher::des_ede3_cbc()); + } + + #[cfg(ossl110)] + fn test_block_cipher_for_partial_block_updates(cipher: &'static CipherRef) { + let mut key = vec![0; cipher.key_length()]; + rand_bytes(&mut key).unwrap(); + let mut iv = vec![0; cipher.iv_length()]; + rand_bytes(&mut iv).unwrap(); + + let mut ctx = CipherCtx::new().unwrap(); + + ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + let block_size = cipher.block_size(); + assert!(block_size > 1, "Need a block cipher, not a stream cipher"); + + // update cipher with non-full block + // expect no output until a block is complete + let outlen = ctx + .cipher_update(&vec![0; block_size - 1], Some(&mut [0; 0])) + .unwrap(); + assert_eq!(0, outlen); + + // update cipher with missing bytes from the previous block + // and one additional block, output should contain two blocks + let mut two_blocks = vec![0; block_size * 2]; + let outlen = ctx + .cipher_update(&vec![0; block_size + 1], Some(&mut two_blocks)) + .unwrap(); + assert_eq!(block_size * 2, outlen); + + ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); + + // try to decrypt + ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + // update cipher with non-full block + // expect no output until a block is complete + let outlen = ctx + .cipher_update(&two_blocks[0..block_size - 1], Some(&mut [0; 0])) + .unwrap(); + assert_eq!(0, outlen); + + // update cipher with missing bytes from the previous block + // and one additional block, output should contain two blocks + let mut two_blocks_decrypted = vec![0; block_size * 2]; + let outlen = ctx + .cipher_update( + &two_blocks[block_size - 1..], + Some(&mut two_blocks_decrypted), + ) + .unwrap(); + assert_eq!(block_size * 2, outlen); + + ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); + // check if the decrypted blocks are the same as input (all zeros) + assert_eq!(two_blocks_decrypted, vec![0; block_size * 2]); + } + + #[test] + fn test_stream_ciphers() { + test_stream_cipher(Cipher::aes_192_ctr()); + test_stream_cipher(Cipher::aes_256_ctr()); + } + + fn test_stream_cipher(cipher: &'static CipherRef) { + let mut key = vec![0; cipher.key_length()]; + rand_bytes(&mut key).unwrap(); + let mut iv = vec![0; cipher.iv_length()]; + rand_bytes(&mut iv).unwrap(); + + let mut ctx = CipherCtx::new().unwrap(); + + ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + assert_eq!( + 1, + cipher.block_size(), + "Need a stream cipher, not a block cipher" + ); + + // update cipher with non-full block + // this is a streaming cipher so the number of output bytes + // will be the same as the number of input bytes + let mut output = vec![0; 32]; + let outlen = ctx + .cipher_update(&[1; 15], Some(&mut output[0..15])) + .unwrap(); + assert_eq!(15, outlen); + + // update cipher with missing bytes from the previous block + // as previously it will output the same number of bytes as + // the input + let outlen = ctx + .cipher_update(&[1; 17], Some(&mut output[15..])) + .unwrap(); + assert_eq!(17, outlen); + + ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); + + // try to decrypt + ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + // update cipher with non-full block + // expect that the output for stream cipher will contain + // the same number of bytes as the input + let mut output_decrypted = vec![0; 32]; + let outlen = ctx + .cipher_update(&output[0..15], Some(&mut output_decrypted[0..15])) + .unwrap(); + assert_eq!(15, outlen); + + let outlen = ctx + .cipher_update(&output[15..], Some(&mut output_decrypted[15..])) + .unwrap(); + assert_eq!(17, outlen); + + ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); + // check if the decrypted blocks are the same as input (all ones) + assert_eq!(output_decrypted, vec![1; 32]); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 16 bytes.")] + #[cfg(ossl110)] + fn full_block_updates_aes_128() { + output_buffer_too_small(Cipher::aes_128_cbc()); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 16 bytes.")] + #[cfg(ossl110)] + fn full_block_updates_aes_256() { + output_buffer_too_small(Cipher::aes_256_cbc()); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 8 bytes.")] + #[cfg(ossl110)] + fn full_block_updates_3des() { + output_buffer_too_small(Cipher::des_ede3_cbc()); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 32 bytes.")] + #[cfg(not(ossl110))] + fn full_block_updates_aes_128() { + output_buffer_too_small(Cipher::aes_128_cbc()); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 32 bytes.")] + #[cfg(not(ossl110))] + fn full_block_updates_aes_256() { + output_buffer_too_small(Cipher::aes_256_cbc()); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 16 bytes.")] + #[cfg(not(ossl110))] + fn full_block_updates_3des() { + output_buffer_too_small(Cipher::des_ede3_cbc()); + } + + fn output_buffer_too_small(cipher: &'static CipherRef) { + let mut key = vec![0; cipher.key_length()]; + rand_bytes(&mut key).unwrap(); + let mut iv = vec![0; cipher.iv_length()]; + rand_bytes(&mut iv).unwrap(); + + let mut ctx = CipherCtx::new().unwrap(); + + ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + let block_size = cipher.block_size(); + assert!(block_size > 1, "Need a block cipher, not a stream cipher"); + + ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1])) + .unwrap(); + } } From 91dfef563fd7518278a5da0fff113b78692cb8a4 Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Thu, 24 Nov 2022 13:21:33 +0100 Subject: [PATCH 03/38] Add module descriptions --- openssl/src/dh.rs | 2 ++ openssl/src/md.rs | 2 ++ openssl/src/version.rs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/openssl/src/dh.rs b/openssl/src/dh.rs index af9912a412..12170b994e 100644 --- a/openssl/src/dh.rs +++ b/openssl/src/dh.rs @@ -1,3 +1,5 @@ +//! Diffie-Hellman key agreement. + use cfg_if::cfg_if; use foreign_types::{ForeignType, ForeignTypeRef}; use std::mem; diff --git a/openssl/src/md.rs b/openssl/src/md.rs index b9297e29a7..4ade8e870d 100644 --- a/openssl/src/md.rs +++ b/openssl/src/md.rs @@ -1,3 +1,5 @@ +//! Message digest algorithms. + #[cfg(ossl300)] use crate::cvt_p; #[cfg(ossl300)] diff --git a/openssl/src/version.rs b/openssl/src/version.rs index da9d24e9fc..f1a324c12c 100644 --- a/openssl/src/version.rs +++ b/openssl/src/version.rs @@ -11,6 +11,8 @@ // limitations under the License. // +//! Build and version information. + use cfg_if::cfg_if; use openssl_macros::corresponds; use std::ffi::CStr; From b42a2b771428d9d99508605ef91639dfe45bb087 Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Thu, 1 Dec 2022 10:09:38 +0100 Subject: [PATCH 04/38] Add documentation to `openssl::sign::Verifier` --- openssl/src/sign.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index 457ff1228d..b675825e2c 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -403,6 +403,8 @@ impl<'a> Write for Signer<'a> { } } +/// A type which can be used to verify the integrity and authenticity +/// of data given the signature. pub struct Verifier<'a> { md_ctx: *mut ffi::EVP_MD_CTX, pctx: *mut ffi::EVP_PKEY_CTX, @@ -426,7 +428,7 @@ impl<'a> Verifier<'a> { /// Creates a new `Verifier`. /// /// This cannot be used with Ed25519 or Ed448 keys. Please refer to - /// `new_without_digest`. + /// [`Verifier::new_without_digest`]. /// /// OpenSSL documentation at [`EVP_DigestVerifyInit`]. /// @@ -553,7 +555,7 @@ impl<'a> Verifier<'a> { /// Feeds more data into the `Verifier`. /// /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. - /// Use `verify_oneshot` instead. + /// Use [`Verifier::verify_oneshot`] instead. /// /// OpenSSL documentation at [`EVP_DigestUpdate`]. /// From a6af54eee171b66633aee339d751a27c99e44436 Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Thu, 1 Dec 2022 10:10:06 +0100 Subject: [PATCH 05/38] Move `openssl::hash` documentation to respective functions --- openssl/src/hash.rs | 103 +++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/openssl/src/hash.rs b/openssl/src/hash.rs index fd83869c9a..8e27505a02 100644 --- a/openssl/src/hash.rs +++ b/openssl/src/hash.rs @@ -1,3 +1,35 @@ +//! Message digest (hash) computation support. +//! +//! # Examples +//! +//! Calculate a hash in one go: +//! +//! ``` +//! # fn main() -> Result<(), Box> { +//! use openssl::hash::{hash, MessageDigest}; +//! +//! let data = b"\x42\xF4\x97\xE0"; +//! let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; +//! let res = hash(MessageDigest::md5(), data)?; +//! assert_eq!(&*res, spec); +//! # Ok(()) } +//! ``` +//! +//! Supply the input in chunks: +//! +//! ``` +//! use openssl::hash::{Hasher, MessageDigest}; +//! +//! # fn main() -> Result<(), Box> { +//! let mut hasher = Hasher::new(MessageDigest::sha256())?; +//! hasher.update(b"test")?; +//! hasher.update(b"this")?; +//! let digest: &[u8] = &hasher.finish()?; +//! +//! let expected = hex::decode("9740e652ab5b4acd997a7cca13d6696702ccb2d441cca59fc6e285127f28cfe6")?; +//! assert_eq!(digest, expected); +//! # Ok(()) } +//! ``` use cfg_if::cfg_if; use std::ffi::CString; use std::fmt; @@ -18,6 +50,7 @@ cfg_if! { } } +/// A message digest algorithm. #[derive(Copy, Clone, PartialEq, Eq)] pub struct MessageDigest(*const ffi::EVP_MD); @@ -174,44 +207,18 @@ use self::State::*; /// /// # Examples /// -/// Calculate a hash in one go: -/// -/// ``` -/// use openssl::hash::{hash, MessageDigest}; -/// -/// let data = b"\x42\xF4\x97\xE0"; -/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; -/// let res = hash(MessageDigest::md5(), data).unwrap(); -/// assert_eq!(&*res, spec); -/// ``` -/// -/// Supply the input in chunks: -/// /// ``` /// use openssl::hash::{Hasher, MessageDigest}; /// +/// # fn main() -> Result<(), Box> { /// let data = [b"\x42\xF4", b"\x97\xE0"]; /// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; -/// let mut h = Hasher::new(MessageDigest::md5()).unwrap(); -/// h.update(data[0]).unwrap(); -/// h.update(data[1]).unwrap(); -/// let res = h.finish().unwrap(); +/// let mut h = Hasher::new(MessageDigest::md5())?; +/// h.update(data[0])?; +/// h.update(data[1])?; +/// let res = h.finish()?; /// assert_eq!(&*res, spec); -/// ``` -/// -/// Use an XOF hasher (OpenSSL 1.1.1+): -/// -/// ``` -/// #[cfg(ossl111)] -/// { -/// use openssl::hash::{hash_xof, MessageDigest}; -/// -/// let data = b"\x41\x6c\x6c\x20\x79\x6f\x75\x72\x20\x62\x61\x73\x65\x20\x61\x72\x65\x20\x62\x65\x6c\x6f\x6e\x67\x20\x74\x6f\x20\x75\x73"; -/// let spec = b"\x49\xd0\x69\x7f\xf5\x08\x11\x1d\x8b\x84\xf1\x5e\x46\xda\xf1\x35"; -/// let mut buf = vec![0; 16]; -/// hash_xof(MessageDigest::shake_128(), data, buf.as_mut_slice()).unwrap(); -/// assert_eq!(buf, spec); -/// } +/// # Ok(()) } /// ``` /// /// # Warning @@ -220,8 +227,10 @@ use self::State::*; /// /// Don't ever hash passwords, use the functions in the `pkcs5` module or bcrypt/scrypt instead. /// -/// For extendable output functions (XOFs, i.e. SHAKE128/SHAKE256), you must use finish_xof instead -/// of finish and provide a buf to store the hash. The hash will be as long as the buf. +/// For extendable output functions (XOFs, i.e. SHAKE128/SHAKE256), +/// you must use [`Hasher::finish_xof`] instead of [`Hasher::finish`] +/// and provide a `buf` to store the hash. The hash will be as long as +/// the `buf`. pub struct Hasher { ctx: *mut ffi::EVP_MD_CTX, md: *const ffi::EVP_MD, @@ -411,6 +420,19 @@ impl fmt::Debug for DigestBytes { } /// Computes the hash of the `data` with the non-XOF hasher `t`. +/// +/// # Examples +/// +/// ``` +/// # fn main() -> Result<(), Box> { +/// use openssl::hash::{hash, MessageDigest}; +/// +/// let data = b"\x42\xF4\x97\xE0"; +/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; +/// let res = hash(MessageDigest::md5(), data)?; +/// assert_eq!(&*res, spec); +/// # Ok(()) } +/// ``` pub fn hash(t: MessageDigest, data: &[u8]) -> Result { let mut h = Hasher::new(t)?; h.update(data)?; @@ -418,6 +440,19 @@ pub fn hash(t: MessageDigest, data: &[u8]) -> Result { } /// Computes the hash of the `data` with the XOF hasher `t` and stores it in `buf`. +/// +/// # Examples +/// +/// ``` +/// use openssl::hash::{hash_xof, MessageDigest}; +/// +/// let data = b"\x41\x6c\x6c\x20\x79\x6f\x75\x72\x20\x62\x61\x73\x65\x20\x61\x72\x65\x20\x62\x65\x6c\x6f\x6e\x67\x20\x74\x6f\x20\x75\x73"; +/// let spec = b"\x49\xd0\x69\x7f\xf5\x08\x11\x1d\x8b\x84\xf1\x5e\x46\xda\xf1\x35"; +/// let mut buf = vec![0; 16]; +/// hash_xof(MessageDigest::shake_128(), data, buf.as_mut_slice()).unwrap(); +/// assert_eq!(buf, spec); +/// ``` +/// #[cfg(ossl111)] pub fn hash_xof(t: MessageDigest, data: &[u8], buf: &mut [u8]) -> Result<(), ErrorStack> { let mut h = Hasher::new(t)?; From 9b851cdf76db340da49e6bfb4c40abb953272bff Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Thu, 1 Dec 2022 10:10:27 +0100 Subject: [PATCH 06/38] Add documentation to several `openssl::ec` items --- openssl/src/ec.rs | 64 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/openssl/src/ec.rs b/openssl/src/ec.rs index a6a6dc975a..24b3832224 100644 --- a/openssl/src/ec.rs +++ b/openssl/src/ec.rs @@ -116,6 +116,19 @@ foreign_type_and_impl_send_sync! { impl EcGroup { /// Returns the group of a standard named curve. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::nid::Nid; + /// use openssl::ec::{EcGroup, EcKey}; + /// + /// let nid = Nid::X9_62_PRIME256V1; // NIST P-256 curve + /// let group = EcGroup::from_curve_name(nid)?; + /// let key = EcKey::generate(&group)?; + /// # Ok(()) } + /// ``` #[corresponds(EC_GROUP_new_by_curve_name)] pub fn from_curve_name(nid: Nid) -> Result { unsafe { @@ -748,26 +761,32 @@ impl EcKey { } impl EcKey { - /// Constructs an `EcKey` from the specified group with the associated `EcPoint`, public_key. + /// Constructs an `EcKey` from the specified group with the associated [`EcPoint`]: `public_key`. /// - /// This will only have the associated public_key. + /// This will only have the associated `public_key`. /// /// # Example /// - /// ```no_run + /// ``` + /// # fn main() -> Result<(), Box> { /// use openssl::bn::BigNumContext; /// use openssl::ec::*; /// use openssl::nid::Nid; /// use openssl::pkey::PKey; /// - /// // get bytes from somewhere, i.e. this will not produce a valid key - /// let public_key: Vec = vec![]; + /// let group = EcGroup::from_curve_name(Nid::SECP384R1)?; + /// let mut ctx = BigNumContext::new()?; + /// + /// // get bytes from somewhere + /// let public_key = // ... + /// # EcKey::generate(&group)?.public_key().to_bytes(&group, + /// # PointConversionForm::COMPRESSED, &mut ctx)?; /// /// // create an EcKey from the binary form of a EcPoint - /// let group = EcGroup::from_curve_name(Nid::SECP256K1).unwrap(); - /// let mut ctx = BigNumContext::new().unwrap(); - /// let point = EcPoint::from_bytes(&group, &public_key, &mut ctx).unwrap(); - /// let key = EcKey::from_public_key(&group, &point); + /// let point = EcPoint::from_bytes(&group, &public_key, &mut ctx)?; + /// let key = EcKey::from_public_key(&group, &point)?; + /// key.check_key()?; + /// # Ok(()) } /// ``` #[corresponds(EC_KEY_set_public_key)] pub fn from_public_key( @@ -835,6 +854,33 @@ impl EcKey { impl EcKey { /// Generates a new public/private key pair on the specified curve. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::bn::BigNumContext; + /// use openssl::nid::Nid; + /// use openssl::ec::{EcGroup, EcKey, PointConversionForm}; + /// + /// let nid = Nid::X9_62_PRIME256V1; // NIST P-256 curve + /// let group = EcGroup::from_curve_name(nid)?; + /// let key = EcKey::generate(&group)?; + /// + /// let mut ctx = BigNumContext::new()?; + /// + /// let public_key = &key.public_key().to_bytes( + /// &group, + /// PointConversionForm::COMPRESSED, + /// &mut ctx, + /// )?; + /// assert_eq!(public_key.len(), 33); + /// assert_ne!(public_key[0], 0x04); + /// + /// let private_key = key.private_key().to_vec(); + /// assert!(private_key.len() >= 31); + /// # Ok(()) } + /// ``` #[corresponds(EC_KEY_generate_key)] pub fn generate(group: &EcGroupRef) -> Result, ErrorStack> { unsafe { From d390c414ec9039207986bf44ce4b89e00ab4a0ed Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Thu, 1 Dec 2022 10:10:50 +0100 Subject: [PATCH 07/38] Add more elaborate ECDH example to `openssl::derive` --- openssl/src/derive.rs | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/openssl/src/derive.rs b/openssl/src/derive.rs index 1e252d9efc..87a04a14a3 100644 --- a/openssl/src/derive.rs +++ b/openssl/src/derive.rs @@ -1,4 +1,54 @@ //! Shared secret derivation. +//! +//! # Example +//! +//! The following example implements [ECDH] using `NIST P-384` keys: +//! +//! ``` +//! # fn main() -> Result<(), Box> { +//! # use std::convert::TryInto; +//! use openssl::bn::BigNumContext; +//! use openssl::pkey::PKey; +//! use openssl::derive::Deriver; +//! use openssl::ec::{EcGroup, EcKey, EcPoint, PointConversionForm}; +//! use openssl::nid::Nid; +//! +//! let group = EcGroup::from_curve_name(Nid::SECP384R1)?; +//! +//! let first: PKey<_> = EcKey::generate(&group)?.try_into()?; +//! +//! // second party generates an ephemeral key and derives +//! // a shared secret using first party's public key +//! let shared_key = EcKey::generate(&group)?; +//! // shared_public is sent to first party +//! let mut ctx = BigNumContext::new()?; +//! let shared_public = shared_key.public_key().to_bytes( +//! &group, +//! PointConversionForm::COMPRESSED, +//! &mut ctx, +//! )?; +//! +//! let shared_key: PKey<_> = shared_key.try_into()?; +//! let mut deriver = Deriver::new(&shared_key)?; +//! deriver.set_peer(&first)?; +//! // secret can be used e.g. as a symmetric encryption key +//! let secret = deriver.derive_to_vec()?; +//! # drop(deriver); +//! +//! // first party derives the same shared secret using +//! // shared_public +//! let point = EcPoint::from_bytes(&group, &shared_public, &mut ctx)?; +//! let recipient_key: PKey<_> = EcKey::from_public_key(&group, &point)?.try_into()?; +//! let mut deriver = Deriver::new(&first)?; +//! deriver.set_peer(&recipient_key)?; +//! let first_secret = deriver.derive_to_vec()?; +//! +//! assert_eq!(secret, first_secret); +//! # Ok(()) } +//! ``` +//! +//! [ECDH]: https://wiki.openssl.org/index.php/Elliptic_Curve_Diffie_Hellman + use foreign_types::ForeignTypeRef; use std::marker::PhantomData; use std::ptr; From 6df9f1374a97bcd5138ea2d9a84e169d9b0b74aa Mon Sep 17 00:00:00 2001 From: iamwwc Date: Fri, 2 Dec 2022 11:04:10 +0800 Subject: [PATCH 08/38] sync to rust-openssl --- openssl-sys/src/ssl.rs | 6 ++++++ openssl/src/ssl/mod.rs | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/openssl-sys/src/ssl.rs b/openssl-sys/src/ssl.rs index 12243dc4fc..d3f09738c6 100644 --- a/openssl-sys/src/ssl.rs +++ b/openssl-sys/src/ssl.rs @@ -339,6 +339,8 @@ pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 71; #[cfg(any(libressl, all(ossl101, not(ossl110))))] pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77; pub const SSL_CTRL_GET_EXTRA_CHAIN_CERTS: c_int = 82; +#[cfg(ossl102)] +pub const SSL_CTRL_CHAIN_CERT: c_int = 89; #[cfg(any(ossl111, libressl252))] pub const SSL_CTRL_SET_GROUPS_LIST: c_int = 92; #[cfg(any(libressl, all(ossl102, not(ossl110))))] @@ -406,6 +408,10 @@ cfg_if! { } } } +#[cfg(ossl102)] +pub unsafe fn SSL_add_chain_certificate_pem(ssl: *mut ::SSL, ptr: *mut c_void) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_CHAIN_CERT, 1, ptr) +} #[cfg(ossl102)] pub unsafe fn SSL_CTX_set1_sigalgs_list(ctx: *mut SSL_CTX, s: *const c_char) -> c_long { diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 4f349a4e4b..ec960fa107 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -3104,6 +3104,19 @@ impl SslRef { } } } + #[corresponds(SSL_add1_chain_cert)] + #[cfg(ossl102)] + pub fn add_chain_certificate_pem(&mut self, chain: &[u8]) -> Result<(), ErrorStack> { + let cert = X509::from_pem(chain)?; + let ret = unsafe { + ffi::SSL_add_chain_certificate_pem(self.as_ptr(), cert.as_ptr() as *mut _ as *mut _) + }; + if ret == 1 { + Ok(()) + }else { + Err(ErrorStack::get()) + } + } } /// An SSL stream midway through the handshake process. From 21bf31dc3a6daf852984ed1fd75c031c3293a810 Mon Sep 17 00:00:00 2001 From: iamwwc Date: Fri, 2 Dec 2022 13:20:28 +0800 Subject: [PATCH 09/38] format code --- openssl/src/ssl/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index ec960fa107..88e550ba8d 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -3113,7 +3113,7 @@ impl SslRef { }; if ret == 1 { Ok(()) - }else { + } else { Err(ErrorStack::get()) } } From 20f6cbee33e6dd062cbc235107fef82b20cf6434 Mon Sep 17 00:00:00 2001 From: iamwwc Date: Fri, 2 Dec 2022 17:17:45 +0800 Subject: [PATCH 10/38] remove duplicate as cast --- openssl/src/ssl/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 88e550ba8d..35da01f37c 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -3109,7 +3109,7 @@ impl SslRef { pub fn add_chain_certificate_pem(&mut self, chain: &[u8]) -> Result<(), ErrorStack> { let cert = X509::from_pem(chain)?; let ret = unsafe { - ffi::SSL_add_chain_certificate_pem(self.as_ptr(), cert.as_ptr() as *mut _ as *mut _) + ffi::SSL_add_chain_certificate_pem(self.as_ptr(), cert.as_ptr() as *mut _ ) }; if ret == 1 { Ok(()) From a43e828460ec6980beba8fae17e858c6c498c3f9 Mon Sep 17 00:00:00 2001 From: iamwwc Date: Fri, 2 Dec 2022 17:43:16 +0800 Subject: [PATCH 11/38] make cargo fmt happy --- openssl/src/ssl/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 35da01f37c..6d192fc594 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -3108,9 +3108,8 @@ impl SslRef { #[cfg(ossl102)] pub fn add_chain_certificate_pem(&mut self, chain: &[u8]) -> Result<(), ErrorStack> { let cert = X509::from_pem(chain)?; - let ret = unsafe { - ffi::SSL_add_chain_certificate_pem(self.as_ptr(), cert.as_ptr() as *mut _ ) - }; + let ret = + unsafe { ffi::SSL_add_chain_certificate_pem(self.as_ptr(), cert.as_ptr() as *mut _) }; if ret == 1 { Ok(()) } else { From 5ae938ee55c949f64329ec95e640f523238219dc Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Fri, 30 Sep 2022 13:25:13 -0500 Subject: [PATCH 12/38] Add support for X509_load_cert_file --- openssl-sys/src/handwritten/x509_vfy.rs | 2 ++ openssl/src/x509/store.rs | 33 +++++++++++++++++++++++++ openssl/src/x509/tests.rs | 24 ++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/openssl-sys/src/handwritten/x509_vfy.rs b/openssl-sys/src/handwritten/x509_vfy.rs index ef2a6aac94..632bb9f689 100644 --- a/openssl-sys/src/handwritten/x509_vfy.rs +++ b/openssl-sys/src/handwritten/x509_vfy.rs @@ -12,6 +12,7 @@ extern "C" { extern "C" { pub fn X509_LOOKUP_free(ctx: *mut X509_LOOKUP); pub fn X509_LOOKUP_hash_dir() -> *mut X509_LOOKUP_METHOD; + pub fn X509_LOOKUP_file() -> *mut X509_LOOKUP_METHOD; pub fn X509_LOOKUP_ctrl( ctx: *mut X509_LOOKUP, cmd: c_int, @@ -19,6 +20,7 @@ extern "C" { argl: c_long, ret: *mut *mut c_char, ) -> c_int; + pub fn X509_load_cert_file(ctx: *mut X509_LOOKUP, file: *const c_char, _type: c_int) -> c_int; } extern "C" { diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs index 120d6369a0..5acbfb5404 100644 --- a/openssl/src/x509/store.rs +++ b/openssl/src/x509/store.rs @@ -56,6 +56,8 @@ use crate::{cvt, cvt_p}; use openssl_macros::corresponds; #[cfg(not(boringssl))] use std::ffi::CString; +#[cfg(not(boringssl))] +use std::path::Path; foreign_type_and_impl_send_sync! { type CType = ffi::X509_STORE; @@ -176,6 +178,37 @@ impl X509LookupRef { } } +/// Marker type corresponding to the [`X509_LOOKUP_file`] lookup method. +/// +/// [`X509_LOOKUP_file`]: https://www.openssl.org/docs/man1.1.1/man3/X509_LOOKUP_file.html +pub struct File; + +impl X509Lookup { + /// Lookup method loads all the certificates or CRLs present in a file + /// into memory at the time the file is added as a lookup source. + #[corresponds(X509_LOOKUP_file)] + pub fn file() -> &'static X509LookupMethodRef { + unsafe { X509LookupMethodRef::from_ptr(ffi::X509_LOOKUP_file()) } + } +} + +#[cfg(not(boringssl))] +impl X509LookupRef { + #[corresponds(X509_load_cert_file)] + /// Specifies a file from which certificates will be loaded + pub fn load_cert_file>(&mut self, file: P, file_type: SslFiletype) -> Result<(), ErrorStack> { + let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); + unsafe { + cvt(ffi::X509_load_cert_file( + self.as_ptr(), + file.as_ptr(), + file_type.as_raw(), + )) + .map(|_| ()) + } + } +} + generic_foreign_type_and_impl_send_sync! { type CType = ffi::X509_LOOKUP_METHOD; fn drop = X509_LOOKUP_meth_free; diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index ace6175017..33d6f4f1e9 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -6,11 +6,15 @@ use crate::hash::MessageDigest; use crate::nid::Nid; use crate::pkey::{PKey, Private}; use crate::rsa::Rsa; +#[cfg(not(boringssl))] +use crate::ssl::SslFiletype; use crate::stack::Stack; use crate::x509::extension::{ AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName, SubjectKeyIdentifier, }; +#[cfg(not(boringssl))] +use crate::x509::store::X509Lookup; use crate::x509::store::X509StoreBuilder; #[cfg(any(ossl102, libressl261))] use crate::x509::verify::{X509VerifyFlags, X509VerifyParam}; @@ -668,3 +672,23 @@ fn test_verify_param_set_depth_fails_verification() { expected_error ) } + +#[test] +#[cfg(not(boringssl))] +fn test_load_cert_file() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + let lookup = store_bldr.add_lookup(X509Lookup::file()).unwrap(); + lookup + .load_cert_file("test/root-ca.pem", SslFiletype::PEM) + .unwrap(); + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); +} From 6643d07213d93186a50f64d28cb8bd955efbe43a Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 3 Dec 2022 15:17:59 -0500 Subject: [PATCH 13/38] rustfmt --- openssl/src/x509/store.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs index 5acbfb5404..a685fa18e6 100644 --- a/openssl/src/x509/store.rs +++ b/openssl/src/x509/store.rs @@ -196,7 +196,11 @@ impl X509Lookup { impl X509LookupRef { #[corresponds(X509_load_cert_file)] /// Specifies a file from which certificates will be loaded - pub fn load_cert_file>(&mut self, file: P, file_type: SslFiletype) -> Result<(), ErrorStack> { + pub fn load_cert_file>( + &mut self, + file: P, + file_type: SslFiletype, + ) -> Result<(), ErrorStack> { let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); unsafe { cvt(ffi::X509_load_cert_file( From 0a44a12a1ed54695138450882f060905051f0ff1 Mon Sep 17 00:00:00 2001 From: iamwwc Date: Sun, 4 Dec 2022 10:27:11 +0800 Subject: [PATCH 14/38] rename function --- openssl-sys/src/ssl.rs | 2 +- openssl/src/ssl/mod.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/openssl-sys/src/ssl.rs b/openssl-sys/src/ssl.rs index d3f09738c6..e38aa367f9 100644 --- a/openssl-sys/src/ssl.rs +++ b/openssl-sys/src/ssl.rs @@ -409,7 +409,7 @@ cfg_if! { } } #[cfg(ossl102)] -pub unsafe fn SSL_add_chain_certificate_pem(ssl: *mut ::SSL, ptr: *mut c_void) -> c_long { +pub unsafe fn SSL_add1_chain_cert(ssl: *mut ::SSL, ptr: *mut c_void) -> c_long { SSL_ctrl(ssl, SSL_CTRL_CHAIN_CERT, 1, ptr) } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 6d192fc594..ddb1894a0f 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -3106,10 +3106,9 @@ impl SslRef { } #[corresponds(SSL_add1_chain_cert)] #[cfg(ossl102)] - pub fn add_chain_certificate_pem(&mut self, chain: &[u8]) -> Result<(), ErrorStack> { + pub fn add_chain_cert_pem(&mut self, chain: &[u8]) -> Result<(), ErrorStack> { let cert = X509::from_pem(chain)?; - let ret = - unsafe { ffi::SSL_add_chain_certificate_pem(self.as_ptr(), cert.as_ptr() as *mut _) }; + let ret = unsafe { ffi::SSL_add1_chain_cert(self.as_ptr(), cert.as_ptr() as *mut _) }; if ret == 1 { Ok(()) } else { From bf02d2d8d3014880a8f9e095de0afaa353084a3f Mon Sep 17 00:00:00 2001 From: iamwwc Date: Mon, 5 Dec 2022 16:13:37 +0800 Subject: [PATCH 15/38] add unit test --- openssl/src/ssl/test/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index ab8d79aab4..e12e4f0854 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -1413,3 +1413,10 @@ fn session_cache_size() { let ctx = ctx.build(); assert_eq!(ctx.session_cache_size(), 1234); } + +#[test] +fn add_chain_cert_pem() { + let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); + let mut ssl = Ssl::new(&ctx).unwrap(); + assert!(ssl.add_chain_cert_pem(CERT).is_ok()); +} \ No newline at end of file From 8c475f7b316a2ba420688764fbf71b470415f60d Mon Sep 17 00:00:00 2001 From: iamwwc Date: Mon, 5 Dec 2022 16:13:51 +0800 Subject: [PATCH 16/38] fmt --- openssl/src/ssl/test/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index e12e4f0854..aa29233ab3 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -1419,4 +1419,4 @@ fn add_chain_cert_pem() { let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); let mut ssl = Ssl::new(&ctx).unwrap(); assert!(ssl.add_chain_cert_pem(CERT).is_ok()); -} \ No newline at end of file +} From 5c2cc87431b5bfc8544e36694887fc5485982e0d Mon Sep 17 00:00:00 2001 From: iamwwc Date: Mon, 5 Dec 2022 16:16:07 +0800 Subject: [PATCH 17/38] reflect macro name --- openssl/src/ssl/mod.rs | 5 ++--- openssl/src/ssl/test/mod.rs | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index ddb1894a0f..460ef63fad 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -3106,9 +3106,8 @@ impl SslRef { } #[corresponds(SSL_add1_chain_cert)] #[cfg(ossl102)] - pub fn add_chain_cert_pem(&mut self, chain: &[u8]) -> Result<(), ErrorStack> { - let cert = X509::from_pem(chain)?; - let ret = unsafe { ffi::SSL_add1_chain_cert(self.as_ptr(), cert.as_ptr() as *mut _) }; + pub fn add_chain_cert_pem(&mut self, chain: X509) -> Result<(), ErrorStack> { + let ret = unsafe { ffi::SSL_add1_chain_cert(self.as_ptr(), chain.as_ptr() as *mut _) }; if ret == 1 { Ok(()) } else { diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index aa29233ab3..39734a2f6a 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -1417,6 +1417,7 @@ fn session_cache_size() { #[test] fn add_chain_cert_pem() { let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); + let cert = X509::from_pem(CERT).unwrap(); let mut ssl = Ssl::new(&ctx).unwrap(); - assert!(ssl.add_chain_cert_pem(CERT).is_ok()); + assert!(ssl.add_chain_cert_pem(cert).is_ok()); } From 24363b3e429e0f2072a14571a6f33e7f76a6887e Mon Sep 17 00:00:00 2001 From: iamwwc Date: Mon, 5 Dec 2022 16:26:17 +0800 Subject: [PATCH 18/38] test cfg. rename --- openssl/src/ssl/mod.rs | 2 +- openssl/src/ssl/test/mod.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 460ef63fad..4016943802 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -3106,7 +3106,7 @@ impl SslRef { } #[corresponds(SSL_add1_chain_cert)] #[cfg(ossl102)] - pub fn add_chain_cert_pem(&mut self, chain: X509) -> Result<(), ErrorStack> { + pub fn add_chain_cert(&mut self, chain: X509) -> Result<(), ErrorStack> { let ret = unsafe { ffi::SSL_add1_chain_cert(self.as_ptr(), chain.as_ptr() as *mut _) }; if ret == 1 { Ok(()) diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index 39734a2f6a..dc9cc78527 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -1415,9 +1415,10 @@ fn session_cache_size() { } #[test] -fn add_chain_cert_pem() { +#[cfg(ossl102)] +fn add_chain_cert() { let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); let cert = X509::from_pem(CERT).unwrap(); let mut ssl = Ssl::new(&ctx).unwrap(); - assert!(ssl.add_chain_cert_pem(cert).is_ok()); + assert!(ssl.add_chain_cert(cert).is_ok()); } From a1b82a2d837ede8f221964c0bbec79f635ea0f23 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 6 Dec 2022 07:37:00 -0500 Subject: [PATCH 19/38] Release openssl-sys v0.9.79 --- openssl-sys/CHANGELOG.md | 11 ++++++++++- openssl-sys/Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index 0c549f6117..ec815325f7 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -2,6 +2,13 @@ ## [Unreleased] +## [v0.9.79] - 2022-12-06 + +### Added + +* Added `EVP_CIPHER_CTX_num`. +* Added `X509_LOOKUP_file` and `X509_load_cert_file`. + ## [v0.9.78] - 2022-11-23 ### Added @@ -350,7 +357,9 @@ * 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.77..master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.79..master +[v0.9.79]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.78...openssl-sys-v0.9.79 +[v0.9.78]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.77...openssl-sys-v0.9.78 [v0.9.77]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.76...openssl-sys-v0.9.77 [v0.9.76]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.75...openssl-sys-v0.9.76 [v0.9.75]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.74...openssl-sys-v0.9.75 diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index ee1a57cd19..de6b33e80b 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl-sys" -version = "0.9.78" +version = "0.9.79" authors = [ "Alex Crichton ", "Steven Fackler ", From e0b937c48ddf9532fcd76c12e4b5d7879762c11d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 6 Dec 2022 07:41:51 -0500 Subject: [PATCH 20/38] Release openssl v0.10.44 --- openssl/CHANGELOG.md | 11 ++++++++++- openssl/Cargo.toml | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index 31564986e0..f66bcb7501 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -2,6 +2,14 @@ ## [Unreleased] +## [v0.10.44] - 2022-12-06 + +### Added + +* Added `CipherCtxRef::num`, `CipherCtxRef::minimal_output_size`, and `CipherCtxRef::cipher_update_unchecked`. +* Improved output buffer size checks in `CipherCtxRef::cipher_update`. +* Added `X509Lookup::file` and `X509LookupRef::load_cert_file`. + ## [v0.10.43] - 2022-11-23 ### Added @@ -641,7 +649,8 @@ Look at the [release tags] for information about older releases. -[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.43...master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.44...master +[v0.10.44]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.44...openssl-v0.10.44 [v0.10.43]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.42...openssl-v0.10.43 [v0.10.42]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.41...openssl-v0.10.42 [v0.10.41]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.40...openssl-v0.10.41 diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index b6204e4490..03f621eddd 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl" -version = "0.10.43" +version = "0.10.44" 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.78", path = "../openssl-sys" } +ffi = { package = "openssl-sys", version = "0.9.79", path = "../openssl-sys" } [dev-dependencies] hex = "0.3" From 230050f00417dd84c558be653b0afbd625ce2da9 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 8 Dec 2022 20:13:41 +0200 Subject: [PATCH 21/38] build: harden ci.yml permissions Signed-off-by: Alex --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9090ca194d..e4aeee0c9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,9 @@ concurrency: group: ${{ github.ref }} cancel-in-progress: true +permissions: + contents: read # to fetch code (actions/checkout) + jobs: rustfmt: name: rustfmt From 5aadcab921fb277a3cc620d822cb7f7d5565d5a8 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 11 Dec 2022 08:11:17 -0500 Subject: [PATCH 22/38] cleanup --- openssl-sys/src/ssl.rs | 5 +++-- openssl/src/ssl/mod.rs | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/openssl-sys/src/ssl.rs b/openssl-sys/src/ssl.rs index e38aa367f9..9e3956bf2c 100644 --- a/openssl-sys/src/ssl.rs +++ b/openssl-sys/src/ssl.rs @@ -408,9 +408,10 @@ cfg_if! { } } } + #[cfg(ossl102)] -pub unsafe fn SSL_add1_chain_cert(ssl: *mut ::SSL, ptr: *mut c_void) -> c_long { - SSL_ctrl(ssl, SSL_CTRL_CHAIN_CERT, 1, ptr) +pub unsafe fn SSL_add0_chain_cert(ssl: *mut ::SSL, ptr: *mut X509) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_CHAIN_CERT, 0, ptr as *mut c_void) } #[cfg(ossl102)] diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 4016943802..89a380e072 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -3104,15 +3104,15 @@ impl SslRef { } } } - #[corresponds(SSL_add1_chain_cert)] + + #[corresponds(SSL_add0_chain_cert)] #[cfg(ossl102)] pub fn add_chain_cert(&mut self, chain: X509) -> Result<(), ErrorStack> { - let ret = unsafe { ffi::SSL_add1_chain_cert(self.as_ptr(), chain.as_ptr() as *mut _) }; - if ret == 1 { - Ok(()) - } else { - Err(ErrorStack::get()) + unsafe { + cvt(ffi::SSL_add0_chain_cert(self.as_ptr(), chain.as_ptr()) as c_int).map(|_| ())?; + mem::forget(chain); } + Ok(()) } } From 3f2563f6eaec658e7288eb972792bd5ffff29011 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Tue, 13 Dec 2022 15:16:09 +0100 Subject: [PATCH 23/38] Add get_security_bits for PKey Signed-off-by: Steffen Eiden --- openssl-sys/src/handwritten/evp.rs | 8 ++++++++ openssl/src/pkey.rs | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/openssl-sys/src/handwritten/evp.rs b/openssl-sys/src/handwritten/evp.rs index a85d628ade..535b2d5f5d 100644 --- a/openssl-sys/src/handwritten/evp.rs +++ b/openssl-sys/src/handwritten/evp.rs @@ -402,6 +402,7 @@ cfg_if! { extern "C" { pub fn EVP_PKEY_get_id(pkey: *const EVP_PKEY) -> c_int; pub fn EVP_PKEY_get_bits(key: *const EVP_PKEY) -> c_int; + pub fn EVP_PKEY_get_security_bits(key: *const EVP_PKEY) -> c_int; } #[inline] @@ -413,6 +414,12 @@ cfg_if! { pub unsafe fn EVP_PKEY_bits(pkey: *const EVP_PKEY) -> c_int { EVP_PKEY_get_bits(pkey) } + + #[inline] + pub unsafe fn EVP_PKEY_security_bits(pkey: *const EVP_PKEY) -> c_int { + EVP_PKEY_get_security_bits(pkey) + } + } else { extern "C" { pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int; @@ -420,6 +427,7 @@ cfg_if! { const_ptr_api! { extern "C" { pub fn EVP_PKEY_bits(key: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int; + pub fn EVP_PKEY_security_bits(pkey: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int; } } } diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 7d438ebadc..ef26c68aaa 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -229,6 +229,14 @@ where unsafe { ffi::EVP_PKEY_bits(self.as_ptr()) as u32 } } + ///Returns the number of security bits. + /// + ///Bits of security is defined in NIST SP800-57. + #[corresponds(EVP_PKEY_security_bits)] + pub fn security_bits(&self) -> u32 { + unsafe { ffi::EVP_PKEY_security_bits(self.as_ptr()) as u32 } + } + /// Compares the public component of this key with another. #[corresponds(EVP_PKEY_cmp)] pub fn public_eq(&self, other: &PKeyRef) -> bool @@ -1018,6 +1026,15 @@ mod tests { assert_eq!(ec_key.private_key(), ec_key_.private_key()); } + #[test] + fn test_security_bits() { + let group = crate::ec::EcGroup::from_curve_name(crate::nid::Nid::SECP521R1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let pkey: PKey = ec_key.clone().try_into().unwrap(); + + assert_eq!(pkey.security_bits(), 256); + } + #[test] #[cfg(not(boringssl))] fn test_dh_conversion() { From 632ed2bee9f78a5e7423e9251829d6f87f5bccec Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Thu, 15 Dec 2022 13:35:50 +0100 Subject: [PATCH 24/38] fixup! Add get_security_bits for PKey --- openssl-sys/src/evp.rs | 5 +++++ openssl/src/pkey.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/openssl-sys/src/evp.rs b/openssl-sys/src/evp.rs index fc3003f7bd..9db924ea53 100644 --- a/openssl-sys/src/evp.rs +++ b/openssl-sys/src/evp.rs @@ -143,6 +143,11 @@ cfg_if! { pub unsafe fn EVP_PKEY_bits(pkey: *const EVP_PKEY) -> c_int { EVP_PKEY_get_bits(pkey) } + + #[inline] + pub unsafe fn EVP_PKEY_security_bits(pkey: *const EVP_PKEY) -> c_int { + EVP_PKEY_get_security_bits(pkey) + } } } diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index ef26c68aaa..62cc71bdad 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -1030,7 +1030,7 @@ mod tests { fn test_security_bits() { let group = crate::ec::EcGroup::from_curve_name(crate::nid::Nid::SECP521R1).unwrap(); let ec_key = EcKey::generate(&group).unwrap(); - let pkey: PKey = ec_key.clone().try_into().unwrap(); + let pkey: PKey = ec_key.try_into().unwrap(); assert_eq!(pkey.security_bits(), 256); } From 4ad1ee6c57055da60201a10fc61b9e229eb8de55 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Thu, 15 Dec 2022 15:57:22 +0100 Subject: [PATCH 25/38] fixup! EVP_PKEY_security_bits --- openssl-sys/src/handwritten/evp.rs | 1 + openssl/src/pkey.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/openssl-sys/src/handwritten/evp.rs b/openssl-sys/src/handwritten/evp.rs index 535b2d5f5d..8bc9675ecd 100644 --- a/openssl-sys/src/handwritten/evp.rs +++ b/openssl-sys/src/handwritten/evp.rs @@ -427,6 +427,7 @@ cfg_if! { const_ptr_api! { extern "C" { pub fn EVP_PKEY_bits(key: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int; + #[cfg(ossl110)] pub fn EVP_PKEY_security_bits(pkey: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int; } } diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 62cc71bdad..dd2af2f36f 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -233,6 +233,7 @@ where /// ///Bits of security is defined in NIST SP800-57. #[corresponds(EVP_PKEY_security_bits)] + #[cfg(ossl110)] pub fn security_bits(&self) -> u32 { unsafe { ffi::EVP_PKEY_security_bits(self.as_ptr()) as u32 } } From afe7f9ad376cfb515925bd7d303e3dfe9ba0d704 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Thu, 15 Dec 2022 16:05:02 +0100 Subject: [PATCH 26/38] fixup! Add get_security_bits for PKey --- openssl/src/pkey.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index dd2af2f36f..1d2e68aea8 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -1028,6 +1028,7 @@ mod tests { } #[test] + #[cfg(ossl110)] fn test_security_bits() { let group = crate::ec::EcGroup::from_curve_name(crate::nid::Nid::SECP521R1).unwrap(); let ec_key = EcKey::generate(&group).unwrap(); From f9f4d6565c60a9b11df928aec3756c0f514a54f7 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 15 Dec 2022 20:05:00 -0500 Subject: [PATCH 27/38] clippy --- openssl/src/asn1.rs | 2 +- openssl/src/bn.rs | 1 + openssl/src/conf.rs | 1 + openssl/src/rsa.rs | 1 + openssl/src/ssl/callbacks.rs | 4 ++-- openssl/src/ssl/mod.rs | 4 ++-- openssl/src/x509/tests.rs | 1 + 7 files changed, 9 insertions(+), 5 deletions(-) diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index 7f936837db..b02f9ac41e 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -512,7 +512,7 @@ impl Asn1Integer { } impl Asn1IntegerRef { - #[allow(missing_docs)] + #[allow(missing_docs, clippy::unnecessary_cast)] #[deprecated(since = "0.10.6", note = "use to_bn instead")] pub fn get(&self) -> i64 { unsafe { ffi::ASN1_INTEGER_get(self.as_ptr()) as i64 } diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs index 2619b5ba63..8f0e350755 100644 --- a/openssl/src/bn.rs +++ b/openssl/src/bn.rs @@ -336,6 +336,7 @@ impl BigNumRef { /// Returns the number of significant bits in `self`. #[corresponds(BN_num_bits)] + #[allow(clippy::unnecessary_cast)] pub fn num_bits(&self) -> i32 { unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 } } diff --git a/openssl/src/conf.rs b/openssl/src/conf.rs index 2c54cf28d0..715519c595 100644 --- a/openssl/src/conf.rs +++ b/openssl/src/conf.rs @@ -20,6 +20,7 @@ mod methods { impl ConfMethod { /// Retrieve handle to the default OpenSSL configuration file processing function. #[corresponds(NCONF_default)] + #[allow(clippy::should_implement_trait)] pub fn default() -> ConfMethod { unsafe { ffi::init(); diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index b5d096744a..68cf64b036 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -234,6 +234,7 @@ where /// Validates RSA parameters for correctness #[corresponds(RSA_check_key)] + #[allow(clippy::unnecessary_cast)] pub fn check_key(&self) -> Result { unsafe { let result = ffi::RSA_check_key(self.as_ptr()) as i32; diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs index 45760dc66a..091b1fb771 100644 --- a/openssl/src/ssl/callbacks.rs +++ b/openssl/src/ssl/callbacks.rs @@ -482,7 +482,7 @@ where .ssl_context() .ex_data(SslContext::cached_ex_index::()) .expect("BUG: stateless cookie verify callback missing") as *const F; - let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize); + let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len); (*callback)(ssl, slice) as c_int } @@ -654,7 +654,7 @@ where .ex_data(SslContext::cached_ex_index::()) .expect("BUG: custom ext parse callback missing") as *const F; let ectx = ExtensionContext::from_bits_truncate(context); - let slice = slice::from_raw_parts(input as *const u8, inlen as usize); + 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))) } else { diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 89a380e072..aba606248f 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -1867,7 +1867,7 @@ impl SslContextRef { /// /// A value of 0 means that the cache size is unbounded. #[corresponds(SSL_CTX_sess_get_cache_size)] - #[allow(clippy::useless_conversion)] + #[allow(clippy::unnecessary_cast)] pub fn session_cache_size(&self) -> i64 { unsafe { ffi::SSL_CTX_sess_get_cache_size(self.as_ptr()) as i64 } } @@ -3289,7 +3289,7 @@ impl SslStream { ) }; if ret > 0 { - Ok(written as usize) + Ok(written) } else { Err(self.make_error(ret)) } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 33d6f4f1e9..336de3c914 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -634,6 +634,7 @@ fn test_verify_param_set_depth() { #[test] #[cfg(any(ossl102, libressl261))] +#[allow(clippy::bool_to_int_with_if)] fn test_verify_param_set_depth_fails_verification() { let cert = include_bytes!("../../test/leaf.pem"); let cert = X509::from_pem(cert).unwrap(); From cc811f5fd17ee808cbde4ff30cb84762e52fa371 Mon Sep 17 00:00:00 2001 From: Charlie Li Date: Fri, 16 Dec 2022 21:20:46 -0500 Subject: [PATCH 28/38] Add to CI/unblock LibreSSL 3.7.0 --- .github/workflows/ci.yml | 10 ++++++++++ openssl-sys/build/main.rs | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4aeee0c9b..57728778f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -187,6 +187,11 @@ jobs: library: name: libressl version: 3.6.1 + - target: x86_64-unknown-linux-gnu + bindgen: true + library: + name: libressl + version: 3.7.0 - target: x86_64-unknown-linux-gnu bindgen: false library: @@ -202,6 +207,11 @@ jobs: library: name: libressl version: 3.6.1 + - target: x86_64-unknown-linux-gnu + bindgen: false + library: + name: libressl + version: 3.7.0 exclude: - library: name: boringssl diff --git a/openssl-sys/build/main.rs b/openssl-sys/build/main.rs index 71b36c2309..cdea3eb447 100644 --- a/openssl-sys/build/main.rs +++ b/openssl-sys/build/main.rs @@ -282,6 +282,7 @@ See rust-openssl documentation for more information: (3, 5, _) => ('3', '5', 'x'), (3, 6, 0) => ('3', '6', '0'), (3, 6, _) => ('3', '6', 'x'), + (3, 7, 0) => ('3', '7', '0'), _ => version_error(), }; @@ -324,7 +325,7 @@ fn version_error() -> ! { " This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3.0.0), or LibreSSL 2.5 -through 3.6.x, but a different version of OpenSSL was found. The build is now aborting +through 3.7.0, but a different version of OpenSSL was found. The build is now aborting due to this version mismatch. " From 8178f3b38ab098e989846a01a560e26207f870b8 Mon Sep 17 00:00:00 2001 From: Charlie Li Date: Fri, 16 Dec 2022 21:42:52 -0500 Subject: [PATCH 29/38] Add LibreSSL 3.7.0 build cfg --- openssl-sys/build/cfgs.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openssl-sys/build/cfgs.rs b/openssl-sys/build/cfgs.rs index 9ae7748cc6..6e1e5286a1 100644 --- a/openssl-sys/build/cfgs.rs +++ b/openssl-sys/build/cfgs.rs @@ -43,6 +43,9 @@ pub fn get(openssl_version: Option, libressl_version: Option) -> Vec<& if libressl_version >= 0x3_05_00_00_0 { cfgs.push("libressl350"); } + if libressl_version >= 0x3_07_00_00_0 { + cfgs.push("libressl370"); + } } else { let openssl_version = openssl_version.unwrap(); From fda7d92f033d5bcbba69850c27148869f01e5745 Mon Sep 17 00:00:00 2001 From: Charlie Li Date: Fri, 16 Dec 2022 21:43:31 -0500 Subject: [PATCH 30/38] X509_V_FLAG_CB_ISSUER_CHECK deprecated in LibreSSL 3.7.0 --- openssl-sys/src/x509_vfy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openssl-sys/src/x509_vfy.rs b/openssl-sys/src/x509_vfy.rs index 8deaeeaaf3..455a748b52 100644 --- a/openssl-sys/src/x509_vfy.rs +++ b/openssl-sys/src/x509_vfy.rs @@ -100,9 +100,9 @@ cfg_if! { #[cfg(ossl300)] pub const X509_V_ERR_INVALID_CA: c_int = 79; -#[cfg(not(ossl110))] +#[cfg(not(any(ossl110, libressl370)))] pub const X509_V_FLAG_CB_ISSUER_CHECK: c_ulong = 0x1; -#[cfg(ossl110)] +#[cfg(any(ossl110, libressl370))] pub const X509_V_FLAG_CB_ISSUER_CHECK: c_ulong = 0x0; pub const X509_V_FLAG_USE_CHECK_TIME: c_ulong = 0x2; pub const X509_V_FLAG_CRL_CHECK: c_ulong = 0x4; From b99d7265430420b63b71baf01cbc23088e10ee2c Mon Sep 17 00:00:00 2001 From: Max Lim Date: Sat, 17 Dec 2022 19:59:47 +0300 Subject: [PATCH 31/38] Add OSSL_PROVIDER_set_default_search_path binding --- openssl-sys/src/handwritten/provider.rs | 5 +++++ openssl/src/provider.rs | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/openssl-sys/src/handwritten/provider.rs b/openssl-sys/src/handwritten/provider.rs index ffa7cc580e..93eaa072f3 100644 --- a/openssl-sys/src/handwritten/provider.rs +++ b/openssl-sys/src/handwritten/provider.rs @@ -12,4 +12,9 @@ extern "C" { ) -> *mut OSSL_PROVIDER; #[cfg(ossl300)] pub fn OSSL_PROVIDER_unload(prov: *mut OSSL_PROVIDER) -> c_int; + #[cfg(ossl300)] + pub fn OSSL_PROVIDER_set_default_search_path( + ctx: *mut OSSL_LIB_CTX, + path: *const c_char, + ) -> c_int; } diff --git a/openssl/src/provider.rs b/openssl/src/provider.rs index 72d54f41dc..147fadfdbc 100644 --- a/openssl/src/provider.rs +++ b/openssl/src/provider.rs @@ -1,6 +1,6 @@ -use crate::cvt_p; use crate::error::ErrorStack; use crate::lib_ctx::LibCtxRef; +use crate::{cvt, cvt_p}; use foreign_types::{ForeignType, ForeignTypeRef}; use openssl_macros::corresponds; use std::ffi::CString; @@ -58,4 +58,20 @@ impl Provider { Ok(Provider::from_ptr(p)) } } + + /// Specifies the default search path that is to be used for looking for providers in the specified library context. + /// If left unspecified, an environment variable and a fall back default value will be used instead + /// + /// If `ctx` is `None`, the provider will be loaded into the default library context. + #[corresponds(OSSL_PROVIDER_set_default_search_path)] + pub fn set_default_search_path(ctx: Option<&LibCtxRef>, path: &str) -> Result<(), ErrorStack> { + let path = CString::new(path).unwrap(); + unsafe { + cvt(ffi::OSSL_PROVIDER_set_default_search_path( + ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), + path.as_ptr(), + )) + .map(|_| ()) + } + } } From e01fbac4b3c98fca47c9b16d58aed329dd4d72b6 Mon Sep 17 00:00:00 2001 From: Charlie Li Date: Mon, 19 Dec 2022 19:55:29 -0500 Subject: [PATCH 32/38] openssl-sys: add LibreSSL 3.6.0 to cfgs --- openssl-sys/build/cfgs.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openssl-sys/build/cfgs.rs b/openssl-sys/build/cfgs.rs index 6e1e5286a1..d925d90ad7 100644 --- a/openssl-sys/build/cfgs.rs +++ b/openssl-sys/build/cfgs.rs @@ -43,6 +43,9 @@ pub fn get(openssl_version: Option, libressl_version: Option) -> Vec<& if libressl_version >= 0x3_05_00_00_0 { cfgs.push("libressl350"); } + if libressl_version >= 0x3_06_00_00_0 { + cfgs.push("libressl360"); + } if libressl_version >= 0x3_07_00_00_0 { cfgs.push("libressl370"); } From 0d8d5022583bb585b6cfe028c344113ecf1b77bc Mon Sep 17 00:00:00 2001 From: Charlie Li Date: Mon, 19 Dec 2022 19:57:58 -0500 Subject: [PATCH 33/38] Expose EVP_PKEY_security_bits for LibreSSL 3.6.0 and later --- openssl-sys/src/handwritten/evp.rs | 2 +- openssl/src/pkey.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openssl-sys/src/handwritten/evp.rs b/openssl-sys/src/handwritten/evp.rs index 8bc9675ecd..5ee017f7d1 100644 --- a/openssl-sys/src/handwritten/evp.rs +++ b/openssl-sys/src/handwritten/evp.rs @@ -427,7 +427,7 @@ cfg_if! { const_ptr_api! { extern "C" { pub fn EVP_PKEY_bits(key: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int; - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl360))] pub fn EVP_PKEY_security_bits(pkey: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int; } } diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 1d2e68aea8..2039e7e908 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -233,7 +233,7 @@ where /// ///Bits of security is defined in NIST SP800-57. #[corresponds(EVP_PKEY_security_bits)] - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl360))] pub fn security_bits(&self) -> u32 { unsafe { ffi::EVP_PKEY_security_bits(self.as_ptr()) as u32 } } @@ -1028,7 +1028,7 @@ mod tests { } #[test] - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl360))] fn test_security_bits() { let group = crate::ec::EcGroup::from_curve_name(crate::nid::Nid::SECP521R1).unwrap(); let ec_key = EcKey::generate(&group).unwrap(); From 71013f7efd637ca9fec214f6cb80e8806f3208af Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Tue, 20 Dec 2022 12:31:27 +0100 Subject: [PATCH 34/38] Fix output buffer check introduced in #1733 Sadly the condition used to relax output buffer checks that depended on the `num` parameter does not really hold so this change effectively reverts PR #1733. As clarified on the OpenSSL mailing list [0] and during integration tests the `num` parameter does not reflect the internal buffer cache size thus one needs to pessimistically assume that each call to `cipher_update` will need sufficient size to contain one additional block. Streaming ciphers are not affected by this revert. [0]: https://mta.openssl.org/pipermail/openssl-users/2022-December/015727.html --- openssl/src/cipher_ctx.rs | 155 +++----------------------------------- 1 file changed, 10 insertions(+), 145 deletions(-) diff --git a/openssl/src/cipher_ctx.rs b/openssl/src/cipher_ctx.rs index c0377d969b..d09f8cbd50 100644 --- a/openssl/src/cipher_ctx.rs +++ b/openssl/src/cipher_ctx.rs @@ -379,49 +379,6 @@ impl CipherCtxRef { unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize } } - /// Returns number of bytes cached in partial block update. - #[cfg(ossl110)] - fn used_block_size(&self) -> usize { - self.num() - } - - /// Returns maximum number of bytes that could be cached. - #[cfg(not(ossl110))] - fn used_block_size(&self) -> usize { - self.block_size() - } - - /// Calculate the minimal size of the output buffer given the - /// input buffer size. - /// - /// For streaming ciphers the minimal output size is the same as - /// the input size. For block ciphers the minimal output size - /// additionally depends on the partial blocks that might have - /// been written in previous calls to [`Self::cipher_update`]. - /// - /// This function takes into account the number of partially - /// written blocks for block ciphers for supported targets - /// (OpenSSL >= 1.1). For unsupported targets the number of - /// partially written bytes is assumed to contain one full block - /// (pessimistic case). - /// - /// # Panics - /// - /// Panics if the context has not been initialized with a cipher. - pub fn minimal_output_size(&self, inlen: usize) -> usize { - let block_size = self.block_size(); - if block_size > 1 { - // block cipher - let num = self.used_block_size(); - let total_size = inlen + num; - let num_blocks = total_size / block_size; - num_blocks * block_size - } else { - // streaming cipher - inlen - } - } - /// Sets the length of the IV expected by this context. /// /// Only some ciphers support configurable IV lengths. @@ -569,7 +526,11 @@ impl CipherCtxRef { output: Option<&mut [u8]>, ) -> Result { if let Some(output) = &output { - let min_output_size = self.minimal_output_size(input.len()); + let mut block_size = self.block_size(); + if block_size == 1 { + block_size = 0; + } + let min_output_size = input.len() + block_size; assert!( output.len() >= min_output_size, "Output buffer size should be at least {} bytes.", @@ -588,16 +549,13 @@ impl CipherCtxRef { /// /// This function is the same as [`Self::cipher_update`] but with the /// output size check removed. It can be used when the exact - /// buffer size control is maintained by the caller and the - /// underlying cryptographic library doesn't expose exact block - /// cache data (e.g. OpenSSL < 1.1, BoringSSL, LibreSSL). + /// buffer size control is maintained by the caller. /// /// SAFETY: The caller is expected to provide `output` buffer /// large enough to contain correct number of bytes. For streaming /// ciphers the output buffer size should be at least as big as /// the input buffer. For block ciphers the size of the output - /// buffer depends on the state of partially updated blocks (see - /// [`Self::minimal_output_size`]). + /// buffer depends on the state of partially updated blocks. #[corresponds(EVP_CipherUpdate)] pub unsafe fn cipher_update_unchecked( &mut self, @@ -757,75 +715,6 @@ mod test { aes_128_cbc(cipher); } - #[test] - #[cfg(ossl110)] - fn partial_block_updates() { - test_block_cipher_for_partial_block_updates(Cipher::aes_128_cbc()); - test_block_cipher_for_partial_block_updates(Cipher::aes_256_cbc()); - test_block_cipher_for_partial_block_updates(Cipher::des_ede3_cbc()); - } - - #[cfg(ossl110)] - fn test_block_cipher_for_partial_block_updates(cipher: &'static CipherRef) { - let mut key = vec![0; cipher.key_length()]; - rand_bytes(&mut key).unwrap(); - let mut iv = vec![0; cipher.iv_length()]; - rand_bytes(&mut iv).unwrap(); - - let mut ctx = CipherCtx::new().unwrap(); - - ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv)) - .unwrap(); - ctx.set_padding(false); - - let block_size = cipher.block_size(); - assert!(block_size > 1, "Need a block cipher, not a stream cipher"); - - // update cipher with non-full block - // expect no output until a block is complete - let outlen = ctx - .cipher_update(&vec![0; block_size - 1], Some(&mut [0; 0])) - .unwrap(); - assert_eq!(0, outlen); - - // update cipher with missing bytes from the previous block - // and one additional block, output should contain two blocks - let mut two_blocks = vec![0; block_size * 2]; - let outlen = ctx - .cipher_update(&vec![0; block_size + 1], Some(&mut two_blocks)) - .unwrap(); - assert_eq!(block_size * 2, outlen); - - ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); - - // try to decrypt - ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv)) - .unwrap(); - ctx.set_padding(false); - - // update cipher with non-full block - // expect no output until a block is complete - let outlen = ctx - .cipher_update(&two_blocks[0..block_size - 1], Some(&mut [0; 0])) - .unwrap(); - assert_eq!(0, outlen); - - // update cipher with missing bytes from the previous block - // and one additional block, output should contain two blocks - let mut two_blocks_decrypted = vec![0; block_size * 2]; - let outlen = ctx - .cipher_update( - &two_blocks[block_size - 1..], - Some(&mut two_blocks_decrypted), - ) - .unwrap(); - assert_eq!(block_size * 2, outlen); - - ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); - // check if the decrypted blocks are the same as input (all zeros) - assert_eq!(two_blocks_decrypted, vec![0; block_size * 2]); - } - #[test] fn test_stream_ciphers() { test_stream_cipher(Cipher::aes_192_ctr()); @@ -894,43 +783,19 @@ mod test { } #[test] - #[should_panic(expected = "Output buffer size should be at least 16 bytes.")] - #[cfg(ossl110)] - fn full_block_updates_aes_128() { - output_buffer_too_small(Cipher::aes_128_cbc()); - } - - #[test] - #[should_panic(expected = "Output buffer size should be at least 16 bytes.")] - #[cfg(ossl110)] - fn full_block_updates_aes_256() { - output_buffer_too_small(Cipher::aes_256_cbc()); - } - - #[test] - #[should_panic(expected = "Output buffer size should be at least 8 bytes.")] - #[cfg(ossl110)] - fn full_block_updates_3des() { - output_buffer_too_small(Cipher::des_ede3_cbc()); - } - - #[test] - #[should_panic(expected = "Output buffer size should be at least 32 bytes.")] - #[cfg(not(ossl110))] + #[should_panic(expected = "Output buffer size should be at least 33 bytes.")] fn full_block_updates_aes_128() { output_buffer_too_small(Cipher::aes_128_cbc()); } #[test] - #[should_panic(expected = "Output buffer size should be at least 32 bytes.")] - #[cfg(not(ossl110))] + #[should_panic(expected = "Output buffer size should be at least 33 bytes.")] fn full_block_updates_aes_256() { output_buffer_too_small(Cipher::aes_256_cbc()); } #[test] - #[should_panic(expected = "Output buffer size should be at least 16 bytes.")] - #[cfg(not(ossl110))] + #[should_panic(expected = "Output buffer size should be at least 17 bytes.")] fn full_block_updates_3des() { output_buffer_too_small(Cipher::des_ede3_cbc()); } From 45e5dce285f189e23f941ac890e17277a5112adc Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Tue, 20 Dec 2022 13:33:09 +0100 Subject: [PATCH 35/38] Expose `Cipher::cipher_final_unchecked` This mirrors the `Cipher::cipher_update_unchecked` API call for clients that want to manually track the state of internal OpenSSL cipher buffer size. --- openssl/src/cipher_ctx.rs | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/openssl/src/cipher_ctx.rs b/openssl/src/cipher_ctx.rs index d09f8cbd50..379f83a7ba 100644 --- a/openssl/src/cipher_ctx.rs +++ b/openssl/src/cipher_ctx.rs @@ -607,14 +607,34 @@ impl CipherCtxRef { assert!(output.len() >= block_size); } + unsafe { self.cipher_final_unchecked(output) } + } + + /// Finalizes the encryption or decryption process. + /// + /// Any remaining data will be written to the output buffer. + /// + /// Returns the number of bytes written to `output`. + /// + /// This function is the same as [`Self::cipher_final`] but with + /// the output buffer size check removed. + /// + /// SAFETY: The caller is expected to provide `output` buffer + /// large enough to contain correct number of bytes. For streaming + /// ciphers the output buffer can be empty, for block ciphers the + /// output buffer should be at least as big as the block. + #[corresponds(EVP_CipherFinal)] + pub unsafe fn cipher_final_unchecked( + &mut self, + output: &mut [u8], + ) -> Result { let mut outl = 0; - unsafe { - cvt(ffi::EVP_CipherFinal( - self.as_ptr(), - output.as_mut_ptr(), - &mut outl, - ))?; - } + + cvt(ffi::EVP_CipherFinal( + self.as_ptr(), + output.as_mut_ptr(), + &mut outl, + ))?; Ok(outl as usize) } From 27edce934080430fbdd9da108dea4807494233aa Mon Sep 17 00:00:00 2001 From: Cfir Tsabari Date: Tue, 20 Dec 2022 15:30:33 +0200 Subject: [PATCH 36/38] Mark Openssl # deprecated functions --- openssl-sys/src/handwritten/aes.rs | 1 + openssl-sys/src/handwritten/bn.rs | 4 ++++ openssl/src/aes.rs | 4 +++- openssl/src/bn.rs | 7 +++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/openssl-sys/src/handwritten/aes.rs b/openssl-sys/src/handwritten/aes.rs index 241848eccf..884f9d7242 100644 --- a/openssl-sys/src/handwritten/aes.rs +++ b/openssl-sys/src/handwritten/aes.rs @@ -12,6 +12,7 @@ extern "C" { pub fn AES_set_encrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int; pub fn AES_set_decrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] pub fn AES_ige_encrypt( in_: *const c_uchar, out: *mut c_uchar, diff --git a/openssl-sys/src/handwritten/bn.rs b/openssl-sys/src/handwritten/bn.rs index d523f24d34..8e5ae153dd 100644 --- a/openssl-sys/src/handwritten/bn.rs +++ b/openssl-sys/src/handwritten/bn.rs @@ -7,8 +7,10 @@ extern "C" { pub fn BN_CTX_secure_new() -> *mut BN_CTX; pub fn BN_CTX_free(ctx: *mut BN_CTX); pub fn BN_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] pub fn BN_pseudo_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int; pub fn BN_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] pub fn BN_pseudo_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int; pub fn BN_new() -> *mut BIGNUM; #[cfg(ossl110)] @@ -122,12 +124,14 @@ extern "C" { rem: *const BIGNUM, cb: *mut BN_GENCB, ) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] pub fn BN_is_prime_ex( p: *const BIGNUM, checks: c_int, ctx: *mut BN_CTX, cb: *mut BN_GENCB, ) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] pub fn BN_is_prime_fasttest_ex( p: *const BIGNUM, checks: c_int, diff --git a/openssl/src/aes.rs b/openssl/src/aes.rs index 440dd05723..cbc4999bb8 100644 --- a/openssl/src/aes.rs +++ b/openssl/src/aes.rs @@ -23,7 +23,7 @@ //! # Examples #![cfg_attr( - not(boringssl), + all(not(boringssl), not(osslconf = "OPENSSL_NO_DEPRECATED_3_0")), doc = r#"\ ## AES IGE ```rust @@ -156,6 +156,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))] +#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] #[corresponds(AES_ige_encrypt)] pub fn aes_ige(in_: &[u8], out: &mut [u8], key: &AesKey, iv: &mut [u8], mode: Mode) { unsafe { @@ -268,6 +269,7 @@ mod test { // From https://www.mgp25.com/AESIGE/ #[test] #[cfg(not(boringssl))] + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] fn ige_vector_1() { let raw_key = "000102030405060708090A0B0C0D0E0F"; let raw_iv = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"; diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs index 8f0e350755..1cd00dd4bc 100644 --- a/openssl/src/bn.rs +++ b/openssl/src/bn.rs @@ -217,6 +217,7 @@ impl BigNumRef { } /// The cryptographically weak counterpart to `rand_in_range`. + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] #[corresponds(BN_pseudo_rand_range)] pub fn pseudo_rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) } @@ -385,6 +386,7 @@ impl BigNumRef { } /// The cryptographically weak counterpart to `rand`. Not suitable for key generation. + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] #[corresponds(BN_pseudo_rand)] #[allow(clippy::useless_conversion)] pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> { @@ -722,6 +724,7 @@ impl BigNumRef { /// # Return Value /// /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`. + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] #[corresponds(BN_is_prime_ex)] #[allow(clippy::useless_conversion)] pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result { @@ -745,6 +748,7 @@ impl BigNumRef { /// # Return Value /// /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`. + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] #[corresponds(BN_is_prime_fasttest_ex)] #[allow(clippy::useless_conversion)] pub fn is_prime_fasttest( @@ -1388,6 +1392,7 @@ mod tests { assert_eq!(a, &(&a << 1) >> 1); } + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] #[test] fn test_rand_range() { let range = BigNum::from_u32(909_829_283).unwrap(); @@ -1396,6 +1401,7 @@ mod tests { assert!(result >= BigNum::from_u32(0).unwrap() && result < range); } + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] #[test] fn test_pseudo_rand_range() { let range = BigNum::from_u32(909_829_283).unwrap(); @@ -1404,6 +1410,7 @@ mod tests { assert!(result >= BigNum::from_u32(0).unwrap() && result < range); } + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] #[test] fn test_prime_numbers() { let a = BigNum::from_u32(19_029_017).unwrap(); From f32af9f4aac5d4a29b48c7782fcdd1a219a3fc64 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 20 Dec 2022 09:36:23 -0500 Subject: [PATCH 37/38] Release openssl-sys v0.9.80 --- openssl-sys/CHANGELOG.md | 16 +++++++++++++++- openssl-sys/Cargo.toml | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/openssl-sys/CHANGELOG.md b/openssl-sys/CHANGELOG.md index ec815325f7..1bf8690dbe 100644 --- a/openssl-sys/CHANGELOG.md +++ b/openssl-sys/CHANGELOG.md @@ -2,6 +2,19 @@ ## [Unreleased] +## [v0.9.80] - 2022-12-20 + +### Fixed + +* Added `NO_DEPRECATED_3_0` cfg checks for more APIs. + +### Added + +* Added support for LibreSSL 3.7.0. +* Added `SSL_CTRL_CHAIN_CERT` and `SSL_add0_chain_cert`. +* Added `EVP_PKEY_get_security_bits` and `EVP_PKEY_security_bits`. +* Added `OSSL_PROVIDER_set_default_search_path`. + ## [v0.9.79] - 2022-12-06 ### Added @@ -357,7 +370,8 @@ * 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.79..master +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.80..master +[v0.9.80]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.79...openssl-sys-v0.9.80 [v0.9.79]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.78...openssl-sys-v0.9.79 [v0.9.78]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.77...openssl-sys-v0.9.78 [v0.9.77]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.76...openssl-sys-v0.9.77 diff --git a/openssl-sys/Cargo.toml b/openssl-sys/Cargo.toml index de6b33e80b..d8e4c7661b 100644 --- a/openssl-sys/Cargo.toml +++ b/openssl-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl-sys" -version = "0.9.79" +version = "0.9.80" authors = [ "Alex Crichton ", "Steven Fackler ", From 7df56869c5e1e32369091ab106750d644d3aa0c4 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 20 Dec 2022 09:41:50 -0500 Subject: [PATCH 38/38] Release openssl v0.10.45 --- openssl/CHANGELOG.md | 19 +++++++++++++++++-- openssl/Cargo.toml | 4 ++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/openssl/CHANGELOG.md b/openssl/CHANGELOG.md index f66bcb7501..0af50bcc24 100644 --- a/openssl/CHANGELOG.md +++ b/openssl/CHANGELOG.md @@ -2,6 +2,20 @@ ## [Unreleased] +## [v0.10.45] - 2022-12-20 + +### Fixed + +* Removed the newly added `CipherCtxRef::minimal_output_size` method, which did not work properly. +* Added `NO_DEPRECATED_3_0` cfg checks for more APIs. + +### Added + +* Added `SslRef::add_chain_cert`. +* Added `PKeyRef::security_bits`. +* Added `Provider::set_default_search_path`. +* Added `CipherCtxRef::cipher_final_unchecked`. + ## [v0.10.44] - 2022-12-06 ### Added @@ -649,8 +663,9 @@ Look at the [release tags] for information about older releases. -[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.44...master -[v0.10.44]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.44...openssl-v0.10.44 +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.45...master +[v0.10.45]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.44...openssl-v0.10.45 +[v0.10.44]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.43...openssl-v0.10.44 [v0.10.43]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.42...openssl-v0.10.43 [v0.10.42]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.41...openssl-v0.10.42 [v0.10.41]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.40...openssl-v0.10.41 diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index 03f621eddd..1fd24448fd 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openssl" -version = "0.10.44" +version = "0.10.45" 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.79", path = "../openssl-sys" } +ffi = { package = "openssl-sys", version = "0.9.80", path = "../openssl-sys" } [dev-dependencies] hex = "0.3"