aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2015-03-29 10:18:30 -0700
committerSteven Fackler <[email protected]>2015-03-29 10:18:30 -0700
commit2b1a9a7814293d50829a60d42f4e8f2ea0353bd7 (patch)
tree036c0d00d49c85bfdc9a8e320ec7e1dd63a8b04f
parentMerge pull request #191 from fhartwig/rustup (diff)
downloadrust-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
-rw-r--r--openssl/Cargo.toml5
-rw-r--r--openssl/src/lib.rs9
-rw-r--r--openssl/src/ssl/mod.rs38
3 files changed, 29 insertions, 23 deletions
diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml
index 6ba69781..8bfc8aca 100644
--- a/openssl/Cargo.toml
+++ b/openssl/Cargo.toml
@@ -21,10 +21,9 @@ path = "../openssl-sys"
version = "0.5.2"
[dependencies]
+bitflags = "0.1.1"
+lazy_static = "0.1"
libc = "0.1"
[dev-dependencies]
rustc-serialize = "0.3"
-
-[dependencies]
-bitflags = "0.1.1"
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,