aboutsummaryrefslogtreecommitdiff
path: root/openssl
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2016-06-13 21:47:02 +0200
committerJonas Schievink <[email protected]>2016-06-26 18:25:54 +0200
commitf0b4a032d5a6cdf3928318e113dcfd7e0ecf03f9 (patch)
treec72ab006de830f2cbcab2e479344bc928149268a /openssl
parentAdd PKey::private_key_from_pem_cb (diff)
downloadrust-openssl-f0b4a032d5a6cdf3928318e113dcfd7e0ecf03f9.tar.xz
rust-openssl-f0b4a032d5a6cdf3928318e113dcfd7e0ecf03f9.zip
Try to propagate callback panics
Diffstat (limited to 'openssl')
-rw-r--r--openssl/src/crypto/pkey.rs27
1 files changed, 21 insertions, 6 deletions
diff --git a/openssl/src/crypto/pkey.rs b/openssl/src/crypto/pkey.rs
index f59ee40a..8ae9aa20 100644
--- a/openssl/src/crypto/pkey.rs
+++ b/openssl/src/crypto/pkey.rs
@@ -1,9 +1,10 @@
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;
@@ -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 {
@@ -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));
@@ -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,