From c4459c37d98b3a56723e6698852698fb2f354d47 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 18 Oct 2016 21:11:23 -0700 Subject: [PATCH] Callback cleanup --- openssl-sys/src/lib.rs | 24 ++++++++++----------- openssl/src/crypto/util.rs | 16 +++++++------- openssl/src/ssl/mod.rs | 43 ++++++++++++++------------------------ 3 files changed, 36 insertions(+), 47 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index ae38d1b3..aae2540c 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -78,19 +78,19 @@ pub type BN_ULONG = libc::c_ulonglong; #[cfg(target_pointer_width = "32")] pub type BN_ULONG = c_uint; -pub type CRYPTO_EX_new = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, - ad: *const CRYPTO_EX_DATA, idx: c_int, - argl: c_long, argp: *const c_void) -> c_int; -pub type CRYPTO_EX_dup = extern "C" fn(to: *mut CRYPTO_EX_DATA, - from: *mut CRYPTO_EX_DATA, from_d: *mut c_void, - idx: c_int, argl: c_long, argp: *mut c_void) - -> c_int; -pub type CRYPTO_EX_free = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, - ad: *mut CRYPTO_EX_DATA, idx: c_int, - argl: c_long, argp: *mut c_void); -pub type PasswordCallback = extern "C" fn(buf: *mut c_char, size: c_int, - rwflag: c_int, user_data: *mut c_void) +pub type CRYPTO_EX_new = unsafe extern fn(parent: *mut c_void, ptr: *mut c_void, + ad: *const CRYPTO_EX_DATA, idx: c_int, + argl: c_long, argp: *const c_void) -> c_int; +pub type CRYPTO_EX_dup = unsafe extern fn(to: *mut CRYPTO_EX_DATA, + from: *mut CRYPTO_EX_DATA, from_d: *mut c_void, + idx: c_int, argl: c_long, argp: *mut c_void) -> c_int; +pub type CRYPTO_EX_free = unsafe extern fn(parent: *mut c_void, ptr: *mut c_void, + ad: *mut CRYPTO_EX_DATA, idx: c_int, + argl: c_long, argp: *mut c_void); +pub type PasswordCallback = unsafe extern fn(buf: *mut c_char, size: c_int, + rwflag: c_int, user_data: *mut c_void) + -> c_int; pub const BIO_TYPE_NONE: c_int = 0; diff --git a/openssl/src/crypto/util.rs b/openssl/src/crypto/util.rs index c11285f8..07099b7c 100644 --- a/openssl/src/crypto/util.rs +++ b/openssl/src/crypto/util.rs @@ -36,16 +36,16 @@ impl Drop for CallbackState { /// Password callback function, passed to private key loading functions. /// /// `cb_state` is expected to be a pointer to a `CallbackState`. -pub extern "C" fn invoke_passwd_cb(buf: *mut c_char, - size: c_int, - _rwflag: c_int, - cb_state: *mut c_void) - -> c_int - where F: FnOnce(&mut [c_char]) -> usize { +pub unsafe extern fn invoke_passwd_cb(buf: *mut c_char, + size: c_int, + _rwflag: c_int, + cb_state: *mut c_void) + -> c_int + where F: FnOnce(&mut [c_char]) -> usize { let result = panic::catch_unwind(|| { // build a `i8` slice to pass to the user callback - let pass_slice = unsafe { slice::from_raw_parts_mut(buf, size as usize) }; - let callback = unsafe { &mut *(cb_state as *mut CallbackState) }; + let pass_slice = slice::from_raw_parts_mut(buf, size as usize); + let callback = &mut *(cb_state as *mut CallbackState); callback.cb.take().unwrap()(pass_slice) }); diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index cd7fe7b9..fafac45c 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -142,20 +142,20 @@ lazy_static! { static ref ALPN_PROTOS_IDX: c_int = get_new_idx::>(); } +unsafe extern fn free_data_box(_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() { + Box::::from_raw(ptr as *mut T); + } +} + /// Determine a new index to use for SSL CTX ex data. /// Registers a destruct for the data which will be called by openssl when the context is freed. fn get_new_idx() -> c_int { - extern fn free_data_box(_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() { - let _: Box = unsafe { mem::transmute(ptr) }; - } - } - unsafe { let idx = compat::get_new_idx(free_data_box::); assert!(idx >= 0); @@ -164,17 +164,6 @@ fn get_new_idx() -> c_int { } fn get_new_ssl_idx() -> c_int { - extern fn free_data_box(_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() { - let _: Box = unsafe { mem::transmute(ptr) }; - } - } - unsafe { let idx = compat::get_new_ssl_idx(free_data_box::); assert!(idx >= 0); @@ -190,7 +179,7 @@ extern fn raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _); let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::()); - let verify: &F = mem::transmute(verify); + let verify: &F = &*(verify as *mut F); let ctx = X509StoreContext::new(x509_ctx); @@ -206,7 +195,7 @@ extern fn ssl_raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_ let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_verify_data_idx::()); - let verify: &F = mem::transmute(verify); + let verify: &F = &*(verify as *mut F); let ctx = X509StoreContext::new(x509_ctx); @@ -220,7 +209,7 @@ extern fn raw_sni(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c unsafe { let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::()); - let callback: &F = mem::transmute(callback); + let callback: &F = &*(callback as *mut F); let mut ssl = SslRef::from_ptr(ssl); match callback(&mut ssl) { @@ -250,7 +239,7 @@ unsafe fn select_proto_using(ssl: *mut ffi::SSL, // extra data. let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let protocols = ffi::SSL_CTX_get_ex_data(ssl_ctx, ex_data); - let protocols: &Vec = mem::transmute(protocols); + let protocols: &Vec = &*(protocols as *mut Vec); // Prepare the client list parameters to be passed to the OpenSSL function... let client = protocols.as_ptr(); let client_len = protocols.len() as c_uint; @@ -313,7 +302,7 @@ extern fn raw_next_protos_advertise_cb(ssl: *mut ffi::SSL, } else { // If the pointer is valid, put the pointer to the actual byte array into the // output parameter `out`, as well as its length into `outlen`. - let protocols: &Vec = mem::transmute(protocols); + let protocols: &Vec = &*(protocols as *mut Vec); *out = protocols.as_ptr(); *outlen = protocols.len() as c_uint; }