From cf9681a55cabd4cb9f1475bde17b5079f2a0384e Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Nov 2023 09:11:34 -0500 Subject: [PATCH 1/2] fixes #2096 -- deprecate `X509StoreRef::objects`, it is unsound Introduce `X509StoreRef::all_certificates` as a replacement. --- openssl-sys/src/handwritten/x509.rs | 2 ++ openssl/src/cipher_ctx.rs | 6 ++++-- openssl/src/lib.rs | 2 +- openssl/src/x509/store.rs | 18 +++++++++++++++++- openssl/src/x509/tests.rs | 15 +++++++++++++++ 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/openssl-sys/src/handwritten/x509.rs b/openssl-sys/src/handwritten/x509.rs index f5e3c24289..c5419ed6eb 100644 --- a/openssl-sys/src/handwritten/x509.rs +++ b/openssl-sys/src/handwritten/x509.rs @@ -644,6 +644,8 @@ const_ptr_api! { extern "C" { #[cfg(any(ossl110, libressl270))] pub fn X509_STORE_get0_objects(ctx: #[const_ptr_if(ossl300)] X509_STORE) -> *mut stack_st_X509_OBJECT; + #[cfg(ossl300)] + pub fn X509_STORE_get1_all_certs(ctx: *mut X509_STORE) -> *mut stack_st_X509; } } diff --git a/openssl/src/cipher_ctx.rs b/openssl/src/cipher_ctx.rs index 1769ee9716..58e789b044 100644 --- a/openssl/src/cipher_ctx.rs +++ b/openssl/src/cipher_ctx.rs @@ -581,7 +581,8 @@ impl CipherCtxRef { /// output size check removed. It can be used when the exact /// buffer size control is maintained by the caller. /// - /// SAFETY: The caller is expected to provide `output` buffer + /// # 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 @@ -693,7 +694,8 @@ impl CipherCtxRef { /// 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 + /// # 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. diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index 4b9ee80454..5c9ccf7a05 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -119,7 +119,7 @@ //! ``` #![doc(html_root_url = "https://docs.rs/openssl/0.10")] #![warn(rust_2018_idioms)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, clippy::needless_doctest_main)] #[doc(inline)] pub use ffi::init; diff --git a/openssl/src/x509/store.rs b/openssl/src/x509/store.rs index a90bf3515f..8619086ebb 100644 --- a/openssl/src/x509/store.rs +++ b/openssl/src/x509/store.rs @@ -42,12 +42,14 @@ //! ``` use cfg_if::cfg_if; -use foreign_types::ForeignTypeRef; +use foreign_types::{ForeignType, ForeignTypeRef}; use std::mem; use crate::error::ErrorStack; #[cfg(not(boringssl))] use crate::ssl::SslFiletype; +#[cfg(ossl300)] +use crate::stack::Stack; use crate::stack::StackRef; #[cfg(any(ossl102, libressl261))] use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef}; @@ -260,10 +262,24 @@ foreign_type_and_impl_send_sync! { impl X509StoreRef { /// Get a reference to the cache of certificates in this store. + /// + /// This method is deprecated. It is **unsound** and will be removed in a + /// future version of rust-openssl. `X509StoreRef::all_certificates` + /// should be used instead. + #[deprecated( + note = "This method is unsound, and will be removed in a future version of rust-openssl. X509StoreRef::all_certificates should be used instead." + )] #[corresponds(X509_STORE_get0_objects)] pub fn objects(&self) -> &StackRef { unsafe { StackRef::from_ptr(X509_STORE_get0_objects(self.as_ptr())) } } + + /// Returns a stack of all the certificates in this store. + #[corresponds(X509_STORE_get1_all_certs)] + #[cfg(ossl300)] + pub fn all_certificates(&self) -> Stack { + unsafe { Stack::from_ptr(ffi::X509_STORE_get1_all_certs(self.as_ptr())) } + } } cfg_if! { diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index a4a3de970c..0444a067dd 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1177,3 +1177,18 @@ fn test_dist_point_null() { let cert = X509::from_pem(cert).unwrap(); assert!(cert.crl_distribution_points().is_none()); } + +#[test] +#[cfg(ossl300)] +fn test_store_all_certificates() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let store = { + let mut b = X509StoreBuilder::new().unwrap(); + b.add_cert(cert).unwrap(); + b.build() + }; + + assert_eq!(store.all_certificates().len(), 1); +} From 602d38dca7b8a22a355e1e53199d922742025c5c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Nov 2023 09:29:12 -0500 Subject: [PATCH 2/2] Added `update_unchecked` to `symm::Crypter` --- openssl/src/cipher_ctx.rs | 6 ++++-- openssl/src/lib.rs | 2 +- openssl/src/symm.rs | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/openssl/src/cipher_ctx.rs b/openssl/src/cipher_ctx.rs index 1769ee9716..58e789b044 100644 --- a/openssl/src/cipher_ctx.rs +++ b/openssl/src/cipher_ctx.rs @@ -581,7 +581,8 @@ impl CipherCtxRef { /// output size check removed. It can be used when the exact /// buffer size control is maintained by the caller. /// - /// SAFETY: The caller is expected to provide `output` buffer + /// # 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 @@ -693,7 +694,8 @@ impl CipherCtxRef { /// 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 + /// # 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. diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index 4b9ee80454..5c9ccf7a05 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -119,7 +119,7 @@ //! ``` #![doc(html_root_url = "https://docs.rs/openssl/0.10")] #![warn(rust_2018_idioms)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, clippy::needless_doctest_main)] #[doc(inline)] pub use ffi::init; diff --git a/openssl/src/symm.rs b/openssl/src/symm.rs index 1e9dc34fc6..0ff9d874e2 100644 --- a/openssl/src/symm.rs +++ b/openssl/src/symm.rs @@ -696,6 +696,27 @@ impl Crypter { self.ctx.cipher_update(input, Some(output)) } + /// Feeds data from `input` through the cipher, writing encrypted/decrypted + /// bytes into `output`. + /// + /// The number of bytes written to `output` is returned. Note that this may + /// not be equal to the length of `input`. + /// + /// # Safety + /// + /// The caller must provide an `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. + pub unsafe fn update_unchecked( + &mut self, + input: &[u8], + output: &mut [u8], + ) -> Result { + self.ctx.cipher_update_unchecked(input, Some(output)) + } + /// Finishes the encryption/decryption process, writing any remaining data /// to `output`. ///