rustls / rustls-platform-verifier

A certificate verification library for rustls that uses the operating system's verifier
Apache License 2.0
66 stars 20 forks source link

Linux: System CA bundle watcher #60

Open daxpedda opened 9 months ago

daxpedda commented 9 months ago

Currently there is no way to reload the system CA bundle on Linux. This is different to other platforms, which use a system API and can therefor detect certificate changes dynamically.

The main motivation here, aside from platform parity, is to not having to restart applications or require more complicated setups to account for this issue. E.g. this was a problem in https://github.com/hickory-dns/hickory-dns/issues/2038.

Is it an option to implement a directory/file watcher to account for that on Linux? As this isn't really supported in rustls-native-certs, it would require using openssl-probe directly to get the paths instead of only getting the certificates.

complexspaces commented 9 months ago

This seems like a reasonable ask. The parts of lib.rs we need and the UNIX implementation of rustls-native-certs is somewhere around ~40 lines of simple code, and most of that comes from needing to respect the SSL_CERT_FILE environment variable. This would also further the minor goal of soft deprecating rustls-native-certs for most users.

Do you think an opt-in feature flag to bring in notify for this could work in your example cases? notify seems a bit heavy to make it a default.

djc commented 9 months ago

Maybe just polling every 5 minutes or so would be good enough?

daxpedda commented 8 months ago

Do you think an opt-in feature flag to bring in notify for this could work in your example cases? notify seems a bit heavy to make it a default.

I looked into notify and I think there could be some work done to reduce the amount of dependencies, but ultimately I still think it would be too heavy for rustls-native-certs, e.g. mio couldn't really be removed).

I think putting it behind a feature flag would be nice.

Maybe just polling every 5 minutes or so would be good enough?

I don't know, but I think a (platform-specific ?) method to update the files would already go some length to alleviate the issue.

complexspaces commented 8 months ago

We already have platform-specific APIs for UNIX, so this wouldn't be a stretch. We could provide an API to

  1. Refresh on-disk certificates
  2. Enable background polling every few (5) minutes, which calls the same refresh function already exposed.

The part I haven't figured out yet is how we change out the certificates after the verifier has been built. The verifier itself needs to be inside an Arc to work with the rustls APIs and ServerCertVerifier doesn't provide any APIs for in-place root modification. So we would need to Mutex the inner store in order to support replacing it. That increases the cost of verifying on the happy path and removes any possible concurrency because the whole verifier will be blocked on.

djc commented 8 months ago

Use an RwLock instead? Then we can do verification concurrently and we can quickly lock the RwLock after the polling task has parsed a fresh set of roots. The write lock should be held for a pretty short while.

Ralith commented 7 months ago

There's also arc_swap.