From e2c3cd9eb714e3635b34d3ce99ff784adbc6f30a Mon Sep 17 00:00:00 2001 From: Remi Tricot-Le Breton Date: Thu, 21 May 2026 15:18:06 +0200 Subject: [PATCH] BUG/MINOR: ocsp: Manage date too far away in the future The check on the OCSP response expire time is based on the "Next Update" field of the response, converted by my_timegm function that returns a time_t (signed long). It is then stored in the 'expire' field of the certificate_ocsp structure which is typed as a signed long. When loading an OCSP response, if the "Next Update" time is too far in the future and we are running on a 32 bits machine, we might end up with negative times ireturned by my_timegm, which make the comparison with the current date fail and raises the "OCSP single response: no longer valid." error message. This problem typically happens in the ocsp_auto_update.vtc regtest since the loaded OCSP response have a "Next Update" field in 2050. This patch simply changes the type of the expire field to an unsigned long since the 'my_timegm' function does not return '-1' in case of error, contrary to the standard 'timegm' one. Ths patch can be backported to all stable branches. --- include/haproxy/ssl_ocsp-t.h | 2 +- src/ssl_ocsp.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/haproxy/ssl_ocsp-t.h b/include/haproxy/ssl_ocsp-t.h index e0b706220..1f3bbc41b 100644 --- a/include/haproxy/ssl_ocsp-t.h +++ b/include/haproxy/ssl_ocsp-t.h @@ -50,7 +50,7 @@ struct certificate_ocsp { int refcount_store; /* Number of ckch_store that reference this certificate_ocsp */ int refcount; /* Number of actual references to this certificate_ocsp (SSL_CTXs mostly) */ struct buffer response; - long expire; + unsigned long expire; X509 *issuer; STACK_OF(X509) *chain; struct eb64_node next_update; /* Key of items inserted in ocsp_update_tree (sorted by absolute date) */ diff --git a/src/ssl_ocsp.c b/src/ssl_ocsp.c index 2709704dc..366ff574d 100644 --- a/src/ssl_ocsp.c +++ b/src/ssl_ocsp.c @@ -290,6 +290,8 @@ int ssl_sock_load_ocsp_response(struct buffer *ocsp_response, int ret = 1; #ifdef HAVE_ASN1_TIME_TO_TM struct tm nextupd_tm = {0}; +#else + long expire = 0; #endif resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, @@ -391,11 +393,12 @@ int ssl_sock_load_ocsp_response(struct buffer *ocsp_response, } ocsp->expire = my_timegm(&nextupd_tm) - OCSP_MAX_RESPONSE_TIME_SKEW; #else - ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW; - if (ocsp->expire < 0) { + expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW; + if (expire < 0) { memprintf(err, "OCSP single response: Invalid \"Next Update\" time"); goto out; } + ocsp->expire = expire; #endif if (ocsp->expire < date.tv_sec) {