Skip to content

Commit

Permalink
Merge pull request #1921 from RoastVeg/client_hello_ciphers
Browse files Browse the repository at this point in the history
Add bindings to SSL_bytes_to_cipher_list
  • Loading branch information
sfackler committed May 15, 2023
2 parents 5d2c405 + 7e6d518 commit 5c7b570
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 1 deletion.
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

0 comments on commit 5c7b570

Please sign in to comment.