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: Correct context-specific skipping algorithm #1723

Open
dishmaker opened this issue Mar 15, 2025 · 8 comments
Open

der: Correct context-specific skipping algorithm #1723

dishmaker opened this issue Mar 15, 2025 · 8 comments

Comments

@dishmaker
Copy link
Contributor

dishmaker commented Mar 15, 2025

Looks like currently tag numbers lower than requested are skipped.

Decoder breaks only on higher than expected tag numbers:
if !tag.is_context_specific() || tag.number() > tag_number { break }

Commit history:
448d5fb?diff=unified#diff-7bb94c63666ed02733ba218c24281358f540200bd845b247f1a84a0f95021234R90

https://github.com/RustCrypto/formats/blame/d87ed96b253e1af95533234804a224cbb408099d/der/src/decoder.rs#L195

However, python asn1tools would not skip lower tags when decoding.

In my example the decoder just stops on tag [1] and does not decode [4].

foo.asn

Foo DEFINITIONS ::= BEGIN

    SequenceA ::= SEQUENCE {
        question  IA5String,
        context1  [1] IA5String OPTIONAL,
        context4  [4] IA5String OPTIONAL
    }

    SequenceB ::= SEQUENCE {
        question  IA5String,
        context4  [4] IA5String OPTIONAL
    }

END
import asn1tools
foo = asn1tools.compile_files('foo.asn')
encoded = foo.encode('SequenceA', {
    'question': '0',
    'context1': '1',
    'context4': '4',
    })
print(encoded.hex(' '))

decoded = foo.decode('SequenceB', encoded)
print(decoded)
$ python test_foo.py 
30 0d 16 01 30 a1 03 16 01 31 a4 03 16 01 34
{'question': '0'}

And btw it works when SequenceA is decoded as SequenceA:

$ python test_foo.py 
30 0d 16 01 30 a1 03 16 01 31 a4 03 16 01 34
{'question': '0', 'context1': '1', 'context4': '4'}

So there are 2 possible algorithms:

  • tag.number() > tag_number
  • tag.number() != tag_number

Which one is correct?

@tarcieri
Copy link
Member

I can't find a citation in ITU X.690, which includes surprisingly little information on context-specific fields in general. Perhaps there's a different document I should be consulting.

This situation arises when there are lower-numbered unknown context-specific tags, which seems like a somewhat odd situation to be in to begin with.

@richsalz
Copy link

I would send to the lamps@ietf.org mailing list, that's where the ASN1 folks mostly hang out. x.690 would have been my guess too.

@richsalz
Copy link

richsalz commented Mar 19, 2025 via email

@carl-wallace
Copy link
Contributor

X.680 is likely what you want.

@richsalz
Copy link

richsalz commented Mar 19, 2025 via email

@tarcieri
Copy link
Member

Perhaps we're not finding anything because there is no special algorithm, and they should be handled like any other tag, in which case the special logic around them should just be removed

@richsalz
Copy link

What was the rationale for skipping them in the first place?

@dishmaker
Copy link
Contributor Author

Looks like entire philisophy of tag.number() != tag_number in rasn crate is contained in: .ok()

https://github.com/librasn/rasn/blob/3e8e3a26048c229b32a66a48362ea476a2ddd92d/src/ber/de.rs#L747

So it ignores the Err(..) and returns Option<D>::None when tag is invalid?

https://github.com/librasn/rasn/blob/3e8e3a26048c229b32a66a48362ea476a2ddd92d/src/ber/de.rs#L707

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

No branches or pull requests

4 participants