| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/cert/pki/revocation_util.h" |
| |
| #include "net/der/encode_values.h" |
| #include "net/der/parse_values.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net { |
| |
| namespace { |
| |
| constexpr int64_t kOneHour = 3600; |
| constexpr int64_t kOneDay = 24 * kOneHour; |
| constexpr int64_t kOneWeek = 7 * kOneDay; |
| constexpr int64_t kWindowsEpoch = -11644473600; // 1601-01-01 00:00:00 UTC |
| constexpr int64_t kMinValidTime = -62167219200; // 0000-01-01 00:00:00 UTC |
| constexpr int64_t kMaxValidTime = 253402300799; // 9999-12-31 23:59:59 UTC |
| |
| } // namespace |
| |
| TEST(CheckRevocationDateTest, Valid) { |
| int64_t now = time(nullptr); |
| int64_t this_update = now - kOneHour; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| EXPECT_TRUE( |
| CheckRevocationDateValid(encoded_this_update, nullptr, now, kOneWeek)); |
| |
| int64_t next_update = this_update + kOneWeek; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| EXPECT_TRUE(CheckRevocationDateValid(encoded_this_update, |
| &encoded_next_update, now, kOneWeek)); |
| } |
| |
| TEST(CheckRevocationDateTest, ThisUpdateInTheFuture) { |
| int64_t now = time(nullptr); |
| int64_t this_update = now + 3600; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| EXPECT_FALSE( |
| CheckRevocationDateValid(encoded_this_update, nullptr, now, kOneWeek)); |
| |
| int64_t next_update = this_update + kOneWeek; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| EXPECT_FALSE(CheckRevocationDateValid(encoded_this_update, |
| &encoded_next_update, now, kOneWeek)); |
| } |
| |
| TEST(CheckRevocationDateTest, NextUpdatePassed) { |
| int64_t now = time(nullptr); |
| int64_t this_update = now - (kOneDay * 6); |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| EXPECT_TRUE( |
| CheckRevocationDateValid(encoded_this_update, nullptr, now, kOneWeek)); |
| |
| int64_t next_update = now - kOneHour; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| EXPECT_FALSE(CheckRevocationDateValid(encoded_this_update, |
| &encoded_next_update, now, kOneWeek)); |
| } |
| |
| TEST(CheckRevocationDateTest, NextUpdateBeforeThisUpdate) { |
| int64_t now = time(nullptr); |
| int64_t this_update = now - kOneDay; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| EXPECT_TRUE( |
| CheckRevocationDateValid(encoded_this_update, nullptr, now, kOneWeek)); |
| |
| int64_t next_update = this_update - kOneDay; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| EXPECT_FALSE(CheckRevocationDateValid(encoded_this_update, |
| &encoded_next_update, now, kOneWeek)); |
| } |
| |
| TEST(CheckRevocationDateTest, ThisUpdateOlderThanMaxAge) { |
| int64_t now = time(nullptr); |
| int64_t this_update = now - kOneWeek; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| EXPECT_TRUE( |
| CheckRevocationDateValid(encoded_this_update, nullptr, now, kOneWeek)); |
| |
| int64_t next_update = now + kOneHour; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| EXPECT_TRUE(CheckRevocationDateValid(encoded_this_update, |
| &encoded_next_update, now, kOneWeek)); |
| |
| ASSERT_TRUE(der::EncodePosixTimeAsGeneralizedTime(this_update - 1, |
| &encoded_this_update)); |
| EXPECT_FALSE( |
| CheckRevocationDateValid(encoded_this_update, nullptr, now, kOneWeek)); |
| EXPECT_FALSE(CheckRevocationDateValid(encoded_this_update, |
| &encoded_next_update, now, kOneWeek)); |
| } |
| |
| TEST(CheckRevocationDateTest, VerifyTimeFromBeforeWindowsEpoch) { |
| int64_t verify_time = kWindowsEpoch - kOneDay; |
| |
| int64_t now = time(nullptr); |
| int64_t this_update = now - kOneHour; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| EXPECT_FALSE(CheckRevocationDateValid(encoded_this_update, nullptr, |
| verify_time, kOneWeek)); |
| |
| int64_t next_update = this_update + kOneWeek; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| EXPECT_FALSE(CheckRevocationDateValid( |
| encoded_this_update, &encoded_next_update, verify_time, kOneWeek)); |
| } |
| |
| TEST(CheckRevocationDateTest, VerifyTimeMinusAgeFromBeforeWindowsEpoch) { |
| int64_t verify_time = kWindowsEpoch + kOneDay; |
| |
| int64_t this_update = kWindowsEpoch; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| // Note: Unlike base/time, BoringSSL can convert POSIX times a day before the |
| // Windows epoch on all platforms. |
| EXPECT_TRUE(CheckRevocationDateValid(encoded_this_update, nullptr, |
| verify_time, kOneWeek)); |
| } |
| |
| TEST(CheckRevocationDateTest, VerifyTimeAtMinTime) { |
| int64_t verify_time = kMinValidTime; |
| |
| int64_t now = time(nullptr); |
| int64_t this_update = now - kOneHour; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| EXPECT_FALSE(CheckRevocationDateValid(encoded_this_update, nullptr, |
| verify_time, kOneWeek)); |
| |
| int64_t next_update = this_update + kOneWeek; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| // This will fail because kMinValidTime - kOneWeek is not a valid time, so |
| // we expect this to not be able to compare to the allowed range. |
| EXPECT_FALSE(CheckRevocationDateValid( |
| encoded_this_update, &encoded_next_update, verify_time, kOneWeek)); |
| // This will fail because the validation time is not in the allowed range. |
| EXPECT_FALSE(CheckRevocationDateValid(encoded_this_update, |
| &encoded_next_update, verify_time, 0)); |
| } |
| |
| TEST(CheckRevocationDateTest, ThisUpdateAtMinTime) { |
| int64_t this_update = kMinValidTime; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| int64_t next_update = kMinValidTime + kOneWeek; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| // This will fail because kMinValidTime - 1 is not a valid time, so |
| // we expect these tests to not be able to compare to the allowed range. |
| EXPECT_FALSE( |
| CheckRevocationDateValid(encoded_this_update, nullptr, kMinValidTime, 1)); |
| EXPECT_FALSE(CheckRevocationDateValid( |
| encoded_this_update, &encoded_next_update, kMinValidTime, 1)); |
| // Unlike the above kMinValidTime - 0 should still be valid, so we expect |
| // these tests to work. |
| EXPECT_TRUE( |
| CheckRevocationDateValid(encoded_this_update, nullptr, kMinValidTime, 0)); |
| EXPECT_TRUE(CheckRevocationDateValid(encoded_this_update, |
| &encoded_next_update, kMinValidTime, 0)); |
| |
| int64_t verify_time = kMinValidTime + kOneDay; |
| EXPECT_TRUE(CheckRevocationDateValid(encoded_this_update, nullptr, |
| verify_time, kOneDay)); |
| EXPECT_TRUE(CheckRevocationDateValid( |
| encoded_this_update, &encoded_next_update, verify_time, kOneDay)); |
| } |
| |
| TEST(CheckRevocationDateTest, VerifyTimeAtMaxTime) { |
| int64_t this_update = time(nullptr) - kOneHour; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| int64_t next_update = this_update + kOneWeek; |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| int64_t verify_time = kMaxValidTime; |
| EXPECT_FALSE(CheckRevocationDateValid(encoded_this_update, nullptr, |
| verify_time, kOneWeek)); |
| EXPECT_FALSE(CheckRevocationDateValid( |
| encoded_this_update, &encoded_next_update, verify_time, kOneWeek)); |
| } |
| |
| TEST(CheckRevocationDateTest, NextUpdateAtMaxTime) { |
| int64_t this_update = kMaxValidTime - kOneWeek; |
| int64_t next_update = kMaxValidTime; |
| der::GeneralizedTime encoded_this_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(this_update, &encoded_this_update)); |
| der::GeneralizedTime encoded_next_update; |
| ASSERT_TRUE( |
| der::EncodePosixTimeAsGeneralizedTime(next_update, &encoded_next_update)); |
| // With no next_update, this is expected to work. |
| EXPECT_TRUE(CheckRevocationDateValid(encoded_this_update, nullptr, |
| kMaxValidTime, kOneWeek)); |
| // With a next_update, validation time must be strictly less than next_update, |
| // so this should fail. |
| EXPECT_FALSE(CheckRevocationDateValid( |
| encoded_this_update, &encoded_next_update, kMaxValidTime, kOneWeek)); |
| |
| int64_t verify_time = kMaxValidTime - kOneDay; |
| EXPECT_TRUE(CheckRevocationDateValid(encoded_this_update, nullptr, |
| verify_time, kOneWeek)); |
| EXPECT_TRUE(CheckRevocationDateValid( |
| encoded_this_update, &encoded_next_update, verify_time, kOneWeek)); |
| } |
| |
| } // namespace net |