| // Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| // Tests for X509 time functions. | |
| #include <openssl/x509.h> | |
| #include <string.h> | |
| #include <time.h> | |
| #include <gtest/gtest.h> | |
| #include <openssl/asn1.h> | |
| namespace { | |
| 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<ASN1_STRING> 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(nullptr); | |
| // Pick a day earlier and later, relative to any system clock. | |
| bssl::UniquePtr<ASN1_TIME> asn1_before(ASN1_TIME_adj(nullptr, now, -1, 0)); | |
| bssl::UniquePtr<ASN1_TIME> asn1_after(ASN1_TIME_adj(nullptr, now, 1, 0)); | |
| ASSERT_EQ(-1, X509_cmp_time(asn1_before.get(), nullptr)); | |
| ASSERT_EQ(1, X509_cmp_time(asn1_after.get(), nullptr)); | |
| } | |
| } // namespace |