Skip to content

Commit

Permalink
Implement SSL_set[01]_chain & SSL_clear_chain_certs
Browse files Browse the repository at this point in the history
Plus the `SSL_CTX` equivalents.
  • Loading branch information
ctz committed Apr 10, 2024
1 parent b1e37c0 commit 4119ccd
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
38 changes: 36 additions & 2 deletions rustls-libssl/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::ffi::{
free_arc, str_from_cstring, to_arc_mut_ptr, try_clone_arc, try_from, try_mut_slice_int,
try_ref_from_ptr, try_slice, try_slice_int, try_str, Castable, OwnershipArc, OwnershipRef,
};
use crate::x509::{load_certs, OwnedX509};
use crate::x509::{load_certs, OwnedX509, OwnedX509Stack};
use crate::ShutdownResult;

/// Makes a entry function definition.
Expand Down Expand Up @@ -162,7 +162,7 @@ entry! {
pub fn _SSL_CTX_ctrl(ctx: *mut SSL_CTX, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long {
let ctx = try_clone_arc!(ctx);

let result = if let Ok(mut _inner) = ctx.lock() {
let result = if let Ok(mut inner) = ctx.lock() {
match SslCtrl::try_from(cmd) {
Ok(SslCtrl::Mode) => {
log::warn!("unimplemented SSL_CTX_set_mode()");
Expand All @@ -180,6 +180,23 @@ entry! {
// not a defined operation in the OpenSSL API
0
}
Ok(SslCtrl::SetChain) => {
let chain = if parg.is_null() {
// this is `SSL_CTX_clear_chain_certs`
vec![]
} else {
match larg {
// this is `SSL_CTX_set1_chain` (incs ref)
1 => OwnedX509Stack::new_copy(parg as *mut stack_st_X509).to_rustls(),
// this is `SSL_CTX_set0_chain` (retain ref)
_ => OwnedX509Stack::new(parg as *mut stack_st_X509).to_rustls(),
}
};

inner.stage_certificate_chain(chain);
C_INT_SUCCESS as i64
}

Err(()) => {
log::warn!("unimplemented _SSL_CTX_ctrl(..., {cmd}, {larg}, ...)");
0
Expand Down Expand Up @@ -574,6 +591,22 @@ entry! {
let hostname = try_str!(parg as *const c_char);
inner.set_sni_hostname(hostname) as c_long
}
Ok(SslCtrl::SetChain) => {
let chain = if parg.is_null() {
// this is `SSL_clear_chain_certs`
vec![]
} else {
match larg {
// this is `SSL_set1_chain` (incs ref)
1 => OwnedX509Stack::new_copy(parg as *mut stack_st_X509).to_rustls(),
// this is `SSL_set0_chain` (retain ref)
_ => OwnedX509Stack::new(parg as *mut stack_st_X509).to_rustls(),
}
};

inner.stage_certificate_chain(chain);
C_INT_SUCCESS as i64
}
Err(()) => {
log::warn!("unimplemented _SSL_ctrl(..., {cmd}, {larg}, ...)");
0
Expand Down Expand Up @@ -1231,6 +1264,7 @@ num_enum! {
Mode = 33,
SetMsgCallbackArg = 16,
SetTlsExtHostname = 55,
SetChain = 88,
SetMaxProtoVersion = 124,
}
}
Expand Down
29 changes: 29 additions & 0 deletions rustls-libssl/src/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ impl OwnedX509Stack {
}
}

/// Make one by adopting ownership of an existing pointer.
pub fn new(raw: *mut stack_st_X509) -> Self {
Self { raw }
}

/// Make one by copying existing stack.
pub fn new_copy(other: *const stack_st_X509) -> Self {
let mut ret = Self::empty();

let len = match unsafe { OPENSSL_sk_num(other as *const OPENSSL_STACK) } {
-1 => 0,
x => x as usize,
};

for index in 0..len {
let item_ptr = unsafe {
OPENSSL_sk_value(other as *const OPENSSL_STACK, index as c_int) as *mut X509
};
// item_ptr belongs to caller.
let item = OwnedX509::new(item_ptr);
// item belongs to `OwnedX509` -- ensure caller's ref is not stolen
item.up_ref();
// `ret` takes its own ref
ret.push(&item);
}

ret
}

pub fn from_rustls(certs: &Vec<CertificateDer<'static>>) -> Self {
let mut r = Self::empty();
for c in certs {
Expand Down

0 comments on commit 4119ccd

Please sign in to comment.