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