Skip to content

Commit

Permalink
Replace some uses of Lazy by OnceCell
Browse files Browse the repository at this point in the history
so some initialization errors don't result in a panic.
  • Loading branch information
jplatte committed Dec 31, 2020
1 parent 0e4aec0 commit f999e8a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 14 deletions.
16 changes: 10 additions & 6 deletions openssl/src/ssl/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ use error::ErrorStack;
use pkey::Params;
#[cfg(any(ossl102, libressl261))]
use ssl::AlpnError;
#[cfg(ossl111)]
use ssl::{ClientHelloResponse, ExtensionContext};
use ssl::{
SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef, SslSession, SslSessionRef,
SESSION_CTX_INDEX,
try_get_session_ctx_index, SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef,
SslSession, SslSessionRef,
};
#[cfg(ossl111)]
use ssl::{ClientHelloResponse, ExtensionContext};
use util::ForeignTypeRefExt;
#[cfg(ossl111)]
use x509::X509Ref;
Expand Down Expand Up @@ -355,9 +355,11 @@ pub unsafe extern "C" fn raw_new_session<F>(
where
F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send,
{
let session_ctx_index =
try_get_session_ctx_index().expect("BUG: session context index initialization failed");
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ex_data(*SESSION_CTX_INDEX)
.ex_data(*session_ctx_index)
.expect("BUG: session context missing")
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: new session callback missing") as *const F;
Expand Down Expand Up @@ -401,9 +403,11 @@ pub unsafe extern "C" fn raw_get_session<F>(
where
F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send,
{
let session_ctx_index =
try_get_session_ctx_index().expect("BUG: session context index initialization failed");
let ssl = SslRef::from_ptr_mut(ssl);
let callback = ssl
.ex_data(*SESSION_CTX_INDEX)
.ex_data(*session_ctx_index)
.expect("BUG: session context missing")
.ex_data(SslContext::cached_ex_index::<F>())
.expect("BUG: get session callback missing") as *const F;
Expand Down
17 changes: 12 additions & 5 deletions openssl/src/ssl/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,14 +398,16 @@ cfg_if! {

fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
let domain = domain.to_string();
ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
let hostname_idx = verify::try_get_hostname_idx()?;
ssl.set_ex_data(*hostname_idx, domain);
Ok(())
}

mod verify {
use std::net::IpAddr;
use std::str;

use error::ErrorStack;
use ex_data::Index;
use nid::Nid;
use ssl::Ssl;
Expand All @@ -414,22 +416,27 @@ cfg_if! {
GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
X509VerifyResult,
};
use once_cell::sync::Lazy;
use once_cell::sync::OnceCell;

pub static HOSTNAME_IDX: Lazy<Index<Ssl, String>> =
Lazy::new(|| Ssl::new_ex_index().unwrap());
static HOSTNAME_IDX: OnceCell<Index<Ssl, String>> = OnceCell::new();

pub fn try_get_hostname_idx() -> Result<&'static Index<Ssl, String>, ErrorStack> {
HOSTNAME_IDX.get_or_try_init(Ssl::new_ex_index)
}

pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool {
if !preverify_ok || x509_ctx.error_depth() != 0 {
return preverify_ok;
}

let hostname_idx =
try_get_hostname_idx.expect("failed to initialize hostname index");
let ok = match (
x509_ctx.current_cert(),
X509StoreContext::ssl_idx()
.ok()
.and_then(|idx| x509_ctx.ex_data(idx))
.and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)),
.and_then(|ssl| ssl.ex_data(*hostname_idx)),
) {
(Some(x509), Some(domain)) => verify_hostname(domain, &x509),
_ => true,
Expand Down
11 changes: 8 additions & 3 deletions openssl/src/ssl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ use ex_data::Index;
use hash::MessageDigest;
#[cfg(ossl110)]
use nid::Nid;
use once_cell::sync::Lazy;
use once_cell::sync::{Lazy, OnceCell};
use pkey::{HasPrivate, PKeyRef, Params, Private};
use srtp::{SrtpProtectionProfile, SrtpProtectionProfileRef};
use ssl::bio::BioMethod;
Expand Down Expand Up @@ -515,7 +515,11 @@ impl NameType {

static INDEXES: Lazy<Mutex<HashMap<TypeId, c_int>>> = Lazy::new(|| Mutex::new(HashMap::new()));
static SSL_INDEXES: Lazy<Mutex<HashMap<TypeId, c_int>>> = Lazy::new(|| Mutex::new(HashMap::new()));
static SESSION_CTX_INDEX: Lazy<Index<Ssl, SslContext>> = Lazy::new(|| Ssl::new_ex_index().unwrap());
static SESSION_CTX_INDEX: OnceCell<Index<Ssl, SslContext>> = OnceCell::new();

fn try_get_session_ctx_index() -> Result<&'static Index<Ssl, SslContext>, ErrorStack> {
SESSION_CTX_INDEX.get_or_try_init(Ssl::new_ex_index)
}

unsafe extern "C" fn free_data_box<T>(
_parent: *mut c_void,
Expand Down Expand Up @@ -2389,10 +2393,11 @@ impl Ssl {
/// [`SSL_new`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_new.html
// FIXME should take &SslContextRef
pub fn new(ctx: &SslContextRef) -> Result<Ssl, ErrorStack> {
let session_ctx_index = try_get_session_ctx_index()?;
unsafe {
let ptr = cvt_p(ffi::SSL_new(ctx.as_ptr()))?;
let mut ssl = Ssl::from_ptr(ptr);
ssl.set_ex_data(*SESSION_CTX_INDEX, ctx.to_owned());
ssl.set_ex_data(*session_ctx_index, ctx.to_owned());

Ok(ssl)
}
Expand Down

0 comments on commit f999e8a

Please sign in to comment.