Crate rustls_pin

Source
Expand description

crates.io version license: Apache 2.0 unsafe forbidden pipeline status

§rustls-pin

Server certificate pinning with rustls.

§Features

  • Make a TLS connection to a server
  • Check that the server is using an allowed certificate
  • forbid(unsafe_code)
  • 100% test coverage

§How to Update Pinned Certificates

Before switching the server to a new certificate, you need to upgrade the clients to accept both the current certificate and the new one.

If your users update their client software infrequently, you may need to wait a long time before switching to a new certificate.

You can change certificates frequently by having multiple pending ā€˜new’ certificates. Example:

  • Server: cert1
  • Client v1: cert1
  • Client v2: cert1, cert2
  • Client v3: cert1, cert2, cert3
  • Server: cert2
  • Client v4: cert2, cert3, cert4
  • Server: cert3
  • Client v5: cert3, cert4, cert5
  • Server cert4

§Example

let mut stream = rustls_pin::connect_pinned(
    addr,
    vec![server_cert1, server_cert2],
).unwrap();
let mut response = String::new();
match std::io::Read::read_to_string(
    &mut stream, &mut response) {
    Ok(_) => {},
    Err(e) if &e.to_string() ==
        "invalid certificate: UnknownIssuer"
     => panic!("Update required."),
    Err(e) => {
        // panic!("{}", e)
    }
}

When the client software reads/writes the stream and gets an invalid certificate: UnknownIssuer error, it can assume that it is outdated. It can tell the user to update.

The rustls client terminates the TLS connection by sending the ā€˜bad certificate’ reason to the server. The server’s stream read/write fails with: "Custom { kind: InvalidData, error: AlertReceived(BadCertificate) }".

§Alternatives

§Changelog

  • v0.1.2
    • Add ā€œHow to Update Pinned Certificatesā€ to docs.
    • Add error handling to example
  • v0.1.1 - Increase test coverage
  • v0.1.0 - Initial version

§Happy Contributors šŸ™‚

Fixing bugs and adding features is easy and fast. Send us a pull request and we intend to:

  • Always respond within 24 hours
  • Provide clear & concrete feedback
  • Immediately make a new release for your accepted change

Structs§

PinnedServerCertVerifier
A struct for TLS clients to verify the server’s certificate. Implements certificate pinning. It accepts the server’s certificate if it is identical to any of the certificates in the struct.

Functions§

arbitrary_dns_name
An arbitrary DNSName struct, for passing to rustls::ClientSession::new. PinnedServerCertVerifier receives the value and ignores it.
connect_pinned
Make a TCP connection to addr and set up a TLS session.