通过OpenSSL获取证书扩展属性之二:“密钥用法”和"增强型密钥用法"
2015-09-10 15:31
381 查看
上篇文章讲述了如何使用OpenSSL获取证书的“基本约束”扩展属性:通过OpenSSL获取证书扩展属性之一:“基本约束”
今天继续讲述如何获取“密钥用法”和“增强型密钥用法”这两个扩展属性。"密钥用法"限定了该证书的用途类型,主要分数据签名和数据加密两大类(有的证书同时具有这两类用途)。如下图所示,该证书的用途类型为“数据签名”:
而“增强型密钥用法”属性进一步指明具体用途, 如下图所以,该证书的具体用途为“邮件签名”和“身份验证签名”:
通过OpenSSL获取这两个扩展属性,具体步骤如下:
1、调用X509_get_ext_d2i()获取对应的扩展属性对象;
2、解析对象结构体,得到具体的用法类型。其中:
“密钥用法”使用结构体ASN1_BIT_STRING表示,其具体定义如下:
而"增强型密钥用法"使用ASN1_OBJECT STACK返回。具体定义如下:
3、根据用法类型,返回用法名称。
基于以上过程,下面给出获取“密钥用法”和“增强型密钥用法”两个扩展属性的完整代码。“密钥用法”扩展属性的获取代码如下:
今天继续讲述如何获取“密钥用法”和“增强型密钥用法”这两个扩展属性。"密钥用法"限定了该证书的用途类型,主要分数据签名和数据加密两大类(有的证书同时具有这两类用途)。如下图所示,该证书的用途类型为“数据签名”:
而“增强型密钥用法”属性进一步指明具体用途, 如下图所以,该证书的具体用途为“邮件签名”和“身份验证签名”:
通过OpenSSL获取这两个扩展属性,具体步骤如下:
1、调用X509_get_ext_d2i()获取对应的扩展属性对象;
2、解析对象结构体,得到具体的用法类型。其中:
“密钥用法”使用结构体ASN1_BIT_STRING表示,其具体定义如下:
<span style="font-size:12px;">struct asn1_string_st { int length; int type; unsigned char *data; /* The value of the following field depends on the type being * held. It is mostly being used for BIT_STRING so if the * input data has a non-zero 'unused bits' value, it will be * handled correctly */ long flags; };</span>其成员变量pbData[0]和pbData[1]表明了用途类型,可以是下面定义的一种、或几种用途的组合。
<span style="font-size:12px;">#define KU_DIGITAL_SIGNATURE 0x0080 #define KU_NON_REPUDIATION 0x0040 #define KU_KEY_ENCIPHERMENT 0x0020 #define KU_DATA_ENCIPHERMENT 0x0010 #define KU_KEY_AGREEMENT 0x0008 #define KU_KEY_CERT_SIGN 0x0004 #define KU_CRL_SIGN 0x0002 #define KU_ENCIPHER_ONLY 0x0001 #define KU_DECIPHER_ONLY 0x8000</span>
而"增强型密钥用法"使用ASN1_OBJECT STACK返回。具体定义如下:
<span style="font-size:12px;">typedef struct asn1_object_st { const char *sn,*ln; int nid; int length; const unsigned char *data; /* data remains const after init */ int flags; /* Should we free this one */ } ASN1_OBJECT;</span>
<span style="font-size:12px;">typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;</span>
3、根据用法类型,返回用法名称。
基于以上过程,下面给出获取“密钥用法”和“增强型密钥用法”两个扩展属性的完整代码。“密钥用法”扩展属性的获取代码如下:
ULONG COpenSSLCertificate::_GetExtKeyUsage(X509 *pX509Cert, LPSTR lpscProperty, ULONG* pulLen) { char value[512] = {0}; ASN1_BIT_STRING* lASN1UsageStr; if (!m_pX509) { return CERT_ERR_INVILIDCALL; } if (!pulLen) { return CERT_ERR_INVALIDPARAM; } lASN1UsageStr = (ASN1_BIT_STRING *)X509_get_ext_d2i(m_pX509, NID_key_usage, NULL, NULL); if (lASN1UsageStr) { char temp[32] = {0}; unsigned short usage = lASN1UsageStr->data[0]; if(lASN1UsageStr->length > 1) { usage |= lASN1UsageStr->data[1] << 8; } sprintf_s(temp, 32, "(%x)", usage); if (usage & KU_DIGITAL_SIGNATURE) { strcat_s(value, 512, "Digital Signature, "); } if (usage & KU_NON_REPUDIATION) { strcat_s(value, 512, "Non-Repudiation, "); } if (usage & KU_KEY_ENCIPHERMENT) { strcat_s(value, 512, "Key Encipherment, "); } if (usage & KU_DATA_ENCIPHERMENT) { strcat_s(value, 512, "Data Encipherment, "); } if (usage & KU_KEY_AGREEMENT) { strcat_s(value, 512, "Key Agreement, "); } if (usage & KU_KEY_CERT_SIGN) { strcat_s(value, 512, "Certificate Signature, "); } if (usage & KU_CRL_SIGN) { strcat_s(value, 512, "CRL Signature, "); } strcat_s(value, 512, temp); } else { return CERT_ERR_ATTR_NOTEXIST; } if (!lpscProperty) { *pulLen = strlen(value) + 1; } if (*pulLen < (strlen(value) + 1)) { return CERT_ERR_BUFFER_TOO_SMALL; } strcpy_s(lpscProperty, *pulLen, value); return CERT_ERR_OK; }“增强型密钥用法”的获取代码如下:
ULONG COpenSSLCertificate::_GetExtEnhancedKeyUsage(X509 *pX509Cert, LPSTR lpscProperty, ULONG* pulLen) { int i = 0; char value[512] = {0}; EXTENDED_KEY_USAGE* extusage; if (!m_pX509) { return CERT_ERR_INVILIDCALL; } if (!pulLen) { return CERT_ERR_INVALIDPARAM; } extusage = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i(m_pX509, NID_ext_key_usage, NULL, NULL); if (!extusage) { return CERT_ERR_ATTR_NOTEXIST; } long id[] = {OBJ_email_protect}; for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { int j = 0; char obj_id[128] = {0}; char obj_name[128] = {0}; ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(extusage, i); OBJ_obj2txt(obj_id, sizeof(obj_id), obj, 1); OBJ_obj2txt(obj_name, sizeof(obj_name), obj, 0); if (strlen(value) > 0) { strcat_s(value, 512, "; "); } strcat_s(value, 512, obj_name); strcat_s(value, 512, " ("); strcat_s(value, 512, obj_id); strcat_s(value, 512, ")"); } sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); if (!lpscProperty) { *pulLen = strlen(value) + 1; } if (*pulLen < (strlen(value) + 1)) { return CERT_ERR_BUFFER_TOO_SMALL; } strcpy_s(lpscProperty, *pulLen, value); return CERT_ERR_OK; }
相关文章推荐
- Linux:闪光的宝石,智慧(下一个)
- Linux下配置GitHub
- 依赖注入及AOP简述(一)——“依赖”的概念
- linux 启动weblogic的某服务报错
- linux目录结构
- Virtualbox中Linux添加一个新磁盘
- 依赖注入及AOP简述(二)——工厂和ServiceLocator
- nginx 绑定域名(centos linux)
- linux下软件管理
- 使用OpenCV画折线图
- Nginx的slab page内存缓存机制
- nginx配置
- Nginx源码main函数解读
- docker安装on mac os x
- docker基础
- 大讲台分享:怎么看Hadoop Summit 2015和Spark Summit 2015?
- linux select 系统调用
- Nginx配置优化
- linux内核学习笔记之——list_for_each_entry
- mysql linux 安装