diff options
| author | Steven Fackler <[email protected]> | 2015-03-29 10:18:30 -0700 |
|---|---|---|
| committer | Steven Fackler <[email protected]> | 2015-03-29 10:18:30 -0700 |
| commit | 2b1a9a7814293d50829a60d42f4e8f2ea0353bd7 (patch) | |
| tree | 036c0d00d49c85bfdc9a8e320ec7e1dd63a8b04f /openssl/src | |
| parent | Merge pull request #191 from fhartwig/rustup (diff) | |
| download | rust-openssl-2b1a9a7814293d50829a60d42f4e8f2ea0353bd7.tar.xz rust-openssl-2b1a9a7814293d50829a60d42f4e8f2ea0353bd7.zip | |
Fix verify data free function
Turns out this is called with a null pointer if you never set the data
which didn't end up doing anything until the recent zeroing drop
changes.
Also use a map of indexes since statics in generic functions don't
monomorphize
Diffstat (limited to 'openssl/src')
| -rw-r--r-- | openssl/src/lib.rs | 9 | ||||
| -rw-r--r-- | openssl/src/ssl/mod.rs | 38 |
2 files changed, 27 insertions, 20 deletions
diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index 90749fd8..beafdd91 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -1,15 +1,16 @@ -#![feature(unsafe_destructor, core, io, std_misc, unique)] +#![feature(unsafe_destructor, core, io, std_misc, unique, collections)] #![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/openssl")] #[macro_use] extern crate bitflags; - extern crate libc; +#[macro_use] +extern crate lazy_static; +extern crate openssl_sys as ffi; + #[cfg(test)] extern crate rustc_serialize as serialize; -extern crate openssl_sys as ffi; - mod macros; pub mod asn1; diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 471bfc5a..5f50a33f 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -1,4 +1,6 @@ use libc::{c_int, c_void, c_long}; +use std::any::TypeId; +use std::collections::HashMap; use std::ffi::{CStr, CString}; use std::fmt; use std::io; @@ -10,9 +12,10 @@ use std::num::FromPrimitive; use std::num::Int; use std::path::Path; use std::ptr; -use std::sync::{Once, ONCE_INIT, Arc}; +use std::sync::{Once, ONCE_INIT, Arc, Mutex}; use std::ops::{Deref, DerefMut}; use std::cmp; +use std::marker::Reflect; #[cfg(feature = "npn")] use libc::{c_uchar, c_uint}; #[cfg(feature = "npn")] @@ -124,29 +127,30 @@ pub enum SslVerifyMode { SslVerifyNone = ffi::SSL_VERIFY_NONE } +lazy_static! { + static ref INDEXES: Mutex<HashMap<TypeId, c_int>> = Mutex::new(HashMap::new()); +} + // Creates a static index for user data of type T // Registers a destructor for the data which will be called // when context is freed -fn get_verify_data_idx<T>() -> c_int { - static mut VERIFY_DATA_IDX: c_int = -1; - static mut INIT: Once = ONCE_INIT; - +fn get_verify_data_idx<T: Reflect + 'static>() -> c_int { extern 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) { - let _: Box<T> = unsafe { mem::transmute(ptr) }; + if ptr != 0 as *mut _ { + let _: Box<T> = unsafe { mem::transmute(ptr) }; + } } - unsafe { - INIT.call_once(|| { + *INDEXES.lock().unwrap().entry(TypeId::of::<T>()).or_insert_with(|| { + unsafe { let f: ffi::CRYPTO_EX_free = free_data_box::<T>; - let idx = ffi::SSL_CTX_get_ex_new_index(0, ptr::null(), None, - None, Some(f)); + let idx = ffi::SSL_CTX_get_ex_new_index(0, ptr::null(), None, None, Some(f)); assert!(idx >= 0); - VERIFY_DATA_IDX = idx; - }); - VERIFY_DATA_IDX - } + idx + } + }) } /// Creates a static index for the list of NPN protocols. @@ -196,7 +200,8 @@ extern fn raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) } extern fn raw_verify_with_data<T>(preverify_ok: c_int, - x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int { + x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int + where T: Reflect + 'static { unsafe { let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); @@ -352,7 +357,8 @@ impl SslContext { // a function handling it pub fn set_verify_with_data<T>(&mut self, mode: SslVerifyMode, verify: VerifyCallbackData<T>, - data: T) { + data: T) + where T: Reflect + 'static { let data = Box::new(data); unsafe { ffi::SSL_CTX_set_ex_data(*self.ctx, VERIFY_IDX, |