We are using the JAC ASN.1 Compiler in our (legacy) project and experienced a situation where we received ASN.1 messages we could not parse.
I took a look at the parser code and noticed that this is a bug in the library. Since switching to a commercial solution isn't so easy, we are forced to fork the library and fix it.
TL;DR
Is there any situation during ASN.1 decoding where you read a tag number and instead of looking if your schema has this tag number on the level of the structure you are in, you look if any nested element has this tag?
Here is a mininal example reproducing the bug in the library. You can use this online playground to compile the schema etc. and see that a functioning parser has no problems with it.
Schema
Basically, it's a structure with two elements: A choice and a string, both of which are optional. The key to the example is that the choice element contains an element with a tag number equal to the tag number of the optional string.
Example DEFINITIONS ::= BEGIN
Message ::= SEQUENCE {
params [1] EXPLICIT Params OPTIONAL,
confuser [2] IMPLICIT PrintableString OPTIONAL
}
Params ::= CHOICE {
unimportant [1] IMPLICIT PrintableString,
accident [2] IMPLICIT Accident
}
Accident ::= SEQUENCE {
irrelevant [1] IMPLICIT PrintableString OPTIONAL
}
END
Example Message
message Message ::= {
confuser "Foo"
}
Example Message (encoded, BER)
30058203 466F6F
When using the JAC parser, it will correctly read the tag number 2
in the message and then iterates over the elements in the schema to find the element to associate it with. However, with choice elements it has some extra logic:
Instead of saying "params has tag 1, which is not 2, so this value does not correspond to it", it goes "params has tag 1, which is not 2, but it is a choice element and it contains an element with tag 2, so this has got to be the element I am looking for".
It then takes the Accident
class, goes on with parsing and finally fails because it now can't find the tag 2
in this class.
A comment in the parser logic says that this is for cases of untagged choice elements. But this confuses me: According to everything I read, untagged choice elements don't have a default tag but will instead be tagged explicitly; moreover, a choice can never be tagged implicitly.
But with this information I fail to imagine any scenario where this logic in the parser is useful and I am leaning towards simply deleting it. However, I just got familiar with ASN.1 because of this bug and may be overlooking something – am I?
There's one possibility for having to look into the tags of choice member and is that the choice is added without tags:
For example if your definition were:
Answering your question.
No, untagged choice elements take the tag of the choice. It is tagged choice elements what must be tagged explicitly and can never be tagged implicitly.
Going back to your definition
the params component must have a explicit tag (both because you mark it as EXPLICIT... but also because of clause 30.7.c of X.680:
In this scenario encoding goes:
x.690: clause 8.9.2 & 8.9.3
But for params component the rule that applies is first the 8.14.2
... and only within the explicit tagged type we can consider the encoding of the choice 8.13