英文:
Why is extnValue in X.509 Extensions always encapsulated in an OCTET_STRING?
问题
我好奇,到目前为止我还没有找到一个解释。
在RFC 5280中,扩展定义如下:
Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER,
critical BOOLEAN DEFAULT FALSE,
extnValue OCTET STRING
-- 包含与extnID标识的扩展类型对应的ASN.1值的DER编码
}
为什么要定义extnValue作为封装的OCTET_STRING,而不是直接定义extnValue为“与extnID标识的扩展类型对应的ASN.1值的DER编码”呢?
谢谢。
英文:
I'm curious, and I was not able to find an explanation so far.
In RFC 5280 Extensions define the following:
Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER,
critical BOOLEAN DEFAULT FALSE,
extnValue OCTET STRING
-- contains the DER encoding of an ASN.1 value
-- corresponding to the extension type identified
-- by extnID
}
What is the reason for defining the encapsulating OCTET_STRING for extnValue, instead of directly defining extnValue as the "DER encoding of an ASN.1 value corresponding to the extension type identified by extnID".
Thank you.
答案1
得分: 2
不是权威回答,但我的想法是:这是因为扩展值可以具有任意的封装标记,并且可以在外部模块中定义:
大多数扩展使用SEQUENCE
,但有些不是,就像在给定的示例中,Subject Key Identifier只是另一个OCTET_STRING
,Key Usages是一个BIT_STRING
。而在基本类型定义中,您必须使用固定标记来表示可变内容(ANY
)。
此外,解析器可能不知道如何解析特定的扩展,因此它们将其读取为八位字节字符串,而无需深入挖掘扩展类型对解析器未知的情况。
2023年2月13日更新(根据评论):
> 关于类型/标记,据我理解,可以通过前导标记字节轻松识别每种不同类型,例如SEQUENCE=0x10,OCTET_STRING=0x04或BIT_STRING=0x03
您不能使用可变标记定义字段,因为这会引入类型不明确性。也就是说,extnValue ANY
字段定义是无效的,因为其类型不确定。当您定义一个类型(在这种情况下,它是Extension
类型)时,所有字段必须具有确定性标记。
英文:
Not an authoritative answer, but my thoughts are: this is because extension values may have arbitrary enclosing tags and can be defined in external modules:
Most extensions use SEQUENCE
, but some are not, like in a given example, Subject Key Identifier is just another OCTET_STRING
, Key Usages is a BIT_STRING
. And in base type definition you have to use fixed tag to represent variable content (ANY
).
In addition, parsers may not know how to parse particular extension, so they read it as octet string without having to dig deeper if extension type is unknown to parser.
update 13.02.2023 (based on comments):
> Regarding the type / tag, from my understanding, each different type can be easily identified by the leading tag byte, such as SEQUENCE=0x10, OCTET_STRING=0x04 or BIT_STRING=0x03
you cannot define the field with variable tag, because you introduce type ambiguity. That is, extnValue ANY
field definition is not valid, because its type is indeterminate. When you define a type (in this case, it is Extension
type), all fields must have deterministic tag.
答案2
得分: 2
extnValue 是我们所谓的规范孔。它只是一个容器,可以放置任何内容。
数据接收者必须知道如何根据另一个规范(extnID 是找到此规范的方式)来理解它。
注释说明它包含了ASN.1值的DER编码...但这只是一个注释。
就我们而言,extnValue 只是字节,而OCTET STRING 是携带字节(8位)的最佳ASN.1类型。
过去曾经有一个(糟糕的)类型叫做ANY,它恰好可以携带表示(未指定的)ASN.1值的字节。但在1995年采纳x.509 v3之前,它在1994年已经被弃用。
注意:
使用DER转储程序(类似于Crypt32的回答)格式化数据,或者使用openssl显示您的证书可能会让您产生一次性解码所有内容的印象。
规范孔的工作方式是,您的工具首先解码Certificate,然后获取每个扩展(孔)的字节。然后,一次一个,您使用extnID指向的规范来解码字节,以获取扩展的值。
英文:
extnValue is what we call a specification hole.
It is just a container for whatever you want.
The receiver of the data will have to know how to understand it based on another specification (extnID is the way to find this specification)
The comment states that it contains the DER encoding of an ASN.1 value ... but it is only a comment.
As far as we are concerned, extnValue are just bytes and OCTET STRING is the best ASN.1 type to carry bytes (8bit).
In the past, there was a (terrible) type called ANY that was doing exactly this: carring bytes that represents an (unspecified) ASN.1 value. But it was deprecated in 1994 before x.509 v3 was considered for adoption (1995).
Note:
Formatting the data with a DER dumper (like in Crypt32's answer) or using openssl to display your certificate can give you the impression that all is decoded in one pass.
The way specification holes work, your tool decodes the Certificate first and gets bytes for each extensions (holes). Then, one at a time, you decode the bytes using the specification pointed to by extnID to get the value of the extensions.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论