sfackler / rust-native-tls

Apache License 2.0
468 stars 197 forks source link

Option to disable certificate CA verification #277

Open slondr opened 11 months ago

slondr commented 11 months ago

Right now it seems like the only way with native_tls to accept self-signed certificates is to disable all certificate validation with the danger_accept_invalid_certs function. This is way, way, way more permissive than I would like my application to be, but currently native_tls has no more granular options to permit self-signed certs but reject certs for any other validity issue.

sfackler commented 11 months ago

If you don't validate that a certificate was issued by a trusted root, then other validity issues aren't really relevant - an attacker can trivially make a self signed cert that is otherwise valid.

slondr commented 11 months ago

That is true, but I am much less concerned about attackers and much more concerned about enabling users to let server operators know when they have misconfigured their servers, such as by serving an expired certificate. Expiry dates have meaning to certificate creators, otherwise they wouldn't set them or they'd set them to year 9999 or something like that, and I'd like to preserve that as much as I can.

sfackler commented 11 months ago

If users care that much, why wouldn't they be able to have the appropriate root CAs loaded?

slondr commented 11 months ago

Because, in this case, they're using a TLS-based protocol which explicitly recommends not using CA-signed certificates.

sfackler commented 11 months ago

I would be very surprised that a standard would specify the use of TLS without authenticity - almost all of TLS's security properties are lost in that case.

I don't think I have ever seen a case where code wanted to validate certificates without checking CA trust, or if that is even possible to do in the TLS backends this crate wraps.

slondr commented 11 months ago

I would be very surprised that a standard would specify the use of TLS without authenticity - almost all of TLS's security properties are lost in that case.

https://gemini.circumlunar.space/docs/specification.gmi Section 4.2 "Server certificate verification" specifies:

Clients can validate TLS connections however they like (including not at all) but the strongly RECOMMENDED approach is to implement a lightweight "TOFU" certificate-pinning system which treats self-signed certificates as first- class citizens. This greatly reduces TLS overhead on the network (only one cert needs to be sent, not a whole chain) and lowers the barrier to entry for setting up a Gemini site (no need to pay a CA or setup a Let's Encrypt cron job, just make a cert and go).

And then goes on to explain that decision.

There are a large number of client and server implementations of this which works fine. I'm in the process of building my own, hence my query.

Just to be clear, if supporting use cases such as this one isn't something you envision for this library, that's fine! I found native_tls to have the nicest API of the various Rust TLS crates, but I can use a different one if native_tls isn't the right choice for the semantics of this application.

sfackler commented 11 months ago

That is explicitly recommending that you self-sign the servers and add their certs to the clients' CA root. That is what certificate pinning is.