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