Add mutable ex_data APIs for X509StoreContext
This commit is contained in:
parent
15975ddde4
commit
45f8589d48
|
|
@ -108,6 +108,8 @@ extern crate libc;
|
|||
#[cfg(test)]
|
||||
extern crate hex;
|
||||
|
||||
use std::ffi::{c_long, c_void};
|
||||
|
||||
#[doc(inline)]
|
||||
pub use crate::ffi::init;
|
||||
|
||||
|
|
@ -193,3 +195,16 @@ fn cvt_n(r: c_int) -> Result<c_int, ErrorStack> {
|
|||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn free_data_box<T>(
|
||||
_parent: *mut c_void,
|
||||
ptr: *mut c_void,
|
||||
_ad: *mut ffi::CRYPTO_EX_DATA,
|
||||
_idx: c_int,
|
||||
_argl: c_long,
|
||||
_argp: *mut c_void,
|
||||
) {
|
||||
if !ptr.is_null() {
|
||||
drop(Box::<T>::from_raw(ptr as *mut T));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
//! }
|
||||
//! ```
|
||||
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
|
||||
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_void};
|
||||
use libc::{c_char, c_int, c_uchar, c_uint, c_void};
|
||||
use openssl_macros::corresponds;
|
||||
use std::any::TypeId;
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -81,7 +81,6 @@ use crate::dh::DhRef;
|
|||
use crate::ec::EcKeyRef;
|
||||
use crate::error::ErrorStack;
|
||||
use crate::ex_data::Index;
|
||||
use crate::ffi;
|
||||
use crate::nid::Nid;
|
||||
use crate::pkey::{HasPrivate, PKeyRef, Params, Private};
|
||||
use crate::srtp::{SrtpProtectionProfile, SrtpProtectionProfileRef};
|
||||
|
|
@ -95,6 +94,7 @@ use crate::x509::{
|
|||
X509Name, X509Ref, X509StoreContextRef, X509VerifyError, X509VerifyResult, X509,
|
||||
};
|
||||
use crate::{cvt, cvt_0i, cvt_n, cvt_p, init};
|
||||
use crate::{ffi, free_data_box};
|
||||
|
||||
pub use self::async_callbacks::{
|
||||
AsyncPrivateKeyMethod, AsyncPrivateKeyMethodError, AsyncSelectCertError, BoxCustomVerifyFinish,
|
||||
|
|
@ -439,19 +439,6 @@ static SESSION_CTX_INDEX: LazyLock<Index<Ssl, SslContext>> =
|
|||
static RPK_FLAG_INDEX: LazyLock<Index<SslContext, bool>> =
|
||||
LazyLock::new(|| SslContext::new_ex_index().unwrap());
|
||||
|
||||
unsafe extern "C" fn free_data_box<T>(
|
||||
_parent: *mut c_void,
|
||||
ptr: *mut c_void,
|
||||
_ad: *mut ffi::CRYPTO_EX_DATA,
|
||||
_idx: c_int,
|
||||
_argl: c_long,
|
||||
_argp: *mut c_void,
|
||||
) {
|
||||
if !ptr.is_null() {
|
||||
drop(Box::<T>::from_raw(ptr as *mut T));
|
||||
}
|
||||
}
|
||||
|
||||
/// An error returned from the SNI callback.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SniError(c_int);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ use crate::bio::{MemBio, MemBioSlice};
|
|||
use crate::conf::ConfRef;
|
||||
use crate::error::ErrorStack;
|
||||
use crate::ex_data::Index;
|
||||
use crate::ffi;
|
||||
use crate::hash::{DigestBytes, MessageDigest};
|
||||
use crate::nid::Nid;
|
||||
use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public};
|
||||
|
|
@ -40,6 +39,7 @@ use crate::string::OpensslString;
|
|||
use crate::util::ForeignTypeRefExt;
|
||||
use crate::x509::verify::{X509VerifyParam, X509VerifyParamRef};
|
||||
use crate::{cvt, cvt_n, cvt_p};
|
||||
use crate::{ffi, free_data_box};
|
||||
|
||||
pub mod extension;
|
||||
pub mod store;
|
||||
|
|
@ -72,6 +72,22 @@ impl X509StoreContext {
|
|||
cvt_p(ffi::X509_STORE_CTX_new()).map(|p| X509StoreContext::from_ptr(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a new extra data index.
|
||||
///
|
||||
/// Each invocation of this function is guaranteed to return a distinct index. These can be used
|
||||
/// to store data in the context that can be retrieved later by callbacks, for example.
|
||||
#[corresponds(SSL_CTX_get_ex_new_index)]
|
||||
pub fn new_ex_index<T>() -> Result<Index<X509StoreContext, T>, ErrorStack>
|
||||
where
|
||||
T: 'static + Sync + Send,
|
||||
{
|
||||
unsafe {
|
||||
ffi::init();
|
||||
let idx = cvt_n(get_new_x509_store_ctx_idx(Some(free_data_box::<T>)))?;
|
||||
Ok(Index::from_raw(idx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl X509StoreContextRef {
|
||||
|
|
@ -88,6 +104,44 @@ impl X509StoreContextRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the extra data at the specified index.
|
||||
#[corresponds(X509_STORE_CTX_get_ex_data)]
|
||||
pub fn ex_data_mut<T>(&mut self, index: Index<X509StoreContext, T>) -> Option<&mut T> {
|
||||
unsafe {
|
||||
let data = ffi::X509_STORE_CTX_get_ex_data(self.as_ptr(), index.as_raw());
|
||||
if data.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut *(data as *mut T))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets or overwrites the extra data at the specified index.
|
||||
///
|
||||
/// This can be used to provide data to callbacks registered with the context. Use the
|
||||
/// `Ssl::new_ex_index` method to create an `Index`.
|
||||
///
|
||||
/// The previous value, if any, will be returned.
|
||||
#[corresponds(X509_STORE_CTX_set_ex_data)]
|
||||
pub fn set_ex_data<T>(&mut self, index: Index<X509StoreContext, T>, data: T) {
|
||||
if let Some(old) = self.ex_data_mut(index) {
|
||||
*old = data;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let data = Box::new(data);
|
||||
|
||||
ffi::X509_STORE_CTX_set_ex_data(
|
||||
self.as_ptr(),
|
||||
index.as_raw(),
|
||||
Box::into_raw(data) as *mut c_void,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the verify result of the context.
|
||||
#[corresponds(X509_STORE_CTX_get_error)]
|
||||
pub fn verify_result(&self) -> X509VerifyResult {
|
||||
|
|
@ -1688,3 +1742,14 @@ unsafe fn X509_OBJECT_free(x: *mut ffi::X509_OBJECT) {
|
|||
ffi::X509_OBJECT_free_contents(x);
|
||||
ffi::OPENSSL_free(x as *mut libc::c_void);
|
||||
}
|
||||
|
||||
unsafe fn get_new_x509_store_ctx_idx(f: ffi::CRYPTO_EX_free) -> c_int {
|
||||
// hack around https://rt.openssl.org/Ticket/Display.html?id=3710&user=guest&pass=guest
|
||||
static ONCE: Once = Once::new();
|
||||
|
||||
ONCE.call_once(|| {
|
||||
ffi::X509_STORE_CTX_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, None);
|
||||
});
|
||||
|
||||
ffi::X509_STORE_CTX_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, f)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue