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