summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2024-04-11 06:42:09 +0000
committertb <>2024-04-11 06:42:09 +0000
commitc7dbc1d09fc1acd9ea6960a0e507b18e921248be (patch)
treeb5641598728f2610405c41856804fb1d3302998b /src
parent30137553e5880795d09be4a50f12f0c075287faf (diff)
downloadopenbsd-c7dbc1d09fc1acd9ea6960a0e507b18e921248be.tar.gz
openbsd-c7dbc1d09fc1acd9ea6960a0e507b18e921248be.tar.bz2
openbsd-c7dbc1d09fc1acd9ea6960a0e507b18e921248be.zip
Rework internal tm_to_*() converters
Make them static. Don't make them allocate if passed a NULL ASN1_TIME to avoid leaks. This currently means that we accept a NULL and succeed. That's very ugly but better than what we have now. Simplify ASN1_TIME_set_string_internal() accordingly and allocate an ASN1_TIME at the API boundary of ASN1_TIME_adj_internal() and of ASN1_TIME_to_generalized_time(). ok beck (after a lot of squealing and distress)
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/asn1/a_time_tm.c135
1 files changed, 66 insertions, 69 deletions
diff --git a/src/lib/libcrypto/asn1/a_time_tm.c b/src/lib/libcrypto/asn1/a_time_tm.c
index 49d6ea2097..59fd32e9ca 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.36 2024/04/10 14:55:12 beck Exp $ */ 1/* $OpenBSD: a_time_tm.c,v 1.37 2024/04/11 06:42:09 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2015 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -78,31 +78,24 @@ ASN1_time_tm_clamp_notafter(struct tm *tm)
78} 78}
79 79
80/* Convert time to GeneralizedTime, X.690, 11.7. */ 80/* Convert time to GeneralizedTime, X.690, 11.7. */
81ASN1_TIME * 81static int
82tm_to_gentime(struct tm *tm, ASN1_TIME *atime) 82tm_to_gentime(struct tm *tm, ASN1_TIME *atime)
83{ 83{
84 char *time_str = NULL; 84 char *time_str = NULL;
85 int year;
86 85
87 year = tm->tm_year + 1900; 86 if (tm->tm_year < -1900 || tm->tm_year > 9999 - 1900) {
88 if (year < 0 || year > 9999) {
89 ASN1error(ASN1_R_ILLEGAL_TIME_VALUE); 87 ASN1error(ASN1_R_ILLEGAL_TIME_VALUE);
90 goto err; 88 return 0;
91 } 89 }
92 90
93 if (asprintf(&time_str, "%04u%02u%02u%02u%02u%02uZ", year, 91 if (atime == NULL)
92 return 1;
93
94 if (asprintf(&time_str, "%04u%02u%02u%02u%02u%02uZ", tm->tm_year + 1900,
94 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, 95 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
95 tm->tm_sec) == -1) { 96 tm->tm_sec) == -1) {
96 time_str = NULL;
97 ASN1error(ERR_R_MALLOC_FAILURE);
98 goto err;
99 }
100
101 if (atime == NULL)
102 atime = ASN1_TIME_new();
103 if (atime == NULL) {
104 ASN1error(ERR_R_MALLOC_FAILURE); 97 ASN1error(ERR_R_MALLOC_FAILURE);
105 goto err; 98 return 0;
106 } 99 }
107 100
108 free(atime->data); 101 free(atime->data);
@@ -110,38 +103,28 @@ tm_to_gentime(struct tm *tm, ASN1_TIME *atime)
110 atime->length = GENTIME_LENGTH; 103 atime->length = GENTIME_LENGTH;
111 atime->type = V_ASN1_GENERALIZEDTIME; 104 atime->type = V_ASN1_GENERALIZEDTIME;
112 105
113 return (atime); 106 return 1;
114
115 err:
116 free(time_str);
117
118 return (NULL);
119} 107}
120 108
121/* Convert time to UTCTime, X.690, 11.8. */ 109/* Convert time to UTCTime, X.690, 11.8. */
122ASN1_TIME * 110static int
123tm_to_utctime(struct tm *tm, ASN1_TIME *atime) 111tm_to_utctime(struct tm *tm, ASN1_TIME *atime)
124{ 112{
125 char *time_str = NULL; 113 char *time_str = NULL;
126 114
127 if (tm->tm_year >= 150 || tm->tm_year < 50) { 115 if (tm->tm_year >= 150 || tm->tm_year < 50) {
128 ASN1error(ASN1_R_ILLEGAL_TIME_VALUE); 116 ASN1error(ASN1_R_ILLEGAL_TIME_VALUE);
129 goto err; 117 return 0;
130 } 118 }
131 119
120 if (atime == NULL)
121 return 1;
122
132 if (asprintf(&time_str, "%02u%02u%02u%02u%02u%02uZ", 123 if (asprintf(&time_str, "%02u%02u%02u%02u%02u%02uZ",
133 tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, 124 tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
134 tm->tm_hour, tm->tm_min, tm->tm_sec) == -1) { 125 tm->tm_hour, tm->tm_min, tm->tm_sec) == -1) {
135 time_str = NULL;
136 ASN1error(ERR_R_MALLOC_FAILURE);
137 goto err;
138 }
139
140 if (atime == NULL)
141 atime = ASN1_TIME_new();
142 if (atime == NULL) {
143 ASN1error(ERR_R_MALLOC_FAILURE); 126 ASN1error(ERR_R_MALLOC_FAILURE);
144 goto err; 127 return 0;
145 } 128 }
146 129
147 free(atime->data); 130 free(atime->data);
@@ -149,15 +132,10 @@ tm_to_utctime(struct tm *tm, ASN1_TIME *atime)
149 atime->length = UTCTIME_LENGTH; 132 atime->length = UTCTIME_LENGTH;
150 atime->type = V_ASN1_UTCTIME; 133 atime->type = V_ASN1_UTCTIME;
151 134
152 return (atime); 135 return 1;
153
154 err:
155 free(time_str);
156
157 return (NULL);
158} 136}
159 137
160ASN1_TIME * 138static int
161tm_to_rfc5280_time(struct tm *tm, ASN1_TIME *atime) 139tm_to_rfc5280_time(struct tm *tm, ASN1_TIME *atime)
162{ 140{
163 if (tm->tm_year >= 50 && tm->tm_year < 150) 141 if (tm->tm_year >= 50 && tm->tm_year < 150)
@@ -344,58 +322,67 @@ ASN1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode)
344static int 322static int
345ASN1_TIME_set_string_internal(ASN1_TIME *s, const char *str, int mode) 323ASN1_TIME_set_string_internal(ASN1_TIME *s, const char *str, int mode)
346{ 324{
347 ASN1_TIME *atime = s;
348 struct tm tm; 325 struct tm tm;
349 int type; 326 int type;
350 int ret = 0;
351 327
352 if ((type = ASN1_time_parse(str, strlen(str), &tm, mode)) == -1) 328 if ((type = ASN1_time_parse(str, strlen(str), &tm, mode)) == -1)
353 return (0); 329 return (0);
354 switch (mode) { 330 switch (mode) {
355 case V_ASN1_UTCTIME: 331 case V_ASN1_UTCTIME:
356 ret = (type == mode && (atime = tm_to_utctime(&tm, s)) != NULL); 332 return (type == mode && tm_to_utctime(&tm, s));
357 break;
358 case V_ASN1_GENERALIZEDTIME: 333 case V_ASN1_GENERALIZEDTIME:
359 ret = (type == mode && (atime = tm_to_gentime(&tm, s)) != NULL); 334 return (type == mode && tm_to_gentime(&tm, s));
360 break;
361 case RFC5280: 335 case RFC5280:
362 ret = ((atime = tm_to_rfc5280_time(&tm, s)) != NULL); 336 return (tm_to_rfc5280_time(&tm, s));
363 break;
364 default: 337 default:
365 ret = 0; 338 return (0);
366 break;
367 } 339 }
368
369 if (atime != s)
370 ASN1_TIME_free(atime);
371
372 return ret;
373} 340}
374 341
375static ASN1_TIME * 342static ASN1_TIME *
376ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec, 343ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
377 int mode) 344 int mode)
378{ 345{
346 ASN1_TIME *atime = s;
379 struct tm tm; 347 struct tm tm;
380 348
381 if (!asn1_time_time_t_to_tm(&t, &tm)) 349 if (!asn1_time_time_t_to_tm(&t, &tm))
382 return (NULL); 350 goto err;
383 351
384 if (offset_day != 0 || offset_sec != 0) { 352 if (offset_day != 0 || offset_sec != 0) {
385 if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec)) 353 if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec))
386 return (NULL); 354 goto err;
387 } 355 }
388 356
357 if (atime == NULL)
358 atime = ASN1_TIME_new();
359 if (atime == NULL)
360 goto err;
361
389 switch (mode) { 362 switch (mode) {
390 case V_ASN1_UTCTIME: 363 case V_ASN1_UTCTIME:
391 return (tm_to_utctime(&tm, s)); 364 if (!tm_to_utctime(&tm, atime))
365 goto err;
366 break;
392 case V_ASN1_GENERALIZEDTIME: 367 case V_ASN1_GENERALIZEDTIME:
393 return (tm_to_gentime(&tm, s)); 368 if (!tm_to_gentime(&tm, atime))
369 goto err;
370 break;
394 case RFC5280: 371 case RFC5280:
395 return (tm_to_rfc5280_time(&tm, s)); 372 if (!tm_to_rfc5280_time(&tm, atime))
373 goto err;
374 break;
396 default: 375 default:
397 return (NULL); 376 goto err;
398 } 377 }
378
379 return atime;
380
381 err:
382 if (atime != s)
383 ASN1_TIME_free(atime);
384
385 return NULL;
399} 386}
400 387
401ASN1_TIME * 388ASN1_TIME *
@@ -428,19 +415,29 @@ ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
428 struct tm tm; 415 struct tm tm;
429 416
430 if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME) 417 if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME)
431 return (NULL); 418 goto err;
432 419
433 if (t->type != ASN1_time_parse(t->data, t->length, &tm, t->type)) 420 if (t->type != ASN1_time_parse(t->data, t->length, &tm, t->type))
434 return (NULL); 421 goto err;
422
423 if (out == NULL || (agt = *out) == NULL)
424 agt = ASN1_TIME_new();
425 if (agt == NULL)
426 goto err;
427
428 if (!tm_to_gentime(&tm, agt))
429 goto err;
435 430
436 if (out != NULL)
437 agt = *out;
438 if ((agt = tm_to_gentime(&tm, agt)) == NULL)
439 return (NULL);
440 if (out != NULL) 431 if (out != NULL)
441 *out = agt; 432 *out = agt;
442 433
443 return (agt); 434 return agt;
435
436 err:
437 if (out == NULL || *out != agt)
438 ASN1_TIME_free(agt);
439
440 return NULL;
444} 441}
445LCRYPTO_ALIAS(ASN1_TIME_to_generalizedtime); 442LCRYPTO_ALIAS(ASN1_TIME_to_generalizedtime);
446 443
@@ -601,7 +598,7 @@ ASN1_TIME_normalize(ASN1_TIME *t)
601 return 0; 598 return 0;
602 if (!ASN1_TIME_to_tm(t, &tm)) 599 if (!ASN1_TIME_to_tm(t, &tm))
603 return 0; 600 return 0;
604 return tm_to_rfc5280_time(&tm, t) != NULL; 601 return tm_to_rfc5280_time(&tm, t);
605} 602}
606LCRYPTO_ALIAS(ASN1_TIME_normalize); 603LCRYPTO_ALIAS(ASN1_TIME_normalize);
607 604