ASN1_TIME_SET(3) | Library Functions Manual | ASN1_TIME_SET(3)

# NAME

`ASN1_TIME_set`, `ASN1_UTCTIME_set`, `ASN1_GENERALIZEDTIME_set`, `ASN1_TIME_adj`, `ASN1_UTCTIME_adj`, `ASN1_GENERALIZEDTIME_adj`, `ASN1_TIME_set_string`, `ASN1_TIME_set_string_X509`, `ASN1_UTCTIME_set_string`, `ASN1_GENERALIZEDTIME_set_string`, `ASN1_TIME_normalize`, `ASN1_TIME_check`, `ASN1_UTCTIME_check`, `ASN1_GENERALIZEDTIME_check`, `ASN1_TIME_print`, `ASN1_UTCTIME_print`, `ASN1_GENERALIZEDTIME_print`, `ASN1_TIME_to_tm`, `ASN1_TIME_diff`, `ASN1_TIME_cmp_time_t`, `ASN1_UTCTIME_cmp_time_t`, `ASN1_TIME_compare`, `ASN1_TIME_to_generalizedtime`, `OPENSSL_gmtime`, `OPENSSL_timegm`, `OPENSSL_posix_to_tm`, `OPENSSL_tm_to_posix` — ASN.1 Time functions

# SYNOPSIS

library “libcrypto”
`#include <openssl/asn1.h>`

ASN1_TIME *
`ASN1_TIME_set`(ASN1_TIME *s, time_t t);

ASN1_UTCTIME *
`ASN1_UTCTIME_set`(ASN1_UTCTIME *s, time_t t);

ASN1_GENERALIZEDTIME *
`ASN1_GENERALIZEDTIME_set`(ASN1_GENERALIZEDTIME *s, time_t t);

ASN1_TIME *
`ASN1_TIME_adj`(ASN1_TIME *s, time_t t, int offset_day, long offset_sec);

ASN1_UTCTIME *
`ASN1_UTCTIME_adj`(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec);

ASN1_GENERALIZEDTIME *
`ASN1_GENERALIZEDTIME_adj`(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, long offset_sec);

int
`ASN1_TIME_set_string`(ASN1_TIME *s, const char *str);

int
`ASN1_TIME_set_string_X509`(ASN1_TIME *s, const char *str);

int
`ASN1_UTCTIME_set_string`(ASN1_UTCTIME *s, const char *str);

int
`ASN1_GENERALIZEDTIME_set_string`(ASN1_GENERALIZEDTIME *s, const char *str);

int
`ASN1_TIME_normalize`(ASN1_TIME *s);

int
`ASN1_TIME_check`(const ASN1_TIME *t);

int
`ASN1_UTCTIME_check`(const ASN1_UTCTIME *t);

int
`ASN1_GENERALIZEDTIME_check`(const ASN1_GENERALIZEDTIME *t);

int
`ASN1_TIME_print`(BIO *b, const ASN1_TIME *s);

int
`ASN1_UTCTIME_print`(BIO *b, const ASN1_UTCTIME *s);

int
`ASN1_GENERALIZEDTIME_print`(BIO *b, const ASN1_GENERALIZEDTIME *s);

int
`ASN1_TIME_to_tm`(const ASN1_TIME *s, struct tm *tm);

int
`ASN1_TIME_diff`(int *pday, int *psec, const ASN1_TIME *from, const ASN1_TIME *to);

int
`ASN1_TIME_cmp_time_t`(const ASN1_TIME *s, time_t t);

int
`ASN1_UTCTIME_cmp_time_t`(const ASN1_UTCTIME *s, time_t t);

int
`ASN1_TIME_compare`(const ASN1_TIME *s, const ASN1_TIME *t);

ASN1_GENERALIZEDTIME *
`ASN1_TIME_to_generalizedtime`(const ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);

`#include <openssl/crypto.h>`

struct tm *
`OPENSSL_gmtime`(const time_t *time, struct tm *out_tm);

`#include <openssl/posix_time.h>`

int
`OPENSSL_timegm`(const struct tm *tm, time_t *out_time);

int
`OPENSSL_posix_to_tm`(int64_t time, struct tm *out_tm);

int
`OPENSSL_tm_to_posix`(struct tm *t_tm, int64_t *out);

# DESCRIPTION

An ASN1_TIME object is a shallow wrapper around a string containing an ASN.1 Time value in the restricted format valid in X.509 certificates. An ASN1_TIME object is either an ASN1_UTCTIME object containing a string of the format YYMMDDHHMMSS `Z` which is valid for the years 1950 to 2049, or an ASN1_GENERALIZEDTIME object containing a string of the format YYYYMMDDHHMMSS `Z` which is valid for the years 0000 to 1949 and 2050 to 9999. In both cases, the mandatory suffix ‘`Z`’ represents the GMT time zone. LibreSSL by design does not support the full syntax of ASN.1 times. In particular, it neither supports fractional seconds nor any other time zone.

The functions `ASN1_TIME_set`(), `ASN1_UTCTIME_set`(), and `ASN1_GENERALIZEDTIME_set`() set the time object s to the time represented by the time_t value t. If s is `NULL`, a new time object is allocated and returned.

The functions `ASN1_TIME_adj`(), `ASN1_UTCTIME_adj`(), and `ASN1_GENERALIZEDTIME_adj`() set the time object s to the time represented by the time offset_day and offset_sec after the time_t value t. The values of offset_day or offset_sec can be negative to set a time before t. The offset_sec value can also exceed the number of seconds in a day. If s is `NULL`, a new time object is allocated and returned.

`ASN1_TIME_adj`() may change the type from ASN1_GENERALIZEDTIME to ASN1_UTCTIME or vice versa depending on the resulting year. The functions `ASN1_UTCTIME_adj`() and `ASN1_GENERALIZEDTIME_adj`() do not modify the type of the return object.

The functions `ASN1_TIME_set_string`(), `ASN1_TIME_set_string_X509`(), `ASN1_UTCTIME_set_string`(), and `ASN1_GENERALIZEDTIME_set_string`() set the time object s to the time string str, which must be in appropriate ASN.1 time format: YYMMDDHHMMSSZ for ASN1_UTCTIME, YYYYMMDDHHMMSSZ for ASN1_GENERALIZEDTIME, or either of the two for ASN1_TIME. The string str is copied into s. If s is `NULL`, these functions only perform a format check on str.

In LibreSSL, `ASN1_TIME_set_string`() and `ASN1_TIME_set_string_X509`() behave identically and always set the time object to a valid value to use in an X.509 certificate. `ASN1_GENERALIZEDTIME_set_string`() may encode a time string that is not valid in an X.509 certificate.

The function `ASN1_TIME_normalize`() converts an ASN1_GENERALIZEDTIME into a time value that can be used in a certificate by changing it to an ASN1_UTCTIME if possible. It has no effect on an ASN1_UTCTIME.

The functions `ASN1_TIME_check`(), `ASN1_UTCTIME_check`(), and `ASN1_GENERALIZEDTIME_check`() check the syntax of the time string contained in the object s.

The functions `ASN1_TIME_print`(), `ASN1_UTCTIME_print`(), and `ASN1_GENERALIZEDTIME_print`() print out the time s to BIO b 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". It does not include a newline. If the time string has an invalid format, it prints out "Bad time value" and returns an error.

The function `ASN1_TIME_to_tm`() converts the time s to the standard tm structure. If s is `NULL`, then the current time is converted. The output time is always in the GMT time zone. The tm_sec, tm_min, tm_hour, tm_mday, tm_mon, and tm_year fields of the tm structure are set to the proper values, whereas all other fields are set to 0. If tm is `NULL`, this function performs a format check on s only.

The function `ASN1_TIME_diff`() sets *pday and *psec to the time difference between from and to. If to represents a time later than from, then one or both (depending on the time difference) of *pday and *psec will be positive. If to represents a time earlier than from, then one or both of *pday and *psec will be negative. If to and from represent the same time, then *pday and *psec will both be zero. If both *pday and *psec are nonzero, they will always have the same sign. The value of *psec will always be less than the number of seconds in a day. If from or to is `NULL`, the current time is used.

The functions `ASN1_TIME_cmp_time_t`(), `ASN1_UTCTIME_cmp_time_t`(), and `ASN1_TIME_compare`() compare the two times represented by s and t.

The function `ASN1_TIME_to_generalizedtime`() converts the ASN1_TIME t to an ASN1_GENERALIZEDTIME, regardless of year. If either out or *out is `NULL`, then a new object is allocated and must be freed after use.

The ASN1_TIME, ASN1_UTCTIME, and ASN1_GENERALIZEDTIME objects are represented as ASN1_STRING objects internally and can be freed using ASN1_STRING_free(3).

It is recommended that ASN1_TIME functions be used instead of ASN1_UTCTIME or ASN1_GENERALIZEDTIME functions because the ASN1_UTCTIME and ASN1_GENERALIZEDTIME functions act only on that specific time format, while the ASN1_TIME functions operate on either format.

`OPENSSL_gmtime`() converts a time_t value in time to a struct tm in out_tm and also returns the struct passed in on success.

`OPENSSL_timegm`() converts a time structure in UTC time in tm to a time_t value in out_time.

`OPENSSL_posix_to_tm`() converts an int64_t POSIX time value in time, which must be in the range of year 0 to 9999, to a broken out time value in tm.

`OPENSSL_tm_to_posix`() converts a time value between the years 0 and 9999 in tm to a POSIX time value in out.

# RETURN VALUES

`ASN1_TIME_set`(), `ASN1_UTCTIME_set`(), `ASN1_GENERALIZEDTIME_set`(), `ASN1_TIME_adj`(), `ASN1_UTCTIME_adj`(), `ASN1_GENERALIZEDTIME_adj`(), and `ASN1_TIME_to_generalizedtime`() return a pointer to a time object or `NULL` if an error occurred.

`ASN1_TIME_set_string`(), `ASN1_TIME_set_string_X509`(), `ASN1_UTCTIME_set_string`(), and `ASN1_GENERALIZEDTIME_set_string`() return 1 if the time value is successfully set or 0 otherwise.

`ASN1_TIME_normalize`() returns 1 on success or 0 on error.

`ASN1_TIME_check`(), `ASN1_UTCTIME_check`(), and `ASN1_GENERALIZEDTIME_check`() return 1 if the time string contained in the object is syntactically correct or 0 otherwise.

`ASN1_TIME_print`(), `ASN1_UTCTIME_print`(), and `ASN1_GENERALIZEDTIME_print`() return 1 if the time is successfully printed or 0 if an error occurred (I/O error or invalid time format).

`ASN1_TIME_to_tm`() returns 1 if the time is successfully parsed or 0 if an error occurred, usually due to an invalid time format.

`ASN1_TIME_diff`() returns 1 for success or 0 for failure. It can for example fail if a time string passed in has invalid syntax.

`ASN1_TIME_cmp_time_t`(), `ASN1_UTCTIME_cmp_time_t`(), and `ASN1_TIME_compare`() return -1 if s is earlier than t, 0 if both are equal, 1 if s is later than t, or -2 on error.

`OPENSSL_timegm`() returns 1 for success or 0 for failure. It can fail if the time is not representable in a time_t, or falls outside the range allowed in RFC 5280 times.

`OPENSSL_gmtime`() returns out_tm on success or NULL for failure. It can fail if the time is not representable in a struct tm, or falls outside the range allowed in RFC 5280 times.

`OPENSSL_posix_to_tm`() and `OPENSSL_tm_to_posix`() return 1 for success or 0 on failure. It is a failure if the year is less than 0 or more than 9999.

# EXAMPLES

Set a time object to one hour after the current time and print it out:

    #include <time.h>
    #include <openssl/asn1.h>

    ASN1_TIME *asn1_time;
    time_t t;
    BIO *b;

    t = time(NULL);
    asn1_time = ASN1_TIME_adj(NULL, t, 0, 60 * 60);
    b = BIO_new_fp(stdout, BIO_NOCLOSE);
    if (asn1_time != NULL) {
    	ASN1_TIME_print(b, asn1_time);
    	BIO_printf(b, "\n");
    } else {
    	BIO_printf(b, "Time out of range or un-representable\n");
    }
    ASN1_STRING_free(asn1_time);
    BIO_free(b);

# SEE ALSO

ASN1_TIME_new(3), X509_cmp_time(3)

# STANDARDS

The usage of the ASN.1 Time, UTCTime, and GeneralizedTime data types in X.509 certificates is specified in RFC 5280, Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile, section 4.1.2.5 (TBS Certificate Validity).

# HISTORY

`ASN1_UTCTIME_check`() and `ASN1_UTCTIME_print`() first appeared in SSLeay 0.5.1. `ASN1_UTCTIME_set`() first appeared in SSLeay 0.6.0. `ASN1_UTCTIME_set_string`() first appeared in SSLeay 0.9.0. All these functions have been available since OpenBSD 2.4.

`ASN1_TIME_set`(), `ASN1_GENERALIZEDTIME_set`(), `ASN1_GENERALIZEDTIME_set_string`(), `ASN1_GENERALIZEDTIME_check`(), `ASN1_TIME_print`(), and `ASN1_GENERALIZEDTIME_print`() first appeared in OpenSSL 0.9.2b and have been available since OpenBSD 2.6.

`ASN1_UTCTIME_cmp_time_t`() first appeared in OpenSSL 0.9.6 and has been available since OpenBSD 2.9.

`ASN1_TIME_check`() and `ASN1_TIME_to_generalizedtime`() first appeared in OpenSSL 0.9.7 and have been available since OpenBSD 3.2.

`ASN1_TIME_adj`(), `ASN1_UTCTIME_adj`(), `ASN1_GENERALIZEDTIME_adj`(), and `ASN1_TIME_set_string`() first appeared in OpenSSL 1.0.0 and have been available since OpenBSD 4.9.

`ASN1_TIME_diff`() first appeared in OpenSSL 1.0.2 and have been available since OpenBSD 7.1.

`ASN1_TIME_set_string_X509`(), `ASN1_TIME_normalize`(), `ASN1_TIME_to_tm`(), `ASN1_TIME_cmp_time_t`(), and `ASN1_TIME_compare`() first appeared in OpenSSL 1.1.1 and have been available since OpenBSD 7.2.

`OPENSSL_gmtime`() first appeared in OpenSSL 0.9.7. `OPENSSL_timegm`(), `OPENSSL_posix_to_tm`(), and `OPENSSL_tm_to_posix`() first appeared in BoringSSL; all these functions have been available since OpenBSD 7.5.

# CAVEATS

Some applications add offset times directly to a time_t value and pass the results to `ASN1_TIME_set`() (or equivalent). This can cause problems as the time_t value can overflow on some systems resulting in unexpected results. New applications should use `ASN1_TIME_adj`() instead and pass the offset value in the offset_sec and offset_day parameters instead of directly manipulating a time_t value.

June 8, 2025 | Debian