From 06674b1b70179dffe53b4a88aef88f7b088f311c Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Sat, 17 Apr 2021 21:58:24 -0400 Subject: [PATCH 1/2] tests: add calendar.rs coverage for pre-1970 dates --- src/calendar.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/calendar.rs b/src/calendar.rs index 0b4c0068..2b928bf5 100644 --- a/src/calendar.rs +++ b/src/calendar.rs @@ -66,7 +66,7 @@ fn days_before_year_since_unix_epoch(year: u64) -> Result { // We don't support dates before January 1, 1970 because that is the // Unix epoch. It is likely that other software won't deal well with // certificates that have dates before the epoch. - if year < 1970 { + if year < UNIX_EPOCH_YEAR { return Err(Error::BadDerTime); } let days_before_year_ad = days_before_year_ad(year); @@ -74,6 +74,8 @@ fn days_before_year_since_unix_epoch(year: u64) -> Result { Ok(days_before_year_ad - DAYS_BEFORE_UNIX_EPOCH_AD) } +const UNIX_EPOCH_YEAR: u64 = 1970; + fn days_before_year_ad(year: u64) -> u64 { ((year - 1) * 365) + ((year - 1) / 4) // leap years are every 4 years, @@ -105,8 +107,25 @@ const DAYS_BEFORE_UNIX_EPOCH_AD: u64 = 719162; mod tests { #[test] fn test_days_before_unix_epoch() { - use super::{days_before_year_ad, DAYS_BEFORE_UNIX_EPOCH_AD}; - assert_eq!(DAYS_BEFORE_UNIX_EPOCH_AD, days_before_year_ad(1970)); + use super::{days_before_year_ad, DAYS_BEFORE_UNIX_EPOCH_AD, UNIX_EPOCH_YEAR}; + assert_eq!( + DAYS_BEFORE_UNIX_EPOCH_AD, + days_before_year_ad(UNIX_EPOCH_YEAR) + ); + } + + #[test] + fn test_days_before_year_since_unix_epoch() { + use super::{days_before_year_since_unix_epoch, Error, UNIX_EPOCH_YEAR}; + assert_eq!(Ok(0), days_before_year_since_unix_epoch(UNIX_EPOCH_YEAR)); + assert_eq!( + Ok(365), + days_before_year_since_unix_epoch(UNIX_EPOCH_YEAR + 1) + ); + assert_eq!( + Err(Error::BadDerTime), + days_before_year_since_unix_epoch(UNIX_EPOCH_YEAR - 1) + ); } #[test] @@ -135,7 +154,37 @@ mod tests { #[allow(clippy::unreadable_literal)] // TODO: Make this clear. #[test] fn test_time_from_ymdhms_utc() { - use super::{time_from_ymdhms_utc, Time}; + use super::{time_from_ymdhms_utc, Error, Time, UNIX_EPOCH_YEAR}; + + // 1969-12-31 00:00:00 + assert_eq!( + Err(Error::BadDerTime), + time_from_ymdhms_utc(UNIX_EPOCH_YEAR - 1, 1, 1, 0, 0, 0) + ); + + // 1969-12-31 23:59:59 + assert_eq!( + Err(Error::BadDerTime), + time_from_ymdhms_utc(UNIX_EPOCH_YEAR - 1, 12, 31, 23, 59, 59) + ); + + // 1970-01-01 00:00:00 + assert_eq!( + Time::from_seconds_since_unix_epoch(0), + time_from_ymdhms_utc(UNIX_EPOCH_YEAR, 1, 1, 0, 0, 0).unwrap() + ); + + // 1970-01-01 00:00:01 + assert_eq!( + Time::from_seconds_since_unix_epoch(1), + time_from_ymdhms_utc(UNIX_EPOCH_YEAR, 1, 1, 0, 0, 1).unwrap() + ); + + // 1971-01-01 00:00:00 + assert_eq!( + Time::from_seconds_since_unix_epoch(365 * 86400), + time_from_ymdhms_utc(UNIX_EPOCH_YEAR + 1, 1, 1, 0, 0, 0).unwrap() + ); // year boundary assert_eq!( From 882d929f1f3c35e2310d9cbf143882907aaa262d Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Thu, 22 Apr 2021 15:39:57 -0400 Subject: [PATCH 2/2] tests: add coverage for der.rs --- src/der.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/der.rs b/src/der.rs index 7db35476..13f1d77c 100644 --- a/src/der.rs +++ b/src/der.rs @@ -222,3 +222,69 @@ macro_rules! oid { [(40 * $first) + $second, $( $tail ),*] ) } + +#[cfg(test)] +mod tests { + #[test] + fn test_optional_boolean() { + use super::{optional_boolean, Error}; + + // Empty input results in false + assert!(!optional_boolean(&mut bytes_reader(&[])).unwrap()); + + // Optional, so another data type results in false + assert!(!optional_boolean(&mut bytes_reader(&[0x05, 0x00])).unwrap()); + + // Only 0x00 and 0xff are accepted values + assert_eq!( + Err(Error::BadDer), + optional_boolean(&mut bytes_reader(&[0x01, 0x01, 0x42])) + ); + + // True + assert!(optional_boolean(&mut bytes_reader(&[0x01, 0x01, 0xff])).unwrap()); + + // False + assert!(!optional_boolean(&mut bytes_reader(&[0x01, 0x01, 0x00])).unwrap()); + } + + #[test] + fn test_bit_string_with_no_unused_bits() { + use super::{bit_string_with_no_unused_bits, Error}; + + // Unexpected type + assert_eq!( + Err(Error::BadDer), + bit_string_with_no_unused_bits(&mut bytes_reader(&[0x01, 0x01, 0xff])) + ); + + // Unexpected nonexistent type + assert_eq!( + Err(Error::BadDer), + bit_string_with_no_unused_bits(&mut bytes_reader(&[0x42, 0xff, 0xff])) + ); + + // Unexpected empty input + assert_eq!( + Err(Error::BadDer), + bit_string_with_no_unused_bits(&mut bytes_reader(&[])) + ); + + // Valid input with non-zero unused bits + assert_eq!( + Err(Error::BadDer), + bit_string_with_no_unused_bits(&mut bytes_reader(&[0x03, 0x03, 0x04, 0x12, 0x34])) + ); + + // Valid input + assert_eq!( + untrusted::Input::from(&[0x12, 0x34]), + bit_string_with_no_unused_bits(&mut bytes_reader(&[0x03, 0x03, 0x00, 0x12, 0x34])) + .unwrap() + ); + } + + fn bytes_reader(bytes: &[u8]) -> untrusted::Reader { + return untrusted::Reader::new(untrusted::Input::from(bytes)); + } +}