Add new public API for checking certificate times.

Fixes: #1631

This changes the previously internal ossl_x509_check_certificate_times()
to be the public X509_check_certificate_times(). It adds documentation
for the new function and marks X509_cmp_time, X509_cmp_timeframe,
and X509_cmp_current_time as deprecated in 4.0, as discussed in #1631.

Since the function is now public, we can replace the remaining
uses of deprecated stuff with this function.

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29152)
This commit is contained in:
Bob Beck 2025-11-14 13:36:56 -07:00 committed by Neil Horman
parent 5cbbced70d
commit 4036f4b0e3
16 changed files with 238 additions and 101 deletions

View file

@ -675,18 +675,16 @@ static void warn_cert_msg(const char *uri, X509 *cert, const char *msg)
static void warn_cert(const char *uri, X509 *cert, int warn_EE,
X509_VERIFY_PARAM *vpm)
{
int error;
uint32_t ex_flags = X509_get_extension_flags(cert);
/*
* This should not be used as as example for how to verify
* certificates. This treats an invalid not before or an invalid
* not after time in the certificate as infinitely valid, which
* you don't want outside of a toy testing function like this.
*/
int res = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert),
X509_get0_notAfter(cert));
if (res != 0)
warn_cert_msg(uri, cert, res > 0 ? "has expired" : "not yet valid");
if (!X509_check_certificate_times(vpm, cert, &error)) {
char msg[128];
ERR_error_string_n(error, msg, sizeof(msg));
warn_cert_msg(uri, cert, msg);
}
if (warn_EE && (ex_flags & EXFLAG_V1) == 0 && (ex_flags & EXFLAG_CA) == 0)
warn_cert_msg(uri, cert, "is not a CA cert");
}

View file

@ -1146,19 +1146,37 @@ cert_loop:
}
if (checkend) {
X509_VERIFY_PARAM *vpm;
time_t tcheck = time(NULL) + checkoffset;
int expired = X509_cmp_time(X509_get0_notAfter(x), &tcheck) < 0;
int expired = 0;
int error, valid;
if (expired)
if ((vpm = X509_VERIFY_PARAM_new()) == NULL) {
BIO_printf(out, "Malloc failed\n");
goto end_cert_loop;
}
X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_CHECK_TIME);
X509_VERIFY_PARAM_set_time(vpm, tcheck);
valid = X509_check_certificate_times(vpm, x, &error);
if (!valid) {
char msg[128];
ERR_error_string_n(error, msg, sizeof(msg));
BIO_printf(out, "%s\n", msg);
}
if (error == X509_V_ERR_CERT_HAS_EXPIRED) {
BIO_printf(out, "Certificate will expire\n");
else
expired = 1;
} else {
BIO_printf(out, "Certificate will not expire\n");
}
if (multi && k > 0)
ret |= expired;
else
ret = expired;
X509_VERIFY_PARAM_free(vpm);
if (multi && k < sk_X509_num(certs) - 1)
goto end_cert_loop;
else

View file

