Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OpenSSL TLS 1.3 PSK callbacks #1993

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions openssl-sys/src/handwritten/ssl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,50 @@ extern "C" {
}

extern "C" {
#[cfg(ossl111)]
pub fn SSL_CTX_set_psk_find_session_callback(
ctx: *mut SSL_CTX,
psk_find_session_cb: Option<
extern "C" fn(*mut SSL, *const c_uchar, size_t, *mut *mut SSL_SESSION) -> c_int,
>,
);

#[cfg(ossl111)]
pub fn SSL_set_psk_find_session_callback(
ssl: *mut SSL,
psk_find_session_cb: Option<
extern "C" fn(*mut SSL, *const c_uchar, size_t, *mut *mut SSL_SESSION) -> c_int,
>,
);

#[cfg(ossl111)]
pub fn SSL_CTX_set_psk_use_session_callback(
ctx: *mut SSL_CTX,
psk_use_session_cb: Option<
extern "C" fn(
*mut SSL,
*const EVP_MD,
*mut *const c_uchar,
*mut size_t,
*mut *mut SSL_SESSION,
) -> c_int,
>,
);

#[cfg(ossl111)]
pub fn SSL_set_psk_use_session_callback(
ctx: *mut SSL,
psk_use_session_cb: Option<
extern "C" fn(
*mut SSL,
*const EVP_MD,
*mut *const c_uchar,
*mut size_t,
*mut *mut SSL_SESSION,
) -> c_int,
>,
);

#[cfg(ossl111)]
pub fn SSL_CTX_add_custom_ext(
ctx: *mut SSL_CTX,
Expand Down Expand Up @@ -476,6 +520,8 @@ const_ptr_api! {
}
}
extern "C" {
#[cfg(any(not(ossl102), libressl273, not(boringssl)))]
pub fn SSL_CIPHER_find(ssl: *mut SSL, ptr: *const c_uchar) -> *const SSL_CIPHER;
#[cfg(ossl111)]
pub fn SSL_CIPHER_get_handshake_digest(cipher: *const SSL_CIPHER) -> *const EVP_MD;
pub fn SSL_CIPHER_get_name(cipher: *const SSL_CIPHER) -> *const c_char;
Expand Down Expand Up @@ -531,10 +577,14 @@ extern "C" {
pub fn SSL_state_string(ssl: *const SSL) -> *const c_char;
pub fn SSL_state_string_long(ssl: *const SSL) -> *const c_char;

#[cfg(not(boringssl))]
pub fn SSL_SESSION_new() -> *mut SSL_SESSION;
pub fn SSL_SESSION_get_time(s: *const SSL_SESSION) -> c_long;
pub fn SSL_SESSION_get_timeout(s: *const SSL_SESSION) -> c_long;
#[cfg(any(ossl110, libressl270))]
pub fn SSL_SESSION_get_protocol_version(s: *const SSL_SESSION) -> c_int;
#[cfg(ossl111)]
pub fn SSL_SESSION_set_protocol_version(s: *mut SSL_SESSION, version: c_int) -> c_int;

#[cfg(any(ossl111, libressl340))]
pub fn SSL_SESSION_set_max_early_data(ctx: *mut SSL_SESSION, max_early_data: u32) -> c_int;
Expand Down Expand Up @@ -787,6 +837,17 @@ extern "C" {
out: *mut c_uchar,
outlen: size_t,
) -> size_t;
#[cfg(ossl111)]
pub fn SSL_SESSION_set1_master_key(
session: *mut SSL_SESSION,
key: *const c_uchar,
key_len: size_t,
) -> c_int;

#[cfg(ossl110)]
pub fn SSL_SESSION_get0_cipher(session: *const SSL_SESSION) -> *const SSL_CIPHER;
#[cfg(ossl111)]
pub fn SSL_SESSION_set_cipher(session: *mut SSL_SESSION, cipher: *const SSL_CIPHER) -> c_int;
}

extern "C" {
Expand Down
195 changes: 195 additions & 0 deletions openssl/src/ssl/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,201 @@ where
}
}

#[cfg(ossl111)]
pub extern "C" fn raw_ssl_ctx_psk_find_session<F>(
ssl: *mut ffi::SSL,
identity: *const c_uchar,
identity_len: size_t,
session: *mut *mut ffi::SSL_SESSION,
) -> c_int
where
F: Fn(&mut SslRef, &[u8]) -> Result<Option<SslSession>, ErrorStack> + 'static + Sync + Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback_idx = SslContext::cached_ex_index::<F>();

let callback = ssl
.ssl_context()
.ex_data(callback_idx)
.expect("BUG: psk find session callback missing") as *const F;

raw_psk_find_session(callback, ssl, identity, identity_len, session)
}
}

