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 bindings to SSL_bytes_to_cipher_list #1921

Merged
merged 1 commit into from May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions openssl-sys/src/handwritten/ssl.rs
Expand Up @@ -648,6 +648,15 @@ extern "C" {
num: size_t,
readbytes: *mut size_t,
) -> c_int;
#[cfg(ossl111)]
pub fn SSL_bytes_to_cipher_list(
s: *mut SSL,
bytes: *const c_uchar,
len: size_t,
isv2format: c_int,
sk: *mut *mut stack_st_SSL_CIPHER,
scsvs: *mut *mut stack_st_SSL_CIPHER,
) -> c_int;
}

extern "C" {
Expand Down
54 changes: 53 additions & 1 deletion openssl/src/ssl/mod.rs
Expand Up @@ -72,7 +72,7 @@ use crate::srtp::{SrtpProtectionProfile, SrtpProtectionProfileRef};
use crate::ssl::bio::BioMethod;
use crate::ssl::callbacks::*;
use crate::ssl::error::InnerError;
use crate::stack::{Stack, StackRef};
use crate::stack::{Stack, StackRef, Stackable};
use crate::util::{ForeignTypeExt, ForeignTypeRefExt};
use crate::x509::store::{X509Store, X509StoreBuilderRef, X509StoreRef};
#[cfg(any(ossl102, libressl261))]
Expand Down Expand Up @@ -1940,6 +1940,10 @@ impl ForeignType for SslCipher {
}
}

impl Stackable for SslCipher {
type StackType = ffi::stack_st_SSL_CIPHER;
}

impl Deref for SslCipher {
type Target = SslCipherRef;

Expand Down Expand Up @@ -2056,6 +2060,19 @@ impl SslCipherRef {
}
}

impl fmt::Debug for SslCipherRef {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.name())
}
}

/// A stack of selected ciphers, and a stack of selected signalling cipher suites
#[derive(Debug)]
pub struct CipherLists {
pub suites: Stack<SslCipher>,
pub signalling_suites: Stack<SslCipher>,
}

foreign_type_and_impl_send_sync! {
type CType = ffi::SSL_SESSION;
fn drop = ffi::SSL_SESSION_free;
Expand Down Expand Up @@ -3083,6 +3100,41 @@ impl SslRef {
}
}

/// Decodes a slice of wire-format cipher suite specification bytes. Unsupported cipher suites
/// are ignored.
///
/// Requires OpenSSL 1.1.1 or newer.
#[corresponds(SSL_bytes_to_cipher_list)]
#[cfg(ossl111)]
pub fn bytes_to_ciphers_stack(
&self,
bytes: &[u8],
isv2format: bool,
) -> Result<CipherLists, ErrorStack> {
unsafe {
let ptr = bytes.as_ptr();
let len = bytes.len();
let mut sk = ptr::null_mut();
let mut scsvs = ptr::null_mut();
let res = ffi::SSL_bytes_to_cipher_list(
self.as_ptr(),
ptr,
len,
isv2format as c_int,
&mut sk,
&mut scsvs,
);
if res == 1 {
Ok(CipherLists {
suites: Stack::from_ptr(sk),
signalling_suites: Stack::from_ptr(scsvs),
})
} else {
Err(ErrorStack::get())
}
}
}

/// Returns the compression methods field of the client's hello message.
///
/// This can only be used inside of the client hello callback. Otherwise, `None` is returned.
Expand Down
3 changes: 3 additions & 0 deletions openssl/src/ssl/test/mod.rs
Expand Up @@ -1458,6 +1458,9 @@ fn client_hello() {
assert!(ssl.client_hello_session_id().is_some());
assert!(ssl.client_hello_ciphers().is_some());
assert!(ssl.client_hello_compression_methods().is_some());
assert!(ssl
.bytes_to_ciphers_stack(ssl.client_hello_ciphers().unwrap(), ssl.client_hello_isv2())
.is_ok());

CALLED_BACK.store(true, Ordering::SeqCst);
Ok(ClientHelloResponse::SUCCESS)
Expand Down