Skip to content

Client certificate example is misleading #1178

@kleinesfilmroellchen

Description

@kleinesfilmroellchen

The client certificate example shows how to gain access to TLS client certificate data and how to pass this data into higher-level handlers. However, the code that extracts the certificate is misleading at best:

if let Some(certs) = tls_session.peer_certificates() {
info!("client certificate found");
// insert a `rustls::Certificate` into request data
data.insert(certs.last().unwrap().clone());

peer_certificates says:

The order of the certificate chain is as it appears in the TLS protocol: the first certificate relates to the peer, the second certifies the first, the third certifies the second, and so on.

As we are using last on the certificate chain, this means we’ll insert the root CA certificate, or some parent certificate, into the request data. When using the curl example command line from the example, this is exactly what happens. I’ve also tested it with OpenSSL, generating a local CA and certificates signed by it. (mkcert doesn’t add SAN to client certificates, which is why I can’t use it in the first place. I didn’t get around to testing this with a production Letsencrypt certificate, which can be used as a client certificate too.)

This certificate is valid, but in many cases it doesn’t relate to the client at all. As the text above clearly says (and as the TLS spec will say), the first certificate is always the one that actually relates to the client, and the one most applications will want to inspect.

I suggest changing the example to call first() instead, which is what users will likely want to do in practice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions