aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2017-07-04 18:19:17 -1000
committerGitHub <[email protected]>2017-07-04 18:19:17 -1000
commit279bffccf54484512a44dbf0d27d97846ff43fac (patch)
tree39d5866f8a10f334557982afae79d975e41fd283 /openssl/src
parentMerge pull request #655 from ltratt/master (diff)
parentMake some changes for review comments (diff)
downloadrust-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.rs50
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);