// Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // Tests for X509 time functions. #include #include #include #include #include struct TestData { const char *data; int type; int64_t cmp_time; // -1 if asn1_time <= cmp_time, 1 if asn1_time > cmp_time, 0 if error. int expected; }; static TestData kX509CmpTests[] = { { "20170217180154Z", V_ASN1_GENERALIZEDTIME, // The same in seconds since epoch. 1487354514, -1, }, { "20170217180154Z", V_ASN1_GENERALIZEDTIME, // One second more. 1487354515, -1, }, { "20170217180154Z", V_ASN1_GENERALIZEDTIME, // One second less. 1487354513, 1, }, // Same as UTC time. { "170217180154Z", V_ASN1_UTCTIME, // The same in seconds since epoch. 1487354514, -1, }, { "170217180154Z", V_ASN1_UTCTIME, // One second more. 1487354515, -1, }, { "170217180154Z", V_ASN1_UTCTIME, // One second less. 1487354513, 1, }, // UTCTime from the 20th century. { "990217180154Z", V_ASN1_UTCTIME, // The same in seconds since epoch. 919274514, -1, }, { "990217180154Z", V_ASN1_UTCTIME, // One second more. 919274515, -1, }, { "990217180154Z", V_ASN1_UTCTIME, // One second less. 919274513, 1, }, // Various invalid formats. { // No trailing Z. "20170217180154", V_ASN1_GENERALIZEDTIME, 0, 0, }, { // No trailing Z, UTCTime. "170217180154", V_ASN1_UTCTIME, 0, 0, }, { // No seconds. "201702171801Z", V_ASN1_GENERALIZEDTIME, 0, 0, }, { // No seconds, UTCTime. "1702171801Z", V_ASN1_UTCTIME, 0, 0, }, { // Fractional seconds. "20170217180154.001Z", V_ASN1_GENERALIZEDTIME, 0, 0, }, { // Fractional seconds, UTCTime. "170217180154.001Z", V_ASN1_UTCTIME, 0, 0, }, { // Timezone offset. "20170217180154+0100", V_ASN1_GENERALIZEDTIME, 0, 0, }, { // Timezone offset, UTCTime. "170217180154+0100", V_ASN1_UTCTIME, 0, 0, }, { // Extra digits. "2017021718015400Z", V_ASN1_GENERALIZEDTIME, 0, 0, }, { // Extra digits, UTCTime. "17021718015400Z", V_ASN1_UTCTIME, 0, 0, }, { // Non-digits. "2017021718015aZ", V_ASN1_GENERALIZEDTIME, 0, 0, }, { // Non-digits, UTCTime. "17021718015aZ", V_ASN1_UTCTIME, 0, 0, }, { // Trailing garbage. "20170217180154Zlongtrailinggarbage", V_ASN1_GENERALIZEDTIME, 0, 0, }, { // Trailing garbage, UTCTime. "170217180154Zlongtrailinggarbage", V_ASN1_UTCTIME, 0, 0, }, { // Swapped type. "20170217180154Z", V_ASN1_UTCTIME, 0, 0, }, { // Swapped type. "170217180154Z", V_ASN1_GENERALIZEDTIME, 0, 0, }, { // Bad type. "20170217180154Z", V_ASN1_OCTET_STRING, 0, 0, }, // Test limits and unusual cases. { "99991231235959Z", V_ASN1_GENERALIZEDTIME, // Test a very large positive time with the largest representable time 253402300799, -1, // TODO(bbe): This is *technically* wrong by rfc5280. }, { "99991231235959Z", V_ASN1_GENERALIZEDTIME, // one second after the largest possible time should still compare // correctly 253402300800, -1, // TODO(bbe): This is *technically* wrong by rfc5280. }, { "99991231235959Z", V_ASN1_GENERALIZEDTIME, // Test one second before the largest time 253402300798, 1, }, { "700101000000Z", V_ASN1_UTCTIME, // The epoch, which should not fail. a time of 0 must be valid. 0, -1, }, { "700101000000Z", V_ASN1_UTCTIME, // One second before the epoch should compare correctly. -1, 1, }, { "700101000000Z", V_ASN1_UTCTIME, // One second after the epoch should compare correctly. 1, -1, }, { "690621025615Z", V_ASN1_UTCTIME, // Test a negative time, we use a time from NASA, close to but not quite // at the epoch. -16751025, -1, }, { "690621025615Z", V_ASN1_UTCTIME, // Test one small second before our negative time. -16751026, 1, }, { "690621025615Z", V_ASN1_UTCTIME, // Test one giant second after our negative time. -16751024, -1, }, { "00000101000000Z", V_ASN1_GENERALIZEDTIME, // Test a very large negative time with the earliest representable time -62167219200, -1, }, { "00000101000000Z", V_ASN1_GENERALIZEDTIME, // Test one second after the earliest time. -62167219199, -1, }, }; TEST(X509TimeTest, TestCmpTime) { for (auto &test : kX509CmpTests) { SCOPED_TRACE(test.data); bssl::UniquePtr t(ASN1_STRING_type_new(test.type)); ASSERT_TRUE(t); ASSERT_TRUE(ASN1_STRING_set(t.get(), test.data, strlen(test.data))); EXPECT_EQ(test.expected, X509_cmp_time_posix(t.get(), test.cmp_time)); } } TEST(X509TimeTest, TestCmpTimeCurrent) { time_t now = time(NULL); // Pick a day earlier and later, relative to any system clock. bssl::UniquePtr asn1_before(ASN1_TIME_adj(NULL, now, -1, 0)); bssl::UniquePtr asn1_after(ASN1_TIME_adj(NULL, now, 1, 0)); ASSERT_EQ(-1, X509_cmp_time(asn1_before.get(), NULL)); ASSERT_EQ(1, X509_cmp_time(asn1_after.get(), NULL)); }