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