---
name: "libressl-ASN1_TIME_set"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-ASN1_TIME_set"
---

# libressl-ASN1\_TIME\_set(3)

ASN.1 Time functions

## 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

Crypto Library (libcrypto, -lcrypto)

**#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.
