diff --git a/mbedtls-sys-espidf/src/lib.rs b/mbedtls-sys-espidf/src/lib.rs index b6b59b66e..c28c571a9 100644 --- a/mbedtls-sys-espidf/src/lib.rs +++ b/mbedtls-sys-espidf/src/lib.rs @@ -1,6 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[macro_use] extern crate cfg_if; pub mod types; diff --git a/mbedtls/src/ssl/context/asynch.rs b/mbedtls/src/ssl/context/asynch.rs index 673e11eef..b58de2f1c 100644 --- a/mbedtls/src/ssl/context/asynch.rs +++ b/mbedtls/src/ssl/context/asynch.rs @@ -1,58 +1,103 @@ use crate::rng::{EspRandom, RngCallback}; use crate::ssl::{config::*, context::*}; +use std::sync::Arc; define!( #[c_ty(ssl_config)] - #[repr(transparent)] - struct Config<'a>; - const init: fn() -> Self = ssl_config_init; + #[repr(C)] + struct Config { + own_cert: Vec>, + own_pk: Vec>, + }; const drop: fn(&mut Self) = ssl_config_free; impl<'b> Into {} impl<'b> UnsafeFrom {} ); -unsafe impl<'a> Sync for Config<'a> {} +unsafe impl Sync for Config {} -impl<'a> Config<'a> { +const MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: u16 = 0x0001; +const MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: u16 = 0x0002; +const MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80: u16 = 0x0005; +const MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32: u16 = 0x0006; +const MBEDTLS_TLS_SRTP_UNSET: u16 = 0x0000; + +const DEFAULT_SRTP_PROFILES: [ssl_srtp_profile; 5] = [ + MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80, + MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32, + MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80, + MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32, + MBEDTLS_TLS_SRTP_UNSET, +]; + +impl Config { pub fn new(e: Endpoint, t: Transport, p: Preset) -> Self { - let mut config = Self::init(); - let conf = config.handle_mut(); + let mut inner = ssl_config::default(); unsafe { - ssl_config_defaults(conf, e as c_int, t as c_int, p as c_int); - ssl_conf_rng(conf, Some(EspRandom::call), EspRandom.data_ptr()); + ssl_config_init(&mut inner); + ssl_config_defaults(&mut inner, e as c_int, t as c_int, p as c_int); + ssl_conf_rng(&mut inner, Some(EspRandom::call), EspRandom.data_ptr()); }; - config + + Self { + inner, + own_cert: vec![], + own_pk: vec![], + } } - pub fn push_cert(&mut self, own_cert: &'a Certificate, own_pk: &'a Pk) -> Result<()> { + pub fn push_cert(&mut self, own_cert: &Arc, own_pk: &Arc) -> Result<()> { unsafe { ssl_conf_own_cert( self.into(), own_cert.inner_ffi_mut(), own_pk.inner_ffi_mut(), ) - .into_result_discard() + .into_result_discard()?; + } + self.own_cert.push(Arc::clone(own_cert)); + self.own_pk.push(Arc::clone(own_pk)); + + Ok(()) + } + + /// Required for SRTP negotiation + pub fn set_default_srtp_profiles(&mut self) -> Result<()> { + unsafe { + ssl_conf_dtls_srtp_protection_profiles(self.into(), DEFAULT_SRTP_PROFILES.as_ptr()) + .into_result_discard() } } + pub fn set_ciphersuites(&mut self, ciphersuites: &[i32]) -> Result<()> { + unsafe { ssl_conf_ciphersuites(self.into(), ciphersuites.as_ptr()) } + Ok(()) + } + setter!(set_authmode(am: AuthMode) = ssl_conf_authmode); } define!( #[c_ty(ssl_context)] - #[repr(transparent)] - struct Context<'a>; - const init: fn() -> Self = ssl_init; + #[repr(C)] + struct Context { + config: Arc, + }; const drop: fn(&mut Self) = ssl_free; impl<'b> Into {} impl<'b> UnsafeFrom {} ); -impl<'a> Context<'a> { - pub fn new(config: &'a Config<'a>) -> Result { - let mut context = Self::init(); - unsafe { ssl_setup(context.handle_mut(), config.handle()) }.into_result()?; - Ok(context) +impl Context { + pub fn new(config: &Arc) -> Result { + let mut inner = ssl_context::default(); + let config = Arc::clone(&config); + unsafe { + ssl_init(&mut inner); + ssl_setup(&mut inner, (&*config).into()).into_result()?; + }; + + Ok(Self { inner, config }) } pub fn read(&mut self, buf: &mut [u8]) -> Result { @@ -67,6 +112,10 @@ impl<'a> Context<'a> { unsafe { ssl_close_notify(self.handle_mut()) }.into_result() } + pub fn handshake(&mut self) -> Result { + unsafe { ssl_handshake(self.handle_mut()) }.into_result() + } + /// # Safety /// TODO pub unsafe fn set_bio( @@ -89,6 +138,14 @@ impl<'a> Context<'a> { ) { ssl_set_timer_cb(self.handle_mut(), timer, set, get) } + + pub unsafe fn set_key_export_cb(&mut self, cb: ssl_export_keys_t, keys: *mut c_void) { + ssl_set_export_keys_cb(self.handle_mut(), cb, keys) + } + + pub unsafe fn get_dtls_srtp_negotiation_result(&self, info: *mut dtls_srtp_info) { + ssl_get_dtls_srtp_negotiation_result(self.handle(), info) + } } impl embedded_io::Error for Error {