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: Generic custom-class long > 30 tags PRIVATE, CONTEXT-SPECIFIC, APPLICATION #1545

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

dishmaker
Copy link

@dishmaker dishmaker commented Oct 6, 2024

In this PR:

  • Allow the use of tag numbers >30. In the der representation they are stored in the long form as multiple bytes.

  • Allow APPLCATION and PRIVATE tags to be annotated like context specific ones in the derive macros

  • Merge application, private, context-specific tags into one generic codebase CustomClass.

  • Split EXPLICIT and IMPLICIT encoding into CustomClassExplicit/Implicit

  • Add generic TAG: u16 to eg. ContextSpecificExplicit wrapper.

  • Fix the need of implementing both Decode and DecodeValue on CONTEXT-SPECIFIC tags.

    • EXPLICIT tags only need to implement Decode<'a>.
    • IMPLICIT tags only need to implement DecodeValue<'a> and Tagged.
    • todo: maybe drop the requirement of Tagged too - it is needed for checking constructed bit.
  • Add read_nested for IMPLICIT decoder (I had to fix x509-cert then tests, negative ones)

    In implicit Decode there was no read_nested before:

    let header = Header::decode(reader)?;
    let value = T::decode_value(reader, header)?;

Main breaking feature is here:

/// Context-specific class, EXPLICIT
pub type ContextSpecificExplicit<const TAG: u16, T> =
CustomClassExplicit<TAG, T, CLASS_CONTEXT_SPECIFIC>;
/// Context-specific class, IMPLICIT
pub type ContextSpecificImplicit<const TAG: u16, T> =
CustomClassImplicit<TAG, T, CLASS_CONTEXT_SPECIFIC>;
/// Context-specific class, reference, EXPLICIT
pub type ContextSpecificExplicitRef<'a, const TAG: u16, T> =
CustomClassExplicitRef<'a, TAG, T, CLASS_CONTEXT_SPECIFIC>;
/// Context-specific class, reference, IMPLICIT
pub type ContextSpecificImplicitRef<'a, const TAG: u16, T> =
CustomClassImplicitRef<'a, TAG, T, CLASS_CONTEXT_SPECIFIC>;

@dishmaker dishmaker marked this pull request as draft October 6, 2024 20:02
@dishmaker dishmaker force-pushed the custom_class_long_tags branch from 756ef5f to 41fa980 Compare October 9, 2024 13:53
@dishmaker dishmaker marked this pull request as ready for review October 9, 2024 15:29
@dishmaker dishmaker changed the title WIP: Custom long > 30 tags PRIVATE, CONTEXT-SPECIFIC, APPLICATION Generic custom-class long > 30 tags PRIVATE, CONTEXT-SPECIFIC, APPLICATION Oct 9, 2024
@dishmaker dishmaker changed the title Generic custom-class long > 30 tags PRIVATE, CONTEXT-SPECIFIC, APPLICATION der: Generic custom-class long > 30 tags PRIVATE, CONTEXT-SPECIFIC, APPLICATION Oct 9, 2024
Harris Kaufmann and others added 8 commits October 10, 2024 08:52
…re stored in long form

draft: CustomClass generic type

feat: add decode_implicit and decode_explicit back

fix: cargo test -p der now pass

refactor: raname to Explicit struct

refactor: TAG, T order

docs: CustomClass

feat: add ContextSpecificRef back (ContextSpecificExplicitRef)

update der-derive to current der implementation

feat: add tests for context-specific

fix: dependency crates

fixed for x509-cert

cargo fmt

fix: crates depending on context-specific and long TagNumber

fix x509-cert
@dishmaker dishmaker force-pushed the custom_class_long_tags branch from 02c666a to fd9b041 Compare October 10, 2024 06:53
@dishmaker
Copy link
Author

Sorry for not providing documentation on ContextSpecificExplicit and AnyCustomClassExplicit etc...
I'll try maybe next week.

@brandonweeks
Copy link

I've tested this PR with a prototype for parsing the Android key attestation X.509 extension that exclusively has tags >31. No issues discovered.

https://developer.android.com/privacy-and-security/security-key-attestation#key_attestation_ext_schema

@dishmaker
Copy link
Author

Currently, CONTEXT-SPECIFIC IMPLICIT forces the user to implement FixedTag (which implies Tagged). But the tag isn't actually used anywhere.

let constructed = <T as FixedTag>::TAG.is_constructed();

I think it might be useful for some types to implement IsConstructed, but not FixedTag
(for example custom CHOICE would not be FixedTag).

But if FixedTag is available, then it will be auto-implemented.
Something like:

impl<T: FixedTag> IsConstructed for T {
    /// ASN.1 constructed bit, used for CONTEXT-SPECIFIC IMPLICIT encoding
    const CONSTRUCTED: bool = T::TAG.is_constructed();
}

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.

2 participants