@ -39,7 +39,7 @@ static int ossl_X509_check(OSSL_CMP_CTX *ctx, const char *source, X509 *cert,
int ret, err;
OSSL_CMP_severity level = vpm == NULL ? OSSL_CMP_LOG_WARNING : OSSL_CMP_LOG_ERR;
ret = ossl_x509_check_certificate_times(vpm, cert, &err);
ret = X509_check_certificate_times(vpm, cert, &err);
if (!ret) {
const char *msg;

View file

@ -265,7 +265,7 @@ static int cert_acceptable(const OSSL_CMP_CTX *ctx,
return 0;
}
if (!ossl_x509_check_certificate_times(vpm, cert, &err)) {
if (!X509_check_certificate_times(vpm, cert, &err)) {
const char *message;
switch (err) {

View file

@ -16,6 +16,7 @@
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/ocsp.h>
#include <openssl/posix_time.h>
#include "ocsp_local.h"
/*
@ -288,6 +289,20 @@ int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
return 1;
}
static int gentime_to_posix(ASN1_GENERALIZEDTIME *time, int64_t *out_time)
{
struct tm ctm;
if (!ASN1_GENERALIZEDTIME_check(time))
return 0;
if (!ASN1_TIME_to_tm(time, &ctm))
return 0;
if (!OPENSSL_tm_to_posix(&ctm, out_time))
return 0;
return 1;
}
/*
* Check validity of thisUpdate and nextUpdate fields. It is possible that
* the request will take a few seconds to process and/or the time won't be
@ -299,55 +314,52 @@ int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
{
int ret = 1;
time_t t_now, t_tmp;
int64_t t_now, this_time, next_time;
int ret = 0;
time(&t_now);
/* Check thisUpdate is valid and not more than nsec in the future */
if (!ASN1_GENERALIZEDTIME_check(thisupd)) {
if (nsec < 0)
nsec = 0;
t_now = (int64_t)time(NULL);
/* Check thisUpdate is valid */
if (!gentime_to_posix(thisupd, &this_time)) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
ret = 0;
} else {
t_tmp = t_now + nsec;
if (X509_cmp_time(thisupd, &t_tmp) > 0) {
goto err;
}
/* Check if thisUpdate is more than nsec in the future */
if (this_time > t_now + nsec) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID);
goto err;
}
/*
* If maxsec specified check thisUpdate is not more than maxsec in
* the past
*/
if (maxsec >= 0 && this_time < t_now - maxsec) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD);
goto err;
}
if (nextupd != NULL) {
/* Check nextUpdate is valid */
if (!gentime_to_posix(nextupd, &next_time)) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
goto err;
}
/* Check nextUpdate is not more than nsec in the past */
if (next_time < t_now - nsec) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID);
ret = 0;
goto err;
}
/*
* If maxsec specified check thisUpdate is not more than maxsec in
* the past
*/
if (maxsec >= 0) {
t_tmp = t_now - maxsec;
if (X509_cmp_time(thisupd, &t_tmp) < 0) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD);
ret = 0;
}
/* Also don't allow nextUpdate to precede thisUpdate */
if (next_time < this_time) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
goto err;
}
}
if (nextupd == NULL)
return ret;
/* Check nextUpdate is valid and not more than nsec in the past */
if (!ASN1_GENERALIZEDTIME_check(nextupd)) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
ret = 0;
} else {
t_tmp = t_now - nsec;
if (X509_cmp_time(nextupd, &t_tmp) < 0) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED);
ret = 0;
}
}
/* Also don't allow nextUpdate to precede thisUpdate */
if (ASN1_STRING_cmp(nextupd, thisupd) < 0) {
ERR_raise(ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
ret = 0;
}
ret = 1;
err:
return ret;
}

View file

