Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context<S>, generic over IO #171

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mbedtls-sys/vendor/library/ssl_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -3330,6 +3330,7 @@ static void ssl_calc_finished_tls_sha384(
* However, to avoid stringop-overflow warning in gcc, we have to cast
* mbedtls_sha512_finish_ret().
*/
// this still emits the warning on clang...
finish_sha384_t finish = (finish_sha384_t)mbedtls_sha512_finish_ret;
finish( &sha512, padbuf );

Expand Down
2 changes: 2 additions & 0 deletions mbedtls/examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ fn result_main(addr: &str) -> TlsResult<()> {
config.set_ca_list(cert, None);
let mut ctx = Context::new(Arc::new(config));

println!("connecting..");
let conn = TcpStream::connect(addr).unwrap();
println!("establishing SSL connection...");
ctx.establish(conn, None)?;

let mut line = String::new();
Expand Down
1 change: 1 addition & 0 deletions mbedtls/src/ssl/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ impl Config {
// - We can pointer cast to it to allow storing additional objects.
//
let cb = &mut *(closure as *mut F);
// TODO is this cast still safe?
let context = UnsafeFrom::from(ctx).unwrap();

let mut ctx = HandshakeContext::init(context);
Expand Down
74 changes: 38 additions & 36 deletions mbedtls/src/ssl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ impl<IO: Read + Write + 'static> IoCallback for IO {
define!(
#[c_ty(ssl_context)]
#[repr(C)]
struct Context {
struct Context<S> {
// config is used read-only for mutliple contexts and is immutable once configured.
config: Arc<Config>,

// Must be held in heap and pointer to it as pointer is sent to MbedSSL and can't be re-allocated.
io: Option<Box<dyn Any>>,
io: Option<Box<S>>,

handshake_ca_cert: Option<Arc<MbedtlsList<Certificate>>>,
handshake_crl: Option<Arc<Crl>>,
Expand All @@ -89,29 +89,8 @@ define!(
impl<'a> UnsafeFrom<ptr> {}
);

impl Context {
pub fn new(config: Arc<Config>) -> Self {
let mut inner = ssl_context::default();

unsafe {
ssl_init(&mut inner);
ssl_setup(&mut inner, (&*config).into());
};

Context {
inner,
config: config.clone(),
io: None,

handshake_ca_cert: None,
handshake_crl: None,

handshake_cert: vec![],
handshake_pk: vec![],
}
}

pub fn establish<T: IoCallback + Send + Sync + 'static>(&mut self, io: T, hostname: Option<&str>) -> Result<()> {
impl<S: IoCallback> Context<S> {
pub fn establish(&mut self, io: S, hostname: Option<&str>) -> Result<()> {
unsafe {
let mut io = Box::new(io);
ssl_session_reset(self.into()).into_result()?;
Expand All @@ -121,8 +100,8 @@ impl Context {
ssl_set_bio(
self.into(),
ptr,
Some(T::call_send),
Some(T::call_recv),
Some(S::call_send),
Some(S::call_recv),
None,
);

Expand All @@ -146,6 +125,29 @@ impl Context {
}
}
}
}

impl<S> Context<S> {
pub fn new(config: Arc<Config>) -> Self {
let mut inner = ssl_context::default();

unsafe {
ssl_init(&mut inner);
ssl_setup(&mut inner, (&*config).into());
};

Context {
inner,
config: config.clone(),
io: None,

handshake_ca_cert: None,
handshake_crl: None,

handshake_cert: vec![],
handshake_pk: vec![],
}
}

#[cfg(not(feature = "std"))]
fn set_hostname(&mut self, hostname: Option<&str>) -> Result<()> {
Expand Down Expand Up @@ -188,11 +190,11 @@ impl Context {
}
}

pub fn io(&self) -> Option<&dyn Any> {
self.io.as_ref().map(|v| &**v)
pub fn io(&self) -> Option<&Box<S>> {
self.io.as_ref()
}
pub fn io_mut(&mut self) -> Option<&mut dyn Any> {
self.io.as_mut().map(|v| &mut **v)
pub fn io_mut(&mut self) -> Option<&mut Box<S>> {
self.io.as_mut()
}

/// Return the minor number of the negotiated TLS version
Expand Down Expand Up @@ -251,7 +253,7 @@ impl Context {
}
}

impl Drop for Context {
impl<S> Drop for Context<S> {
fn drop(&mut self) {
unsafe {
self.close();
Expand All @@ -260,7 +262,7 @@ impl Drop for Context {
}
}

impl Read for Context {
impl<S> Read for Context<S> {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
match unsafe { ssl_read(self.into(), buf.as_mut_ptr(), buf.len()).into_result() } {
Err(Error::SslPeerCloseNotify) => Ok(0),
Expand All @@ -270,7 +272,7 @@ impl Read for Context {
}
}

impl Write for Context {
impl<S> Write for Context<S> {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
match unsafe { ssl_write(self.into(), buf.as_ptr(), buf.len()).into_result() } {
Err(Error::SslPeerCloseNotify) => Ok(0),
Expand All @@ -286,7 +288,7 @@ impl Write for Context {


pub struct HandshakeContext<'ctx> {
pub context: &'ctx mut Context,
pub context: &'ctx mut Context<Box<dyn Any>>,
}

//
Expand All @@ -303,7 +305,7 @@ pub struct HandshakeContext<'ctx> {
//
impl<'ctx> HandshakeContext<'ctx> {

pub(crate) fn init(context: &'ctx mut Context) -> Self {
pub(crate) fn init(context: &'ctx mut Context<Box<dyn Any>>) -> Self {
HandshakeContext { context }
}

Expand Down
121 changes: 112 additions & 9 deletions mbedtls/src/wrapper_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ macro_rules! callback {

macro_rules! define {
// When using members, careful with UnsafeFrom, the data casted back must have been allocated on rust side.
{ #[c_ty($inner:ident)] $(#[$m:meta])* struct $name:ident$(<$l:tt>)* $({ $($(#[$mm:meta])* $member:ident: $member_type:ty,)* })?; $($defs:tt)* } => {
{ #[c_ty($inner:ident)] $(#[$m:meta])* struct $name:ident$(<$l:lifetime>)* $({ $($(#[$mm:meta])* $member:ident: $member_type:ty,)* })?; $($defs:tt)* } => {
define_struct!(define $(#[$m])* struct $name $(lifetime $l)* inner $inner members $($($(#[$mm])* $member: $member_type,)*)*);
define_struct!(<< $name $(lifetime $l)* inner $inner >> $($defs)*);
};
// case for generic type
{ #[c_ty($inner:ident)] $(#[$m:meta])* struct $name:ident$(<$g:tt>)* $({ $($(#[$mm:meta])* $member:ident: $member_type:ty,)* })?; $($defs:tt)* } => {
define_struct!(define $(#[$m])* struct $name $(generic $g)* inner $inner members $($($(#[$mm])* $member: $member_type,)*)*);
define_struct!(<< $name $(generic $g)* inner $inner >> $($defs)*);
};
// Do not use UnsafeFrom with 'c_box_ty'. That is currently not supported as its not needed anywhere, support may be added in the future if needed anywhere.
{ #[c_box_ty($inner:ident)] $(#[$m:meta])* struct $name:ident$(<$l:tt>)* $({ $($(#[$mm:meta])* $member:ident: $member_type:ty,)* })?; $($defs:tt)* } => {
define_struct!(define_box $(#[$m])* struct $name $(lifetime $l)* inner $inner members $($($(#[$mm])* $member: $member_type,)*)*);
Expand Down Expand Up @@ -109,7 +114,7 @@ macro_rules! define_enum {
}

macro_rules! define_struct {
{ define $(#[$m:meta])* struct $name:ident $(lifetime $l:tt)* inner $inner:ident members $($(#[$mm:meta])* $member:ident: $member_type:ty,)* } => {
{ define $(#[$m:meta])* struct $name:ident $(lifetime $l:lifetime)* inner $inner:ident members $($(#[$mm:meta])* $member:ident: $member_type:ty,)* } => {
as_item!(
#[allow(dead_code)]
$(#[$m])*
Expand Down Expand Up @@ -144,6 +149,42 @@ macro_rules! define_struct {
);
};

{ define $(#[$m:meta])* struct $name:ident $(generic $g:tt)* inner $inner:ident members $($(#[$mm:meta])* $member:ident: $member_type:ty,)* } => {
as_item!(
#[allow(dead_code)]
$(#[$m])*
pub struct $name<$($g)*> {
inner: ::mbedtls_sys::$inner,
$($(#[$mm])* $member: $member_type,)*
}
);

as_item!(
#[allow(dead_code)]
impl<$($g)*> $name<$($g)*> {
pub(crate) fn into_inner(self) -> ::mbedtls_sys::$inner {
let inner = self.inner;
::core::mem::forget(self);
inner
}

pub(crate) fn handle(&self) -> &::mbedtls_sys::$inner {
&self.inner
}

pub(crate) fn handle_mut(&mut self) -> &mut ::mbedtls_sys::$inner {
&mut self.inner
}
}
);

as_item!(
unsafe impl<$($g)*> Send for $name<$($g)*>
where $($g: Send)*
{}
);
};

{ define_box $(#[$m:meta])* struct $name:ident $(lifetime $l:tt)* inner $inner:ident members $($(#[$mm:meta])* $member:ident: $member_type:ty,)* } => {
as_item!(
#[allow(dead_code)]
Expand Down Expand Up @@ -173,14 +214,22 @@ macro_rules! define_struct {
);
};

{ << $name:ident $(lifetime $l:tt)* inner $inner:ident >> const init: fn() -> Self = $ctor:ident $({ $($member:ident: $member_init:expr,)* })?; $($defs:tt)* } => {
{ << $name:ident $(lifetime $l:lifetime)* inner $inner:ident >> const init: fn() -> Self = $ctor:ident $({ $($member:ident: $member_init:expr,)* })?; $($defs:tt)* } => {
define_struct!(init $name () init $ctor $(lifetime $l)* members $($($member: $member_init,)*)* );
define_struct!(<< $name $(lifetime $l)* inner $inner >> $($defs)*);
};
{ << $name:ident $(lifetime $l:tt)* inner $inner:ident >> pub const new: fn() -> Self = $ctor:ident $({ $($member:ident: $member_init:expr,)* })?; $($defs:tt)* } => {
{ << $name:ident $(generic $g:tt)* inner $inner:ident >> const init: fn() -> Self = $ctor:ident $({ $($member:ident: $member_init:expr,)* })?; $($defs:tt)* } => {
define_struct!(init $name () init $ctor $(generic $g)* members $($($member: $member_init,)*)* );
define_struct!(<< $name $(generic $g)* inner $inner >> $($defs)*);
};
{ << $name:ident $(lifetime $l:lifetime)* inner $inner:ident >> pub const new: fn() -> Self = $ctor:ident $({ $($member:ident: $member_init:expr,)* })?; $($defs:tt)* } => {
define_struct!(init $name (pub) new $ctor $(lifetime $l)* members $($($member: $member_init,)*)* );
define_struct!(<< $name $(lifetime $l)* inner $inner >> $($defs)*);
};
{ << $name:ident $(generic $g:tt)* inner $inner:ident >> pub const new: fn() -> Self = $ctor:ident $({ $($member:ident: $member_init:expr,)* })?; $($defs:tt)* } => {
define_struct!(init $name (pub) new $ctor $(generic $g)* members $($($member: $member_init,)*)* );
define_struct!(<< $name $(generic $g)* inner $inner >> $($defs)*);
};
{ init $name:ident ($($vis:tt)*) $new:ident $ctor:ident $(lifetime $l:tt)* members $($member:ident: $member_init:expr,)* } => {
as_item!(
#[allow(dead_code)]
Expand Down Expand Up @@ -215,10 +264,14 @@ macro_rules! define_struct {
);
};

{ << $name:ident $(lifetime $l:tt)* inner $inner:ident >> impl<$l2:tt> Into<ptr> {} $($defs:tt)* } => {
{ << $name:ident $(lifetime $l:lifetime)* inner $inner:ident >> impl<$l2:tt> Into<ptr> {} $($defs:tt)* } => {
define_struct!(into $name inner $inner $(lifetime $l)* lifetime2 $l2 );
define_struct!(<< $name $(lifetime $l)* inner $inner >> $($defs)*);
};
{ << $name:ident $(generic $g:tt)* inner $inner:ident >> impl<$l2:tt> Into<ptr> {} $($defs:tt)* } => {
define_struct!(into $name inner $inner $(generic $g)* lifetime2 $l2 );
define_struct!(<< $name $(generic $g)* inner $inner >> $($defs)*);
};
{ into $name:ident inner $inner:ident $(lifetime $l:tt)* lifetime2 $l2:tt } => {
as_item!(
impl<$l2,$($l),*> Into<*const $inner> for &$l2 $name<$($l)*> {
Expand Down Expand Up @@ -246,12 +299,43 @@ macro_rules! define_struct {
}
);
};
{ into $name:ident inner $inner:ident $(generic $g:tt)* lifetime2 $l2:tt } => {
as_item!(
impl<$l2,$($g),*> Into<*const $inner> for &$l2 $name<$($g)*> {
fn into(self) -> *const $inner {
self.handle()
}
}
);

as_item!(
impl<$l2,$($g),*> Into<*mut $inner> for &$l2 mut $name<$($g)*> {
fn into(self) -> *mut $inner {
self.handle_mut()
}
}
);
as_item!(
impl<$($g),*> $name<$($g)*> {
/// Needed for compatibility with mbedtls - where we could pass
/// `*const` but function signature requires `*mut`
#[allow(dead_code)]
pub(crate) unsafe fn inner_ffi_mut(&self) -> *mut $inner {
self.handle() as *const _ as *mut $inner
}
}
);
};

{ << $name:ident $(lifetime $l:tt)* inner $inner:ident >> impl<$l2:tt> UnsafeFrom<ptr> {} $($defs:tt)* } => {
{ << $name:ident $(lifetime $l:lifetime)* inner $inner:ident >> impl<$l2:tt> UnsafeFrom<ptr> {} $($defs:tt)* } => {
define_struct!(unsafe_from $name inner $inner $(lifetime $l)* lifetime2 $l2 );
define_struct!(<< $name $(lifetime $l)* inner $inner >> $($defs)*);
};
{ unsafe_from $name:ident inner $inner:ident $(lifetime $l:tt)* lifetime2 $l2:tt } => {
{ << $name:ident $(generic $g:tt)* inner $inner:ident >> impl<$l2:tt> UnsafeFrom<ptr> {} $($defs:tt)* } => {
define_struct!(unsafe_from $name inner $inner $(generic $g)* lifetime2 $l2 );
define_struct!(<< $name $(generic $g)* inner $inner >> $($defs)*);
};
{ unsafe_from $name:ident inner $inner:ident $(lifetime $l:lifetime)* lifetime2 $l2:tt } => {
as_item!(
impl<$l2,$($l),*> crate::private::UnsafeFrom<*const $inner> for &$l2 $name<$($l)*> {
unsafe fn from(ptr: *const $inner) -> Option<Self> {
Expand All @@ -268,9 +352,28 @@ macro_rules! define_struct {
}
);
};
{ unsafe_from $name:ident inner $inner:ident $(generic $g:tt)* lifetime2 $l2:tt } => {
as_item!(
impl<$l2,$($g),*> crate::private::UnsafeFrom<*const $inner> for &$l2 $name<$($g)*> {
unsafe fn from(ptr: *const $inner) -> Option<Self> {
(ptr as *const $name<$($g),*>).as_ref()
}
}
);

as_item!(
impl<$l2,$($g),*> crate::private::UnsafeFrom<*mut $inner> for &$l2 mut $name<$($g)*> {
unsafe fn from(ptr: *mut $inner) -> Option<Self> {
(ptr as *mut $name<$($g),*>).as_mut()
}
}
);
};

{ << $name:ident $(lifetime $l:tt)* inner $inner:ident >> } => {};
{ lifetime $l:tt } => {};
{ << $name:ident $(lifetime $l:lifetime)* inner $inner:ident >> } => {};
{ << $name:ident $(generic $g:tt)* inner $inner:ident >> } => {};
{ lifetime $l:lifetime } => {};
{ generic $g:tt } => {};
}

macro_rules! setter {
Expand Down