上篇文章讲述了如何使用CryptoAPI获取证书的“颁发机构密钥标识”和"使用者密钥标识"扩展属性:使用CryptoAPI获取证书扩展属性之三:“颁发机构密钥标识”和"使用者密钥标识"
今天继续讲述如何获取“CRL分发点”和“颁发机构信息访问”这两个扩展属性。这两个扩展属性在证书中如下图所示:
通过CryptoAPI获取这两个扩展属性,具体步骤如下:
1、调用函数CertFindExtension()找到扩展对象
2、使用函数CryptDecodeObject()解码对象,得到属性结构体。其中“CRL分发点”属性使用结构体 CRL_DIST_POINTS_INFO 表示,具体定义如下:
typedef struct _CRL_DIST_POINTS_INFO {
DWORD cDistPoint;
PCRL_DIST_POINT rgDistPoint;
} CRL_DIST_POINTS_INFO, *PCRL_DIST_POINTS_INFO;
cDistPoint:分发点个数
rgDistPoint:具体分发点信息
“颁发机构信息访问”属性使用结构体CERT_AUTHORITY_INFO_ACCESS表示,具体定义如下:
typedef struct _CERT_AUTHORITY_INFO_ACCESS {
DWORD cAccDescr;
PCERT_ACCESS_DESCRIPTION rgAccDescr;
} CERT_AUTHORITY_INFO_ACCESS, *PCERT_AUTHORITY_INFO_ACCESS,
CERT_SUBJECT_INFO_ACCESS, *PCERT_SUBJECT_INFO_ACCESS;
cAccDescr:信息访问个数
rgAccDescr:具体访问信息
3、解析结构体中的值,得到具体含义
基于以上过程,下面给出获取“CRL分发点”和“颁发机构信息访问”两个扩展属性的完整代码。“CRL分发点”扩展属性的获取代码如下:
ULONG CCSPCertificate::_GetExtCRLDistPoints(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;
}
USES_CONVERSION;
pCertExt = CertFindExtension(szOID_CRL_DIST_POINTS, pCertContext->pCertInfo->cExtension, pCertContext->pCertInfo->rgExtension);
if (!pCertExt)
{
return CERT_ERR_ATTR_NOTEXIST;
}
PCRL_DIST_POINTS_INFO pCRLDistPoint = (PCRL_DIST_POINTS_INFO)btData;
if (CryptDecodeObject( GLOBAL_ENCODING_TYPE, szOID_CRL_DIST_POINTS,
pCertExt->Value.pbData, pCertExt->Value.cbData,
CRYPT_DECODE_NOCOPY_FLAG, pCRLDistPoint, &ulDataLen))
{
CHAR csTemp[8] = {0};
sprintf_s(csTemp, "[%d]", pCRLDistPoint->cDistPoint);
strcat_s(csProperty, 512, csTemp);
for (ULONG ulIndex = 0; ulIndex < pCRLDistPoint->cDistPoint; ulIndex++)
{
for (ULONG ulAltEntry = 0; ulAltEntry < pCRLDistPoint->rgDistPoint[ulIndex].DistPointName.FullName.cAltEntry; ulAltEntry++)
{
strcat_s(csProperty, 512, W2A(pCRLDistPoint->rgDistPoint[ulIndex].DistPointName.FullName.rgAltEntry[ulAltEntry].pwszURL));
strcat_s(csProperty, 512, " ");
}
}
}
else
{
return GetLastError();
}
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;
}
“
颁发机构信息访问
”的获取代码如下:
ULONG CCSPCertificate::_GetExtAuthorityInfoAccess(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;
}
USES_CONVERSION;
pCertExt = CertFindExtension(szOID_AUTHORITY_INFO_ACCESS, pCertContext->pCertInfo->cExtension, pCertContext->pCertInfo->rgExtension);
if (!pCertExt)
{
return CERT_ERR_ATTR_NOTEXIST;
}
PCERT_AUTHORITY_INFO_ACCESS pAuthorityInfo = (PCERT_AUTHORITY_INFO_ACCESS)btData;
if (CryptDecodeObject( GLOBAL_ENCODING_TYPE, szOID_AUTHORITY_INFO_ACCESS,
pCertExt->Value.pbData, pCertExt->Value.cbData,
CRYPT_DECODE_NOCOPY_FLAG, pAuthorityInfo, &ulDataLen))
{
CHAR csTemp[256] = {0};
sprintf_s(csTemp, 256, "[%d]Authority Info Access: \r\n", pAuthorityInfo->cAccDescr);
strcat_s(csProperty, 512, csTemp);
for (ULONG ulIndex = 0; ulIndex < pAuthorityInfo->cAccDescr; ulIndex++)
{
sprintf_s(csTemp, 256, "Access Method=证书颁发机构颁发者 (%s), \r\n", pAuthorityInfo->rgAccDescr[ulIndex].pszAccessMethod);
strcat_s(csProperty, 512, csTemp);
//
strcat_s(csProperty, 512, W2A(pAuthorityInfo->rgAccDescr[ulIndex].AccessLocation.pwszURL));
}
}
else
{
return GetLastError();
}
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;
}