1) I would also check if the file size was changed, not only mtime.

2) I wasn't digging the code deeply, but the
> ssl_ctx->crl_last_mtime.tv_sec >= crl_stat.st_mtime
makes me think it would fail if the file goes reverted to a previous version. 
Perhaps the check shall be != instead of >=.


> In order to prevent annoying delays upon client connection,
> reload the CRL file only if it was modified since the last
> reload operation.
> If not, keep on using the already stored CRL.
> 
> This change will boost client connection time in instances
> where the CRL file is quite large (dropping from several
> seconds to few milliseconds).
> 
> Cc: Steffan Karger <steffan.kar...@fox-it.com>
> Signed-off-by: Antonio Quartulli <a...@unstable.cc>
> ---
> 
> Tested on linux by using my VM.
> No test was performed on Windows* (compiled-only).
> 
> Note: the check "!(session->opt->ssl_flags & SSLF_CRL_VERIFY_DIR))" may not
> always work as expected. The user may forge a wrong, but still compliant,
> configuration that would fool this test. This issue exists even before
> applying
> this patch.
> 
> Cheers,
> 
>  src/openvpn/ssl.c         | 40 +++++++++++++++++++++++++++++++++++++---
>  src/openvpn/ssl_backend.h |  2 +-
>  src/openvpn/ssl_mbedtls.c |  2 +-
>  src/openvpn/ssl_mbedtls.h |  1 +
>  src/openvpn/ssl_openssl.c |  2 +-
>  src/openvpn/ssl_openssl.h |  1 +
>  6 files changed, 42 insertions(+), 6 deletions(-)
> 
> diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
> index 7347a78..235f7df 100644
> --- a/src/openvpn/ssl.c
> +++ b/src/openvpn/ssl.c
> @@ -612,7 +612,8 @@ init_ssl (const struct options *options, struct
> tls_root_ctx *new_ctx)
>    /* Read CRL */
>    if (options->crl_file && !(options->ssl_flags & SSLF_CRL_VERIFY_DIR))
>      {
> -      tls_ctx_reload_crl(new_ctx, options->crl_file,
> options->crl_file_inline);
> +      tls_ctx_reload_crl(new_ctx, options->crl_file,
> options->crl_file_inline,
> +                      false);
>      }
>  
>    /* Once keys and cert are loaded, load ECDH parameters */
> @@ -2450,6 +2451,36 @@ auth_deferred_expire_window (const struct tls_options
> *o)
>    return ret;
>  }
>  
> +void
> +tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file,
> +                const char *crl_file_inline, bool reload)
> +{
> +  /* if something goes wrong with stat(), we'll store 0 as mtime */
> +  platform_stat_t crl_stat = {0};
> +
> +  /*
> +   * an inline CRL can't change at runtime, therefore there is no need to
> +   * reload it. It will be reloaded upon config change + SIGHUP.
> +   */
> +  if (crl_file_inline && reload)
> +    return;
> +
> +  if (!crl_file_inline)
> +    platform_stat(crl_file, &crl_stat);
> +
> +  /*
> +   * If this is not a reload, update the CRL right away.
> +   * Otherwise, update only if the CRL file was modified after the last
> reload.
> +   * Note: Windows does not support tv_nsec.
> +   */
> +  if (reload &&
> +      (ssl_ctx->crl_last_mtime.tv_sec >= crl_stat.st_mtime))
> +    return;
> +
> +  ssl_ctx->crl_last_mtime.tv_sec = crl_stat.st_mtime;
> +  backend_tls_ctx_reload_crl(ssl_ctx, crl_file, crl_file_inline);
> +}
> +
>  /*
>   * This is the primary routine for processing TLS stuff inside the
>   * the main event loop.  When this routine exits
> @@ -2581,12 +2612,15 @@ tls_process (struct tls_multi *multi,
>         ks->state = S_START;
>         state_change = true;
>  
> -       /* Reload the CRL before TLS negotiation */
> +       /*
> +        * Attempt CRL reload before TLS negotiation. Won't be performed if
> +        * the file was not modified since the last reload
> +        */
>         if (session->opt->crl_file &&
>             !(session->opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
>           {
>             tls_ctx_reload_crl(&session->opt->ssl_ctx,
> -               session->opt->crl_file, session->opt->crl_file_inline);
> +               session->opt->crl_file, session->opt->crl_file_inline, true);
>           }
>  
>         dmsg (D_TLS_DEBUG_MED, "STATE S_START");
> diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h
> index 0777c61..3fbd2b4 100644
> --- a/src/openvpn/ssl_backend.h
> +++ b/src/openvpn/ssl_backend.h
> @@ -353,7 +353,7 @@ void key_state_ssl_free(struct key_state_ssl *ks_ssl);
>   *                      "[[INLINE]]" in the case of inline files.
>   * @param crl_inline    A string containing the CRL
>   */
> -void tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx,
> +void backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx,
>      const char *crl_file, const char *crl_inline);
>  
>  /**
> diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c
> index 7fa35a7..11ee65b 100644
> --- a/src/openvpn/ssl_mbedtls.c
> +++ b/src/openvpn/ssl_mbedtls.c
> @@ -771,7 +771,7 @@ static void tls_version_to_major_minor(int tls_ver, int
> *major, int *minor) {
>  }
>  
>  void
> -tls_ctx_reload_crl(struct tls_root_ctx *ctx, const char *crl_file,
> +backend_tls_ctx_reload_crl(struct tls_root_ctx *ctx, const char *crl_file,
>      const char *crl_inline)
>  {
>    ASSERT (crl_file);
> diff --git a/src/openvpn/ssl_mbedtls.h b/src/openvpn/ssl_mbedtls.h
> index 3edeedc..911f3c7 100644
> --- a/src/openvpn/ssl_mbedtls.h
> +++ b/src/openvpn/ssl_mbedtls.h
> @@ -74,6 +74,7 @@ struct tls_root_ctx {
>      mbedtls_x509_crt *ca_chain;              /**< CA chain for remote 
> verification */
>      mbedtls_pk_context *priv_key;    /**< Local private key */
>      mbedtls_x509_crl *crl;              /**< Certificate Revocation List */
> +    struct timespec crl_last_mtime;     /**< CRL last modification time */
>  #if defined(ENABLE_PKCS11)
>      mbedtls_pkcs11_context *priv_key_pkcs11; /**< PKCS11 private key */
>  #endif
> diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
> index 51669fc..4f472ff 100644
> --- a/src/openvpn/ssl_openssl.c
> +++ b/src/openvpn/ssl_openssl.c
> @@ -772,7 +772,7 @@ end:
>  }
>  
>  void
> -tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file,
> +backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char
> *crl_file,
>          const char *crl_inline)
>  {
>    X509_CRL *crl = NULL;
> diff --git a/src/openvpn/ssl_openssl.h b/src/openvpn/ssl_openssl.h
> index 97dc742..e0be660 100644
> --- a/src/openvpn/ssl_openssl.h
> +++ b/src/openvpn/ssl_openssl.h
> @@ -49,6 +49,7 @@
>   */
>  struct tls_root_ctx {
>      SSL_CTX *ctx;
> +    struct timespec crl_last_mtime;
>  };
>  
>  struct key_state_ssl {
> -- 
> 2.11.0.rc2
> 
> 
> ------------------------------------------------------------------------------
> _______________________________________________
> Openvpn-devel mailing list
> Openvpn-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openvpn-devel
> 


-- 
Svjatoslav Mikhailov
------------------------------------------------------------------------------
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to