diff options
| author | Steven Fackler <[email protected]> | 2017-07-04 18:19:17 -1000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2017-07-04 18:19:17 -1000 |
| commit | 279bffccf54484512a44dbf0d27d97846ff43fac (patch) | |
| tree | 39d5866f8a10f334557982afae79d975e41fd283 /openssl/src | |
| parent | Merge pull request #655 from ltratt/master (diff) | |
| parent | Make some changes for review comments (diff) | |
| download | rust-openssl-279bffccf54484512a44dbf0d27d97846ff43fac.tar.xz rust-openssl-279bffccf54484512a44dbf0d27d97846ff43fac.zip | |
Merge pull request #641 from luser/psk
Expose PSK via a SslContextBuilder::set_psk_callback method
Diffstat (limited to 'openssl/src')
| -rw-r--r-- | openssl/src/ssl/mod.rs | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index e30def2d..8dd2b455 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -73,7 +73,7 @@ use ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_int, c_void, c_long, c_ulong}; -use libc::{c_uchar, c_uint}; +use libc::{c_char, c_uchar, c_uint}; use std::any::Any; use std::any::TypeId; use std::borrow::Borrow; @@ -317,6 +317,36 @@ extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_ } } +#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] +extern "C" fn raw_psk<F>(ssl: *mut ffi::SSL, + hint: *const c_char, + identity: *mut c_char, + max_identity_len: c_uint, + psk: *mut c_uchar, + max_psk_len: c_uint) -> c_uint + where F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result<usize, ErrorStack> + Any + 'static + Sync + Send +{ + unsafe { + let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _); + let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_callback_idx::<F>()); + let ssl = SslRef::from_ptr_mut(ssl); + let callback = &*(callback as *mut F); + let hint = if hint != ptr::null() { + Some(CStr::from_ptr(hint).to_bytes()) + } else { + None + }; + // Give the callback mutable slices into which it can write the identity and psk. + let identity_sl = slice::from_raw_parts_mut(identity as *mut u8, + max_identity_len as usize); + let psk_sl = slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize); + match callback(ssl, hint, identity_sl, psk_sl) { + Ok(psk_len) => psk_len as u32, + _ => 0, + } + } +} + extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send { @@ -987,6 +1017,24 @@ impl SslContextBuilder { } } + /// Sets the callback for providing an identity and pre-shared key for a TLS-PSK client. + /// + /// The callback will be called with the SSL context, an identity hint if one was provided + /// by the server, a mut slice for each of the identity and pre-shared key bytes. The identity + /// must be written as a null-terminated C string. + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + pub fn set_psk_callback<F>(&mut self, callback: F) + where F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result<usize, ErrorStack> + Any + 'static + Sync + Send + { + unsafe { + let callback = Box::new(callback); + ffi::SSL_CTX_set_ex_data(self.as_ptr(), + get_callback_idx::<F>(), + mem::transmute(callback)); + ffi::SSL_CTX_set_psk_client_callback(self.as_ptr(), Some(raw_psk::<F>)) + } + } + pub fn build(self) -> SslContext { let ctx = SslContext(self.0); mem::forget(self); |