GithubHelp home page GithubHelp logo

Comments (7)

ctz avatar ctz commented on May 30, 2024 2

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.

djc avatar djc commented on May 30, 2024

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.

joshtriplett avatar joshtriplett commented on May 30, 2024

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.

djc avatar djc commented on May 30, 2024

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.

ctz avatar ctz commented on May 30, 2024

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.

joshtriplett avatar joshtriplett commented on May 30, 2024

@ctz

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.

jsha avatar jsha commented on May 30, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.