diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 3890ea96..cc4b49d3 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1881,6 +1881,8 @@ extern "C" { pub fn ERR_func_error_string(err: c_ulong) -> *const c_char; pub fn ERR_reason_error_string(err: c_ulong) -> *const c_char; pub fn ERR_clear_error(); + pub fn ERR_put_error(lib: c_int, func: c_int, reason: c_int, file: *const c_char, line: c_int); + pub fn ERR_set_error_data(data: *mut c_char, flags: c_int); pub fn EVP_md5() -> *const EVP_MD; pub fn EVP_ripemd160() -> *const EVP_MD; diff --git a/openssl/src/error.rs b/openssl/src/error.rs index 30558912..7f3d472e 100644 --- a/openssl/src/error.rs +++ b/openssl/src/error.rs @@ -15,7 +15,7 @@ //! Err(e) => println!("Parsing Error: {:?}", e), //! } //! ``` -use libc::{c_char, c_ulong}; +use libc::{c_char, c_int, c_ulong}; use std::fmt; use std::error; use std::ffi::CStr; @@ -41,6 +41,13 @@ impl ErrorStack { } ErrorStack(vec) } + + /// Pushes the errors back onto the OpenSSL error stack. + pub fn put(&self) { + for error in self.errors() { + error.put(); + } + } } impl ErrorStack { @@ -87,7 +94,7 @@ impl From for fmt::Error { pub struct Error { code: c_ulong, file: *const c_char, - line: u32, + line: c_int, data: Option>, } @@ -124,7 +131,7 @@ impl Error { Some(Error { code, file, - line: line as u32, + line, data, }) } @@ -132,6 +139,40 @@ impl Error { } } + /// Pushes the error back onto the OpenSSL error stack. + pub fn put(&self) { + unsafe { + ffi::ERR_put_error( + ffi::ERR_GET_LIB(self.code), + ffi::ERR_GET_FUNC(self.code), + ffi::ERR_GET_REASON(self.code), + self.file, + self.line, + ); + let data = match self.data { + Some(Cow::Borrowed(data)) => Some((data.as_ptr() as *mut c_char, 0)), + Some(Cow::Owned(ref data)) => { + let ptr = ffi::CRYPTO_malloc( + (data.len() + 1) as _, + concat!(file!(), "\0").as_ptr() as _, + line!() as _, + ) as *mut c_char; + if ptr.is_null() { + None + } else { + ptr::copy_nonoverlapping(data.as_ptr(), ptr as *mut u8, data.len()); + *ptr.offset(data.len() as isize) = 0; + Some((ptr, ffi::ERR_TXT_MALLOCED)) + } + } + None => None, + }; + if let Some((ptr, flags)) = data { + ffi::ERR_set_error_data(ptr, flags | ffi::ERR_TXT_STRING); + } + } + } + /// Returns the raw OpenSSL error code for this error. pub fn code(&self) -> c_ulong { self.code @@ -184,7 +225,7 @@ impl Error { /// Returns the line in the source file which encountered the error. pub fn line(&self) -> u32 { - self.line + self.line as u32 } /// Returns additional data describing the error. diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs index 2fc43ac0..c06d32a0 100644 --- a/openssl/src/ssl/callbacks.rs +++ b/openssl/src/ssl/callbacks.rs @@ -162,8 +162,8 @@ where mem::forget(dh); ptr } - Err(_) => { - // FIXME reset error stack + Err(e) => { + e.put(); ptr::null_mut() } } @@ -189,8 +189,8 @@ where mem::forget(ec_key); ptr } - Err(_) => { - // FIXME reset error stack + Err(e) => { + e.put(); ptr::null_mut() } } @@ -214,8 +214,8 @@ where mem::forget(dh); ptr } - Err(_) => { - // FIXME reset error stack + Err(e) => { + e.put(); ptr::null_mut() } } @@ -240,8 +240,8 @@ where mem::forget(ec_key); ptr } - Err(_) => { - // FIXME reset error stack + Err(e) => { + e.put(); ptr::null_mut() } } @@ -262,8 +262,8 @@ where match ret { Ok(true) => ffi::SSL_TLSEXT_ERR_OK, Ok(false) => ffi::SSL_TLSEXT_ERR_NOACK, - Err(_) => { - // FIXME reset error stack + Err(e) => { + e.put(); ffi::SSL_TLSEXT_ERR_ALERT_FATAL } } @@ -271,8 +271,8 @@ where match ret { Ok(true) => 1, Ok(false) => 0, - Err(_) => { - // FIXME reset error stack + Err(e) => { + e.put(); -1 } }