192f3ab15Sopenharmony_ciuse cfg_if::cfg_if; 292f3ab15Sopenharmony_ciuse foreign_types::ForeignType; 392f3ab15Sopenharmony_ciuse foreign_types::ForeignTypeRef; 492f3ab15Sopenharmony_ci#[cfg(any(ossl111, not(osslconf = "OPENSSL_NO_PSK")))] 592f3ab15Sopenharmony_ciuse libc::c_char; 692f3ab15Sopenharmony_ci#[cfg(ossl111)] 792f3ab15Sopenharmony_ciuse libc::size_t; 892f3ab15Sopenharmony_ciuse libc::{c_int, c_uchar, c_uint, c_void}; 992f3ab15Sopenharmony_ci#[cfg(any(ossl111, not(osslconf = "OPENSSL_NO_PSK")))] 1092f3ab15Sopenharmony_ciuse std::ffi::CStr; 1192f3ab15Sopenharmony_ciuse std::mem; 1292f3ab15Sopenharmony_ciuse std::ptr; 1392f3ab15Sopenharmony_ciuse std::slice; 1492f3ab15Sopenharmony_ci#[cfg(ossl111)] 1592f3ab15Sopenharmony_ciuse std::str; 1692f3ab15Sopenharmony_ciuse std::sync::Arc; 1792f3ab15Sopenharmony_ci 1892f3ab15Sopenharmony_ciuse crate::dh::Dh; 1992f3ab15Sopenharmony_ci#[cfg(all(ossl101, not(ossl110)))] 2092f3ab15Sopenharmony_ciuse crate::ec::EcKey; 2192f3ab15Sopenharmony_ciuse crate::error::ErrorStack; 2292f3ab15Sopenharmony_ciuse crate::pkey::Params; 2392f3ab15Sopenharmony_ci#[cfg(any(ossl102, libressl261))] 2492f3ab15Sopenharmony_ciuse crate::ssl::AlpnError; 2592f3ab15Sopenharmony_ciuse crate::ssl::{ 2692f3ab15Sopenharmony_ci try_get_session_ctx_index, SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef, 2792f3ab15Sopenharmony_ci SslSession, SslSessionRef, 2892f3ab15Sopenharmony_ci}; 2992f3ab15Sopenharmony_ci#[cfg(ossl111)] 3092f3ab15Sopenharmony_ciuse crate::ssl::{ClientHelloResponse, ExtensionContext}; 3192f3ab15Sopenharmony_ci#[cfg(ossl111)] 3292f3ab15Sopenharmony_ciuse crate::util::ForeignTypeRefExt; 3392f3ab15Sopenharmony_ci#[cfg(ossl111)] 3492f3ab15Sopenharmony_ciuse crate::x509::X509Ref; 3592f3ab15Sopenharmony_ciuse crate::x509::{X509StoreContext, X509StoreContextRef}; 3692f3ab15Sopenharmony_ci 3792f3ab15Sopenharmony_cipub extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int 3892f3ab15Sopenharmony_ciwhere 3992f3ab15Sopenharmony_ci F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send, 4092f3ab15Sopenharmony_ci{ 4192f3ab15Sopenharmony_ci unsafe { 4292f3ab15Sopenharmony_ci let ctx = X509StoreContextRef::from_ptr_mut(x509_ctx); 4392f3ab15Sopenharmony_ci let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing"); 4492f3ab15Sopenharmony_ci let verify_idx = SslContext::cached_ex_index::<F>(); 4592f3ab15Sopenharmony_ci 4692f3ab15Sopenharmony_ci // raw pointer shenanigans to break the borrow of ctx 4792f3ab15Sopenharmony_ci // the callback can't mess with its own ex_data slot so this is safe 4892f3ab15Sopenharmony_ci let verify = ctx 4992f3ab15Sopenharmony_ci .ex_data(ssl_idx) 5092f3ab15Sopenharmony_ci .expect("BUG: store context missing ssl") 5192f3ab15Sopenharmony_ci .ssl_context() 5292f3ab15Sopenharmony_ci .ex_data(verify_idx) 5392f3ab15Sopenharmony_ci .expect("BUG: verify callback missing") as *const F; 5492f3ab15Sopenharmony_ci 5592f3ab15Sopenharmony_ci (*verify)(preverify_ok != 0, ctx) as c_int 5692f3ab15Sopenharmony_ci } 5792f3ab15Sopenharmony_ci} 5892f3ab15Sopenharmony_ci 5992f3ab15Sopenharmony_ci#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] 6092f3ab15Sopenharmony_cipub extern "C" fn raw_client_psk<F>( 6192f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 6292f3ab15Sopenharmony_ci hint: *const c_char, 6392f3ab15Sopenharmony_ci identity: *mut c_char, 6492f3ab15Sopenharmony_ci max_identity_len: c_uint, 6592f3ab15Sopenharmony_ci psk: *mut c_uchar, 6692f3ab15Sopenharmony_ci max_psk_len: c_uint, 6792f3ab15Sopenharmony_ci) -> c_uint 6892f3ab15Sopenharmony_ciwhere 6992f3ab15Sopenharmony_ci F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result<usize, ErrorStack> 7092f3ab15Sopenharmony_ci + 'static 7192f3ab15Sopenharmony_ci + Sync 7292f3ab15Sopenharmony_ci + Send, 7392f3ab15Sopenharmony_ci{ 7492f3ab15Sopenharmony_ci unsafe { 7592f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 7692f3ab15Sopenharmony_ci let callback_idx = SslContext::cached_ex_index::<F>(); 7792f3ab15Sopenharmony_ci 7892f3ab15Sopenharmony_ci let callback = ssl 7992f3ab15Sopenharmony_ci .ssl_context() 8092f3ab15Sopenharmony_ci .ex_data(callback_idx) 8192f3ab15Sopenharmony_ci .expect("BUG: psk callback missing") as *const F; 8292f3ab15Sopenharmony_ci let hint = if !hint.is_null() { 8392f3ab15Sopenharmony_ci Some(CStr::from_ptr(hint).to_bytes()) 8492f3ab15Sopenharmony_ci } else { 8592f3ab15Sopenharmony_ci None 8692f3ab15Sopenharmony_ci }; 8792f3ab15Sopenharmony_ci // Give the callback mutable slices into which it can write the identity and psk. 8892f3ab15Sopenharmony_ci let identity_sl = slice::from_raw_parts_mut(identity as *mut u8, max_identity_len as usize); 8992f3ab15Sopenharmony_ci let psk_sl = slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize); 9092f3ab15Sopenharmony_ci match (*callback)(ssl, hint, identity_sl, psk_sl) { 9192f3ab15Sopenharmony_ci Ok(psk_len) => psk_len as u32, 9292f3ab15Sopenharmony_ci Err(e) => { 9392f3ab15Sopenharmony_ci e.put(); 9492f3ab15Sopenharmony_ci 0 9592f3ab15Sopenharmony_ci } 9692f3ab15Sopenharmony_ci } 9792f3ab15Sopenharmony_ci } 9892f3ab15Sopenharmony_ci} 9992f3ab15Sopenharmony_ci 10092f3ab15Sopenharmony_ci#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] 10192f3ab15Sopenharmony_cipub extern "C" fn raw_server_psk<F>( 10292f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 10392f3ab15Sopenharmony_ci identity: *const c_char, 10492f3ab15Sopenharmony_ci psk: *mut c_uchar, 10592f3ab15Sopenharmony_ci max_psk_len: c_uint, 10692f3ab15Sopenharmony_ci) -> c_uint 10792f3ab15Sopenharmony_ciwhere 10892f3ab15Sopenharmony_ci F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8]) -> Result<usize, ErrorStack> 10992f3ab15Sopenharmony_ci + 'static 11092f3ab15Sopenharmony_ci + Sync 11192f3ab15Sopenharmony_ci + Send, 11292f3ab15Sopenharmony_ci{ 11392f3ab15Sopenharmony_ci unsafe { 11492f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 11592f3ab15Sopenharmony_ci let callback_idx = SslContext::cached_ex_index::<F>(); 11692f3ab15Sopenharmony_ci 11792f3ab15Sopenharmony_ci let callback = ssl 11892f3ab15Sopenharmony_ci .ssl_context() 11992f3ab15Sopenharmony_ci .ex_data(callback_idx) 12092f3ab15Sopenharmony_ci .expect("BUG: psk callback missing") as *const F; 12192f3ab15Sopenharmony_ci let identity = if identity.is_null() { 12292f3ab15Sopenharmony_ci None 12392f3ab15Sopenharmony_ci } else { 12492f3ab15Sopenharmony_ci Some(CStr::from_ptr(identity).to_bytes()) 12592f3ab15Sopenharmony_ci }; 12692f3ab15Sopenharmony_ci // Give the callback mutable slices into which it can write the psk. 12792f3ab15Sopenharmony_ci let psk_sl = slice::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize); 12892f3ab15Sopenharmony_ci match (*callback)(ssl, identity, psk_sl) { 12992f3ab15Sopenharmony_ci Ok(psk_len) => psk_len as u32, 13092f3ab15Sopenharmony_ci Err(e) => { 13192f3ab15Sopenharmony_ci e.put(); 13292f3ab15Sopenharmony_ci 0 13392f3ab15Sopenharmony_ci } 13492f3ab15Sopenharmony_ci } 13592f3ab15Sopenharmony_ci } 13692f3ab15Sopenharmony_ci} 13792f3ab15Sopenharmony_ci 13892f3ab15Sopenharmony_cipub extern "C" fn ssl_raw_verify<F>( 13992f3ab15Sopenharmony_ci preverify_ok: c_int, 14092f3ab15Sopenharmony_ci x509_ctx: *mut ffi::X509_STORE_CTX, 14192f3ab15Sopenharmony_ci) -> c_int 14292f3ab15Sopenharmony_ciwhere 14392f3ab15Sopenharmony_ci F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send, 14492f3ab15Sopenharmony_ci{ 14592f3ab15Sopenharmony_ci unsafe { 14692f3ab15Sopenharmony_ci let ctx = X509StoreContextRef::from_ptr_mut(x509_ctx); 14792f3ab15Sopenharmony_ci let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing"); 14892f3ab15Sopenharmony_ci let callback_idx = Ssl::cached_ex_index::<Arc<F>>(); 14992f3ab15Sopenharmony_ci 15092f3ab15Sopenharmony_ci let callback = ctx 15192f3ab15Sopenharmony_ci .ex_data(ssl_idx) 15292f3ab15Sopenharmony_ci .expect("BUG: store context missing ssl") 15392f3ab15Sopenharmony_ci .ex_data(callback_idx) 15492f3ab15Sopenharmony_ci .expect("BUG: ssl verify callback missing") 15592f3ab15Sopenharmony_ci .clone(); 15692f3ab15Sopenharmony_ci 15792f3ab15Sopenharmony_ci callback(preverify_ok != 0, ctx) as c_int 15892f3ab15Sopenharmony_ci } 15992f3ab15Sopenharmony_ci} 16092f3ab15Sopenharmony_ci 16192f3ab15Sopenharmony_cipub extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, arg: *mut c_void) -> c_int 16292f3ab15Sopenharmony_ciwhere 16392f3ab15Sopenharmony_ci F: Fn(&mut SslRef, &mut SslAlert) -> Result<(), SniError> + 'static + Sync + Send, 16492f3ab15Sopenharmony_ci{ 16592f3ab15Sopenharmony_ci unsafe { 16692f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 16792f3ab15Sopenharmony_ci let callback = arg as *const F; 16892f3ab15Sopenharmony_ci let mut alert = SslAlert(*al); 16992f3ab15Sopenharmony_ci 17092f3ab15Sopenharmony_ci let r = (*callback)(ssl, &mut alert); 17192f3ab15Sopenharmony_ci *al = alert.0; 17292f3ab15Sopenharmony_ci match r { 17392f3ab15Sopenharmony_ci Ok(()) => ffi::SSL_TLSEXT_ERR_OK, 17492f3ab15Sopenharmony_ci Err(e) => e.0, 17592f3ab15Sopenharmony_ci } 17692f3ab15Sopenharmony_ci } 17792f3ab15Sopenharmony_ci} 17892f3ab15Sopenharmony_ci 17992f3ab15Sopenharmony_ci#[cfg(any(ossl102, libressl261))] 18092f3ab15Sopenharmony_cipub extern "C" fn raw_alpn_select<F>( 18192f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 18292f3ab15Sopenharmony_ci out: *mut *const c_uchar, 18392f3ab15Sopenharmony_ci outlen: *mut c_uchar, 18492f3ab15Sopenharmony_ci inbuf: *const c_uchar, 18592f3ab15Sopenharmony_ci inlen: c_uint, 18692f3ab15Sopenharmony_ci _arg: *mut c_void, 18792f3ab15Sopenharmony_ci) -> c_int 18892f3ab15Sopenharmony_ciwhere 18992f3ab15Sopenharmony_ci F: for<'a> Fn(&mut SslRef, &'a [u8]) -> Result<&'a [u8], AlpnError> + 'static + Sync + Send, 19092f3ab15Sopenharmony_ci{ 19192f3ab15Sopenharmony_ci unsafe { 19292f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 19392f3ab15Sopenharmony_ci let callback = ssl 19492f3ab15Sopenharmony_ci .ssl_context() 19592f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 19692f3ab15Sopenharmony_ci .expect("BUG: alpn callback missing") as *const F; 19792f3ab15Sopenharmony_ci let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize); 19892f3ab15Sopenharmony_ci 19992f3ab15Sopenharmony_ci match (*callback)(ssl, protos) { 20092f3ab15Sopenharmony_ci Ok(proto) => { 20192f3ab15Sopenharmony_ci *out = proto.as_ptr() as *const c_uchar; 20292f3ab15Sopenharmony_ci *outlen = proto.len() as c_uchar; 20392f3ab15Sopenharmony_ci ffi::SSL_TLSEXT_ERR_OK 20492f3ab15Sopenharmony_ci } 20592f3ab15Sopenharmony_ci Err(e) => e.0, 20692f3ab15Sopenharmony_ci } 20792f3ab15Sopenharmony_ci } 20892f3ab15Sopenharmony_ci} 20992f3ab15Sopenharmony_ci 21092f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_tmp_dh<F>( 21192f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 21292f3ab15Sopenharmony_ci is_export: c_int, 21392f3ab15Sopenharmony_ci keylength: c_int, 21492f3ab15Sopenharmony_ci) -> *mut ffi::DH 21592f3ab15Sopenharmony_ciwhere 21692f3ab15Sopenharmony_ci F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send, 21792f3ab15Sopenharmony_ci{ 21892f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 21992f3ab15Sopenharmony_ci let callback = ssl 22092f3ab15Sopenharmony_ci .ssl_context() 22192f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 22292f3ab15Sopenharmony_ci .expect("BUG: tmp dh callback missing") as *const F; 22392f3ab15Sopenharmony_ci 22492f3ab15Sopenharmony_ci match (*callback)(ssl, is_export != 0, keylength as u32) { 22592f3ab15Sopenharmony_ci Ok(dh) => { 22692f3ab15Sopenharmony_ci let ptr = dh.as_ptr(); 22792f3ab15Sopenharmony_ci mem::forget(dh); 22892f3ab15Sopenharmony_ci ptr 22992f3ab15Sopenharmony_ci } 23092f3ab15Sopenharmony_ci Err(e) => { 23192f3ab15Sopenharmony_ci e.put(); 23292f3ab15Sopenharmony_ci ptr::null_mut() 23392f3ab15Sopenharmony_ci } 23492f3ab15Sopenharmony_ci } 23592f3ab15Sopenharmony_ci} 23692f3ab15Sopenharmony_ci 23792f3ab15Sopenharmony_ci#[cfg(all(ossl101, not(ossl110)))] 23892f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_tmp_ecdh<F>( 23992f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 24092f3ab15Sopenharmony_ci is_export: c_int, 24192f3ab15Sopenharmony_ci keylength: c_int, 24292f3ab15Sopenharmony_ci) -> *mut ffi::EC_KEY 24392f3ab15Sopenharmony_ciwhere 24492f3ab15Sopenharmony_ci F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, 24592f3ab15Sopenharmony_ci{ 24692f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 24792f3ab15Sopenharmony_ci let callback = ssl 24892f3ab15Sopenharmony_ci .ssl_context() 24992f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 25092f3ab15Sopenharmony_ci .expect("BUG: tmp ecdh callback missing") as *const F; 25192f3ab15Sopenharmony_ci 25292f3ab15Sopenharmony_ci match (*callback)(ssl, is_export != 0, keylength as u32) { 25392f3ab15Sopenharmony_ci Ok(ec_key) => { 25492f3ab15Sopenharmony_ci let ptr = ec_key.as_ptr(); 25592f3ab15Sopenharmony_ci mem::forget(ec_key); 25692f3ab15Sopenharmony_ci ptr 25792f3ab15Sopenharmony_ci } 25892f3ab15Sopenharmony_ci Err(e) => { 25992f3ab15Sopenharmony_ci e.put(); 26092f3ab15Sopenharmony_ci ptr::null_mut() 26192f3ab15Sopenharmony_ci } 26292f3ab15Sopenharmony_ci } 26392f3ab15Sopenharmony_ci} 26492f3ab15Sopenharmony_ci 26592f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_tmp_dh_ssl<F>( 26692f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 26792f3ab15Sopenharmony_ci is_export: c_int, 26892f3ab15Sopenharmony_ci keylength: c_int, 26992f3ab15Sopenharmony_ci) -> *mut ffi::DH 27092f3ab15Sopenharmony_ciwhere 27192f3ab15Sopenharmony_ci F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send, 27292f3ab15Sopenharmony_ci{ 27392f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 27492f3ab15Sopenharmony_ci let callback = ssl 27592f3ab15Sopenharmony_ci .ex_data(Ssl::cached_ex_index::<Arc<F>>()) 27692f3ab15Sopenharmony_ci .expect("BUG: ssl tmp dh callback missing") 27792f3ab15Sopenharmony_ci .clone(); 27892f3ab15Sopenharmony_ci 27992f3ab15Sopenharmony_ci match callback(ssl, is_export != 0, keylength as u32) { 28092f3ab15Sopenharmony_ci Ok(dh) => { 28192f3ab15Sopenharmony_ci let ptr = dh.as_ptr(); 28292f3ab15Sopenharmony_ci mem::forget(dh); 28392f3ab15Sopenharmony_ci ptr 28492f3ab15Sopenharmony_ci } 28592f3ab15Sopenharmony_ci Err(e) => { 28692f3ab15Sopenharmony_ci e.put(); 28792f3ab15Sopenharmony_ci ptr::null_mut() 28892f3ab15Sopenharmony_ci } 28992f3ab15Sopenharmony_ci } 29092f3ab15Sopenharmony_ci} 29192f3ab15Sopenharmony_ci 29292f3ab15Sopenharmony_ci#[cfg(all(ossl101, not(ossl110)))] 29392f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_tmp_ecdh_ssl<F>( 29492f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 29592f3ab15Sopenharmony_ci is_export: c_int, 29692f3ab15Sopenharmony_ci keylength: c_int, 29792f3ab15Sopenharmony_ci) -> *mut ffi::EC_KEY 29892f3ab15Sopenharmony_ciwhere 29992f3ab15Sopenharmony_ci F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, 30092f3ab15Sopenharmony_ci{ 30192f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 30292f3ab15Sopenharmony_ci let callback = ssl 30392f3ab15Sopenharmony_ci .ex_data(Ssl::cached_ex_index::<Arc<F>>()) 30492f3ab15Sopenharmony_ci .expect("BUG: ssl tmp ecdh callback missing") 30592f3ab15Sopenharmony_ci .clone(); 30692f3ab15Sopenharmony_ci 30792f3ab15Sopenharmony_ci match callback(ssl, is_export != 0, keylength as u32) { 30892f3ab15Sopenharmony_ci Ok(ec_key) => { 30992f3ab15Sopenharmony_ci let ptr = ec_key.as_ptr(); 31092f3ab15Sopenharmony_ci mem::forget(ec_key); 31192f3ab15Sopenharmony_ci ptr 31292f3ab15Sopenharmony_ci } 31392f3ab15Sopenharmony_ci Err(e) => { 31492f3ab15Sopenharmony_ci e.put(); 31592f3ab15Sopenharmony_ci ptr::null_mut() 31692f3ab15Sopenharmony_ci } 31792f3ab15Sopenharmony_ci } 31892f3ab15Sopenharmony_ci} 31992f3ab15Sopenharmony_ci 32092f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_tlsext_status<F>(ssl: *mut ffi::SSL, _: *mut c_void) -> c_int 32192f3ab15Sopenharmony_ciwhere 32292f3ab15Sopenharmony_ci F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + 'static + Sync + Send, 32392f3ab15Sopenharmony_ci{ 32492f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 32592f3ab15Sopenharmony_ci let callback = ssl 32692f3ab15Sopenharmony_ci .ssl_context() 32792f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 32892f3ab15Sopenharmony_ci .expect("BUG: ocsp callback missing") as *const F; 32992f3ab15Sopenharmony_ci let ret = (*callback)(ssl); 33092f3ab15Sopenharmony_ci 33192f3ab15Sopenharmony_ci if ssl.is_server() { 33292f3ab15Sopenharmony_ci match ret { 33392f3ab15Sopenharmony_ci Ok(true) => ffi::SSL_TLSEXT_ERR_OK, 33492f3ab15Sopenharmony_ci Ok(false) => ffi::SSL_TLSEXT_ERR_NOACK, 33592f3ab15Sopenharmony_ci Err(e) => { 33692f3ab15Sopenharmony_ci e.put(); 33792f3ab15Sopenharmony_ci ffi::SSL_TLSEXT_ERR_ALERT_FATAL 33892f3ab15Sopenharmony_ci } 33992f3ab15Sopenharmony_ci } 34092f3ab15Sopenharmony_ci } else { 34192f3ab15Sopenharmony_ci match ret { 34292f3ab15Sopenharmony_ci Ok(true) => 1, 34392f3ab15Sopenharmony_ci Ok(false) => 0, 34492f3ab15Sopenharmony_ci Err(e) => { 34592f3ab15Sopenharmony_ci e.put(); 34692f3ab15Sopenharmony_ci -1 34792f3ab15Sopenharmony_ci } 34892f3ab15Sopenharmony_ci } 34992f3ab15Sopenharmony_ci } 35092f3ab15Sopenharmony_ci} 35192f3ab15Sopenharmony_ci 35292f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_new_session<F>( 35392f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 35492f3ab15Sopenharmony_ci session: *mut ffi::SSL_SESSION, 35592f3ab15Sopenharmony_ci) -> c_int 35692f3ab15Sopenharmony_ciwhere 35792f3ab15Sopenharmony_ci F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, 35892f3ab15Sopenharmony_ci{ 35992f3ab15Sopenharmony_ci let session_ctx_index = 36092f3ab15Sopenharmony_ci try_get_session_ctx_index().expect("BUG: session context index initialization failed"); 36192f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 36292f3ab15Sopenharmony_ci let callback = ssl 36392f3ab15Sopenharmony_ci .ex_data(*session_ctx_index) 36492f3ab15Sopenharmony_ci .expect("BUG: session context missing") 36592f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 36692f3ab15Sopenharmony_ci .expect("BUG: new session callback missing") as *const F; 36792f3ab15Sopenharmony_ci let session = SslSession::from_ptr(session); 36892f3ab15Sopenharmony_ci 36992f3ab15Sopenharmony_ci (*callback)(ssl, session); 37092f3ab15Sopenharmony_ci 37192f3ab15Sopenharmony_ci // the return code doesn't indicate error vs success, but whether or not we consumed the session 37292f3ab15Sopenharmony_ci 1 37392f3ab15Sopenharmony_ci} 37492f3ab15Sopenharmony_ci 37592f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_remove_session<F>( 37692f3ab15Sopenharmony_ci ctx: *mut ffi::SSL_CTX, 37792f3ab15Sopenharmony_ci session: *mut ffi::SSL_SESSION, 37892f3ab15Sopenharmony_ci) where 37992f3ab15Sopenharmony_ci F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send, 38092f3ab15Sopenharmony_ci{ 38192f3ab15Sopenharmony_ci let ctx = SslContextRef::from_ptr(ctx); 38292f3ab15Sopenharmony_ci let callback = ctx 38392f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 38492f3ab15Sopenharmony_ci .expect("BUG: remove session callback missing"); 38592f3ab15Sopenharmony_ci let session = SslSessionRef::from_ptr(session); 38692f3ab15Sopenharmony_ci 38792f3ab15Sopenharmony_ci callback(ctx, session) 38892f3ab15Sopenharmony_ci} 38992f3ab15Sopenharmony_ci 39092f3ab15Sopenharmony_cicfg_if! { 39192f3ab15Sopenharmony_ci if #[cfg(any(ossl110, libressl280, boringssl))] { 39292f3ab15Sopenharmony_ci type DataPtr = *const c_uchar; 39392f3ab15Sopenharmony_ci } else { 39492f3ab15Sopenharmony_ci type DataPtr = *mut c_uchar; 39592f3ab15Sopenharmony_ci } 39692f3ab15Sopenharmony_ci} 39792f3ab15Sopenharmony_ci 39892f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_get_session<F>( 39992f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 40092f3ab15Sopenharmony_ci data: DataPtr, 40192f3ab15Sopenharmony_ci len: c_int, 40292f3ab15Sopenharmony_ci copy: *mut c_int, 40392f3ab15Sopenharmony_ci) -> *mut ffi::SSL_SESSION 40492f3ab15Sopenharmony_ciwhere 40592f3ab15Sopenharmony_ci F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send, 40692f3ab15Sopenharmony_ci{ 40792f3ab15Sopenharmony_ci let session_ctx_index = 40892f3ab15Sopenharmony_ci try_get_session_ctx_index().expect("BUG: session context index initialization failed"); 40992f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 41092f3ab15Sopenharmony_ci let callback = ssl 41192f3ab15Sopenharmony_ci .ex_data(*session_ctx_index) 41292f3ab15Sopenharmony_ci .expect("BUG: session context missing") 41392f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 41492f3ab15Sopenharmony_ci .expect("BUG: get session callback missing") as *const F; 41592f3ab15Sopenharmony_ci let data = slice::from_raw_parts(data as *const u8, len as usize); 41692f3ab15Sopenharmony_ci 41792f3ab15Sopenharmony_ci match (*callback)(ssl, data) { 41892f3ab15Sopenharmony_ci Some(session) => { 41992f3ab15Sopenharmony_ci let p = session.as_ptr(); 42092f3ab15Sopenharmony_ci mem::forget(session); 42192f3ab15Sopenharmony_ci *copy = 0; 42292f3ab15Sopenharmony_ci p 42392f3ab15Sopenharmony_ci } 42492f3ab15Sopenharmony_ci None => ptr::null_mut(), 42592f3ab15Sopenharmony_ci } 42692f3ab15Sopenharmony_ci} 42792f3ab15Sopenharmony_ci 42892f3ab15Sopenharmony_ci#[cfg(ossl111)] 42992f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_keylog<F>(ssl: *const ffi::SSL, line: *const c_char) 43092f3ab15Sopenharmony_ciwhere 43192f3ab15Sopenharmony_ci F: Fn(&SslRef, &str) + 'static + Sync + Send, 43292f3ab15Sopenharmony_ci{ 43392f3ab15Sopenharmony_ci let ssl = SslRef::from_const_ptr(ssl); 43492f3ab15Sopenharmony_ci let callback = ssl 43592f3ab15Sopenharmony_ci .ssl_context() 43692f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 43792f3ab15Sopenharmony_ci .expect("BUG: get session callback missing"); 43892f3ab15Sopenharmony_ci let line = CStr::from_ptr(line).to_bytes(); 43992f3ab15Sopenharmony_ci let line = str::from_utf8_unchecked(line); 44092f3ab15Sopenharmony_ci 44192f3ab15Sopenharmony_ci callback(ssl, line); 44292f3ab15Sopenharmony_ci} 44392f3ab15Sopenharmony_ci 44492f3ab15Sopenharmony_ci#[cfg(ossl111)] 44592f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_stateless_cookie_generate<F>( 44692f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 44792f3ab15Sopenharmony_ci cookie: *mut c_uchar, 44892f3ab15Sopenharmony_ci cookie_len: *mut size_t, 44992f3ab15Sopenharmony_ci) -> c_int 45092f3ab15Sopenharmony_ciwhere 45192f3ab15Sopenharmony_ci F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send, 45292f3ab15Sopenharmony_ci{ 45392f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 45492f3ab15Sopenharmony_ci let callback = ssl 45592f3ab15Sopenharmony_ci .ssl_context() 45692f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 45792f3ab15Sopenharmony_ci .expect("BUG: stateless cookie generate callback missing") as *const F; 45892f3ab15Sopenharmony_ci let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize); 45992f3ab15Sopenharmony_ci match (*callback)(ssl, slice) { 46092f3ab15Sopenharmony_ci Ok(len) => { 46192f3ab15Sopenharmony_ci *cookie_len = len as size_t; 46292f3ab15Sopenharmony_ci 1 46392f3ab15Sopenharmony_ci } 46492f3ab15Sopenharmony_ci Err(e) => { 46592f3ab15Sopenharmony_ci e.put(); 46692f3ab15Sopenharmony_ci 0 46792f3ab15Sopenharmony_ci } 46892f3ab15Sopenharmony_ci } 46992f3ab15Sopenharmony_ci} 47092f3ab15Sopenharmony_ci 47192f3ab15Sopenharmony_ci#[cfg(ossl111)] 47292f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_stateless_cookie_verify<F>( 47392f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 47492f3ab15Sopenharmony_ci cookie: *const c_uchar, 47592f3ab15Sopenharmony_ci cookie_len: size_t, 47692f3ab15Sopenharmony_ci) -> c_int 47792f3ab15Sopenharmony_ciwhere 47892f3ab15Sopenharmony_ci F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, 47992f3ab15Sopenharmony_ci{ 48092f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 48192f3ab15Sopenharmony_ci let callback = ssl 48292f3ab15Sopenharmony_ci .ssl_context() 48392f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 48492f3ab15Sopenharmony_ci .expect("BUG: stateless cookie verify callback missing") as *const F; 48592f3ab15Sopenharmony_ci let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len); 48692f3ab15Sopenharmony_ci (*callback)(ssl, slice) as c_int 48792f3ab15Sopenharmony_ci} 48892f3ab15Sopenharmony_ci 48992f3ab15Sopenharmony_ci#[cfg(not(boringssl))] 49092f3ab15Sopenharmony_cipub extern "C" fn raw_cookie_generate<F>( 49192f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 49292f3ab15Sopenharmony_ci cookie: *mut c_uchar, 49392f3ab15Sopenharmony_ci cookie_len: *mut c_uint, 49492f3ab15Sopenharmony_ci) -> c_int 49592f3ab15Sopenharmony_ciwhere 49692f3ab15Sopenharmony_ci F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send, 49792f3ab15Sopenharmony_ci{ 49892f3ab15Sopenharmony_ci unsafe { 49992f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 50092f3ab15Sopenharmony_ci let callback = ssl 50192f3ab15Sopenharmony_ci .ssl_context() 50292f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 50392f3ab15Sopenharmony_ci .expect("BUG: cookie generate callback missing") as *const F; 50492f3ab15Sopenharmony_ci // We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for 50592f3ab15Sopenharmony_ci // compatibility. See comments in dtls1.h. 50692f3ab15Sopenharmony_ci let slice = 50792f3ab15Sopenharmony_ci slice::from_raw_parts_mut(cookie as *mut u8, ffi::DTLS1_COOKIE_LENGTH as usize - 1); 50892f3ab15Sopenharmony_ci match (*callback)(ssl, slice) { 50992f3ab15Sopenharmony_ci Ok(len) => { 51092f3ab15Sopenharmony_ci *cookie_len = len as c_uint; 51192f3ab15Sopenharmony_ci 1 51292f3ab15Sopenharmony_ci } 51392f3ab15Sopenharmony_ci Err(e) => { 51492f3ab15Sopenharmony_ci e.put(); 51592f3ab15Sopenharmony_ci 0 51692f3ab15Sopenharmony_ci } 51792f3ab15Sopenharmony_ci } 51892f3ab15Sopenharmony_ci } 51992f3ab15Sopenharmony_ci} 52092f3ab15Sopenharmony_ci 52192f3ab15Sopenharmony_ci#[cfg(not(boringssl))] 52292f3ab15Sopenharmony_cicfg_if! { 52392f3ab15Sopenharmony_ci if #[cfg(any(ossl110, libressl280))] { 52492f3ab15Sopenharmony_ci type CookiePtr = *const c_uchar; 52592f3ab15Sopenharmony_ci } else { 52692f3ab15Sopenharmony_ci type CookiePtr = *mut c_uchar; 52792f3ab15Sopenharmony_ci } 52892f3ab15Sopenharmony_ci} 52992f3ab15Sopenharmony_ci 53092f3ab15Sopenharmony_ci#[cfg(not(boringssl))] 53192f3ab15Sopenharmony_cipub extern "C" fn raw_cookie_verify<F>( 53292f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 53392f3ab15Sopenharmony_ci cookie: CookiePtr, 53492f3ab15Sopenharmony_ci cookie_len: c_uint, 53592f3ab15Sopenharmony_ci) -> c_int 53692f3ab15Sopenharmony_ciwhere 53792f3ab15Sopenharmony_ci F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, 53892f3ab15Sopenharmony_ci{ 53992f3ab15Sopenharmony_ci unsafe { 54092f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 54192f3ab15Sopenharmony_ci let callback = ssl 54292f3ab15Sopenharmony_ci .ssl_context() 54392f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 54492f3ab15Sopenharmony_ci .expect("BUG: cookie verify callback missing") as *const F; 54592f3ab15Sopenharmony_ci let slice = 54692f3ab15Sopenharmony_ci slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize); 54792f3ab15Sopenharmony_ci (*callback)(ssl, slice) as c_int 54892f3ab15Sopenharmony_ci } 54992f3ab15Sopenharmony_ci} 55092f3ab15Sopenharmony_ci 55192f3ab15Sopenharmony_ci#[cfg(ossl111)] 55292f3ab15Sopenharmony_cipub struct CustomExtAddState<T>(Option<T>); 55392f3ab15Sopenharmony_ci 55492f3ab15Sopenharmony_ci#[cfg(ossl111)] 55592f3ab15Sopenharmony_cipub extern "C" fn raw_custom_ext_add<F, T>( 55692f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 55792f3ab15Sopenharmony_ci _: c_uint, 55892f3ab15Sopenharmony_ci context: c_uint, 55992f3ab15Sopenharmony_ci out: *mut *const c_uchar, 56092f3ab15Sopenharmony_ci outlen: *mut size_t, 56192f3ab15Sopenharmony_ci x: *mut ffi::X509, 56292f3ab15Sopenharmony_ci chainidx: size_t, 56392f3ab15Sopenharmony_ci al: *mut c_int, 56492f3ab15Sopenharmony_ci _: *mut c_void, 56592f3ab15Sopenharmony_ci) -> c_int 56692f3ab15Sopenharmony_ciwhere 56792f3ab15Sopenharmony_ci F: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) -> Result<Option<T>, SslAlert> 56892f3ab15Sopenharmony_ci + 'static 56992f3ab15Sopenharmony_ci + Sync 57092f3ab15Sopenharmony_ci + Send, 57192f3ab15Sopenharmony_ci T: AsRef<[u8]> + 'static + Sync + Send, 57292f3ab15Sopenharmony_ci{ 57392f3ab15Sopenharmony_ci unsafe { 57492f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 57592f3ab15Sopenharmony_ci let callback = ssl 57692f3ab15Sopenharmony_ci .ssl_context() 57792f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 57892f3ab15Sopenharmony_ci .expect("BUG: custom ext add callback missing") as *const F; 57992f3ab15Sopenharmony_ci let ectx = ExtensionContext::from_bits_truncate(context); 58092f3ab15Sopenharmony_ci let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) { 58192f3ab15Sopenharmony_ci Some((chainidx, X509Ref::from_ptr(x))) 58292f3ab15Sopenharmony_ci } else { 58392f3ab15Sopenharmony_ci None 58492f3ab15Sopenharmony_ci }; 58592f3ab15Sopenharmony_ci match (*callback)(ssl, ectx, cert) { 58692f3ab15Sopenharmony_ci Ok(None) => 0, 58792f3ab15Sopenharmony_ci Ok(Some(buf)) => { 58892f3ab15Sopenharmony_ci *outlen = buf.as_ref().len(); 58992f3ab15Sopenharmony_ci *out = buf.as_ref().as_ptr(); 59092f3ab15Sopenharmony_ci 59192f3ab15Sopenharmony_ci let idx = Ssl::cached_ex_index::<CustomExtAddState<T>>(); 59292f3ab15Sopenharmony_ci let mut buf = Some(buf); 59392f3ab15Sopenharmony_ci let new = match ssl.ex_data_mut(idx) { 59492f3ab15Sopenharmony_ci Some(state) => { 59592f3ab15Sopenharmony_ci state.0 = buf.take(); 59692f3ab15Sopenharmony_ci false 59792f3ab15Sopenharmony_ci } 59892f3ab15Sopenharmony_ci None => true, 59992f3ab15Sopenharmony_ci }; 60092f3ab15Sopenharmony_ci if new { 60192f3ab15Sopenharmony_ci ssl.set_ex_data(idx, CustomExtAddState(buf)); 60292f3ab15Sopenharmony_ci } 60392f3ab15Sopenharmony_ci 1 60492f3ab15Sopenharmony_ci } 60592f3ab15Sopenharmony_ci Err(alert) => { 60692f3ab15Sopenharmony_ci *al = alert.0; 60792f3ab15Sopenharmony_ci -1 60892f3ab15Sopenharmony_ci } 60992f3ab15Sopenharmony_ci } 61092f3ab15Sopenharmony_ci } 61192f3ab15Sopenharmony_ci} 61292f3ab15Sopenharmony_ci 61392f3ab15Sopenharmony_ci#[cfg(ossl111)] 61492f3ab15Sopenharmony_cipub extern "C" fn raw_custom_ext_free<T>( 61592f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 61692f3ab15Sopenharmony_ci _: c_uint, 61792f3ab15Sopenharmony_ci _: c_uint, 61892f3ab15Sopenharmony_ci _: *const c_uchar, 61992f3ab15Sopenharmony_ci _: *mut c_void, 62092f3ab15Sopenharmony_ci) where 62192f3ab15Sopenharmony_ci T: 'static + Sync + Send, 62292f3ab15Sopenharmony_ci{ 62392f3ab15Sopenharmony_ci unsafe { 62492f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 62592f3ab15Sopenharmony_ci let idx = Ssl::cached_ex_index::<CustomExtAddState<T>>(); 62692f3ab15Sopenharmony_ci if let Some(state) = ssl.ex_data_mut(idx) { 62792f3ab15Sopenharmony_ci state.0 = None; 62892f3ab15Sopenharmony_ci } 62992f3ab15Sopenharmony_ci } 63092f3ab15Sopenharmony_ci} 63192f3ab15Sopenharmony_ci 63292f3ab15Sopenharmony_ci#[cfg(ossl111)] 63392f3ab15Sopenharmony_cipub extern "C" fn raw_custom_ext_parse<F>( 63492f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 63592f3ab15Sopenharmony_ci _: c_uint, 63692f3ab15Sopenharmony_ci context: c_uint, 63792f3ab15Sopenharmony_ci input: *const c_uchar, 63892f3ab15Sopenharmony_ci inlen: size_t, 63992f3ab15Sopenharmony_ci x: *mut ffi::X509, 64092f3ab15Sopenharmony_ci chainidx: size_t, 64192f3ab15Sopenharmony_ci al: *mut c_int, 64292f3ab15Sopenharmony_ci _: *mut c_void, 64392f3ab15Sopenharmony_ci) -> c_int 64492f3ab15Sopenharmony_ciwhere 64592f3ab15Sopenharmony_ci F: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) -> Result<(), SslAlert> 64692f3ab15Sopenharmony_ci + 'static 64792f3ab15Sopenharmony_ci + Sync 64892f3ab15Sopenharmony_ci + Send, 64992f3ab15Sopenharmony_ci{ 65092f3ab15Sopenharmony_ci unsafe { 65192f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 65292f3ab15Sopenharmony_ci let callback = ssl 65392f3ab15Sopenharmony_ci .ssl_context() 65492f3ab15Sopenharmony_ci .ex_data(SslContext::cached_ex_index::<F>()) 65592f3ab15Sopenharmony_ci .expect("BUG: custom ext parse callback missing") as *const F; 65692f3ab15Sopenharmony_ci let ectx = ExtensionContext::from_bits_truncate(context); 65792f3ab15Sopenharmony_ci let slice = slice::from_raw_parts(input as *const u8, inlen); 65892f3ab15Sopenharmony_ci let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) { 65992f3ab15Sopenharmony_ci Some((chainidx, X509Ref::from_ptr(x))) 66092f3ab15Sopenharmony_ci } else { 66192f3ab15Sopenharmony_ci None 66292f3ab15Sopenharmony_ci }; 66392f3ab15Sopenharmony_ci match (*callback)(ssl, ectx, slice, cert) { 66492f3ab15Sopenharmony_ci Ok(()) => 1, 66592f3ab15Sopenharmony_ci Err(alert) => { 66692f3ab15Sopenharmony_ci *al = alert.0; 66792f3ab15Sopenharmony_ci 0 66892f3ab15Sopenharmony_ci } 66992f3ab15Sopenharmony_ci } 67092f3ab15Sopenharmony_ci } 67192f3ab15Sopenharmony_ci} 67292f3ab15Sopenharmony_ci 67392f3ab15Sopenharmony_ci#[cfg(ossl111)] 67492f3ab15Sopenharmony_cipub unsafe extern "C" fn raw_client_hello<F>( 67592f3ab15Sopenharmony_ci ssl: *mut ffi::SSL, 67692f3ab15Sopenharmony_ci al: *mut c_int, 67792f3ab15Sopenharmony_ci arg: *mut c_void, 67892f3ab15Sopenharmony_ci) -> c_int 67992f3ab15Sopenharmony_ciwhere 68092f3ab15Sopenharmony_ci F: Fn(&mut SslRef, &mut SslAlert) -> Result<ClientHelloResponse, ErrorStack> 68192f3ab15Sopenharmony_ci + 'static 68292f3ab15Sopenharmony_ci + Sync 68392f3ab15Sopenharmony_ci + Send, 68492f3ab15Sopenharmony_ci{ 68592f3ab15Sopenharmony_ci let ssl = SslRef::from_ptr_mut(ssl); 68692f3ab15Sopenharmony_ci let callback = arg as *const F; 68792f3ab15Sopenharmony_ci let mut alert = SslAlert(*al); 68892f3ab15Sopenharmony_ci 68992f3ab15Sopenharmony_ci let r = (*callback)(ssl, &mut alert); 69092f3ab15Sopenharmony_ci *al = alert.0; 69192f3ab15Sopenharmony_ci match r { 69292f3ab15Sopenharmony_ci Ok(c) => c.0, 69392f3ab15Sopenharmony_ci Err(e) => { 69492f3ab15Sopenharmony_ci e.put(); 69592f3ab15Sopenharmony_ci ffi::SSL_CLIENT_HELLO_ERROR 69692f3ab15Sopenharmony_ci } 69792f3ab15Sopenharmony_ci } 69892f3ab15Sopenharmony_ci} 699