C++ 使用OpenSSL查询X509证书上的扩展

C++ 使用OpenSSL查询X509证书上的扩展,c++,ssl,openssl,C++,Ssl,Openssl,我正在使用OpenSSL库的X509证书类,需要查询“密钥使用”扩展 在放弃了OpenSSL的vapourware“文档”之后,一些暗中搜索的网站最终透露我需要打电话 X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx) 通过搜索对象,h头显示了正确的NID 问题是,这个调用返回一个指向void的指针,它显然可以指向各种结构,这取决于所请求的扩展 由于所有这些似乎都没有被记录下来,因此没有办法弄清楚如何解析函数返回的内容 有人能给我指

我正在使用OpenSSL库的X509证书类,需要查询“密钥使用”扩展

在放弃了OpenSSL的vapourware“文档”之后,一些暗中搜索的网站最终透露我需要打电话

X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx) 
通过搜索对象,h头显示了正确的NID

问题是,这个调用返回一个指向void的指针,它显然可以指向各种结构,这取决于所请求的扩展

由于所有这些似乎都没有被记录下来,因此没有办法弄清楚如何解析函数返回的内容

有人能给我指出一个真正讨论这个问题的文档,而不是仅仅列出我自己能找到的东西(函数配置文件,它来自哪个文件,等等)

第二个参数(nid)确定返回的类型

查看此代码:


对于密钥用法NID,它似乎返回一个ASN1_位_字符串。(第361行)。

阅读密钥用法的最简单解决方案似乎是

X509* x509_cert = ...
// without X509_check_ca x509_cert->ex_kusage always returns 0 (no idea why)
int ca = X509_check_ca(x509_cert);
unsigned long usage = x509_cert->ex_kusage;
结果值在opensc/pkcs15 init.h中定义

SC_PKCS15INIT_X509_DIGITAL_SIGNATURE     0x0080UL
SC_PKCS15INIT_X509_NON_REPUDIATION       0x0040UL
SC_PKCS15INIT_X509_KEY_ENCIPHERMENT      0x0020UL
SC_PKCS15INIT_X509_DATA_ENCIPHERMENT     0x0010UL
SC_PKCS15INIT_X509_KEY_AGREEMENT         0x0008UL
SC_PKCS15INIT_X509_KEY_CERT_SIGN         0x0004UL
SC_PKCS15INIT_X509_CRL_SIGN              0x0002UL
我是通过找到openssl源文件的以下代码来解决这个问题的

/* Handle key usage */
if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
    if(usage->length > 0) {
        x->ex_kusage = usage->data[0];
        if(usage->length > 1) 
        x->ex_kusage |= usage->data[1] << 8;
    } else x->ex_kusage = 0;
    x->ex_flags |= EXFLAG_KUSAGE;
    ASN1_BIT_STRING_free(usage);
}
/*处理密钥使用*/
if((用法=X509\u get\u ext\u d2i(x,NID\u key\u用法,NULL,NULL))){
如果(用法->长度>0){
x->ex_kusage=用法->数据[0];
如果(使用->长度>1)
x->ex|u kusage |=用法->数据[1]ex|u kusage=0;
x->ex|u flags |=EXFLAG_KUSAGE;
无ASN1位字符串(使用);
}

我没有答案,但我要强调一下OpenSSL的文档质量……我现在也在使用它(刚刚开始),试图找到简单操作以外的示例或文档是很可怕的……我感觉到了你的痛苦。我知道如何使用API的唯一方法是使用命令行工具(源代码),修改代码(注释掉我不需要的命令行参数)并进行跟踪。从那里我可以使用API“docs”为了填补空白。My
x509.h
包含警告:
/*这些包含x509结构中许多元素的各种扩展值的副本*/
,包括
ex\u kusage
。这可能就是为什么在调用该函数之前它是零。如果设置了
EXFLAG\u,则必须检查
EXFLAG\u的值ode>这意味着设置了
ex\u kusage
ex\u xkusage
,您不需要调用
X509\u check\u ca
,您可以查看
v3\u purple.c
了解更多详细信息