[PATCH] Add provision to fetch certificate chain from Nginx
Maxim Dounin
mdounin at mdounin.ru
Sun Jan 30 23:55:09 UTC 2022
Hello!
On Sat, Jan 29, 2022 at 01:50:24PM +0000, CHHABRA Mandeep Singh via nginx-devel wrote:
> > Sure, intermediate certificates are not required to be known
> > by the server and can be provided by the client in the extra
> > certificates during SSL/TLS handshake.
>
> I am not sure what you mean by passing the intermediate CAs in
> the extra certificates. They are CA certificates and are passed
> as CA certificate chain. For example: curl has option --cacert
> which can take the entire chain of CA certificates (from
> immediate issuer to the trust anchor)
> # curl --cacert
The "extra" is as in SSL_CTX_add_extra_chain_cert, see
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_add_extra_chain_cert.html.
During SSL/TLS handshake client sends the list of certificates to
the server. The certificate list is expected to contain the
client certificate itself, followed by optional/extra additional
certificates (usually not including the root, since including it
is just a waste of resources). It is defined by TLSv1.2
sepecification as follows
(https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.2):
certificate_list
This is a sequence (chain) of certificates. The sender's
certificate MUST come first in the list. Each following
certificate MUST directly certify the one preceding it. Because
certificate validation requires that root keys be distributed
independently, the self-signed certificate that specifies the root
certificate authority MAY be omitted from the chain, under the
assumption that the remote end must already possess it in order to
validate it in any case.
Note that the certificate list is used for both server and client
certificates. As previously suggested, it is believed that client
certificates are almost always used without any additional
intermediate certificates being sent by the client.
> > Further, it is not really possible to properly retrieve such
> > client-provided intermediate certificates after the initial
> > handshake: these certificates are not saved to the session
> > data and therefore not available after session reuse, see
> > 7653:8409f9df6219
> > (http://hg.nginx.org/nginx/rev/8409f9df6219).
>
> AFAIU, intermediate CA certificates are not supposed to be known
> by Nginx anyway. I am not sure if we are referring to
> two different things here. But with the changes which I
> proposed, I am able to retrieve the entire chain from Nginx(also
> in cases
> when intermediate CAs are not known to the server). During
> certificate verification, Nginx creates a verified chain from
> the incoming certificate chain and the CA certificate which is
> trusted on the web interface. Nginx only needs to know about the
> trust anchor (the self signed CA certificate)
Try to retrieve the entire chain in a connection which is using an
abbreviated handshake, not an initial one.
The information about intermediate certificates which are not
known on the server is not preserved by OpenSSL in the session
data. As such, it is not possible to re-create the certificate
chain in the connection using abbreviated handshake.
This is explicitly documented in the man page of the
SSL_get0_verified_chain() function you are using, see
https://www.openssl.org/docs/man1.1.1/man3/SSL_get0_verified_chain.html:
: If the session is resumed peers do not send certificates so a NULL
: pointer is returned by these functions.
The client certificate itself is preserved in the session data, so
it is available after session resumption. This makes it possible
to re-create the certificate chain if no client-provided
certificates are used, see the 7653:8409f9df6219 change mentioned
above.
Hope this helps.
> > And you want to allow access only to certificates signed by
> > Intermediate1 CA in some cases, and only certificates signed by
> > Intermediate2 CA in other cases. Is that correct?
>
> You are correct partially. Yes, we need to allow/deny a configuration based on the configuration available for the CA.
> There could be different combinations with the chain here
> 1- Cert-> Intermediate1 -> Root
> 2- Cert-> Intermediate2 -> Root
> 3- Cert-> Root
> 4- Cert-> Intermediate1 -> Intermediate2 -> Root
>
> For example:-
> Consider the chain "Cert-> Intermediate1 -> Intermediate2 -> Root"
> We need to something based on Intermediate2's configuration and it is possible that the
> Intermediate1 is not known to the server.
As previously suggested, while technically it is possible, it is
usually indicate that it might be a good idea to reconsider the
configuration and make sure that all intermediate certificates are
known on the server.
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx-devel
mailing list