Skip to content

Commit 4119ccd

Browse files
committed
Implement SSL_set[01]_chain & SSL_clear_chain_certs
Plus the `SSL_CTX` equivalents.
1 parent b1e37c0 commit 4119ccd

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

rustls-libssl/src/entry.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::ffi::{
2222
free_arc, str_from_cstring, to_arc_mut_ptr, try_clone_arc, try_from, try_mut_slice_int,
2323
try_ref_from_ptr, try_slice, try_slice_int, try_str, Castable, OwnershipArc, OwnershipRef,
2424
};
25-
use crate::x509::{load_certs, OwnedX509};
25+
use crate::x509::{load_certs, OwnedX509, OwnedX509Stack};
2626
use crate::ShutdownResult;
2727

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

165-
let result = if let Ok(mut _inner) = ctx.lock() {
165+
let result = if let Ok(mut inner) = ctx.lock() {
166166
match SslCtrl::try_from(cmd) {
167167
Ok(SslCtrl::Mode) => {
168168
log::warn!("unimplemented SSL_CTX_set_mode()");
@@ -180,6 +180,23 @@ entry! {
180180
// not a defined operation in the OpenSSL API
181181
0
182182
}
183+
Ok(SslCtrl::SetChain) => {
184+
let chain = if parg.is_null() {
185+
// this is `SSL_CTX_clear_chain_certs`
186+
vec![]
187+
} else {
188+
match larg {
189+
// this is `SSL_CTX_set1_chain` (incs ref)
190+
1 => OwnedX509Stack::new_copy(parg as *mut stack_st_X509).to_rustls(),
191+
// this is `SSL_CTX_set0_chain` (retain ref)
192+
_ => OwnedX509Stack::new(parg as *mut stack_st_X509).to_rustls(),
193+
}
194+
};
195+
196+
inner.stage_certificate_chain(chain);
197+
C_INT_SUCCESS as i64
198+
}
199+
183200
Err(()) => {
184201
log::warn!("unimplemented _SSL_CTX_ctrl(..., {cmd}, {larg}, ...)");
185202
0
@@ -574,6 +591,22 @@ entry! {
574591
let hostname = try_str!(parg as *const c_char);
575592
inner.set_sni_hostname(hostname) as c_long
576593
}
594+
Ok(SslCtrl::SetChain) => {
595+
let chain = if parg.is_null() {
596+
// this is `SSL_clear_chain_certs`
597+
vec![]
598+
} else {
599+
match larg {
600+
// this is `SSL_set1_chain` (incs ref)
601+
1 => OwnedX509Stack::new_copy(parg as *mut stack_st_X509).to_rustls(),
602+
// this is `SSL_set0_chain` (retain ref)
603+
_ => OwnedX509Stack::new(parg as *mut stack_st_X509).to_rustls(),
604+
}
605+
};
606+
607+
inner.stage_certificate_chain(chain);
608+
C_INT_SUCCESS as i64
609+
}
577610
Err(()) => {
578611
log::warn!("unimplemented _SSL_ctrl(..., {cmd}, {larg}, ...)");
579612
0
@@ -1231,6 +1264,7 @@ num_enum! {
12311264
Mode = 33,
12321265
SetMsgCallbackArg = 16,
12331266
SetTlsExtHostname = 55,
1267+
SetChain = 88,
12341268
SetMaxProtoVersion = 124,
12351269
}
12361270
}

rustls-libssl/src/x509.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,35 @@ impl OwnedX509Stack {
2727
}
2828
}
2929

30+
/// Make one by adopting ownership of an existing pointer.
31+
pub fn new(raw: *mut stack_st_X509) -> Self {
32+
Self { raw }
33+
}
34+
35+
/// Make one by copying existing stack.
36+
pub fn new_copy(other: *const stack_st_X509) -> Self {
37+
let mut ret = Self::empty();
38+
39+
let len = match unsafe { OPENSSL_sk_num(other as *const OPENSSL_STACK) } {
40+
-1 => 0,
41+
x => x as usize,
42+
};
43+
44+
for index in 0..len {
45+
let item_ptr = unsafe {
46+
OPENSSL_sk_value(other as *const OPENSSL_STACK, index as c_int) as *mut X509
47+
};
48+
// item_ptr belongs to caller.
49+
let item = OwnedX509::new(item_ptr);
50+
// item belongs to `OwnedX509` -- ensure caller's ref is not stolen
51+
item.up_ref();
52+
// `ret` takes its own ref
53+
ret.push(&item);
54+
}
55+
56+
ret
57+
}
58+
3059
pub fn from_rustls(certs: &Vec<CertificateDer<'static>>) -> Self {
3160
let mut r = Self::empty();
3261
for c in certs {

0 commit comments

Comments
 (0)