From 6fa13d12d56a78e1c5d6d1ec4bca23d00c863f18 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 23 Sep 2022 05:01:22 +0000 Subject: [PATCH] Support RFC3339 timestamps This extracts @lukesteensen's RFC 3339 timestamp parser from #377. This allows rust-tuf to interoperate better with other TUF implementations, which might include things like microseconds, or not be in the UTC timezone. --- tuf/src/interchange/cjson/shims.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tuf/src/interchange/cjson/shims.rs b/tuf/src/interchange/cjson/shims.rs index db7a4ff..25d8fb6 100644 --- a/tuf/src/interchange/cjson/shims.rs +++ b/tuf/src/interchange/cjson/shims.rs @@ -19,7 +19,8 @@ fn valid_spec_version(other: &str) -> bool { } fn parse_datetime(ts: &str) -> Result> { - Utc.datetime_from_str(ts, "%FT%TZ") + DateTime::parse_from_rfc3339(ts) + .map(|ts| ts.with_timezone(&Utc)) .map_err(|e| Error::Encoding(format!("Can't parse DateTime: {:?}", e))) } @@ -601,4 +602,28 @@ mod test { ); } } + + #[test] + fn datetime_formats() { + // The TUF spec says datetimes should be in ISO8601 format, specifically + // "YYYY-MM-DDTHH:MM:SSZ". Since not all TUF clients adhere strictly to that, we choose to + // be more lenient here. The following represent the intersection of valid ISO8601 and + // RFC3339 datetime formats (source: https://ijmacd.github.io/rfc3339-iso8601/). + let valid_formats = [ + "2022-08-30T19:53:55Z", + "2022-08-30T19:53:55.7Z", + "2022-08-30T19:53:55.77Z", + "2022-08-30T19:53:55.775Z", + "2022-08-30T19:53:55+00:00", + "2022-08-30T19:53:55.7+00:00", + "2022-08-30T14:53:55-05:00", + "2022-08-30T14:53:55.7-05:00", + "2022-08-30T14:53:55.77-05:00", + "2022-08-30T14:53:55.775-05:00", + ]; + + for format in valid_formats { + assert!(parse_datetime(format).is_ok(), "should parse {:?}", format); + } + } }