Hi,

On 02/04/2020 12:38, Arne Schwabe wrote:
> Commit f67efa94 exposed that tls_ctx_add_extra_certs will always leave
> an error of PEM_R_NO_START_LINE on the stack that will printed the next
> time that the error is printed.
> 
> Fix this by discarding this error. Also clean up the logic to report
> real error on other errors and also the no start line error if no
> certificate can be found at all and it is required (--extra-certs
> config option)
> 
> Patch V2: fix optional flag was flipped betwen --cert and --extra-certs
> Patch V3: Make logic more easy to follow, no functional changes
> 
> Signed-off-by: Arne Schwabe <a...@rfc2549.org>
> ---
>  src/openvpn/ssl_openssl.c | 30 +++++++++++++++++++++---------
>  1 file changed, 21 insertions(+), 9 deletions(-)
> 
> diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
> index 3f0031ff..1731474d 100644
> --- a/src/openvpn/ssl_openssl.c
> +++ b/src/openvpn/ssl_openssl.c
> @@ -881,24 +881,36 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const 
> char *cryptoapi_cert)
>  #endif /* ENABLE_CRYPTOAPI */
>  
>  static void
> -tls_ctx_add_extra_certs(struct tls_root_ctx *ctx, BIO *bio)
> +tls_ctx_add_extra_certs(struct tls_root_ctx *ctx, BIO *bio, bool optional)
>  {
>      X509 *cert;
> -    for (;; )
> +    while (true)
>      {
>          cert = NULL;
> -        if (!PEM_read_bio_X509(bio, &cert, NULL, NULL)) /* takes ownership 
> of cert */
> -        {
> -            break;
> -        }
> -        if (!cert)
> +        if (!PEM_read_bio_X509(bio, &cert, NULL, NULL))
>          {
> +            /*  Error indicates that no certificate is found in the buffer.

I would substitute "Error" with "PEM_R_NO_START_LINE" for clarity

> +             *  If loading more certificates is optional, break without
> +             *  raising an error */
> +

This empty line should be removed

> +            if (optional
> +                && ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
> +            {
> +                /* remove that error from error stack */
> +                (void)ERR_get_error();
> +                break;
> +            }
> +
> +            /* Otherwise, bail out with error */
>              crypto_msg(M_FATAL, "Error reading extra certificate");
>          }
> +        /* takes ownership of cert like a set1 method */
>          if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1)
>          {
>              crypto_msg(M_FATAL, "Error adding extra certificate");
>          }
> +        /* We loaded at least one certificate, so loading more is optional */
> +        optional = true;
>      }
>  }
>  
> @@ -942,7 +954,7 @@ tls_ctx_load_cert_file(struct tls_root_ctx *ctx, const 
> char *cert_file,
>      ret = SSL_CTX_use_certificate(ctx->ctx, x);
>      if (ret)
>      {
> -        tls_ctx_add_extra_certs(ctx, in);
> +        tls_ctx_add_extra_certs(ctx, in, true);
>      }
>  
>  end:
> @@ -1663,7 +1675,7 @@ tls_ctx_load_extra_certs(struct tls_root_ctx *ctx, 
> const char *extra_certs_file,
>      }
>      else
>      {
> -        tls_ctx_add_extra_certs(ctx, in);
> +        tls_ctx_add_extra_certs(ctx, in, false);
>      }
>  
>      BIO_free(in);
> 


The rest looks good!

I reviewed the code and tested it with different combinations of files
provided to --cert and --extra-certs.

It all works as expected:
- an empty extra-certs file leads to a critical failure with an OpenSSL
error printed to screen;
- empty cert file leads to the same as above;
- proper cert and extra-certs files result to no error printed to screen
and everything works


Acked-by: Antonio Quartulli <a...@unstable.cc>


Cheers,

-- 
Antonio Quartulli


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

Reply via email to