使用 OpenSSL(以编程方式)向 PKCS#10 请求添加自定义扩展
Adding custom extension to PKCS#10 request using OpenSSL (programatically)
我想向通过 OpenSSL 创建的 PKCS#10 请求添加自定义扩展。请求生成和签名代码工作正常。
我可以通过它的 nid 添加已知的扩展,像这样(我从 Delphi 调用 OpenSSL):
as := 'critical,digitalSignature';
ext := X509V3_EXT_conf_nid(nil,nil,NID_key_usage,addr(as[1]));
sk_push(exts,ext);
X509_REQ_add_extensions(req,exts)
这按预期工作。现在我有了扩展的 OID 和数据,但我没有 nid。据我所知,我可以创建一个 nid:
NID:= OBJ_create(PAnsiChar(aoid),PAnsiChar(ashortname),PAnsiChar(alongname));
但是如果我尝试使用这个扩展,我会收到未知扩展错误。我发现我需要告诉 OpenSSL 如何处理我的扩展,例如通过使用类似的扩展:
X509V3_EXT_add_alias(nid,NID_netscape_comment);
但问题是,如果我没有类似的扩展名来给它取别名怎么办?例如我想添加 szOID_REQUEST_CLIENT_INFO (1.3.6.1.4.1.311.21.20) 这是一个整数序列和 3 个 UTF8Strings:
SEQUENCE
{
clientId INTEGER,
MachineName UTF8STRING,
UserName UTF8STRING,
ProcessName UTF8STRING
}
或 szOID_ENROLLMENT_CSP_PROVIDER (1.3.6.1.4.1.311.13.2.2) 基本上是一个 BMP 字符串。
我有一个从 ASN.1 创建 DER 字节的代码,因此我可以轻松地将扩展数据创建为 OpenSSL 的原始字节,但我没有找到创建此类扩展的方法。基本上 man x509v3_config
中描述了类似的东西
1.2.3.4=DER:01:02:03:04
我终于成功了。主要的困惑是我不想添加扩展名而是添加属性。扩展只能包含 OCTET STRING 数据。这可以通过如下指定数据来实现:
data := 'DER:310C160A3....';
ext := X509V3_EXT_conf_nid(nil,nil,nid,addr(data[1]));
在这种情况下,X509V3_EXT_conf_nid 不会抱怨未知扩展(即使没有别名)并创建将采用以下形式的扩展:
377:d=7 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.13.2.3
389:d=7 hl=2 l= 15 prim: OCTET STRING [HEX DUMP]:310C160A362E312E373630312E3230
扩展名将始终是 OCTET STRING,因为它应该是 DER 编码数据。
但是该属性与扩展具有相同的深度,并且可以包含任何 DER 数据。所以
data := loadfromhex('31091607312E322E33234');
X509_REQ_add1_attr_by_nid(req,nid,ASN1_SEQUENCE,addr(data[1]),length(data));
将产生所需的输出:
377:d=4 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.13.2.3
389:d=4 hl=2 l= 9 cons: SET
391:d=5 hl=2 l= 7 prim: IA5STRING :1.2.3.4
我想向通过 OpenSSL 创建的 PKCS#10 请求添加自定义扩展。请求生成和签名代码工作正常。
我可以通过它的 nid 添加已知的扩展,像这样(我从 Delphi 调用 OpenSSL):
as := 'critical,digitalSignature';
ext := X509V3_EXT_conf_nid(nil,nil,NID_key_usage,addr(as[1]));
sk_push(exts,ext);
X509_REQ_add_extensions(req,exts)
这按预期工作。现在我有了扩展的 OID 和数据,但我没有 nid。据我所知,我可以创建一个 nid:
NID:= OBJ_create(PAnsiChar(aoid),PAnsiChar(ashortname),PAnsiChar(alongname));
但是如果我尝试使用这个扩展,我会收到未知扩展错误。我发现我需要告诉 OpenSSL 如何处理我的扩展,例如通过使用类似的扩展:
X509V3_EXT_add_alias(nid,NID_netscape_comment);
但问题是,如果我没有类似的扩展名来给它取别名怎么办?例如我想添加 szOID_REQUEST_CLIENT_INFO (1.3.6.1.4.1.311.21.20) 这是一个整数序列和 3 个 UTF8Strings:
SEQUENCE
{
clientId INTEGER,
MachineName UTF8STRING,
UserName UTF8STRING,
ProcessName UTF8STRING
}
或 szOID_ENROLLMENT_CSP_PROVIDER (1.3.6.1.4.1.311.13.2.2) 基本上是一个 BMP 字符串。
我有一个从 ASN.1 创建 DER 字节的代码,因此我可以轻松地将扩展数据创建为 OpenSSL 的原始字节,但我没有找到创建此类扩展的方法。基本上 man x509v3_config
中描述了类似的东西1.2.3.4=DER:01:02:03:04
我终于成功了。主要的困惑是我不想添加扩展名而是添加属性。扩展只能包含 OCTET STRING 数据。这可以通过如下指定数据来实现:
data := 'DER:310C160A3....';
ext := X509V3_EXT_conf_nid(nil,nil,nid,addr(data[1]));
在这种情况下,X509V3_EXT_conf_nid 不会抱怨未知扩展(即使没有别名)并创建将采用以下形式的扩展:
377:d=7 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.13.2.3
389:d=7 hl=2 l= 15 prim: OCTET STRING [HEX DUMP]:310C160A362E312E373630312E3230
扩展名将始终是 OCTET STRING,因为它应该是 DER 编码数据。
但是该属性与扩展具有相同的深度,并且可以包含任何 DER 数据。所以
data := loadfromhex('31091607312E322E33234');
X509_REQ_add1_attr_by_nid(req,nid,ASN1_SEQUENCE,addr(data[1]),length(data));
将产生所需的输出:
377:d=4 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.311.13.2.3
389:d=4 hl=2 l= 9 cons: SET
391:d=5 hl=2 l= 7 prim: IA5STRING :1.2.3.4