use boring::error::ErrorStack;
use boring::pkey::{HasPrivate, PKeyRef};
use boring::ssl::{Ssl, SslAcceptor, SslRef};
use boring::x509::store::X509StoreRef;
use boring::x509::verify::X509VerifyParamRef;
use boring::x509::X509Ref;
use foreign_types_shared::ForeignTypeRef;
use libc::*;
use std::ffi::CString;
fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
if r != 1 {
Err(ErrorStack::get())
} else {
Ok(r)
}
}
pub fn add_host(verify_param: &mut X509VerifyParamRef, host: &str) -> Result<(), ErrorStack> {
if host.is_empty() {
return Ok(());
}
unsafe {
cvt(boring_sys::X509_VERIFY_PARAM_add1_host(
verify_param.as_ptr(),
host.as_ptr() as *const _,
host.len(),
))
.map(|_| ())
}
}
pub fn ssl_set_verify_cert_store(
ssl: &mut SslRef,
cert_store: &X509StoreRef,
) -> Result<(), ErrorStack> {
unsafe {
cvt(boring_sys::SSL_set1_verify_cert_store(
ssl.as_ptr(),
cert_store.as_ptr(),
))?;
}
Ok(())
}
pub fn ssl_use_certificate(ssl: &mut SslRef, cert: &X509Ref) -> Result<(), ErrorStack> {
unsafe {
cvt(boring_sys::SSL_use_certificate(ssl.as_ptr(), cert.as_ptr()))?;
}
Ok(())
}
pub fn ssl_use_private_key<T>(ssl: &mut SslRef, key: &PKeyRef<T>) -> Result<(), ErrorStack>
where
T: HasPrivate,
{
unsafe {
cvt(boring_sys::SSL_use_PrivateKey(ssl.as_ptr(), key.as_ptr()))?;
}
Ok(())
}
pub fn ssl_add_chain_cert(ssl: &mut SslRef, cert: &X509Ref) -> Result<(), ErrorStack> {
unsafe {
cvt(boring_sys::SSL_add1_chain_cert(ssl.as_ptr(), cert.as_ptr()))?;
}
Ok(())
}
pub fn ssl_set_renegotiate_mode_freely(ssl: &mut SslRef) {
unsafe {
boring_sys::SSL_set_renegotiate_mode(
ssl.as_ptr(),
boring_sys::ssl_renegotiate_mode_t::ssl_renegotiate_freely,
);
}
}
pub fn ssl_set_groups_list(ssl: &mut SslRef, groups: &str) -> Result<(), ErrorStack> {
let groups = CString::new(groups).unwrap();
unsafe {
cvt(boring_sys::SSL_set1_curves_list(
ssl.as_ptr(),
groups.as_ptr(),
))?;
}
Ok(())
}
#[cfg(feature = "pq_use_second_keyshare")]
pub fn ssl_use_second_key_share(ssl: &mut SslRef, enabled: bool) {
unsafe { boring_sys::SSL_use_second_keyshare(ssl.as_ptr(), enabled as _) }
}
#[cfg(not(feature = "pq_use_second_keyshare"))]
pub fn ssl_use_second_key_share(_ssl: &mut SslRef, _enabled: bool) {}
pub fn clear_error_stack() {
let _ = ErrorStack::get();
}
pub fn ssl_from_acceptor(acceptor: &SslAcceptor) -> Result<Ssl, ErrorStack> {
Ssl::new_from_ref(acceptor.context())
}
pub fn suspend_when_need_ssl_cert(ssl: &mut SslRef) {
unsafe {
boring_sys::SSL_set_cert_cb(ssl.as_ptr(), Some(raw_cert_block), std::ptr::null_mut());
}
}
pub fn unblock_ssl_cert(ssl: &mut SslRef) {
unsafe {
boring_sys::SSL_set_cert_cb(ssl.as_ptr(), None, std::ptr::null_mut());
}
}
extern "C" fn raw_cert_block(_ssl: *mut boring_sys::SSL, _arg: *mut c_void) -> c_int {
-1
}
pub fn is_suspended_for_cert(error: &boring::ssl::Error) -> bool {
error.code().as_raw() == boring_sys::SSL_ERROR_WANT_X509_LOOKUP
}
#[allow(clippy::mut_from_ref)]
pub unsafe fn ssl_mut(ssl: &SslRef) -> &mut SslRef {
unsafe { SslRef::from_ptr_mut(ssl.as_ptr()) }
}