From 4dffa0c33fc1cc938bbf4fd3b654f7e6f3ce789a Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 16 Feb 2018 21:26:23 -0800 Subject: [PATCH 1/3] SSL session callbacks have always been around --- openssl-sys/src/lib.rs | 8 ++ openssl-sys/src/ossl10x.rs | 189 ++++++++++++++++++++++++----------- openssl-sys/src/ossl110.rs | 6 +- openssl/src/ssl/callbacks.rs | 6 +- openssl/src/ssl/mod.rs | 3 - openssl/src/ssl/test.rs | 5 +- 6 files changed, 142 insertions(+), 75 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index f9cfd0d4..bfd7d0d7 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -2466,6 +2466,14 @@ extern "C" { ctx: *mut SSL_CTX, dh: unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut DH, ); + pub fn SSL_CTX_sess_set_new_cb( + ctx: *mut SSL_CTX, + new_session_cb: Option c_int>, + ); + pub fn SSL_CTX_sess_set_remove_cb( + ctx: *mut SSL_CTX, + remove_session_cb: Option, + ); #[cfg(not(any(ossl101, libressl)))] pub fn SSL_CTX_get0_certificate(ctx: *const SSL_CTX) -> *mut X509; diff --git a/openssl-sys/src/ossl10x.rs b/openssl-sys/src/ossl10x.rs index 0abbd7d0..f8ff7193 100644 --- a/openssl-sys/src/ossl10x.rs +++ b/openssl-sys/src/ossl10x.rs @@ -263,9 +263,12 @@ pub struct X509 { crldp: *mut c_void, altname: *mut c_void, nc: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))] rfc3779_addr: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))] rfc3779_asid: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_SHA"))] sha1_hash: [c_uchar; 20], + #[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))] + rfc3779_addr: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))] + rfc3779_asid: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_SHA"))] + sha1_hash: [c_uchar; 20], aux: *mut c_void, } @@ -372,7 +375,8 @@ pub struct SSL { info_callback: Option, error: c_int, error_code: c_int, - #[cfg(not(osslconf = "OPENSSL_NO_KRB5"))] kssl_ctx: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_KRB5"))] + kssl_ctx: *mut c_void, #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] psk_client_callback: Option< unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_char, c_uint, *mut c_uchar, c_uint) @@ -396,16 +400,26 @@ pub struct SSL { #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_debug_cb: Option, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_debug_arg: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_hostname: *mut c_char, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] servername_done: c_int, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_status_type: c_int, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_status_expected: c_int, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_ocsp_ids: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_ocsp_exts: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_ocsp_resp: *mut c_uchar, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_ocsp_resplen: c_int, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_ticket_expected: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_debug_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_hostname: *mut c_char, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + servername_done: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_status_type: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_status_expected: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ocsp_ids: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ocsp_exts: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ocsp_resp: *mut c_uchar, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ocsp_resplen: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ticket_expected: c_int, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))] tlsext_ecpointformatlist_length: size_t, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))] @@ -414,28 +428,43 @@ pub struct SSL { tlsext_ellipticcurvelist_length: size_t, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))] tlsext_ellipticcurvelist: *mut c_uchar, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_opaque_prf_input: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_opaque_prf_input_len: size_t, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_session_ticket: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_opaque_prf_input: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_opaque_prf_input_len: size_t, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_session_ticket: *mut c_void, #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_session_ticket_ext_cb: ::tls_session_ticket_ext_cb_fn, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tls_session_ticket_ext_cb_arg: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tls_session_secret_cb: ::tls_session_secret_cb_fn, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tls_session_secret_cb_arg: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] initial_ctx: *mut ::SSL_CTX, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tls_session_ticket_ext_cb_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tls_session_secret_cb: ::tls_session_secret_cb_fn, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tls_session_secret_cb_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + initial_ctx: *mut ::SSL_CTX, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))] next_proto_negotiated: *mut c_uchar, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))] next_proto_negotiated_len: c_uchar, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] srtp_profiles: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] srtp_profile: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_heartbeat: c_uint, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_hb_pending: c_uint, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_hb_seq: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + srtp_profiles: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + srtp_profile: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_heartbeat: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_hb_pending: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_hb_seq: c_uint, renegotiate: c_int, - #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] srp_ctx: ::SRP_CTX, - #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] alpn_client_proto_list: *mut c_uchar, - #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] alpn_client_proto_list_len: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] + srp_ctx: ::SRP_CTX, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_client_proto_list: *mut c_uchar, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_client_proto_list_len: c_uint, } #[repr(C)] @@ -486,28 +515,46 @@ pub struct SSL_CTX { quiet_shutdown: c_int, max_send_fragment: c_uint, - #[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))] client_cert_engine: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))] + client_cert_engine: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_servername_callback: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsect_servername_arg: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_tick_key_name: [c_uchar; 16], - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_tick_hmac_key: [c_uchar; 16], - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_tick_aes_key: [c_uchar; 16], - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_ticket_key_cb: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_status_cb: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_status_arg: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_opaque_prf_input_callback: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_opaque_prf_input_callback_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_servername_callback: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsect_servername_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick_key_name: [c_uchar; 16], + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick_hmac_key: [c_uchar; 16], + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick_aes_key: [c_uchar; 16], + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ticket_key_cb: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_status_cb: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_status_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_opaque_prf_input_callback: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_opaque_prf_input_callback_arg: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] psk_identity_hint: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] psk_client_callback: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] psk_server_callback: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_identity_hint: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_client_callback: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_server_callback: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] freelist_max_len: c_uint, - #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] wbuf_freelist: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] rbuf_freelist: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] + freelist_max_len: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] + wbuf_freelist: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] + rbuf_freelist: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] srp_ctx: SRP_CTX, + #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] + srp_ctx: SRP_CTX, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))] next_protos_advertised_cb: *mut c_void, @@ -518,13 +565,19 @@ pub struct SSL_CTX { #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_NEXTPROTONEG")))] next_proto_select_cb_arg: *mut c_void, - #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))] srtp_profiles: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))] + srtp_profiles: *mut c_void, - #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] srtp_profiles: *mut c_void, - #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] alpn_select_cb: *mut c_void, - #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] alpn_select_cb_arg: *mut c_void, - #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] alpn_client_proto_list: *mut c_void, - #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] alpn_client_proto_list_len: c_uint, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + srtp_profiles: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_select_cb: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_select_cb_arg: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_client_proto_list: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_client_proto_list_len: c_uint, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC"), ossl102))] tlsext_ecpointformatlist_length: size_t, @@ -547,11 +600,14 @@ pub struct SSL_SESSION { session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize], sid_ctx_length: c_uint, sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize], - #[cfg(not(osslconf = "OPENSSL_NO_KRB5"))] krb5_client_princ_len: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_KRB5"))] + krb5_client_princ_len: c_uint, #[cfg(not(osslconf = "OPENSSL_NO_KRB5"))] krb5_client_princ: [c_uchar; SSL_MAX_KRB5_PRINCIPAL_LENGTH as usize], - #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] psk_identity_hint: *mut c_char, - #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] psk_identity: *mut c_char, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_identity_hint: *mut c_char, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_identity: *mut c_char, not_resumable: c_int, sess_cert: *mut c_void, peer: *mut X509, @@ -566,7 +622,8 @@ pub struct SSL_SESSION { ex_data: ::CRYPTO_EX_DATA, prev: *mut c_void, next: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_hostname: *mut c_char, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_hostname: *mut c_char, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))] tlsext_ecpointformatlist_length: size_t, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))] @@ -575,10 +632,14 @@ pub struct SSL_SESSION { tlsext_ellipticcurvelist_length: size_t, #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), not(osslconf = "OPENSSL_NO_EC")))] tlsext_ellipticcurvelist: *mut c_uchar, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_tick: *mut c_uchar, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_ticklen: size_t, - #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] tlsext_tick_lifetime_hint: c_long, - #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] srp_username: *mut c_char, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick: *mut c_uchar, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ticklen: size_t, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick_lifetime_hint: c_long, + #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] + srp_username: *mut c_char, } #[repr(C)] @@ -830,6 +891,12 @@ extern "C" { ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int) -> *mut ::EC_KEY, ); + pub fn SSL_CTX_sess_set_get_cb( + ctx: *mut ::SSL_CTX, + get_session_cb: Option< + unsafe extern "C" fn(*mut ::SSL, *mut c_uchar, c_int, *mut c_int) -> *mut SSL_SESSION, + >, + ); pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME; pub fn X509_get_issuer_name(x: *mut ::X509) -> *mut ::X509_NAME; pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int; diff --git a/openssl-sys/src/ossl110.rs b/openssl-sys/src/ossl110.rs index 86f9223f..29462f30 100644 --- a/openssl-sys/src/ossl110.rs +++ b/openssl-sys/src/ossl110.rs @@ -206,9 +206,11 @@ 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( + pub fn SSL_CTX_sess_set_get_cb( ctx: *mut ::SSL_CTX, - new_session_cb: Option c_int>, + get_session_cb: Option< + unsafe extern "C" fn(*mut ::SSL, *const c_uchar, c_int, *mut c_int) -> *mut SSL_SESSION, + >, ); pub fn X509_getm_notAfter(x: *const ::X509) -> *mut ::ASN1_TIME; pub fn X509_getm_notBefore(x: *const ::X509) -> *mut ::ASN1_TIME; diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs index 0a38952b..b11cac7e 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,10 @@ 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, SslRef, SslSession}; #[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(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int @@ -279,7 +276,6 @@ where } } -#[cfg(any(all(feature = "v110", ossl110), all(feature = "v111", ossl111)))] pub unsafe extern "C" fn raw_new_session( ssl: *mut ffi::SSL, session: *mut ffi::SSL_SESSION, diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index a589d6a3..2b17641c 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(&mut self, callback: F) where F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, 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; From e5123d266b07976e3e8e2a42b3f6630e3b680fcb Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 16 Feb 2018 22:24:34 -0800 Subject: [PATCH 2/3] Bind remove and get session callbacks --- openssl/src/ssl/callbacks.rs | 50 +++++++++++++++++++++++++++++++++- openssl/src/ssl/mod.rs | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs index b11cac7e..0e7299e3 100644 --- a/openssl/src/ssl/callbacks.rs +++ b/openssl/src/ssl/callbacks.rs @@ -12,7 +12,8 @@ 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, SslSession}; +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; @@ -295,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( + 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::()); + 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( + ssl: *mut ffi::SSL, + data: DataPtr, + len: c_int, + copy: *mut c_int, +) -> *mut ffi::SSL_SESSION +where + F: Fn(&mut SslRef, &[u8]) -> Option + '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::()); + 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 2b17641c..98d982bb 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -1195,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(&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::(), + Box::into_raw(callback) as *mut _, + ); + ffi::SSL_CTX_sess_set_remove_cb( + self.as_ptr(), + Some(callbacks::raw_remove_session::), + ); + } + } + + /// 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(&mut self, callback: F) + where + F: Fn(&mut SslRef, &[u8]) -> Option + 'static + Sync + Send, + { + let callback = Box::new(callback); + ffi::SSL_CTX_set_ex_data( + self.as_ptr(), + get_callback_idx::(), + Box::into_raw(callback) as *mut _, + ); + ffi::SSL_CTX_sess_set_get_cb(self.as_ptr(), Some(callbacks::raw_get_session::)); + } + /// Sets the session caching mode use for connections made with the context. /// /// Returns the previous session caching mode. From 18b87e65e3ce0813a016e9ed5d18722577a2acc3 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 16 Feb 2018 22:28:38 -0800 Subject: [PATCH 3/3] Fix libressl --- openssl-sys/src/libressl/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openssl-sys/src/libressl/mod.rs b/openssl-sys/src/libressl/mod.rs index d460605f..8454a78a 100644 --- a/openssl-sys/src/libressl/mod.rs +++ b/openssl-sys/src/libressl/mod.rs @@ -267,7 +267,8 @@ pub struct X509 { crldp: *mut c_void, altname: *mut c_void, nc: *mut c_void, - #[cfg(not(osslconf = "OPENSSL_NO_SHA"))] sha1_hash: [c_uchar; 20], + #[cfg(not(osslconf = "OPENSSL_NO_SHA"))] + sha1_hash: [c_uchar; 20], aux: *mut c_void, } @@ -527,6 +528,12 @@ extern "C" { ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int) -> *mut ::EC_KEY, ); + pub fn SSL_CTX_sess_set_get_cb( + ctx: *mut ::SSL_CTX, + get_session_cb: Option< + unsafe extern "C" fn(*mut ::SSL, *mut c_uchar, c_int, *mut c_int) -> *mut SSL_SESSION, + >, + ); pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME; pub fn X509_get_issuer_name(x: *mut ::X509) -> *mut ::X509_NAME; pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;