1 /*
2 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 // Tests for X509 time functions.
11
12 #include <openssl/x509.h>
13
14 #include <string.h>
15 #include <time.h>
16
17 #include <gtest/gtest.h>
18 #include <openssl/asn1.h>
19
20 struct TestData {
21 const char *data;
22 int type;
23 int64_t cmp_time;
24 // -1 if asn1_time <= cmp_time, 1 if asn1_time > cmp_time, 0 if error.
25 int expected;
26 };
27
28 static TestData kX509CmpTests[] = {
29 {
30 "20170217180154Z",
31 V_ASN1_GENERALIZEDTIME,
32 // The same in seconds since epoch.
33 1487354514,
34 -1,
35 },
36 {
37 "20170217180154Z",
38 V_ASN1_GENERALIZEDTIME,
39 // One second more.
40 1487354515,
41 -1,
42 },
43 {
44 "20170217180154Z",
45 V_ASN1_GENERALIZEDTIME,
46 // One second less.
47 1487354513,
48 1,
49 },
50 // Same as UTC time.
51 {
52 "170217180154Z",
53 V_ASN1_UTCTIME,
54 // The same in seconds since epoch.
55 1487354514,
56 -1,
57 },
58 {
59 "170217180154Z",
60 V_ASN1_UTCTIME,
61 // One second more.
62 1487354515,
63 -1,
64 },
65 {
66 "170217180154Z",
67 V_ASN1_UTCTIME,
68 // One second less.
69 1487354513,
70 1,
71 },
72 // UTCTime from the 20th century.
73 {
74 "990217180154Z",
75 V_ASN1_UTCTIME,
76 // The same in seconds since epoch.
77 919274514,
78 -1,
79 },
80 {
81 "990217180154Z",
82 V_ASN1_UTCTIME,
83 // One second more.
84 919274515,
85 -1,
86 },
87 {
88 "990217180154Z",
89 V_ASN1_UTCTIME,
90 // One second less.
91 919274513,
92 1,
93 },
94 // Various invalid formats.
95 {
96 // No trailing Z.
97 "20170217180154",
98 V_ASN1_GENERALIZEDTIME,
99 0,
100 0,
101 },
102 {
103 // No trailing Z, UTCTime.
104 "170217180154",
105 V_ASN1_UTCTIME,
106 0,
107 0,
108 },
109 {
110 // No seconds.
111 "201702171801Z",
112 V_ASN1_GENERALIZEDTIME,
113 0,
114 0,
115 },
116 {
117 // No seconds, UTCTime.
118 "1702171801Z",
119 V_ASN1_UTCTIME,
120 0,
121 0,
122 },
123 {
124 // Fractional seconds.
125 "20170217180154.001Z",
126 V_ASN1_GENERALIZEDTIME,
127 0,
128 0,
129 },
130 {
131 // Fractional seconds, UTCTime.
132 "170217180154.001Z",
133 V_ASN1_UTCTIME,
134 0,
135 0,
136 },
137 {
138 // Timezone offset.
139 "20170217180154+0100",
140 V_ASN1_GENERALIZEDTIME,
141 0,
142 0,
143 },
144 {
145 // Timezone offset, UTCTime.
146 "170217180154+0100",
147 V_ASN1_UTCTIME,
148 0,
149 0,
150 },
151 {
152 // Extra digits.
153 "2017021718015400Z",
154 V_ASN1_GENERALIZEDTIME,
155 0,
156 0,
157 },
158 {
159 // Extra digits, UTCTime.
160 "17021718015400Z",
161 V_ASN1_UTCTIME,
162 0,
163 0,
164 },
165 {
166 // Non-digits.
167 "2017021718015aZ",
168 V_ASN1_GENERALIZEDTIME,
169 0,
170 0,
171 },
172 {
173 // Non-digits, UTCTime.
174 "17021718015aZ",
175 V_ASN1_UTCTIME,
176 0,
177 0,
178 },
179 {
180 // Trailing garbage.
181 "20170217180154Zlongtrailinggarbage",
182 V_ASN1_GENERALIZEDTIME,
183 0,
184 0,
185 },
186 {
187 // Trailing garbage, UTCTime.
188 "170217180154Zlongtrailinggarbage",
189 V_ASN1_UTCTIME,
190 0,
191 0,
192 },
193 {
194 // Swapped type.
195 "20170217180154Z",
196 V_ASN1_UTCTIME,
197 0,
198 0,
199 },
200 {
201 // Swapped type.
202 "170217180154Z",
203 V_ASN1_GENERALIZEDTIME,
204 0,
205 0,
206 },
207 {
208 // Bad type.
209 "20170217180154Z",
210 V_ASN1_OCTET_STRING,
211 0,
212 0,
213 },
214 // Test limits and unusual cases.
215 {
216 "99991231235959Z", V_ASN1_GENERALIZEDTIME,
217 // Test a very large positive time with the largest representable time
218 253402300799,
219 -1, // TODO(bbe): This is *technically* wrong by rfc5280.
220 },
221 {
222 "99991231235959Z", V_ASN1_GENERALIZEDTIME,
223 // one second after the largest possible time should still compare
224 // correctly
225 253402300800,
226 -1, // TODO(bbe): This is *technically* wrong by rfc5280.
227 },
228 {
229 "99991231235959Z",
230 V_ASN1_GENERALIZEDTIME,
231 // Test one second before the largest time
232 253402300798,
233 1,
234 },
235 {
236 "700101000000Z",
237 V_ASN1_UTCTIME,
238 // The epoch, which should not fail. a time of 0 must be valid.
239 0,
240 -1,
241 },
242 {
243 "700101000000Z",
244 V_ASN1_UTCTIME,
245 // One second before the epoch should compare correctly.
246 -1,
247 1,
248 },
249 {
250 "700101000000Z",
251 V_ASN1_UTCTIME,
252 // One second after the epoch should compare correctly.
253 1,
254 -1,
255 },
256 {
257 "690621025615Z",
258 V_ASN1_UTCTIME,
259 // Test a negative time, we use a time from NASA, close to but not quite
260 // at the epoch.
261 -16751025,
262 -1,
263 },
264 {
265 "690621025615Z",
266 V_ASN1_UTCTIME,
267 // Test one small second before our negative time.
268 -16751026,
269 1,
270 },
271 {
272 "690621025615Z",
273 V_ASN1_UTCTIME,
274 // Test one giant second after our negative time.
275 -16751024,
276 -1,
277 },
278 {
279 "00000101000000Z",
280 V_ASN1_GENERALIZEDTIME,
281 // Test a very large negative time with the earliest representable time
282 -62167219200,
283 -1,
284 },
285 {
286 "00000101000000Z",
287 V_ASN1_GENERALIZEDTIME,
288 // Test one second after the earliest time.
289 -62167219199,
290 -1,
291 },
292
293 };
294
TEST(X509TimeTest,TestCmpTime)295 TEST(X509TimeTest, TestCmpTime) {
296 for (auto &test : kX509CmpTests) {
297 SCOPED_TRACE(test.data);
298
299 bssl::UniquePtr<ASN1_STRING> t(ASN1_STRING_type_new(test.type));
300 ASSERT_TRUE(t);
301 ASSERT_TRUE(ASN1_STRING_set(t.get(), test.data, strlen(test.data)));
302
303 EXPECT_EQ(test.expected, X509_cmp_time_posix(t.get(), test.cmp_time));
304 }
305 }
306
TEST(X509TimeTest,TestCmpTimeCurrent)307 TEST(X509TimeTest, TestCmpTimeCurrent) {
308 time_t now = time(NULL);
309 // Pick a day earlier and later, relative to any system clock.
310 bssl::UniquePtr<ASN1_TIME> asn1_before(ASN1_TIME_adj(NULL, now, -1, 0));
311 bssl::UniquePtr<ASN1_TIME> asn1_after(ASN1_TIME_adj(NULL, now, 1, 0));
312
313 ASSERT_EQ(-1, X509_cmp_time(asn1_before.get(), NULL));
314 ASSERT_EQ(1, X509_cmp_time(asn1_after.get(), NULL));
315 }
316