From d345ce4d78b8b81dec6ebfc3fa3fe242fb2c98e9 Mon Sep 17 00:00:00 2001 From: Michael Baentsch <57787676+baentsch@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:57:28 +0100 Subject: [PATCH] Improve ASN1_TIME_print documentation and output This adds missing GMT indication when printing the local time as it is converted to the UTC timezone before printing. Also fixing the fractional seconds printing on EBCDIC platforms. Fixes #26313 Reviewed-by: Todd Short Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/26344) (cherry picked from commit c81ff978667e7c0d792e02db7a02b7bc12433abd) --- crypto/asn1/a_time.c | 55 +++++++++++++++++--------------------- doc/man3/ASN1_TIME_set.pod | 8 ++++-- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c index 5d63dbbc26c..7fe9cddb128 100644 --- a/crypto/asn1/a_time.c +++ b/crypto/asn1/a_time.c @@ -488,9 +488,9 @@ int ASN1_TIME_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags) int ossl_asn1_time_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags) { char *v; - int gmt = 0, l; + int l; struct tm stm; - const char upper_z = 0x5A, period = 0x2E; + const char period = 0x2E; /* ossl_asn1_time_to_tm will check the time type */ if (!ossl_asn1_time_to_tm(&stm, tm)) @@ -498,8 +498,6 @@ int ossl_asn1_time_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags) l = tm->length; v = (char *)tm->data; - if (v[l - 1] == upper_z) - gmt = 1; if (tm->type == V_ASN1_GENERALIZEDTIME) { char *f = NULL; @@ -510,39 +508,36 @@ int ossl_asn1_time_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags) * 'fraction point' in a GeneralizedTime string. */ if (tm->length > 15 && v[14] == period) { - f = &v[14]; - f_len = 1; - while (14 + f_len < l && ossl_ascii_isdigit(f[f_len])) + /* exclude the . itself */ + f = &v[15]; + f_len = 0; + while (15 + f_len < l && ossl_ascii_isdigit(f[f_len])) ++f_len; } - if ((flags & ASN1_DTFLGS_TYPE_MASK) == ASN1_DTFLGS_ISO8601) { - return BIO_printf(bp, "%4d-%02d-%02d %02d:%02d:%02d%.*s%s", - stm.tm_year + 1900, stm.tm_mon + 1, - stm.tm_mday, stm.tm_hour, - stm.tm_min, stm.tm_sec, f_len, f, - (gmt ? "Z" : "")) > 0; - } - else { - return BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", - _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour, - stm.tm_min, stm.tm_sec, f_len, f, stm.tm_year + 1900, - (gmt ? " GMT" : "")) > 0; + if (f_len > 0) { + if ((flags & ASN1_DTFLGS_TYPE_MASK) == ASN1_DTFLGS_ISO8601) { + return BIO_printf(bp, "%4d-%02d-%02d %02d:%02d:%02d.%.*sZ", + stm.tm_year + 1900, stm.tm_mon + 1, + stm.tm_mday, stm.tm_hour, + stm.tm_min, stm.tm_sec, f_len, f) > 0; + } else { + return BIO_printf(bp, "%s %2d %02d:%02d:%02d.%.*s %d GMT", + _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour, + stm.tm_min, stm.tm_sec, f_len, f, + stm.tm_year + 1900) > 0; + } } - } else { - if ((flags & ASN1_DTFLGS_TYPE_MASK) == ASN1_DTFLGS_ISO8601) { - return BIO_printf(bp, "%4d-%02d-%02d %02d:%02d:%02d%s", + } + if ((flags & ASN1_DTFLGS_TYPE_MASK) == ASN1_DTFLGS_ISO8601) { + return BIO_printf(bp, "%4d-%02d-%02d %02d:%02d:%02dZ", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, - stm.tm_min, stm.tm_sec, - (gmt ? "Z" : "")) > 0; - } - else { - return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", + stm.tm_min, stm.tm_sec) > 0; + } else { + return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d GMT", _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour, - stm.tm_min, stm.tm_sec, stm.tm_year + 1900, - (gmt ? " GMT" : "")) > 0; - } + stm.tm_min, stm.tm_sec, stm.tm_year + 1900) > 0; } } diff --git a/doc/man3/ASN1_TIME_set.pod b/doc/man3/ASN1_TIME_set.pod index 66d9fefe1af..1efe305e00d 100644 --- a/doc/man3/ASN1_TIME_set.pod +++ b/doc/man3/ASN1_TIME_set.pod @@ -102,8 +102,8 @@ functions check the syntax of the time structure I. The ASN1_TIME_print(), ASN1_UTCTIME_print() and ASN1_GENERALIZEDTIME_print() functions print the time structure I to BIO I in human readable -format. It will be of the format MMM DD HH:MM:SS YYYY [GMT], for example -"Feb 3 00:55:52 2015 GMT", which does not include a newline. +format. It will be of the format MMM DD HH:MM:SS[.s*] YYYY GMT, for example +"Feb E<32>3 00:55:52 2015 GMT", which does not include a newline. If the time structure has invalid format it prints out "Bad time value" and returns an error. The output for generalized time may include a fractional part following the second. @@ -179,6 +179,10 @@ starting with B and B act only on that specific time format. The functions starting with B will operate on either format. +Users familiar with RFC822 should note that when specifying the flag +B the year will be formatted as documented above, +i.e., using 4 digits, not 2 as specified in RFC822. + =head1 BUGS ASN1_TIME_print(), ASN1_UTCTIME_print() and ASN1_GENERALIZEDTIME_print() do -- 2.47.2