1 /*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 #include "s2n_test.h"
17 #include "utils/s2n_asn1_time.h"
18
19 #include <stdlib.h>
20 #include <time.h>
21
main(int argc,char ** argv)22 int main(int argc, char **argv)
23 {
24 BEGIN_TEST();
25 EXPECT_SUCCESS(s2n_disable_tls13());
26
27 /* October 20, 2017 3:09:11 PM GMT-07:00 */
28 uint64_t expected_ns = 1508539878000000000;
29
30 /* test GMT date parses without the millis*/
31 {
32 const char *time_str = "20171020225118Z";
33 uint64_t timestamp = 0;
34 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp));
35 EXPECT_EQUAL(expected_ns, timestamp);
36 }
37
38 /* test GMT date parses */
39 {
40 const char *time_str = "20171020225118.999Z";
41 uint64_t timestamp = 0;
42 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp));
43 EXPECT_EQUAL(expected_ns, timestamp);
44 }
45
46 /* test zero offset date parses */
47 {
48 const char *time_str = "20171020225118.999+0000";
49 uint64_t timestamp = 0;
50 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp));
51 EXPECT_EQUAL(expected_ns, timestamp);
52 }
53
54 /* test 1:15 west offset date parses */
55 {
56 const char *time_str = "20171020213618.999-0115";
57 uint64_t timestamp = 0;
58 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp));
59 EXPECT_EQUAL(expected_ns, timestamp);
60 }
61
62 /* test 1:15 east offset date parses */
63 {
64 const char *time_str = "20171021000618.999+0115";
65 uint64_t timestamp = 0;
66 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp));
67 EXPECT_EQUAL(expected_ns, timestamp);
68 }
69
70 /* test invalid date fails */
71 {
72 const char *time_str = "201710210";
73 uint64_t timestamp = 0;
74 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
75 }
76
77 /* test invalid tz character fails. */
78 {
79 const char *time_str = "20171020225118.999q";
80 uint64_t timestamp = 0;
81 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
82 }
83
84 /* test invalid month fails. */
85 {
86 const char *time_str = "20171320225118.999Z";
87 uint64_t timestamp = 0;
88 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
89 }
90
91 /* test invalid day fails. */
92 {
93 const char *time_str = "20171032225118.999Z";
94 uint64_t timestamp = 0;
95 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
96 }
97
98 /* test invalid hour fails. */
99 {
100 const char *time_str = "20171020255118.999Z";
101 uint64_t timestamp = 0;
102 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
103 }
104
105 /* test invalid minute fails. */
106 {
107 const char *time_str = "20171020226118.999Z";
108 uint64_t timestamp = 0;
109 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
110 }
111
112 /* test invalid second fails. */
113 {
114 const char *time_str = "20171020225161.999Z";
115 uint64_t timestamp = 0;
116 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
117 }
118
119 /* test empty fails */
120 {
121 const char *time_str = "";
122 uint64_t timestamp = 0;
123 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
124 }
125
126 /* now run a test where we are certain UTC is not the timezone used, but make sure it still converts.
127 * Also note, the moment timezones come into play, so does daylight savings time. So there are two tests here, across the timezone boundaries.*/
128 {
129 char *tz = getenv("TZ");
130 setenv("TZ", "US/Pacific", 1);
131 tzset();
132 const char *dst_time_str = "20171020225118.999Z";
133 uint64_t timestamp = 0;
134 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(dst_time_str, strlen(dst_time_str), ×tamp));
135 EXPECT_EQUAL(expected_ns, timestamp);
136
137 uint64_t non_dst_stamp = 1510610608000000000;
138 const char *non_dst_str = "20171113220328.999Z";
139 timestamp = 0;
140 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(non_dst_str, strlen(non_dst_str), ×tamp));
141 EXPECT_EQUAL(non_dst_stamp, timestamp);
142 if(tz) {
143 setenv("TZ", tz, 1);
144 }
145 tzset();
146 }
147
148 /* make sure a leap-year date works */
149 {
150 const char *leap_yr = "20200229220328.999Z";
151 uint64_t leap_yr_stamp = 1583013808000000000;
152 uint64_t timestamp = 0;
153 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(leap_yr, strlen(leap_yr), ×tamp));
154 EXPECT_EQUAL(leap_yr_stamp, timestamp);
155 }
156
157 /* make sure a leap-year date on a non-leap year works */
158 {
159 const char *non_leap_yr = "20170229220328.999Z";
160 uint64_t non_leap_yr_stamp = 1488405808000000000;
161 uint64_t timestamp = 0;
162 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(non_leap_yr, strlen(non_leap_yr), ×tamp));
163 EXPECT_EQUAL(non_leap_yr_stamp, timestamp);
164 }
165
166 /* test non digit character fails */
167 {
168 const char *time_str = "2017102B225118.999Z";
169 uint64_t timestamp = 0;
170 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_INVALID_ARGUMENT);
171 }
172
173 /* Test Epoch timestamp in UTC */
174 {
175 const char *time_str = "19700101000000.000Z";
176 uint64_t timestamp = 1; /* Initial assignment must be non-zero, so we know if it was set correctly. */
177 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp));
178 EXPECT_EQUAL(0, timestamp);
179 }
180
181 /* Test Epoch timestamp with 1:15 east offset */
182 {
183 const char *time_str = "19700101011500.000+0115";
184 uint64_t timestamp = 1; /* Initial assignment must be non-zero, so we know if it was set correctly. */
185 EXPECT_OK(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp));
186 EXPECT_EQUAL(0, timestamp);
187 }
188
189 /* Note: We cannot use the function to convert a timestamp from before Epoch with an offset,
190 * even if the adjusted time falls after the Epoch, e.g. "19691231224500.000-0115", because
191 * mktime() will fail. */
192
193 /* Test UTC time before Epoch fails */
194 {
195 const char *time_str = "19691231235959.999Z";
196 uint64_t timestamp = 0;
197 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_SAFETY);
198 }
199
200 /* Test time from way before Epoch*/
201 {
202 const char *time_str = "19680101000000.000Z";
203 uint64_t timestamp = 0;
204 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_SAFETY);
205 }
206
207 /* Test time before Epoch with east offset fails */
208 {
209 const char *time_str = "19700101011500.000+0116"; /* One minute before Epoch */
210 uint64_t timestamp = 0;
211 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_SAFETY);
212 }
213
214 /* Test time before Epoch with west offset fails */
215 {
216 const char *time_str = "19691231224400.000-0115"; /* One minute before Epoch */
217 uint64_t timestamp = 0;
218 EXPECT_ERROR_WITH_ERRNO(s2n_asn1_time_to_nano_since_epoch_ticks(time_str, strlen(time_str), ×tamp), S2N_ERR_SAFETY);
219 }
220
221 END_TEST();
222 }
223