Skip to content

Commit f447f7d

Browse files
bors[bot]Goirad
andauthored
Merge #50
50: Implement cert expiry checking without libc r=jack-fortanix a=Goirad Add features and implementations of time related functions to use when `libc` isn't available. Because of feature weirdness I added a `use_libc` feature for those that want to just use libc. The `gmtime_r` function is written with chrono, as is the custom `time` function. Co-authored-by: Dario Gonzalez <[email protected]>
2 parents 0c9cdd0 + 5c11407 commit f447f7d

File tree

11 files changed

+298
-18
lines changed

11 files changed

+298
-18
lines changed

Cargo.lock

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

ct.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ cargo test --features zlib
1616
cargo test --features pkcs12
1717
cargo test --features pkcs12_rc2
1818
cargo test --features force_aesni_support
19+
cargo +$CORE_IO_NIGHTLY test --no-default-features --features core_io,rdrand,time,custom_time,custom_gmtime_r
1920
cargo +$CORE_IO_NIGHTLY test --no-default-features --features core_io,rdrand
2021
cargo +nightly test --no-run --target=x86_64-fortanix-unknown-sgx --features=sgx --no-default-features

mbedtls-sys/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ cmake = "0.1.17"
3535
default = ["std", "zlib", "time", "pthread", "aesni", "padlock", "legacy_protocols"]
3636
std = []
3737
custom_printf = []
38+
custom_time = ["custom_gmtime_r", "time"]
39+
custom_gmtime_r = ["time"]
3840
custom_has_support = []
3941
aes_alt = []
4042
custom_threading = ["threading"]
4143
pthread = ["libc","threading"]
4244
threading = []
43-
time = ["libc"]
45+
time = []
4446
havege = ["time"]
4547
zlib = ["libz-sys"]
4648
pkcs11 = []

