-
Notifications
You must be signed in to change notification settings - Fork 324
Expose cryptography backends via CryptoProvider #452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
4483fd7 to
370f904
Compare
|
@Keats any chance of a review on this? |
|
Would this allow applications to use rustls rather than openssl? |
|
@drusellers As far as I know rustls doesn't implement the cryptography directly, rather it relies on other crates like |
Keats
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be simplified
38698b3 to
3344881
Compare
|
@Keats I made the JWK functions private after all. For the In regards to the macro, I also left it as is, if #461 goes through and does gate the implementation itself behind a feature, I guess the best would be to remove the macro and write the functions by hand for each built-in provider. As for the example, I used the |
| pub extract_ec_public_key_coordinates: | ||
| fn(&[u8], Algorithm) -> Result<(EllipticCurve, Vec<u8>, Vec<u8>)>, | ||
| /// Given some data and a name of a hash function, compute hash_function(data) | ||
| pub compute_digest: fn(&[u8], ThumbprintHash) -> Vec<u8>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems I forgot to bring this up before, but it would really be great if we could do a breaking change to turn this into Result<Vec<u8>>. Everything else lets you return an error should it happen in your custom provider (e.g. botan can technically error here, because it does go through an FFI, and while it shouldn't error, I still need to call unwrap here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you create an issue for it? We can change that for the next major version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments how to implement it better and simplify provider logic
I think it would be also great to have NOOP provider implementation to be used by default instead of relying on Option to reduce indirection
|
@DoumanAsh I can sympathize with most of the comments, and will try them out soon-ish. What I don't sympathize with is returning a default provider when both features are enabled. If there is a default provider, it should be a default feature. Making cryptographic choices for the user that they might not know about is imo a very bad idea. |
|
@arckoor This is user responsibility to install provider he wants use, if he doesn't want to install any, then user is fine with any. I suggest AWS-LC because it has FIPS mode by default, which makes it most reasonable choice P.s. let me know if you need any help to get this PR ready, it would be nice to get P.s.s Please note that it is my personal opinion and has nothing to with author of the library so defer to Keats's approval to get this PR merged |
|
I agree with @arckoor if several features are enabled in the tree but the user didn't pick. That's a one time choice for the user but for example aws-ls-rc doesn't work with WASM afaik so I would rather not pick the backend library without a clear input in case of conflict. |
|
@Keats The problem is that feature can be enabled by your dependency, it can be alleviated by having NOOP backend so that library could encourage others not to enable features I guess, but if for some reason you accidentally enable both features, you have no way to diagnose it simply, so that's my concern |
|
@Keats oh joy, CI fails because of the botan use in the example. I don't know what other crypto lib to use, if you have any preference, please let me know. I can also copy paste code from one of the built in providers, or just remove the example entirely and e.g. point to my |
|
Sorry for the delay. Let's point to other backends for examples, no need to maintain one ourselves. |
af6dded to
0e50a59
Compare
Keats
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Are you ok with that @DoumanAsh ?
| pub extract_ec_public_key_coordinates: | ||
| fn(&[u8], Algorithm) -> Result<(EllipticCurve, Vec<u8>, Vec<u8>)>, | ||
| /// Given some data and a name of a hash function, compute hash_function(data) | ||
| pub compute_digest: fn(&[u8], ThumbprintHash) -> Vec<u8>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you create an issue for it? We can change that for the next major version?
| /// The algorithms supported for signing/verifying JWTs | ||
| #[allow(clippy::upper_case_acronyms)] | ||
| #[derive(Debug, Default, PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize)] | ||
| #[non_exhaustive] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why non exhaustive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that when e.g. #461 is merged, providers still compile and throw an unimplemented!() instead of not compiling at all
|
Functionally wise it solves issue, but generally I think Arc and Option are adding unnecessary indirection to access provider (I pointed it out in my review but as I'm not really owner I didn't insist on it) |
0e50a59 to
f273be8
Compare
I really have no opinion on that tbh. @arckoor what do you think? |
|
Well, I originally wrote it the way I did because rustls did it this way, and my thinking was "It's rustls, they ought to know what they're doing". The |
😅 I really do not care personally but if Arc is not needed in any way we can remove it |
|
@arckoor @Keats Here is quick approach to remove Arc and Option It moves everything into static variables and relies on P.s. Dynamic creation (i.e. without |
|
Yeah, I see the point with the static, but imo for the cryptography it's important to panic as early as possible when nothing is installed |
|
I'm not sure why this case would make difference? This optimises default initialisation path, but panic will happen as provider will always initialise on the first usage of any method inside provider. There should be practically no difference aside from overhead of individual interface's method invocation. |
f273be8 to
82f1294
Compare
|
@Keats can be merged from my side |
Adds a
CryptoProviderstruct that allows replacing the built-in providers with something custom.All the details from this implementation that could be considered "interesting" are stolen straight from
rustls's CryptoProvider.I've marked the
new_signer,new_verifierand JWK functions from the two built in backends aspub, so you can do stuff like this:i.e. overwrite just specific algorithms.
One area I'm a little unsure about is
JwkUtils, 1) about the name and 2) about theDefaultimplementation. TheCryptoProvider::signer_andCryptoProvider::verifier_factoryfunctions are obviously mandatory for a custom provider, but not everyone uses JWK, so the default just uses dummy functions withunimplemented!().