@ -381,31 +381,45 @@ int X509_aux_print(BIO *out, const X509 *x, int indent)
int ossl_x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags)
{
unsigned long flags = ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN;
X509_VERIFY_PARAM *vpm = X509_VERIFY_PARAM_new();
int error, ret = 0;
if (cert == NULL)
return BIO_printf(bio, " (no certificate)\n") > 0;
if (vpm == NULL) {
ret = BIO_printf(bio, " (malloc failed)\n") > 0;
goto err;
}
if (cert == NULL) {
ret = BIO_printf(bio, " (no certificate)\n") > 0;
goto err;
}
if (BIO_printf(bio, " certificate\n") <= 0
|| !X509_print_ex(bio, cert, flags, ~X509_FLAG_NO_SUBJECT))
return 0;
goto err;
if (X509_check_issued((X509 *)cert, cert) == X509_V_OK) {
if (BIO_printf(bio, " self-issued\n") <= 0)
return 0;
goto err;
} else {
if (BIO_printf(bio, " ") <= 0
|| !X509_print_ex(bio, cert, flags, ~X509_FLAG_NO_ISSUER))
return 0;
goto err;
}
if (!X509_print_ex(bio, cert, flags,
~(X509_FLAG_NO_SERIAL | X509_FLAG_NO_VALIDITY)))
return 0;
if (X509_cmp_current_time(X509_get0_notBefore(cert)) > 0)
if (BIO_printf(bio, " not yet valid\n") <= 0)
return 0;
if (X509_cmp_current_time(X509_get0_notAfter(cert)) < 0)
if (BIO_printf(bio, " no more valid\n") <= 0)
return 0;
return X509_print_ex(bio, cert, flags,
goto err;
if (!X509_check_certificate_times(vpm, cert, &error)) {
char msg[128];
ERR_error_string_n(error, msg, sizeof(msg));
if (BIO_printf(bio, " %s\n", msg) <= 0)
goto err;
}
ret = X509_print_ex(bio, cert, flags,
~neg_cflags & ~X509_FLAG_EXTENSIONS_ONLY_KID);
err:
X509_VERIFY_PARAM_free(vpm);
return ret;
}
static int print_certs(BIO *bio, const STACK_OF(X509) *certs)

View file

@ -7,6 +7,7 @@
* https://www.openssl.org/source/license.html
*/
#define OPENSSL_SUPPRESS_DEPRECATED
#include "internal/deprecated.h"
#include <stdio.h>
@ -2126,9 +2127,13 @@ memerr:
/*-
* Check certificate validity times.
*
* Return 1 on success, 0 otherwise.
* Returns 1 if the certificate |x| is temporally valid at the
* verification time requested by |vpm|, or 0 otherwise. if |error| is
* non-NULL, |*error| will be set to 0 when the certificate is
* temporally valid, otherwise it will be set to a non-zero error
* code.
*/
int ossl_x509_check_certificate_times(const X509_VERIFY_PARAM *vpm, X509 *x,
int X509_check_certificate_times(const X509_VERIFY_PARAM *vpm, const X509 *x,
int *error)
{
int ret = 0, err = 0;
@ -2352,6 +2357,7 @@ static int internal_verify(X509_STORE_CTX *ctx)
return 1;
}
#if !defined(OPENSSL_NO_DEPRECATED_4_0)
int X509_cmp_current_time(const ASN1_TIME *ctm)
{
return X509_cmp_time(ctm, NULL);
@ -2421,6 +2427,7 @@ int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm,
return -1;
return 0;
}
#endif /* !defined(OPENSSL_NO_DEPRECATED_4_0) */
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
{

View file

@ -3023,6 +3023,10 @@ DEPEND[html/man3/X509_check_ca.html]=man3/X509_check_ca.pod
GENERATE[html/man3/X509_check_ca.html]=man3/X509_check_ca.pod
DEPEND[man/man3/X509_check_ca.3]=man3/X509_check_ca.pod
GENERATE[man/man3/X509_check_ca.3]=man3/X509_check_ca.pod
DEPEND[html/man3/X509_check_certificate_times.html]=man3/X509_check_certificate_times.pod
GENERATE[html/man3/X509_check_certificate_times.html]=man3/X509_check_certificate_times.pod
DEPEND[man/man3/X509_check_certificate_times.3]=man3/X509_check_certificate_times.pod
GENERATE[man/man3/X509_check_certificate_times.3]=man3/X509_check_certificate_times.pod
DEPEND[html/man3/X509_check_host.html]=man3/X509_check_host.pod
GENERATE[html/man3/X509_check_host.html]=man3/X509_check_host.pod
DEPEND[man/man3/X509_check_host.3]=man3/X509_check_host.pod
@ -3043,10 +3047,6 @@ DEPEND[html/man3/X509_cmp.html]=man3/X509_cmp.pod
GENERATE[html/man3/X509_cmp.html]=man3/X509_cmp.pod
DEPEND[man/man3/X509_cmp.3]=man3/X509_cmp.pod
GENERATE[man/man3/X509_cmp.3]=man3/X509_cmp.pod
DEPEND[html/man3/X509_cmp_time.html]=man3/X509_cmp_time.pod
GENERATE[html/man3/X509_cmp_time.html]=man3/X509_cmp_time.pod
DEPEND[man/man3/X509_cmp_time.3]=man3/X509_cmp_time.pod
GENERATE[man/man3/X509_cmp_time.3]=man3/X509_cmp_time.pod
DEPEND[html/man3/X509_digest.html]=man3/X509_digest.pod
GENERATE[html/man3/X509_digest.html]=man3/X509_digest.pod
DEPEND[man/man3/X509_digest.3]=man3/X509_digest.pod
@ -3801,12 +3801,12 @@ html/man3/X509_STORE_set_verify_cb_func.html \
html/man3/X509_VERIFY_PARAM_set_flags.html \
html/man3/X509_add_cert.html \
html/man3/X509_check_ca.html \
html/man3/X509_check_certificate_times.html \
html/man3/X509_check_host.html \
html/man3/X509_check_issued.html \
html/man3/X509_check_private_key.html \
html/man3/X509_check_purpose.html \
html/man3/X509_cmp.html \
html/man3/X509_cmp_time.html \
html/man3/X509_digest.html \
html/man3/X509_dup.html \
html/man3/X509_get0_distinguishing_id.html \
@ -4473,12 +4473,12 @@ man/man3/X509_STORE_set_verify_cb_func.3 \
man/man3/X509_VERIFY_PARAM_set_flags.3 \
man/man3/X509_add_cert.3 \
man/man3/X509_check_ca.3 \
man/man3/X509_check_certificate_times.3 \
man/man3/X509_check_host.3 \
man/man3/X509_check_issued.3 \
man/man3/X509_check_private_key.3 \
man/man3/X509_check_purpose.3 \
man/man3/X509_cmp.3 \
man/man3/X509_cmp_time.3 \
man/man3/X509_digest.3 \
man/man3/X509_dup.3 \
man/man3/X509_get0_distinguishing_id.3 \

View file

@ -2,23 +2,43 @@
=head1 NAME
X509_cmp_time, X509_cmp_current_time, X509_cmp_timeframe,
X509_time_adj, X509_time_adj_ex, X509_gmtime_adj
- X509 time functions
X509_check_certificate_times, X509_time_adj, X509_time_adj_ex, X509_gmtime_adj,
X509_cmp_time, X509_cmp_current_time, X509_cmp_timeframe - X509 time functions
=head1 SYNOPSIS
int X509_cmp_time(const ASN1_TIME *asn1_time, time_t *in_tm);
int X509_cmp_current_time(const ASN1_TIME *asn1_time);
int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm,
const ASN1_TIME *start, const ASN1_TIME *end);
int X509_check_certificate_times(const X509_VERIFY_PARAM *vpm, const X509 *x,
int *error);
ASN1_TIME *X509_time_adj(ASN1_TIME *asn1_time, long offset_sec, time_t *in_tm);
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *asn1_time, int offset_day, long
offset_sec, time_t *in_tm);
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *asn1_time, long offset_sec);
The following functions have been deprecated since OpenSSL 4.0, and can be
hidden entirely by defining B<OPENSSL_API_COMPAT> with a suitable version value,
see L<openssl_user_macros(7)>:
int X509_cmp_time(const ASN1_TIME *asn1_time, time_t *in_tm);
int X509_cmp_current_time(const ASN1_TIME *asn1_time);
int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm,
const ASN1_TIME *start, const ASN1_TIME *end);
=head1 DESCRIPTION
X509_check_certificate_times() compares the notBefore and notAfter
times in certificate I<x> to check the certificate for temporal validity.
The time used for the check will be the current system time, unless
The the reference time included in the verification parameter I<vpm>
is non NULL and I<vpm> has the flag B<X509_V_FLAG_USE_CHECK_TIME> set.
The notBefore and notAfter times in the certificate will be accepted
only if they are either the format of a GeneralizedTime
(YYYYMMDDHHMMSSZ), or a UTCTime (YYMMDDHHMMSSZ) as per RFC5280, with
the exception that the requirement: "CAs conforming to this profile
MUST always encode certificate validity dates through the year 2049 as
UTCTime; certificate validity dates in 2050 or later MUST be encoded
as GeneralizedTime." is not enforced.
X509_cmp_time() compares the ASN1_TIME in I<asn1_time> with the time
in <in_tm>.
@ -52,11 +72,35 @@ X509_time_adj() with the last parameter as NULL.
=head1 BUGS
Unlike many standard comparison functions, X509_cmp_time() and
X509_cmp_current_time() return 0 on error.
Unlike many standard comparison functions, The deprecated functions
X509_cmp_time() and X509_cmp_current_time() return 0 on error, and
return -1 when the values are equal.
The deprecated function X509_cmp_timeframe() may accept invalid
certificate times as infinitely valid.
=head1 RETURN VALUES
X509_check_certiticate_times() returns 1 if the certificate is
temporally valid at the verification time as per the rules from RFC
5280. It returns 0 otherwise. if I<error> is non NULL, the integer
value it points to will be set to an error code when the certificate
is not temporally valid, or 0 when the certificate is temporally valid.
The integer pointed to by I<error> will be set to
X509_V_ERROR_ERROR_IN_CERT_NOT_BEFORE_FIELD
or
X509_V_ERROR_ERROR_IN_CERT_NOT_AFTER_FIELD
if the certificate has an invalid notBefore or notAfter field, respectively.
The integer pointed to by I<error> will be set to
X509_V_ERR_CERT_NOT_YET_VALID
or
X509_V_ERR_CERT_HAS_EXPIRED
if the
verification time is outside of the certificate's correctly encoded
validity window as per RFC5280.
X509_cmp_time() and X509_cmp_current_time() return -1 if I<asn1_time>
is earlier than, or equal to, I<in_tm> (resp. current time), and 1
otherwise. These methods return 0 on error.
@ -85,13 +129,31 @@ as valid forever.
X509_time_adj(), X509_time_adj_ex() and X509_gmtime_adj() return a pointer to
the updated ASN1_TIME structure, and NULL on error.
=head1 SEE ALSO
L<ASN1_GENERALIZEDTIME_check(3)>
L<ASN1_UTCTIME_check(3)>
L<ASN1_TIME_to_tm(3)>
L<OPENSSL_tm_to_posix(3)> L<OPENSSL_posix_to_tm(3)>
L<ERR_error_string_n(3)>
=head1 HISTORY
X509_cmp_timeframe() was added in OpenSSL 3.0.
X509_cmp_timeframe(), X509_cmp_current_time(), and
X509_cmp_timeframe() were deprecated in OpenSSL 4.0
For replacement, consider using X509_check_certificate_times() for use
with X509 certificates. For applications checking individual ASN1_TIME
values, consider using ASN1_TIME_to_tm(3) with appropriate validity
checking of the I<ASN1_TIME> value for your application, and subsequent
comparison of either the resulting I<tm> structure, or conversion to
posix seconds via OPENSSL_tm_to_posix(3)
X509_check_certificate_times() was added in OpenSSL 4.0.
=head1 COPYRIGHT
Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy

