使用CryptoAPI获取证书扩展属性之一:“基本约束”

来源:互联网 发布:添加网络共享打印机 编辑:程序博客网 时间:2024/05/20 04:47

        前面通过一系列文章,讲述了如使用CryptoAPI解析证书的基本项,现在我们来看看如何获取证书的扩展项。

        目前CA中心颁发的证书,都有一些扩展项属性,用来限定证书的用途、提供颁发者信息、以及CRL的下载地址等等。在下图中,红色区域内的属性都为证书的扩展属性。


        在CryptoAPI中,提供了获取这些扩展属性的方法。今天,我们先看看如何获取证书扩展属性中的“基本约束”属性。具体可以通过以下步骤来实现:

1、调用函数CertFindExtension()找到扩展对象

该函数的定义如下:

PCERT_EXTENSION WINAPI CertFindExtension(  _In_ LPCSTR         pszObjId,  _In_ DWORD          cExtensions,  _In_ CERT_EXTENSION rgExtensions[]);

其中:

第一个参数pszObjId为对象的ID,要获取“基本约束”扩展对象需要指定为szOID_BASIC_CONSTRAINTS2;

第二个参数是指扩展属性数组的成员个数,由证书信息结构体中的cExtension成员指定;

第三个参数为扩展属性数组,由证书信息结构体中的rgExtension成员指定。

2、使用函数CryptDecodeObject()解码对象,得到属性结构体

在CryptoAPI中,微软为“基本约束”扩展属性定义了结构体,具体如下:

typedef struct _CERT_BASIC_CONSTRAINTS2_INFO {    BOOL                    fCA;    BOOL                    fPathLenConstraint;    DWORD                   dwPathLenConstraint;} CERT_BASIC_CONSTRAINTS2_INFO, *PCERT_BASIC_CONSTRAINTS2_INFO;

其中:

第一个成员fCA,表明该证书可否作为CA证书签发下一级证书。一般用户证书该值都为FALSE;

第二个成员fPathLenConstraint,表明当作CA证书时,是否有级别限制;

第三个成员dwPathLenConstraint,只有到fPathLenConstraint为TRUE时有效,表明具体可以签发的证书级别。

3、解析结构体中的值

如果我们得到了上面结构体的具体值,就可以根据值来显示“基本约束”的属性了。

        完整的解析“基本约束”属性的函数代码如下:

ULONG CCSPCertificate::_GetExtBasicConstraints(PCCERT_CONTEXT pCertContext,    LPSTR lpscProperty,    ULONG* pulLen){ULONG ulRes = 0;ULONG ulDataLen = 512;ULONG ulPropertyLen = 512;BYTE btData[512] = {0};CHAR csProperty[512] = {0};PCERT_EXTENSION pCertExt = NULL;if (!pCertContext){return CERT_ERR_INVILIDCALL;}if (!pulLen){return CERT_ERR_INVALIDPARAM;}pCertExt = CertFindExtension(szOID_BASIC_CONSTRAINTS2, pCertContext->pCertInfo->cExtension, pCertContext->pCertInfo->rgExtension); if (pCertExt){PCERT_BASIC_CONSTRAINTS2_INFO pInfo = (PCERT_BASIC_CONSTRAINTS2_INFO)btData;if (CryptDecodeObject(GLOBAL_ENCODING_TYPE, szOID_BASIC_CONSTRAINTS2, pCertExt->Value.pbData, pCertExt->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, pInfo, &ulDataLen)){if (pInfo->fCA) {strcat_s(csProperty, 512, "Subject Type=CA; ");}else {strcat_s(csProperty, 512, "Subject Type=End Entity; ");}if (pInfo->fPathLenConstraint) {CHAR csTemp[128] = {0};sprintf_s(csTemp, 128, "Path Length Constraint=%d", pInfo->dwPathLenConstraint);strcat_s(csProperty, 512, csTemp);}else{strcat_s(csProperty, 512, "Path Length Constraint=None");}}else{return GetLastError();}}else{pCertExt = CertFindExtension(szOID_BASIC_CONSTRAINTS, pCertContext->pCertInfo->cExtension, pCertContext->pCertInfo->rgExtension); if (pCertExt){PCERT_BASIC_CONSTRAINTS_INFO pInfo = (PCERT_BASIC_CONSTRAINTS_INFO)btData;if (CryptDecodeObject(GLOBAL_ENCODING_TYPE, szOID_BASIC_CONSTRAINTS, pCertExt->Value.pbData, pCertExt->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, pInfo, &ulDataLen)){if (pInfo->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG) {strcat_s(csProperty, 512, "Subject Type=CA; ");}else if (pInfo->SubjectType.pbData[0] & CERT_END_ENTITY_SUBJECT_FLAG) {strcat_s(csProperty, 512, "Subject Type=End Entity; ");}else{strcat_s(csProperty, 512, "Subject Type=Unknown; ");}if (pInfo->fPathLenConstraint) {CHAR csTemp[128] = {0};sprintf_s(csTemp, 128, "Path Length Constraint=%d", pInfo->dwPathLenConstraint);strcat_s(csProperty, 512, csTemp);}else{strcat_s(csProperty, 512, "Path Length Constraint=None");}}else{return GetLastError();}}else{return CERT_ERR_ATTR_NOTEXIST;}}if (!lpscProperty){*pulLen = strlen(csProperty) + 1;}if (*pulLen < (strlen(csProperty) + 1)){return CERT_ERR_BUFFER_TOO_SMALL;}strcpy_s(lpscProperty, *pulLen, csProperty);return CERT_ERR_OK;}


0 0
原创粉丝点击