From 913267e68afec06b67abb5699eb7587e159b87b3 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 28 Feb 2019 19:48:10 -0800 Subject: [PATCH 1/3] Add SslCtx::{add,remove}_session --- openssl-sys/src/ssl.rs | 2 ++ openssl/src/ssl/mod.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/openssl-sys/src/ssl.rs b/openssl-sys/src/ssl.rs index 4976fcf7..ca2fbb44 100644 --- a/openssl-sys/src/ssl.rs +++ b/openssl-sys/src/ssl.rs @@ -930,6 +930,8 @@ extern "C" { pub fn SSL_SESSION_free(s: *mut SSL_SESSION); pub fn i2d_SSL_SESSION(s: *mut SSL_SESSION, pp: *mut *mut c_uchar) -> c_int; pub fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int; + pub fn SSL_CTX_add_session(ctx: *mut SSL_CTX, session: *mut SSL_SESSION) -> c_int; + pub fn SSL_CTX_remove_session(ctx: *mut SSL_CTX, session: *mut SSL_SESSION) -> c_int; pub fn d2i_SSL_SESSION( a: *mut *mut SSL_SESSION, pp: *mut *const c_uchar, diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 3731714a..b67c333b 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -1841,6 +1841,38 @@ impl SslContextRef { pub fn max_early_data(&self) -> u32 { unsafe { ffi::SSL_CTX_get_max_early_data(self.as_ptr()) } } + + /// Adds a session to the context's cache. + /// + /// Returns `true` if the session was successfully added to the cache, and `false` if it was already present. + /// + /// This corresponds to [`SSL_CTX_add_session`]. + /// + /// # Safety + /// + /// The caller of this method is responsible for ensuring that the session has never been used with another + /// `SslContext` than this one. + /// + /// [`SSL_CTX_add_session`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_remove_session.html + pub unsafe fn add_session(&self, session: &SslSessionRef) -> bool { + ffi::SSL_CTX_add_session(self.as_ptr(), session.as_ptr()) != 0 + } + + /// Removes a session from the context's cache and marks it as non-resumable. + /// + /// Returns `true` if the session was successfully found and removed, and `false` otherwise. + /// + /// This corresponds to [`SSL_CTX_remove_session`]. + /// + /// # Safety + /// + /// The caller of this method is responsible for ensuring that the session has never been used with another + /// `SslContext` than this one. + /// + /// [`SSL_CTX_remove_session`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_remove_session.html + pub unsafe fn remove_session(&self, session: &SslSessionRef) -> bool { + ffi::SSL_CTX_remove_session(self.as_ptr(), session.as_ptr()) != 0 + } } /// Information about the state of a cipher. From a16482f9729de00f1a6f1878dfdeb59d66fa3ce9 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 28 Feb 2019 22:08:48 -0800 Subject: [PATCH 2/3] Add session info accessors --- openssl-sys/src/ssl.rs | 5 +++++ openssl/src/ssl/mod.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/openssl-sys/src/ssl.rs b/openssl-sys/src/ssl.rs index ca2fbb44..2a4d44a4 100644 --- a/openssl-sys/src/ssl.rs +++ b/openssl-sys/src/ssl.rs @@ -919,6 +919,11 @@ extern "C" { pub fn SSL_state_string(ssl: *const SSL) -> *const c_char; pub fn SSL_state_string_long(ssl: *const SSL) -> *const c_char; + pub fn SSL_SESSION_get_time(s: *const SSL_SESSION) -> c_long; + pub fn SSL_SESSION_get_timeout(s: *const SSL_SESSION) -> c_long; + #[cfg(ossl110)] + pub fn SSL_SESSION_get_protocol_version(s: *const SSL_SESSION) -> c_int; + #[cfg(ossl111)] pub fn SSL_SESSION_set_max_early_data(ctx: *mut SSL_SESSION, max_early_data: u32) -> c_int; #[cfg(ossl111)] diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index b67c333b..dfdc2cee 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -2129,6 +2129,41 @@ impl SslSessionRef { unsafe { ffi::SSL_SESSION_get_max_early_data(self.as_ptr()) } } + /// Returns the time at which the session was established, in seconds since the Unix epoch. + /// + /// This corresponds to [`SSL_SESSION_get_time`]. + /// + /// [`SSL_SESSION_get_time`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_time.html + pub fn time(&self) -> i64 { + unsafe { ffi::SSL_SESSION_get_time(self.as_ptr()) as i64 } + } + + /// Returns the sessions timeout, in seconds. + /// + /// A session older than this time should not be used for session resumption. + /// + /// This corresponds to [`SSL_SESSION_get_timeout`]. + /// + /// [`SSL_SESSION_get_timeout`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_time.html + pub fn timeout(&self) -> i64 { + unsafe { ffi::SSL_SESSION_get_timeout(self.as_ptr()) as i64 } + } + + /// Returns the session's TLS protocol version. + /// + /// Requires OpenSSL 1.1.0 or newer. + /// + /// This corresponds to [`SSL_SESSION_get_protocol_version`]. + /// + /// [`SSL_SESSION_get_protocol_version`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_time.html + #[cfg(ossl110)] + pub fn protocol_version(&self) -> SslVersion { + unsafe { + let version = ffi::SSL_SESSION_get_protocol_version(self.as_ptr()); + SslVersion(version) + } + } + to_der! { /// Serializes the session into a DER-encoded structure. /// From 404b7f1790995ddc620c4924516a9fbe338b7c2d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 1 Mar 2019 10:06:11 -0800 Subject: [PATCH 3/3] Add session cache size accessors --- openssl-sys/src/ssl.rs | 10 ++++++++++ openssl/src/ssl/mod.rs | 22 ++++++++++++++++++++++ openssl/src/ssl/test.rs | 8 ++++++++ 3 files changed, 40 insertions(+) diff --git a/openssl-sys/src/ssl.rs b/openssl-sys/src/ssl.rs index 2a4d44a4..fcbac300 100644 --- a/openssl-sys/src/ssl.rs +++ b/openssl-sys/src/ssl.rs @@ -697,6 +697,8 @@ pub const SSL_CTRL_EXTRA_CHAIN_CERT: c_int = 14; pub const SSL_CTRL_OPTIONS: c_int = 32; pub const SSL_CTRL_MODE: c_int = 33; pub const SSL_CTRL_SET_READ_AHEAD: c_int = 41; +pub const SSL_CTRL_SET_SESS_CACHE_SIZE: c_int = 42; +pub const SSL_CTRL_GET_SESS_CACHE_SIZE: c_int = 43; pub const SSL_CTRL_SET_SESS_CACHE_MODE: c_int = 44; pub const SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: c_int = 53; pub const SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: c_int = 54; @@ -1224,6 +1226,14 @@ extern "C" { pub fn SSL_get_ex_data_X509_STORE_CTX_idx() -> c_int; } +pub unsafe fn SSL_CTX_sess_set_cache_size(ctx: *mut SSL_CTX, t: c_long) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_SIZE, t, ptr::null_mut()) +} + +pub unsafe fn SSL_CTX_sess_get_cache_size(ctx: *mut SSL_CTX) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_SESS_CACHE_SIZE, 0, ptr::null_mut()) +} + pub unsafe fn SSL_CTX_set_session_cache_mode(ctx: *mut SSL_CTX, m: c_long) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_MODE, m, ptr::null_mut()) } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index dfdc2cee..134ac5a8 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -1675,6 +1675,17 @@ impl SslContextBuilder { } } + /// Sets the context's session cache size limit, returning the previous limit. + /// + /// A value of 0 means that the cache size is unbounded. + /// + /// This corresponds to [`SSL_CTX_sess_get_cache_size`]. + /// + /// [`SSL_CTX_sess_get_cache_size`]: https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_sess_set_cache_size.html + pub fn set_session_cache_size(&mut self, size: i32) -> i64 { + unsafe { ffi::SSL_CTX_sess_set_cache_size(self.as_ptr(), size.into()).into() } + } + /// Consumes the builder, returning a new `SslContext`. pub fn build(self) -> SslContext { self.0 @@ -1873,6 +1884,17 @@ impl SslContextRef { pub unsafe fn remove_session(&self, session: &SslSessionRef) -> bool { ffi::SSL_CTX_remove_session(self.as_ptr(), session.as_ptr()) != 0 } + + /// Returns the context's session cache size limit. + /// + /// A value of 0 means that the cache size is unbounded. + /// + /// This corresponds to [`SSL_CTX_sess_get_cache_size`]. + /// + /// [`SSL_CTX_sess_get_cache_size`]: https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_sess_set_cache_size.html + pub fn session_cache_size(&self) -> i64 { + unsafe { ffi::SSL_CTX_sess_get_cache_size(self.as_ptr()).into() } + } } /// Information about the state of a cipher. diff --git a/openssl/src/ssl/test.rs b/openssl/src/ssl/test.rs index 2b515af4..84c219fd 100644 --- a/openssl/src/ssl/test.rs +++ b/openssl/src/ssl/test.rs @@ -1849,3 +1849,11 @@ fn openssl_cipher_name() { assert_eq!(super::cipher_name("asdf"), "(NONE)"); } + +#[test] +fn session_cache_size() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_session_cache_size(1234); + let ctx = ctx.build(); + assert_eq!(ctx.session_cache_size(), 1234); +}