diff --git a/mbedtls-sys/vendor/library/ssl_tls.c b/mbedtls-sys/vendor/library/ssl_tls.c index e367fbd9c..79194f89a 100644 --- a/mbedtls-sys/vendor/library/ssl_tls.c +++ b/mbedtls-sys/vendor/library/ssl_tls.c @@ -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 ); diff --git a/mbedtls/examples/client.rs b/mbedtls/examples/client.rs index 53fe5dbff..e7894575e 100644 --- a/mbedtls/examples/client.rs +++ b/mbedtls/examples/client.rs @@ -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(); diff --git a/mbedtls/src/ssl/config.rs b/mbedtls/src/ssl/config.rs index 7f2c5debc..b15dccdb5 100644 --- a/mbedtls/src/ssl/config.rs +++ b/mbedtls/src/ssl/config.rs @@ -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); diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index f40a31f15..48c29ee60 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -70,12 +70,12 @@ impl IoCallback for IO { define!( #[c_ty(ssl_context)] #[repr(C)] - struct Context { + struct Context { // config is used read-only for mutliple contexts and is immutable once configured. config: Arc, // Must be held in heap and pointer to it as pointer is sent to MbedSSL and can't be re-allocated. - io: Option>, + io: Option>, handshake_ca_cert: Option>>, handshake_crl: Option>, @@ -89,29 +89,8 @@ define!( impl<'a> UnsafeFrom {} ); -impl Context { - pub fn new(config: Arc) -> 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(&mut self, io: T, hostname: Option<&str>) -> Result<()> { +impl Context { + 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()?; @@ -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, ); @@ -146,6 +125,29 @@ impl Context { } } } +} + +impl Context { + pub fn new(config: Arc) -> 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<()> { @@ -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> { + 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> { + self.io.as_mut() } /// Return the minor number of the negotiated TLS version @@ -251,7 +253,7 @@ impl Context { } } -impl Drop for Context { +impl Drop for Context { fn drop(&mut self) { unsafe { self.close(); @@ -260,7 +262,7 @@ impl Drop for Context { } } -impl Read for Context { +impl Read for Context { fn read(&mut self, buf: &mut [u8]) -> IoResult { match unsafe { ssl_read(self.into(), buf.as_mut_ptr(), buf.len()).into_result() } { Err(Error::SslPeerCloseNotify) => Ok(0), @@ -270,7 +272,7 @@ impl Read for Context { } } -impl Write for Context { +impl Write for Context { fn write(&mut self, buf: &[u8]) -> IoResult { match unsafe { ssl_write(self.into(), buf.as_ptr(), buf.len()).into_result() } { Err(Error::SslPeerCloseNotify) => Ok(0), @@ -286,7 +288,7 @@ impl Write for Context { pub struct HandshakeContext<'ctx> { - pub context: &'ctx mut Context, + pub context: &'ctx mut Context>, } // @@ -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>) -> Self { HandshakeContext { context } } diff --git a/mbedtls/src/wrapper_macros.rs b/mbedtls/src/wrapper_macros.rs index 6c2d20156..d724bebc2 100644 --- a/mbedtls/src/wrapper_macros.rs +++ b/mbedtls/src/wrapper_macros.rs @@ -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,)*)*); @@ -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])* @@ -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)] @@ -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)] @@ -215,10 +264,14 @@ macro_rules! define_struct { ); }; - { << $name:ident $(lifetime $l:tt)* inner $inner:ident >> impl<$l2:tt> Into {} $($defs:tt)* } => { + { << $name:ident $(lifetime $l:lifetime)* inner $inner:ident >> impl<$l2:tt> Into {} $($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 {} $($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)*> { @@ -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 {} $($defs:tt)* } => { + { << $name:ident $(lifetime $l:lifetime)* inner $inner:ident >> impl<$l2:tt> UnsafeFrom {} $($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 {} $($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 { @@ -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 { + (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 { + (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 {