]>
Commit | Line | Data |
---|---|---|
80770da3 | 1 | /* |
38fc02a7 | 2 | * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. |
80770da3 | 3 | * |
909f1a2e | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
80770da3 EK |
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 <string.h> | |
13 | #include <time.h> | |
14 | ||
15 | #include <openssl/asn1.h> | |
16 | #include <openssl/x509.h> | |
17 | #include "testutil.h" | |
176db6dc | 18 | #include "internal/nelem.h" |
80770da3 EK |
19 | |
20 | typedef struct { | |
21 | const char *data; | |
22 | int type; | |
23 | time_t cmp_time; | |
24 | /* -1 if asn1_time <= cmp_time, 1 if asn1_time > cmp_time, 0 if error. */ | |
25 | int expected; | |
26 | } TESTDATA; | |
27 | ||
04e62715 RS |
28 | typedef struct { |
29 | const char *data; | |
30 | /* 0 for check-only mode, 1 for set-string mode */ | |
31 | int set_string; | |
32 | /* 0 for error, 1 if succeed */ | |
33 | int expected; | |
34 | /* | |
35 | * The following 2 fields are ignored if set_string field is set to '0' | |
36 | * (in check only mode). | |
37 | * | |
38 | * But they can still be ignored explicitly in set-string mode by: | |
39 | * setting -1 to expected_type and setting NULL to expected_string. | |
40 | * | |
41 | * It's useful in a case of set-string mode but the expected result | |
42 | * is a 'parsing error'. | |
43 | */ | |
44 | int expected_type; | |
45 | const char *expected_string; | |
46 | } TESTDATA_FORMAT; | |
47 | ||
48 | /* | |
49 | * Actually, the "loose" mode has been tested in | |
50 | * those time-compare-cases, so we may not test it again. | |
51 | */ | |
52 | static TESTDATA_FORMAT x509_format_tests[] = { | |
53 | /* GeneralizedTime */ | |
54 | { | |
55 | /* good format, check only */ | |
56 | "20170217180105Z", 0, 1, -1, NULL, | |
57 | }, | |
3d0f1cb9 PY |
58 | { |
59 | /* not leap year, check only */ | |
60 | "20170229180105Z", 0, 0, -1, NULL, | |
61 | }, | |
62 | { | |
63 | /* leap year, check only */ | |
64 | "20160229180105Z", 0, 1, -1, NULL, | |
65 | }, | |
04e62715 RS |
66 | { |
67 | /* SS is missing, check only */ | |
68 | "201702171801Z", 0, 0, -1, NULL, | |
69 | }, | |
70 | { | |
71 | /* fractional seconds, check only */ | |
72 | "20170217180105.001Z", 0, 0, -1, NULL, | |
73 | }, | |
74 | { | |
9929c817 | 75 | /* timezone, check only */ |
04e62715 RS |
76 | "20170217180105+0800", 0, 0, -1, NULL, |
77 | }, | |
78 | { | |
79 | /* SS is missing, set string */ | |
80 | "201702171801Z", 1, 0, -1, NULL, | |
81 | }, | |
82 | { | |
83 | /* fractional seconds, set string */ | |
84 | "20170217180105.001Z", 1, 0, -1, NULL, | |
85 | }, | |
86 | { | |
9929c817 | 87 | /* timezone, set string */ |
04e62715 RS |
88 | "20170217180105+0800", 1, 0, -1, NULL, |
89 | }, | |
90 | { | |
91 | /* good format, check returned 'turned' string */ | |
92 | "20170217180154Z", 1, 1, V_ASN1_UTCTIME, "170217180154Z", | |
93 | }, | |
94 | { | |
95 | /* good format, check returned string */ | |
96 | "20510217180154Z", 1, 1, V_ASN1_GENERALIZEDTIME, "20510217180154Z", | |
97 | }, | |
98 | { | |
99 | /* good format but out of UTC range, check returned string */ | |
100 | "19230419180154Z", 1, 1, V_ASN1_GENERALIZEDTIME, "19230419180154Z", | |
101 | }, | |
102 | /* UTC */ | |
103 | { | |
104 | /* SS is missing, check only */ | |
105 | "1702171801Z", 0, 0, -1, NULL, | |
106 | }, | |
3d0f1cb9 PY |
107 | { |
108 | /* not leap year, check only */ | |
109 | "050229180101Z", 0, 0, -1, NULL, | |
110 | }, | |
111 | { | |
112 | /* leap year, check only */ | |
113 | "040229180101Z", 0, 1, -1, NULL, | |
114 | }, | |
04e62715 | 115 | { |
9929c817 | 116 | /* timezone, check only */ |
04e62715 RS |
117 | "170217180154+0800", 0, 0, -1, NULL, |
118 | }, | |
119 | { | |
120 | /* SS is missing, set string */ | |
121 | "1702171801Z", 1, 0, -1, NULL, | |
122 | }, | |
123 | { | |
9929c817 | 124 | /* timezone, set string */ |
04e62715 RS |
125 | "170217180154+0800", 1, 0, -1, NULL, |
126 | }, | |
127 | { | |
128 | /* 2017, good format, check returned string */ | |
129 | "170217180154Z", 1, 1, V_ASN1_UTCTIME, "170217180154Z", | |
130 | }, | |
131 | { | |
132 | /* 1998, good format, check returned string */ | |
133 | "981223180154Z", 1, 1, V_ASN1_UTCTIME, "981223180154Z", | |
134 | }, | |
135 | }; | |
136 | ||
80770da3 EK |
137 | static TESTDATA x509_cmp_tests[] = { |
138 | { | |
139 | "20170217180154Z", V_ASN1_GENERALIZEDTIME, | |
140 | /* The same in seconds since epoch. */ | |
141 | 1487354514, -1, | |
142 | }, | |
143 | { | |
144 | "20170217180154Z", V_ASN1_GENERALIZEDTIME, | |
145 | /* One second more. */ | |
146 | 1487354515, -1, | |
147 | }, | |
148 | { | |
149 | "20170217180154Z", V_ASN1_GENERALIZEDTIME, | |
150 | /* One second less. */ | |
151 | 1487354513, 1, | |
152 | }, | |
153 | /* Same as UTC time. */ | |
154 | { | |
155 | "170217180154Z", V_ASN1_UTCTIME, | |
156 | /* The same in seconds since epoch. */ | |
157 | 1487354514, -1, | |
158 | }, | |
159 | { | |
160 | "170217180154Z", V_ASN1_UTCTIME, | |
161 | /* One second more. */ | |
162 | 1487354515, -1, | |
163 | }, | |
164 | { | |
165 | "170217180154Z", V_ASN1_UTCTIME, | |
166 | /* One second less. */ | |
167 | 1487354513, 1, | |
168 | }, | |
169 | /* UTCTime from the 20th century. */ | |
170 | { | |
171 | "990217180154Z", V_ASN1_UTCTIME, | |
172 | /* The same in seconds since epoch. */ | |
173 | 919274514, -1, | |
174 | }, | |
175 | { | |
176 | "990217180154Z", V_ASN1_UTCTIME, | |
177 | /* One second more. */ | |
178 | 919274515, -1, | |
179 | }, | |
180 | { | |
181 | "990217180154Z", V_ASN1_UTCTIME, | |
182 | /* One second less. */ | |
183 | 919274513, 1, | |
184 | }, | |
185 | /* Various invalid formats. */ | |
186 | { | |
187 | /* No trailing Z. */ | |
188 | "20170217180154", V_ASN1_GENERALIZEDTIME, 0, 0, | |
189 | }, | |
190 | { | |
191 | /* No trailing Z, UTCTime. */ | |
192 | "170217180154", V_ASN1_UTCTIME, 0, 0, | |
193 | }, | |
194 | { | |
195 | /* No seconds. */ | |
196 | "201702171801Z", V_ASN1_GENERALIZEDTIME, 0, 0, | |
197 | }, | |
198 | { | |
199 | /* No seconds, UTCTime. */ | |
200 | "1702171801Z", V_ASN1_UTCTIME, 0, 0, | |
201 | }, | |
202 | { | |
203 | /* Fractional seconds. */ | |
204 | "20170217180154.001Z", V_ASN1_GENERALIZEDTIME, 0, 0, | |
205 | }, | |
206 | { | |
207 | /* Fractional seconds, UTCTime. */ | |
208 | "170217180154.001Z", V_ASN1_UTCTIME, 0, 0, | |
209 | }, | |
210 | { | |
211 | /* Timezone offset. */ | |
212 | "20170217180154+0100", V_ASN1_GENERALIZEDTIME, 0, 0, | |
213 | }, | |
214 | { | |
215 | /* Timezone offset, UTCTime. */ | |
216 | "170217180154+0100", V_ASN1_UTCTIME, 0, 0, | |
217 | }, | |
218 | { | |
219 | /* Extra digits. */ | |
220 | "2017021718015400Z", V_ASN1_GENERALIZEDTIME, 0, 0, | |
221 | }, | |
222 | { | |
223 | /* Extra digits, UTCTime. */ | |
224 | "17021718015400Z", V_ASN1_UTCTIME, 0, 0, | |
225 | }, | |
226 | { | |
227 | /* Non-digits. */ | |
228 | "2017021718015aZ", V_ASN1_GENERALIZEDTIME, 0, 0, | |
229 | }, | |
230 | { | |
231 | /* Non-digits, UTCTime. */ | |
232 | "17021718015aZ", V_ASN1_UTCTIME, 0, 0, | |
233 | }, | |
234 | { | |
235 | /* Trailing garbage. */ | |
236 | "20170217180154Zlongtrailinggarbage", V_ASN1_GENERALIZEDTIME, 0, 0, | |
237 | }, | |
238 | { | |
239 | /* Trailing garbage, UTCTime. */ | |
240 | "170217180154Zlongtrailinggarbage", V_ASN1_UTCTIME, 0, 0, | |
241 | }, | |
242 | { | |
243 | /* Swapped type. */ | |
244 | "20170217180154Z", V_ASN1_UTCTIME, 0, 0, | |
245 | }, | |
246 | { | |
247 | /* Swapped type. */ | |
248 | "170217180154Z", V_ASN1_GENERALIZEDTIME, 0, 0, | |
249 | }, | |
250 | { | |
251 | /* Bad type. */ | |
252 | "20170217180154Z", V_ASN1_OCTET_STRING, 0, 0, | |
253 | }, | |
254 | }; | |
255 | ||
256 | static int test_x509_cmp_time(int idx) | |
257 | { | |
258 | ASN1_TIME t; | |
259 | int result; | |
260 | ||
261 | memset(&t, 0, sizeof(t)); | |
262 | t.type = x509_cmp_tests[idx].type; | |
263 | t.data = (unsigned char*)(x509_cmp_tests[idx].data); | |
264 | t.length = strlen(x509_cmp_tests[idx].data); | |
04e62715 | 265 | t.flags = 0; |
80770da3 EK |
266 | |
267 | result = X509_cmp_time(&t, &x509_cmp_tests[idx].cmp_time); | |
2fae041d P |
268 | if (!TEST_int_eq(result, x509_cmp_tests[idx].expected)) { |
269 | TEST_info("test_x509_cmp_time(%d) failed: expected %d, got %d\n", | |
80770da3 EK |
270 | idx, x509_cmp_tests[idx].expected, result); |
271 | return 0; | |
272 | } | |
273 | return 1; | |
274 | } | |
275 | ||
31a80694 | 276 | static int test_x509_cmp_time_current(void) |
80770da3 EK |
277 | { |
278 | time_t now = time(NULL); | |
279 | /* Pick a day earlier and later, relative to any system clock. */ | |
280 | ASN1_TIME *asn1_before = NULL, *asn1_after = NULL; | |
281 | int cmp_result, failed = 0; | |
282 | ||
283 | asn1_before = ASN1_TIME_adj(NULL, now, -1, 0); | |
284 | asn1_after = ASN1_TIME_adj(NULL, now, 1, 0); | |
285 | ||
286 | cmp_result = X509_cmp_time(asn1_before, NULL); | |
2fae041d | 287 | if (!TEST_int_eq(cmp_result, -1)) |
80770da3 | 288 | failed = 1; |
80770da3 EK |
289 | |
290 | cmp_result = X509_cmp_time(asn1_after, NULL); | |
2fae041d | 291 | if (!TEST_int_eq(cmp_result, 1)) |
80770da3 | 292 | failed = 1; |
80770da3 EK |
293 | |
294 | ASN1_TIME_free(asn1_before); | |
295 | ASN1_TIME_free(asn1_after); | |
296 | ||
297 | return failed == 0; | |
298 | } | |
299 | ||
25d7cd1d DDO |
300 | static int test_X509_cmp_timeframe_vpm(const X509_VERIFY_PARAM *vpm, |
301 | ASN1_TIME *asn1_before, | |
302 | ASN1_TIME *asn1_mid, | |
303 | ASN1_TIME *asn1_after) | |
304 | { | |
305 | int always_0 = vpm != NULL | |
306 | && (X509_VERIFY_PARAM_get_flags(vpm) & X509_V_FLAG_USE_CHECK_TIME) == 0 | |
307 | && (X509_VERIFY_PARAM_get_flags(vpm) & X509_V_FLAG_NO_CHECK_TIME) != 0; | |
308 | ||
309 | return asn1_before != NULL && asn1_mid != NULL && asn1_after != NULL | |
310 | && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_before, asn1_after), 0) | |
311 | && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_before, NULL), 0) | |
312 | && TEST_int_eq(X509_cmp_timeframe(vpm, NULL, asn1_after), 0) | |
313 | && TEST_int_eq(X509_cmp_timeframe(vpm, NULL, NULL), 0) | |
314 | && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_after, asn1_after), | |
315 | always_0 ? 0 : -1) | |
316 | && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_before, asn1_before), | |
317 | always_0 ? 0 : 1) | |
318 | && TEST_int_eq(X509_cmp_timeframe(vpm, asn1_after, asn1_before), | |
319 | always_0 ? 0 : 1); | |
320 | } | |
321 | ||
322 | static int test_X509_cmp_timeframe(void) | |
323 | { | |
324 | time_t now = time(NULL); | |
325 | ASN1_TIME *asn1_mid = ASN1_TIME_adj(NULL, now, 0, 0); | |
326 | /* Pick a day earlier and later, relative to any system clock. */ | |
327 | ASN1_TIME *asn1_before = ASN1_TIME_adj(NULL, now, -1, 0); | |
328 | ASN1_TIME *asn1_after = ASN1_TIME_adj(NULL, now, 1, 0); | |
329 | X509_VERIFY_PARAM *vpm = X509_VERIFY_PARAM_new(); | |
86723c2a | 330 | int res = 0; |
25d7cd1d | 331 | |
86723c2a P |
332 | if (vpm == NULL) |
333 | goto finish; | |
334 | res = test_X509_cmp_timeframe_vpm(NULL, asn1_before, asn1_mid, asn1_after) | |
25d7cd1d DDO |
335 | && test_X509_cmp_timeframe_vpm(vpm, asn1_before, asn1_mid, asn1_after); |
336 | ||
337 | X509_VERIFY_PARAM_set_time(vpm, now); | |
338 | res = res | |
339 | && test_X509_cmp_timeframe_vpm(vpm, asn1_before, asn1_mid, asn1_after) | |
340 | && X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME) | |
341 | && test_X509_cmp_timeframe_vpm(vpm, asn1_before, asn1_mid, asn1_after); | |
342 | ||
343 | X509_VERIFY_PARAM_free(vpm); | |
86723c2a | 344 | finish: |
25d7cd1d DDO |
345 | ASN1_TIME_free(asn1_mid); |
346 | ASN1_TIME_free(asn1_before); | |
347 | ASN1_TIME_free(asn1_after); | |
348 | ||
349 | return res; | |
350 | } | |
351 | ||
04e62715 RS |
352 | static int test_x509_time(int idx) |
353 | { | |
354 | ASN1_TIME *t = NULL; | |
355 | int result, rv = 0; | |
356 | ||
357 | if (x509_format_tests[idx].set_string) { | |
358 | /* set-string mode */ | |
359 | t = ASN1_TIME_new(); | |
360 | if (t == NULL) { | |
361 | TEST_info("test_x509_time(%d) failed: internal error\n", idx); | |
362 | return 0; | |
363 | } | |
364 | } | |
365 | ||
366 | result = ASN1_TIME_set_string_X509(t, x509_format_tests[idx].data); | |
367 | /* time string parsing result is always checked against what's expected */ | |
368 | if (!TEST_int_eq(result, x509_format_tests[idx].expected)) { | |
369 | TEST_info("test_x509_time(%d) failed: expected %d, got %d\n", | |
370 | idx, x509_format_tests[idx].expected, result); | |
371 | goto out; | |
372 | } | |
373 | ||
374 | /* if t is not NULL but expected_type is ignored(-1), it is an 'OK' case */ | |
375 | if (t != NULL && x509_format_tests[idx].expected_type != -1) { | |
376 | if (!TEST_int_eq(t->type, x509_format_tests[idx].expected_type)) { | |
377 | TEST_info("test_x509_time(%d) failed: expected_type %d, got %d\n", | |
378 | idx, x509_format_tests[idx].expected_type, t->type); | |
379 | goto out; | |
380 | } | |
381 | } | |
382 | ||
383 | /* if t is not NULL but expected_string is NULL, it is an 'OK' case too */ | |
384 | if (t != NULL && x509_format_tests[idx].expected_string) { | |
1f365708 MC |
385 | if (!TEST_mem_eq((const char *)t->data, t->length, |
386 | x509_format_tests[idx].expected_string, | |
387 | strlen(x509_format_tests[idx].expected_string))) { | |
388 | TEST_info("test_x509_time(%d) failed: expected_string %s, got %.*s\n", | |
389 | idx, x509_format_tests[idx].expected_string, t->length, | |
390 | t->data); | |
04e62715 RS |
391 | goto out; |
392 | } | |
393 | } | |
394 | ||
395 | rv = 1; | |
396 | out: | |
397 | if (t != NULL) | |
398 | ASN1_TIME_free(t); | |
399 | return rv; | |
400 | } | |
401 | ||
1a68e5b0 P |
402 | static const struct { |
403 | int y, m, d; | |
404 | int yd, wd; | |
405 | } day_of_week_tests[] = { | |
406 | /*YYYY MM DD DoY DoW */ | |
407 | { 1900, 1, 1, 0, 1 }, | |
408 | { 1900, 2, 28, 58, 3 }, | |
409 | { 1900, 3, 1, 59, 4 }, | |
410 | { 1900, 12, 31, 364, 1 }, | |
411 | { 1901, 1, 1, 0, 2 }, | |
412 | { 1970, 1, 1, 0, 4 }, | |
413 | { 1999, 1, 10, 9, 0 }, | |
414 | { 1999, 12, 31, 364, 5 }, | |
415 | { 2000, 1, 1, 0, 6 }, | |
416 | { 2000, 2, 28, 58, 1 }, | |
417 | { 2000, 2, 29, 59, 2 }, | |
418 | { 2000, 3, 1, 60, 3 }, | |
419 | { 2000, 12, 31, 365, 0 }, | |
420 | { 2001, 1, 1, 0, 1 }, | |
421 | { 2008, 1, 1, 0, 2 }, | |
422 | { 2008, 2, 28, 58, 4 }, | |
423 | { 2008, 2, 29, 59, 5 }, | |
424 | { 2008, 3, 1, 60, 6 }, | |
425 | { 2008, 12, 31, 365, 3 }, | |
426 | { 2009, 1, 1, 0, 4 }, | |
427 | { 2011, 1, 1, 0, 6 }, | |
428 | { 2011, 2, 28, 58, 1 }, | |
429 | { 2011, 3, 1, 59, 2 }, | |
430 | { 2011, 12, 31, 364, 6 }, | |
431 | { 2012, 1, 1, 0, 0 }, | |
432 | { 2019, 1, 2, 1, 3 }, | |
433 | { 2019, 2, 2, 32, 6 }, | |
434 | { 2019, 3, 2, 60, 6 }, | |
435 | { 2019, 4, 2, 91, 2 }, | |
436 | { 2019, 5, 2, 121, 4 }, | |
437 | { 2019, 6, 2, 152, 0 }, | |
438 | { 2019, 7, 2, 182, 2 }, | |
439 | { 2019, 8, 2, 213, 5 }, | |
440 | { 2019, 9, 2, 244, 1 }, | |
441 | { 2019, 10, 2, 274, 3 }, | |
442 | { 2019, 11, 2, 305, 6 }, | |
443 | { 2019, 12, 2, 335, 1 }, | |
444 | { 2020, 1, 2, 1, 4 }, | |
445 | { 2020, 2, 2, 32, 0 }, | |
446 | { 2020, 3, 2, 61, 1 }, | |
447 | { 2020, 4, 2, 92, 4 }, | |
448 | { 2020, 5, 2, 122, 6 }, | |
449 | { 2020, 6, 2, 153, 2 }, | |
450 | { 2020, 7, 2, 183, 4 }, | |
451 | { 2020, 8, 2, 214, 0 }, | |
452 | { 2020, 9, 2, 245, 3 }, | |
453 | { 2020, 10, 2, 275, 5 }, | |
454 | { 2020, 11, 2, 306, 1 }, | |
455 | { 2020, 12, 2, 336, 3 } | |
456 | }; | |
457 | ||
458 | static int test_days(int n) | |
459 | { | |
460 | char d[16]; | |
461 | ASN1_TIME *a = NULL; | |
462 | struct tm t; | |
463 | int r; | |
464 | ||
465 | BIO_snprintf(d, sizeof(d), "%04d%02d%02d050505Z", | |
466 | day_of_week_tests[n].y, day_of_week_tests[n].m, | |
467 | day_of_week_tests[n].d); | |
468 | ||
469 | if (!TEST_ptr(a = ASN1_TIME_new())) | |
470 | return 0; | |
471 | ||
472 | r = TEST_true(ASN1_TIME_set_string(a, d)) | |
473 | && TEST_true(ASN1_TIME_to_tm(a, &t)) | |
474 | && TEST_int_eq(t.tm_yday, day_of_week_tests[n].yd) | |
475 | && TEST_int_eq(t.tm_wday, day_of_week_tests[n].wd); | |
476 | ||
477 | ASN1_TIME_free(a); | |
478 | return r; | |
479 | } | |
480 | ||
a9dee230 PY |
481 | #define construct_asn1_time(s, t, e) \ |
482 | { { sizeof(s) - 1, t, (unsigned char*)s, 0 }, e } | |
483 | ||
484 | static const struct { | |
485 | ASN1_TIME asn1; | |
486 | const char *readable; | |
8c5bff22 | 487 | } x509_print_tests_rfc_822 [] = { |
a9dee230 PY |
488 | /* Generalized Time */ |
489 | construct_asn1_time("20170731222050Z", V_ASN1_GENERALIZEDTIME, | |
490 | "Jul 31 22:20:50 2017 GMT"), | |
491 | /* Generalized Time, no seconds */ | |
492 | construct_asn1_time("201707312220Z", V_ASN1_GENERALIZEDTIME, | |
eadd8c47 | 493 | "Bad time value"), |
a9dee230 PY |
494 | /* Generalized Time, fractional seconds (3 digits) */ |
495 | construct_asn1_time("20170731222050.123Z", V_ASN1_GENERALIZEDTIME, | |
496 | "Jul 31 22:20:50.123 2017 GMT"), | |
497 | /* Generalized Time, fractional seconds (1 digit) */ | |
498 | construct_asn1_time("20170731222050.1Z", V_ASN1_GENERALIZEDTIME, | |
499 | "Jul 31 22:20:50.1 2017 GMT"), | |
500 | /* Generalized Time, fractional seconds (0 digit) */ | |
501 | construct_asn1_time("20170731222050.Z", V_ASN1_GENERALIZEDTIME, | |
502 | "Bad time value"), | |
503 | /* UTC Time */ | |
504 | construct_asn1_time("170731222050Z", V_ASN1_UTCTIME, | |
505 | "Jul 31 22:20:50 2017 GMT"), | |
506 | /* UTC Time, no seconds */ | |
507 | construct_asn1_time("1707312220Z", V_ASN1_UTCTIME, | |
eadd8c47 | 508 | "Bad time value"), |
a9dee230 PY |
509 | }; |
510 | ||
8c5bff22 WE |
511 | static const struct { |
512 | ASN1_TIME asn1; | |
513 | const char *readable; | |
514 | } x509_print_tests_iso_8601 [] = { | |
515 | /* Generalized Time */ | |
516 | construct_asn1_time("20170731222050Z", V_ASN1_GENERALIZEDTIME, | |
517 | "2017-07-31 22:20:50Z"), | |
518 | /* Generalized Time, no seconds */ | |
519 | construct_asn1_time("201707312220Z", V_ASN1_GENERALIZEDTIME, | |
eadd8c47 | 520 | "Bad time value"), |
8c5bff22 WE |
521 | /* Generalized Time, fractional seconds (3 digits) */ |
522 | construct_asn1_time("20170731222050.123Z", V_ASN1_GENERALIZEDTIME, | |
523 | "2017-07-31 22:20:50.123Z"), | |
524 | /* Generalized Time, fractional seconds (1 digit) */ | |
525 | construct_asn1_time("20170731222050.1Z", V_ASN1_GENERALIZEDTIME, | |
526 | "2017-07-31 22:20:50.1Z"), | |
527 | /* Generalized Time, fractional seconds (0 digit) */ | |
528 | construct_asn1_time("20170731222050.Z", V_ASN1_GENERALIZEDTIME, | |
529 | "Bad time value"), | |
530 | /* UTC Time */ | |
531 | construct_asn1_time("170731222050Z", V_ASN1_UTCTIME, | |
532 | "2017-07-31 22:20:50Z"), | |
533 | /* UTC Time, no seconds */ | |
534 | construct_asn1_time("1707312220Z", V_ASN1_UTCTIME, | |
eadd8c47 | 535 | "Bad time value"), |
8c5bff22 WE |
536 | }; |
537 | ||
538 | static int test_x509_time_print_rfc_822(int idx) | |
539 | { | |
540 | BIO *m; | |
541 | int ret = 0, rv; | |
542 | char *pp; | |
543 | const char *readable; | |
544 | ||
545 | if (!TEST_ptr(m = BIO_new(BIO_s_mem()))) | |
546 | goto err; | |
547 | ||
548 | rv = ASN1_TIME_print_ex(m, &x509_print_tests_rfc_822[idx].asn1, ASN1_DTFLGS_RFC822); | |
549 | readable = x509_print_tests_rfc_822[idx].readable; | |
550 | ||
551 | if (rv == 0 && !TEST_str_eq(readable, "Bad time value")) { | |
552 | /* only if the test case intends to fail... */ | |
553 | goto err; | |
554 | } | |
555 | if (!TEST_int_ne(rv = BIO_get_mem_data(m, &pp), 0) | |
556 | || !TEST_int_eq(rv, (int)strlen(readable)) | |
557 | || !TEST_strn_eq(pp, readable, rv)) | |
558 | goto err; | |
559 | ||
560 | ret = 1; | |
561 | err: | |
562 | BIO_free(m); | |
563 | return ret; | |
564 | } | |
565 | ||
566 | static int test_x509_time_print_iso_8601(int idx) | |
a9dee230 PY |
567 | { |
568 | BIO *m; | |
569 | int ret = 0, rv; | |
570 | char *pp; | |
571 | const char *readable; | |
572 | ||
573 | if (!TEST_ptr(m = BIO_new(BIO_s_mem()))) | |
574 | goto err; | |
575 | ||
8c5bff22 WE |
576 | rv = ASN1_TIME_print_ex(m, &x509_print_tests_iso_8601[idx].asn1, ASN1_DTFLGS_ISO8601); |
577 | readable = x509_print_tests_iso_8601[idx].readable; | |
a9dee230 PY |
578 | |
579 | if (rv == 0 && !TEST_str_eq(readable, "Bad time value")) { | |
580 | /* only if the test case intends to fail... */ | |
581 | goto err; | |
582 | } | |
583 | if (!TEST_int_ne(rv = BIO_get_mem_data(m, &pp), 0) | |
584 | || !TEST_int_eq(rv, (int)strlen(readable)) | |
585 | || !TEST_strn_eq(pp, readable, rv)) | |
586 | goto err; | |
587 | ||
588 | ret = 1; | |
589 | err: | |
590 | BIO_free(m); | |
591 | return ret; | |
592 | } | |
593 | ||
3cb7c5cf | 594 | int setup_tests(void) |
80770da3 EK |
595 | { |
596 | ADD_TEST(test_x509_cmp_time_current); | |
25d7cd1d | 597 | ADD_TEST(test_X509_cmp_timeframe); |
80770da3 | 598 | ADD_ALL_TESTS(test_x509_cmp_time, OSSL_NELEM(x509_cmp_tests)); |
04e62715 | 599 | ADD_ALL_TESTS(test_x509_time, OSSL_NELEM(x509_format_tests)); |
1a68e5b0 | 600 | ADD_ALL_TESTS(test_days, OSSL_NELEM(day_of_week_tests)); |
8c5bff22 WE |
601 | ADD_ALL_TESTS(test_x509_time_print_rfc_822, OSSL_NELEM(x509_print_tests_rfc_822)); |
602 | ADD_ALL_TESTS(test_x509_time_print_iso_8601, OSSL_NELEM(x509_print_tests_iso_8601)); | |
ad887416 | 603 | return 1; |
80770da3 | 604 | } |