/src/openssl36/crypto/x509/v3_timespec.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2024 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 | 36.9k | } ASN1_SEQUENCE_END(OSSL_TIME_SPEC_ABSOLUTE) |
53 | 36.9k | |
54 | 36.9k | ASN1_SEQUENCE(OSSL_DAY_TIME) = { |
55 | 36.9k | ASN1_EXP_OPT(OSSL_DAY_TIME, hour, ASN1_INTEGER, 0), |
56 | 36.9k | ASN1_EXP_OPT(OSSL_DAY_TIME, minute, ASN1_INTEGER, 1), |
57 | 36.9k | ASN1_EXP_OPT(OSSL_DAY_TIME, second, ASN1_INTEGER, 2), |
58 | 36.9k | } ASN1_SEQUENCE_END(OSSL_DAY_TIME) |
59 | 8.76k | |
60 | 8.76k | ASN1_SEQUENCE(OSSL_DAY_TIME_BAND) = { |
61 | 8.76k | ASN1_EXP_OPT(OSSL_DAY_TIME_BAND, startDayTime, OSSL_DAY_TIME, 0), |
62 | 8.76k | ASN1_EXP_OPT(OSSL_DAY_TIME_BAND, endDayTime, OSSL_DAY_TIME, 1), |
63 | 36.8k | } ASN1_SEQUENCE_END(OSSL_DAY_TIME_BAND) |
64 | 36.8k | |
65 | 36.8k | ASN1_CHOICE(OSSL_NAMED_DAY) = { |
66 | 36.8k | ASN1_SET_OF(OSSL_NAMED_DAY, choice.intNamedDays, ASN1_ENUMERATED), |
67 | 36.8k | ASN1_SIMPLE(OSSL_NAMED_DAY, choice.bitNamedDays, ASN1_BIT_STRING), |
68 | 36.8k | } ASN1_CHOICE_END(OSSL_NAMED_DAY) |
69 | 6.29k | |
70 | 6.29k | ASN1_CHOICE(OSSL_TIME_SPEC_X_DAY_OF) = { |
71 | 6.29k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.first, OSSL_NAMED_DAY, 1), |
72 | 6.29k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.second, OSSL_NAMED_DAY, 2), |
73 | 6.29k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.third, OSSL_NAMED_DAY, 3), |
74 | 6.29k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.fourth, OSSL_NAMED_DAY, 4), |
75 | 6.29k | ASN1_EXP(OSSL_TIME_SPEC_X_DAY_OF, choice.fifth, OSSL_NAMED_DAY, 5), |
76 | 7.85k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_X_DAY_OF) |
77 | 7.85k | |
78 | 7.85k | ASN1_CHOICE(OSSL_TIME_SPEC_DAY) = { |
79 | 7.85k | ASN1_SET_OF(OSSL_TIME_SPEC_DAY, choice.intDay, ASN1_INTEGER), |
80 | 7.85k | ASN1_SIMPLE(OSSL_TIME_SPEC_DAY, choice.bitDay, ASN1_BIT_STRING), |
81 | 7.85k | ASN1_SIMPLE(OSSL_TIME_SPEC_DAY, choice.dayOf, OSSL_TIME_SPEC_X_DAY_OF), |
82 | 272k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_DAY) |
83 | 272k | |
84 | 272k | ASN1_CHOICE(OSSL_TIME_SPEC_WEEKS) = { |
85 | 272k | ASN1_SIMPLE(OSSL_TIME_SPEC_WEEKS, choice.allWeeks, ASN1_NULL), |
86 | 272k | ASN1_SET_OF(OSSL_TIME_SPEC_WEEKS, choice.intWeek, ASN1_INTEGER), |
87 | 272k | ASN1_SIMPLE(OSSL_TIME_SPEC_WEEKS, choice.bitWeek, ASN1_BIT_STRING), |
88 | 272k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_WEEKS) |
89 | 269k | |
90 | 269k | ASN1_CHOICE(OSSL_TIME_SPEC_MONTH) = { |
91 | 269k | ASN1_SIMPLE(OSSL_TIME_SPEC_MONTH, choice.allMonths, ASN1_NULL), |
92 | 269k | ASN1_SET_OF(OSSL_TIME_SPEC_MONTH, choice.intMonth, ASN1_INTEGER), |
93 | 269k | ASN1_SIMPLE(OSSL_TIME_SPEC_MONTH, choice.bitMonth, ASN1_BIT_STRING), |
94 | 269k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_MONTH) |
95 | 269k | |
96 | 269k | ASN1_SEQUENCE(OSSL_TIME_PERIOD) = { |
97 | 269k | ASN1_EXP_SET_OF_OPT(OSSL_TIME_PERIOD, timesOfDay, OSSL_DAY_TIME_BAND, 0), |
98 | 269k | ASN1_EXP_OPT(OSSL_TIME_PERIOD, days, OSSL_TIME_SPEC_DAY, 1), |
99 | 269k | ASN1_EXP_OPT(OSSL_TIME_PERIOD, weeks, OSSL_TIME_SPEC_WEEKS, 2), |
100 | 269k | ASN1_EXP_OPT(OSSL_TIME_PERIOD, months, OSSL_TIME_SPEC_MONTH, 3), |
101 | 269k | ASN1_EXP_SET_OF_OPT(OSSL_TIME_PERIOD, years, ASN1_INTEGER, 4), |
102 | 269k | } ASN1_SEQUENCE_END(OSSL_TIME_PERIOD) |
103 | 76.5k | |
104 | 76.5k | ASN1_CHOICE(OSSL_TIME_SPEC_TIME) = { |
105 | 76.5k | ASN1_SIMPLE(OSSL_TIME_SPEC_TIME, choice.absolute, OSSL_TIME_SPEC_ABSOLUTE), |
106 | 76.5k | ASN1_SET_OF(OSSL_TIME_SPEC_TIME, choice.periodic, OSSL_TIME_PERIOD) |
107 | 217k | } ASN1_CHOICE_END(OSSL_TIME_SPEC_TIME) |
108 | 217k | |
109 | 217k | ASN1_SEQUENCE(OSSL_TIME_SPEC) = { |
110 | 217k | ASN1_SIMPLE(OSSL_TIME_SPEC, time, OSSL_TIME_SPEC_TIME), |
111 | 217k | ASN1_OPT(OSSL_TIME_SPEC, notThisTime, ASN1_FBOOLEAN), |
112 | 217k | ASN1_OPT(OSSL_TIME_SPEC, timeZone, ASN1_INTEGER), |
113 | 217k | } ASN1_SEQUENCE_END(OSSL_TIME_SPEC) |
114 | 61.1k | |
115 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_DAY_TIME) |
116 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_DAY_TIME_BAND) |
117 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_DAY) |
118 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_WEEKS) |
119 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_MONTH) |
120 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_NAMED_DAY) |
121 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_X_DAY_OF) |
122 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_ABSOLUTE) |
123 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC_TIME) |
124 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_SPEC) |
125 | 61.1k | IMPLEMENT_ASN1_FUNCTIONS(OSSL_TIME_PERIOD) |
126 | 61.1k | |
127 | 61.1k | static int i2r_OSSL_TIME_SPEC_ABSOLUTE(X509V3_EXT_METHOD *method, |
128 | 61.1k | OSSL_TIME_SPEC_ABSOLUTE *time, |
129 | 61.1k | BIO *out, int indent) |
130 | 61.1k | { |
131 | 3.25k | 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 | 3.25k | } else if (time->startTime != NULL) { |
141 | 9 | if (!BIO_puts(out, "Any time after ")) |
142 | 0 | return 0; |
143 | 9 | if (!ossl_asn1_time_print_ex(out, time->startTime, 0)) |
144 | 0 | return 0; |
145 | 9 | if (BIO_printf(out, "%.*s", time->startTime->length, time->startTime->data) <= 0) |
146 | 6 | return 0; |
147 | 3.24k | } 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 | 3.24k | } else { /* Invalid: there must be SOME time specified. */ |
153 | 3.24k | return BIO_puts(out, "INVALID (EMPTY)"); |
154 | 3.24k | } |
155 | 6 | return 1; |
156 | 3.25k | } |
157 | | |
158 | | static int i2r_OSSL_DAY_TIME(X509V3_EXT_METHOD *method, |
159 | | OSSL_DAY_TIME *dt, |
160 | | BIO *out, int indent) |
161 | 54 | { |
162 | 54 | int64_t h = 0; |
163 | 54 | int64_t m = 0; |
164 | 54 | int64_t s = 0; |
165 | | |
166 | 54 | if (!dt->hour || !ASN1_INTEGER_get_int64(&h, dt->hour)) |
167 | 54 | return 0; |
168 | 0 | if (dt->minute && !ASN1_INTEGER_get_int64(&m, dt->minute)) |
169 | 0 | return 0; |
170 | 0 | if (dt->minute && !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 | 995 | { |
181 | 995 | if (band->startDayTime) { |
182 | 35 | if (!i2r_OSSL_DAY_TIME(method, band->startDayTime, out, indent)) |
183 | 35 | return 0; |
184 | 960 | } else if (!BIO_puts(out, "00:00:00")) { |
185 | 0 | return 0; |
186 | 0 | } |
187 | 960 | if (!BIO_puts(out, " - ")) |
188 | 0 | return 0; |
189 | 960 | if (band->endDayTime) { |
190 | 19 | if (!i2r_OSSL_DAY_TIME(method, band->endDayTime, out, indent)) |
191 | 19 | return 0; |
192 | 941 | } else if (!BIO_puts(out, "23:59:59")) { |
193 | 0 | return 0; |
194 | 0 | } |
195 | 941 | return 1; |
196 | 960 | } |
197 | | |
198 | | static int print_int_month(BIO *out, int64_t month) |
199 | 1.75k | { |
200 | 1.75k | switch (month) { |
201 | 1.36k | case (OSSL_TIME_SPEC_INT_MONTH_JAN): |
202 | 1.36k | return BIO_puts(out, "JAN"); |
203 | 10 | case (OSSL_TIME_SPEC_INT_MONTH_FEB): |
204 | 10 | return BIO_puts(out, "FEB"); |
205 | 11 | case (OSSL_TIME_SPEC_INT_MONTH_MAR): |
206 | 11 | return BIO_puts(out, "MAR"); |
207 | 14 | case (OSSL_TIME_SPEC_INT_MONTH_APR): |
208 | 14 | return BIO_puts(out, "APR"); |
209 | 17 | case (OSSL_TIME_SPEC_INT_MONTH_MAY): |
210 | 17 | return BIO_puts(out, "MAY"); |
211 | 8 | case (OSSL_TIME_SPEC_INT_MONTH_JUN): |
212 | 8 | return BIO_puts(out, "JUN"); |
213 | 10 | case (OSSL_TIME_SPEC_INT_MONTH_JUL): |
214 | 10 | return BIO_puts(out, "JUL"); |
215 | 16 | case (OSSL_TIME_SPEC_INT_MONTH_AUG): |
216 | 16 | return BIO_puts(out, "AUG"); |
217 | 13 | case (OSSL_TIME_SPEC_INT_MONTH_SEP): |
218 | 13 | return BIO_puts(out, "SEP"); |
219 | 14 | case (OSSL_TIME_SPEC_INT_MONTH_OCT): |
220 | 14 | return BIO_puts(out, "OCT"); |
221 | 4 | case (OSSL_TIME_SPEC_INT_MONTH_NOV): |
222 | 4 | return BIO_puts(out, "NOV"); |
223 | 14 | case (OSSL_TIME_SPEC_INT_MONTH_DEC): |
224 | 14 | return BIO_puts(out, "DEC"); |
225 | 266 | default: |
226 | 266 | return 0; |
227 | 1.75k | } |
228 | 0 | return 0; |
229 | 1.75k | } |
230 | | |
231 | | static int print_bit_month(BIO *out, ASN1_BIT_STRING *bs) |
232 | 308 | { |
233 | 308 | int i = OSSL_TIME_SPEC_BIT_MONTH_JAN; |
234 | 308 | int j = 0; |
235 | | |
236 | 4.00k | for (; i <= OSSL_TIME_SPEC_BIT_MONTH_DEC; i++) { |
237 | 3.69k | if (ASN1_BIT_STRING_get_bit(bs, i)) { |
238 | 1.87k | if (j > 0 && !BIO_puts(out, ", ")) |
239 | 0 | return 0; |
240 | 1.87k | j++; |
241 | 1.87k | if (!BIO_puts(out, MONTH_NAMES[i])) |
242 | 0 | return 0; |
243 | 1.87k | } |
244 | 3.69k | } |
245 | 308 | return 1; |
246 | 308 | } |
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 | 212 | { |
255 | 212 | int i = OSSL_TIME_SPEC_BIT_WEEKS_1; |
256 | 212 | int j = 0; |
257 | | |
258 | 1.27k | for (; i <= OSSL_TIME_SPEC_BIT_WEEKS_5; i++) { |
259 | 1.06k | if (ASN1_BIT_STRING_get_bit(bs, i)) { |
260 | 771 | if (j > 0 && !BIO_puts(out, ", ")) |
261 | 0 | return 0; |
262 | 771 | j++; |
263 | 771 | if (!BIO_puts(out, WEEK_NAMES[i])) |
264 | 0 | return 0; |
265 | 771 | } |
266 | 1.06k | } |
267 | 212 | return 1; |
268 | 212 | } |
269 | | |
270 | | static int print_day_of_week(BIO *out, ASN1_BIT_STRING *bs) |
271 | 715 | { |
272 | 715 | int i = OSSL_TIME_SPEC_DAY_BIT_SUN; |
273 | 715 | int j = 0; |
274 | | |
275 | 5.72k | for (; i <= OSSL_TIME_SPEC_DAY_BIT_SAT; i++) { |
276 | 5.00k | if (ASN1_BIT_STRING_get_bit(bs, i)) { |
277 | 3.29k | if (j > 0 && !BIO_puts(out, ", ")) |
278 | 0 | return 0; |
279 | 3.29k | j++; |
280 | 3.29k | if (!BIO_puts(out, WEEKDAY_NAMES[i])) |
281 | 0 | return 0; |
282 | 3.29k | } |
283 | 5.00k | } |
284 | 715 | return 1; |
285 | 715 | } |
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 | 613 | { |
335 | 613 | return print_day_of_week(out, bs); |
336 | 613 | } |
337 | | |
338 | | static int i2r_OSSL_PERIOD(X509V3_EXT_METHOD *method, |
339 | | OSSL_TIME_PERIOD *p, |
340 | | BIO *out, int indent) |
341 | 18.0k | { |
342 | 18.0k | int i; |
343 | 18.0k | OSSL_DAY_TIME_BAND *band; |
344 | 18.0k | ASN1_INTEGER *big_val; |
345 | 18.0k | int64_t small_val; |
346 | 18.0k | OSSL_NAMED_DAY *nd; |
347 | | |
348 | 18.0k | if (BIO_printf(out, "%*sPeriod:\n", indent, "") <= 0) |
349 | 0 | return 0; |
350 | 18.0k | if (p->timesOfDay) { |
351 | 210 | if (BIO_printf(out, "%*sDaytime bands:\n", indent + 4, "") <= 0) |
352 | 0 | return 0; |
353 | 1.15k | for (i = 0; i < sk_OSSL_DAY_TIME_BAND_num(p->timesOfDay); i++) { |
354 | 995 | band = sk_OSSL_DAY_TIME_BAND_value(p->timesOfDay, i); |
355 | 995 | if (BIO_printf(out, "%*s", indent + 8, "") <= 0) |
356 | 0 | return 0; |
357 | 995 | if (!i2r_OSSL_DAY_TIME_BAND(method, band, out, indent + 8)) |
358 | 54 | return 0; |
359 | 941 | if (!BIO_puts(out, "\n")) |
360 | 0 | return 0; |
361 | 941 | } |
362 | 210 | } |
363 | 17.9k | if (p->days) { |
364 | 955 | if (p->days->type == OSSL_TIME_SPEC_DAY_TYPE_INT) { |
365 | 222 | if (p->weeks != NULL) { |
366 | 35 | if (BIO_printf(out, "%*sDays of the week: ", indent + 4, "") <= 0) |
367 | 0 | return 0; |
368 | 187 | } else if (p->months != NULL) { |
369 | 11 | if (BIO_printf(out, "%*sDays of the month: ", indent + 4, "") <= 0) |
370 | 0 | return 0; |
371 | 176 | } else if (p->years != NULL) { |
372 | 1 | if (BIO_printf(out, "%*sDays of the year: ", indent + 4, "") <= 0) |
373 | 0 | return 0; |
374 | 1 | } |
375 | 733 | } else { |
376 | 733 | if (BIO_printf(out, "%*sDays: ", indent + 4, "") <= 0) |
377 | 0 | return 0; |
378 | 733 | } |
379 | | |
380 | 955 | switch (p->days->type) { |
381 | 222 | case (OSSL_TIME_SPEC_DAY_TYPE_INT): |
382 | 681 | for (i = 0; i < sk_ASN1_INTEGER_num(p->days->choice.intDay); i++) { |
383 | 537 | big_val = sk_ASN1_INTEGER_value(p->days->choice.intDay, i); |
384 | 537 | if (!ASN1_INTEGER_get_int64(&small_val, big_val)) |
385 | 77 | return 0; |
386 | 460 | if (i > 0 && !BIO_puts(out, ", ")) |
387 | 0 | return 0; |
388 | | /* If weeks is defined, then print day of week by name. */ |
389 | 460 | if (p->weeks != NULL) { |
390 | 1 | if (!print_int_day_of_week(out, small_val)) |
391 | 1 | return 0; |
392 | 459 | } else if (BIO_printf(out, "%lld", (long long int)small_val) <= 0) { |
393 | 0 | return 0; |
394 | 0 | } |
395 | 460 | } |
396 | 144 | break; |
397 | 144 | case (OSSL_TIME_SPEC_DAY_TYPE_BIT): |
398 | 102 | if (!print_day_of_week(out, p->days->choice.bitDay)) |
399 | 0 | return 0; |
400 | 102 | break; |
401 | 631 | case (OSSL_TIME_SPEC_DAY_TYPE_DAY_OF): |
402 | 631 | switch (p->days->choice.dayOf->type) { |
403 | 23 | case (OSSL_TIME_SPEC_X_DAY_OF_FIRST): |
404 | 23 | if (!BIO_puts(out, "FIRST ")) |
405 | 0 | return 0; |
406 | 23 | nd = p->days->choice.dayOf->choice.first; |
407 | 23 | break; |
408 | 29 | case (OSSL_TIME_SPEC_X_DAY_OF_SECOND): |
409 | 29 | if (!BIO_puts(out, "SECOND ")) |
410 | 0 | return 0; |
411 | 29 | nd = p->days->choice.dayOf->choice.second; |
412 | 29 | break; |
413 | 506 | case (OSSL_TIME_SPEC_X_DAY_OF_THIRD): |
414 | 506 | if (!BIO_puts(out, "THIRD ")) |
415 | 0 | return 0; |
416 | 506 | nd = p->days->choice.dayOf->choice.third; |
417 | 506 | break; |
418 | 32 | case (OSSL_TIME_SPEC_X_DAY_OF_FOURTH): |
419 | 32 | if (!BIO_puts(out, "FOURTH ")) |
420 | 0 | return 0; |
421 | 32 | nd = p->days->choice.dayOf->choice.fourth; |
422 | 32 | break; |
423 | 41 | case (OSSL_TIME_SPEC_X_DAY_OF_FIFTH): |
424 | 41 | if (!BIO_puts(out, "FIFTH ")) |
425 | 0 | return 0; |
426 | 41 | nd = p->days->choice.dayOf->choice.fifth; |
427 | 41 | break; |
428 | 0 | default: |
429 | 0 | return 0; |
430 | 631 | } |
431 | 631 | switch (nd->type) { |
432 | 18 | case (OSSL_NAMED_DAY_TYPE_INT): |
433 | 18 | if (!ASN1_INTEGER_get_int64(&small_val, nd->choice.intNamedDays)) |
434 | 18 | return 0; |
435 | 0 | if (!print_int_named_day(out, small_val)) |
436 | 0 | return 0; |
437 | 0 | break; |
438 | 613 | case (OSSL_NAMED_DAY_TYPE_BIT): |
439 | 613 | if (!print_bit_named_day(out, nd->choice.bitNamedDays)) |
440 | 0 | return 0; |
441 | 613 | break; |
442 | 613 | default: |
443 | 0 | return 0; |
444 | 631 | } |
445 | 613 | break; |
446 | 613 | default: |
447 | 0 | return 0; |
448 | 955 | } |
449 | 859 | if (!BIO_puts(out, "\n")) |
450 | 0 | return 0; |
451 | 859 | } |
452 | 17.8k | if (p->weeks) { |
453 | 394 | if (p->weeks->type == OSSL_TIME_SPEC_WEEKS_TYPE_INT) { |
454 | 88 | if (p->months != NULL) { |
455 | 7 | if (BIO_printf(out, "%*sWeeks of the month: ", indent + 4, "") <= 0) |
456 | 0 | return 0; |
457 | 81 | } else if (p->years != NULL) { |
458 | 1 | if (BIO_printf(out, "%*sWeeks of the year: ", indent + 4, "") <= 0) |
459 | 0 | return 0; |
460 | 1 | } |
461 | 306 | } else { |
462 | 306 | if (BIO_printf(out, "%*sWeeks: ", indent + 4, "") <= 0) |
463 | 0 | return 0; |
464 | 306 | } |
465 | | |
466 | 394 | switch (p->weeks->type) { |
467 | 94 | case (OSSL_TIME_SPEC_WEEKS_TYPE_ALL): |
468 | 94 | if (!BIO_puts(out, "ALL")) |
469 | 0 | return 0; |
470 | 94 | break; |
471 | 94 | case (OSSL_TIME_SPEC_WEEKS_TYPE_INT): |
472 | 186 | for (i = 0; i < sk_ASN1_INTEGER_num(p->weeks->choice.intWeek); i++) { |
473 | 114 | big_val = sk_ASN1_INTEGER_value(p->weeks->choice.intWeek, i); |
474 | 114 | if (!ASN1_INTEGER_get_int64(&small_val, big_val)) |
475 | 16 | return 0; |
476 | 98 | if (i > 0 && !BIO_puts(out, ", ")) |
477 | 0 | return 0; |
478 | 98 | if (!BIO_printf(out, "%lld", (long long int)small_val)) |
479 | 0 | return 0; |
480 | 98 | } |
481 | 72 | break; |
482 | 212 | case (OSSL_TIME_SPEC_WEEKS_TYPE_BIT): |
483 | 212 | if (!print_bit_week(out, p->weeks->choice.bitWeek)) |
484 | 0 | return 0; |
485 | 212 | break; |
486 | 212 | default: |
487 | 0 | return 0; |
488 | 394 | } |
489 | 378 | if (!BIO_puts(out, "\n")) |
490 | 0 | return 0; |
491 | 378 | } |
492 | 17.8k | if (p->months) { |
493 | 1.15k | if (BIO_printf(out, "%*sMonths: ", indent + 4, "") <= 0) |
494 | 0 | return 0; |
495 | 1.15k | switch (p->months->type) { |
496 | 123 | case (OSSL_TIME_SPEC_MONTH_TYPE_ALL): |
497 | 123 | if (!BIO_puts(out, "ALL")) |
498 | 0 | return 0; |
499 | 123 | break; |
500 | 723 | case (OSSL_TIME_SPEC_MONTH_TYPE_INT): |
501 | 2.21k | for (i = 0; i < sk_ASN1_INTEGER_num(p->months->choice.intMonth); i++) { |
502 | 1.77k | big_val = sk_ASN1_INTEGER_value(p->months->choice.intMonth, i); |
503 | 1.77k | if (!ASN1_INTEGER_get_int64(&small_val, big_val)) |
504 | 12 | return 0; |
505 | 1.75k | if (i > 0 && !BIO_puts(out, ", ")) |
506 | 0 | return 0; |
507 | 1.75k | if (!print_int_month(out, small_val)) |
508 | 266 | return 0; |
509 | 1.75k | } |
510 | 445 | break; |
511 | 445 | case (OSSL_TIME_SPEC_MONTH_TYPE_BIT): |
512 | 308 | if (!print_bit_month(out, p->months->choice.bitMonth)) |
513 | 0 | return 0; |
514 | 308 | break; |
515 | 308 | default: |
516 | 0 | return 0; |
517 | 1.15k | } |
518 | 876 | if (!BIO_puts(out, "\n")) |
519 | 0 | return 0; |
520 | 876 | } |
521 | 17.5k | if (p->years) { |
522 | 350 | if (BIO_printf(out, "%*sYears: ", indent + 4, "") <= 0) |
523 | 0 | return 0; |
524 | 805 | for (i = 0; i < sk_ASN1_INTEGER_num(p->years); i++) { |
525 | 486 | big_val = sk_ASN1_INTEGER_value(p->years, i); |
526 | 486 | if (!ASN1_INTEGER_get_int64(&small_val, big_val)) |
527 | 31 | return 0; |
528 | 455 | if (i > 0 && !BIO_puts(out, ", ")) |
529 | 0 | return 0; |
530 | 455 | if (BIO_printf(out, "%04lld", (long long int)small_val) <= 0) |
531 | 0 | return 0; |
532 | 455 | } |
533 | 350 | } |
534 | 17.5k | return 1; |
535 | 17.5k | } |
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 | 14.9k | { |
541 | 14.9k | OSSL_TIME_PERIOD *tp; |
542 | 14.9k | int i; |
543 | | |
544 | 14.9k | switch (time->type) { |
545 | 3.25k | case (OSSL_TIME_SPEC_TIME_TYPE_ABSOLUTE): |
546 | 3.25k | if (BIO_printf(out, "%*sAbsolute: ", indent, "") <= 0) |
547 | 0 | return 0; |
548 | 3.25k | if (i2r_OSSL_TIME_SPEC_ABSOLUTE(method, time->choice.absolute, out, indent + 4) <= 0) |
549 | 6 | return 0; |
550 | 3.24k | return BIO_puts(out, "\n"); |
551 | 11.6k | case (OSSL_TIME_SPEC_TIME_TYPE_PERIODIC): |
552 | 11.6k | if (BIO_printf(out, "%*sPeriodic:\n", indent, "") <= 0) |
553 | 0 | return 0; |
554 | 29.2k | for (i = 0; i < sk_OSSL_TIME_PERIOD_num(time->choice.periodic); i++) { |
555 | 18.0k | if (i > 0 && !BIO_puts(out, "\n")) |
556 | 0 | return 0; |
557 | 18.0k | tp = sk_OSSL_TIME_PERIOD_value(time->choice.periodic, i); |
558 | 18.0k | if (!i2r_OSSL_PERIOD(method, tp, out, indent + 4)) |
559 | 475 | return 0; |
560 | 18.0k | } |
561 | 11.1k | return BIO_puts(out, "\n"); |
562 | 0 | default: |
563 | 0 | return 0; |
564 | 14.9k | } |
565 | 0 | return 0; |
566 | 14.9k | } |
567 | | |
568 | | static int i2r_OSSL_TIME_SPEC(X509V3_EXT_METHOD *method, |
569 | | OSSL_TIME_SPEC *time, |
570 | | BIO *out, int indent) |
571 | 14.9k | { |
572 | 14.9k | int64_t tz; |
573 | | |
574 | 14.9k | if (time->timeZone) { |
575 | 1.82k | if (ASN1_INTEGER_get_int64(&tz, time->timeZone) != 1) |
576 | 51 | return 0; |
577 | 1.77k | if (BIO_printf(out, "%*sTimezone: UTC%+03lld:00\n", indent, "", (long long int)tz) <= 0) |
578 | 0 | return 0; |
579 | 1.77k | } |
580 | 14.9k | if (time->notThisTime > 0) { |
581 | 406 | if (BIO_printf(out, "%*sNOT this time:\n", indent, "") <= 0) |
582 | 0 | return 0; |
583 | 14.5k | } else if (BIO_printf(out, "%*sTime:\n", indent, "") <= 0) { |
584 | 0 | return 0; |
585 | 0 | } |
586 | 14.9k | return i2r_OSSL_TIME_SPEC_TIME(method, time->time, out, indent + 4); |
587 | 14.9k | } |
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 | | }; |