问题描述
我正在尝试为代理证书创建X509请求(ProxyCertInfo扩展 RFC3820 ),但我无法弄清楚应该如何定义ProxyCertInfo的数据结构. RFC定义了ASN.1语言,如下所示:
PKIXproxy88 { iso(1) identified-organization(3) dod(6)
internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
proxy-cert-extns(25) }
DEFINITIONS EXPLICIT TAGS ::=
BEGIN
-- EXPORTS ALL --
-- IMPORTS NONE --
-- PKIX specific OIDs
id-pkix OBJECT IDENTIFIER ::=
{ iso(1) identified-organization(3)
dod(6) internet(1) security(5) mechanisms(5) pkix(7) }
-- private certificate extensions
id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
-- Locally defined OIDs
-- The proxy certificate extension
id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pe 14 }
-- Proxy certificate policy languages
id-ppl OBJECT IDENTIFIER ::= { id-pkix 21 }
-- Proxy certificate policies languages defined in
id-ppl-anyLanguage OBJECT IDENTIFIER ::= { id-ppl 0 }
id-ppl-inheritAll OBJECT IDENTIFIER ::= { id-ppl 1 }
id-ppl-independent OBJECT IDENTIFIER ::= { id-ppl 2 }
-- The ProxyCertInfo Extension
ProxyCertInfoExtension ::= SEQUENCE {
pCPathLenConstraint ProxyCertPathLengthConstraint OPTIONAL,
proxyPolicy ProxyPolicy
}
ProxyCertPathLengthConstraint ::= INTEGER
ProxyPolicy ::= SEQUENCE {
policyLanguage OBJECT IDENTIFIER,
policy OCTET STRING OPTIONAL
}
END
我查看了非常有限的OpenSSL文档,无法找到如何将其解析为C数据结构的方法.我还阅读了 http://www.openssl.org/docs/apps/asn1parse .html#,因为它说明了如何将解析器用于命令行工具,而不是如何将其包含在您自己的源代码中.
我已经设法在X509请求中包括其他扩展,所以我相对确定我唯一的问题是该特定扩展的数据结构格式.
我认为您的问题是如何将数据格式化为ProxyCertInfoExtension?"如果不正确,请通知我.
如果您想了解一些理论,我发现的最佳参考文献是 Layman's ASN.1,BER和DER子集的指南.
问题中的代码部分描述了如何对ProxyCertInfoExtension的数据进行编码.将编码描述视为可以由解析器生成器处理的语法,就像yacc将语法作为输入和输出C代码一样.实际上,至少存在一个ASN.1解析器生成器 ASN1C
ASN.1编码的大小可能可变.数据以最外层或顶层ASN.1编码开始.每个ASN.1编码内部可能包含一个或多个ASN.1编码.这样,ASN.1是递归的.
ASN.1编码由标头,长度,可选内容和可选结尾组成.
ASN.1 encoding { Header length [content] [end] }
头由Class类型,Primitive/Constructed位和Tag-Number组成.如果标记号大于63,则标记号将跨越多个字节.这意味着报头可以是一个字节长,也可以是多个字节长,具体取决于标记号的值.标头是按字节对齐的,这意味着它总是一定数量的字节长.
ASN.1 header { ClassType Primitive/Constructed Tag-number }
长度也可以是一个字节到多个字节,具体取决于长度的值.长度再次按字节对齐.
类"类型和标记号"告诉您内容中编码的内容.
最外面的编码通常是序列或集合,它们是复合基本类型.在您的编码中,最外面的编码是ProxyCertInfoExtension,它是可选ProxyCertPathLengthConstraint和ProxyPolicy的序列.您的编码如下:
ProxyCertInfoExtension { [ProxyCertPathLengthConstraint] ProxyPolicy }
回顾一下编码规则,ProxyCertPathLengthConstraint只是一个整数,因此您的编码确实是:
ProxyCertInfoExtension { [Integer] ProxyPolicy }
编码规则将ProxyPolicy定义为policyLanguage和可选策略的序列.因此,我们可以更新编码表示形式,如下所示:
ProxyCertInfoExtension { [Integer] { policyLanguage [policy] } }
编码规则将策略指定为八位位组字符串(仅一定数量的字节).因此进一步简化会产生:
ProxyCertInfoExtension { [Integer] { policyLanguage [Octet String] } }
取决于对象标识符,编码是以下之一:
ProxyCertInfoExtension { [Integer] { id-ppl-anyLanguage [Octet String] } }
ProxyCertInfoExtension { [Integer] { id-ppl-inheritAll [Octet String] } }
ProxyCertInfoExtension { [Integer] { id-ppl-independent [Octet String] } }
我将尝试一个 unested 示例ProxyCertPathLengthConstraint = 64policyLanguage = id-ppl-anyLanguagepolicy ="test"我将从政策长度为04开始由内而外这是一个可打印的字符串,因此class = 00(通用)primitive/constructed = 0(primitive)且tag-number = 0x13标头字节为0x13长度= 4,因此长度字节为0x04ASCII中的测试"为0x74 0x65 0x73 0x74策略的编码为0x13 0x04 0x74 0x65 0x73 0x74
id-ppl-anyLanguage是一个对象标识符,因此class = 00(通用)primitive/constructed = 0(primitive)且tag-number = 0x06标头字节为0x06id-ppl-anyLanguage的值是"1.3.6.1.5.5.7.21.0"长度= 18,因此长度字节为0x12"1.3.6.1.5.5.7.21.0" = 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10policyLanguage的编码是0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10
proxyPolicy是一个序列,因此class = 00(通用)primitive/constructed = 0(primitive)且tag-number = 0x10标头字节为0x10长度= lengthof(policyLanguage)+ lengthof(policy)=(lengthof(policyLanguage标头)+ lengthof(policyLanguage内容))+(lengthof(policyheaders)+ lengthof(策略内容))=(2 + 4)+(2 + 18)= 6 + 20 = 26长度= 26,因此长度字节为0x1A内容为policyLanguage,后跟policy =0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74proxyPolicy的编码为0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x73 0x74
ProxyCertPathLengthConstraint是一个整数,因此class = 00(通用)primitive/constructed = 0(primitive),并且标记数= 0x02标头字节为0x02长度= 0x01内容= 0x40编码为0x02 0x01 0x40
ProxyCertInfoExtension是一个SEQUENCE,因此class = 00(通用)primitive/constructed = 0(primitive)和tag-number = 0x10标头字节为0x10长度= lengthof(pCPathLenConstraint)+ lengthof(proxyPolicy)= lengthof(pCPathLenConstraint标头)+ lengthof(pCPathLenConstraint内容)+(lengthof(proxyPolicy标头)+ lengthof(proxyPolicy内容))=(2 +1)+(2 + 26)= 3 + 28 = 31 = 0x1Fcontent = pCPathLenConstraint,后跟proxyPolicy= 0x02 0x01 0x40 0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x040x740编码为0x10 0x1F 0x02 0x01 0x40 0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x740x
I'm trying to create a X509 Request for a Proxy Certificate (ProxyCertInfo Extension RFC3820) in C (OpenSSL), but I cannot figure out how the datastructures of the ProxyCertInfo should be defined. The RFC defines the ASN.1 language as follows:
PKIXproxy88 { iso(1) identified-organization(3) dod(6)
internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
proxy-cert-extns(25) }
DEFINITIONS EXPLICIT TAGS ::=
BEGIN
-- EXPORTS ALL --
-- IMPORTS NONE --
-- PKIX specific OIDs
id-pkix OBJECT IDENTIFIER ::=
{ iso(1) identified-organization(3)
dod(6) internet(1) security(5) mechanisms(5) pkix(7) }
-- private certificate extensions
id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
-- Locally defined OIDs
-- The proxy certificate extension
id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pe 14 }
-- Proxy certificate policy languages
id-ppl OBJECT IDENTIFIER ::= { id-pkix 21 }
-- Proxy certificate policies languages defined in
id-ppl-anyLanguage OBJECT IDENTIFIER ::= { id-ppl 0 }
id-ppl-inheritAll OBJECT IDENTIFIER ::= { id-ppl 1 }
id-ppl-independent OBJECT IDENTIFIER ::= { id-ppl 2 }
-- The ProxyCertInfo Extension
ProxyCertInfoExtension ::= SEQUENCE {
pCPathLenConstraint ProxyCertPathLengthConstraint OPTIONAL,
proxyPolicy ProxyPolicy
}
ProxyCertPathLengthConstraint ::= INTEGER
ProxyPolicy ::= SEQUENCE {
policyLanguage OBJECT IDENTIFIER,
policy OCTET STRING OPTIONAL
}
END
I have looked at the very limited documentation of OpenSSL and cannot find out how to parse this to C data structs. I've also read http://www.openssl.org/docs/apps/asn1parse.html# as it explains how to use the parser for the command line tool, but not how to include this in your own source code.
I have managed to include other extensions to the X509 request already, so I'm relatively sure my only problem is with the formatting of the data structures for this particular extension.
I think your question is "How do I format data as a ProxyCertInfoExtension?" If this in incorrect please let me know.
If you want to know some theory, the best reference I have found is A Layman's Guide to a Subset of ASN.1, BER, and DER.
The code section in your question is a description of how the data for the ProxyCertInfoExtension is encoded. Think of the encoding description as a grammar that could be processed by a parser generator, much as yacc take a grammar as input and outputs C code. In fact at least one ASN.1 parser generator exists ASN1C
ASN.1 encodings may be of variable size. The data begins with an outtermost or top level ASN.1 encoding. Each ASN.1 encoding may contain one or more ASN.1 encoding inside itself. In this way ASN.1 is recursive.
An ASN.1 encoding is composed of a header, a length, optional content, and an optional end.
ASN.1 encoding { Header length [content] [end] }
The header is composed of a Class type, a Primitive/Constructed bit, and a Tag-Number. If the Tag-Number is larger than 63 then the Tag-Number will span multiple bytes. This means that the header may be one byte long or many bytes long depending on the value of the Tag-Number. The header is byte aligned meaning that is always some number of bytes long.
ASN.1 header { ClassType Primitive/Constructed Tag-number }
The length may also be one byte to many bytes long depending on the value of the length. Again the Length is byte aligned.
The Class type and the Tag-Number tell you what is encoded in the Content.
The outtermost encoding is usually a sequence or set, which are compound basic types. In your encoding, the outtermost encoding is the ProxyCertInfoExtension which is a sequence of an optional ProxyCertPathLengthConstraint and a ProxyPolicy. Your encoding looks like this:
ProxyCertInfoExtension { [ProxyCertPathLengthConstraint] ProxyPolicy }
Looking back at the encoding rules, ProxyCertPathLengthConstraint is just an integer, so your encoding is really:
ProxyCertInfoExtension { [Integer] ProxyPolicy }
The encoding rules define a ProxyPolicy as a sequence of a policyLanguage and an optional policy. So we can update the encoding representation to look like this:
ProxyCertInfoExtension { [Integer] { policyLanguage [policy] } }
The encoding rules specify policy as an Octet String (Just some number of bytes). So firther simplification produces:
ProxyCertInfoExtension { [Integer] { policyLanguage [Octet String] } }
Depending on the object identifier, the encoding is one of:
ProxyCertInfoExtension { [Integer] { id-ppl-anyLanguage [Octet String] } }
ProxyCertInfoExtension { [Integer] { id-ppl-inheritAll [Octet String] } }
ProxyCertInfoExtension { [Integer] { id-ppl-independent [Octet String] } }
I'll try an untested exampleProxyCertPathLengthConstraint=64policyLanguage=id-ppl-anyLanguagepolicy="test"I'll work inside out starting with policy length is 04this is a printable string so class=00(universal) primitive/constructed=0(primitive) and tag-number=0x13the header byte is 0x13 length=4, so length byte is 0x04"test" in ascii is 0x74 0x65 0x73 0x74 the encoding for policy is 0x13 0x04 0x74 0x65 0x73 0x74
id-ppl-anyLanguage is an Object Identifier so class=00(universal) primitive/constructed=0(primitive) and tag-number=0x06the header byte is 0x06 the value for id-ppl-anyLanguage is "1.3.6.1.5.5.7.21.0"length=18, so length byte is 0x12"1.3.6.1.5.5.7.21.0" = 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10the encoding for policyLanguage is 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10
proxyPolicy is a sequence so class=00(universal) primitive/constructed=0(primitive) and tag-number=0x10the header byte is 0x10 the length= lengthof(policyLanguage) + lengthof(policy) = (lengthof(policyLanguage headers) + lengthof (policyLanguage content)) + (lengthof(policyheaders) + lengthof (policy content)) = (2 + 4) + (2 + 18) = 6 + 20 = 26length=26, so length byte is 0x1Athe content is policyLanguage followed by policy = 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74the encoding for proxyPolicy is0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74
ProxyCertPathLengthConstraint is a integer so class=00(universal) primitive/constructed=0(primitive) and tag-number=0x02the header byte is 0x02the length=0x01the content=0x40the encoding is 0x02 0x01 0x40
ProxyCertInfoExtension is a SEQUENCE so class=00(universal) primitive/constructed=0(primitive) and tag-number=0x10the header byte is 0x10the length = lengthof(pCPathLenConstraint) + lengthof(proxyPolicy)= lengthof(pCPathLenConstraint headers) + lengthof (pCPathLenConstraint content)) + (lengthof(proxyPolicy headers) + lengthof(proxyPolicy content)) = (2 + 1) + (2 + 26) = 3 + 28 = 31 = 0x1Fthe content= pCPathLenConstraint followed by proxyPolicy= 0x02 0x01 0x40 0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74the encoding is 0x10 0x1F 0x02 0x01 0x40 0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74
这篇关于X.509v3 ASN.1到C的数据结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!