我们正在使用JAC ASN.1 编译器,遇到了我们收到无法解析的 ASN.1 消息的情况。
我查看了解析器代码,发现这是库中的一个错误。由于切换到商业解决方案不是那么容易,我们被迫分叉库并修复它。
TL;博士
在 ASN.1 解码期间是否有任何情况下您读取标签号,而不是查看您的架构是否在您所在的结构级别上具有此标签号,而是查看是否有任何嵌套元素具有此标签?
这是一个重现库中错误的小示例。您可以使用这个在线游乐场来编译模式等,并查看正常运行的解析器没有问题。
架构
基本上,它是一个包含两个元素的结构:一个选项和一个字符串,这两个元素都是可选的。该示例的关键是choice 元素包含一个标签号等于可选字符串的标签号的元素。
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
示例消息
message Message ::= {
confuser "Foo"
}
示例消息(编码,BER)
30058203 466F6F
使用 JAC 解析器时,它将正确读取2
消息中的标记号,然后遍历模式中的元素以找到与之关联的元素。但是,对于选择元素,它有一些额外的逻辑:
不是说“params 有标签 1,不是 2,所以这个值不对应”,而是说“params 有标签 1,不是 2,但它是一个选择元素,它包含一个带有标签的元素2,所以这必须是我正在寻找的元素”。
然后它接受这个类,继续解析并最终失败,因为它现在在这个类中Accident
找不到标签。2
解析器逻辑中的注释说这是针对未标记选择元素的情况。但这让我感到困惑:根据我阅读的所有内容,未标记的选择元素没有默认标记,而是会被显式标记;此外,永远不能隐含地标记选择。
但是有了这些信息,我无法想象解析器中的这个逻辑有用的任何场景,我倾向于简单地删除它。但是,由于这个错误,我刚刚熟悉了 ASN.1,并且可能忽略了一些东西——是吗?