View file

@ -399,8 +399,6 @@ int ossl_serial_number_print(BIO *out, const ASN1_INTEGER *bs, int indent);
int ossl_bio_print_hex(BIO *out, unsigned char *buf, int len);
int ossl_x509_compare_asn1_time(const X509_VERIFY_PARAM *vpm,
const ASN1_TIME *time, int *comparison);
int ossl_x509_check_certificate_times(const X509_VERIFY_PARAM *vpm, X509 *x,
int *error);
/* No error callback if depth < 0 */
int ossl_x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth);
int ossl_x509_check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify);

View file

@ -49,6 +49,9 @@
#define OSSL_DEPRECATED_FOR(since, message) __declspec(deprecated)
#define OSSL_DEPRECATED_MESSAGE(message) __declspec(deprecated)
#endif
#define OSSL_BEGIN_ALLOW_DEPRECATED \
__pragma(warning(push)) __pragma(warning(disable : 4996))
#define OSSL_END_ALLOW_DEPRECATED __pragma(warning(pop))
#elif defined(__GNUC__)
/*
* According to GCC documentation, deprecations with message appeared in
@ -65,12 +68,20 @@
#define OSSL_DEPRECATED_FOR(since, message) __attribute__((deprecated))
#define OSSL_DEPRECATED_MESSAGE(message) __attribute__((deprecated))
#endif
#define OSSL_BEGIN_ALLOW_DEPRECATED \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#define OSSL_END_ALLOW_DEPRECATED _Pragma("GCC diagnostic pop")
#elif defined(__SUNPRO_C)
#if (__SUNPRO_C >= 0x5130)
#define OSSL_DEPRECATED(since) __attribute__((deprecated))
#define OSSL_DEPRECATED_FOR(since, message) __attribute__((deprecated))
#define OSSL_DEPRECATED_MESSAGE(message) __attribute__((deprecated))
#endif
#define OSSL_BEGIN_ALLOW_DEPRECATED \
#pragma error_messages(off, E_DEPRECATED_ATT, E_DEPRECATED_ATT_MESS)
#define OSSL_END_ALLOW_DEPRECATED \
#pragma error_messages(on, E_DEPRECATED_ATT, E_DEPRECATED_ATT_MESS)
#endif
#endif
#endif

View file

@ -495,10 +495,15 @@ int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src);
DECLARE_ASN1_DUP_FUNCTION(X509_NAME)
DECLARE_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
int X509_cmp_time(const ASN1_TIME *s, time_t *t);
int X509_cmp_current_time(const ASN1_TIME *s);
int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm,
const ASN1_TIME *start, const ASN1_TIME *end);
#ifndef OPENSSL_NO_DEPRECATED_4_0
OSSL_DEPRECATEDIN_4_0 int X509_cmp_time(const ASN1_TIME *s, time_t *t);
OSSL_DEPRECATEDIN_4_0 int X509_cmp_current_time(const ASN1_TIME *s);
OSSL_DEPRECATEDIN_4_0 int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm,
const ASN1_TIME *start,
const ASN1_TIME *end);
#endif
int X509_check_certificate_times(const X509_VERIFY_PARAM *vpm, const X509 *x,
int *error);
ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
int offset_day, long offset_sec, time_t *t);

View file

@ -670,8 +670,9 @@ ok(!run(app(["openssl", "x509", "-checkend", $delta_early + 3600,
# Single + expiring at boundary
# Test may fail erroneously due to sequential now() calls
# See https://github.com/openssl/openssl/pull/29155
# Certificate should be valid at exact NotAfter time.
my $delta_exact = Time::Piece->strptime( get_field($c_early, "Not After "),
"%b %d %T %Y %Z")->epoch - Time::Piece->gmtime->epoch;
"%b %d %T %Y %Z")->epoch - Time::Piece->gmtime->epoch + 1;
ok(!run(app(["openssl", "x509", "-checkend", $delta_exact, "-in", $c_early])),
"Single cert + expiring at -checkend boundary");
# Multi + none expiring

View file

@ -308,8 +308,8 @@ static int test_a_time(X509_STORE_CTX *ctx, X509 *x509,
return 1;
}
error = 0;
if (ossl_x509_check_certificate_times(vpm, x509, &error) != expected_value) {
TEST_info("%s:%d - ossl_X509_check_certificate_times %s unexpectedly "
if (X509_check_certificate_times(vpm, x509, &error) != expected_value) {
TEST_info("%s:%d - X509_check_certificate_times %s unexpectedly "
"when verifying notBefore %lld, notAfter %lld at time %lld\n",
file, line,
expected_value ? "failed" : "succeeded",

View file

@ -214,6 +214,7 @@ static TESTDATA_FORMAT x509_format_tests[] = {
},
};
#if !defined(OPENSSL_NO_DEPRECATED_4_0)
static TESTDATA x509_cmp_tests[] = {
{
"20170217180154Z",
@ -413,7 +414,9 @@ static int test_x509_cmp_time(int idx)
t.length = (int)strlen(x509_cmp_tests[idx].data);
t.flags = 0;
OSSL_BEGIN_ALLOW_DEPRECATED
result = X509_cmp_time(&t, &x509_cmp_tests[idx].cmp_time);
OSSL_END_ALLOW_DEPRECATED
if (!TEST_int_eq(result, x509_cmp_tests[idx].expected)) {
TEST_info("test_x509_cmp_time(%d) failed: expected %d, got %d\n",
idx, x509_cmp_tests[idx].expected, result);
@ -434,6 +437,7 @@ static int test_x509_cmp_time_current(void)
asn1_now = ASN1_TIME_adj(NULL, now, 0, 0);
/* X509_cmp_time is expected to return -1 for equal */
OSSL_BEGIN_ALLOW_DEPRECATED
cmp_result = X509_cmp_time(asn1_now, &now);
if (!TEST_int_eq(cmp_result, -1))
failed = 1;
@ -445,6 +449,7 @@ static int test_x509_cmp_time_current(void)
cmp_result = X509_cmp_time(asn1_after, &now);
if (!TEST_int_eq(cmp_result, 1))
failed = 1;
OSSL_END_ALLOW_DEPRECATED
ASN1_TIME_free(asn1_before);
ASN1_TIME_free(asn1_after);
@ -462,6 +467,7 @@ static int test_X509_cmp_timeframe_vpm(const X509_VERIFY_PARAM *vpm,
&& (X509_VERIFY_PARAM_get_flags(vpm) & X509_V_FLAG_USE_CHECK_TIME) == 0
&& (X509_VERIFY_PARAM_get_flags(vpm) & X509_V_FLAG_NO_CHECK_TIME) != 0;
OSSL_BEGIN_ALLOW_DEPRECATED
return asn1_before != NULL && asn1_mid != NULL && asn1_after != NULL
&& TEST_int_eq(X509_cmp_timeframe(vpm, asn1_before, asn1_after), 0)
&& TEST_int_eq(X509_cmp_timeframe(vpm, asn1_before, NULL), 0)
@ -473,6 +479,7 @@ static int test_X509_cmp_timeframe_vpm(const X509_VERIFY_PARAM *vpm,
always_0 ? 0 : 1)
&& TEST_int_eq(X509_cmp_timeframe(vpm, asn1_after, asn1_before),
always_0 ? 0 : 1);
OSSL_END_ALLOW_DEPRECATED
}
static int test_X509_cmp_timeframe(void)
@ -504,6 +511,7 @@ finish:
return res;
}
#endif /* !defined(OPENSSL_NO_DEPRECATED_4_0) */
static int test_x509_time(int idx)
{
@ -749,9 +757,11 @@ err:
int setup_tests(void)
{
#if !defined(OPENSSL_NO_DEPRECATED_4_0)
ADD_TEST(test_x509_cmp_time_current);
ADD_TEST(test_X509_cmp_timeframe);
ADD_ALL_TESTS(test_x509_cmp_time, OSSL_NELEM(x509_cmp_tests));
#endif /* !defined(OPENSSL_NO_DEPRECATED_4_0) */
ADD_ALL_TESTS(test_x509_time, OSSL_NELEM(x509_format_tests));
ADD_ALL_TESTS(test_days, OSSL_NELEM(day_of_week_tests));
ADD_ALL_TESTS(test_x509_time_print_rfc_822, OSSL_NELEM(x509_print_tests_rfc_822));

View file

@ -4427,9 +4427,10 @@ X509_ALGOR_cmp ? 4_0_0 EXIST::FUNCTION:
X509_ALGOR_copy ? 4_0_0 EXIST::FUNCTION:
X509_NAME_dup ? 4_0_0 EXIST::FUNCTION:
X509_NAME_ENTRY_dup ? 4_0_0 EXIST::FUNCTION:
X509_cmp_time ? 4_0_0 EXIST::FUNCTION:
X509_cmp_current_time ? 4_0_0 EXIST::FUNCTION:
X509_cmp_timeframe ? 4_0_0 EXIST::FUNCTION:
X509_cmp_time ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_0
X509_cmp_current_time ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_0
X509_cmp_timeframe ? 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_0
X509_check_certificate_times ? 4_0_0 EXIST::FUNCTION:
X509_time_adj ? 4_0_0 EXIST::FUNCTION:
X509_time_adj_ex ? 4_0_0 EXIST::FUNCTION:
X509_gmtime_adj ? 4_0_0 EXIST::FUNCTION: