diff options
| author | tb <> | 2024-04-11 06:42:09 +0000 |
|---|---|---|
| committer | tb <> | 2024-04-11 06:42:09 +0000 |
| commit | 232d00c010fdfe7a0a8d452cd24ed43bbdcdeb0e (patch) | |
| tree | b5641598728f2610405c41856804fb1d3302998b | |
| parent | dece4af8efa44252473b6e9c019d504489cdaebb (diff) | |
| download | openbsd-232d00c010fdfe7a0a8d452cd24ed43bbdcdeb0e.tar.gz openbsd-232d00c010fdfe7a0a8d452cd24ed43bbdcdeb0e.tar.bz2 openbsd-232d00c010fdfe7a0a8d452cd24ed43bbdcdeb0e.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 '')
| -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 | ||
