Skip to content

Commit

Permalink
Initial changes for async support, get rid of Any for Context, add al…
Browse files Browse the repository at this point in the history
…pn and minor changes elsewhere
  • Loading branch information
Adrian Cruceru committed Feb 8, 2022
1 parent c5b103f commit f72fb41
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 123 deletions.
2 changes: 1 addition & 1 deletion mbedtls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ rs-libc = "0.2.0"
chrono = "0.4"

[dependencies.mbedtls-sys-auto]
version = "2.25.0"
version = "2.26.0"
default-features = false
features = ["custom_printf", "trusted_cert_callback", "threading"]
path = "../mbedtls-sys"
Expand Down
33 changes: 5 additions & 28 deletions mbedtls/src/pk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,34 +201,7 @@ define!(
//
// - Only used when creating/freeing - which is safe by design - eckey_alloc_wrap / eckey_free_wrap
//
// 3. ECDSA: mbedtls_ecdsa_info at ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:729
// This does not use internal locks but avoids interior mutability.
//
// - Const access / copies context to stack based variables:
// ecdsa_verify_wrap: ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:544
// This copies the public key on the stack - in buf[] and copies the group id and nbits.
// That is done via: mbedtls_pk_write_pubkey( &p, buf, &key ) where key.pk_ctx = ctx;
// And the key is a const parameter to mbedtls_pk_write_pubkey - ../../../mbedtls-sys/vendor/crypto/library/pkwrite.c:158
//
// - Const access with additional notes due to call stacks involved.
//
// ecdsa_sign_wrap: ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:657
// mbedtls_ecdsa_write_signature ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:688
// mbedtls_ecdsa_write_signature_restartable ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:640
// MBEDTLS_ECDSA_DETERMINISTIC is not defined.
// MBEDTLS_ECDSA_SIGN_ALT is not defined.
// Passes grp to: ecdsa_sign_restartable: ../../../mbedtls-sys/vendor/crypto/library/ecdsa.c:253
// Const access to group - reads parameters, passed as const to mbedtls_ecp_gen_privkey,
// mbedtls_ecp_mul_restartable: ../../../mbedtls-sys/vendor/crypto/library/ecp.c:2351
// 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
// Passes as const to: mbedtls_ecp_check_privkey / mbedtls_ecp_check_pubkey / mbedtls_ecp_get_type( grp
//
// - Ignored due to not defined: ecdsa_verify_rs_wrap, ecdsa_sign_rs_wrap, ecdsa_rs_alloc, ecdsa_rs_free
// (Undefined - MBEDTLS_ECP_RESTARTABLE - ../../../mbedtls-sys/build/config.rs:173)
//
// - Only const access to context: eckey_check_pair
//
// - Only used when creating/freeing - which is safe by design: ecdsa_alloc_wrap, ecdsa_free_wrap
// 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)
//
unsafe impl Sync for Pk {}

Expand Down Expand Up @@ -913,6 +886,10 @@ impl Pk {
}

pub fn verify(&mut self, md: MdType, hash: &[u8], sig: &[u8]) -> Result<()> {
if hash.len() == 0 || sig.len() == 0 {
return Err(Error::PkBadInputData)
}

unsafe {
pk_verify(
&mut self.inner,
Expand Down
31 changes: 28 additions & 3 deletions mbedtls/src/rng/ctr_drbg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ use mbedtls_sys::types::size_t;
#[cfg(not(feature = "std"))]
use crate::alloc_prelude::*;
use crate::error::{IntoResult, Result};
use crate::rng::{EntropyCallback, RngCallback, RngCallbackMut};
use crate::rng::{EntropyCallback, EntropyCallbackMut, RngCallback, RngCallbackMut};

enum EntropyHolder {
Shared(Arc<dyn EntropyCallback + 'static>),
Unique(Box<dyn EntropyCallbackMut + 'static>),
}

define!(
// `ctr_drbg_context` inlines an `aes_context`, which is immovable. See
Expand All @@ -30,7 +35,7 @@ define!(
#[c_box_ty(ctr_drbg_context)]
#[repr(C)]
struct CtrDrbg {
entropy: Arc<dyn EntropyCallback + 'static>,
entropy: EntropyHolder,
};
const drop: fn(&mut Self) = ctr_drbg_free;
impl<'a> Into<ptr> {}
Expand Down Expand Up @@ -63,8 +68,28 @@ impl CtrDrbg {
).into_result()?;
}

Ok(CtrDrbg { inner, entropy })
Ok(CtrDrbg { inner, entropy: EntropyHolder::Shared(entropy) })
}

pub fn new_mut<T: EntropyCallbackMut + 'static>(entropy: T, additional_entropy: Option<&[u8]>) -> Result<Self> {
let mut inner = Box::new(ctr_drbg_context::default());

// We take sole ownership of entropy, all access is guarded via mutexes.
let mut entropy = Box::new(entropy);
unsafe {
ctr_drbg_init(&mut *inner);
ctr_drbg_seed(
&mut *inner,
Some(T::call_mut),
entropy.data_ptr_mut(),
additional_entropy.map(<[_]>::as_ptr).unwrap_or(::core::ptr::null()),
additional_entropy.map(<[_]>::len).unwrap_or(0)
).into_result()?;
}

Ok(CtrDrbg { inner, entropy: EntropyHolder::Unique(entropy) })
}


pub fn prediction_resistance(&self) -> bool {
if self.inner.prediction_resistance == CTR_DRBG_PR_OFF {
Expand Down
73 changes: 63 additions & 10 deletions mbedtls/src/ssl/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,49 @@ callback!(DbgCallback: Fn(i32, Cow<'_, str>, i32, Cow<'_, str>) -> ());
callback!(SniCallback: Fn(&mut HandshakeContext, &[u8]) -> Result<()>);
callback!(CaCallback: Fn(&MbedtlsList<Certificate>) -> Result<MbedtlsList<Certificate>>);


#[repr(transparent)]
pub struct NullTerminatedStrList {
c: Box<[*mut i8]>,
}

unsafe impl Send for NullTerminatedStrList {}
unsafe impl Sync for NullTerminatedStrList {}

impl NullTerminatedStrList {
pub fn new(list: &[&str]) -> Result<Self> {
let mut c = Vec::with_capacity(list.len() + 1);

for s in list {
let cstr = ::std::ffi::CString::new(*s).map_err(|_| Error::SslBadInputData)?;
c.push(cstr.into_raw());
}

c.push(core::ptr::null_mut());

Ok(NullTerminatedStrList {
c: c.into_boxed_slice(),
})
}

pub fn as_ptr(&self) -> *const *const u8 {
self.c.as_ptr() as *const _
}
}

impl Drop for NullTerminatedStrList {
fn drop(&mut self) {
for i in self.c.iter() {
unsafe {
if !(*i).is_null() {
let _ = ::std::ffi::CString::from_raw(*i);
}
}
}
}
}


define!(
#[c_ty(ssl_config)]
#[repr(C)]
Expand All @@ -116,9 +159,7 @@ define!(

ciphersuites: Vec<Arc<Vec<c_int>>>,
curves: Option<Arc<Vec<ecp_group_id>>>,

#[allow(dead_code)]
dhm: Option<Arc<Dhm>>,
protocols: Option<Arc<NullTerminatedStrList>>,

verify_callback: Option<Arc<dyn VerifyCallback + 'static>>,
#[cfg(feature = "std")]
Expand Down Expand Up @@ -154,7 +195,7 @@ impl Config {
rng: None,
ciphersuites: vec![],
curves: None,
dhm: None,
protocols: None,
verify_callback: None,
#[cfg(feature = "std")]
dbg_callback: None,
Expand Down Expand Up @@ -184,6 +225,20 @@ impl Config {
self.ciphersuites.push(list);
}

/// Set the supported Application Layer Protocols.
///
/// Each protocol name in the list must also be terminated with a null character (`\0`).
pub fn set_alpn_protocols(&mut self, protocols: Arc<NullTerminatedStrList>) -> Result<()> {
unsafe {
ssl_conf_alpn_protocols(&mut self.inner, protocols.as_ptr() as *mut _)
.into_result()
.map(|_| ())?;
}

self.protocols = Some(protocols);
Ok(())
}

pub fn set_ciphersuites_for_version(&mut self, list: Arc<Vec<c_int>>, major: c_int, minor: c_int) {
Self::check_c_list(&list);
unsafe { ssl_conf_ciphersuites_for_version(self.into(), list.as_ptr(), major, minor) }
Expand Down Expand Up @@ -232,13 +287,13 @@ impl Config {
/// Takes both DER and PEM forms of FFDH parameters in `DHParams` format.
///
/// When calling on PEM-encoded data, `params` must be NULL-terminated
pub fn set_dh_params(&mut self, dhm: Arc<Dhm>) -> Result<()> {
pub fn set_dh_params(&mut self, dhm: &Dhm) -> Result<()> {
unsafe {
// This copies the dhm parameters and does not store any pointer to it
ssl_conf_dh_param_ctx(self.into(), dhm.inner_ffi_mut())
.into_result()
.map(|_| ())?;
}
self.dhm = Some(dhm);
Ok(())
}

Expand Down Expand Up @@ -316,12 +371,10 @@ impl Config {
// - We can pointer cast to it to allow storing additional objects.
//
let cb = &mut *(closure as *mut F);
let context = UnsafeFrom::from(ctx).unwrap();

let mut ctx = HandshakeContext::init(context);
let ctx = UnsafeFrom::from(ctx).unwrap();

let name = from_raw_parts(name, name_len);
match cb(&mut ctx, name) {
match cb(ctx, name) {
Ok(()) => 0,
Err(_) => -1,
}
Expand Down
Loading

0 comments on commit f72fb41

Please sign in to comment.