我想将 Procuration 扩展添加到我的证书中。因此我使用工具 XCA,它使用 OpenSSL conf 来创建证书。
这是 ASN1 结构:
ProcurationSyntax ::= SEQUENCE
{
country [1] EXPLICIT PrintableString OPTIONAL
typeOfSubstitution[2] EXPLICIT DirectoryString OPTIONAL
signingFor [3] EXPLICIT SigningFor
}
SigningFor ::= CHOICE
{
thirdPerson GeneralName
certRef IssuerSerial
}
IssuerSerial ::= SEQUENCE
{
issuer GeneralNames
serial CertificateSerialNumber
issuerUID UniqueIdentifier OPTIONAL
}
现在我想通过 openssl conf 将此扩展添加为任意扩展(https://www.openssl.org/docs/man1.1.0/apps/x509v3_config.html#ARBITRARY-EXTENSIONS)
我的代码看起来是这样的,但我坚持其余部分 - 第三人称的东西:
1.3.36.8.3.2=ASN1:SEQUENCE:proc_sect
[proc_sect]
country=EXPLICIT:1,IA5STRING:EN
typeOfSubtitution=EXPLICIT:2,IA5STRING:My Type of Substitution
thirdPerson OR certRef=EXPLICIT:3,TODO
因此,如果有人可以提供缺失的其余部分(即 thirdPerson 和 certRef)的有效示例代码,那将会非常有帮助。
答案1
整个事情的最小例子
1.3.36.8.3.2 = ASN1:SEQUENCE:procuration
[procuration]
country = EXP:1, PRINTABLE:EN
typeOfSubstitution = EXP:2, UTF8:My Type of Substitution
thirdPerson = EXP:3, EXP:0, EXP:1, IA5:[email protected]
为了获得测试用例,我使用以下 ASN.1 值符号编译了asn1-游乐场:
procuration ProcurationSyntax ::= {
country "EN",
typeOfSubstitution utf8String : "My Type of Substitution",
signingFor thirdPerson rfc822Name : "[email protected]"
}
我使用了这个模式:
-- RFC 5280 Appendix A.1
PKIX1Explicit88 DEFINITIONS EXPLICIT TAGS ::=
BEGIN
Name ::= CHOICE { -- only one possibility for now --
rdnSequence RDNSequence }
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
DistinguishedName ::= RDNSequence
RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value AttributeValue }
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= ANY -- DEFINED BY AttributeType
DirectoryString ::= CHOICE {
teletexString TeletexString (SIZE (1..MAX)),
printableString PrintableString (SIZE (1..MAX)),
universalString UniversalString (SIZE (1..MAX)),
utf8String UTF8String (SIZE (1..MAX)),
bmpString BMPString (SIZE (1..MAX)) }
CertificateSerialNumber ::= INTEGER
UniqueIdentifier ::= BIT STRING
END
-- RFC 5280 Appendix A.2
PKIX1Implicit88 DEFINITIONS IMPLICIT TAGS ::=
BEGIN
IMPORTS
DirectoryString,
Name
FROM PKIX1Explicit88;
GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
GeneralName ::= CHOICE {
otherName [0] AnotherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
--x400Address [3] ORAddress,
directoryName [4] Name,
--ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER }
AnotherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT ANY DEFINED BY type-id }
END
-- Foo
Procuration-Schema DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
IMPORTS
CertificateSerialNumber, DirectoryString, UniqueIdentifier FROM PKIX1Explicit88
GeneralName, GeneralNames FROM PKIX1Implicit88;
ProcurationSyntax ::= SEQUENCE
{
country [1] EXPLICIT PrintableString OPTIONAL,
typeOfSubstitution[2] EXPLICIT DirectoryString OPTIONAL,
signingFor [3] EXPLICIT SigningFor
}
SigningFor ::= CHOICE
{
thirdPerson GeneralName,
certRef IssuerSerial
}
IssuerSerial ::= SEQUENCE
{
issuer GeneralNames,
serial CertificateSerialNumber,
issuerUID UniqueIdentifier OPTIONAL
}
END
这个 OpenSSL.cfg 也可能有效:
[v3]
subjectAltName = @alt_names
1.3.36.8.3.2 = ASN1:SEQUENCE:procuration
[alt_names]
DNS.1 = ldap.example.com
DNS.2 = ldap1.example.com
[procuration]
country = EXPLICIT:1, PRINTABLE:EN
typeOfSubstitution = EXPLICIT:2, UTF8:My Type of Substitution
thirdPerson = EXPLICIT:3, EXPLICIT:0, IMP:1, IA5:[email protected]
#certRef = EXPLICIT:3, IMP:1, SEQUENCE:cert_ref
#[cert_ref]
#issuer = IMP:0, SEQUENCE:proc_certref_issuer
#serial = IMP:1, INTEGER:12345
#[proc_certref_issuer]
#1 = IMP:1, IA5:bar
#2 = EXP:4, IMP:1, IMP:16U, FORMAT:HEX, #OCTETSTRING:3035310b30090603550406130245553110300e060355040a0c074578616d706c653114301206035504030c0b4672656420466f6f626172
[过程]
注意各种不同的字符串类型。
country
定义为 PrintableString (它只是一个子集IA5String 的):
country = EXPLICIT:1, PRINTABLE:EN
typeOfSubstitution
定义为目录字符串,它是 TeletexString、PrintableString、UniversalString、UTF8String 或 BMPString 之间的选择 - 其中一些是 IA5String 的子集,其他是超集,但实际的IA5String 实际上并不允许。因此,让我们使用 UTF-8 Unicode:
; ┌── tag for ProcurationSyntax sequence
; ¦
typeOfSubstitution = EXPLICIT:2, UTF8:My Type of Substitution
(在线 asn1step 说 DirectoryString 选择没有单独的标签;我猜这是因为所有可能的选择都已经有独特的“通用”标签。)
因为signingFor
thirdPerson
是vs之间的选择certRef
,你可以包括一个或者另一个,由您来选择合适的类型。
thirdPerson
定义为 [0]通用名称,这是各种其他类型之间的选择——与 subjectAltName 扩展中的选择完全相同。例如,您可以包含电子邮件地址(格式为 rfc822Name [1] IA5String):
; ┌── tag for ProcurationSyntax sequence
; │ ┌── tag for SigningFor choice
; │ │ ┌── tag for GeneralName choice
; ¦ ¦ ¦
thirdPerson = EXP:3, EXP:0, EXP:1, IA5:[email protected]
或者 dNSName (定义为 [2] IA5String):
thirdPerson = EXP:3, EXP:0, EXP:2, IA5:example.com
(或者包含小猫的 MPEG 视频的 otherName。)
如果你想选择一个certRef
,这是一个完整的嵌套序列。
; ┌── tag for ProcurationSyntax sequence
; │ ┌── tag for SigningFor choice
; ¦ ¦
certRef = EXP:3, IMP:1, SEQUENCE:proc_certref
[proc_certref]
在该[proc_certref]
部分内,您必须至少定义issuer
和serial
。
issuer
是通用名称,它是 GeneralName 值的序列。
issuer = IMP:0, SEQUENCE:proc_certref_issuer
; └── tag for IssuerSerial sequence
serial
是证书序列号只是一个整数。
serial = IMP:1, INTEGER:0x123456
笔记:我非常不确定这些是否应该有隐式标签。
[proc_certref_issuer]
太棒了。又一个部分,还有通用名称仅此而已。幸运的是,只有一个。不幸的是,有超过零个。
最简单的有效值是单个 GeneralName,它只是一个 rfc822Name 或一个 dNSName(都是 IA5String):
issuer.0 = IMP:1, IA5:[email protected]
; └── tag for GeneralName choice
…实际上,我们已经做过一次 directoryName 了,不是吗?因为这issuer.0
是一个 GeneralName,所以它使用与admissionAuthority
你的以前的扩展(具有相同的标记和所有内容)——所以我不会再次尝试在这里实现它。