diff options
author | tb <> | 2024-04-11 06:42:09 +0000 |
---|---|---|
committer | tb <> | 2024-04-11 06:42:09 +0000 |
commit | c7dbc1d09fc1acd9ea6960a0e507b18e921248be (patch) | |
tree | b5641598728f2610405c41856804fb1d3302998b /src | |
parent | 30137553e5880795d09be4a50f12f0c075287faf (diff) | |
download | openbsd-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.c | 135 |
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. */ |
81 | ASN1_TIME * | 81 | static int |
82 | tm_to_gentime(struct tm *tm, ASN1_TIME *atime) | 82 | tm_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. */ |
122 | ASN1_TIME * | 110 | static int |
123 | tm_to_utctime(struct tm *tm, ASN1_TIME *atime) | 111 | tm_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 | ||
160 | ASN1_TIME * | 138 | static int |
161 | tm_to_rfc5280_time(struct tm *tm, ASN1_TIME *atime) | 139 | tm_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) | |||
344 | static int | 322 | static int |
345 | ASN1_TIME_set_string_internal(ASN1_TIME *s, const char *str, int mode) | 323 | ASN1_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 | ||
375 | static ASN1_TIME * | 342 | static ASN1_TIME * |
376 | ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec, | 343 | ASN1_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 | ||
401 | ASN1_TIME * | 388 | ASN1_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 | } |
445 | LCRYPTO_ALIAS(ASN1_TIME_to_generalizedtime); | 442 | LCRYPTO_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 | } |
606 | LCRYPTO_ALIAS(ASN1_TIME_normalize); | 603 | LCRYPTO_ALIAS(ASN1_TIME_normalize); |
607 | 604 | ||