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