-
Notifications
You must be signed in to change notification settings - Fork 30
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
Implement serde Serialize and Deserialize for relevant types #192
Comments
Fantastic feature request, as always. I agree this change seems to make a lot of sense. There are much more benefits to this, especially usability, than I see cons for this. The only other con I see, is that it complicates the crate's feature-offering. This is unavoidable however and a sacrifice worth here.
If it's hidden behind a non-default feature and we document the risk, I believe this con is greatly outweighed by the pros. The scope should also include Some additional notes to this (not necessarily in scope of this, probably separate issues too):
|
I agree, especially since it seems pretty common for Rust crates to feature-gate serde support. The compile times are pretty rough to make it default.
Good catch. I missed this one.
Are you saying this because we’re pre-1.0 or because it’s something like a security policy for orion? Normally I think a feature would be a minor release under semver.
I strongly agree. I’ve been frustrated too many times trying to look through source code to figure out exactly what a feature does.
Agreed. I think we should fuzz something like |
I think I've maybe been mistaken on this part actually. I simply assumed it was breaking because if compiled with That said, when the |
Hereby you mean fuzz the serialization implementations through |
Yes, that's what I mean. We need something that implements |
Re-opened since there's still the fuzzers missing. Additionally, in extension of the issue-description, mentioning which types implement provide |
Fuzzing targets have been added in orion-rs/orion-fuzz#18 |
Summary
The
serde::Serialize
andserde::Deserialize
traits are used pervasively throughout the Rust ecosystem to enable flexible (de)serialization of data. Many authors derive these types on structs using macros provided byserde
. If orion's types don't support these traits, users won't be able to derive these serialization traits, and will have to resort to converting orion types before storing them in a struct for serialization.By implementing
serde
's standard traits, we enable authors to skip the mental burden and increased complexity of serializing orion types without serde.Scope
At least for a first implementation, I would suggest only implementing serialization traits for types that are expected to either be stored in a database or sent to another application (e.g. over the network). This would include the following types.
pwhash::PasswordHash
hash::Digest
auth::Tag
kdf::Salt
(added after suggestion below)Motivating Example
My motivating example is storing a
User
type in a database. It would be nice to simply define aUser
struct, and then have it serialize to one long string using, for example, thebincode
crate. This is what I would like the basic code to look like (using a fictional database API).The
PasswordHash
type would serialize as a string by delegating toPasswordHash::unprotected_as_encoded
.Without
serde
's types implemented, however, we would have to do one of the following.User
type that can be serialized.serde
manually onUser
and delegate thePasswordHash
serialization to itsunprotected_as_encoded
method. Neither solution is particularly attractive.A separate, serializable
User
struct is probably the easiest of the the alternatives. It would look like this.It isn't terrible in terms of boilerplate, but it could start to get annoying and possibly error-prone to repeat struct definitions for several different types instead of just
User
.Implementing
Serialize
andDeserialize
manually can be… unpleasant. Especially for anything complex, and definitely more boilerplate in any case.Pros of implementing
Serialize
/Deserialize
serde
do it for them. The common workflow is to deserialize some bytes or a string into the relevant type (would beUser
here, for example), and then to do operations on the fully featured type. This is beneficial because many of orion's types use constant-time operations for things like comparisons. It's anecdotal, but in my first example, thePasswordHash
type spends very little time in its serialized state because it's so easy to deserialize into the fully featured type. Making deserialization the fast path could save users from security mistakes.Cons
unprotected_*
to signify that by using them, authors are relinquishing the constant-time features that orion provides. If we hide these functions in aserde::Serialize
implementation, users may be more likely to mistakenly serialize a sensitive type and perform insecure operations on it. I realize that this somewhat contradicts the last "Pro" above, but they both seem like legitimate possibilities to consider.Additional Considerations
PasswordHash
should serialize as a string using the already-implementedPasswordHash::unprotected_as_encoded
function.serde
feature enabled.The text was updated successfully, but these errors were encountered: