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
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 YYMMDDHHMMSSZ which is valid for the years 1950 to 2049, or an ASN1_GENERALIZEDTIME object containing a string of the format YYYYMMDDHHMMSSZ 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.