#[cfg(ossl111)]
pub extern "C" fn raw_ssl_psk_find_session<F>(
ssl: *mut ffi::SSL,
identity: *const c_uchar,
identity_len: size_t,
session: *mut *mut ffi::SSL_SESSION,
) -> c_int
where
F: Fn(&mut SslRef, &[u8]) -> Result<Option<SslSession>, ErrorStack> + 'static + Sync + Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback_idx = Ssl::cached_ex_index::<F>();

let callback = ssl
.ex_data(callback_idx)
.expect("BUG: psk find session callback missing") as *const F;

raw_psk_find_session(callback, ssl, identity, identity_len, session)
}
}

#[cfg(ossl111)]
pub extern "C" fn raw_psk_find_session<F>(
callback: *const F,
ssl: &mut SslRef,
identity: *const c_uchar,
identity_len: size_t,
session: *mut *mut ffi::SSL_SESSION,
) -> c_int
where
F: Fn(&mut SslRef, &[u8]) -> Result<Option<SslSession>, ErrorStack> + 'static + Sync + Send,
{
unsafe {
let identity_sl = slice::from_raw_parts(identity as *const u8, identity_len);

match (*callback)(ssl, identity_sl) {
Ok(ssl_session) => {
*session = if let Some(ssl_session) = ssl_session {
let p = ssl_session.as_ptr();
mem::forget(ssl_session);

p
} else {
ptr::null_mut()
};

1
}
Err(e) => {
e.put();
0
}
}
}
}

#[cfg(ossl111)]
pub extern "C" fn raw_ssl_ctx_psk_use_session<F>(
ssl: *mut ffi::SSL,
md: *const ffi::EVP_MD,
id: *mut *const c_uchar,
idlen: *mut size_t,
session: *mut *mut ffi::SSL_SESSION,
) -> c_int
where
F: for<'a> Fn(
&'a mut SslRef,
Option<crate::hash::MessageDigest>,
) -> Result<Option<(SslSession, Vec<u8>)>, ErrorStack>
+ 'static
+ Sync
+ Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback_idx = SslContext::cached_ex_index::<F>();

let callback = ssl
.ssl_context()
.ex_data(callback_idx)
.expect("BUG: psk use session callback missing") as *const F;

raw_psk_use_session(callback, ssl, md, id, idlen, session)
}
}

#[cfg(ossl111)]
pub extern "C" fn raw_ssl_psk_use_session<F>(
ssl: *mut ffi::SSL,
md: *const ffi::EVP_MD,
id: *mut *const c_uchar,
idlen: *mut size_t,
session: *mut *mut ffi::SSL_SESSION,
) -> c_int
where
F: for<'a> Fn(
&'a mut SslRef,
Option<crate::hash::MessageDigest>,
) -> Result<Option<(SslSession, Vec<u8>)>, ErrorStack>
+ 'static
+ Sync
+ Send,
{
unsafe {
let ssl = SslRef::from_ptr_mut(ssl);
let callback_idx = Ssl::cached_ex_index::<F>();

let callback = ssl
.ex_data(callback_idx)
.expect("BUG: psk use session callback missing") as *const F;

raw_psk_use_session(callback, ssl, md, id, idlen, session)
}
}

#[cfg(ossl111)]
struct Psk(Vec<u8>);

#[cfg(ossl111)]
pub extern "C" fn raw_psk_use_session<F>(
callback: *const F,
ssl: &mut SslRef,
md: *const ffi::EVP_MD,
id: *mut *const c_uchar,
idlen: *mut size_t,
session: *mut *mut ffi::SSL_SESSION,
) -> c_int
where
F: for<'a> Fn(
&'a mut SslRef,
Option<crate::hash::MessageDigest>,
) -> Result<Option<(SslSession, Vec<u8>)>, ErrorStack>
+ 'static
+ Sync
+ Send,
{
unsafe {
let psk_idx = Ssl::cached_ex_index::<Psk>();

let md = if md.is_null() {
None
} else {
Some(crate::hash::MessageDigest::from_ptr(md))
};

match (*callback)(ssl, md) {
Ok(ssl_session) => {
*session = if let Some((ssl_session, psk_id)) = ssl_session {
*id = psk_id.as_ptr() as *const c_uchar;
*idlen = psk_id.len() as size_t;

ssl.set_ex_data(psk_idx, Psk(psk_id));

let p = ssl_session.as_ptr();
mem::forget(ssl_session);

p
} else {
ptr::null_mut()
};

1
}
Err(e) => {
e.put();
0
}
}
}
}

pub extern "C" fn ssl_raw_verify<F>(
preverify_ok: c_int,
x509_ctx: *mut ffi::X509_STORE_CTX,
Expand Down
Loading
Loading