diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c
index a7f51751d22..fd2bb2e53ba 100644
--- a/src/openvpn/ssl_verify.c
+++ b/src/openvpn/ssl_verify.c
@@ -431,6 +431,17 @@ verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert,
     return SUCCESS;
 }
 
+static void
+setenv_validity (struct env_set *es, char *envprefix, int depth, char *dt)
+{
+    char varname[32];
+
+    if (!dt[0]) return;
+
+    openvpn_snprintf(varname, sizeof(varname), "%s_%d", envprefix, depth);
+    setenv_str(es, varname, dt);
+}
+
 /*
  * Export the subject, common_name, and raw certificate fields to the
  * environment for later verification by scripts and plugins.
@@ -660,6 +671,8 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
     char common_name[TLS_USERNAME_LEN+1] = {0}; /* null-terminated */
     const struct tls_options *opt;
     struct gc_arena gc = gc_new();
+    char notbefore_buf[32], notafter_buf[32];
+    int notbefore_cmp, notafter_cmp;
 
     opt = session->opt;
     ASSERT(opt);
@@ -754,6 +767,13 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
     /* export current untrusted IP */
     setenv_untrusted(session);
 
+    backend_x509_get_validity(cert, sizeof (notbefore_buf), notbefore_buf, &notbefore_cmp, notafter_buf, &notafter_cmp);
+    setenv_validity (opt->es, "tls_notbefore", cert_depth, notbefore_buf);
+    setenv_validity (opt->es, "tls_notafter",  cert_depth, notafter_buf);
+
+    if (notbefore_cmp < 0) msg(M_WARN, "Certificate notBefore (%s)", notbefore_buf);
+    if (notafter_cmp  > 0) msg(M_WARN, "Certificate notAfter (%s)",  notafter_buf);
+
     /* If this is the peer's own certificate, verify it */
     if (cert_depth == 0 && SUCCESS != verify_peer_cert(opt, cert, subject, common_name))
     {
@@ -793,7 +813,8 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
         }
     }
 
-    msg(D_HANDSHAKE, "VERIFY OK: depth=%d, %s", cert_depth, subject);
+    msg(D_HANDSHAKE, "VERIFY OK: depth=%d, %s, notAfter=%s", cert_depth, subject,
+        (notafter_buf[0] ? notafter_buf : "-"));
     session->verified = true;
     ret = SUCCESS;
 
diff --git a/src/openvpn/ssl_verify_backend.h b/src/openvpn/ssl_verify_backend.h
index d6b31bfa666..51c5d56aa3f 100644
--- a/src/openvpn/ssl_verify_backend.h
+++ b/src/openvpn/ssl_verify_backend.h
@@ -268,4 +268,31 @@ result_t x509_write_pem(FILE *peercert_file, openvpn_x509_cert_t *peercert);
  */
 bool tls_verify_crl_missing(const struct tls_options *opt);
 
+/*
+ * Get certificate notBefore and notAfter attributes
+ *
+ * @param cert          Certificate to retrieve attributes from
+ * @param notsize       Size of char buffers for notbefore and notafter
+ * @param notbefore     Charachter representation of notBefore attribute
+ * @param cmpbefore     Compare notBefore with "now"; > 0 if notBefore in the past
+ * @param notafter      Character representation of notAfter attribute
+ * @param cmpafter      Compare notAfter  with "now"; > 0 if notAfter  in the past
+ *
+ * Not all backend (versions) support the same features (yet), so:
+ *
+ * On failing to retrieve notBefore attributes:
+ *   - notbefore[0] = '\0'
+ *
+ * On failing to retrieve notAfter attributes:
+ *   - notafter[0] = '\0'
+ *
+ * On failing to compare notBefore attributes with "now":
+ *   - cmpbefore    = 0
+ *
+ * On failing to compare notAfter attributes with "now":
+ *   - cmpafter    = 0
+ */
+
+void backend_x509_get_validity(openvpn_x509_cert_t *cert, int notsize, char *notbefore, int *cmpbefore, char *notafter, int *cmpafter);
+
 #endif /* SSL_VERIFY_BACKEND_H_ */
diff --git a/src/openvpn/ssl_verify_mbedtls.c b/src/openvpn/ssl_verify_mbedtls.c
index fd31bbbdaea..342828da195 100644
--- a/src/openvpn/ssl_verify_mbedtls.c
+++ b/src/openvpn/ssl_verify_mbedtls.c
@@ -550,4 +550,14 @@ tls_verify_crl_missing(const struct tls_options *opt)
     return false;
 }
 
+void
+backend_x509_get_validity(mbedtls_x509_crt *cert, int notsize, char *notbefore, int *cmpbefore, char *notafter, int *cmpafter)
+{
+    notbefore[0] = '\0';
+    notafter[0]  = '\0';
+
+    *cmpbefore = 0;
+    *cmpafter  = 0;
+}
+
 #endif /* #if defined(ENABLE_CRYPTO_MBEDTLS) */
diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c
index ff14db23886..7624eacc7e3 100644
--- a/src/openvpn/ssl_verify_openssl.c
+++ b/src/openvpn/ssl_verify_openssl.c
@@ -790,4 +790,39 @@ tls_verify_crl_missing(const struct tls_options *opt)
     return true;
 }
 
+static int
+get_ASN1_TIME(const ASN1_TIME *asn1_time, char *dt, int dtsize, int *cmpnow)
+{
+    BIO *mem;
+    int ret, pday, psec;
+
+    mem = BIO_new(BIO_s_mem());
+    if ((ret = ASN1_TIME_print (mem, asn1_time))) {
+        dt[BIO_read(mem, dt, dtsize-1)] = '\0';
+    }
+    BIO_free(mem);
+    if (!ret) goto fail;
+
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+    if (!ASN1_TIME_diff(&pday, &psec, asn1_time, NULL)) goto fail;
+    *cmpnow = (pday ? pday : psec);
+#else
+    *cmpnow = 0;
+#endif  /* OPENSSL_VERSION_NUMBER >= 1.0.2 */
+
+    return 1;
+
+fail:
+    dt[0] = '\0';
+    *cmpnow = 0;
+    return 0;
+}
+
+void
+backend_x509_get_validity(X509 *cert, int notsize, char *notbefore, int *cmpbefore, char *notafter, int *cmpafter)
+{
+    get_ASN1_TIME(X509_get_notBefore(cert), notbefore, notsize, cmpbefore);
+    get_ASN1_TIME(X509_get_notAfter(cert),  notafter,  notsize, cmpafter);
+}
+
 #endif /* defined(ENABLE_CRYPTO_OPENSSL) */