From 3817340efe340a063c5a59784484aeb5a02aaea2 Mon Sep 17 00:00:00 2001 From: Adrian Cruceru Date: Thu, 16 Sep 2021 13:01:15 +0200 Subject: [PATCH 01/14] Preparation for porting async branch --- mbedtls-sys/Cargo.toml | 5 ++--- mbedtls/Cargo.toml | 3 ++- mbedtls/src/lib.rs | 7 ++++-- mbedtls/src/pk/dsa/mod.rs | 22 +++++++++++++++--- mbedtls/src/pk/mod.rs | 40 +++++---------------------------- mbedtls/src/rust_printf.c | 4 ++-- mbedtls/src/self_test.rs | 8 +++++-- mbedtls/src/ssl/context.rs | 4 ++-- mbedtls/src/wrapper_macros.rs | 30 +++++++++++++++++++++++++ mbedtls/tests/ec.rs | 6 ++--- mbedtls/tests/rsa.rs | 4 ++-- mbedtls/tests/ssl_conf_ca_cb.rs | 2 -- 12 files changed, 79 insertions(+), 56 deletions(-) diff --git a/mbedtls-sys/Cargo.toml b/mbedtls-sys/Cargo.toml index e49ade9cd..5218287a3 100644 --- a/mbedtls-sys/Cargo.toml +++ b/mbedtls-sys/Cargo.toml @@ -42,9 +42,8 @@ quote = "1.0.9" # * strstr/strlen/strncpy/strncmp/strcmp/snprintf # * memmove/memcpy/memcmp/memset # * rand/printf (used only for self tests. optionally use custom_printf) -default = ["std", "debug", "threading", "zlib", "time", "aesni", "padlock", "legacy_protocols"] -std = ["debug"] # deprecated automatic enabling of debug, can be removed on major version bump -debug = [] +default = ["std", "threading", "zlib", "time", "aesni", "padlock", "legacy_protocols"] +std = [] # deprecated automatic enabling of debug, can be removed on major version bump custom_printf = [] custom_has_support = [] aes_alt = [] diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index df79b5e2a..e77dfebd3 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -35,7 +35,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" @@ -68,6 +68,7 @@ dsa = ["std", "yasna", "num-bigint", "bit-vec"] pkcs12 = ["std", "yasna"] pkcs12_rc2 = ["pkcs12", "rc2", "cbc"] legacy_protocols = ["mbedtls-sys-auto/legacy_protocols"] +migration_mode=[] [[example]] name = "client" diff --git a/mbedtls/src/lib.rs b/mbedtls/src/lib.rs index 07b18e9d1..90aa5b040 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -53,9 +53,11 @@ mod private; // needs to be pub for global visiblity #[doc(hidden)] -#[cfg(sys_threading_component = "custom")] + +#[cfg(all(sys_threading_component = "custom", not(feature = "migration_mode")))] pub mod threading; +#[cfg(not(feature = "migration_mode"))] cfg_if::cfg_if! { if #[cfg(any(feature = "force_aesni_support", target_env = "sgx"))] { // needs to be pub for global visiblity @@ -105,6 +107,7 @@ mod alloc_prelude { pub(crate) use rust_alloc::borrow::Cow; } +#[cfg(not(feature = "migration_mode"))] cfg_if::cfg_if! { if #[cfg(sys_time_component = "custom")] { use mbedtls_sys::types::{time_t, tm}; @@ -154,7 +157,7 @@ cfg_if::cfg_if! { /// /// The caller must ensure no other MbedTLS code is running when calling this /// function. -#[cfg(feature = "debug")] +#[cfg(all(feature = "debug", not(feature = "migration_mode")))] pub unsafe fn set_global_debug_threshold(threshold: i32) { mbedtls_sys::debug_set_threshold(threshold); } diff --git a/mbedtls/src/pk/dsa/mod.rs b/mbedtls/src/pk/dsa/mod.rs index fdf030149..bf868217b 100644 --- a/mbedtls/src/pk/dsa/mod.rs +++ b/mbedtls/src/pk/dsa/mod.rs @@ -217,9 +217,13 @@ fn sample_secret_value(upper_bound: &Mpi, rng: &mut F) -> Result Ok(c) } -fn encode_dsa_signature(r: &Mpi, s: &Mpi) -> Result> { - let r = BigUint::from_bytes_be(&r.to_binary()?); - let s = BigUint::from_bytes_be(&s.to_binary()?); +pub fn encode_dsa_signature(r: &Mpi, s: &Mpi) -> Result> { + serialize_signature(&r.to_binary()?, &s.to_binary()?) +} + +pub fn serialize_signature(r: &[u8], s: &[u8]) -> Result> { + let r = BigUint::from_bytes_be(r); + let s = BigUint::from_bytes_be(s); Ok(yasna::construct_der(|w| { w.write_sequence(|w| { @@ -229,6 +233,18 @@ fn encode_dsa_signature(r: &Mpi, s: &Mpi) -> Result> { })) } +pub fn deserialize_signature(signature: &Vec) -> Result<(Vec, Vec)> { + let (r,s) = yasna::parse_der(signature, |r| { + r.read_sequence(|rdr| { + let r = rdr.next().read_biguint()?; + let s = rdr.next().read_biguint()?; + Ok((r,s)) + }) + }).map_err(|_| Error::X509InvalidSignature)?; + + Ok((r.to_bytes_be(), s.to_bytes_be())) +} + impl DsaPrivateKey { pub fn from_components(params: DsaParams, x: Mpi) -> Result { if x <= Mpi::new(1)? || x >= params.q { diff --git a/mbedtls/src/pk/mod.rs b/mbedtls/src/pk/mod.rs index b71daffef..1343f0acb 100644 --- a/mbedtls/src/pk/mod.rs +++ b/mbedtls/src/pk/mod.rs @@ -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 {} @@ -826,7 +799,7 @@ impl Pk { /// /// On success, returns the actual number of bytes written to `sig`. pub fn sign( - &mut self, + &self, md: MdType, hash: &[u8], sig: &mut [u8], @@ -853,7 +826,7 @@ impl Pk { let mut ret = 0usize; unsafe { pk_sign( - &mut self.inner, + &self.inner as *const _ as *mut _, md.into(), hash.as_ptr(), hash.len(), @@ -922,15 +895,14 @@ impl Pk { } } - pub fn verify(&mut self, md: MdType, hash: &[u8], sig: &[u8]) -> Result<()> { - // If hash or sig are allowed with size 0 (&[]) then mbedtls will attempt to auto-detect size and cause an invalid write. + pub fn verify(&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, + &self.inner as *const _ as *mut _, md.into(), hash.as_ptr(), hash.len(), @@ -1255,7 +1227,7 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi #[test] fn rsa_sign_verify_pkcs1v15() { - let mut pk = + let pk = Pk::generate_rsa(&mut crate::test_support::rand::test_rng(), 2048, 0x10001).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SIGNATURE TEST SIGNATURE TEST SIGN"; let mut signature = vec![0u8; (pk.len() + 7) / 8]; diff --git a/mbedtls/src/rust_printf.c b/mbedtls/src/rust_printf.c index c3b2ac93c..183552e0d 100644 --- a/mbedtls/src/rust_printf.c +++ b/mbedtls/src/rust_printf.c @@ -9,7 +9,7 @@ #include #include -extern void mbedtls_log(const char* msg); +extern void mbedtls8_log(const char* msg); extern int mbedtls_printf(const char *fmt, ...) { va_list ap; @@ -31,7 +31,7 @@ extern int mbedtls_printf(const char *fmt, ...) { if (n<0) return -1; - mbedtls_log(p); + mbedtls8_log(p); return n; } diff --git a/mbedtls/src/self_test.rs b/mbedtls/src/self_test.rs index 659b5ea69..fa3b71f7f 100644 --- a/mbedtls/src/self_test.rs +++ b/mbedtls/src/self_test.rs @@ -25,7 +25,7 @@ cfg_if::cfg_if! { // needs to be pub for global visiblity #[doc(hidden)] #[no_mangle] - pub unsafe extern "C" fn mbedtls_log(msg: *const std::os::raw::c_char) { + pub unsafe extern "C" fn mbedtls8_log(msg: *const std::os::raw::c_char) { print!("{}", std::ffi::CStr::from_ptr(msg).to_string_lossy()); } } else { @@ -35,11 +35,13 @@ cfg_if::cfg_if! { // needs to be pub for global visiblity #[doc(hidden)] #[no_mangle] - pub unsafe extern "C" fn mbedtls_log(msg: *const c_char) { + pub unsafe extern "C" fn mbedtls8_log(msg: *const c_char) { log_f.expect("Called self-test log without enabling self-test")(msg) } } } + +#[cfg(not(feature = "migration_mode"))] cfg_if::cfg_if! { if #[cfg(any(not(feature = "std"), target_env = "sgx"))] { #[allow(non_upper_case_globals)] @@ -66,6 +68,7 @@ cfg_if::cfg_if! { /// The caller needs to ensure this function is not called while any other /// function in this module is called. #[allow(unused)] +#[cfg(not(feature = "migration_mode"))] pub unsafe fn enable(rand: fn() -> c_int, log: Option) { #[cfg(any(not(feature = "std"), target_env = "sgx"))] { rand_f = Some(rand); @@ -79,6 +82,7 @@ pub unsafe fn enable(rand: fn() -> c_int, log: Option) /// /// The caller needs to ensure this function is not called while any other /// function in this module is called. +#[cfg(not(feature = "migration_mode"))] pub unsafe fn disable() { #[cfg(any(not(feature = "std"), target_env = "sgx"))] { rand_f = None; diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index 8ce2d6574..9beb3bd06 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -251,6 +251,7 @@ impl Context { client_transport_id: None, } } +} pub(crate) fn handle(&self) -> &::mbedtls_sys::ssl_context { self.inner.handle() @@ -541,7 +542,6 @@ impl Write for Context { Ok(()) } } - // // Class exists only during SNI callback that is configured from Config. // SNI Callback must provide input whose lifetime exceeds the SNI closure to avoid memory corruptions. @@ -555,7 +555,7 @@ impl Write for Context { // - no reasonable way to obtain a storage within the sni callback tied to the handshake or to the rust Context. (without resorting to a unscalable map or pointer magic that mbedtls may invalidate) // impl HandshakeContext { - fn reset_handshake(&mut self) { + pub fn reset_handshake(&mut self) { self.handshake_cert.clear(); self.handshake_pk.clear(); self.handshake_ca_cert = None; diff --git a/mbedtls/src/wrapper_macros.rs b/mbedtls/src/wrapper_macros.rs index 8a3d916ff..c8c58d27b 100644 --- a/mbedtls/src/wrapper_macros.rs +++ b/mbedtls/src/wrapper_macros.rs @@ -61,6 +61,10 @@ macro_rules! define { define_struct!(define $(#[$m])* struct $name $(lifetime $l)* inner $inner members $($($(#[$mm])* $member: $member_type,)*)*); define_struct!(<< $name $(lifetime $l)* inner $inner >> $($defs)*); }; + { #[c_custom_ty($inner:ident)] $(#[$m:meta])* struct $name:ident$(<$l:tt>)* $({ $($(#[$mm:meta])* $member:ident: $member_type:ty,)* })?; $($defs:tt)* } => { + define_struct!(define_custom $(#[$m])* struct $name $(lifetime $l)* inner $inner members $($($(#[$mm])* $member: $member_type,)*)*); + define_struct!(<< $name $(lifetime $l)* 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,6 +113,32 @@ macro_rules! define_enum { } macro_rules! define_struct { + { define_custom $(#[$m:meta])* struct $name:ident $(lifetime $l:tt)* inner $inner:ident members $($(#[$mm:meta])* $member:ident: $member_type:ty,)* } => { + as_item!( + #[allow(dead_code)] + $(#[$m])* + pub struct $name<$($l)*> { + $($(#[$mm])* $member: $member_type,)* + } + ); + + as_item!( + #[allow(dead_code)] + impl<$($l)*> $name<$($l)*> { + pub(crate) fn handle(&self) -> &::mbedtls_sys::$inner { + self.inner.handle() + } + + pub(crate) fn handle_mut(&mut self) -> &mut ::mbedtls_sys::$inner { + self.inner.handle_mut() + } + } + ); + + as_item!( + unsafe impl<$($l)*> Send for $name<$($l)*> {} + ); + }; { define $(#[$m:meta])* struct $name:ident $(lifetime $l:tt)* inner $inner:ident members $($(#[$mm:meta])* $member:ident: $member_type:ty,)* } => { as_item!( #[allow(dead_code)] diff --git a/mbedtls/tests/ec.rs b/mbedtls/tests/ec.rs index 2ecdc25c4..aea532209 100644 --- a/mbedtls/tests/ec.rs +++ b/mbedtls/tests/ec.rs @@ -44,7 +44,7 @@ wvkbR/h/+CNU1mMPdGoooNsldBtbNKgoAIsirMI/kk+q+9TTP4HqZpVt/qor/fz1 #[test] fn sign_verify() { - let mut k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); + let k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature1 = [0u8; ECDSA_MAX_LEN]; @@ -67,7 +67,7 @@ fn sign_verify() { #[test] fn verify_failure() { - let mut k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); + let k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature = [0u8; ECDSA_MAX_LEN]; @@ -150,7 +150,7 @@ fn sign_verify_rfc6979_sig() { #[test] fn buffer_too_small() { - let mut k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); + let k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature = [0u8; ECDSA_MAX_LEN - 1]; diff --git a/mbedtls/tests/rsa.rs b/mbedtls/tests/rsa.rs index 33c3d68d2..84815191d 100644 --- a/mbedtls/tests/rsa.rs +++ b/mbedtls/tests/rsa.rs @@ -21,7 +21,7 @@ const EXPONENT: u32 = 0x10001; #[test] fn sign_verify() { - let mut k = Pk::generate_rsa(&mut test_rng(), RSA_BITS, EXPONENT).unwrap(); + let k = Pk::generate_rsa(&mut test_rng(), RSA_BITS, EXPONENT).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature = [0u8; RSA_BITS as usize / 8]; @@ -36,7 +36,7 @@ fn sign_verify() { #[test] fn buffer_too_small() { - let mut k = Pk::generate_rsa(&mut test_rng(), RSA_BITS, EXPONENT).unwrap(); + let k = Pk::generate_rsa(&mut test_rng(), RSA_BITS, EXPONENT).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature = [0u8; RSA_BITS as usize / 8 - 1]; diff --git a/mbedtls/tests/ssl_conf_ca_cb.rs b/mbedtls/tests/ssl_conf_ca_cb.rs index 880a699bc..981a6f084 100644 --- a/mbedtls/tests/ssl_conf_ca_cb.rs +++ b/mbedtls/tests/ssl_conf_ca_cb.rs @@ -25,8 +25,6 @@ use mbedtls::ssl::config::CaCallback; mod support; use support::entropy::entropy_new; -use mbedtls::alloc::{List as MbedtlsList}; - fn client(conn: TcpStream, ca_callback: F) -> TlsResult<()> where F: CaCallback + Send + 'static, From bfc9651a2f104f734bb497cb15d05e7c672aaf20 Mon Sep 17 00:00:00 2001 From: Adrian Cruceru Date: Thu, 16 Sep 2021 11:16:49 +0000 Subject: [PATCH 02/14] Async support --- Cargo.lock | 518 ++++++++++++++++++++++++++++++++- Cargo.toml | 5 + mbedtls/Cargo.toml | 27 +- mbedtls/src/ssl/async_utils.rs | 145 +++++++++ mbedtls/src/ssl/context.rs | 233 +++++++++++++++ mbedtls/src/ssl/mod.rs | 4 + mbedtls/tests/async_session.rs | 295 +++++++++++++++++++ mbedtls/tests/hyper13.rs | 322 ++++++++++++++++++++ mbedtls/tests/support/net.rs | 11 + 9 files changed, 1543 insertions(+), 17 deletions(-) create mode 100644 mbedtls/src/ssl/async_utils.rs create mode 100644 mbedtls/tests/async_session.rs create mode 100644 mbedtls/tests/hyper13.rs diff --git a/Cargo.lock b/Cargo.lock index 0df1ad641..33cb3d1c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,39 @@ dependencies = [ "winapi", ] +[[package]] +name = "async-stream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", +] + +[[package]] +name = "async-usercalls" +version = "0.1.0" +source = "git+https://github.com/fortanix/rust-sgx.git?branch=mz/async-usercalls#4cf2a8e12912bfd5e0ce8ef7fcf8f607110dfda2" +dependencies = [ + "crossbeam-channel", + "fnv", + "fortanix-sgx-abi", + "ipc-queue", + "lazy_static", +] + [[package]] name = "atty" version = "0.2.14" @@ -37,6 +70,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + [[package]] name = "base64" version = "0.9.3" @@ -91,12 +130,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "byteorder" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" - [[package]] name = "cbc" version = "0.1.2" @@ -106,6 +139,36 @@ dependencies = [ "cipher", ] +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" + +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + +[[package]] +name = "bytes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + [[package]] name = "cc" version = "1.0.67" @@ -213,12 +276,117 @@ dependencies = [ "termcolor", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fortanix-sgx-abi" +version = "0.4.0" +source = "git+https://github.com/fortanix/rust-sgx.git?branch=mz/async-usercalls#4cf2a8e12912bfd5e0ce8ef7fcf8f607110dfda2" + [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "futures" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" + +[[package]] +name = "futures-executor" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" + +[[package]] +name = "futures-macro" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +dependencies = [ + "autocfg 1.0.1", + "proc-macro-hack", + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", +] + +[[package]] +name = "futures-sink" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" + +[[package]] +name = "futures-task" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" + +[[package]] +name = "futures-util" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +dependencies = [ + "autocfg 1.0.1", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite 0.2.7", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + [[package]] name = "generic-array" version = "0.14.6" @@ -235,6 +403,32 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "h2" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +dependencies = [ + "bytes 0.5.6", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio 0.2.25", + "tokio-util", + "tracing", + "tracing-futures", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "hermit-abi" version = "0.1.17" @@ -250,12 +444,39 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" +[[package]] +name = "http" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +dependencies = [ + "bytes 1.1.0", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" +dependencies = [ + "bytes 0.5.6", + "http", +] + [[package]] name = "httparse" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" +[[package]] +name = "httpdate" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" + [[package]] name = "humantime" version = "2.1.0" @@ -281,6 +502,29 @@ dependencies = [ "url", ] +[[package]] +name = "hyper" +version = "0.13.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a6f157065790a3ed2f88679250419b5cdd96e714a0d65f7797fd337186e96bb" +dependencies = [ + "bytes 0.5.6", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project", + "tokio 0.2.25", + "tower-service", + "tracing", + "want", +] + [[package]] name = "idna" version = "0.1.5" @@ -302,6 +546,30 @@ dependencies = [ "generic-array", ] +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg 1.0.1", + "hashbrown", +] + +[[package]] +name = "ipc-queue" +version = "0.1.0" +source = "git+https://github.com/fortanix/rust-sgx.git?branch=mz/async-usercalls#4cf2a8e12912bfd5e0ce8ef7fcf8f607110dfda2" +dependencies = [ + "fortanix-sgx-abi", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + [[package]] name = "language-tags" version = "0.2.2" @@ -322,9 +590,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.62" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" [[package]] name = "libloading" @@ -372,10 +640,17 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "mbedtls" version = "0.9.0" dependencies = [ + "async-stream", "bit-vec", "bitflags", "byteorder", @@ -384,7 +659,8 @@ dependencies = [ "cfg-if 1.0.0", "chrono", "hex", - "hyper", + "hyper 0.10.16", + "hyper 0.13.10", "libc", "matches", "mbedtls-sys-auto", @@ -396,6 +672,9 @@ dependencies = [ "serde_cbor", "serde_derive", "spin", + "tokio 0.2.25", + "tokio 0.3.4", + "tracing", "yasna", ] @@ -429,6 +708,29 @@ dependencies = [ "log 0.3.9", ] +[[package]] +name = "mio" +version = "0.7.6" +source = "git+https://github.com/mzohreva/mio?branch=mz/sgx-port-0.7.6#b4370d8bea9951f7f01e29115b8ca0e9bfa25a77" +dependencies = [ + "async-usercalls", + "crossbeam-channel", + "libc", + "log 0.4.8", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + [[package]] name = "nom" version = "5.1.2" @@ -439,13 +741,22 @@ dependencies = [ "version_check 0.9.2", ] +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + [[package]] name = "num-bigint" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343b3df15c945a59e72aae31e89a7cfc9e11850e96d4fde6fed5e3c7c8d9c887" dependencies = [ - "autocfg", + "autocfg 0.1.6", "num-integer", "num-traits", ] @@ -456,7 +767,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" dependencies = [ - "autocfg", + "autocfg 0.1.6", "num-traits", ] @@ -466,7 +777,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" dependencies = [ - "autocfg", + "autocfg 0.1.6", ] [[package]] @@ -497,12 +808,62 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +[[package]] +name = "pin-project" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea" +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + [[package]] name = "proc-macro2" version = "0.4.30" @@ -611,9 +972,9 @@ checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" [[package]] name = "rs-libc" -version = "0.2.2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b434763aff74b924c33af0ce3a3791c7c5ff8fb431773061dde30447e2fb77f0" +checksum = "80a671d6c4696a49b78e0a271c99bc58bc1a17a64893a3684a1ba1a944b26ca9" dependencies = [ "cc", ] @@ -673,6 +1034,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d" +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + [[package]] name = "spin" version = "0.4.10" @@ -760,12 +1127,121 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tokio" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" +dependencies = [ + "bytes 0.5.6", + "fnv", + "futures-core", + "memchr", + "pin-project-lite 0.1.12", +] + +[[package]] +name = "tokio" +version = "0.3.4" +source = "git+https://github.com/mzohreva/tokio?branch=mz/sgx-port-0.3.4#8af31a7b14986b34d6d544f48c2423e7b9792c7f" +dependencies = [ + "autocfg 1.0.1", + "bytes 0.6.0", + "lazy_static", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite 0.2.7", + "slab", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "0.3.1" +source = "git+https://github.com/mzohreva/tokio?branch=mz/sgx-port-0.3.4#8af31a7b14986b34d6d544f48c2423e7b9792c7f" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", +] + +[[package]] +name = "tokio-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +dependencies = [ + "bytes 0.5.6", + "futures-core", + "futures-sink", + "log 0.4.8", + "pin-project-lite 0.1.12", + "tokio 0.2.25", +] + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ba9ab62b7d6497a8638dfda5e5c4fb3b2d5a7fca4118f2b96151c8ef1a437e" +dependencies = [ + "cfg-if 1.0.0", + "log 0.4.8", + "pin-project-lite 0.2.7", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98863d0dd09fa59a1b79c6750ad80dbda6b75f4e71c437a6a1a8cb91a8bcbd77" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.9", + "syn 1.0.64", +] + +[[package]] +name = "tracing-core" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + [[package]] name = "typeable" version = "0.1.2" @@ -858,6 +1334,16 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log 0.4.8", + "try-lock", +] + [[package]] name = "which" version = "3.0.0" @@ -869,9 +1355,9 @@ dependencies = [ [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", diff --git a/Cargo.toml b/Cargo.toml index dd5aacf66..ea4ea1647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,8 @@ [workspace] members = ["mbedtls", "mbedtls-sys"] resolver = "2" + +[patch.crates-io] +mio = { git = "https://github.com/mzohreva/mio", branch = "mz/sgx-port-0.7.6" } +tokio = { git = "https://github.com/mzohreva/tokio", branch = "mz/sgx-port-0.3.4" } + diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index e77dfebd3..dfd16feeb 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -29,9 +29,10 @@ bit-vec = { version = "0.5", optional = true } cbc = { version = "0.1.2", optional = true } rc2 = { version = "0.8.1", optional = true } cfg-if = "1.0.0" +tokio = { version = "0.3.4", optional = true } [target.x86_64-fortanix-unknown-sgx.dependencies] -rs-libc = "0.2.0" +rs-libc = "0.1.0" chrono = "0.4" [dependencies.mbedtls-sys-auto] @@ -47,6 +48,11 @@ serde_cbor = "0.6" hex = "0.3" matches = "0.1.8" hyper = { version = "0.10.16", default-features = false } +hyper13 = { package = "hyper", version = "0.13", default-features = false, features = ["stream"] } +tokio-02 = { package = "tokio", version = "0.2", default-features = false } +async-stream = "0.3.0" +futures = "0.3" +tracing = "0.1" [build-dependencies] cc = "1.0" @@ -68,6 +74,8 @@ dsa = ["std", "yasna", "num-bigint", "bit-vec"] pkcs12 = ["std", "yasna"] pkcs12_rc2 = ["pkcs12", "rc2", "cbc"] legacy_protocols = ["mbedtls-sys-auto/legacy_protocols"] +async = ["std", "tokio","tokio/net","tokio/io-util", "tokio/macros"] +async-rt = ["async", "tokio/rt", "tokio/sync", "tokio/rt-multi-thread"] migration_mode=[] [[example]] @@ -101,3 +109,20 @@ required-features = ["std"] [[test]] name = "hyper" required-features = ["std"] + +[[test]] +name = "hyper13" +required-features = ["std", "async-rt"] + +[[test]] +name = "async_session" +path = "tests/async_session.rs" +required-features = ["async-rt"] + + +[package.metadata.fortanix-sgx] +threads = 100 +heap-size = 0x40000000 +stack-size = 0x100000 +# The following are not processed by the EDP tools but are picked up by build-enclave.sh: +#isvprodid = 66 diff --git a/mbedtls/src/ssl/async_utils.rs b/mbedtls/src/ssl/async_utils.rs new file mode 100644 index 000000000..e876a3e20 --- /dev/null +++ b/mbedtls/src/ssl/async_utils.rs @@ -0,0 +1,145 @@ +/* Copyright (c) Fortanix, Inc. + * + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except + * according to those terms. */ + +#![cfg(all(feature = "std", feature = "async"))] + +use std::cell::Cell; +use std::ptr::null_mut; +use std::rc::Rc; +use std::task::{Context as TaskContext, Poll}; + + +#[cfg(not(feature = "std"))] +use core_io::{Error as IoError, Result as IoResult, ErrorKind as IoErrorKind}; +#[cfg(feature = "std")] +use std::io::{Error as IoError, Result as IoResult, ErrorKind as IoErrorKind}; + + +#[derive(Clone)] +pub struct ErasedContext(Rc>); + +unsafe impl Send for ErasedContext {} + +impl ErasedContext { + pub fn new() -> Self { + Self(Rc::new(Cell::new(null_mut()))) + } + + pub unsafe fn get(&self) -> Option<&mut TaskContext<'_>> { + let ptr = self.0.get(); + if ptr.is_null() { + None + } else { + Some(&mut *(ptr as *mut _)) + } + } + + pub fn set(&self, cx: &mut TaskContext<'_>) { + self.0.set(cx as *mut _ as *mut ()); + } + + pub fn clear(&self) { + self.0.set(null_mut()); + } +} + +// mbedtls_ssl_write() has some weird semantics w.r.t non-blocking I/O: +// +// > When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, it must be +// > called later **with the same arguments**, until it returns a value greater +// > than or equal to 0. When the function returns MBEDTLS_ERR_SSL_WANT_WRITE +// > there may be some partial data in the output buffer, however this is not +// > yet sent. +// +// WriteTracker is used to ensure we pass the same data in that scenario. +// +// Reference: +// https://tls.mbed.org/api/ssl_8h.html#a5bbda87d484de82df730758b475f32e5 +pub struct WriteTracker { + pending: Option>, +} + +struct DigestAndLen { + #[cfg(debug_assertions)] + digest: [u8; 20], // SHA-1 + len: usize, +} + +impl WriteTracker { + fn new() -> Self { + WriteTracker { + pending: None, + } + } + + #[cfg(debug_assertions)] + fn digest(buf: &[u8]) -> [u8; 20] { + use crate::hash::{Md, Type}; + let mut out = [0u8; 20]; + let res = Md::hash(Type::Sha1, buf, &mut out[..]); + assert_eq!(res, Ok(out.len())); + out + } + + pub fn adjust_buf<'a>(&self, buf: &'a [u8]) -> IoResult<&'a [u8]> { + match self.pending.as_ref() { + None => Ok(buf), + Some(pending) => { + if pending.len <= buf.len() { + let buf = &buf[..pending.len]; + + // We only do this check in debug mode since it's an expensive check. + #[cfg(debug_assertions)] + if Self::digest(buf) == pending.digest { + return Ok(buf); + } + + #[cfg(not(debug_assertions))] + return Ok(buf); + } + Err(IoError::new( + IoErrorKind::Other, + "mbedtls expects the same data if the previous call to poll_write() returned Poll::Pending" + )) + }, + } + } + + pub fn post_write(&mut self, buf: &[u8], res: &Poll>) { + match res { + &Poll::Pending => { + if self.pending.is_none() { + self.pending = Some(Box::new(DigestAndLen { + #[cfg(debug_assertions)] + digest: Self::digest(buf), + len: buf.len(), + })); + } + }, + _ => { + self.pending = None; + } + } + } +} + +pub struct IoAdapter { + pub inner: S, + pub ecx: ErasedContext, + pub write_tracker: WriteTracker, +} + +impl IoAdapter { + pub fn new(stream: S) -> Self { + Self { + inner: stream, + ecx: ErasedContext::new(), + write_tracker: WriteTracker::new(), + } + } +} diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index 9beb3bd06..6d0f1c4f1 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -18,6 +18,9 @@ use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; use mbedtls_sys::types::size_t; use mbedtls_sys::*; +#[cfg(all(feature = "std", feature = "async"))] +use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; + #[cfg(not(feature = "std"))] use crate::alloc_prelude::*; use crate::alloc::{List as MbedtlsList}; @@ -25,6 +28,8 @@ use crate::error::{Error, Result, IntoResult}; use crate::pk::Pk; use crate::private::UnsafeFrom; use crate::ssl::config::{Config, Version, AuthMode}; +#[cfg(all(feature = "std", feature = "async"))] +use crate::ssl::async_utils::IoAdapter; use crate::x509::{Certificate, Crl, VerifyError}; pub trait IoCallback { @@ -227,6 +232,10 @@ impl<'a, T> Into<*mut ssl_context> for &'a mut Context { } } +#[cfg(all(feature = "std", feature = "async"))] +pub type AsyncContext = Context>; + + impl Context { pub fn new(config: Arc) -> Self { let mut inner = ssl_context::default(); @@ -620,6 +629,230 @@ impl HandshakeContext { } } +#[cfg(all(feature = "std", feature = "async"))] +pub trait IoAsyncCallback { + unsafe extern "C" fn call_recv_async(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int where Self: Sized; + unsafe extern "C" fn call_send_async(user_data: *mut c_void, data: *const c_uchar, len: size_t) -> c_int where Self: Sized; +} + +#[cfg(all(feature = "std", feature = "async"))] +impl IoAsyncCallback for IoAdapter { + unsafe extern "C" fn call_recv_async(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int { + let len = if len > (c_int::max_value() as size_t) { + c_int::max_value() as size_t + } else { + len + }; + + let adapter = &mut *(user_data as *mut IoAdapter); + + if let Some(cx) = adapter.ecx.get() { + let mut buf = ReadBuf::new(::core::slice::from_raw_parts_mut(data, len)); + let stream = Pin::new(&mut adapter.inner); + + match stream.poll_read(cx, &mut buf) { + Poll::Ready(Ok(())) => buf.filled().len() as c_int, + Poll::Ready(Err(_)) => ::mbedtls_sys::ERR_NET_RECV_FAILED, + Poll::Pending => ::mbedtls_sys::ERR_SSL_WANT_READ, + } + } else { + ::mbedtls_sys::ERR_NET_RECV_FAILED + } + } + + unsafe extern "C" fn call_send_async(user_data: *mut c_void, data: *const c_uchar, len: size_t) -> c_int { + let len = if len > (c_int::max_value() as size_t) { + c_int::max_value() as size_t + } else { + len + }; + + let adapter = &mut *(user_data as *mut IoAdapter); + + if let Some(cx) = adapter.ecx.get() { + let stream = Pin::new(&mut adapter.inner); + + match stream.poll_write(cx, ::core::slice::from_raw_parts(data, len)) { + Poll::Ready(Ok(i)) => i as c_int, + Poll::Ready(Err(_)) => ::mbedtls_sys::ERR_NET_RECV_FAILED, + Poll::Pending => ::mbedtls_sys::ERR_SSL_WANT_WRITE, + } + } else { + ::mbedtls_sys::ERR_NET_RECV_FAILED + } + } +} + +#[cfg(all(feature = "std", feature = "async"))] +struct HandshakeFuture<'a, T>(&'a mut Context::>); + +#[cfg(all(feature = "std", feature = "async"))] +impl std::future::Future for HandshakeFuture<'_, T> { + type Output = Result<()>; + fn poll(mut self: Pin<&mut Self>, ctx: &mut TaskContext) -> std::task::Poll { + self.0.io_mut().ok_or(Error::NetInvalidContext)? + .ecx.set(ctx); + + let result = match self.0.handshake() { + Err(Error::SslWantRead) | + Err(Error::SslWantWrite) => { + Poll::Pending + }, + Err(e) => Poll::Ready(Err(e)), + Ok(()) => Poll::Ready(Ok(())) + }; + + self.0.io_mut().map(|v| v.ecx.clear()); + + result + } +} + +#[cfg(all(feature = "std", feature = "async"))] +impl AsyncContext { + pub async fn accept_async(config: Arc, io: T, hostname: Option<&str>) -> IoResult> { + let mut context = Self::new(config); + context.establish_async(io, hostname).await.map_err(|e| crate::private::error_to_io_error(e))?; + Ok(context) + } + + pub async fn establish_async(&mut self, io: T, hostname: Option<&str>) -> Result<()> { + unsafe { + let mut io = Box::new(IoAdapter::new(io)); + + ssl_session_reset(self.into()).into_result()?; + self.set_hostname(hostname)?; + + let ptr = &mut *io as *mut _ as *mut c_void; + ssl_set_bio( + self.into(), + ptr, + Some(IoAdapter::::call_send_async), + Some(IoAdapter::::call_recv_async), + None, + ); + + self.io = Some(io); + self.inner.reset_handshake(); + } + + HandshakeFuture(self).await + } +} + +#[cfg(all(feature = "std", feature = "async"))] +impl AsyncRead for Context> { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut TaskContext<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + + if self.handle().session.is_null() { + return Poll::Ready(Err(IoError::new(IoErrorKind::Other, "stream has been shutdown"))); + } + + self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))? + .ecx.set(cx); + + let result = match unsafe { ssl_read((&mut *self).into(), buf.initialize_unfilled().as_mut_ptr(), buf.initialize_unfilled().len()).into_result() } { + Err(Error::SslPeerCloseNotify) => Poll::Ready(Ok(())), + Err(Error::SslWantRead) => Poll::Pending, + Err(e) => Poll::Ready(Err(crate::private::error_to_io_error(e))), + Ok(i) => { + buf.advance(i as usize); + Poll::Ready(Ok(())) + } + }; + + self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))? + .ecx.clear(); + + result + } +} + +#[cfg(all(feature = "std", feature = "async"))] +impl AsyncWrite for Context> { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut TaskContext<'_>, + buf: &[u8], + ) -> Poll> { + + if self.handle().session.is_null() { + return Poll::Ready(Err(IoError::new(IoErrorKind::Other, "stream has been shutdown"))); + } + + let buf = { + let io = self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))?; + io.ecx.set(cx); + io.write_tracker.adjust_buf(buf) + }?; + + + self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))? + .ecx.set(cx); + + let result = match unsafe { ssl_write((&mut *self).into(), buf.as_ptr(), buf.len()).into_result() } { + Err(Error::SslPeerCloseNotify) => Poll::Ready(Ok(0)), + Err(Error::SslWantWrite) => Poll::Pending, + Err(e) => Poll::Ready(Err(crate::private::error_to_io_error(e))), + Ok(i) => Poll::Ready(Ok(i as usize)) + }; + + let io = self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))?; + + io.ecx.clear(); + io.write_tracker.post_write(buf, &result); + + cx.waker().clone().wake(); + + result + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll> { + // We can only flush the actual IO here. + // To flush mbedtls we need writes with the same buffer until complete. + let io = &mut self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))? + .inner; + let stream = Pin::new(io); + stream.poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll> { + if self.handle().session.is_null() { + return Poll::Ready(Err(IoError::new(IoErrorKind::Other, "stream has been shutdown"))); + } + + self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))? + .ecx.set(cx); + + let result = match unsafe { ssl_close_notify((&mut *self).into()).into_result() } { + Err(Error::SslWantRead) | + Err(Error::SslWantWrite) => Poll::Pending, + Err(e) => { + unsafe { ssl_set_bio((&mut *self).into(), ::core::ptr::null_mut(), None, None, None); } + self.io = None; + Poll::Ready(Err(crate::private::error_to_io_error(e))) + } + Ok(0) => { + unsafe { ssl_set_bio((&mut *self).into(), ::core::ptr::null_mut(), None, None, None); } + self.io = None; + Poll::Ready(Ok(())) + } + Ok(v) => { + unsafe { ssl_set_bio((&mut *self).into(), ::core::ptr::null_mut(), None, None, None); } + self.io = None; + Poll::Ready(Err(IoError::new(IoErrorKind::Other, format!("unexpected result from ssl_close_notify: {}", v)))) + } + }; + + self.io_mut().map(|v| v.ecx.clear()); + result + } +} + #[cfg(test)] mod tests { #[cfg(feature = "std")] diff --git a/mbedtls/src/ssl/mod.rs b/mbedtls/src/ssl/mod.rs index 1bfc078cf..d0283ba0a 100644 --- a/mbedtls/src/ssl/mod.rs +++ b/mbedtls/src/ssl/mod.rs @@ -11,6 +11,7 @@ pub mod config; pub mod context; pub mod cookie; pub mod ticket; +pub mod async_utils; #[doc(inline)] pub use self::ciphersuites::CipherSuite; @@ -22,3 +23,6 @@ pub use self::context::Context; pub use self::cookie::CookieContext; #[doc(inline)] pub use self::ticket::TicketContext; +#[cfg(all(feature = "std", feature = "async"))] +#[doc(inline)] +pub use self::context::{AsyncContext}; diff --git a/mbedtls/tests/async_session.rs b/mbedtls/tests/async_session.rs new file mode 100644 index 000000000..b5442b8c3 --- /dev/null +++ b/mbedtls/tests/async_session.rs @@ -0,0 +1,295 @@ +/* Copyright (c) Fortanix, Inc. + * + * Licensed under the GNU General Public License, version 2 or the Apache License, Version + * 2.0 , at your + * option. This file may not be copied, modified, or distributed except + * according to those terms. */ + +#![cfg(not(target_env = "sgx"))] + +extern crate mbedtls; + +use std::sync::Arc; +use std::pin::Pin; +use std::future::Future; + +use mbedtls::pk::Pk; +use mbedtls::rng::CtrDrbg; +use mbedtls::ssl::config::{Endpoint, Preset, Transport}; +use mbedtls::ssl::{Config, Context, Version}; +use mbedtls::x509::{Certificate, VerifyError}; +use mbedtls::Error; +use mbedtls::Result as TlsResult; + +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::TcpStream; + +mod support; +use support::entropy::entropy_new; +use support::keys; + +use mbedtls::ssl::async_utils::IoAdapter; + +async fn client( + conn: TcpStream, + min_version: Version, + max_version: Version, + exp_version: Option) -> TlsResult<()> { + + let entropy = Arc::new(entropy_new()); + let rng = Arc::new(CtrDrbg::new(entropy, None)?); + let cacert = Arc::new(Certificate::from_pem_multiple(keys::ROOT_CA_CERT.as_bytes())?); + let expected_flags = VerifyError::empty(); + #[cfg(feature = "time")] + let expected_flags = expected_flags | VerifyError::CERT_EXPIRED; + { + let verify_callback = move |crt: &Certificate, depth: i32, verify_flags: &mut VerifyError| { + + match (crt.subject().unwrap().as_str(), depth, &verify_flags) { + ("CN=RootCA", 1, _) => (), + (keys::EXPIRED_CERT_SUBJECT, 0, flags) => assert_eq!(**flags, expected_flags), + _ => assert!(false), + }; + + verify_flags.remove(VerifyError::CERT_EXPIRED); //we check the flags at the end, + //so removing this flag here prevents the connections from failing with VerifyError + Ok(()) + }; + let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); + config.set_rng(rng); + config.set_verify_callback(verify_callback); + config.set_ca_list(cacert, None); + config.set_min_version(min_version)?; + config.set_max_version(max_version)?; + let mut ctx = Context::new(Arc::new(config)); + + match ctx.establish_async(conn, None).await { + Ok(()) => { + assert_eq!(ctx.version(), exp_version.unwrap()); + } + Err(e) => { + match e { + Error::SslBadHsProtocolVersion => {assert!(exp_version.is_none())}, + Error::SslFatalAlertMessage => {}, + e => panic!("Unexpected error {}", e), + }; + return Ok(()); + } + }; + + let ciphersuite = ctx.ciphersuite().unwrap(); + ctx + .write_all(format!("Client2Server {:4x}", ciphersuite).as_bytes()) + .await + .unwrap(); + let mut buf = [0u8; 13 + 4 + 1]; + ctx.read_exact(&mut buf).await.unwrap(); + assert_eq!(&buf, format!("Server2Client {:4x}", ciphersuite).as_bytes()); + } // drop verify_callback, releasing borrow of verify_args + Ok(()) +} + +async fn server( + conn: TcpStream, + min_version: Version, + max_version: Version, + exp_version: Option, +) -> TlsResult<()> { + let entropy = entropy_new(); + let rng = Arc::new(CtrDrbg::new(Arc::new(entropy), None)?); + let cert = Arc::new(Certificate::from_pem_multiple(keys::EXPIRED_CERT.as_bytes())?); + let key = Arc::new(Pk::from_private_key(keys::EXPIRED_KEY.as_bytes(), None)?); + let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default); + config.set_rng(rng); + config.set_min_version(min_version)?; + config.set_max_version(max_version)?; + config.push_cert(cert, key)?; + let mut ctx = Context::new(Arc::new(config)); + + match ctx.establish_async(conn, None).await { + Ok(()) => { + assert_eq!(ctx.version(), exp_version.unwrap()); + } + Err(e) => { + match e { + // client just closes connection instead of sending alert + Error::NetSendFailed => {assert!(exp_version.is_none())}, + Error::SslBadHsProtocolVersion => {}, + e => panic!("Unexpected error {}", e), + }; + return Ok(()); + } + }; + + //assert_eq!(ctx.get_alpn_protocol().unwrap().unwrap(), None); + let ciphersuite = ctx.ciphersuite().unwrap(); + ctx + .write_all(format!("Server2Client {:4x}", ciphersuite).as_bytes()) + .await + .unwrap(); + let mut buf = [0u8; 13 + 1 + 4]; + ctx.read_exact(&mut buf).await.unwrap(); + + assert_eq!(&buf, format!("Client2Server {:4x}", ciphersuite).as_bytes()); + Ok(()) +} + +async fn with_client(conn: TcpStream, f: F) -> R +where + F: FnOnce(Context>) -> Pin + Send>>, +{ + let entropy = Arc::new(entropy_new()); + let rng = Arc::new(CtrDrbg::new(entropy, None).unwrap()); + let cacert = Arc::new(Certificate::from_pem_multiple(keys::ROOT_CA_CERT.as_bytes()).unwrap()); + + let verify_callback = move |_crt: &Certificate, _depth: i32, verify_flags: &mut VerifyError| { + verify_flags.remove(VerifyError::CERT_EXPIRED); + Ok(()) + }; + + let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); + config.set_rng(rng); + config.set_verify_callback(verify_callback); + config.set_ca_list(cacert, None); + + let mut ctx = Context::new(Arc::new(config)); + ctx.establish_async(conn, None).await.unwrap(); + + f(ctx).await +} + +async fn with_server(conn: TcpStream, f: F) -> R +where + F: FnOnce(Context>) -> Pin + Send>>, +{ + let entropy = Arc::new(entropy_new()); + let rng = Arc::new(CtrDrbg::new(entropy, None).unwrap()); + let cert = Arc::new(Certificate::from_pem_multiple(keys::EXPIRED_CERT.as_bytes()).unwrap()); + let key = Arc::new(Pk::from_private_key(keys::EXPIRED_KEY.as_bytes(), None).unwrap()); + + let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default); + config.set_rng(rng); + config.push_cert(cert, key).unwrap(); + let mut ctx = Context::new(Arc::new(config)); + + ctx.establish_async(conn, None).await.unwrap(); + + f(ctx).await +} + +#[cfg(unix)] +mod test { + use tokio::io::{AsyncReadExt, AsyncWriteExt}; + + #[tokio::test] + async fn asyncsession_client_server_test() { + use mbedtls::ssl::Version; + + #[derive(Copy,Clone)] + struct TestConfig { + min_c: Version, + max_c: Version, + min_s: Version, + max_s: Version, + exp_ver: Option, + } + + impl TestConfig { + pub fn new(min_c: Version, max_c: Version, min_s: Version, max_s: Version, exp_ver: Option) -> Self { + TestConfig { min_c, max_c, min_s, max_s, exp_ver } + } + } + + let test_configs = [ + TestConfig::new(Version::Ssl3, Version::Ssl3, Version::Ssl3, Version::Ssl3, Some(Version::Ssl3)), + TestConfig::new(Version::Ssl3, Version::Tls1_2, Version::Ssl3, Version::Ssl3, Some(Version::Ssl3)), + TestConfig::new(Version::Tls1_0, Version::Tls1_0, Version::Tls1_0, Version::Tls1_0, Some(Version::Tls1_0)), + TestConfig::new(Version::Tls1_1, Version::Tls1_1, Version::Tls1_1, Version::Tls1_1, Some(Version::Tls1_1)), + TestConfig::new(Version::Tls1_2, Version::Tls1_2, Version::Tls1_2, Version::Tls1_2, Some(Version::Tls1_2)), + TestConfig::new(Version::Tls1_0, Version::Tls1_2, Version::Tls1_0, Version::Tls1_2, Some(Version::Tls1_2)), + TestConfig::new(Version::Tls1_2, Version::Tls1_2, Version::Tls1_0, Version::Tls1_2, Some(Version::Tls1_2)), + TestConfig::new(Version::Tls1_0, Version::Tls1_1, Version::Tls1_2, Version::Tls1_2, None) + ]; + + for config in &test_configs { + let min_c = config.min_c; + let max_c = config.max_c; + let min_s = config.min_s; + let max_s = config.max_s; + let exp_ver = config.exp_ver; + + if (max_c < Version::Tls1_2 || max_s < Version::Tls1_2) && !cfg!(feature = "legacy_protocols") { + continue; + } + + let (c, s) = crate::support::net::create_tcp_pair_async().unwrap(); + let c = tokio::spawn(super::client(c, min_c, max_c, exp_ver.clone())); + let s = tokio::spawn(super::server(s, min_s, max_s, exp_ver)); + + c.await.unwrap().unwrap(); + s.await.unwrap().unwrap(); + } + } + + #[tokio::test] + async fn asyncsession_shutdown1() { + let (c, s) = crate::support::net::create_tcp_pair_async().unwrap(); + + let c = tokio::spawn(super::with_client(c, |mut session| Box::pin(async move { + session.shutdown().await.unwrap(); + }))); + + let s = tokio::spawn(super::with_server(s, |mut session| Box::pin(async move { + let mut buf = [0u8; 1]; + match session.read(&mut buf).await { + Ok(0) | Err(_) => {} + _ => panic!("expected no data"), + } + }))); + + c.await.unwrap(); + s.await.unwrap(); + } + + #[tokio::test] + async fn asyncsession_shutdown2() { + let (c, s) = crate::support::net::create_tcp_pair_async().unwrap(); + + let c = tokio::spawn(super::with_client(c, |mut session| Box::pin(async move { + let mut buf = [0u8; 5]; + session.read_exact(&mut buf).await.unwrap(); + assert_eq!(&buf, b"hello"); + match session.read(&mut buf).await { + Ok(0) | Err(_) => {} + _ => panic!("expected no data"), + } + }))); + + let s = tokio::spawn(super::with_server(s, |mut session| Box::pin(async move { + session.write_all(b"hello").await.unwrap(); + session.shutdown().await.unwrap(); + }))); + + c.await.unwrap(); + s.await.unwrap(); + } + + #[tokio::test] + async fn asyncsession_shutdown3() { + let (c, s) = crate::support::net::create_tcp_pair_async().unwrap(); + + let c = tokio::spawn(super::with_client(c, |mut session| Box::pin(async move { + session.shutdown().await + }))); + + let s = tokio::spawn(super::with_server(s, |mut session| Box::pin(async move { + session.shutdown().await + }))); + + match (c.await.unwrap(), s.await.unwrap()) { + (Err(_), Err(_)) => panic!("at least one should succeed"), + _ => {} + } + } +} diff --git a/mbedtls/tests/hyper13.rs b/mbedtls/tests/hyper13.rs new file mode 100644 index 000000000..b1b2448f7 --- /dev/null +++ b/mbedtls/tests/hyper13.rs @@ -0,0 +1,322 @@ +#![allow(unused_imports)] + + +use async_stream::stream; + +use std::fmt; +use std::future::Future; +use std::io; +use std::io::{Error as IoError}; +use std::pin::Pin; +use std::sync::{Arc}; +use std::task::{Context as TaskContext, Poll}; +use std::net::SocketAddr; + +use hyper13::Server; +use hyper13::service::{make_service_fn, service_fn}; +use hyper13::client::connect::{Connected, Connection}; +use hyper13::{Client, service::Service, Uri, Request, Body, Method, Response, StatusCode}; +use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +use tokio::net::{TcpStream, TcpListener}; +use tokio_02::io::{AsyncRead as AsyncRead02, AsyncWrite as AsyncWrite02}; + +use mbedtls::ssl::async_utils::IoAdapter; +use mbedtls::ssl::{Config, AsyncContext}; + +use futures::stream::{FuturesUnordered}; + +#[derive(Clone)] +pub struct HttpsConnector { + config: Arc, +} + +#[derive(Debug)] +struct ForceHttpsButUriNotHttps; + +impl std::error::Error for ForceHttpsButUriNotHttps {} + +impl fmt::Display for ForceHttpsButUriNotHttps { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("https required but URI was not https") + } +} + +const DEFAULT_HTTPS_PORT: u16 = 443; + +impl Service for HttpsConnector { + type Response = IoCompat>; + type Error = Box; + type Future = Pin> + Send>>; + + fn poll_ready(&mut self, _cx: &mut TaskContext<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, dst: Uri) -> Self::Future { + // Strip [] for IPv6 addresses + let host = dst.host().unwrap_or("").trim_matches(|c| c == '[' || c == ']').to_owned(); + let port = dst.port_u16().unwrap_or(DEFAULT_HTTPS_PORT); + let config = self.config.clone(); + + Box::pin(async move { + if dst.scheme_str() != Some("https") { + return Err(ForceHttpsButUriNotHttps.into()); + } + + let tcp = TcpStream::connect((host.clone(), port)).await?; + let mut tls = AsyncContext::new(config); + tls.establish_async(tcp, Some(&host)).await?; + Ok(IoCompat(tls)) + }) + } +} + +// IoCompat is needed because hyper 0.13 relies on tokio 0.2's `AsyncRead` +// and `AsyncWrite` traits. It would have been nice if we could use +// `tokio_compat_02::IoCompat`, but that type does not implement `Connection` +// and we cannot impl `Connection` for it here either since it's not defined +// in this crate. +pub struct IoCompat(T); + +impl Connection for IoCompat { + fn connected(&self) -> Connected { + let connected = Connected::new(); + //check_alpn(&self.0, connected) + connected + } +} + +impl AsyncRead02 for IoCompat { + fn poll_read(self: Pin<&mut Self>, cx: &mut TaskContext, buf: &mut [u8]) -> Poll> { + let mut read_buf = ReadBuf::new(buf); + match Pin::new(&mut self.get_mut().0).poll_read(cx, &mut read_buf) { + Poll::Ready(Ok(())) => Poll::Ready(Ok(read_buf.filled().len())), + Poll::Ready(Err(err)) => Poll::Ready(Err(err)), + Poll::Pending => Poll::Pending, + } + } +} + +impl AsyncWrite02 for IoCompat { + fn poll_write(self: Pin<&mut Self>, cx: &mut TaskContext<'_>, buf: &[u8]) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_write(cx, buf) + } + fn poll_flush(self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_flush(cx) + } + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_shutdown(cx) + } +} + +#[derive(Copy, Clone)] +pub struct TokioExecutor; + +impl hyper13::rt::Executor for TokioExecutor +where + F: Future + Send + 'static, + F::Output: Send + 'static, +{ + fn execute(&self, fut: F) { + tokio::spawn(fut); + } +} + + + +use tokio_02::stream::Stream; + +type TlsFuture = Pin>, IoError>> + Send>>; + +pub struct HyperAcceptor { + clients: FuturesUnordered>>, io::Error>>>, + listener: TcpListener, + config: Arc, +} + +impl HyperAcceptor { + pub async fn create(config: Arc, addr: &str) -> Result { + let listener = TcpListener::bind(addr).await?; + + Ok(HyperAcceptor { + clients: FuturesUnordered::new(), + listener, + config, + }) + } +} + +const MAX_CONCURRENT_ACCEPTS: usize = 100; + +impl hyper13::server::accept::Accept for HyperAcceptor { + type Conn = IoCompat>; + type Error = io::Error; + + fn poll_accept(mut self: Pin<&mut Self>, cx: &mut TaskContext,) -> Poll>> { + if self.clients.len() < MAX_CONCURRENT_ACCEPTS { + match self.listener.poll_accept(cx) { + Poll::Pending => (), + Poll::Ready(Ok((conn, _addr))) => { + let config = self.config.clone(); + self.clients.push(tokio::spawn(async move { + let context = AsyncContext::accept_async(config, conn, None).await?; + Ok(IoCompat(context)) + })); + }, + Poll::Ready(Err(e)) => { + // We likely don't care about user errors enough to stop processing under normal circumstances + return Poll::Ready(Some(Err(e))); + }, + }; + } + + if self.clients.len() > 0 { + match Pin::new(&mut self.clients).poll_next(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(Some(v)) => Poll::Ready(Some(v?)), // fold Result Poll::Ready(None), + } + } else { + Poll::Pending + } + } +} + + + +#[cfg(test)] +mod tests { + // Note this useful idiom: importing names from outer (for mod tests) scope. + use super::*; + + use mbedtls::pk::Pk; + use mbedtls::ssl::Config; + use mbedtls::ssl::config::{Endpoint, Preset, Transport, AuthMode, Version, UseSessionTickets, Renegotiation}; + use mbedtls::ssl::context::HandshakeContext; + use mbedtls::x509::{Certificate, VerifyError}; + use std::sync::Arc; + use mbedtls::ssl::CipherSuite::*; + use std::io::Write; + use mbedtls::ssl::TicketContext; + use std::time::Instant; + + #[cfg(not(target_env = "sgx"))] + use mbedtls::rng::{OsEntropy, CtrDrbg, HmacDrbg}; + + #[cfg(target_env = "sgx")] + use mbedtls::rng::{Rdrand}; + + use tokio::io::{AsyncReadExt, AsyncWriteExt}; + use tokio_02::stream::StreamExt; + use futures::stream::{FuturesUnordered}; + + #[cfg(not(target_env = "sgx"))] + pub fn rng_new() -> Arc { + let entropy = Arc::new(OsEntropy::new()); + let rng = Arc::new(CtrDrbg::new(entropy, None).unwrap()); + rng + } + + #[cfg(target_env = "sgx")] + pub fn rng_new() -> Arc { + Arc::new(Rdrand) + } + + pub const PEM_KEY: &'static [u8] = concat!(include_str!("./support/keys/user.key"),"\0").as_bytes(); + pub const PEM_CERT: &'static [u8] = concat!(include_str!("./support/keys/user.crt"),"\0").as_bytes(); + pub const ROOT_CA_CERT: &'static [u8] = concat!(include_str!("./support/keys/ca.crt"),"\0").as_bytes(); + + #[tokio::test] + async fn async_hyper_client_test() { + + let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); + config.set_authmode(AuthMode::None); + config.set_rng(rng_new()); + config.set_min_version(Version::Tls1_2).unwrap(); + + let https = HttpsConnector { config: Arc::new(config) }; + let client = Client::builder().executor(TokioExecutor).build::<_, hyper13::Body>(https); + + let res = client.get("https://hyper.rs".parse().unwrap()).await.unwrap(); + assert_eq!(res.status(), 200); + } + + async fn echo(req: Request) -> Result, hyper::Error> { + let mut response = Response::new(Body::empty()); + + match (req.method(), req.uri().path()) { + (&Method::GET, "/") => *response.body_mut() = Body::from("Try POST /echo\n"), + (&Method::POST, "/echo") => *response.body_mut() = req.into_body(), + _ => *response.status_mut() = StatusCode::NOT_FOUND, + }; + + Ok(response) + } + + async fn get_acceptor(address: &str) -> Result { + let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default); + + config.set_rng(rng_new()); + config.set_authmode(AuthMode::None); + config.set_min_version(Version::Tls1_2).unwrap(); + + let cert = Arc::new(Certificate::from_pem_multiple(PEM_CERT).unwrap()); + let key = Arc::new(Pk::from_private_key(PEM_KEY, None).unwrap()); + config.push_cert(cert, key).unwrap(); + + HyperAcceptor::create(Arc::new(config), address).await + } + + #[tokio::test] + async fn async_hyper_server_fullhandshake_test() { + std::env::set_var("RUST_BACKTRACE", "full"); + + // Set up hyper server to echo function and a graceful shutdown + let acceptor = get_acceptor("127.0.0.1:0").await.unwrap(); + let local_addr = acceptor.listener.local_addr().unwrap().clone(); + + let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(echo)) }); + let server = Server::builder(acceptor).executor(TokioExecutor).serve(service); + + let (tx, rx) = tokio::sync::oneshot::channel::<()>(); + let graceful = server.with_graceful_shutdown(async { rx.await.ok(); }); + + let s = tokio::spawn(graceful); + + let mut clients = FuturesUnordered::new(); + + let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); + config.set_authmode(AuthMode::None); + config.set_rng(rng_new()); + config.set_min_version(Version::Tls1_2).unwrap(); + let config = Arc::new(config); + + let start = Instant::now(); + + for _ in 0..100 { + let config = config.clone(); + + clients.push(tokio::spawn(async move { + let client = Client::builder().executor(TokioExecutor).build::<_, hyper13::Body>(HttpsConnector { config }); + + let mut res = client.get(format!("https://{}/", local_addr).parse().unwrap()).await.unwrap(); + assert_eq!(res.status(), 200); + + let body_bytes = hyper13::body::to_bytes(res.into_body()).await.unwrap(); + let body = String::from_utf8(body_bytes.to_vec()).expect("response was not valid utf-8"); + assert_eq!(body, "Try POST /echo\n"); + })); + + if clients.len() > MAX_CONCURRENT_ACCEPTS { + clients.next().await.unwrap(); + } + } + + while let Some(r) = clients.next().await { + r.unwrap(); + } + + tx.send(()); + s.await.unwrap().unwrap(); + } +} diff --git a/mbedtls/tests/support/net.rs b/mbedtls/tests/support/net.rs index f061b32af..9446d7f7f 100644 --- a/mbedtls/tests/support/net.rs +++ b/mbedtls/tests/support/net.rs @@ -26,3 +26,14 @@ pub fn create_tcp_pair() -> IoResult<(TcpStream, TcpStream)> { } } } + +#[cfg(feature = "tokio")] +pub fn create_tcp_pair_async() -> IoResult<(tokio::net::TcpStream, tokio::net::TcpStream)> { + let (c, s) = create_tcp_pair()?; + c.set_nonblocking(true)?; + s.set_nonblocking(true)?; + Ok(( + tokio::net::TcpStream::from_std(c)?, + tokio::net::TcpStream::from_std(s)?, + )) +} From 30f288c5138aab3c6b62bee78c5c5874bcf713c2 Mon Sep 17 00:00:00 2001 From: Adrian Cruceru Date: Mon, 3 Jan 2022 09:53:27 +0000 Subject: [PATCH 03/14] Update unit tests --- mbedtls/tests/ssl_conf_ca_cb.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mbedtls/tests/ssl_conf_ca_cb.rs b/mbedtls/tests/ssl_conf_ca_cb.rs index 981a6f084..370400333 100644 --- a/mbedtls/tests/ssl_conf_ca_cb.rs +++ b/mbedtls/tests/ssl_conf_ca_cb.rs @@ -60,7 +60,8 @@ mod test { use crate::support::keys; use mbedtls::x509::{Certificate}; use mbedtls::Error; - + use mbedtls::alloc::{List as MbedtlsList, Box as MbedtlsBox}; + // This callback should accept any valid self-signed certificate fn self_signed_ca_callback(child: &MbedtlsList) -> TlsResult> { Ok(child.clone()) From b0e7b071e0f670fcf9d4a95d4be8cfa1019f9c6a Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Tue, 14 Mar 2023 13:18:47 -0700 Subject: [PATCH 04/14] fix: resolve rebase error --- Cargo.lock | 26 ++++++++++++++++++++++++-- mbedtls/Cargo.toml | 14 +++----------- mbedtls/src/pk/mod.rs | 2 +- mbedtls/src/ssl/context.rs | 14 +++++++++++--- mbedtls/tests/ssl_conf_ca_cb.rs | 4 ++-- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33cb3d1c4..541faf062 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -263,6 +263,27 @@ dependencies = [ "typenum", ] +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg 1.0.1", + "cfg-if 0.1.10", + "lazy_static", +] + [[package]] name = "env_logger" version = "0.8.3" @@ -658,6 +679,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "chrono", + "futures", "hex", "hyper 0.10.16", "hyper 0.13.10", @@ -972,9 +994,9 @@ checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" [[package]] name = "rs-libc" -version = "0.1.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80a671d6c4696a49b78e0a271c99bc58bc1a17a64893a3684a1ba1a944b26ca9" +checksum = "914c985b921cf571d950d17ca33221ed54fed3c2001a329ee6fd5b15dd433260" dependencies = [ "cc", ] diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index dfd16feeb..c109f7185 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -32,11 +32,11 @@ cfg-if = "1.0.0" tokio = { version = "0.3.4", optional = true } [target.x86_64-fortanix-unknown-sgx.dependencies] -rs-libc = "0.1.0" +rs-libc = "0.2.0" chrono = "0.4" [dependencies.mbedtls-sys-auto] -version = "2.26.0" +version = "2.28.0" default-features = false features = ["custom_printf", "trusted_cert_callback", "threading"] path = "../mbedtls-sys" @@ -61,7 +61,7 @@ cc = "1.0" # Features are documented in the README default = ["std", "aesni", "time", "padlock"] std = ["byteorder/std", "mbedtls-sys-auto/std", "serde/std", "yasna"] -debug = ["mbedtls-sys-auto/debug"] +debug = [] no_std_deps = ["spin", "serde/alloc"] force_aesni_support = ["mbedtls-sys-auto/custom_has_support", "mbedtls-sys-auto/aes_alt", "aesni"] mpi_force_c_code = ["mbedtls-sys-auto/mpi_force_c_code"] @@ -118,11 +118,3 @@ required-features = ["std", "async-rt"] name = "async_session" path = "tests/async_session.rs" required-features = ["async-rt"] - - -[package.metadata.fortanix-sgx] -threads = 100 -heap-size = 0x40000000 -stack-size = 0x100000 -# The following are not processed by the EDP tools but are picked up by build-enclave.sh: -#isvprodid = 66 diff --git a/mbedtls/src/pk/mod.rs b/mbedtls/src/pk/mod.rs index 1343f0acb..94a0eef20 100644 --- a/mbedtls/src/pk/mod.rs +++ b/mbedtls/src/pk/mod.rs @@ -1227,7 +1227,7 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi #[test] fn rsa_sign_verify_pkcs1v15() { - let pk = + let mut pk = Pk::generate_rsa(&mut crate::test_support::rand::test_rng(), 2048, 0x10001).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SIGNATURE TEST SIGNATURE TEST SIGN"; let mut signature = vec![0u8; (pk.len() + 7) / 8]; diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index 6d0f1c4f1..0816c054b 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -14,6 +14,14 @@ use { std::sync::Arc, }; +#[cfg(all(feature = "std", feature = "async"))] +use { + std::io::ErrorKind as IoErrorKind, + std::marker::Unpin, + std::pin::Pin, + std::task::{Context as TaskContext, Poll}, +}; + use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; use mbedtls_sys::types::size_t; use mbedtls_sys::*; @@ -260,12 +268,11 @@ impl Context { client_transport_id: None, } } -} - + pub(crate) fn handle(&self) -> &::mbedtls_sys::ssl_context { self.inner.handle() } - + pub(crate) fn handle_mut(&mut self) -> &mut ::mbedtls_sys::ssl_context { self.inner.handle_mut() } @@ -551,6 +558,7 @@ impl Write for Context { Ok(()) } } + // // Class exists only during SNI callback that is configured from Config. // SNI Callback must provide input whose lifetime exceeds the SNI closure to avoid memory corruptions. diff --git a/mbedtls/tests/ssl_conf_ca_cb.rs b/mbedtls/tests/ssl_conf_ca_cb.rs index 370400333..1fed49686 100644 --- a/mbedtls/tests/ssl_conf_ca_cb.rs +++ b/mbedtls/tests/ssl_conf_ca_cb.rs @@ -58,9 +58,9 @@ mod test { use std::thread; use crate::support::net::create_tcp_pair; use crate::support::keys; - use mbedtls::x509::{Certificate}; + use mbedtls::x509::Certificate; use mbedtls::Error; - use mbedtls::alloc::{List as MbedtlsList, Box as MbedtlsBox}; + use mbedtls::alloc::List as MbedtlsList; // This callback should accept any valid self-signed certificate fn self_signed_ca_callback(child: &MbedtlsList) -> TlsResult> { From d0302dcd9700f317feb7cd05a5ec43ee2392c784 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Tue, 14 Mar 2023 13:46:53 -0700 Subject: [PATCH 05/14] test: update tests for async --- ct.sh | 2 ++ mbedtls/tests/async_session.rs | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ct.sh b/ct.sh index c3689b25f..bb4759919 100755 --- a/ct.sh +++ b/ct.sh @@ -33,6 +33,8 @@ if [ "$TRAVIS_RUST_VERSION" == "stable" ] || [ "$TRAVIS_RUST_VERSION" == "beta" cargo test --features pkcs12 --target $TARGET cargo test --features pkcs12_rc2 --target $TARGET cargo test --features dsa --target $TARGET + cargo test --test hyper13 --features=std,async-rt --target $TARGET + cargo test --test async_session --features=async-rt --target $TARGET # If zlib is installed, test the zlib feature if [ -n "$ZLIB_INSTALLED" ]; then diff --git a/mbedtls/tests/async_session.rs b/mbedtls/tests/async_session.rs index b5442b8c3..98b113a78 100644 --- a/mbedtls/tests/async_session.rs +++ b/mbedtls/tests/async_session.rs @@ -7,7 +7,6 @@ * according to those terms. */ #![cfg(not(target_env = "sgx"))] - extern crate mbedtls; use std::sync::Arc; From fb7679955cb0816dd3c2aca0b1e9a2b814f347e5 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Wed, 15 Mar 2023 13:07:28 -0700 Subject: [PATCH 06/14] remove feature `migration_mode` --- mbedtls/Cargo.toml | 1 - mbedtls/src/lib.rs | 7 ++----- mbedtls/src/self_test.rs | 4 ---- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index c109f7185..5af95a6a5 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -76,7 +76,6 @@ pkcs12_rc2 = ["pkcs12", "rc2", "cbc"] legacy_protocols = ["mbedtls-sys-auto/legacy_protocols"] async = ["std", "tokio","tokio/net","tokio/io-util", "tokio/macros"] async-rt = ["async", "tokio/rt", "tokio/sync", "tokio/rt-multi-thread"] -migration_mode=[] [[example]] name = "client" diff --git a/mbedtls/src/lib.rs b/mbedtls/src/lib.rs index 90aa5b040..07b18e9d1 100644 --- a/mbedtls/src/lib.rs +++ b/mbedtls/src/lib.rs @@ -53,11 +53,9 @@ mod private; // needs to be pub for global visiblity #[doc(hidden)] - -#[cfg(all(sys_threading_component = "custom", not(feature = "migration_mode")))] +#[cfg(sys_threading_component = "custom")] pub mod threading; -#[cfg(not(feature = "migration_mode"))] cfg_if::cfg_if! { if #[cfg(any(feature = "force_aesni_support", target_env = "sgx"))] { // needs to be pub for global visiblity @@ -107,7 +105,6 @@ mod alloc_prelude { pub(crate) use rust_alloc::borrow::Cow; } -#[cfg(not(feature = "migration_mode"))] cfg_if::cfg_if! { if #[cfg(sys_time_component = "custom")] { use mbedtls_sys::types::{time_t, tm}; @@ -157,7 +154,7 @@ cfg_if::cfg_if! { /// /// The caller must ensure no other MbedTLS code is running when calling this /// function. -#[cfg(all(feature = "debug", not(feature = "migration_mode")))] +#[cfg(feature = "debug")] pub unsafe fn set_global_debug_threshold(threshold: i32) { mbedtls_sys::debug_set_threshold(threshold); } diff --git a/mbedtls/src/self_test.rs b/mbedtls/src/self_test.rs index fa3b71f7f..6e35dfc2f 100644 --- a/mbedtls/src/self_test.rs +++ b/mbedtls/src/self_test.rs @@ -40,8 +40,6 @@ cfg_if::cfg_if! { } } } - -#[cfg(not(feature = "migration_mode"))] cfg_if::cfg_if! { if #[cfg(any(not(feature = "std"), target_env = "sgx"))] { #[allow(non_upper_case_globals)] @@ -68,7 +66,6 @@ cfg_if::cfg_if! { /// The caller needs to ensure this function is not called while any other /// function in this module is called. #[allow(unused)] -#[cfg(not(feature = "migration_mode"))] pub unsafe fn enable(rand: fn() -> c_int, log: Option) { #[cfg(any(not(feature = "std"), target_env = "sgx"))] { rand_f = Some(rand); @@ -82,7 +79,6 @@ pub unsafe fn enable(rand: fn() -> c_int, log: Option) /// /// The caller needs to ensure this function is not called while any other /// function in this module is called. -#[cfg(not(feature = "migration_mode"))] pub unsafe fn disable() { #[cfg(any(not(feature = "std"), target_env = "sgx"))] { rand_f = None; From 956aae793266853829f82411d65e57a1cec16fff Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Wed, 15 Mar 2023 13:09:11 -0700 Subject: [PATCH 07/14] revert changes on fn Pk::{sign, verify} Revert changing `&mut self` to `&self` --- mbedtls/src/pk/mod.rs | 9 +++++---- mbedtls/tests/ec.rs | 6 +++--- mbedtls/tests/rsa.rs | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mbedtls/src/pk/mod.rs b/mbedtls/src/pk/mod.rs index 94a0eef20..0c4c5e99b 100644 --- a/mbedtls/src/pk/mod.rs +++ b/mbedtls/src/pk/mod.rs @@ -799,7 +799,7 @@ impl Pk { /// /// On success, returns the actual number of bytes written to `sig`. pub fn sign( - &self, + &mut self, md: MdType, hash: &[u8], sig: &mut [u8], @@ -826,7 +826,7 @@ impl Pk { let mut ret = 0usize; unsafe { pk_sign( - &self.inner as *const _ as *mut _, + &mut self.inner, md.into(), hash.as_ptr(), hash.len(), @@ -895,14 +895,15 @@ impl Pk { } } - pub fn verify(&self, md: MdType, hash: &[u8], sig: &[u8]) -> Result<()> { + pub fn verify(&mut self, md: MdType, hash: &[u8], sig: &[u8]) -> Result<()> { + // If hash or sig are allowed with size 0 (&[]) then mbedtls will attempt to auto-detect size and cause an invalid write. if hash.len() == 0 || sig.len() == 0 { return Err(Error::PkBadInputData) } unsafe { pk_verify( - &self.inner as *const _ as *mut _, + &mut self.inner, md.into(), hash.as_ptr(), hash.len(), diff --git a/mbedtls/tests/ec.rs b/mbedtls/tests/ec.rs index aea532209..2ecdc25c4 100644 --- a/mbedtls/tests/ec.rs +++ b/mbedtls/tests/ec.rs @@ -44,7 +44,7 @@ wvkbR/h/+CNU1mMPdGoooNsldBtbNKgoAIsirMI/kk+q+9TTP4HqZpVt/qor/fz1 #[test] fn sign_verify() { - let k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); + let mut k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature1 = [0u8; ECDSA_MAX_LEN]; @@ -67,7 +67,7 @@ fn sign_verify() { #[test] fn verify_failure() { - let k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); + let mut k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature = [0u8; ECDSA_MAX_LEN]; @@ -150,7 +150,7 @@ fn sign_verify_rfc6979_sig() { #[test] fn buffer_too_small() { - let k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); + let mut k = Pk::from_private_key(TEST_KEY_PEM.as_bytes(), None).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature = [0u8; ECDSA_MAX_LEN - 1]; diff --git a/mbedtls/tests/rsa.rs b/mbedtls/tests/rsa.rs index 84815191d..33c3d68d2 100644 --- a/mbedtls/tests/rsa.rs +++ b/mbedtls/tests/rsa.rs @@ -21,7 +21,7 @@ const EXPONENT: u32 = 0x10001; #[test] fn sign_verify() { - let k = Pk::generate_rsa(&mut test_rng(), RSA_BITS, EXPONENT).unwrap(); + let mut k = Pk::generate_rsa(&mut test_rng(), RSA_BITS, EXPONENT).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature = [0u8; RSA_BITS as usize / 8]; @@ -36,7 +36,7 @@ fn sign_verify() { #[test] fn buffer_too_small() { - let k = Pk::generate_rsa(&mut test_rng(), RSA_BITS, EXPONENT).unwrap(); + let mut k = Pk::generate_rsa(&mut test_rng(), RSA_BITS, EXPONENT).unwrap(); let data = b"SIGNATURE TEST SIGNATURE TEST SI"; let mut signature = [0u8; RSA_BITS as usize / 8 - 1]; From 147ce091d7cdeec330fbe8258aba97c2206dde29 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Wed, 15 Mar 2023 13:12:35 -0700 Subject: [PATCH 08/14] revert changes of mbedtls_log --- mbedtls/src/rust_printf.c | 4 ++-- mbedtls/src/self_test.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mbedtls/src/rust_printf.c b/mbedtls/src/rust_printf.c index 183552e0d..c3b2ac93c 100644 --- a/mbedtls/src/rust_printf.c +++ b/mbedtls/src/rust_printf.c @@ -9,7 +9,7 @@ #include #include -extern void mbedtls8_log(const char* msg); +extern void mbedtls_log(const char* msg); extern int mbedtls_printf(const char *fmt, ...) { va_list ap; @@ -31,7 +31,7 @@ extern int mbedtls_printf(const char *fmt, ...) { if (n<0) return -1; - mbedtls8_log(p); + mbedtls_log(p); return n; } diff --git a/mbedtls/src/self_test.rs b/mbedtls/src/self_test.rs index 6e35dfc2f..659b5ea69 100644 --- a/mbedtls/src/self_test.rs +++ b/mbedtls/src/self_test.rs @@ -25,7 +25,7 @@ cfg_if::cfg_if! { // needs to be pub for global visiblity #[doc(hidden)] #[no_mangle] - pub unsafe extern "C" fn mbedtls8_log(msg: *const std::os::raw::c_char) { + pub unsafe extern "C" fn mbedtls_log(msg: *const std::os::raw::c_char) { print!("{}", std::ffi::CStr::from_ptr(msg).to_string_lossy()); } } else { @@ -35,7 +35,7 @@ cfg_if::cfg_if! { // needs to be pub for global visiblity #[doc(hidden)] #[no_mangle] - pub unsafe extern "C" fn mbedtls8_log(msg: *const c_char) { + pub unsafe extern "C" fn mbedtls_log(msg: *const c_char) { log_f.expect("Called self-test log without enabling self-test")(msg) } } From 9215561b8a8ed9d607bd2fc5c90f9fbbcafc01af Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Wed, 15 Mar 2023 13:13:22 -0700 Subject: [PATCH 09/14] cleanup & improve code style --- mbedtls/src/pk/mod.rs | 37 +++++++++++++++--- mbedtls/src/ssl/context.rs | 66 ++++++++++++++++----------------- mbedtls/tests/ssl_conf_ca_cb.rs | 3 +- 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/mbedtls/src/pk/mod.rs b/mbedtls/src/pk/mod.rs index 0c4c5e99b..f5b6b47a9 100644 --- a/mbedtls/src/pk/mod.rs +++ b/mbedtls/src/pk/mod.rs @@ -163,7 +163,7 @@ define!( // B. Verifying thread safety. // // 1. Calls towards the specific Pk implementation are done via function pointers. -// +// // - Example call towards Pk: // ../../../mbedtls-sys/vendor/library/ssl_srv.c:3707 - mbedtls_pk_decrypt( private_key, p, len, ... // - This calls a generic function pointer via: @@ -174,7 +174,7 @@ define!( // - The function pointers are defined via function: // ../../../mbedtls-sys/vendor/crypto/library/pk.c:115 - mbedtls_pk_info_from_type // - They are as follows: mbedtls_rsa_info / mbedtls_eckey_info / mbedtls_ecdsa_info -// - These are defined in: +// - These are defined in: // ../../../mbedtls-sys/vendor/crypto/library/pk_wrap.c:196 // // C. Checking types one by one. @@ -201,7 +201,34 @@ define!( // // - Only used when creating/freeing - which is safe by design - eckey_alloc_wrap / eckey_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) +// 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 // unsafe impl Sync for Pk {} @@ -900,7 +927,7 @@ impl Pk { if hash.len() == 0 || sig.len() == 0 { return Err(Error::PkBadInputData) } - + unsafe { pk_verify( &mut self.inner, @@ -1270,7 +1297,7 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi let mut dummy_sig = []; assert_eq!(pk.sign(digest, data, &mut dummy_sig, &mut crate::test_support::rand::test_rng()).unwrap_err(), Error::PkBadInputData); assert_eq!(pk.sign(digest, &[], &mut signature, &mut crate::test_support::rand::test_rng()).unwrap_err(), Error::PkBadInputData); - + assert_eq!(pk.sign_deterministic(digest, data, &mut dummy_sig, &mut crate::test_support::rand::test_rng()).unwrap_err(), Error::PkBadInputData); assert_eq!(pk.sign_deterministic(digest, &[], &mut signature, &mut crate::test_support::rand::test_rng()).unwrap_err(), Error::PkBadInputData); diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index 0816c054b..e02654ca7 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -20,15 +20,14 @@ use { std::marker::Unpin, std::pin::Pin, std::task::{Context as TaskContext, Poll}, + tokio::io::{AsyncRead, AsyncWrite, ReadBuf}, + crate::ssl::async_utils::IoAdapter, }; use mbedtls_sys::types::raw_types::{c_int, c_uchar, c_void}; use mbedtls_sys::types::size_t; use mbedtls_sys::*; -#[cfg(all(feature = "std", feature = "async"))] -use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; - #[cfg(not(feature = "std"))] use crate::alloc_prelude::*; use crate::alloc::{List as MbedtlsList}; @@ -36,8 +35,6 @@ use crate::error::{Error, Result, IntoResult}; use crate::pk::Pk; use crate::private::UnsafeFrom; use crate::ssl::config::{Config, Version, AuthMode}; -#[cfg(all(feature = "std", feature = "async"))] -use crate::ssl::async_utils::IoAdapter; use crate::x509::{Certificate, Crl, VerifyError}; pub trait IoCallback { @@ -199,7 +196,7 @@ define!( struct HandshakeContext { handshake_ca_cert: Option>>, handshake_crl: Option>, - + handshake_cert: Vec>>, handshake_pk: Vec>, }; @@ -213,10 +210,10 @@ define!( pub struct Context { // Base structure used in SNI callback where we cannot determine the io type. inner: HandshakeContext, - + // config is used read-only for multiple contexts and is immutable once configured. - config: Arc, - + 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>, @@ -240,14 +237,10 @@ impl<'a, T> Into<*mut ssl_context> for &'a mut Context { } } -#[cfg(all(feature = "std", feature = "async"))] -pub type AsyncContext = 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()); @@ -258,7 +251,7 @@ impl Context { inner, handshake_ca_cert: None, handshake_crl: None, - + handshake_cert: vec![], handshake_pk: vec![], }, @@ -268,11 +261,11 @@ impl Context { client_transport_id: None, } } - + pub(crate) fn handle(&self) -> &::mbedtls_sys::ssl_context { self.inner.handle() } - + pub(crate) fn handle_mut(&mut self) -> &mut ::mbedtls_sys::ssl_context { self.inner.handle_mut() } @@ -385,7 +378,7 @@ impl Context { pub fn config(&self) -> &Arc { &self.config } - + pub fn close(&mut self) { unsafe { ssl_close_notify(self.into()); @@ -393,15 +386,15 @@ impl Context { self.io = None; } } - + pub fn io(&self) -> Option<&T> { self.io.as_ref().map(|v| &**v) } - + pub fn io_mut(&mut self) -> Option<&mut T> { self.io.as_mut().map(|v| &mut **v) } - + /// Return the minor number of the negotiated TLS version pub fn minor_version(&self) -> i32 { self.handle().minor_ver @@ -433,7 +426,7 @@ impl Context { // Session specific functions - + /// Return the 16-bit ciphersuite identifier. /// All assigned ciphersuites are listed by the IANA in /// @@ -441,7 +434,7 @@ impl Context { if self.handle().session.is_null() { return Err(Error::SslBadInputData); } - + Ok(unsafe { self.handle().session.as_ref().unwrap().ciphersuite as u16 }) } @@ -578,12 +571,12 @@ impl HandshakeContext { self.handshake_ca_cert = None; self.handshake_crl = None; } - + pub fn set_authmode(&mut self, am: AuthMode) -> Result<()> { if self.inner.handshake as *const _ == ::core::ptr::null() { return Err(Error::SslBadInputData); } - + unsafe { ssl_set_hs_authmode(self.into(), am as i32) } Ok(()) } @@ -637,6 +630,9 @@ impl HandshakeContext { } } +#[cfg(all(feature = "std", feature = "async"))] +pub type AsyncContext = Context>; + #[cfg(all(feature = "std", feature = "async"))] pub trait IoAsyncCallback { unsafe extern "C" fn call_recv_async(user_data: *mut c_void, data: *mut c_uchar, len: size_t) -> c_int where Self: Sized; @@ -700,7 +696,7 @@ impl std::future::Future for HandshakeFuture<'_, T> { fn poll(mut self: Pin<&mut Self>, ctx: &mut TaskContext) -> std::task::Poll { self.0.io_mut().ok_or(Error::NetInvalidContext)? .ecx.set(ctx); - + let result = match self.0.handshake() { Err(Error::SslWantRead) | Err(Error::SslWantWrite) => { @@ -709,9 +705,9 @@ impl std::future::Future for HandshakeFuture<'_, T> { Err(e) => Poll::Ready(Err(e)), Ok(()) => Poll::Ready(Ok(())) }; - + self.0.io_mut().map(|v| v.ecx.clear()); - + result } } @@ -741,7 +737,7 @@ impl AsyncContext { ); self.io = Some(io); - self.inner.reset_handshake(); + self.inner.reset_handshake(); } HandshakeFuture(self).await @@ -762,7 +758,7 @@ impl AsyncRead for Context> { self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))? .ecx.set(cx); - + let result = match unsafe { ssl_read((&mut *self).into(), buf.initialize_unfilled().as_mut_ptr(), buf.initialize_unfilled().len()).into_result() } { Err(Error::SslPeerCloseNotify) => Poll::Ready(Ok(())), Err(Error::SslWantRead) => Poll::Pending, @@ -798,10 +794,10 @@ impl AsyncWrite for Context> { io.write_tracker.adjust_buf(buf) }?; - + self.io_mut().ok_or(IoError::new(IoErrorKind::Other, "stream has been shutdown"))? .ecx.set(cx); - + let result = match unsafe { ssl_write((&mut *self).into(), buf.as_ptr(), buf.len()).into_result() } { Err(Error::SslPeerCloseNotify) => Poll::Ready(Ok(0)), Err(Error::SslWantWrite) => Poll::Pending, @@ -868,7 +864,7 @@ mod tests { use crate::ssl::context::{HandshakeContext, Context}; use crate::tests::TestTrait; - + #[test] fn handshakecontext_sync() { assert!(!TestTrait::::new().impls_trait(), "HandshakeContext must be !Sync"); @@ -884,7 +880,7 @@ mod tests { unimplemented!() } } - + #[cfg(feature = "std")] impl Write for NonSendStream { fn write(&mut self, _: &[u8]) -> IoResult { @@ -906,7 +902,7 @@ mod tests { unimplemented!() } } - + #[cfg(feature = "std")] impl Write for SendStream { fn write(&mut self, _: &[u8]) -> IoResult { diff --git a/mbedtls/tests/ssl_conf_ca_cb.rs b/mbedtls/tests/ssl_conf_ca_cb.rs index 1fed49686..c490f6bb2 100644 --- a/mbedtls/tests/ssl_conf_ca_cb.rs +++ b/mbedtls/tests/ssl_conf_ca_cb.rs @@ -18,7 +18,7 @@ use mbedtls::pk::Pk; use mbedtls::rng::CtrDrbg; use mbedtls::ssl::config::{Endpoint, Preset, Transport}; use mbedtls::ssl::{Config, Context}; -use mbedtls::x509::{Certificate}; +use mbedtls::x509::Certificate; use mbedtls::Result as TlsResult; use mbedtls::ssl::config::CaCallback; @@ -58,7 +58,6 @@ mod test { use std::thread; use crate::support::net::create_tcp_pair; use crate::support::keys; - use mbedtls::x509::Certificate; use mbedtls::Error; use mbedtls::alloc::List as MbedtlsList; From 988332a6cf757e589d23a92c467a80b82a3835ea Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Wed, 15 Mar 2023 13:49:39 -0700 Subject: [PATCH 10/14] update tokio and rm unnecessary patch.crates-io --- Cargo.lock | 204 ++++++++++++++++++++++----------------------- Cargo.toml | 5 -- mbedtls/Cargo.toml | 2 +- 3 files changed, 101 insertions(+), 110 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 541faf062..0480424b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,18 +41,6 @@ dependencies = [ "syn 1.0.64", ] -[[package]] -name = "async-usercalls" -version = "0.1.0" -source = "git+https://github.com/fortanix/rust-sgx.git?branch=mz/async-usercalls#4cf2a8e12912bfd5e0ce8ef7fcf8f607110dfda2" -dependencies = [ - "crossbeam-channel", - "fnv", - "fortanix-sgx-abi", - "ipc-queue", - "lazy_static", -] - [[package]] name = "atty" version = "0.2.14" @@ -157,12 +145,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" -[[package]] -name = "bytes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16" - [[package]] name = "bytes" version = "1.1.0" @@ -253,37 +235,6 @@ dependencies = [ "cc", ] -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "crossbeam-channel" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" -dependencies = [ - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg 1.0.1", - "cfg-if 0.1.10", - "lazy_static", -] - [[package]] name = "env_logger" version = "0.8.3" @@ -303,11 +254,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "fortanix-sgx-abi" -version = "0.4.0" -source = "git+https://github.com/fortanix/rust-sgx.git?branch=mz/async-usercalls#4cf2a8e12912bfd5e0ce8ef7fcf8f607110dfda2" - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -577,14 +523,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "ipc-queue" -version = "0.1.0" -source = "git+https://github.com/fortanix/rust-sgx.git?branch=mz/async-usercalls#4cf2a8e12912bfd5e0ce8ef7fcf8f607110dfda2" -dependencies = [ - "fortanix-sgx-abi", -] - [[package]] name = "itoa" version = "0.4.8" @@ -611,9 +549,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.102" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "libloading" @@ -661,12 +599,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "mbedtls" version = "0.9.0" @@ -695,7 +627,7 @@ dependencies = [ "serde_derive", "spin", "tokio 0.2.25", - "tokio 0.3.4", + "tokio 1.19.2", "tracing", "yasna", ] @@ -732,25 +664,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.6" -source = "git+https://github.com/mzohreva/mio?branch=mz/sgx-port-0.7.6#b4370d8bea9951f7f01e29115b8ca0e9bfa25a77" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ - "async-usercalls", - "crossbeam-channel", "libc", "log 0.4.8", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", + "wasi", + "windows-sys", ] [[package]] @@ -763,15 +684,6 @@ dependencies = [ "version_check 0.9.2", ] -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - [[package]] name = "num-bigint" version = "0.2.4" @@ -1062,6 +974,16 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "spin" version = "0.4.10" @@ -1164,25 +1086,27 @@ dependencies = [ [[package]] name = "tokio" -version = "0.3.4" -source = "git+https://github.com/mzohreva/tokio?branch=mz/sgx-port-0.3.4#8af31a7b14986b34d6d544f48c2423e7b9792c7f" +version = "1.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" dependencies = [ - "autocfg 1.0.1", - "bytes 0.6.0", - "lazy_static", + "bytes 1.1.0", "libc", "memchr", "mio", "num_cpus", + "once_cell", "pin-project-lite 0.2.7", - "slab", + "socket2", "tokio-macros", + "winapi", ] [[package]] name = "tokio-macros" -version = "0.3.1" -source = "git+https://github.com/mzohreva/tokio?branch=mz/sgx-port-0.3.4#8af31a7b14986b34d6d544f48c2423e7b9792c7f" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2 1.0.24", "quote 1.0.9", @@ -1366,6 +1290,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "which" version = "3.0.0" @@ -1406,6 +1336,72 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "yasna" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index ea4ea1647..dd5aacf66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,3 @@ [workspace] members = ["mbedtls", "mbedtls-sys"] resolver = "2" - -[patch.crates-io] -mio = { git = "https://github.com/mzohreva/mio", branch = "mz/sgx-port-0.7.6" } -tokio = { git = "https://github.com/mzohreva/tokio", branch = "mz/sgx-port-0.3.4" } - diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index 5af95a6a5..1590981ab 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -29,7 +29,7 @@ bit-vec = { version = "0.5", optional = true } cbc = { version = "0.1.2", optional = true } rc2 = { version = "0.8.1", optional = true } cfg-if = "1.0.0" -tokio = { version = "0.3.4", optional = true } +tokio = { version = "1.16.1", optional = true } [target.x86_64-fortanix-unknown-sgx.dependencies] rs-libc = "0.2.0" From 966f2eb401986e56d726c97403206240aae8f6bb Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Mar 2023 09:44:12 -0700 Subject: [PATCH 11/14] clean up --- mbedtls-sys/Cargo.toml | 2 +- mbedtls/src/ssl/async_utils.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/mbedtls-sys/Cargo.toml b/mbedtls-sys/Cargo.toml index 5218287a3..2e21c9497 100644 --- a/mbedtls-sys/Cargo.toml +++ b/mbedtls-sys/Cargo.toml @@ -43,7 +43,7 @@ quote = "1.0.9" # * memmove/memcpy/memcmp/memset # * rand/printf (used only for self tests. optionally use custom_printf) default = ["std", "threading", "zlib", "time", "aesni", "padlock", "legacy_protocols"] -std = [] # deprecated automatic enabling of debug, can be removed on major version bump +std = [] custom_printf = [] custom_has_support = [] aes_alt = [] diff --git a/mbedtls/src/ssl/async_utils.rs b/mbedtls/src/ssl/async_utils.rs index e876a3e20..63ea35eae 100644 --- a/mbedtls/src/ssl/async_utils.rs +++ b/mbedtls/src/ssl/async_utils.rs @@ -14,8 +14,6 @@ use std::rc::Rc; use std::task::{Context as TaskContext, Poll}; -#[cfg(not(feature = "std"))] -use core_io::{Error as IoError, Result as IoResult, ErrorKind as IoErrorKind}; #[cfg(feature = "std")] use std::io::{Error as IoError, Result as IoResult, ErrorKind as IoErrorKind}; From 84a1c20ca68b53fb5a8fca2af1e10736d51f8341 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Mar 2023 10:04:21 -0700 Subject: [PATCH 12/14] clean up unnecessary changes --- mbedtls/src/pk/dsa/mod.rs | 22 +++------------------- mbedtls/src/pk/mod.rs | 2 +- mbedtls/src/ssl/context.rs | 2 +- mbedtls/src/ssl/mod.rs | 2 +- mbedtls/src/wrapper_macros.rs | 4 ---- 5 files changed, 6 insertions(+), 26 deletions(-) diff --git a/mbedtls/src/pk/dsa/mod.rs b/mbedtls/src/pk/dsa/mod.rs index bf868217b..fdf030149 100644 --- a/mbedtls/src/pk/dsa/mod.rs +++ b/mbedtls/src/pk/dsa/mod.rs @@ -217,13 +217,9 @@ fn sample_secret_value(upper_bound: &Mpi, rng: &mut F) -> Result Ok(c) } -pub fn encode_dsa_signature(r: &Mpi, s: &Mpi) -> Result> { - serialize_signature(&r.to_binary()?, &s.to_binary()?) -} - -pub fn serialize_signature(r: &[u8], s: &[u8]) -> Result> { - let r = BigUint::from_bytes_be(r); - let s = BigUint::from_bytes_be(s); +fn encode_dsa_signature(r: &Mpi, s: &Mpi) -> Result> { + let r = BigUint::from_bytes_be(&r.to_binary()?); + let s = BigUint::from_bytes_be(&s.to_binary()?); Ok(yasna::construct_der(|w| { w.write_sequence(|w| { @@ -233,18 +229,6 @@ pub fn serialize_signature(r: &[u8], s: &[u8]) -> Result> { })) } -pub fn deserialize_signature(signature: &Vec) -> Result<(Vec, Vec)> { - let (r,s) = yasna::parse_der(signature, |r| { - r.read_sequence(|rdr| { - let r = rdr.next().read_biguint()?; - let s = rdr.next().read_biguint()?; - Ok((r,s)) - }) - }).map_err(|_| Error::X509InvalidSignature)?; - - Ok((r.to_bytes_be(), s.to_bytes_be())) -} - impl DsaPrivateKey { pub fn from_components(params: DsaParams, x: Mpi) -> Result { if x <= Mpi::new(1)? || x >= params.q { diff --git a/mbedtls/src/pk/mod.rs b/mbedtls/src/pk/mod.rs index f5b6b47a9..52135e4e9 100644 --- a/mbedtls/src/pk/mod.rs +++ b/mbedtls/src/pk/mod.rs @@ -211,8 +211,8 @@ define!( // 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 // +// 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. diff --git a/mbedtls/src/ssl/context.rs b/mbedtls/src/ssl/context.rs index e02654ca7..bf75c4581 100644 --- a/mbedtls/src/ssl/context.rs +++ b/mbedtls/src/ssl/context.rs @@ -565,7 +565,7 @@ impl Write for Context { // - no reasonable way to obtain a storage within the sni callback tied to the handshake or to the rust Context. (without resorting to a unscalable map or pointer magic that mbedtls may invalidate) // impl HandshakeContext { - pub fn reset_handshake(&mut self) { + fn reset_handshake(&mut self) { self.handshake_cert.clear(); self.handshake_pk.clear(); self.handshake_ca_cert = None; diff --git a/mbedtls/src/ssl/mod.rs b/mbedtls/src/ssl/mod.rs index d0283ba0a..40ebd8007 100644 --- a/mbedtls/src/ssl/mod.rs +++ b/mbedtls/src/ssl/mod.rs @@ -25,4 +25,4 @@ pub use self::cookie::CookieContext; pub use self::ticket::TicketContext; #[cfg(all(feature = "std", feature = "async"))] #[doc(inline)] -pub use self::context::{AsyncContext}; +pub use self::context::AsyncContext; diff --git a/mbedtls/src/wrapper_macros.rs b/mbedtls/src/wrapper_macros.rs index c8c58d27b..379f844ec 100644 --- a/mbedtls/src/wrapper_macros.rs +++ b/mbedtls/src/wrapper_macros.rs @@ -61,10 +61,6 @@ macro_rules! define { define_struct!(define $(#[$m])* struct $name $(lifetime $l)* inner $inner members $($($(#[$mm])* $member: $member_type,)*)*); define_struct!(<< $name $(lifetime $l)* inner $inner >> $($defs)*); }; - { #[c_custom_ty($inner:ident)] $(#[$m:meta])* struct $name:ident$(<$l:tt>)* $({ $($(#[$mm:meta])* $member:ident: $member_type:ty,)* })?; $($defs:tt)* } => { - define_struct!(define_custom $(#[$m])* struct $name $(lifetime $l)* inner $inner members $($($(#[$mm])* $member: $member_type,)*)*); - define_struct!(<< $name $(lifetime $l)* 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,)*)*); From 6d15a4f2fc2b14ef548f9ddf7c1744fcd537e2ae Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Fri, 17 Mar 2023 10:10:45 -0700 Subject: [PATCH 13/14] clean up unnecessary tests --- Cargo.lock | 214 +------------------------- ct.sh | 1 - mbedtls/Cargo.toml | 6 - mbedtls/tests/hyper13.rs | 322 --------------------------------------- 4 files changed, 6 insertions(+), 537 deletions(-) delete mode 100644 mbedtls/tests/hyper13.rs diff --git a/Cargo.lock b/Cargo.lock index 0480424b9..46bccf05a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,12 +139,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - [[package]] name = "bytes" version = "1.1.0" @@ -248,12 +242,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -347,7 +335,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.7", + "pin-project-lite", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -370,32 +358,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "h2" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" -dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio 0.2.25", - "tokio-util", - "tracing", - "tracing-futures", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "hermit-abi" version = "0.1.17" @@ -411,39 +373,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" -[[package]] -name = "http" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" -dependencies = [ - "bytes 1.1.0", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" -dependencies = [ - "bytes 0.5.6", - "http", -] - [[package]] name = "httparse" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" -[[package]] -name = "httpdate" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" - [[package]] name = "humantime" version = "2.1.0" @@ -469,29 +404,6 @@ dependencies = [ "url", ] -[[package]] -name = "hyper" -version = "0.13.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a6f157065790a3ed2f88679250419b5cdd96e714a0d65f7797fd337186e96bb" -dependencies = [ - "bytes 0.5.6", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project", - "tokio 0.2.25", - "tower-service", - "tracing", - "want", -] - [[package]] name = "idna" version = "0.1.5" @@ -503,32 +415,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg 1.0.1", - "hashbrown", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - [[package]] name = "language-tags" version = "0.2.2" @@ -613,8 +499,7 @@ dependencies = [ "chrono", "futures", "hex", - "hyper 0.10.16", - "hyper 0.13.10", + "hyper", "libc", "matches", "mbedtls-sys-auto", @@ -626,8 +511,7 @@ dependencies = [ "serde_cbor", "serde_derive", "spin", - "tokio 0.2.25", - "tokio 1.19.2", + "tokio", "tracing", "yasna", ] @@ -742,32 +626,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -[[package]] -name = "pin-project" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" -dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - [[package]] name = "pin-project-lite" version = "0.2.7" @@ -1071,32 +929,19 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" -[[package]] -name = "tokio" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" -dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "memchr", - "pin-project-lite 0.1.12", -] - [[package]] name = "tokio" version = "1.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" dependencies = [ - "bytes 1.1.0", + "bytes", "libc", "memchr", "mio", "num_cpus", "once_cell", - "pin-project-lite 0.2.7", + "pin-project-lite", "socket2", "tokio-macros", "winapi", @@ -1113,26 +958,6 @@ dependencies = [ "syn 1.0.64", ] -[[package]] -name = "tokio-util" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" -dependencies = [ - "bytes 0.5.6", - "futures-core", - "futures-sink", - "log 0.4.8", - "pin-project-lite 0.1.12", - "tokio 0.2.25", -] - -[[package]] -name = "tower-service" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - [[package]] name = "tracing" version = "0.1.27" @@ -1140,8 +965,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2ba9ab62b7d6497a8638dfda5e5c4fb3b2d5a7fca4118f2b96151c8ef1a437e" dependencies = [ "cfg-if 1.0.0", - "log 0.4.8", - "pin-project-lite 0.2.7", + "pin-project-lite", "tracing-attributes", "tracing-core", ] @@ -1166,28 +990,12 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - [[package]] name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - [[package]] name = "typeable" version = "0.1.2" @@ -1280,16 +1088,6 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log 0.4.8", - "try-lock", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/ct.sh b/ct.sh index bb4759919..7ef9d91f3 100755 --- a/ct.sh +++ b/ct.sh @@ -33,7 +33,6 @@ if [ "$TRAVIS_RUST_VERSION" == "stable" ] || [ "$TRAVIS_RUST_VERSION" == "beta" cargo test --features pkcs12 --target $TARGET cargo test --features pkcs12_rc2 --target $TARGET cargo test --features dsa --target $TARGET - cargo test --test hyper13 --features=std,async-rt --target $TARGET cargo test --test async_session --features=async-rt --target $TARGET # If zlib is installed, test the zlib feature diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index 1590981ab..e4fe7403a 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -48,8 +48,6 @@ serde_cbor = "0.6" hex = "0.3" matches = "0.1.8" hyper = { version = "0.10.16", default-features = false } -hyper13 = { package = "hyper", version = "0.13", default-features = false, features = ["stream"] } -tokio-02 = { package = "tokio", version = "0.2", default-features = false } async-stream = "0.3.0" futures = "0.3" tracing = "0.1" @@ -109,10 +107,6 @@ required-features = ["std"] name = "hyper" required-features = ["std"] -[[test]] -name = "hyper13" -required-features = ["std", "async-rt"] - [[test]] name = "async_session" path = "tests/async_session.rs" diff --git a/mbedtls/tests/hyper13.rs b/mbedtls/tests/hyper13.rs deleted file mode 100644 index b1b2448f7..000000000 --- a/mbedtls/tests/hyper13.rs +++ /dev/null @@ -1,322 +0,0 @@ -#![allow(unused_imports)] - - -use async_stream::stream; - -use std::fmt; -use std::future::Future; -use std::io; -use std::io::{Error as IoError}; -use std::pin::Pin; -use std::sync::{Arc}; -use std::task::{Context as TaskContext, Poll}; -use std::net::SocketAddr; - -use hyper13::Server; -use hyper13::service::{make_service_fn, service_fn}; -use hyper13::client::connect::{Connected, Connection}; -use hyper13::{Client, service::Service, Uri, Request, Body, Method, Response, StatusCode}; -use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; -use tokio::net::{TcpStream, TcpListener}; -use tokio_02::io::{AsyncRead as AsyncRead02, AsyncWrite as AsyncWrite02}; - -use mbedtls::ssl::async_utils::IoAdapter; -use mbedtls::ssl::{Config, AsyncContext}; - -use futures::stream::{FuturesUnordered}; - -#[derive(Clone)] -pub struct HttpsConnector { - config: Arc, -} - -#[derive(Debug)] -struct ForceHttpsButUriNotHttps; - -impl std::error::Error for ForceHttpsButUriNotHttps {} - -impl fmt::Display for ForceHttpsButUriNotHttps { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("https required but URI was not https") - } -} - -const DEFAULT_HTTPS_PORT: u16 = 443; - -impl Service for HttpsConnector { - type Response = IoCompat>; - type Error = Box; - type Future = Pin> + Send>>; - - fn poll_ready(&mut self, _cx: &mut TaskContext<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, dst: Uri) -> Self::Future { - // Strip [] for IPv6 addresses - let host = dst.host().unwrap_or("").trim_matches(|c| c == '[' || c == ']').to_owned(); - let port = dst.port_u16().unwrap_or(DEFAULT_HTTPS_PORT); - let config = self.config.clone(); - - Box::pin(async move { - if dst.scheme_str() != Some("https") { - return Err(ForceHttpsButUriNotHttps.into()); - } - - let tcp = TcpStream::connect((host.clone(), port)).await?; - let mut tls = AsyncContext::new(config); - tls.establish_async(tcp, Some(&host)).await?; - Ok(IoCompat(tls)) - }) - } -} - -// IoCompat is needed because hyper 0.13 relies on tokio 0.2's `AsyncRead` -// and `AsyncWrite` traits. It would have been nice if we could use -// `tokio_compat_02::IoCompat`, but that type does not implement `Connection` -// and we cannot impl `Connection` for it here either since it's not defined -// in this crate. -pub struct IoCompat(T); - -impl Connection for IoCompat { - fn connected(&self) -> Connected { - let connected = Connected::new(); - //check_alpn(&self.0, connected) - connected - } -} - -impl AsyncRead02 for IoCompat { - fn poll_read(self: Pin<&mut Self>, cx: &mut TaskContext, buf: &mut [u8]) -> Poll> { - let mut read_buf = ReadBuf::new(buf); - match Pin::new(&mut self.get_mut().0).poll_read(cx, &mut read_buf) { - Poll::Ready(Ok(())) => Poll::Ready(Ok(read_buf.filled().len())), - Poll::Ready(Err(err)) => Poll::Ready(Err(err)), - Poll::Pending => Poll::Pending, - } - } -} - -impl AsyncWrite02 for IoCompat { - fn poll_write(self: Pin<&mut Self>, cx: &mut TaskContext<'_>, buf: &[u8]) -> Poll> { - Pin::new(&mut self.get_mut().0).poll_write(cx, buf) - } - fn poll_flush(self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll> { - Pin::new(&mut self.get_mut().0).poll_flush(cx) - } - fn poll_shutdown(self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll> { - Pin::new(&mut self.get_mut().0).poll_shutdown(cx) - } -} - -#[derive(Copy, Clone)] -pub struct TokioExecutor; - -impl hyper13::rt::Executor for TokioExecutor -where - F: Future + Send + 'static, - F::Output: Send + 'static, -{ - fn execute(&self, fut: F) { - tokio::spawn(fut); - } -} - - - -use tokio_02::stream::Stream; - -type TlsFuture = Pin>, IoError>> + Send>>; - -pub struct HyperAcceptor { - clients: FuturesUnordered>>, io::Error>>>, - listener: TcpListener, - config: Arc, -} - -impl HyperAcceptor { - pub async fn create(config: Arc, addr: &str) -> Result { - let listener = TcpListener::bind(addr).await?; - - Ok(HyperAcceptor { - clients: FuturesUnordered::new(), - listener, - config, - }) - } -} - -const MAX_CONCURRENT_ACCEPTS: usize = 100; - -impl hyper13::server::accept::Accept for HyperAcceptor { - type Conn = IoCompat>; - type Error = io::Error; - - fn poll_accept(mut self: Pin<&mut Self>, cx: &mut TaskContext,) -> Poll>> { - if self.clients.len() < MAX_CONCURRENT_ACCEPTS { - match self.listener.poll_accept(cx) { - Poll::Pending => (), - Poll::Ready(Ok((conn, _addr))) => { - let config = self.config.clone(); - self.clients.push(tokio::spawn(async move { - let context = AsyncContext::accept_async(config, conn, None).await?; - Ok(IoCompat(context)) - })); - }, - Poll::Ready(Err(e)) => { - // We likely don't care about user errors enough to stop processing under normal circumstances - return Poll::Ready(Some(Err(e))); - }, - }; - } - - if self.clients.len() > 0 { - match Pin::new(&mut self.clients).poll_next(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(Some(v)) => Poll::Ready(Some(v?)), // fold Result Poll::Ready(None), - } - } else { - Poll::Pending - } - } -} - - - -#[cfg(test)] -mod tests { - // Note this useful idiom: importing names from outer (for mod tests) scope. - use super::*; - - use mbedtls::pk::Pk; - use mbedtls::ssl::Config; - use mbedtls::ssl::config::{Endpoint, Preset, Transport, AuthMode, Version, UseSessionTickets, Renegotiation}; - use mbedtls::ssl::context::HandshakeContext; - use mbedtls::x509::{Certificate, VerifyError}; - use std::sync::Arc; - use mbedtls::ssl::CipherSuite::*; - use std::io::Write; - use mbedtls::ssl::TicketContext; - use std::time::Instant; - - #[cfg(not(target_env = "sgx"))] - use mbedtls::rng::{OsEntropy, CtrDrbg, HmacDrbg}; - - #[cfg(target_env = "sgx")] - use mbedtls::rng::{Rdrand}; - - use tokio::io::{AsyncReadExt, AsyncWriteExt}; - use tokio_02::stream::StreamExt; - use futures::stream::{FuturesUnordered}; - - #[cfg(not(target_env = "sgx"))] - pub fn rng_new() -> Arc { - let entropy = Arc::new(OsEntropy::new()); - let rng = Arc::new(CtrDrbg::new(entropy, None).unwrap()); - rng - } - - #[cfg(target_env = "sgx")] - pub fn rng_new() -> Arc { - Arc::new(Rdrand) - } - - pub const PEM_KEY: &'static [u8] = concat!(include_str!("./support/keys/user.key"),"\0").as_bytes(); - pub const PEM_CERT: &'static [u8] = concat!(include_str!("./support/keys/user.crt"),"\0").as_bytes(); - pub const ROOT_CA_CERT: &'static [u8] = concat!(include_str!("./support/keys/ca.crt"),"\0").as_bytes(); - - #[tokio::test] - async fn async_hyper_client_test() { - - let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); - config.set_authmode(AuthMode::None); - config.set_rng(rng_new()); - config.set_min_version(Version::Tls1_2).unwrap(); - - let https = HttpsConnector { config: Arc::new(config) }; - let client = Client::builder().executor(TokioExecutor).build::<_, hyper13::Body>(https); - - let res = client.get("https://hyper.rs".parse().unwrap()).await.unwrap(); - assert_eq!(res.status(), 200); - } - - async fn echo(req: Request) -> Result, hyper::Error> { - let mut response = Response::new(Body::empty()); - - match (req.method(), req.uri().path()) { - (&Method::GET, "/") => *response.body_mut() = Body::from("Try POST /echo\n"), - (&Method::POST, "/echo") => *response.body_mut() = req.into_body(), - _ => *response.status_mut() = StatusCode::NOT_FOUND, - }; - - Ok(response) - } - - async fn get_acceptor(address: &str) -> Result { - let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default); - - config.set_rng(rng_new()); - config.set_authmode(AuthMode::None); - config.set_min_version(Version::Tls1_2).unwrap(); - - let cert = Arc::new(Certificate::from_pem_multiple(PEM_CERT).unwrap()); - let key = Arc::new(Pk::from_private_key(PEM_KEY, None).unwrap()); - config.push_cert(cert, key).unwrap(); - - HyperAcceptor::create(Arc::new(config), address).await - } - - #[tokio::test] - async fn async_hyper_server_fullhandshake_test() { - std::env::set_var("RUST_BACKTRACE", "full"); - - // Set up hyper server to echo function and a graceful shutdown - let acceptor = get_acceptor("127.0.0.1:0").await.unwrap(); - let local_addr = acceptor.listener.local_addr().unwrap().clone(); - - let service = make_service_fn(|_| async { Ok::<_, io::Error>(service_fn(echo)) }); - let server = Server::builder(acceptor).executor(TokioExecutor).serve(service); - - let (tx, rx) = tokio::sync::oneshot::channel::<()>(); - let graceful = server.with_graceful_shutdown(async { rx.await.ok(); }); - - let s = tokio::spawn(graceful); - - let mut clients = FuturesUnordered::new(); - - let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default); - config.set_authmode(AuthMode::None); - config.set_rng(rng_new()); - config.set_min_version(Version::Tls1_2).unwrap(); - let config = Arc::new(config); - - let start = Instant::now(); - - for _ in 0..100 { - let config = config.clone(); - - clients.push(tokio::spawn(async move { - let client = Client::builder().executor(TokioExecutor).build::<_, hyper13::Body>(HttpsConnector { config }); - - let mut res = client.get(format!("https://{}/", local_addr).parse().unwrap()).await.unwrap(); - assert_eq!(res.status(), 200); - - let body_bytes = hyper13::body::to_bytes(res.into_body()).await.unwrap(); - let body = String::from_utf8(body_bytes.to_vec()).expect("response was not valid utf-8"); - assert_eq!(body, "Try POST /echo\n"); - })); - - if clients.len() > MAX_CONCURRENT_ACCEPTS { - clients.next().await.unwrap(); - } - } - - while let Some(r) = clients.next().await { - r.unwrap(); - } - - tx.send(()); - s.await.unwrap().unwrap(); - } -} From 2e5a225bbcf89ae3686d27a1cadc8ea58c6d2054 Mon Sep 17 00:00:00 2001 From: Yuxiang Cao Date: Mon, 20 Mar 2023 11:06:59 -0700 Subject: [PATCH 14/14] update lock file after rebase --- Cargo.lock | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46bccf05a..5462292bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,21 +118,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "byteorder" version = "1.3.2" @@ -145,6 +130,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.0.67" @@ -229,6 +223,16 @@ dependencies = [ "cc", ] +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "env_logger" version = "0.8.3" @@ -415,6 +419,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding", + "generic-array", +] + [[package]] name = "language-tags" version = "0.2.2"