summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/asn1/a_time_tm.c166
1 files changed, 82 insertions, 84 deletions
diff --git a/src/lib/libcrypto/asn1/a_time_tm.c b/src/lib/libcrypto/asn1/a_time_tm.c
index 5be2ff0af2..0e040ae579 100644
--- a/src/lib/libcrypto/asn1/a_time_tm.c
+++ b/src/lib/libcrypto/asn1/a_time_tm.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: a_time_tm.c,v 1.19 2022/03/31 13:04:47 tb Exp $ */ 1/* $OpenBSD: a_time_tm.c,v 1.20 2022/04/28 17:31:29 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2015 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -14,6 +14,7 @@
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17
17#include <ctype.h> 18#include <ctype.h>
18#include <limits.h> 19#include <limits.h>
19#include <stdio.h> 20#include <stdio.h>
@@ -75,59 +76,101 @@ ASN1_time_tm_clamp_notafter(struct tm *tm)
75 return 1; 76 return 1;
76} 77}
77 78
78/* Format a time as an RFC 5280 format Generalized time */ 79/* Convert time to GeneralizedTime, X.690, 11.7. */
79char * 80ASN1_TIME *
80gentime_string_from_tm(struct tm *tm) 81tm_to_gentime(struct tm *tm, ASN1_TIME *atime)
81{ 82{
82 char *ret = NULL; 83 char *time_str = NULL;
83 int year; 84 int year;
84 85
85 year = tm->tm_year + 1900; 86 year = tm->tm_year + 1900;
86 if (year < 0 || year > 9999) 87 if (year < 0 || year > 9999) {
87 return (NULL); 88 ASN1error(ASN1_R_ILLEGAL_TIME_VALUE);
89 goto err;
90 }
88 91
89 if (asprintf(&ret, "%04u%02u%02u%02u%02u%02uZ", year, 92 if (asprintf(&time_str, "%04u%02u%02u%02u%02u%02uZ", year,
90 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, 93 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
91 tm->tm_sec) == -1) 94 tm->tm_sec) == -1) {
92 ret = NULL; 95 time_str = NULL;
96 ASN1error(ERR_R_MALLOC_FAILURE);
97 goto err;
98 }
93 99
94 return (ret); 100 if (atime == NULL)
101 atime = ASN1_TIME_new();
102 if (atime == NULL) {
103 ASN1error(ERR_R_MALLOC_FAILURE);
104 goto err;
105 }
106
107 free(atime->data);
108 atime->data = time_str;
109 atime->length = GENTIME_LENGTH;
110 atime->type = V_ASN1_GENERALIZEDTIME;
111
112 return (atime);
113
114 err:
115 free(time_str);
116
117 return (NULL);
95} 118}
96 119
97/* Format a time as an RFC 5280 format UTC time */ 120/* Convert time to UTCTime, X.690, 11.8. */
98char * 121ASN1_TIME *
99utctime_string_from_tm(struct tm *tm) 122tm_to_utctime(struct tm *tm, ASN1_TIME *atime)
100{ 123{
101 char *ret = NULL; 124 char *time_str = NULL;
102 125
103 if (tm->tm_year >= 150 || tm->tm_year < 50) 126 if (tm->tm_year >= 150 || tm->tm_year < 50) {
104 return (NULL); 127 ASN1error(ASN1_R_ILLEGAL_TIME_VALUE);
128 goto err;
129 }
105 130
106 if (asprintf(&ret, "%02u%02u%02u%02u%02u%02uZ", 131 if (asprintf(&time_str, "%02u%02u%02u%02u%02u%02uZ",
107 tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, 132 tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
108 tm->tm_hour, tm->tm_min, tm->tm_sec) == -1) 133 tm->tm_hour, tm->tm_min, tm->tm_sec) == -1) {
109 ret = NULL; 134 time_str = NULL;
135 ASN1error(ERR_R_MALLOC_FAILURE);
136 goto err;
137 }
138
139 if (atime == NULL)
140 atime = ASN1_TIME_new();
141 if (atime == NULL) {
142 ASN1error(ERR_R_MALLOC_FAILURE);
143 goto err;
144 }
110 145
111 return (ret); 146 free(atime->data);
147 atime->data = time_str;
148 atime->length = UTCTIME_LENGTH;
149 atime->type = V_ASN1_UTCTIME;
150
151 return (atime);
152
153 err:
154 free(time_str);
155
156 return (NULL);
112} 157}
113 158
114/* Format a time correctly for an X509 object as per RFC 5280 */ 159ASN1_TIME *
115char * 160tm_to_rfc5280_time(struct tm *tm, ASN1_TIME *atime)
116rfc5280_string_from_tm(struct tm *tm)
117{ 161{
118 char *ret = NULL;
119 int year; 162 int year;
120 163
121 year = tm->tm_year + 1900; 164 year = tm->tm_year + 1900;
122 if (year < 1950 || year > 9999) 165 if (year < 1950 || year > 9999) {
166 ASN1error(ASN1_R_ILLEGAL_TIME_VALUE);
123 return (NULL); 167 return (NULL);
168 }
124 169
125 if (year < 2050) 170 if (year < 2050)
126 ret = utctime_string_from_tm(tm); 171 return (tm_to_utctime(tm, atime));
127 else
128 ret = gentime_string_from_tm(tm);
129 172
130 return (ret); 173 return (tm_to_gentime(tm, atime));
131} 174}
132 175
133/* 176/*
@@ -256,63 +299,26 @@ static ASN1_TIME *
256ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec, 299ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
257 int mode) 300 int mode)
258{ 301{
259 int allocated = 0;
260 struct tm tm; 302 struct tm tm;
261 size_t len;
262 char *p;
263 303
264 if (gmtime_r(&t, &tm) == NULL) 304 if (gmtime_r(&t, &tm) == NULL)
265 return (NULL); 305 return (NULL);
266 306
267 if (offset_day || offset_sec) { 307 if (offset_day != 0 || offset_sec != 0) {
268 if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec)) 308 if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec))
269 return (NULL); 309 return (NULL);
270 } 310 }
271 311
272 switch (mode) { 312 switch (mode) {
273 case V_ASN1_UTCTIME: 313 case V_ASN1_UTCTIME:
274 p = utctime_string_from_tm(&tm); 314 return (tm_to_utctime(&tm, s));
275 break;
276 case V_ASN1_GENERALIZEDTIME: 315 case V_ASN1_GENERALIZEDTIME:
277 p = gentime_string_from_tm(&tm); 316 return (tm_to_gentime(&tm, s));
278 break;
279 case RFC5280: 317 case RFC5280:
280 p = rfc5280_string_from_tm(&tm); 318 return (tm_to_rfc5280_time(&tm, s));
281 break;
282 default: 319 default:
283 return (NULL); 320 return (NULL);
284 } 321 }
285 if (p == NULL) {
286 ASN1error(ASN1_R_ILLEGAL_TIME_VALUE);
287 return (NULL);
288 }
289
290 if (s == NULL) {
291 if ((s = ASN1_TIME_new()) == NULL) {
292 free(p);
293 return (NULL);
294 }
295 allocated = 1;
296 }
297
298 len = strlen(p);
299 switch (len) {
300 case GENTIME_LENGTH:
301 s->type = V_ASN1_GENERALIZEDTIME;
302 break;
303 case UTCTIME_LENGTH:
304 s->type = V_ASN1_UTCTIME;
305 break;
306 default:
307 if (allocated)
308 ASN1_TIME_free(s);
309 free(p);
310 return (NULL);
311 }
312 free(s->data);
313 s->data = p;
314 s->length = len;
315 return (s);
316} 322}
317 323
318ASN1_TIME * 324ASN1_TIME *
@@ -348,31 +354,23 @@ ASN1_TIME_check(const ASN1_TIME *t)
348ASN1_GENERALIZEDTIME * 354ASN1_GENERALIZEDTIME *
349ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, ASN1_GENERALIZEDTIME **out) 355ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
350{ 356{
351 ASN1_GENERALIZEDTIME *tmp = NULL; 357 ASN1_GENERALIZEDTIME *agt = NULL;
352 struct tm tm; 358 struct tm tm;
353 char *str;
354 359
355 if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME) 360 if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME)
356 return (NULL); 361 return (NULL);
357 362
358 if (t->type != ASN1_time_parse(t->data, t->length, &tm, t->type)) 363 if (t->type != ASN1_time_parse(t->data, t->length, &tm, t->type))
359 return (NULL); 364 return (NULL);
360 if ((str = gentime_string_from_tm(&tm)) == NULL)
361 return (NULL);
362 365
363 if (out != NULL) 366 if (out != NULL)
364 tmp = *out; 367 agt = *out;
365 if (tmp == NULL && (tmp = ASN1_GENERALIZEDTIME_new()) == NULL) { 368 if ((agt = tm_to_gentime(&tm, agt)) == NULL)
366 free(str);
367 return (NULL); 369 return (NULL);
368 }
369 if (out != NULL) 370 if (out != NULL)
370 *out = tmp; 371 *out = agt;
371 372
372 free(tmp->data); 373 return (agt);
373 tmp->data = str;
374 tmp->length = strlen(str);
375 return (tmp);
376} 374}
377 375
378int 376int