On 01-12-16 11:41, Antonio Quartulli wrote:
> 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>
> ---
> 
> Changes since v2:
> - print warning if stat() on CRL fails
> - abort CRL (re)load if stat() fails
> 
> Changes since v1:
> - move tls_ctx_reload_crl() before any invocation
> - add doxygen-doc for tls_ctx_reload_crl()
> - add check against CRL size file
> - simplify tls_ctx_reload_crl() by removing reload argument
> 
>  src/openvpn/ssl.c         | 53 
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  src/openvpn/ssl_backend.h |  2 +-
>  src/openvpn/ssl_mbedtls.c |  2 +-
>  src/openvpn/ssl_mbedtls.h |  2 ++
>  src/openvpn/ssl_openssl.c |  2 +-
>  src/openvpn/ssl_openssl.h |  2 ++
>  6 files changed, 59 insertions(+), 4 deletions(-)
> 
> diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
> index 7347a78..ec0a189 100644
> --- a/src/openvpn/ssl.c
> +++ b/src/openvpn/ssl.c
> @@ -512,6 +512,54 @@ tls_version_parse(const char *vstr, const char *extra)
>      return TLS_VER_BAD;
>  }
>  
> +/**
> + * Load (or possibly reload) the CRL file into the SSL context.
> + * No reload is performed under the following conditions:
> + * - the CRL file was passed inline
> + * - the CRL file was not modified since the last (re)load
> + *
> + * @param ssl_ctx       The TLS context to use when reloading the CRL
> + * @param crl_file      The file name to load the CRL from, or
> + *                      "[[INLINE]]" in the case of inline files.
> + * @param crl_inline    A string containing the CRL
> + */
> +static void
> +tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file,
> +                const char *crl_file_inline)
> +{
> +  /* 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.
> +   * Use always '1' as dummy timestamp in this case: it will trigger the
> +   * first load, but will prevent any future reload.
> +   */
> +  if (crl_file_inline)
> +    {
> +      crl_stat.st_mtime = 1;
> +    }
> +  else if (platform_stat(crl_file, &crl_stat) < 0)
> +    {
> +      msg(M_WARN, "WARNING: Failed to stat CRL file, not (re)loading CRL.");
> +      return;
> +    }
> +
> +  /*
> +   * Store the CRL if this is the first time or if the file was changed since
> +   * the last load.
> +   * Note: Windows does not support tv_nsec.
> +   */
> +  if ((ssl_ctx->crl_last_size == crl_stat.st_size) &&
> +      (ssl_ctx->crl_last_mtime.tv_sec == crl_stat.st_mtime))
> +    return;
> +
> +  ssl_ctx->crl_last_mtime.tv_sec = crl_stat.st_mtime;
> +  ssl_ctx->crl_last_size = crl_stat.st_size;
> +  backend_tls_ctx_reload_crl(ssl_ctx, crl_file, crl_file_inline);
> +}
> +
>  /*
>   * Initialize SSL context.
>   * All files are in PEM format.
> @@ -2581,7 +2629,10 @@ 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))
>           {
> 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..a4a7f05 100644
> --- a/src/openvpn/ssl_mbedtls.h
> +++ b/src/openvpn/ssl_mbedtls.h
> @@ -74,6 +74,8 @@ 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 */
> +    off_t crl_last_size;             /**< size of last loaded CRL */
>  #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..115ac43 100644
> --- a/src/openvpn/ssl_openssl.h
> +++ b/src/openvpn/ssl_openssl.h
> @@ -49,6 +49,8 @@
>   */
>  struct tls_root_ctx {
>      SSL_CTX *ctx;
> +    struct timespec crl_last_mtime;
> +    off_t crl_last_size;
>  };
>  
>  struct key_state_ssl {
> 

Looks good now, thanks!

ACK

-Steffan

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

Reply via email to