使用CryptoAPI获取证书扩展属性之四:“CRL分发点”和“颁发机构信息访问”

        上篇文章讲述了如何使用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;
}


©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值