Loading openssl-sys/src/lib.rs +16 −0 Original line number Diff line number Diff line Loading @@ -1206,6 +1206,7 @@ pub const SSL_CTRL_SET_TMP_ECDH: c_int = 4; pub const SSL_CTRL_EXTRA_CHAIN_CERT: c_int = 14; 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_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; pub const SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55; Loading Loading @@ -1296,6 +1297,16 @@ pub const SSL_OP_NO_SSL_MASK: c_ulong = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_ pub const SSL_FILETYPE_PEM: c_int = X509_FILETYPE_PEM; pub const SSL_FILETYPE_ASN1: c_int = X509_FILETYPE_ASN1; pub const SSL_SESS_CACHE_OFF: c_long = 0; pub const SSL_SESS_CACHE_CLIENT: c_long = 0x1; pub const SSL_SESS_CACHE_SERVER: c_long = 0x2; pub const SSL_SESS_CACHE_BOTH: c_long = SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER; pub const SSL_SESS_CACHE_NO_AUTO_CLEAR: c_long = 0x80; pub const SSL_SESS_CACHE_NO_INTERNAL_LOOKUP: c_long = 0x100; pub const SSL_SESS_CACHE_NO_INTERNAL_STORE: c_long = 0x200; pub const SSL_SESS_CACHE_NO_INTERNAL: c_long = SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE; pub const TLSEXT_NAMETYPE_host_name: c_int = 0; pub const TLSEXT_STATUSTYPE_ocsp: c_int = 1; Loading Loading @@ -1530,6 +1541,10 @@ pub unsafe fn SSL_CTX_get_extra_chain_certs( SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 0, chain as *mut c_void) } 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()) } pub unsafe fn SSL_get_tlsext_status_ocsp_resp(ssl: *mut SSL, resp: *mut *mut c_uchar) -> c_long { SSL_ctrl( ssl, Loading Loading @@ -2489,6 +2504,7 @@ extern "C" { -> c_uint, >, ); pub fn SSL_select_next_proto( out: *mut *mut c_uchar, outlen: *mut c_uchar, Loading openssl-sys/src/ossl110.rs +5 −0 Original line number Diff line number Diff line Loading @@ -206,6 +206,10 @@ extern "C" { pub fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong; pub fn SSL_CTX_set_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong; pub fn SSL_CTX_clear_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong; pub fn SSL_CTX_sess_set_new_cb( ctx: *mut ::SSL_CTX, new_session_cb: Option<unsafe extern "C" fn(*mut ::SSL, *mut ::SSL_SESSION) -> c_int>, ); pub fn X509_getm_notAfter(x: *const ::X509) -> *mut ::ASN1_TIME; pub fn X509_getm_notBefore(x: *const ::X509) -> *mut ::ASN1_TIME; pub fn X509_get0_signature( Loading @@ -224,6 +228,7 @@ extern "C" { pub fn BIO_get_data(a: *mut ::BIO) -> *mut c_void; pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut ::BIO_METHOD; pub fn BIO_meth_free(biom: *mut ::BIO_METHOD); // FIXME should wrap in Option pub fn BIO_meth_set_write( biom: *mut ::BIO_METHOD, write: unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int, Loading openssl/src/ssl/callbacks.rs +25 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,8 @@ 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; use dh::Dh; Loading @@ -15,6 +17,8 @@ use ssl::{get_callback_idx, get_ssl_callback_idx, SniError, SslAlert, SslRef}; #[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 Loading Loading @@ -274,3 +278,24 @@ 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, ) -> c_int where F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, { 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 callback = &*(callback as *mut F); let ssl = SslRef::from_ptr_mut(ssl); let session = SslSession::from_ptr(session); callback(ssl, session); // the return code doesn't indicate error vs success, but whether or not we consumed the session 1 } openssl/src/ssl/mod.rs +87 −3 Original line number Diff line number Diff line Loading @@ -305,19 +305,55 @@ bitflags! { /// Verifies that the peer's certificate is trusted. /// /// On the server side, this will cause OpenSSL to request a certificate from the client. const PEER = ::ffi::SSL_VERIFY_PEER; const PEER = ffi::SSL_VERIFY_PEER; /// Disables verification of the peer's certificate. /// /// On the server side, this will cause OpenSSL to not request a certificate from the /// client. On the client side, the certificate will be checked for validity, but the /// negotiation will continue regardless of the result of that check. const NONE = ::ffi::SSL_VERIFY_NONE; const NONE = ffi::SSL_VERIFY_NONE; /// On the server side, abort the handshake if the client did not send a certificate. /// /// This should be paired with `SSL_VERIFY_PEER`. It has no effect on the client side. const FAIL_IF_NO_PEER_CERT = ::ffi::SSL_VERIFY_FAIL_IF_NO_PEER_CERT; const FAIL_IF_NO_PEER_CERT = ffi::SSL_VERIFY_FAIL_IF_NO_PEER_CERT; } } bitflags! { /// Options controlling the behavior of session caching. pub struct SslSessionCacheMode: c_long { /// No session caching for the client or server takes place. const OFF = ffi::SSL_SESS_CACHE_OFF; /// Enable session caching on the client side. /// /// OpenSSL has no way of identifying the proper session to reuse automatically, so the /// application is responsible for setting it explicitly via [`SslRef::set_session`]. /// /// [`SslRef::set_session`]: struct.SslRef.html#method.set_session const CLIENT = ffi::SSL_SESS_CACHE_CLIENT; /// Enable session caching on the server side. /// /// This is the default mode. const SERVER = ffi::SSL_SESS_CACHE_SERVER; /// Enable session caching on both the client and server side. const BOTH = ffi::SSL_SESS_CACHE_BOTH; /// Disable automatic removal of expired sessions from the session cache. const NO_AUTO_CLEAR = ffi::SSL_SESS_CACHE_NO_AUTO_CLEAR; /// Disable use of the internal session cache for session lookups. const NO_INTERNAL_LOOKUP = ffi::SSL_SESS_CACHE_NO_INTERNAL_LOOKUP; /// Disable use of the internal session cache for session storage. const NO_INTERNAL_STORE = ffi::SSL_SESS_CACHE_NO_INTERNAL_STORE; /// Disable use of the internal session cache for storage and lookup. const NO_INTERNAL = ffi::SSL_SESS_CACHE_NO_INTERNAL; } } Loading Loading @@ -1128,6 +1164,54 @@ impl SslContextBuilder { } } /// Sets the callback which is called when new sessions are negotiated. /// /// This can be used by clients to implement session caching. While in TLSv1.2 the session is /// available to access via [`SslRef::session`] immediately after the handshake completes, this /// is not the case for TLSv1.3. There, a session is not generally available immediately, and /// the server may provide multiple session tokens to the client over a single session. The new /// session callback is a portable way to deal with both cases. /// /// Note that session caching must be enabled for the callback to be invoked, and it defaults /// off for clients. [`set_session_cache_mode`] controls that behavior. /// /// 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, { 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_new_cb(self.as_ptr(), Some(callbacks::raw_new_session::<F>)); } } /// Sets the session caching mode use for connections made with the context. /// /// Returns the previous session caching mode. /// /// This corresponds to [`SSL_CTX_set_session_cache_mode`]. /// /// [`SSL_CTX_set_session_cache_mode`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_get_session_cache_mode.html pub fn set_session_cache_mode(&mut self, mode: SslSessionCacheMode) -> SslSessionCacheMode { unsafe { let bits = ffi::SSL_CTX_set_session_cache_mode(self.as_ptr(), mode.bits()); SslSessionCacheMode { bits } } } /// Sets the extra data at the specified index. /// /// This can be used to provide data to callbacks registered with the context. Use the Loading openssl/src/ssl/test.rs +36 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ 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; use x509::{X509, X509Name, X509StoreContext, X509VerifyResult}; #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] Loading Loading @@ -1245,6 +1247,40 @@ fn status_callbacks() { guard.join().unwrap(); } #[test] #[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] fn new_session_callback() { static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { let stream = listener.accept().unwrap().0; let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) .unwrap(); ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) .unwrap(); ctx.set_session_id_context(b"foo").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_session_cache_mode(SslSessionCacheMode::CLIENT | SslSessionCacheMode::NO_INTERNAL); ctx.set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); let ssl = Ssl::new(&ctx.build()).unwrap(); let mut stream = ssl.connect(stream).unwrap(); // read 1 byte to make sure the session is received for TLSv1.3 let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); } fn _check_kinds() { fn is_send<T: Send>() {} fn is_sync<T: Sync>() {} Loading Loading
openssl-sys/src/lib.rs +16 −0 Original line number Diff line number Diff line Loading @@ -1206,6 +1206,7 @@ pub const SSL_CTRL_SET_TMP_ECDH: c_int = 4; pub const SSL_CTRL_EXTRA_CHAIN_CERT: c_int = 14; 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_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; pub const SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55; Loading Loading @@ -1296,6 +1297,16 @@ pub const SSL_OP_NO_SSL_MASK: c_ulong = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_ pub const SSL_FILETYPE_PEM: c_int = X509_FILETYPE_PEM; pub const SSL_FILETYPE_ASN1: c_int = X509_FILETYPE_ASN1; pub const SSL_SESS_CACHE_OFF: c_long = 0; pub const SSL_SESS_CACHE_CLIENT: c_long = 0x1; pub const SSL_SESS_CACHE_SERVER: c_long = 0x2; pub const SSL_SESS_CACHE_BOTH: c_long = SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER; pub const SSL_SESS_CACHE_NO_AUTO_CLEAR: c_long = 0x80; pub const SSL_SESS_CACHE_NO_INTERNAL_LOOKUP: c_long = 0x100; pub const SSL_SESS_CACHE_NO_INTERNAL_STORE: c_long = 0x200; pub const SSL_SESS_CACHE_NO_INTERNAL: c_long = SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE; pub const TLSEXT_NAMETYPE_host_name: c_int = 0; pub const TLSEXT_STATUSTYPE_ocsp: c_int = 1; Loading Loading @@ -1530,6 +1541,10 @@ pub unsafe fn SSL_CTX_get_extra_chain_certs( SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 0, chain as *mut c_void) } 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()) } pub unsafe fn SSL_get_tlsext_status_ocsp_resp(ssl: *mut SSL, resp: *mut *mut c_uchar) -> c_long { SSL_ctrl( ssl, Loading Loading @@ -2489,6 +2504,7 @@ extern "C" { -> c_uint, >, ); pub fn SSL_select_next_proto( out: *mut *mut c_uchar, outlen: *mut c_uchar, Loading
openssl-sys/src/ossl110.rs +5 −0 Original line number Diff line number Diff line Loading @@ -206,6 +206,10 @@ extern "C" { pub fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong; pub fn SSL_CTX_set_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong; pub fn SSL_CTX_clear_options(ctx: *mut ::SSL_CTX, op: c_ulong) -> c_ulong; pub fn SSL_CTX_sess_set_new_cb( ctx: *mut ::SSL_CTX, new_session_cb: Option<unsafe extern "C" fn(*mut ::SSL, *mut ::SSL_SESSION) -> c_int>, ); pub fn X509_getm_notAfter(x: *const ::X509) -> *mut ::ASN1_TIME; pub fn X509_getm_notBefore(x: *const ::X509) -> *mut ::ASN1_TIME; pub fn X509_get0_signature( Loading @@ -224,6 +228,7 @@ extern "C" { pub fn BIO_get_data(a: *mut ::BIO) -> *mut c_void; pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut ::BIO_METHOD; pub fn BIO_meth_free(biom: *mut ::BIO_METHOD); // FIXME should wrap in Option pub fn BIO_meth_set_write( biom: *mut ::BIO_METHOD, write: unsafe extern "C" fn(*mut ::BIO, *const c_char, c_int) -> c_int, Loading
openssl/src/ssl/callbacks.rs +25 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,8 @@ 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; use dh::Dh; Loading @@ -15,6 +17,8 @@ use ssl::{get_callback_idx, get_ssl_callback_idx, SniError, SslAlert, SslRef}; #[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 Loading Loading @@ -274,3 +278,24 @@ 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, ) -> c_int where F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, { 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 callback = &*(callback as *mut F); let ssl = SslRef::from_ptr_mut(ssl); let session = SslSession::from_ptr(session); callback(ssl, session); // the return code doesn't indicate error vs success, but whether or not we consumed the session 1 }
openssl/src/ssl/mod.rs +87 −3 Original line number Diff line number Diff line Loading @@ -305,19 +305,55 @@ bitflags! { /// Verifies that the peer's certificate is trusted. /// /// On the server side, this will cause OpenSSL to request a certificate from the client. const PEER = ::ffi::SSL_VERIFY_PEER; const PEER = ffi::SSL_VERIFY_PEER; /// Disables verification of the peer's certificate. /// /// On the server side, this will cause OpenSSL to not request a certificate from the /// client. On the client side, the certificate will be checked for validity, but the /// negotiation will continue regardless of the result of that check. const NONE = ::ffi::SSL_VERIFY_NONE; const NONE = ffi::SSL_VERIFY_NONE; /// On the server side, abort the handshake if the client did not send a certificate. /// /// This should be paired with `SSL_VERIFY_PEER`. It has no effect on the client side. const FAIL_IF_NO_PEER_CERT = ::ffi::SSL_VERIFY_FAIL_IF_NO_PEER_CERT; const FAIL_IF_NO_PEER_CERT = ffi::SSL_VERIFY_FAIL_IF_NO_PEER_CERT; } } bitflags! { /// Options controlling the behavior of session caching. pub struct SslSessionCacheMode: c_long { /// No session caching for the client or server takes place. const OFF = ffi::SSL_SESS_CACHE_OFF; /// Enable session caching on the client side. /// /// OpenSSL has no way of identifying the proper session to reuse automatically, so the /// application is responsible for setting it explicitly via [`SslRef::set_session`]. /// /// [`SslRef::set_session`]: struct.SslRef.html#method.set_session const CLIENT = ffi::SSL_SESS_CACHE_CLIENT; /// Enable session caching on the server side. /// /// This is the default mode. const SERVER = ffi::SSL_SESS_CACHE_SERVER; /// Enable session caching on both the client and server side. const BOTH = ffi::SSL_SESS_CACHE_BOTH; /// Disable automatic removal of expired sessions from the session cache. const NO_AUTO_CLEAR = ffi::SSL_SESS_CACHE_NO_AUTO_CLEAR; /// Disable use of the internal session cache for session lookups. const NO_INTERNAL_LOOKUP = ffi::SSL_SESS_CACHE_NO_INTERNAL_LOOKUP; /// Disable use of the internal session cache for session storage. const NO_INTERNAL_STORE = ffi::SSL_SESS_CACHE_NO_INTERNAL_STORE; /// Disable use of the internal session cache for storage and lookup. const NO_INTERNAL = ffi::SSL_SESS_CACHE_NO_INTERNAL; } } Loading Loading @@ -1128,6 +1164,54 @@ impl SslContextBuilder { } } /// Sets the callback which is called when new sessions are negotiated. /// /// This can be used by clients to implement session caching. While in TLSv1.2 the session is /// available to access via [`SslRef::session`] immediately after the handshake completes, this /// is not the case for TLSv1.3. There, a session is not generally available immediately, and /// the server may provide multiple session tokens to the client over a single session. The new /// session callback is a portable way to deal with both cases. /// /// Note that session caching must be enabled for the callback to be invoked, and it defaults /// off for clients. [`set_session_cache_mode`] controls that behavior. /// /// 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, { 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_new_cb(self.as_ptr(), Some(callbacks::raw_new_session::<F>)); } } /// Sets the session caching mode use for connections made with the context. /// /// Returns the previous session caching mode. /// /// This corresponds to [`SSL_CTX_set_session_cache_mode`]. /// /// [`SSL_CTX_set_session_cache_mode`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_get_session_cache_mode.html pub fn set_session_cache_mode(&mut self, mode: SslSessionCacheMode) -> SslSessionCacheMode { unsafe { let bits = ffi::SSL_CTX_set_session_cache_mode(self.as_ptr(), mode.bits()); SslSessionCacheMode { bits } } } /// Sets the extra data at the specified index. /// /// This can be used to provide data to callbacks registered with the context. Use the Loading
openssl/src/ssl/test.rs +36 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ 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; use x509::{X509, X509Name, X509StoreContext, X509VerifyResult}; #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] Loading Loading @@ -1245,6 +1247,40 @@ fn status_callbacks() { guard.join().unwrap(); } #[test] #[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] fn new_session_callback() { static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let port = listener.local_addr().unwrap().port(); thread::spawn(move || { let stream = listener.accept().unwrap().0; let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) .unwrap(); ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) .unwrap(); ctx.set_session_id_context(b"foo").unwrap(); let ssl = Ssl::new(&ctx.build()).unwrap(); let mut stream = ssl.accept(stream).unwrap(); stream.write_all(&[0]).unwrap(); }); let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); ctx.set_session_cache_mode(SslSessionCacheMode::CLIENT | SslSessionCacheMode::NO_INTERNAL); ctx.set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); let ssl = Ssl::new(&ctx.build()).unwrap(); let mut stream = ssl.connect(stream).unwrap(); // read 1 byte to make sure the session is received for TLSv1.3 let mut buf = [0]; stream.read_exact(&mut buf).unwrap(); assert!(CALLED_BACK.load(Ordering::SeqCst)); } fn _check_kinds() { fn is_send<T: Send>() {} fn is_sync<T: Sync>() {} Loading