Skip to content

Commit ca38f0f

Browse files
bors[bot]Adrian CruceruJethro Beekman
authored
Merge #128
128: MbedTLS Reference counted instead of lifetimes r=jethrogb a=AdrianCX Moving from referene counting allows simpler move to native-tls / hyper. Arc Changes: - Each Config/Context/... will hold Arcs towards items it holds pointers to. - This forces objects to live as long as needed, once no longer used they get destroyed by reference counting. This allows passing the objects to multiple threads without worrying about lifetime. I've also added notes why classes are Sync where used. Let me know if I missed any classes. Usage example of an intermediate mbed-hyper integration is at: - https://github.com/fortanix/rust-mbedtls/tree/acruceru/wip-mbed-hyper-v2/mbedtls-hyper/examples/integrations There I added a crate to wrap hyper - similar to native-tls. (that will be moved to native-tls layer soon) That crate can be considered an integration test that I will raise a separate PR for. Edit: Changes after initial review: - Added forward_mbedtls_calloc / forward_mbedtls_free functions so we can pass certificates to and from mbedtls without allocator mismatches/corruptions. - Switched to MbedtlsList<Certificate> and Certificate. A MbedtlsBox is pending for this PR as well. - Fixed most comments. Still pending: - Update define! macros - Add MbedtlsBox<Certificate> Fixes #1 Partial progress on #3 Fixes #4 Fixes #8 Partially addresses #9 Co-authored-by: Adrian Cruceru <[email protected]> Co-authored-by: Jethro Beekman <[email protected]>
2 parents f82e140 + 4062e7d commit ca38f0f

37 files changed

+2770
-1000
lines changed

Cargo.lock

Lines changed: 164 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bors.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
status = [
22
"continuous-integration/travis-ci/push",
33
]
4+
timeout_sec = 36000 # ten hours

ct.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ if [ $TRAVIS_RUST_VERSION = "stable" ] || [ $TRAVIS_RUST_VERSION = "beta" ] || [
1919
cargo test --features pkcs12
2020
cargo test --features pkcs12_rc2
2121
cargo test --features force_aesni_support
22+
cargo test --features default,pthread
2223

2324
elif [ $TRAVIS_RUST_VERSION = $CORE_IO_NIGHTLY ]; then
2425
cargo +$CORE_IO_NIGHTLY test --no-default-features --features core_io,rdrand,time,custom_time,custom_gmtime_r

mbedtls-sys/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This version generates the correct bindings at compile time using bindgen."""
1212
readme = "../README.md"
1313
repository = "https://github.com/fortanix/rust-mbedtls"
1414
documentation = "https://docs.rs/mbedtls-sys-auto/"
15+
links = "mbedtls"
1516

1617
[lib]
1718
name = "mbedtls_sys"

mbedtls-sys/build/cmake.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,8 @@ impl super::BuildConfig {
4949
println!("cargo:rustc-link-lib=mbedtls");
5050
println!("cargo:rustc-link-lib=mbedx509");
5151
println!("cargo:rustc-link-lib=mbedcrypto");
52+
53+
println!("cargo:include={}/{}", ::std::env::current_dir().unwrap().display(), self.mbedtls_src.join("include").display());
54+
println!("cargo:config_h={}", self.config_h.to_str().expect("config.h UTF-8 error"));
5255
}
5356
}

mbedtls/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ rand = "0.4.0"
4444
serde_cbor = "0.6"
4545
hex = "0.3"
4646
matches = "0.1.8"
47+
hyper = { version = "0.10.16", default-features = false }
4748

4849
[build-dependencies]
4950
cc = "1.0"
@@ -119,3 +120,9 @@ required-features = ["std"]
119120
name = "ssl_conf_verify"
120121
path = "tests/ssl_conf_verify.rs"
121122
required-features = ["std"]
123+
124+
125+
[[test]]
126+
name = "hyper"
127+
path = "tests/hyper.rs"
128+
required-features = ["std", "threading"]

mbedtls/build.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ use std::env;
1212

1313
fn main() {
1414
let mut b = cc::Build::new();
15+
b.include(env::var_os("DEP_MBEDTLS_INCLUDE").expect("Links was not properly set in mbedtls-sys package, missing DEP_MBEDTLS_INCLUDE"));
16+
let config_file = format!("\"{}\"", env::var_os("DEP_MBEDTLS_CONFIG_H").expect("Links was not properly set in mbedtls-sys package, missing DEP_MBEDTLS_CONFIG_H").to_str().unwrap());
17+
b.define("MBEDTLS_CONFIG_FILE",
18+
Some(config_file.as_str()));
19+
20+
b.file("src/mbedtls_malloc.c");
1521
b.file("src/rust_printf.c");
1622
if env::var_os("CARGO_FEATURE_STD").is_none()
1723
|| ::std::env::var("TARGET")

mbedtls/examples/client.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ extern crate mbedtls;
1010

1111
use std::io::{self, stdin, stdout, Write};
1212
use std::net::TcpStream;
13+
use std::sync::Arc;
1314

1415
use mbedtls::rng::CtrDrbg;
1516
use mbedtls::ssl::config::{Endpoint, Preset, Transport};
@@ -23,21 +24,21 @@ use support::entropy::entropy_new;
2324
use support::keys;
2425

2526
fn result_main(addr: &str) -> TlsResult<()> {
26-
let mut entropy = entropy_new();
27-
let mut rng = CtrDrbg::new(&mut entropy, None)?;
28-
let mut cert = Certificate::from_pem(keys::ROOT_CA_CERT)?;
27+
let entropy = Arc::new(entropy_new());
28+
let rng = Arc::new(CtrDrbg::new(entropy, None)?);
29+
let cert = Arc::new(Certificate::from_pem_multiple(keys::PEM_CERT)?);
2930
let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default);
30-
config.set_rng(Some(&mut rng));
31-
config.set_ca_list(Some(&mut *cert), None);
32-
let mut ctx = Context::new(&config)?;
31+
config.set_rng(rng);
32+
config.set_ca_list(cert, None);
33+
let mut ctx = Context::new(Arc::new(config));
3334

34-
let mut conn = TcpStream::connect(addr).unwrap();
35-
let mut session = ctx.establish(&mut conn, None)?;
35+
let conn = TcpStream::connect(addr).unwrap();
36+
ctx.establish(conn, None)?;
3637

3738
let mut line = String::new();
3839
stdin().read_line(&mut line).unwrap();
39-
session.write_all(line.as_bytes()).unwrap();
40-
io::copy(&mut session, &mut stdout()).unwrap();
40+
ctx.write_all(line.as_bytes()).unwrap();
41+
io::copy(&mut ctx, &mut stdout()).unwrap();
4142
Ok(())
4243
}
4344

mbedtls/examples/server.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ extern crate mbedtls;
1010

1111
use std::io::{BufRead, BufReader, Write};
1212
use std::net::{TcpListener, TcpStream};
13+
use std::sync::Arc;
1314

1415
use mbedtls::pk::Pk;
1516
use mbedtls::rng::CtrDrbg;
@@ -29,21 +30,25 @@ fn listen<E, F: FnMut(TcpStream) -> Result<(), E>>(mut handle_client: F) -> Resu
2930
println!("Connection from {}", conn.peer_addr().unwrap());
3031
handle_client(conn)?;
3132
}
33+
3234
Ok(())
3335
}
3436

3537
fn result_main() -> TlsResult<()> {
36-
let mut entropy = entropy_new();
37-
let mut rng = CtrDrbg::new(&mut entropy, None)?;
38-
let mut cert = Certificate::from_pem(keys::PEM_CERT)?;
39-
let mut key = Pk::from_private_key(keys::PEM_KEY, None)?;
38+
let entropy = entropy_new();
39+
let rng = Arc::new(CtrDrbg::new(Arc::new(entropy), None)?);
40+
let cert = Arc::new(Certificate::from_pem_multiple(keys::PEM_CERT)?);
41+
let key = Arc::new(Pk::from_private_key(keys::PEM_KEY, None)?);
4042
let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default);
41-
config.set_rng(Some(&mut rng));
42-
config.push_cert(&mut *cert, &mut key)?;
43-
let mut ctx = Context::new(&config)?;
43+
config.set_rng(rng);
44+
config.push_cert(cert, key)?;
45+
46+
let rc_config = Arc::new(config);
4447

45-
listen(|mut conn| {
46-
let mut session = BufReader::new(ctx.establish(&mut conn, None)?);
48+
listen(move |conn| {
49+
let mut ctx = Context::new(rc_config.clone());
50+
ctx.establish(conn, None)?;
51+
let mut session = BufReader::new(ctx);
4752
let mut line = Vec::new();
4853
session.read_until(b'\n', &mut line).unwrap();
4954
session.get_mut().write_all(&line).unwrap();

mbedtls/src/alloc.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* Copyright (c) Fortanix, Inc.
2+
*
3+
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
4+
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
5+
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
6+
* option. This file may not be copied, modified, or distributed except
7+
* according to those terms. */
8+
9+
use core::fmt;
10+
use core::ops::{Deref, DerefMut};
11+
use core::ptr::NonNull;
12+
use core::ptr::drop_in_place;
13+
use core::mem::ManuallyDrop;
14+
15+
use mbedtls_sys::types::raw_types::c_void;
16+
17+
extern "C" {
18+
pub(crate) fn forward_mbedtls_free(n: *mut mbedtls_sys::types::raw_types::c_void);
19+
}
20+
21+
#[repr(transparent)]
22+
pub struct Box<T> {
23+
pub(crate) inner: NonNull<T>
24+
}
25+
26+
impl<T> Box<T> {
27+
pub(crate) fn into_raw(self) -> *mut T {
28+
let v = ManuallyDrop::new(self);
29+
v.inner.as_ptr()
30+
}
31+
}
32+
33+
impl<T> Deref for Box<T> {
34+
type Target = T;
35+
fn deref(&self) -> &T {
36+
unsafe { self.inner.as_ref() }
37+
}
38+
}
39+
40+
impl<T> DerefMut for Box<T> {
41+
fn deref_mut(&mut self) -> &mut T {
42+
unsafe { self.inner.as_mut() }
43+
}
44+
}
45+
46+
impl<T: fmt::Debug> fmt::Debug for Box<T> {
47+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48+
fmt::Debug::fmt(&**self, f)
49+
}
50+
}
51+
52+
impl<T> Drop for Box<T> {
53+
fn drop(&mut self) {
54+
unsafe {
55+
drop_in_place(self.inner.as_ptr());
56+
forward_mbedtls_free(self.inner.as_ptr() as *mut c_void)
57+
}
58+
}
59+
}
60+
61+
#[repr(transparent)]
62+
pub struct List<T> {
63+
pub(crate) inner: Option<Box<T>>
64+
}
65+

mbedtls/src/lib.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const ERROR: _MUST_USE_EITHER_STD_OR_CORE_IO_ = ();
1515

1616
#[cfg(not(feature = "std"))]
1717
#[macro_use]
18-
extern crate alloc;
18+
extern crate alloc as rust_alloc;
1919
#[cfg(feature = "std")]
2020
extern crate core;
2121
#[cfg(not(feature = "std"))]
@@ -59,6 +59,7 @@ pub mod rng;
5959
pub mod self_test;
6060
pub mod ssl;
6161
pub mod x509;
62+
pub mod alloc;
6263

6364
#[cfg(feature = "pkcs12")]
6465
pub mod pkcs12;
@@ -112,11 +113,13 @@ mod mbedtls {
112113
#[cfg(not(feature = "std"))]
113114
mod alloc_prelude {
114115
#![allow(unused)]
115-
pub(crate) use alloc::borrow::ToOwned;
116-
pub(crate) use alloc::boxed::Box;
117-
pub(crate) use alloc::string::String;
118-
pub(crate) use alloc::string::ToString;
119-
pub(crate) use alloc::vec::Vec;
116+
pub(crate) use rust_alloc::borrow::ToOwned;
117+
pub(crate) use rust_alloc::boxed::Box;
118+
pub(crate) use rust_alloc::sync::Arc;
119+
pub(crate) use rust_alloc::string::String;
120+
pub(crate) use rust_alloc::string::ToString;
121+
pub(crate) use rust_alloc::vec::Vec;
122+
pub(crate) use rust_alloc::borrow::Cow;
120123
}
121124

122125
#[cfg(all(feature="time", any(feature="custom_gmtime_r", feature="custom_time")))]
@@ -163,3 +166,11 @@ pub unsafe extern "C" fn mbedtls_time(tp: *mut time_t) -> time_t {
163166
}
164167
timestamp
165168
}
169+
170+
// Debug not available in SGX
171+
#[cfg(not(target_env = "sgx"))]
172+
pub unsafe fn set_global_debug_threshold(threshold: i32) {
173+
mbedtls_sys::debug_set_threshold(threshold);
174+
}
175+
176+

mbedtls/src/mbedtls_malloc.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* Copyright (c) Fortanix, Inc.
2+
*
3+
* Licensed under the GNU General Public License, version 2 <LICENSE-GPL or
4+
* https://www.gnu.org/licenses/gpl-2.0.html> or the Apache License, Version
5+
* 2.0 <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>, at your
6+
* option. This file may not be copied, modified, or distributed except
7+
* according to those terms. */
8+
9+
// Follow same pattern for config and alloc/free as everywhere in mbedtls
10+
#if !defined(MBEDTLS_CONFIG_FILE)
11+
#include "mbedtls/config.h"
12+
#else
13+
#include MBEDTLS_CONFIG_FILE
14+
#endif
15+
16+
#if defined(MBEDTLS_PLATFORM_C)
17+
#include "mbedtls/platform.h"
18+
#else
19+
#include <stdlib.h>
20+
#define mbedtls_calloc calloc
21+
#define mbedtls_free free
22+
#endif
23+
24+
extern void *forward_mbedtls_calloc( size_t n, size_t size ) {
25+
return mbedtls_calloc(n, size);
26+
}
27+
28+
extern void forward_mbedtls_free( void *ptr ) {
29+
mbedtls_free(ptr);
30+
}
31+

mbedtls/src/pk/dhparam.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl Dhm {
2222
/// Takes both DER and PEM forms of FFDH parameters in `DHParams` format.
2323
///
2424
/// When calling on PEM-encoded data, `params` must be NULL-terminated
25-
pub(crate) fn from_params(params: &[u8]) -> Result<Dhm> {
25+
pub fn from_params(params: &[u8]) -> Result<Dhm> {
2626
let mut ret = Self::init();
2727
unsafe { dhm_parse_dhm(&mut ret.inner, params.as_ptr(), params.len()) }.into_result()?;
2828
Ok(ret)

0 commit comments

Comments
 (0)