Does ssl_trusted_certificate actually send certs to client?

Hi all,
I have an Nginx 1.7.6 server serving HTTPS content, and I’ve been
tweaking the configuration lately to ensure it is secure and
performant[1].

One component of this is ensuring that the intermediate certificate from
my CA is sent along to any clients connecting to my server, to ensure
they don’t have to fetch it from somewhere else and risk at best a
longer connection time, and at worst some sort of (unlikely) tampering.

The traditional way to do this, as far as I’m aware, is to concatenate
any intermediate certs, as well as the actual certificate for your
domain, into one file, and then tell Nginx about it using the
ssl_client_certificate directive. This works great, but I wanted to see
if there was a way to keep the different certificates in different
files, just for clarity and ease of maintenance. I put the intermediate
cert in another file and told Nginx about it with the
ssl_trusted_certificate directive, and everything worked great!

However, the docs[2] for ssl_trusted_certificate specifically state the
following:

In contrast to the certificate set by ssl_client_certificate, the list
of these certificates will not be sent to clients.

This seems to be at odds with what I’m experiencing. At first I thought
it was possible that the certificate was sent because I had ssl_stapling
set to on, to ensure OCSP responses are also included, but turning that
option off still sends the intermediate cert when new connections are
being initialized. Only removing the ssl_trusted_certificate line from
my config causes the SSL Test to show that not all intermediate certs
are sent.

A nearly un-modified copy of my configs can be found on Github[3], and I
would very much like to know if my configuration is working because I am
misunderstanding something (by far the most likely), because the docs
are
wrong, because there is a bug in Nginx, or something else.

Thanks,
Julian

[1] Mostly by following the SSL Labs Server Test

[2]
http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate
[3] https://github.com/orangejulius/https-on-nginx/blob/master/ssl.conf
and
https://github.com/orangejulius/https-on-nginx/blob/master/example-site.conf

Hello!

On Thu, Feb 12, 2015 at 11:02:34AM +0100, Julian Simioni wrote:

The traditional way to do this, as far as I’m aware, is to concatenate
any intermediate certs, as well as the actual certificate for your
domain, into one file, and then tell Nginx about it using the
ssl_client_certificate directive. This works great, but I wanted to see
if there was a way to keep the different certificates in different
files, just for clarity and ease of maintenance. I put the intermediate
cert in another file and told Nginx about it with the
ssl_trusted_certificate directive, and everything worked great!

Both ssl_client_certificate and ssl_trusted_certificate will load
certificates to the trusted store, and OpenSSL will use these
certs to build the certificate chain at runtime if one wasn’t
explicitly provided.

That is, it’s a [mis]feature of the OpenSSL library which leads to
such behaviour.

While one can use this to construct certificate chains as of now,
it’s not a recommended approach because:

  • this consumes more CPU power, as the chain will be constructed
    at runtime;

  • this is not something we (at least I) consider to be a good
    feature, and if/when it will be possible to stop OpenSSL from
    doing this - we’ll do so.

However, the docs[2] for ssl_trusted_certificate specifically state the
following:

In contrast to the certificate set by ssl_client_certificate, the list
of these certificates will not be sent to clients.

This note is not about certificate chain sent to the client, but
about the list of certificates sent to clients while requesting
client certificates. See RFC5246, 7.4.4. Certificate Request,
RFC 5246 - The Transport Layer Security (TLS) Protocol Version 1.2 - the list is
sent in the certificate_authorities field of the Certificate
Request message to let clients know which authorities are accepted
by the server.


Maxim D.
http://nginx.org/

Hi
I’m facing this problem as well, though in a different context: OCSP
stapling. Everything looks good without OCSP stapling: my
ssl_certificate
file contain my domain (wildcard) cert from AlphaSSL, that doesn’t
require
any intermediate cert, so the domain cert is the only one in that file.

However to enable OCSP stapling, I have to specify the full cert chain
in
ssl_trusted_certificate. I do this by including first GlobalSign root,
then
alpha SSL intermediate. This works fine, and OCSP stapling is operating
normally.

But as a side effect, now clients also receives the full chain of
certificates. I think, from your response above, that openssl auto chain
building is responsible for that (you also made the same reply in
Re: OCSP, ssl_trusted_certificate, and ssl_stapling_verify)

1 - You say: “It shouldn’t happen as long as there is at least one
intermediate cert in ssl_certificate file”. That’s precisely what I want
to
avoid, include the while chain in the ssl_certificate file. Only adding
alphassl intermediate cert in ssl_certificate (ie NO adding GlobalSign
root
cert) results in an error #20)

2 - Googling a bit more, and totally shooting in the dark here, I also
found
that Openssl has an SSL_MODE_NO_AUTO_CHAIN flag that “…Allow an
application to disable the automatic SSL chain building…”. Isn’t it
something you could use to disable the auto chain building? (originated
from
http://t93518.encryption-openssl-development.encryptiontalk.info/ssl-server-root-certs-and-client-auth-t93518.html
I think)

Thanks for any input anyway!

Cheers

Posted at Nginx Forum:

Hello!

On Sun, Mar 01, 2015 at 07:05:43AM -0500, shumisha wrote:

2 - Googling a bit more, and totally shooting in the dark here, I also found
that Openssl has an SSL_MODE_NO_AUTO_CHAIN flag that “…Allow an
application to disable the automatic SSL chain building…”. Isn’t it
something you could use to disable the auto chain building? (originated from

http://t93518.encryption-openssl-development.encryptiontalk.info/ssl-server-root-certs-and-client-auth-t93518.html

I think)

Thanks for any input anyway!

Thanks, this looks like correct flag to use. Try the following
patch:

— a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -277,6 +277,10 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_
SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
#endif

+#ifdef SSL_MODE_NO_AUTO_CHAIN

  • SSL_CTX_set_mode(ssl->ctx, SSL_MODE_NO_AUTO_CHAIN);
    +#endif

  • SSL_CTX_set_read_ahead(ssl->ctx, 1);

    SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);


Maxim D.
http://nginx.org/

Hi Maxim,

Just did that and work fine for me! The warning “chain contains anchor”
is
gone from qualys ssl test page, while OCSP stapling is on, as well as
ssl_stapling_verify.

Side note: after applying this patch, I realized my config was actually
wrong: the ssl_certificate file was indeed lacking my ssl cert provider
intermediate cert and the trust chain verification started to fail.
Previously, this error was masked by openssl auto building the trust
chain
using alphaSSL intermediate found in ssl_trsuted_certificate.

Also, I applied the patch to nginx 1.6.2, which I’m using.

Assuming this needs more testing, hope it can make it into an upcoming
release.

Thanks

Posted at Nginx Forum: