From dfd940bb008feb2fe981ceab3ed66fdb3cf21bdb Mon Sep 17 00:00:00 2001 From: Steffan Karger Date: Sat, 19 Dec 2015 12:39:29 +0100 Subject: [PATCH] Warn user if their certificate has expired Previously, client certificate expiry warnings would only visible in the server log, and server certificate expiry warnings in the client log. Both after a (failed) connection attempt. This patch adds a warning to log when a users own certificate has expired (or is not yet valid) to ease problem diagnosis / error reporting. Note that this is just a warning, since on some systems (notably embedded devices) there might be no correct time available. The SSL_CTX_get0_certificate() function is available in OpenSSL 1.0.2+ only. Older versions seem to not have a useful alternative, and the certificate reference we need is hidden in an opaque struct. The remaining option would then be to add extra workaround code for the select group of people that do use an up-to-date openvpn, but do not update their openssl. I don't think that's worth it. So just disable the code for older openssl versions. (This is a combination of commits 091edd8e and 644f2cdd from the master branch, adjusted to apply to the release/2.3 branch cleanly) Signed-off-by: Steffan Karger Acked-by: Gert Doering Message-Id: <1450525169-12961-2-git-send-email-steffan@karger.me> URL: http://article.gmane.org/gmane.network.openvpn.devel/10855 Signed-off-by: Gert Doering --- src/openvpn/ssl.c | 3 +++ src/openvpn/ssl_backend.h | 9 +++++++++ src/openvpn/ssl_openssl.c | 29 +++++++++++++++++++++++++++++ src/openvpn/ssl_polarssl.c | 14 ++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 202a03fea..f728ffb88 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -556,6 +556,9 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_load_extra_certs(new_ctx, options->extra_certs_file, options->extra_certs_file_inline); } + /* Check certificate notBefore and notAfter */ + tls_ctx_check_cert_time(new_ctx); + /* Allowable ciphers */ if (options->cipher_list) { diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h index 6d47bd044..4b35e5149 100644 --- a/src/openvpn/ssl_backend.h +++ b/src/openvpn/ssl_backend.h @@ -175,6 +175,15 @@ void tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags); */ void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers); +/** + * Check our certificate notBefore and notAfter fields, and warn if the cert is + * either not yet valid or has expired. Note that this is a non-fatal error, + * since we compare against the system time, which might be incorrect. + * + * @param ctx TLS context to get our certificate from. + */ +void tls_ctx_check_cert_time (const struct tls_root_ctx *ctx); + /** * Load Diffie Hellman Parameters, and load them into the library-specific * TLS context. diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index be33caa23..13cce5e27 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -334,6 +334,35 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", openssl_ciphers); } +void +tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + int ret; + const X509 *cert = SSL_CTX_get0_certificate(ctx->ctx); + + ret = X509_cmp_time (X509_get_notBefore (cert), NULL); + if (ret == 0) + { + msg (D_TLS_DEBUG_MED, "Failed to read certificate notBefore field."); + } + if (ret > 0) + { + msg (M_WARN, "WARNING: Your certificate is not yet valid!"); + } + + ret = X509_cmp_time (X509_get_notAfter (cert), NULL); + if (ret == 0) + { + msg (D_TLS_DEBUG_MED, "Failed to read certificate notAfter field."); + } + if (ret < 0) + { + msg (M_WARN, "WARNING: Your certificate has expired!"); + } +#endif +} + void tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, const char *dh_file_inline diff --git a/src/openvpn/ssl_polarssl.c b/src/openvpn/ssl_polarssl.c index 8d9d219fa..def397da6 100644 --- a/src/openvpn/ssl_polarssl.c +++ b/src/openvpn/ssl_polarssl.c @@ -204,6 +204,20 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) free(tmp_ciphers_orig); } +void +tls_ctx_check_cert_time (const struct tls_root_ctx *ctx) +{ + if (x509_time_future (&ctx->crt_chain->valid_from)) + { + msg (M_WARN, "WARNING: Your certificate is not yet valid!"); + } + + if (x509_time_expired (&ctx->crt_chain->valid_to)) + { + msg (M_WARN, "WARNING: Your certificate has expired!"); + } +} + void tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file, const char *dh_inline -- 2.47.2