/src/openssl41/crypto/x509/v3_timespec.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (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 | | #include <stdio.h> |
11 | | #include <openssl/asn1t.h> |
12 | | #include <openssl/x509v3.h> |
13 | | #include <crypto/asn1.h> |
14 | | #include "ext_dat.h" |
15 | | |
16 | | static const char *const WEEKDAY_NAMES[7] = { |
17 | | "SUN", |
18 | | "MON", |
19 | | "TUE", |
20 | | "WED", |
21 | | "THU", |
22 | | "FRI", |
23 | | "SAT" |
24 | | }; |
25 | | |
26 | | static const char *const WEEK_NAMES[5] = { |
27 | | "first", |
28 | | "second", |
29 | | "third", |
30 | | "fourth", |
31 | | "final" |
32 | | }; |
33 | | |
34 | | static const char *const MONTH_NAMES[12] = { |
35 | | "JAN", |
36 | | "FEB", |
37 | | "MAR", |
38 | | "APR", |
39 | | "MAY", |
40 | | "JUN", |
41 | | "JUL", |
42 | | "AUG", |
43 | | "SEPT", |
44 | | "OCT", |
45 | | "NOV", |
46 | | "DEC" |
47 | | }; |
48 | | |
49 | | ASN1_SEQUENCE(OSSL_TIME_SPEC_ABSOLUTE) = { |
50 | | ASN1_EXP_OPT(OSSL_TIME_SPEC_ABSOLUTE, startTime, ASN1_GENERALIZEDTIME, 0), |
51 | | ASN1_EXP_OPT(OSSL_TIME_SPEC_ABSOLUTE, endTime, ASN1_GENERALIZEDTIME, 1), |
52 | 40.6k | } ASN1_SEQUENCE_END(OSSL_TIME_SPEC_ABSOLUTE) |
53 | 40.6k | |
54 | 40.6k | ASN1_SEQUENCE(OSSL_DAY_TIME) = { |
55 | 40.6k | ASN1_EXP_OPT(OSSL_DAY_TIME, hour, ASN1_INTEGER, 0), |
56 | 40.6k | ASN1_EXP_OPT(OSSL_DAY_TIME, minute, ASN1_INTEGER, 1), |
57 | 40.6k | ASN1_EXP_OPT(OSSL_DAY_TIME, second, ASN1_INTEGER, 2), |
58 | 40.6k | } ASN1_SEQUENCE_END(OSSL_DAY_TIME) |
59 | 10.1k | |
60 | 10.1k | ASN1_SEQUENCE(OSSL_DAY_TIME_BAND) = { |
61 | 10.1k | ASN1_EXP_OPT(OSSL_DAY_TIME_BAND, startDayTime, OSSL_DAY_TIME, 0), |
62 | 10.1k | ASN1_EXP_OPT(OSSL_DAY_TIME_BAND, endDayTime, OSSL_DAY_TIME, 1), |
63 | 53.7k | } ASN1_SEQUENCE_END(OSSL_DAY_TIME_BAND) |
64 | 53.7k | |
65 | 53.7k | ASN1_CHOICE(OSSL_NAMED_DAY) = { |
66 | 53.7k | ASN1_SET_OF(OSSL_NAMED_DAY, choice.intNamedDays, ASN1_ENUMERATED), |
67 | 53.7k | ASN1_SIMPLE(OSSL_NAMED_DAY, choice.bitNamedDays, ASN1_BIT_STRING), |
68 | 53.7k | } ASN1_CHOICE_END(OSSL_NAMED_DAY) |
69 | 21.5k | |
70 | 21.5k | ASN1_CHOICE(OSSL_TIME_SPEC_X_DAY_OF) = { |
71 | 21.5k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.first, OSSL_NAMED_DAY, 1), |
72 | 21.5k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.second, OSSL_NAMED_DAY, 2), |
73 | 21.5k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.third, OSSL_NAMED_DAY, 3), |
74 | 21.5k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.fourth, OSSL_NAMED_DAY, 4), |
75 | 21.5k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.fifth, OSSL_NAMED_DAY, 5), |
76 | 23.3k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_X_DAY_OF) |
77 | 23.3k | |
78 | 23.3k | ASN1_CHOICE(OSSL_TIME_SPEC_DAY) = { |
79 | 23.3k | ASN1_SET_OF(OSSL_TIME_SPEC_DAY, choice.intDay, ASN1_INTEGER), |
80 | 23.3k | ASN1_SIMPLE(OSSL_TIME_SPEC_DAY, choice.bitDay, ASN1_BIT_STRING), |
81 | 23.3k | ASN1_SIMPLE(OSSL_TIME_SPEC_DAY, choice.dayOf, OSSL_TIME_SPEC_X_DAY_OF), |
82 | 405k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_DAY) |
83 | 405k | |
84 | 405k | ASN1_CHOICE(OSSL_TIME_SPEC_WEEKS) = { |
85 | 405k | ASN1_SIMPLE(OSSL_TIME_SPEC_WEEKS, choice.allWeeks, ASN1_NULL), |
86 | 405k | ASN1_SET_OF(OSSL_TIME_SPEC_WEEKS, choice.intWeek, ASN1_INTEGER), |
87 | 405k | ASN1_SIMPLE(OSSL_TIME_SPEC_WEEKS, choice.bitWeek, ASN1_BIT_STRING), |
88 | 405k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_WEEKS) |
89 | 401k | |
90 | 401k | ASN1_CHOICE(OSSL_TIME_SPEC_MONTH) = { |
91 | 401k | ASN1_SIMPLE(OSSL_TIME_SPEC_MONTH, choice.allMonths, ASN1_NULL), |
92 | 401k | ASN1_SET_OF(OSSL_TIME_SPEC_MONTH, choice.intMonth, ASN1_INTEGER), |
93 | 401k | ASN1_SIMPLE(OSSL_TIME_SPEC_MONTH, choice.bitMonth, ASN1_BIT_STRING), |
94 | 401k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_MONTH) |
95 | 401k | |
96 | 401k | ASN1_SEQUENCE(OSSL_TIME_PERIOD) = { |
97 | 401k | ASN1_EXP_SET_OF_OPT(OSSL_TIME_PERIOD, timesOfDay, OSSL_DAY_TIME_BAND, 0), |
98 | 401k | ASN1_EXP_OPT(OSSL_TIME_PERIOD, days, OSSL_TIME_SPEC_DAY, 1), |
99 | 401k | ASN1_EXP_OPT(OSSL_TIME_PERIOD, weeks, OSSL_TIME_SPEC_WEEKS, 2), |
100 | 401k | ASN1_EXP_OPT(OSSL_TIME_PERIOD, months, OSSL_TIME_SPEC_MONTH, 3), |
101 | 401k | ASN1_EXP_SET_OF_OPT(OSSL_TIME_PERIOD, years, ASN1_INTEGER, 4), |
102 | 401k | } ASN1_SEQUENCE_END(OSSL_TIME_PERIOD) |
103 | 106k | |
104 | 106k | ASN1_CHOICE(OSSL_TIME_SPEC_TIME) = { |
105 | 106k | ASN1_SIMPLE(OSSL_TIME_SPEC_TIME, choice.absolute, OSSL_TIME_SPEC_ABSOLUTE), |
106 | 106k | ASN1_SET_OF(OSSL_TIME_SPEC_TIME, choice.periodic, OSSL_TIME_PERIOD) |
107 | 210k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_TIME) |
108 | 210k | |
109 | 210k | ASN1_SEQUENCE(OSSL_TIME_SPEC) = { |
110 | 210k | ASN1_SIMPLE(OSSL_TIME_SPEC, time, OSSL_TIME_SPEC_TIME), |
111 | 210k | ASN1_OPT(OSSL_TIME_SPEC, notThisTime, ASN1_FBOOLEAN), |
112 | 210k | ASN1_OPT(OSSL_TIME_SPEC, timeZone, ASN1_INTEGER), |
113 | 210k | } ASN1_SEQUENCE_END(OSSL_TIME_SPEC) |
114 | 60.4k | |
115 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_DAY_TIME) |
116 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_DAY_TIME_BAND) |
117 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_DAY) |
118 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_WEEKS) |
119 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_MONTH) |
120 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_NAMED_DAY) |
121 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_X_DAY_OF) |
122 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_ABSOLUTE) |
123 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_TIME) |
124 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC) |
125 | 60.4k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_PERIOD) |
126 | 60.4k | |
127 | 60.4k | static int i2r_OSSL_TIME_SPEC_ABSOLUTE(X509V3_EXT_METHOD *method, |
128 | 60.4k | OSSL_TIME_SPEC_ABSOLUTE *time, |
129 | 60.4k | BIO *out, int indent) |
130 | 60.4k | { |
131 | 406 | if (time->startTime != NULL && time->endTime != NULL) { |
132 | 0 | if (!BIO_puts(out, "Any time between ")) |
133 | 0 | return 0; |
134 | 0 | if (!ossl_asn1_time_print_ex(out, time->startTime, 0)) |
135 | 0 | return 0; |
136 | 0 | if (!BIO_puts(out, " and ")) |
137 | 0 | return 0; |
138 | 0 | if (!ossl_asn1_time_print_ex(out, time->endTime, 0)) |
139 | 0 | return 0; |
140 | 406 | } else if (time->startTime != NULL) { |
141 | 0 | if (!BIO_puts(out, "Any time after ")) |
142 | 0 | return 0; |
143 | 0 | if (!ossl_asn1_time_print_ex(out, time->startTime, 0)) |
144 | 0 | return 0; |
145 | 0 | if (BIO_printf(out, "%.*s", time->startTime->length, |
146 | 0 | time->startTime->length |
147 | 0 | ? time->startTime->data |
148 | 0 | : (const unsigned char *)"") |
149 | 0 | <= 0) |
150 | 0 | return 0; |
151 | 406 | } else if (time->endTime != NULL) { |
152 | 0 | if (!BIO_puts(out, "Any time until ")) |
153 | 0 | return 0; |
154 | 0 | if (!ossl_asn1_time_print_ex(out, time->endTime, 0)) |
155 | 0 | return 0; |
156 | 406 | } else { /* Invalid: there must be SOME time specified. */ |
157 | 406 | return BIO_puts(out, "INVALID (EMPTY)"); |
158 | 406 | } |
159 | 0 | return 1; |
160 | 406 | } |
161 | | |
162 | | static int i2r_OSSL_DAY_TIME(X509V3_EXT_METHOD *method, |
163 | | OSSL_DAY_TIME *dt, |
164 | | BIO *out, int indent) |
165 | 128 | { |
166 | 128 | int64_t h = 0; |
167 | 128 | int64_t m = 0; |
168 | 128 | int64_t s = 0; |
169 | | |
170 | 128 | if (!dt->hour || !ASN1_INTEGER_get_int64(&h, dt->hour)) |
171 | 128 | return 0; |
172 | 0 | if (dt->minute && !ASN1_INTEGER_get_int64(&m, dt->minute)) |
173 | 0 | return 0; |
174 | 0 | if (dt->second && !ASN1_INTEGER_get_int64(&s, dt->second)) |
175 | 0 | return 0; |
176 | 0 | return BIO_printf(out, "%02lld:%02lld:%02lld", |
177 | 0 | (long long int)h, (long long int)m, (long long int)s) |
178 | 0 | > 0; |
179 | 0 | } |
180 | | |
181 | | static int i2r_OSSL_DAY_TIME_BAND(X509V3_EXT_METHOD *method, |
182 | | OSSL_DAY_TIME_BAND *band, |
183 | | BIO *out, int indent) |
184 | 1.13k | { |
185 | 1.13k | if (band->startDayTime) { |
186 | 44 | if (!i2r_OSSL_DAY_TIME(method, band->startDayTime, out, indent)) |
187 | 44 | return 0; |
188 | 1.08k | } else if (!BIO_puts(out, "00:00:00")) { |
189 | 0 | return 0; |
190 | 0 | } |
191 | 1.08k | if (!BIO_puts(out, " - ")) |
192 | 0 | return 0; |
193 | 1.08k | if (band->endDayTime) { |
194 | 84 | if (!i2r_OSSL_DAY_TIME(method, band->endDayTime, out, indent)) |
195 | 84 | return 0; |
196 | 1.00k | } else if (!BIO_puts(out, "23:59:59")) { |
197 | 0 | return 0; |
198 | 0 | } |
199 | 1.00k | return 1; |
200 | 1.08k | } |
201 | | |
202 | | static int print_int_month(BIO *out, int64_t month) |
203 | 7.08k | { |
204 | 7.08k | switch (month) { |
205 | 6.00k | case (OSSL_TIME_SPEC_INT_MONTH_JAN): |
206 | 6.00k | return BIO_puts(out, "JAN"); |
207 | 106 | case (OSSL_TIME_SPEC_INT_MONTH_FEB): |
208 | 106 | return BIO_puts(out, "FEB"); |
209 | 11 | case (OSSL_TIME_SPEC_INT_MONTH_MAR): |
210 | 11 | return BIO_puts(out, "MAR"); |
211 | 29 | case (OSSL_TIME_SPEC_INT_MONTH_APR): |
212 | 29 | return BIO_puts(out, "APR"); |
213 | 27 | case (OSSL_TIME_SPEC_INT_MONTH_MAY): |
214 | 27 | return BIO_puts(out, "MAY"); |
215 | 11 | case (OSSL_TIME_SPEC_INT_MONTH_JUN): |
216 | 11 | return BIO_puts(out, "JUN"); |
217 | 23 | case (OSSL_TIME_SPEC_INT_MONTH_JUL): |
218 | 23 | return BIO_puts(out, "JUL"); |
219 | 10 | case (OSSL_TIME_SPEC_INT_MONTH_AUG): |
220 | 10 | return BIO_puts(out, "AUG"); |
221 | 49 | case (OSSL_TIME_SPEC_INT_MONTH_SEP): |
222 | 49 | return BIO_puts(out, "SEP"); |
223 | 18 | case (OSSL_TIME_SPEC_INT_MONTH_OCT): |
224 | 18 | return BIO_puts(out, "OCT"); |
225 | 14 | case (OSSL_TIME_SPEC_INT_MONTH_NOV): |
226 | 14 | return BIO_puts(out, "NOV"); |
227 | 35 | case (OSSL_TIME_SPEC_INT_MONTH_DEC): |
228 | 35 | return BIO_puts(out, "DEC"); |
229 | 744 | default: |
230 | 744 | return 0; |
231 | 7.08k | } |
232 | 0 | return 0; |
233 | 7.08k | } |
234 | | |
235 | | static int print_bit_month(BIO *out, ASN1_BIT_STRING *bs) |
236 | 1.87k | { |
237 | 1.87k | int i = OSSL_TIME_SPEC_BIT_MONTH_JAN; |
238 | 1.87k | int j = 0; |
239 | | |
240 | 24.3k | for (; i <= OSSL_TIME_SPEC_BIT_MONTH_DEC; i++) { |
241 | 22.5k | if (ASN1_BIT_STRING_get_bit(bs, i)) { |
242 | 7.67k | if (j > 0 && !BIO_puts(out, ", ")) |
243 | 0 | return 0; |
244 | 7.67k | j++; |
245 | 7.67k | if (!BIO_puts(out, MONTH_NAMES[i])) |
246 | 0 | return 0; |
247 | 7.67k | } |
248 | 22.5k | } |
249 | 1.87k | return 1; |
250 | 1.87k | } |
251 | | |
252 | | /* |
253 | | * It might seem like you could just print the bits of the string numerically, |
254 | | * but the fifth bit has the special meaning of "the final week" imputed to it |
255 | | * by the text of ITU-T Recommendation X.520. |
256 | | */ |
257 | | static int print_bit_week(BIO *out, ASN1_BIT_STRING *bs) |
258 | 548 | { |
259 | 548 | int i = OSSL_TIME_SPEC_BIT_WEEKS_1; |
260 | 548 | int j = 0; |
261 | | |
262 | 3.28k | for (; i <= OSSL_TIME_SPEC_BIT_WEEKS_5; i++) { |
263 | 2.74k | if (ASN1_BIT_STRING_get_bit(bs, i)) { |
264 | 1.81k | if (j > 0 && !BIO_puts(out, ", ")) |
265 | 0 | return 0; |
266 | 1.81k | j++; |
267 | 1.81k | if (!BIO_puts(out, WEEK_NAMES[i])) |
268 | 0 | return 0; |
269 | 1.81k | } |
270 | 2.74k | } |
271 | 548 | return 1; |
272 | 548 | } |
273 | | |
274 | | static int print_day_of_week(BIO *out, ASN1_BIT_STRING *bs) |
275 | 5.16k | { |
276 | 5.16k | int i = OSSL_TIME_SPEC_DAY_BIT_SUN; |
277 | 5.16k | int j = 0; |
278 | | |
279 | 41.3k | for (; i <= OSSL_TIME_SPEC_DAY_BIT_SAT; i++) { |
280 | 36.1k | if (ASN1_BIT_STRING_get_bit(bs, i)) { |
281 | 21.2k | if (j > 0 && !BIO_puts(out, ", ")) |
282 | 0 | return 0; |
283 | 21.2k | j++; |
284 | 21.2k | if (!BIO_puts(out, WEEKDAY_NAMES[i])) |
285 | 0 | return 0; |
286 | 21.2k | } |
287 | 36.1k | } |
288 | 5.16k | return 1; |
289 | 5.16k | } |
290 | | |
291 | | static int print_int_day_of_week(BIO *out, int64_t dow) |
292 | 1 | { |
293 | 1 | switch (dow) { |
294 | 0 | case (OSSL_TIME_SPEC_DAY_INT_SUN): |
295 | 0 | return BIO_puts(out, "SUN"); |
296 | 0 | case (OSSL_TIME_SPEC_DAY_INT_MON): |
297 | 0 | return BIO_puts(out, "MON"); |
298 | 0 | case (OSSL_TIME_SPEC_DAY_INT_TUE): |
299 | 0 | return BIO_puts(out, "TUE"); |
300 | 0 | case (OSSL_TIME_SPEC_DAY_INT_WED): |
301 | 0 | return BIO_puts(out, "WED"); |
302 | 0 | case (OSSL_TIME_SPEC_DAY_INT_THU): |
303 | 0 | return BIO_puts(out, "THU"); |
304 | 0 | case (OSSL_TIME_SPEC_DAY_INT_FRI): |
305 | 0 | return BIO_puts(out, "FRI"); |
306 | 0 | case (OSSL_TIME_SPEC_DAY_INT_SAT): |
307 | 0 | return BIO_puts(out, "SAT"); |
308 | 1 | default: |
309 | 1 | return 0; |
310 | 1 | } |
311 | 0 | return 0; |
312 | 1 | } |
313 | | |
314 | | static int print_int_named_day(BIO *out, int64_t nd) |
315 | 0 | { |
316 | 0 | switch (nd) { |
317 | 0 | case (OSSL_NAMED_DAY_INT_SUN): |
318 | 0 | return BIO_puts(out, "SUN"); |
319 | 0 | case (OSSL_NAMED_DAY_INT_MON): |
320 | 0 | return BIO_puts(out, "MON"); |
321 | 0 | case (OSSL_NAMED_DAY_INT_TUE): |
322 | 0 | return BIO_puts(out, "TUE"); |
323 | 0 | case (OSSL_NAMED_DAY_INT_WED): |
324 | 0 | return BIO_puts(out, "WED"); |
325 | 0 | case (OSSL_NAMED_DAY_INT_THU): |
326 | 0 | return BIO_puts(out, "THU"); |
327 | 0 | case (OSSL_NAMED_DAY_INT_FRI): |
328 | 0 | return BIO_puts(out, "FRI"); |
329 | 0 | case (OSSL_NAMED_DAY_INT_SAT): |
330 | 0 | return BIO_puts(out, "SAT"); |
331 | 0 | default: |
332 | 0 | return 0; |
333 | 0 | } |
334 | 0 | return 0; |
335 | 0 | } |
336 | | |
337 | | static int print_bit_named_day(BIO *out, ASN1_BIT_STRING *bs) |
338 | 3.78k | { |
339 | 3.78k | return print_day_of_week(out, bs); |
340 | 3.78k | } |
341 | | |
342 | | static int i2r_OSSL_PERIOD(X509V3_EXT_METHOD *method, |
343 | | OSSL_TIME_PERIOD *p, |
344 | | BIO *out, int indent) |
345 | 32.9k | { |
346 | 32.9k | int i; |
347 | 32.9k | OSSL_DAY_TIME_BAND *band; |
348 | 32.9k | ASN1_INTEGER *big_val; |
349 | 32.9k | int64_t small_val; |
350 | 32.9k | OSSL_NAMED_DAY *nd; |
351 | | |
352 | 32.9k | if (BIO_printf(out, "%*sPeriod:\n", indent, "") <= 0) |
353 | 0 | return 0; |
354 | 32.9k | if (p->timesOfDay) { |
355 | 403 | if (BIO_printf(out, "%*sDaytime bands:\n", indent + 4, "") <= 0) |
356 | 0 | return 0; |
357 | 1.40k | for (i = 0; i < sk_OSSL_DAY_TIME_BAND_num(p->timesOfDay); i++) { |
358 | 1.13k | band = sk_OSSL_DAY_TIME_BAND_value(p->timesOfDay, i); |
359 | 1.13k | if (BIO_printf(out, "%*s", indent + 8, "") <= 0) |
360 | 0 | return 0; |
361 | 1.13k | if (!i2r_OSSL_DAY_TIME_BAND(method, band, out, indent + 8)) |
362 | 128 | return 0; |
363 | 1.00k | if (!BIO_puts(out, "\n")) |
364 | 0 | return 0; |
365 | 1.00k | } |
366 | 403 | } |
367 | 32.8k | if (p->days) { |
368 | 6.37k | if (p->days->type == OSSL_TIME_SPEC_DAY_TYPE_INT) { |
369 | 971 | if (p->weeks != NULL) { |
370 | 62 | if (BIO_printf(out, "%*sDays of the week: ", indent + 4, "") <= 0) |
371 | 0 | return 0; |
372 | 909 | } else if (p->months != NULL) { |
373 | 150 | if (BIO_printf(out, "%*sDays of the month: ", indent + 4, "") <= 0) |
374 | 0 | return 0; |
375 | 759 | } else if (p->years != NULL) { |
376 | 219 | if (BIO_printf(out, "%*sDays of the year: ", indent + 4, "") <= 0) |
377 | 0 | return 0; |
378 | 219 | } |
379 | 5.40k | } else { |
380 | 5.40k | if (BIO_printf(out, "%*sDays: ", indent + 4, "") <= 0) |
381 | 0 | return 0; |
382 | 5.40k | } |
383 | | |
384 | 6.37k | switch (p->days->type) { |
385 | 971 | case (OSSL_TIME_SPEC_DAY_TYPE_INT): |
386 | 3.44k | for (i = 0; i < sk_ASN1_INTEGER_num(p->days->choice.intDay); i++) { |
387 | 2.61k | big_val = sk_ASN1_INTEGER_value(p->days->choice.intDay, i); |
388 | 2.61k | if (!ASN1_INTEGER_get_int64(&small_val, big_val)) |
389 | 147 | return 0; |
390 | 2.47k | if (i > 0 && !BIO_puts(out, ", ")) |
391 | 0 | return 0; |
392 | | /* If weeks is defined, then print day of week by name. */ |
393 | 2.47k | if (p->weeks != NULL) { |
394 | 1 | if (!print_int_day_of_week(out, small_val)) |
395 | 1 | return 0; |
396 | 2.47k | } else if (BIO_printf(out, "%lld", (long long int)small_val) <= 0) { |
397 | 0 | return 0; |
398 | 0 | } |
399 | 2.47k | } |
400 | 823 | break; |
401 | 1.37k | case (OSSL_TIME_SPEC_DAY_TYPE_BIT): |
402 | 1.37k | if (!print_day_of_week(out, p->days->choice.bitDay)) |
403 | 0 | return 0; |
404 | 1.37k | break; |
405 | 4.02k | case (OSSL_TIME_SPEC_DAY_TYPE_DAY_OF): |
406 | 4.02k | switch (p->days->choice.dayOf->type) { |
407 | 864 | case (OSSL_TIME_SPEC_X_DAY_OF_FIRST): |
408 | 864 | if (!BIO_puts(out, "FIRST ")) |
409 | 0 | return 0; |
410 | 864 | nd = p->days->choice.dayOf->choice.first; |
411 | 864 | break; |
412 | 521 | case (OSSL_TIME_SPEC_X_DAY_OF_SECOND): |
413 | 521 | if (!BIO_puts(out, "SECOND ")) |
414 | 0 | return 0; |
415 | 521 | nd = p->days->choice.dayOf->choice.second; |
416 | 521 | break; |
417 | 2.29k | case (OSSL_TIME_SPEC_X_DAY_OF_THIRD): |
418 | 2.29k | if (!BIO_puts(out, "THIRD ")) |
419 | 0 | return 0; |
420 | 2.29k | nd = p->days->choice.dayOf->choice.third; |
421 | 2.29k | break; |
422 | 192 | case (OSSL_TIME_SPEC_X_DAY_OF_FOURTH): |
423 | 192 | if (!BIO_puts(out, "FOURTH ")) |
424 | 0 | return 0; |
425 | 192 | nd = p->days->choice.dayOf->choice.fourth; |
426 | 192 | break; |
427 | 153 | case (OSSL_TIME_SPEC_X_DAY_OF_FIFTH): |
428 | 153 | if (!BIO_puts(out, "FIFTH ")) |
429 | 0 | return 0; |
430 | 153 | nd = p->days->choice.dayOf->choice.fifth; |
431 | 153 | break; |
432 | 0 | default: |
433 | 0 | return 0; |
434 | 4.02k | } |
435 | 4.02k | switch (nd->type) { |
436 | 237 | case (OSSL_NAMED_DAY_TYPE_INT): |
437 | 237 | if (!ASN1_INTEGER_get_int64(&small_val, nd->choice.intNamedDays)) |
438 | 237 | return 0; |
439 | 0 | if (!print_int_named_day(out, small_val)) |
440 | 0 | return 0; |
441 | 0 | break; |
442 | 3.78k | case (OSSL_NAMED_DAY_TYPE_BIT): |
443 | 3.78k | if (!print_bit_named_day(out, nd->choice.bitNamedDays)) |
444 | 0 | return 0; |
445 | 3.78k | break; |
446 | 3.78k | default: |
447 | 0 | return 0; |
448 | 4.02k | } |
449 | 3.78k | break; |
450 | 3.78k | default: |
451 | 0 | return 0; |
452 | 6.37k | } |
453 | 5.98k | if (!BIO_puts(out, "\n")) |
454 | 0 | return 0; |
455 | 5.98k | } |
456 | 32.4k | if (p->weeks) { |
457 | 2.34k | if (p->weeks->type == OSSL_TIME_SPEC_WEEKS_TYPE_INT) { |
458 | 1.69k | if (p->months != NULL) { |
459 | 34 | if (BIO_printf(out, "%*sWeeks of the month: ", indent + 4, "") <= 0) |
460 | 0 | return 0; |
461 | 1.65k | } else if (p->years != NULL) { |
462 | 980 | if (BIO_printf(out, "%*sWeeks of the year: ", indent + 4, "") <= 0) |
463 | 0 | return 0; |
464 | 980 | } |
465 | 1.69k | } else { |
466 | 655 | if (BIO_printf(out, "%*sWeeks: ", indent + 4, "") <= 0) |
467 | 0 | return 0; |
468 | 655 | } |
469 | | |
470 | 2.34k | switch (p->weeks->type) { |
471 | 107 | case (OSSL_TIME_SPEC_WEEKS_TYPE_ALL): |
472 | 107 | if (!BIO_puts(out, "ALL")) |
473 | 0 | return 0; |
474 | 107 | break; |
475 | 1.69k | case (OSSL_TIME_SPEC_WEEKS_TYPE_INT): |
476 | 3.34k | for (i = 0; i < sk_ASN1_INTEGER_num(p->weeks->choice.intWeek); i++) { |
477 | 1.73k | big_val = sk_ASN1_INTEGER_value(p->weeks->choice.intWeek, i); |
478 | 1.73k | if (!ASN1_INTEGER_get_int64(&small_val, big_val)) |
479 | 76 | return 0; |
480 | 1.65k | if (i > 0 && !BIO_puts(out, ", ")) |
481 | 0 | return 0; |
482 | 1.65k | if (!BIO_printf(out, "%lld", (long long int)small_val)) |
483 | 0 | return 0; |
484 | 1.65k | } |
485 | 1.61k | break; |
486 | 1.61k | case (OSSL_TIME_SPEC_WEEKS_TYPE_BIT): |
487 | 548 | if (!print_bit_week(out, p->weeks->choice.bitWeek)) |
488 | 0 | return 0; |
489 | 548 | break; |
490 | 548 | default: |
491 | 0 | return 0; |
492 | 2.34k | } |
493 | 2.27k | if (!BIO_puts(out, "\n")) |
494 | 0 | return 0; |
495 | 2.27k | } |
496 | 32.3k | if (p->months) { |
497 | 5.79k | if (BIO_printf(out, "%*sMonths: ", indent + 4, "") <= 0) |
498 | 0 | return 0; |
499 | 5.79k | switch (p->months->type) { |
500 | 1.46k | case (OSSL_TIME_SPEC_MONTH_TYPE_ALL): |
501 | 1.46k | if (!BIO_puts(out, "ALL")) |
502 | 0 | return 0; |
503 | 1.46k | break; |
504 | 2.44k | case (OSSL_TIME_SPEC_MONTH_TYPE_INT): |
505 | 8.78k | for (i = 0; i < sk_ASN1_INTEGER_num(p->months->choice.intMonth); i++) { |
506 | 7.21k | big_val = sk_ASN1_INTEGER_value(p->months->choice.intMonth, i); |
507 | 7.21k | if (!ASN1_INTEGER_get_int64(&small_val, big_val)) |
508 | 134 | return 0; |
509 | 7.08k | if (i > 0 && !BIO_puts(out, ", ")) |
510 | 0 | return 0; |
511 | 7.08k | if (!print_int_month(out, small_val)) |
512 | 744 | return 0; |
513 | 7.08k | } |
514 | 1.56k | break; |
515 | 1.87k | case (OSSL_TIME_SPEC_MONTH_TYPE_BIT): |
516 | 1.87k | if (!print_bit_month(out, p->months->choice.bitMonth)) |
517 | 0 | return 0; |
518 | 1.87k | break; |
519 | 1.87k | default: |
520 | 0 | return 0; |
521 | 5.79k | } |
522 | 4.91k | if (!BIO_puts(out, "\n")) |
523 | 0 | return 0; |
524 | 4.91k | } |
525 | 31.5k | if (p->years) { |
526 | 2.28k | if (BIO_printf(out, "%*sYears: ", indent + 4, "") <= 0) |
527 | 0 | return 0; |
528 | 4.30k | for (i = 0; i < sk_ASN1_INTEGER_num(p->years); i++) { |
529 | 2.18k | big_val = sk_ASN1_INTEGER_value(p->years, i); |
530 | 2.18k | if (!ASN1_INTEGER_get_int64(&small_val, big_val)) |
531 | 164 | return 0; |
532 | 2.02k | if (i > 0 && !BIO_puts(out, ", ")) |
533 | 0 | return 0; |
534 | 2.02k | if (BIO_printf(out, "%04lld", (long long int)small_val) <= 0) |
535 | 0 | return 0; |
536 | 2.02k | } |
537 | 2.28k | } |
538 | 31.3k | return 1; |
539 | 31.5k | } |
540 | | |
541 | | static int i2r_OSSL_TIME_SPEC_TIME(X509V3_EXT_METHOD *method, |
542 | | OSSL_TIME_SPEC_TIME *time, |
543 | | BIO *out, int indent) |
544 | 19.8k | { |
545 | 19.8k | OSSL_TIME_PERIOD *tp; |
546 | 19.8k | int i; |
547 | | |
548 | 19.8k | switch (time->type) { |
549 | 3.46k | case (OSSL_TIME_SPEC_TIME_TYPE_ABSOLUTE): |
550 | 3.46k | if (BIO_printf(out, "%*sAbsolute: ", indent, "") <= 0) |
551 | 0 | return 0; |
552 | 3.46k | if (i2r_OSSL_TIME_SPEC_ABSOLUTE(method, time->choice.absolute, out, indent + 4) <= 0) |
553 | 3 | return 0; |
554 | 3.46k | return BIO_puts(out, "\n"); |
555 | 16.3k | case (OSSL_TIME_SPEC_TIME_TYPE_PERIODIC): |
556 | 16.3k | if (BIO_printf(out, "%*sPeriodic:\n", indent, "") <= 0) |
557 | 0 | return 0; |
558 | 47.7k | for (i = 0; i < sk_OSSL_TIME_PERIOD_num(time->choice.periodic); i++) { |
559 | 32.9k | if (i > 0 && !BIO_puts(out, "\n")) |
560 | 0 | return 0; |
561 | 32.9k | tp = sk_OSSL_TIME_PERIOD_value(time->choice.periodic, i); |
562 | 32.9k | if (!i2r_OSSL_PERIOD(method, tp, out, indent + 4)) |
563 | 1.63k | return 0; |
564 | 32.9k | } |
565 | 14.7k | return BIO_puts(out, "\n"); |
566 | 0 | default: |
567 | 0 | return 0; |
568 | 19.8k | } |
569 | 0 | return 0; |
570 | 19.8k | } |
571 | | |
572 | | static int i2r_OSSL_TIME_SPEC(X509V3_EXT_METHOD *method, |
573 | | OSSL_TIME_SPEC *time, |
574 | | BIO *out, int indent) |
575 | 20.5k | { |
576 | 20.5k | int64_t tz; |
577 | | |
578 | 20.5k | if (time->timeZone) { |
579 | 3.29k | if (ASN1_INTEGER_get_int64(&tz, time->timeZone) != 1) |
580 | 701 | return 0; |
581 | 2.59k | if (BIO_printf(out, "%*sTimezone: UTC%+03lld:00\n", indent, "", (long long int)tz) <= 0) |
582 | 0 | return 0; |
583 | 2.59k | } |
584 | 19.8k | if (time->notThisTime > 0) { |
585 | 812 | if (BIO_printf(out, "%*sNOT this time:\n", indent, "") <= 0) |
586 | 0 | return 0; |
587 | 19.0k | } else if (BIO_printf(out, "%*sTime:\n", indent, "") <= 0) { |
588 | 0 | return 0; |
589 | 0 | } |
590 | 19.8k | return i2r_OSSL_TIME_SPEC_TIME(method, time->time, out, indent + 4); |
591 | 19.8k | } |
592 | | |
593 | | const X509V3_EXT_METHOD ossl_v3_time_specification = { |
594 | | NID_time_specification, X509V3_EXT_MULTILINE, |
595 | | ASN1_ITEM_ref(OSSL_TIME_SPEC), |
596 | | 0, 0, 0, 0, |
597 | | 0, 0, |
598 | | 0, |
599 | | 0, |
600 | | (X509V3_EXT_I2R)i2r_OSSL_TIME_SPEC, |
601 | | NULL, |
602 | | NULL |
603 | | }; |