-
Notifications
You must be signed in to change notification settings - Fork 132
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
tls_codec: feature for conditional deserialization derivation #1214
tls_codec: feature for conditional deserialization derivation #1214
Conversation
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.
Thanks, some thoughts.
- having plain booleans is always a little difficult because you don't know what the value stands for
- having to add the const generic feels a little odd when we have an attribute on it anyway
- what is an unverified/verified struct supposed to (not) offer?
I think we can make this a little nicer.
How about having an attribute for #[verifiable]
, which adds a const generic to the struct and adds aliases as well as the implementation? That way we could hide all the details.
It could also be generalised a little and use a u8
to allow other states. That might be something we want to have, but not sure if it fits in here.
tls_codec/derive/src/lib.rs
Outdated
//! | ||
//! |
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.
//! | |
//! |
Thanks for the review! All very good points.
Agreed, but since we can't use enums just yet, I thought it would be a neat option. We can use constants for true and false, but I agree that it's not ideal.
We don't necessarily have to have an attribute on it if we can find a way for the deserialize macro to detect the "Verifiable" pattern, although this bears the risk of false positives, of course. We could try to implement it all in one attribute, but we have to make sure that we implementer stays somewhat flexible. The design goals for this whole thing would probably look something like this:
I like these ideas, although I'll have to step up my macro-foo somewhat. I'm not sure how we would want to generalize this to other states, since the requirements listed above are relatively specific (especially the restriction on deserialization). Is there something you had in mind? In any case, if we don't implement this in the derive macro and if we find that generalization is not something we want, we might want to just implement this on the OpenMLS side for now. |
My 2 cents: I think this feature, while still nice for some uses (i.e. OpenMLS API), should live in another crate that depends on & extends This seems way out of scope of the crate (which is to allow de/serializing from/to TPL). |
I disagree. Safe deserialisation is very much in scope of this crate. I talked through the PR with @kkohbrok and I think it's a useful addition because it allows users to differentiate between incoming and outgoing structs/messages. This facilitates safe implementations. |
I've made the changes discussed OOB. I think we also discussed renaming the functions of the DeserializeBytes variant. Once this is done (I'll create a PR for this shortly), we can probably get rid of the input for the attribute macro and just derive both the reader and the bytes based functions for the deserializable variant. |
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.
Generally looks good to me. The doc tests fail though.
Looks like this isn't on CI right now. Can you add this at the bottom to the tls_codec.yml
action?
- run: cargo hack test -p tls_codec_derive --feature-powerset --doc
tls_codec/derive/Cargo.toml
Outdated
@@ -14,7 +14,7 @@ rust-version = "1.60" | |||
proc-macro = true | |||
|
|||
[dependencies] | |||
syn = { version = "2", features = ["parsing"] } | |||
syn = { version = "2", features = ["parsing", "full"] } |
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.
Do we always need full
? If not, let's only enable it for the conditional_deserialization
feature.
tls_codec/derive/src/lib.rs
Outdated
Span::call_site(), | ||
); | ||
let annotated_item_visibility = annotated_item.vis.clone(); | ||
// For now, we assume that the struct doesn't |
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 like there's something missing 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.
Thanks, lgtm now.
This PR proposes a feature that enables the
verifiable
attribute macro.The macro extends the annotated struct with a boolean const generic indicating if the given instance of the struct was verified or not. The macro takes as input either
Bytes
orReader
and derives the respective flavour ofTlsDeserialize
for the unverified variant of the struct. The macro also creates two type aliases. Each type alias points to the verified or unverified struct variant and prefixes the struct name with "Verified" or "Unverified" respectively.This allows a pattern, where a struct is meant to pass a processing step (e.g. verification) after verification. Any functionality that is conditional on that processing step can then be implemented for the verified version of the struct.
TODO:
Create separate PR to bumpadd "full" feature tosyn
syn
dependency