-
Notifications
You must be signed in to change notification settings - Fork 173
Refactor Error and Result usage for pkcs5 crate #26
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
Conversation
dwhjames
commented
Sep 15, 2021
- introduce Error enum with one and only existing error value
- introduce specialized Result type for crate
- rewrite references to der crate Error & Result types
|
@tarcieri, admittedly I’m just trying to do easy/accessible things, with learning being the primary motivation. I hope this is actually useful work, and not just busy work. It it did seem that the one error value was actually rolling up a variety of distinct error categories, so I thought I’d rewrite the one and only error, before moving on to separating out the cases. |
ec05443 to
a391e5b
Compare
|
It'd make sense if Note that the only variants I think should be added are ones which distinguish encoding-related errors from actual cryptographic errors. I don't think you should try to categorize the various kinds of cryptographic errors or propagate information about it. That has the potential for leakage. |
|
Here were my ideas:
|
I'd be careful with this one in particular. Once you start identifying information around padding you're introducing the possibility of a padding oracle. That's a large potential foot-gun if the library user isn't careful about that information leaking. |
|
Going through these one-by-one:
I think it's fine to have a variant that says PBES1 is unsupported. This will effectively be a perpetual WONTFIX.
I would really like to avoid overspecializing variants for specific algorithms, especially if they are variants that are only available via conditional compilation. How about something like: If you'd really like to break the cases above down, perhaps it could be
An error case for the output buffer being too small sounds fine. I would avoid mentioning anything about padding: the real problem is that the buffer is too small.
This is the kind of error I'd personally prefer to continue to keep an opaque
These are effectively unsupported algorithm errors. As I mentioned earlier, I'd prefer not to get too off in the weeds with algorithm-specific error variants. Something like
Across the RustCrypto projects we generally try to minimize any potential runtime panics, and especially in low-level libraries like this we are aiming for panic-free code. The reason is we'd like to make these libraries usable in contexts where panics are unacceptable, like OS kernels or bare metal embedded device programming. That's not a hard rule, or an easily enforceable one (see previous link for some discussion on that), but we would like to ensure that there is a baseline level of functionality which does not require a panic handler. |
Yep, exactly, avoiding this sort of leakage is exactly why we've largely kept the error types opaque. |
8c950bb to
38ca864
Compare
tarcieri
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.
Looks good! I'll hold off on merging this until we're ready to make breaking changes
|
@dwhjames can you rebase? If so, I can merge after that |
- introduce Error enum with new error cases - introduce specialized Result type for crate - rewrite references to der crate Error & Result types - some collateral refactoring as well
|
@tarcieri, 👍, conflicts resolved. |
pkcs5/src/pbes2/encryption.rs
Outdated
| let algo_params_invalid_error = Error::AlgorithmParametersInvalid { | ||
| oid: params.encryption.oid(), | ||
| }; |
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.
Rather than eagerly calculating this, you could make it a function on Parameters, e.g. Parameters::invalid_error.
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.
see d30f931
pkcs5/src/pbes2/encryption.rs
Outdated
| let algo_params_invalid_error = Error::AlgorithmParametersInvalid { | ||
| oid: params.encryption.oid(), | ||
| }; |
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.
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.
see d30f931
|
|
||
| impl<'a> Pbkdf2Params<'a> { | ||
| /// Initialize PBKDF2-SHA256 with the given iteration count and salt | ||
| pub fn hmac_with_sha256(iteration_count: u16, salt: &'a [u8]) -> Result<Self, CryptoError> { |
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.
It would probably be good to leave this fallible.
I'm not sure why u16 was used for the iteration count but it unnecessarily constrains the number of iterations. Using 100,000+ should be supported.
However, if this type is changed to a u32, it would also be good to set a sanity limit on the number of iterations.
RFC8018 says the sanity limit is implementation defined:
https://datatracker.ietf.org/doc/html/rfc8018#appendix-A.2
iterationCount specifies the iteration count. The maximum iteration count allowed depends on the implementation. It is expected that implementation profiles may further constrain the bounds.
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.
see d30f931
sanity limit chosen as 100 million
|
|
||
| impl<'a> ScryptParams<'a> { | ||
| #[cfg(feature = "scrypt")] | ||
| const INVALID_ERR: Error = Error::AlgorithmParametersInvalid { oid: SCRYPT_OID }; |
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.
This can also be replaced with a function on params.
Edit: actually, since it's private I guess this is fine. You could also use this approach on the other params structs.
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.
see d30f931
same added for Pbkdf2Params
|
Thank you! |