Skip to content
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

der: add IsConstructed trait, impl'ed on any FixedTag #1744

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

dishmaker
Copy link
Contributor

@dishmaker dishmaker commented Mar 27, 2025

Closes #1741

This PR drops the need to implement Tagged on all structs that are IMPLICIT.

For example CHOICE does not implement FixedTag, but is always constructed.

@tarcieri
Copy link
Member

This doesn't seem to do a whole lot as-is. What else are you planning on impl'ing IsConstructed on?

@dishmaker
Copy link
Contributor Author

On trait Choice and my weird little edge case where derive(Choice) needed Tagged on something that wasn't.

@dishmaker
Copy link
Contributor Author

dishmaker commented Mar 27, 2025

If I remember correctly, the edge case is here:
https://github.com/monai/node-passport/blob/master/lib/pkcs15/cryptographic_information_framework.asn1#L181

So it's a CHOICE with [0] CHOICE inside for ObjectValue {RSAPublicKeyChoice}

@tarcieri
Copy link
Member

You should try to add it there, as I think for what you’re proposing the blanket impls(?) would conflict

@dishmaker dishmaker marked this pull request as draft March 27, 2025 15:27
@dishmaker
Copy link
Contributor Author

It will take me some time to recreate the Tagged IMPLICIT bug with CHOICE inside [0] CHOICE :)

@dishmaker
Copy link
Contributor Author

dishmaker commented Mar 28, 2025

I give up. It's pretty much impossible to implement this case in current der, without splitting EXPLICIT and IMPLICIT encoders.

#[derive(Choice)]
pub enum ObjectValue<T>
where
    for<'a> T: /* what to put here ? */,
{
    Indirect(Path),

    #[asn1(context_specific = "0", tag_mode = "IMPLICIT")]
    Direct(T),
}
[Spoiler] error[E0277]
error[E0277]: the trait bound `RSAPublicKeyChoice: FixedTag` is not satisfied
   --> der/tests/derive.rs:261:52
    |
261 |             let object_value = ObjectValue::Direct(rsa_choice);
    |                                ------------------- ^^^^^^^^^^ the trait `der::Sequence<'_>` is not implemented for `RSAPublicKeyChoice`
    |                                |
    |                                required by a bound introduced by this call
    |
    = note: required for `RSAPublicKeyChoice` to implement `FixedTag`
note: required by a bound in `ObjectValue::Direct`
   --> der/tests/derive.rs:220:78
    |
220 |             for<'a> T: Encode + Decode<'a> + EncodeValue + DecodeValue<'a> + FixedTag,
    |                                                                              ^^^^^^^^ required by this bound in `ObjectValue::Direct`
...
225 |             Direct(T),
    |             ------ required by a bound in this tuple variant

So ObjectValue::Direct should be bound:

  • only by EncodeValue + DecodeValue<'a> + IsConstructed,
  • but now Encode + Decode<'a> + EncodeValue + DecodeValue<'a> + FixedTag is required.

Tagged and FixedTag traits are forced elsewere in the crate by ContextSpecific wrapper.

@dishmaker
Copy link
Contributor Author

Btw CHOICE inside CHOICE isn't a problem. Such case can be simplified by hand.

/// ```asn1
/// ReferencedValue {Type} ::= CHOICE {
///     path Path,
///     url URL
/// }
/// URL ::= CHOICE {
///     url CHOICE {
///         printable PrintableString, 
///         ia5 IA5String
///     },
///     urlWithDigest [3] SEQUENCE {
///         url IA5String,
///         digest DigestInfoWithDefault
///     }
/// }
/// ```
#[derive(Choice, Clone, Debug, Eq, PartialEq)]
#[tag_mode = "IMPLICIT"]
pub enum ReferencedValue {
    Path(Path),
    PrintableStringUrl(PrintableString),
    Ia5StringUrl(Ia5String),
    #[asn1(context_specific = "3")]
    UrlWithDigest(()),
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

der: add IsConstructed trait
2 participants