Skip to content

Commit f72fb41

Browse files
author
Adrian Cruceru
committed
Initial changes for async support, get rid of Any for Context, add alpn and minor changes elsewhere
1 parent c5b103f commit f72fb41

File tree

7 files changed

+245
-123
lines changed

7 files changed

+245
-123
lines changed

mbedtls/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ rs-libc = "0.2.0"
3636
chrono = "0.4"
3737

3838
[dependencies.mbedtls-sys-auto]
39-
version = "2.25.0"
39+
version = "2.26.0"
4040
default-features = false
4141
features = ["custom_printf", "trusted_cert_callback", "threading"]
4242
path = "../mbedtls-sys"

mbedtls/src/pk/mod.rs

+5-28
Original file line numberDiff line numberDiff line change
@@ -201,34 +201,7 @@ define!(
201201
//
202202
// - Only used when creating/freeing - which is safe by design - eckey_alloc_wrap / eckey_free_wrap
203203
//
204-
// 3. ECDSA: mbedtls_ecdsa_info at ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:729
205-
// This does not use internal locks but avoids interior mutability.
206-
//
207-
// - Const access / copies context to stack based variables:
208-
// ecdsa_verify_wrap: ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:544
209-
// This copies the public key on the stack - in buf[] and copies the group id and nbits.
210-
// That is done via: mbedtls_pk_write_pubkey( &p, buf, &key ) where key.pk_ctx = ctx;
211-
// And the key is a const parameter to mbedtls_pk_write_pubkey - ../../../mbedtls-sys/vendor/crypto/library/pkwrite.c:158
212-
//
213-
// - Const access with additional notes due to call stacks involved.
214-
//
215-
// ecdsa_sign_wrap: ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:657
216-
// mbedtls_ecdsa_write_signature ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:688
217-
// mbedtls_ecdsa_write_signature_restartable ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:640
218-
// MBEDTLS_ECDSA_DETERMINISTIC is not defined.
219-
// MBEDTLS_ECDSA_SIGN_ALT is not defined.
220-
// Passes grp to: ecdsa_sign_restartable: ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:253
221-
// Const access to group - reads parameters, passed as const to mbedtls_ecp_gen_privkey,
222-
// mbedtls_ecp_mul_restartable: ../../../mbedtls-sys/vendor/crypto/library/ecp.c:2351
223-
// MBEDTLS_ECP_INTERNAL_ALT is not defined. (otherwise it might not be safe depending on ecp_init/ecp_free) ../../../mbedtls-sys/build/config.rs:131
224-
// Passes as const to: mbedtls_ecp_check_privkey / mbedtls_ecp_check_pubkey / mbedtls_ecp_get_type( grp
225-
//
226-
// - Ignored due to not defined: ecdsa_verify_rs_wrap, ecdsa_sign_rs_wrap, ecdsa_rs_alloc, ecdsa_rs_free
227-
// (Undefined - MBEDTLS_ECP_RESTARTABLE - ../../../mbedtls-sys/build/config.rs:173)
228-
//
229-
// - Only const access to context: eckey_check_pair
230-
//
231-
// - Only used when creating/freeing - which is safe by design: ecdsa_alloc_wrap, ecdsa_free_wrap
204+
// 3. ECDSA - code uses mbedtls_pk wrappers. In this case code goes through ECKEY logic above. (mbedtls_pk_parse_key intentionally never calls mbedtls_pk_info_from_type with MBEDTLS_PK_ECDSA)
232205
//
233206
unsafe impl Sync for Pk {}
234207

@@ -913,6 +886,10 @@ impl Pk {
913886
}
914887

915888
pub fn verify(&mut self, md: MdType, hash: &[u8], sig: &[u8]) -> Result<()> {
889+
if hash.len() == 0 || sig.len() == 0 {
890+
return Err(Error::PkBadInputData)
891+
}
892+
916893
unsafe {
917894
pk_verify(
918895
&mut self.inner,

mbedtls/src/rng/ctr_drbg.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ use mbedtls_sys::types::size_t;
1717
#[cfg(not(feature = "std"))]
1818
use crate::alloc_prelude::*;
1919
use crate::error::{IntoResult, Result};
20-
use crate::rng::{EntropyCallback, RngCallback, RngCallbackMut};
20+
use crate::rng::{EntropyCallback, EntropyCallbackMut, RngCallback, RngCallbackMut};
21+
22+
enum EntropyHolder {
23+
Shared(Arc<dyn EntropyCallback + 'static>),
24+
Unique(Box<dyn EntropyCallbackMut + 'static>),
25+
}
2126

2227
define!(
2328
// `ctr_drbg_context` inlines an `aes_context`, which is immovable. See
@@ -30,7 +35,7 @@ define!(
3035
#[c_box_ty(ctr_drbg_context)]
3136
#[repr(C)]
3237
struct CtrDrbg {
33-
entropy: Arc<dyn EntropyCallback + 'static>,
38+
entropy: EntropyHolder,
3439
};
3540
const drop: fn(&mut Self) = ctr_drbg_free;
3641
impl<'a> Into<ptr> {}
@@ -63,8 +68,28 @@ impl CtrDrbg {
6368
).into_result()?;
6469
}
6570

66-
Ok(CtrDrbg { inner, entropy })
71+
Ok(CtrDrbg { inner, entropy: EntropyHolder::Shared(entropy) })
72+
}
73+
74+
pub fn new_mut<T: EntropyCallbackMut + 'static>(entropy: T, additional_entropy: Option<&[u8]>) -> Result<Self> {
75+
let mut inner = Box::new(ctr_drbg_context::default());
76+
77+
// We take sole ownership of entropy, all access is guarded via mutexes.
78+
let mut entropy = Box::new(entropy);
79+
unsafe {
80+
ctr_drbg_init(&mut *inner);
81+
ctr_drbg_seed(
82+
&mut *inner,
83+
Some(T::call_mut),
84+
entropy.data_ptr_mut(),
85+
additional_entropy.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()),
86+
additional_entropy.map(<[_]>::len).unwrap_or(0)
87+
).into_result()?;
88+
}
89+
90+
Ok(CtrDrbg { inner, entropy: EntropyHolder::Unique(entropy) })
6791
}
92+
6893

6994
pub fn prediction_resistance(&self) -> bool {
7095
if self.inner.prediction_resistance == CTR_DRBG_PR_OFF {

mbedtls/src/ssl/config.rs

+63-10
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,49 @@ callback!(DbgCallback: Fn(i32, Cow<'_, str>, i32, Cow<'_, str>) -> ());
100100
callback!(SniCallback: Fn(&mut HandshakeContext, &[u8]) -> Result<()>);
101101
callback!(CaCallback: Fn(&MbedtlsList<Certificate>) -> Result<MbedtlsList<Certificate>>);
102102

103+
104+
#[repr(transparent)]
105+
pub struct NullTerminatedStrList {
106+
c: Box<[*mut i8]>,
107+
}
108+
109+
unsafe impl Send for NullTerminatedStrList {}
110+
unsafe impl Sync for NullTerminatedStrList {}
111+
112+
impl NullTerminatedStrList {
113+
pub fn new(list: &[&str]) -> Result<Self> {
114+
let mut c = Vec::with_capacity(list.len() + 1);
115+
116+
for s in list {
117+
let cstr = ::std::ffi::CString::new(*s).map_err(|_| Error::SslBadInputData)?;
118+
c.push(cstr.into_raw());
119+
}
120+
121+
c.push(core::ptr::null_mut());
122+
123+
Ok(NullTerminatedStrList {
124+
c: c.into_boxed_slice(),
125+
})
126+
}
127+
128+
pub fn as_ptr(&self) -> *const *const u8 {
129+
self.c.as_ptr() as *const _
130+
}
131+
}
132+
133+
impl Drop for NullTerminatedStrList {
134+
fn drop(&mut self) {
135+
for i in self.c.iter() {
136+
unsafe {
137+
if !(*i).is_null() {
138+
let _ = ::std::ffi::CString::from_raw(*i);
139+
}
140+
}
141+
}
142+
}
143+
}
144+
145+
103146
define!(
104147
#[c_ty(ssl_config)]
105148
#[repr(C)]
@@ -116,9 +159,7 @@ define!(
116159

117160
ciphersuites: Vec<Arc<Vec<c_int>>>,
118161
curves: Option<Arc<Vec<ecp_group_id>>>,
119-
120-
#[allow(dead_code)]
121-
dhm: Option<Arc<Dhm>>,
162+
protocols: Option<Arc<NullTerminatedStrList>>,
122163

123164
verify_callback: Option<Arc<dyn VerifyCallback + 'static>>,
124165
#[cfg(feature = "std")]
@@ -154,7 +195,7 @@ impl Config {
154195
rng: None,
155196
ciphersuites: vec![],
156197
curves: None,
157-
dhm: None,
198+
protocols: None,
158199
verify_callback: None,
159200
#[cfg(feature = "std")]
160201
dbg_callback: None,
@@ -184,6 +225,20 @@ impl Config {
184225
self.ciphersuites.push(list);
185226
}
186227

228+
/// Set the supported Application Layer Protocols.
229+
///
230+
/// Each protocol name in the list must also be terminated with a null character (`\0`).
231+
pub fn set_alpn_protocols(&mut self, protocols: Arc<NullTerminatedStrList>) -> Result<()> {
232+
unsafe {
233+
ssl_conf_alpn_protocols(&mut self.inner, protocols.as_ptr() as *mut _)
234+
.into_result()
235+
.map(|_| ())?;
236+
}
237+
238+
self.protocols = Some(protocols);
239+
Ok(())
240+
}
241+
187242
pub fn set_ciphersuites_for_version(&mut self, list: Arc<Vec<c_int>>, major: c_int, minor: c_int) {
188243
Self::check_c_list(&list);
189244
unsafe { ssl_conf_ciphersuites_for_version(self.into(), list.as_ptr(), major, minor) }
@@ -232,13 +287,13 @@ impl Config {
232287
/// Takes both DER and PEM forms of FFDH parameters in `DHParams` format.
233288
///
234289
/// When calling on PEM-encoded data, `params` must be NULL-terminated
235-
pub fn set_dh_params(&mut self, dhm: Arc<Dhm>) -> Result<()> {
290+
pub fn set_dh_params(&mut self, dhm: &Dhm) -> Result<()> {
236291
unsafe {
292+
// This copies the dhm parameters and does not store any pointer to it
237293
ssl_conf_dh_param_ctx(self.into(), dhm.inner_ffi_mut())
238294
.into_result()
239295
.map(|_| ())?;
240296
}
241-
self.dhm = Some(dhm);
242297
Ok(())
243298
}
244299

@@ -316,12 +371,10 @@ impl Config {
316371
// - We can pointer cast to it to allow storing additional objects.
317372
//
318373
let cb = &mut *(closure as *mut F);
319-
let context = UnsafeFrom::from(ctx).unwrap();
320-
321-
let mut ctx = HandshakeContext::init(context);
374+
let ctx = UnsafeFrom::from(ctx).unwrap();
322375

323376
let name = from_raw_parts(name, name_len);
324-
match cb(&mut ctx, name) {
377+
match cb(ctx, name) {
325378
Ok(()) => 0,
326379
Err(_) => -1,
327380
}

0 commit comments

Comments
 (0)