[Openvpn-devel,v5] OpenSSL 4.0: Use X509_check_certificate_times instead of X509_cmp_time

Message ID 20260417164644.17897-1-gert@greenie.muc.de
State New
Headers show
Series [Openvpn-devel,v5] OpenSSL 4.0: Use X509_check_certificate_times instead of X509_cmp_time | expand

Commit Message

Gert Doering April 17, 2026, 4:46 p.m. UTC
From: Arne Schwabe <arne@rfc2549.org>

The X509_cmp_time function is deprecated in OpenSSL 4.0. So we avoid it and
use the new API.

Change-Id: I6c2eda0e5bbb3a70b404f821e25ded81f0f5ddd5
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1595
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1595
This mail reflects revision 5 of this Change.

Acked-by according to Gerrit (reflected above):
Gert Doering <gert@greenie.muc.de>

Comments

Gert Doering April 18, 2026, 6:32 p.m. UTC | #1
So, for "non openssl 4.0" builds, this patch has no effect.  With 4.0, we
get compile warnings without this patch, and it compiles fine with it -
and for a profile I had around with an expired cert, it shows the expected
message.  All the error codes that are documented as possible return
values are handled, though I cannot test this (I guess you need to produce
a corrupt cert for two of them).

As for "add a default clause for yet-unknown error messages", we decided
against (because there are not really any other ways this could fail,
and even if, it's just a helper function to tell users that their 
certificate lifetime is in conflict with local date, which might or might
not lead to problems connecting).

Your patch has been applied to the master and release/2.7 branch.

commit 353ec724f9bc1dceb36760eceee0a128e140044c (master)
commit 8747fcf641214d4f05de53f9db825f396049e3d3 (release/2.7)
Author: Arne Schwabe
Date:   Fri Apr 17 18:46:38 2026 +0200

     OpenSSL 4.0: Use X509_check_certificate_times instead of X509_cmp_time

     Signed-off-by: Arne Schwabe <arne@rfc2549.org>
     Acked-by: Gert Doering <gert@greenie.muc.de>
     Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1595
     Message-Id: <20260417164644.17897-1-gert@greenie.muc.de>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg36651.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index efe5b5b..6130dc3 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -634,6 +634,7 @@ 
 #endif /* if OPENSSL_VERSION_NUMBER < 0x30000000L */
 }
 
+#if OPENSSL_VERSION_NUMBER < 0x40000000L
 void
 tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)
 {
@@ -669,6 +670,60 @@ 
         msg(M_WARN, "WARNING: Your certificate has expired!");
     }
 }
+#else
+void
+tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)
+{
+    const X509 *cert;
+    ASSERT(ctx);
+
+    cert = SSL_CTX_get0_certificate(ctx->ctx);
+
+    if (cert == NULL)
+    {
+        return; /* Nothing to check if there is no certificate */
+    }
+
+    X509_VERIFY_PARAM *vpm = X509_VERIFY_PARAM_new();
+
+    if (vpm == NULL)
+    {
+        msg(D_TLS_DEBUG_MED, "Failed to initialise certificate verification parameters.");
+        return;
+    }
+
+    X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_CHECK_TIME);
+    X509_VERIFY_PARAM_set_time(vpm, now);
+
+    int error = 0;
+    int ret = X509_check_certificate_times(vpm, cert, &error);
+    X509_VERIFY_PARAM_free(vpm);
+
+    if (ret == 1)
+    {
+        return;
+    }
+
+    switch (error)
+    {
+        case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+            msg(D_TLS_DEBUG_MED, "Failed to read certificate notBefore field.");
+            break;
+
+        case X509_V_ERR_CERT_NOT_YET_VALID:
+            msg(M_WARN, "WARNING: Your certificate is not yet valid!");
+            break;
+
+        case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+            msg(D_TLS_DEBUG_MED, "Failed to read certificate notAfter field.");
+            break;
+
+        case X509_V_ERR_CERT_HAS_EXPIRED:
+            msg(M_WARN, "WARNING: Your certificate has expired!");
+            break;
+    }
+}
+#endif
 
 void
 tls_ctx_load_dh_params(struct tls_root_ctx *ctx, const char *dh_file, bool dh_file_inline)