mbedtls-sys/build/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ pub const FEATURE_DEFINES: &'static [(&'static str, CDefine)] = &[
382382
("time", ("MBEDTLS_HAVE_TIME", Defined)),
383383
("time", ("MBEDTLS_HAVE_TIME_DATE", Defined)),
384384
("time", ("MBEDTLS_TIMING_C", Defined)),
385+
("custom_time", ("MBEDTLS_PLATFORM_TIME_MACRO", DefinedAs("mbedtls_time"))),
386+
("custom_gmtime_r", ("MBEDTLS_PLATFORM_GMTIME_R_ALT", Defined)),
385387
("havege", ("MBEDTLS_HAVEGE_C", Defined)),
386388
("threading", ("MBEDTLS_THREADING_C", Defined)),
387389
("pthread", ("MBEDTLS_THREADING_PTHREAD", Defined)),

mbedtls-sys/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,9 @@ pub use bindings::*;
1919
https://github.com/rust-lang-nursery/rust-bindgen/issues/231
2020
*/
2121
pub const ECDSA_MAX_LEN : u32 = 141;
22+
23+
#[cfg(all(feature = "time", not(feature = "custom_time"), not(feature = "libc")))]
24+
impl _ERROR_MUST_ENABLE_EITHER_CUSTOM_TIME_OR_LIBC_ for _TIME_FEATURE_ {}
25+
26+
#[cfg(all(feature = "time", not(feature = "custom_gmtime_r"), not(feature = "libc")))]
27+
impl _ERROR_MUST_ENABLE_EITHER_CUSTOM_GMTIME_R_OR_LIBC_ for _TIME_FEATURE_ {}

mbedtls-sys/src/types.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,40 @@ extern crate libc;
8989
#[cfg(feature = "libc")]
9090
mod libc_types {
9191
pub use super::libc::FILE;
92+
93+
#[cfg(feature = "time")]
94+
pub use super::libc::{time_t, tm};
95+
9296
}
9397

9498
#[cfg(not(feature = "libc"))]
9599
mod libc_types {
96100
pub enum FILE {}
101+
102+
#[cfg(feature = "time")]
103+
pub type time_t = i64;
104+
105+
#[cfg(feature = "time")]
106+
#[repr(C)]
107+
pub struct tm {
108+
pub tm_sec: i32, /* Seconds. [0-60] (1 leap second) */
109+
pub tm_min: i32, /* Minutes. [0-59] */
110+
pub tm_hour: i32, /* Hours. [0-23] */
111+
pub tm_mday: i32, /* Day. [1-31] */
112+
pub tm_mon: i32, /* Month. [0-11] */
113+
pub tm_year: i32, /* Year - 1900. */
114+
pub tm_wday: i32, /* Day of week. [0-6] */
115+
pub tm_yday: i32, /* Days in year. [0-365]*/
116+
pub tm_isdst: i32,
117+
}
118+
97119
}
98120

99121
pub use self::libc_types::*;
100122

101123
#[cfg(feature = "pthread")]
102124
pub use self::libc::pthread_mutex_t;
103125

104-
#[cfg(feature = "time")]
105-
pub use self::libc::{time_t, tm};
106-
107126
#[cfg(feature = "zlib")]
108127
extern crate libz_sys;
109128
#[cfg(feature = "zlib")]

mbedtls/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ keywords = ["MbedTLS","mbed","TLS","SSL","cryptography"]
1919

2020
[dependencies]
2121
bitflags = "1"
22+
chrono = "0.4"
2223
core_io = { version = "0.1", features = ["collections"], optional = true }
2324
spin = { version = "0.4.0", default-features = false, optional = true }
2425
serde = { version = "1.0.7", default-features = false }
@@ -47,7 +48,7 @@ cc = "1.0"
4748

4849
[features]
4950
# Features are documented in the README
50-
default = ["std", "aesni", "time", "padlock", "legacy_protocols"]
51+
default = ["std", "aesni", "time", "padlock", "legacy_protocols", "use_libc"]
5152
std = ["mbedtls-sys-auto/std","serde/std"]
5253
threading = []
5354
pthread = ["threading","std","mbedtls-sys-auto/pthread"]
@@ -56,6 +57,9 @@ sgx = ["std", "rust_threading", "rdrand", "force_aesni_support"]
5657
rust_threading = ["threading", "mbedtls-sys-auto/custom_threading", "std"]
5758
force_aesni_support = ["mbedtls-sys-auto/custom_has_support","mbedtls-sys-auto/aes_alt","aesni"]
5859
rdrand = []
60+
use_libc = ["mbedtls-sys-auto/libc"]
61+
custom_gmtime_r = ["mbedtls-sys-auto/custom_gmtime_r"]
62+
custom_time = ["mbedtls-sys-auto/custom_time"]
5963
aesni = ["mbedtls-sys-auto/aesni"]
6064
zlib = ["mbedtls-sys-auto/zlib"]
6165
time = ["mbedtls-sys-auto/time"]

mbedtls/src/lib.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,48 @@ mod alloc_prelude {
117117
pub(crate) use alloc::string::ToString;
118118
pub(crate) use alloc::vec::Vec;
119119
}
120+
121+
#[cfg(all(feature="time", any(feature="custom_gmtime_r", feature="custom_time")))]
122+
use mbedtls_sys::types::{time_t, tm};
123+
124+
#[cfg(any(feature = "custom_gmtime_r", feature = "custom_time"))]
125+
extern crate chrono;
126+
127+
#[cfg(feature="custom_gmtime_r")]
128+
#[doc(hidden)]
129+
#[no_mangle]
130+
pub unsafe extern "C" fn mbedtls_platform_gmtime_r(tt: *const time_t, tp: *mut tm) -> *mut tm {
131+
use chrono::prelude::*;
132+
133+
//0 means no TZ offset
134+
let naive = if tp.is_null() {
135+
return core::ptr::null_mut()
136+
} else {
137+
NaiveDateTime::from_timestamp(*tt, 0)
138+
};
139+
let utc = DateTime::<Utc>::from_utc(naive, Utc);
140+
141+
let tp = &mut *tp;
142+
tp.tm_sec = utc.second() as i32;
143+
tp.tm_min = utc.minute() as i32;
144+
tp.tm_hour = utc.hour() as i32;
145+
tp.tm_mday = utc.day() as i32;
146+
tp.tm_mon = utc.month0() as i32;
147+
tp.tm_year = utc.year() as i32 - 1900;
148+
tp.tm_wday = utc.weekday().num_days_from_monday() as i32;
149+
tp.tm_yday = utc.ordinal0() as i32;
150+
tp.tm_isdst = 0;
151+
152+
tp
153+
}
154+
155+
#[cfg(feature="custom_time")]
156+
#[doc(hidden)]
157+
#[no_mangle]
158+
pub unsafe extern "C" fn mbedtls_time(tp: *mut time_t) -> time_t {
159+
let timestamp = chrono::Utc::now().timestamp() as time_t;
160+
if !tp.is_null() {
161+
*tp = timestamp;
162+
}
163+
timestamp
164+
}

mbedtls/src/x509/certificate.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ impl LinkedCertificate {
206206
if result.is_err() {
207207
if let Some(err_info) = err_info {
208208
let verify_info = crate::private::alloc_string_repeat(|buf, size| unsafe {
209-
x509_crt_verify_info(buf, size, ptr::null_mut(), flags)
209+
let prefix = "\0";
210+
x509_crt_verify_info(buf, size, prefix.as_ptr() as *const _, flags)
210211
});
211212
if let Ok(error_str) = verify_info {
212213
*err_info = error_str;

mbedtls/tests/client_server.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,23 @@ fn client(
3232
exp_version: Option<Version>) -> TlsResult<()> {
3333
let mut entropy = entropy_new();
3434
let mut rng = CtrDrbg::new(&mut entropy, None)?;
35-
let mut cert = Certificate::from_pem(keys::PEM_CERT)?;
35+
let mut cacert = Certificate::from_pem(keys::ROOT_CA_CERT)?;
36+
let expected_flags = VerifyError::empty();
37+
#[cfg(feature = "time")]
38+
let expected_flags = expected_flags | VerifyError::CERT_EXPIRED;
3639
let mut verify_args = None;
3740
{
3841
let verify_callback =
3942
&mut |crt: &mut LinkedCertificate, depth, verify_flags: &mut VerifyError| {
40-
verify_args = Some((crt.subject().unwrap(), depth, verify_flags.bits()));
43+
verify_args = Some((crt.subject().unwrap(), depth, *verify_flags));
44+
verify_flags.remove(VerifyError::CERT_EXPIRED); //we check the flags at the end,
45+
//so removing this flag here prevents the connections from failing with VerifyError
4146
Ok(())
4247
};
4348
let mut config = Config::new(Endpoint::Client, Transport::Stream, Preset::Default);
4449
config.set_rng(Some(&mut rng));
4550
config.set_verify_callback(verify_callback);
46-
config.set_ca_list(Some(&mut *cert), None);
51+
config.set_ca_list(Some(&mut *cacert), None);
4752
config.set_min_version(min_version)?;
4853
config.set_max_version(max_version)?;
4954
let mut ctx = Context::new(&config)?;
@@ -56,10 +61,9 @@ fn client(
5661
s
5762
}
5863
Err(e) => {
59-
assert!(exp_version.is_none());
6064
match e {
61-
Error::SslBadHsProtocolVersion => {}
62-
Error::SslFatalAlertMessage => {}
65+
Error::SslBadHsProtocolVersion => {assert!(exp_version.is_none())},
66+
Error::SslFatalAlertMessage => {},
6367
e => panic!("Unexpected error {}", e),
6468
};
6569
return Ok(());
@@ -74,7 +78,7 @@ fn client(
7478
session.read_exact(&mut buf).unwrap();
7579
assert_eq!(&buf, format!("Server2Client {:4x}", ciphersuite).as_bytes());
7680
} // drop verify_callback, releasing borrow of verify_args
77-
assert_eq!(verify_args, Some((keys::PEM_CERT_SUBJECT.to_owned(), 0, 0)));
81+
assert_eq!(verify_args, Some((keys::EXPIRED_CERT_SUBJECT.to_owned(), 0, expected_flags)));
7882
Ok(())
7983
}
8084

@@ -86,8 +90,8 @@ fn server(
8690
) -> TlsResult<()> {
8791
let mut entropy = entropy_new();
8892
let mut rng = CtrDrbg::new(&mut entropy, None)?;
89-
let mut cert = Certificate::from_pem(keys::PEM_CERT)?;
90-
let mut key = Pk::from_private_key(keys::PEM_KEY, None)?;
93+
let mut cert = Certificate::from_pem(keys::EXPIRED_CERT)?;
94+
let mut key = Pk::from_private_key(keys::EXPIRED_KEY, None)?;
9195
let mut config = Config::new(Endpoint::Server, Transport::Stream, Preset::Default);
9296
config.set_rng(Some(&mut rng));
9397
config.set_min_version(min_version)?;
@@ -102,11 +106,10 @@ fn server(
102106
s
103107
}
104108
Err(e) => {
105-
assert!(exp_version.is_none());
106109
match e {
107110
// client just closes connection instead of sending alert
108-
Error::NetSendFailed => {}
109-
Error::SslBadHsProtocolVersion => {}
111+
Error::NetSendFailed => {assert!(exp_version.is_none())},
112+
Error::SslBadHsProtocolVersion => {},
110113
e => panic!("Unexpected error {}", e),
111114
};
112115
return Ok(());

0 commit comments

Comments
 (0)