Loading openssl/src/crypto/pkey.rs +21 −6 Original line number Diff line number Diff line use libc::{c_int, c_uint, c_ulong, c_char, c_void}; use std::any::Any; use std::io; use std::io::prelude::*; use std::iter::repeat; use std::mem; use std::panic::catch_unwind; use std::panic; use std::ptr; use std::slice; use bio::MemBio; Loading Loading @@ -100,21 +101,26 @@ impl PKey { /// /// The callback will be passed the password buffer and should return the number of characters /// placed into the buffer. pub fn private_key_from_pem_cb<R, F>(reader: &mut R, mut pass_cb: F) -> Result<PKey, SslError> pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> Result<PKey, SslError> where R: Read, F: FnMut(&mut [i8]) -> usize { struct CallbackState<F: FnMut(&mut [i8]) -> usize> { cb: F, panic: Option<Box<Any + Send + 'static>>, } extern "C" fn user_cb_wrapper<F>(buf: *mut c_char, size: c_int, _rwflag: c_int, user_cb: *mut c_void) -> c_int where F: FnMut(&mut [i8]) -> usize { let result = catch_unwind(|| { 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 *(user_cb as *mut F) }; let callback = unsafe { &mut *(user_cb as *mut CallbackState<F>) }; callback(pass_slice) (callback.cb)(pass_slice) }); if let Ok(len) = result { Loading @@ -124,6 +130,11 @@ impl PKey { } } let mut cb = CallbackState { cb: pass_cb, panic: None, }; let mut mem_bio = try!(MemBio::new()); try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); Loading @@ -131,7 +142,11 @@ impl PKey { let evp = try_ssl_null!(ffi::PEM_read_bio_PrivateKey(mem_bio.get_handle(), ptr::null_mut(), Some(user_cb_wrapper::<F>), &mut pass_cb as *mut _ as *mut c_void)); &mut cb as *mut _ as *mut c_void)); if let Some(panic) = cb.panic { panic::resume_unwind(panic); } Ok(PKey { evp: evp as *mut ffi::EVP_PKEY, Loading Loading
openssl/src/crypto/pkey.rs +21 −6 Original line number Diff line number Diff line use libc::{c_int, c_uint, c_ulong, c_char, c_void}; use std::any::Any; use std::io; use std::io::prelude::*; use std::iter::repeat; use std::mem; use std::panic::catch_unwind; use std::panic; use std::ptr; use std::slice; use bio::MemBio; Loading Loading @@ -100,21 +101,26 @@ impl PKey { /// /// The callback will be passed the password buffer and should return the number of characters /// placed into the buffer. pub fn private_key_from_pem_cb<R, F>(reader: &mut R, mut pass_cb: F) -> Result<PKey, SslError> pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> Result<PKey, SslError> where R: Read, F: FnMut(&mut [i8]) -> usize { struct CallbackState<F: FnMut(&mut [i8]) -> usize> { cb: F, panic: Option<Box<Any + Send + 'static>>, } extern "C" fn user_cb_wrapper<F>(buf: *mut c_char, size: c_int, _rwflag: c_int, user_cb: *mut c_void) -> c_int where F: FnMut(&mut [i8]) -> usize { let result = catch_unwind(|| { 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 *(user_cb as *mut F) }; let callback = unsafe { &mut *(user_cb as *mut CallbackState<F>) }; callback(pass_slice) (callback.cb)(pass_slice) }); if let Ok(len) = result { Loading @@ -124,6 +130,11 @@ impl PKey { } } let mut cb = CallbackState { cb: pass_cb, panic: None, }; let mut mem_bio = try!(MemBio::new()); try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); Loading @@ -131,7 +142,11 @@ impl PKey { let evp = try_ssl_null!(ffi::PEM_read_bio_PrivateKey(mem_bio.get_handle(), ptr::null_mut(), Some(user_cb_wrapper::<F>), &mut pass_cb as *mut _ as *mut c_void)); &mut cb as *mut _ as *mut c_void)); if let Some(panic) = cb.panic { panic::resume_unwind(panic); } Ok(PKey { evp: evp as *mut ffi::EVP_PKEY, Loading