aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2018-02-16 22:37:14 -0800
committerGitHub <[email protected]>2018-02-16 22:37:14 -0800
commitb1e7bf4d54365bd53a19992f4089153b0d3b76a8 (patch)
treefcc78f8952afb73d53450ae62ae3c5142428785b /openssl/src
parentMerge pull request #842 from nyradr/Documentation_fix_openssl_symm (diff)
parentFix libressl (diff)
downloadrust-openssl-b1e7bf4d54365bd53a19992f4089153b0d3b76a8.tar.xz
rust-openssl-b1e7bf4d54365bd53a19992f4089153b0d3b76a8.zip
Merge pull request #843 from sfackler/session-callback-2
Session callback 2
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/ssl/callbacks.rs54
-rw-r--r--openssl/src/ssl/mod.rs55
-rw-r--r--openssl/src/ssl/test.rs5
3 files changed, 102 insertions, 12 deletions
diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs
index 0a38952b..0e7299e3 100644
--- a/openssl/src/ssl/callbacks.rs
+++ b/openssl/src/ssl/callbacks.rs
@@ -5,7 +5,6 @@ use std::ptr;
use std::slice;
use std::mem;
use foreign_types::ForeignTypeRef;
-#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))]
use foreign_types::ForeignType;
use error::ErrorStack;
@@ -13,12 +12,11 @@ use dh::Dh;
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
use ec::EcKey;
use pkey::Params;
-use ssl::{get_callback_idx, get_ssl_callback_idx, SniError, SslAlert, SslRef};
+use ssl::{get_callback_idx, get_ssl_callback_idx, SniError, SslAlert, SslContextRef, SslRef,
+ SslSession, SslSessionRef};
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110),
all(feature = "v111", ossl111)))]
use ssl::AlpnError;
-#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))]
-use ssl::SslSession;
use x509::X509StoreContextRef;
pub extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
@@ -279,7 +277,6 @@ where
}
}
-#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))]
pub unsafe extern "C" fn raw_new_session<F>(
ssl: *mut ffi::SSL,
session: *mut ffi::SSL_SESSION,
@@ -299,3 +296,50 @@ where
// the return code doesn't indicate error vs success, but whether or not we consumed the session
1
}
+
+pub unsafe extern "C" fn raw_remove_session<F>(
+ ctx: *mut ffi::SSL_CTX,
+ session: *mut ffi::SSL_SESSION,
+) where
+ F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send,
+{
+ let callback = ffi::SSL_CTX_get_ex_data(ctx, get_callback_idx::<F>());
+ let callback = &*(callback as *mut F);
+
+ let ctx = SslContextRef::from_ptr(ctx);
+ let session = SslSessionRef::from_ptr(session);
+
+ callback(ctx, session)
+}
+
+#[cfg(any(ossl110, ossl111))]
+type DataPtr = *const c_uchar;
+#[cfg(not(any(ossl110, ossl111)))]
+type DataPtr = *mut c_uchar;
+
+pub unsafe extern "C" fn raw_get_session<F>(
+ ssl: *mut ffi::SSL,
+ data: DataPtr,
+ len: c_int,
+ copy: *mut c_int,
+) -> *mut ffi::SSL_SESSION
+where
+ F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send,
+{
+ let ctx = ffi::SSL_get_SSL_CTX(ssl as *const _);
+ let callback = ffi::SSL_CTX_get_ex_data(ctx, get_callback_idx::<F>());
+ let callback = &*(callback as *mut F);
+
+ let ssl = SslRef::from_ptr_mut(ssl);
+ let data = slice::from_raw_parts(data as *const u8, len as usize);
+
+ match callback(ssl, data) {
+ Some(session) => {
+ let p = session.as_ptr();
+ mem::forget(p);
+ *copy = 0;
+ p
+ }
+ None => ptr::null_mut(),
+ }
+}
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index a589d6a3..98d982bb 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -1177,12 +1177,9 @@ impl SslContextBuilder {
///
/// This corresponds to [`SSL_CTX_sess_set_new_cb`].
///
- /// Requires OpenSSL 1.1.0 or 1.1.1 and the corresponding Cargo feature.
- ///
/// [`SslRef::session`]: struct.SslRef.html#method.session
/// [`set_session_cache_mode`]: #method.set_session_cache_mode
/// [`SSL_CTX_sess_set_new_cb`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_new_cb.html
- #[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))]
pub fn set_new_session_callback<F>(&mut self, callback: F)
where
F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send,
@@ -1198,6 +1195,58 @@ impl SslContextBuilder {
}
}
+ /// Sets the callback which is called when sessions are removed from the context.
+ ///
+ /// Sessions can be removed because they have timed out or because they are considered faulty.
+ ///
+ /// This corresponds to [`SSL_CTX_sess_set_remove_cb`].
+ ///
+ /// [`SSL_CTX_sess_set_remove_cb`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_new_cb.html
+ pub fn set_remove_session_callback<F>(&mut self, callback: F)
+ where
+ F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send,
+ {
+ unsafe {
+ let callback = Box::new(callback);
+ ffi::SSL_CTX_set_ex_data(
+ self.as_ptr(),
+ get_callback_idx::<F>(),
+ Box::into_raw(callback) as *mut _,
+ );
+ ffi::SSL_CTX_sess_set_remove_cb(
+ self.as_ptr(),
+ Some(callbacks::raw_remove_session::<F>),
+ );
+ }
+ }
+
+ /// Sets the callback which is called when a client proposed to resume a session but it was not
+ /// found in the internal cache.
+ ///
+ /// The callback is passed a reference to the session ID provided by the client. It should
+ /// return the session corresponding to that ID if available. This is only used for servers, not
+ /// clients.
+ ///
+ /// This corresponds to [`SSL_CTX_sess_set_get_cb`].
+ ///
+ /// # Safety
+ ///
+ /// The returned `SslSession` must not be associated with a different `SslContext`.
+ ///
+ /// [`SSL_CTX_sess_set_get_cb`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_sess_set_new_cb.html
+ pub unsafe fn set_get_session_callback<F>(&mut self, callback: F)
+ where
+ F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send,
+ {
+ let callback = Box::new(callback);
+ ffi::SSL_CTX_set_ex_data(
+ self.as_ptr(),
+ get_callback_idx::<F>(),
+ Box::into_raw(callback) as *mut _,
+ );
+ ffi::SSL_CTX_sess_set_get_cb(self.as_ptr(), Some(callbacks::raw_get_session::<F>));
+ }
+
/// Sets the session caching mode use for connections made with the context.
///
/// Returns the previous session caching mode.
diff --git a/openssl/src/ssl/test.rs b/openssl/src/ssl/test.rs
index 17bc37d9..1913d835 100644
--- a/openssl/src/ssl/test.rs
+++ b/openssl/src/ssl/test.rs
@@ -19,9 +19,7 @@ use hash::MessageDigest;
use ocsp::{OcspResponse, OcspResponseStatus};
use ssl;
use ssl::{Error, HandshakeError, ShutdownResult, Ssl, SslAcceptor, SslConnector, SslContext,
- SslFiletype, SslMethod, SslStream, SslVerifyMode, StatusType};
-#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))]
-use ssl::SslSessionCacheMode;
+ SslFiletype, SslMethod, SslSessionCacheMode, SslStream, SslVerifyMode, StatusType};
use x509::{X509, X509Name, X509StoreContext, X509VerifyResult};
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110),
all(feature = "v111", ossl111)))]
@@ -1248,7 +1246,6 @@ fn status_callbacks() {
}
#[test]
-#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))]
fn new_session_callback() {
static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT;