Comments (7)
My thoughts on this:
I would like to get away from further builder()
functions, because they are the entry point into configuration of the library. Making that API too broad stands to confuse people in their early steps with the library. However, we could simply reexport one of the providers under a different name, and then have people call rustls::ClientConfig::builder_with_provider(rustls::crypto::default_provider_from_crate_features())
or whatever.
I would like to avoid giving any special primacy to the providers in the rustls
crate. I think if we end up with the crates ecosystem all using the API suggested in this issue, that would be a bad outcome. It would mean only providers that are known by this crate are widely usable, and there is no reasonable way to use others. That was one of the goals of this work -- to let people use nationalist or otherwise esoteric/experimental providers without our approval or assistance.
I guess this (especially (2)) is an argument in favour of moving the ring and aws-lc-rs providers into their own crates (that re-export the entire public API of rustls as it currently stands), and having downstream users depend on rustls-ring
or rustls-aws-lc-rs
crates.
from rustls.
How is this different from https://docs.rs/rustls/latest/rustls/client/struct.ClientConfig.html#method.builder today? We are intentionally not providing a method whose provided crypto provider depends on Cargo features only, since that could have very surprising behavior due to feature unification.
from rustls.
How is this different from https://docs.rs/rustls/latest/rustls/client/struct.ClientConfig.html#method.builder today?
It works with ring disabled and aws-lc-rs enabled, without having to non-trivially change your code.
I suggested a separate method name by way of not changing the behavior of existing code, so that library code could opt-in to not caring what crypto provider it uses.
We are intentionally not providing a method whose provided crypto provider depends on Cargo features only, since that could have very surprising behavior due to feature unification.
I won't argue that it's ideal, but that's going to push people to reinvent it at the next level of dependency up, rather than doing without it. For instance, I currently have a draft PR for a project that does this:
- ClientConfig::builder()
+ #[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))]
+ let provider = rustls::crypto::ring::default_provider();
+ #[cfg(feature = "aws-lc-rs")]
+ let provider = rustls::crypto::aws_lc_rs::default_provider();
+
+ ClientConfig::builder_with_provider(Arc::new(provider))
+ .with_safe_default_protocol_versions()
+ .expect("could not enable default TLS versions")
.with_root_certificates(root_store)
.with_no_client_auth()
And the same thing for ServerConfig
elsewhere.
I really appreciate the rustls work on multiple backends, and I'm incredibly excited about it. But it's already going to be painful to have to get patches into many different places to add default-features = false
to crates depending on rustls
. If those patches will also require non-trivial patches to anything that uses configuration, as well, that makes that work harder and more likely to result in pushback.
Would it be possible to get some way to abstract over the "give me a default CryptoProvider" dance above, without requiring cfg
and a proliferation of feature flags in libraries? Or something to make it so that crates don't have to write things like the above? Changing stable APIs to always require passing in a ClientConfig
/ServerConfig
is not always an option, leaving aside the UX of going that route.
Long-term, I'd love to see Cargo global features. And once those exist, this is clearly a good candidate for them. But in the meantime, what do you see as the mechanism that stable library crates should use for allowing consumers of the library crate to use either ring or aws-lc-rs?
from rustls.
We could add a builder_with_enabled_provider()
or something. But it seems to me a pretty big footgun for libraries to use, which would mean that applications can find themselves accidentally pulling a different crypto provider because another library has enabled a different crypto provider than expected. Given how Cargo features work, the only way to guard against that is to not offer that method all. At least diffs like the one you showed make this explicit.
from rustls.
Having said all that, see #1732 where we are making ClientConfig::builder()
default to using aws-lc-rs in FIPS mode if the fips
crate feature is enabled. That kinda makes some sense, because generally someone who wants FIPS anywhere wants it everywhere, and it is a headline feature we want to make easy to enable.
from rustls.
However, we could simply reexport one of the providers under a different name, and then have people call
rustls::ClientConfig::builder_with_provider(rustls::crypto::default_provider_from_crate_features())
or whatever.
If people had to port to that, that'd be fine, and still an improvement over hardcoding it themselves.
I would like to avoid giving any special primacy to the providers in the rustls crate.
I think it's very likely that, in the absence of some kind of abstraction layer that allows libraries to not care what provider they use, they're very likely to end up hardcoding a set of supported providers anyway. And I'd rather have a single list in rustls than numerous disparate lists throughout the ecosystem.
I think it'd be reasonable for rustls to have some endorsed providers that are known to support all the algorithms people would reasonably expect, a standard that ring and aws-lc-rs currently meet. Both of those providers meet the standard that a library could reasonably not care which one they get, and not be terribly surprised.
People can also use any provider they want, including third-party ones. And that's not going to be quite as easy until either cargo / rust provide a "global capability" system, or rustls provides some application-level way to set the global provider, or all the crates you use that interact with rustls let you pass in a ClientConfig / ServerConfig. And the latter two cases have usability downsides.
But I don't think the potential for further improvements in the future should prevent making the common case better in the near-term future.
from rustls.
rustls provides some application-level way to set the global provider
Just to link the issues together, I suggested an application-level setting over here: #1642. I agree it has usability problems, but I kinda think it might wind up being the most practical.
from rustls.
Related Issues (20)
- Address difficulty upgrading between versions HOT 9
- Weird BoGo failure related with EarlyData HOT 1
- TLS1.3 performance problem HOT 8
- Request for Information on Dedicated discussion Channel for Rustls like Element.io or Discord Alternatives? HOT 3
- use openssl not get Panic,use rusttls get panic HOT 4
- BadRecordMac, client abort connection after several packets after handshake HOT 9
- Randomly getting `InappropriateHandshakeMessage` HOT 1
- 0.23 release preparation HOT 9
- Support for some clipersuite to connect Microsoft-IIS 8.5 server HOT 6
- Current main fails to compile aws-lc-sys HOT 18
- When accepting new TLS connection with Accepted::into_connection(config) no TLS alert is sent HOT 17
- Is there any benchmark comparison of existing TLS libraries in other languages like java, C++ and python etc. with Rustls ? HOT 6
- Random with 0 system entropy - workarounds? HOT 2
- Be able to get the not_before and not_after through some API in CertifiedKey or CertificateDer<'_>. HOT 6
- ServerConnection data lost HOT 3
- Async code in `ProducesTickets` implementation HOT 2
- `ServerHelloPayload` re-export inquery/request HOT 7
- Benchmark the `Unbuffered{Client,Server}Connection` API
- ClientConnection.peer_certificates() to return Some() regardless of CertificateError::UnknownIssuer HOT 5
- Consider a process default server certificate verifier HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rustls.