编写ATL工程实现ActiveX控件调用cryptoAPI接口(五)------------获取证书转成Base64码

注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.

/*
* 
* 
* 文件名称:CertMsg.cpp
* 摘    要:
*		对证书一系列操作的封装,包括查找证书,验证证书合法性等
* 
* 作    者:周绍禹
* 创建日期:2012年2月29日
*/
#include "StdAfx.h"
#include "CertMsg.h"
#include "base64.h"
#include <sstream>
#include "Map.h"
#include "generic.h"
#include <atlconv.h>
#include <atlbase.h> 
#include <atlstr.h>
#include <Cryptuiapi.h>
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "Cryptui.lib")
CertMsg::CertMsg():CSP_NAME(FEITIAN_CSP_NAME)
{
	log = new Log("CertMsg");
}


CertMsg::~CertMsg()
{
	delete log;

}


//-----------------------------------------------------------
// 函数名称:
//     findCertInStore
// 参数:
//    - HCRYPTPROV hProv	上下文句柄
//    - CRYPT_INTEGER_BLOB *target	目标证书序列号
//    - HCERTSTORE &hCertStore	返回当前的证书库,需要关闭
// 返回:
//     PCCERT_CONTEXT	返回查找到的证书
// 说明:
//     从证书库中查找指定序列号的证书并返回,需要手动释放证书库和证书
//-----------------------------------------------------------
PCCERT_CONTEXT CertMsg::findCertInStore(HCRYPTPROV hProv,CRYPT_INTEGER_BLOB *target,HCERTSTORE &hCertStore)
{
	// 打开证书库  
	hCertStore = CertOpenStore(  
		CERT_STORE_PROV_SYSTEM,   // The store provider type.  
		0,                        // The encoding type is not needed.  
		hProv,               // Use the epassNG HCRYPTPROV.  
		CERT_SYSTEM_STORE_CURRENT_USER,  
		L"MY"  
		);  
	if(hCertStore == NULL)  
	{  
		log->info("------------------\n打开MY证书库失败!");
		string errorcode = getErrorCode();
		return NULL;
	}  
	PCCERT_CONTEXT hCert;
	// 查找与参数匹配的序号的证书  
	hCert = CertFindCertificateInStore(  
		hCertStore,  
		X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,  
		0,  
		CERT_FIND_ANY,  
		NULL,  
		NULL);

	bool getTarget = false;



	if(hCert == NULL)  
	{  
		//证书库无证书
		log->info("------------------\n查找证书失败!");
		if(hCertStore)
			CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
		return NULL;
	}
	else if(!CertCompareIntegerBlob (&(hCert->pCertInfo->SerialNumber),target))
	{
		//第一个获取到的证书序号不匹配,继续查询
		while( hCert = CertFindCertificateInStore(  
			hCertStore,  
			X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,  
			0,  
			CERT_FIND_ANY,  
			NULL,  
			hCert))
		{
			if(CertCompareIntegerBlob (&(hCert->pCertInfo->SerialNumber),target))
			{
				getTarget = true;
				break;
			}
		}
	}
	else
	{
		//第一个查到的即是匹配的证书
		getTarget = true;
	}



	if(!getTarget)
	{
		log->info("------------------\n查找证书失败!");
		return NULL;
	}

	return hCert;
}

//-----------------------------------------------------------
// 函数名称:
//     exportCert
// 参数:
//    - BYTE* target_SN_blob	目标证书的序列号字节数组
//    - int cblob	目标证书的序列号字节数组大小
// 返回:
//     Result*	返回Result结构,包含正确结果或异常信息
// 说明:
//     导出指定序列号的证书,返回的Result结构中包含异常信息或者成功返回证书的base64码
//-----------------------------------------------------------
Result* CertMsg::exportCert(BYTE* target_SN_blob,int cblob)
{
	CRYPT_INTEGER_BLOB *target = new CRYPT_INTEGER_BLOB();
	target->cbData = cblob;
	target->pbData = target_SN_blob;

	// 准备数据  
	HCRYPTPROV hProv;  
	log->info("------------------\nThe following phase of this program is signature.\n");  
	if(!CryptAcquireContext(  
		&hProv,   
		NULL,   
		CSP_NAME,  
		PROV_RSA_FULL,   
		CRYPT_VERIFYCONTEXT))   
	{
		DWORD dwLastErr = GetLastError();

		if(NTE_BAD_KEYSET == dwLastErr) 
		{
			Result* result = new Result("CertMsg.cpp",100,"密钥库不存在,或者访问被拒绝!","{}");
			return result;
		}
		else{
			if(!CryptAcquireContext(&hProv,
				NULL,
				this->CSP_NAME,
				PROV_RSA_AES,
				CRYPT_NEWKEYSET))
			{
				Map* map = new Map(1);
				map->put("errcode",dwLastErr);
				string errcode = map->toString();
				delete map;
				Result* result = new Result("CertMsg.cpp",115,"密钥库已存在,创建密钥库失败!",errcode);
				return result;
			}
		}

	}  
	HCERTSTORE hCertStore;
	PCCERT_CONTEXT hCert = findCertInStore(hProv,target,hCertStore);

	if(hCert==NULL)
	{
		if(hCertStore)
			CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); 

		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",132,"查找证书失败!",errorcode.length()==0?"{}":errorcode);
		return result;
	}

	//将证书转成base64编码发送到接收方  
	BYTE *newCert;  
	newCert = hCert->pbCertEncoded;  
	string baseCert = Base64::base64_encode(newCert,hCert->cbCertEncoded);  

	if(target) delete target;
	Result* result = new Result(baseCert);
	if(hCert)
		CertFreeCertificateContext(hCert);
	if(hCertStore)
		CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
	if(hProv) CryptReleaseContext(hProv,0);
	return result;  
}
//-----------------------------------------------------------
// 函数名称:
//     acquirePrivateKey
// 参数:
//    - HCRYPTPROV hProv	当前上下文句柄
//    - BYTE* target_SN_blob	目标证书的序列号字节码
//    - int cblob	目标证书序列号字节码的大小
//    - HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *hKeyProv	返回私钥句柄
//    - DWORD *dwKeyType	返回私钥类型参数
// 返回:
//     Result*	返回Result结构,包含正确结果或异常信息
// 说明:
//     获取证书对应的私钥句柄以及类型参数
//-----------------------------------------------------------
Result* CertMsg::acquirePrivateKey(HCRYPTPROV hProv,BYTE* target_SN_blob,int cblob,HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *hKeyProv, DWORD *dwKeyType)
{
	CRYPT_INTEGER_BLOB *target = new CRYPT_INTEGER_BLOB();
	target->cbData = cblob;
	target->pbData = target_SN_blob;
	HCERTSTORE hCertStore;

	PCCERT_CONTEXT hCert = findCertInStore(hProv,target,hCertStore);

	if(hCert==NULL)
	{
		if(hCertStore)
			CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); 
		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",159,"查找证书失败!",errorcode.length()==0?"{}":errorcode);
		return result;
	}

	// 请求证书私钥服务  
	BOOL bFreeKeyProv = FALSE;  
	if(!CryptAcquireCertificatePrivateKey(hCert, 0, 0, hKeyProv, dwKeyType, &bFreeKeyProv))  
	{  
		if(hCertStore)
			CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); 
		CertFreeCertificateContext(hCert);  
		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",170,"获取私钥失败!",errorcode.length()==0?"{}":errorcode);
		return result;
	} 


	if(target) delete target;
	if(hCert)
		CertFreeCertificateContext(hCert);
	if(hCertStore)
		CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); 
	return new Result(true);
}

//-----------------------------------------------------------
// 函数名称:
//     verifyCert
// 参数:
//    - string sn_base64	待验证证书的序列号base64
//    - string crl_base64	吊销列表base64
// 返回:
//     Result*
// 说明:
//     验证证书合法性,查找到证书后进行验证
//-----------------------------------------------------------
Result* CertMsg::verifyCert(string sn_base64,string crl_base64)
{
	// 准备数据  
	HCRYPTPROV hProv;  
	HCERTSTORE certStore;
	log->info("------------------\nThe following phase of this program is signature.\n");  
	if(!CryptAcquireContext(  
		&hProv,   
		NULL,   
		CSP_NAME,  
		PROV_RSA_FULL,   
		CRYPT_VERIFYCONTEXT))   
	{
		DWORD dwLastErr = GetLastError();

		if(NTE_BAD_KEYSET == dwLastErr) 
		{
			Result* result = new Result("CertMsg.cpp",100,"密钥库不存在,或者访问被拒绝!","{}");
			return result;
		}
		else{
			if(!CryptAcquireContext(&hProv,
				NULL,
				this->CSP_NAME,
				PROV_RSA_AES,
				CRYPT_NEWKEYSET))
			{
				Map* map = new Map(1);
				map->put("errcode",dwLastErr);
				string errcode = map->toString();
				delete map;
				Result* result = new Result("CertMsg.cpp",115,"密钥库已存在,创建密钥库失败!",errcode);
				return result;
			}
		}

	}  
	int sn_length = 0;
	BYTE* sn_bytes = Base64::base64_decode(sn_base64,sn_length);
	CRYPT_INTEGER_BLOB* blob = new CRYPT_INTEGER_BLOB();
	blob->cbData = sn_length;
	blob->pbData = sn_bytes;

	PCCERT_CONTEXT certContext = findCertInStore(hProv,blob,certStore);

	Result* result = verifyCert(certContext,crl_base64);

	if(sn_bytes) delete[] sn_bytes;
	if(hProv) CryptReleaseContext(hProv,0);
	if(certContext)
		CertFreeCertificateContext(certContext);
	if(certStore)
		CertCloseStore(certStore, CERT_CLOSE_STORE_FORCE_FLAG);  
	return result;
}
//-----------------------------------------------------------
// 函数名称:
//     verifyCert
// 参数:
//    - PCCERT_CONTEXT pCertContext	待验证证书句柄
//    - string crl_base64	序列化吊销列表的base64码
// 返回:
//     Result*	返回Result结构,包含正确结果或异常信息
// 说明:
//     验证证书合法性,分别调用
//		verifyCertTime,verifyCertCRL,verifyCertIssuer
//		验证证书的时间,吊销列表以及发行者
//-----------------------------------------------------------
Result* CertMsg::verifyCert(PCCERT_CONTEXT pCertContext,string crl_base64)
{
	Result* result_time = verifyCertTime(pCertContext);
	if(!result_time->isSuccess())
		return result_time;

	Result* result_CRL = verifyCertCRL(pCertContext,crl_base64);
	if(!result_CRL->isSuccess())
		return result_CRL;

	Result* result_issuer = verifyCertIssuer(pCertContext);
	if(!result_issuer->isSuccess())
		return result_CRL;

	return new Result(true);
}
//-----------------------------------------------------------
// 函数名称:
//     verifyCertTime
// 参数:
//    - PCCERT_CONTEXT pCertContext	待验证证书句柄
// 返回:
//     Result*	返回Result结构,包含正确结果或异常信息
// 说明:
//     验证证书的时间合法性
//-----------------------------------------------------------
Result* CertMsg::verifyCertTime(PCCERT_CONTEXT pCertContext)
{
	int nRetCode = CertVerifyTimeValidity(NULL, pCertContext->pCertInfo);  

	string message = "";
	Result* result;

	if(nRetCode < 0)  
	{  
		message = "证书尚未激活!";
		result = new Result("CertMsg.cpp",190,message,"{}");
	}  

	if(nRetCode > 0)  
	{  
		message = "证书已过期!";
		result = new Result("CertMsg.cpp",190,message,"{}");
	}  

	if(nRetCode == 0)  
	{  
		message = "证书时间合法!";
		result = new Result(message);
	}  
	return result;
}
//-----------------------------------------------------------
// 函数名称:
//     verifyCertCRL
// 参数:
//    - PCCERT_CONTEXT pCertContext	待验证证书句柄
//    - string crl_base64	序列化吊销列表的base64码
// 返回:
//     Result*	返回Result结构,包含正确结果或异常信息
// 说明:
//     验证证书的吊销列表合法性
//-----------------------------------------------------------
Result* CertMsg::verifyCertCRL(PCCERT_CONTEXT pCertContext,string crl_base64)
{
	BYTE *pbCRL = NULL;  
	int cbCRL;
	pbCRL = Base64::base64_decode(crl_base64,cbCRL);  
	PCCRL_CONTEXT hCRL = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,pbCRL,cbCRL);  
	if(hCRL != NULL)  
	{  
		if(!CertIsValidCRLForCertificate(pCertContext, hCRL, 0, NULL))  
		{  
			Result* result = new Result("CertMsg.cpp",239,"证书CRL与证书不匹配","{}");
			return result;
		}  

		//检查CRL是否包含该证书  
		PCRL_ENTRY pCrlEntry = NULL;  
		if(CertFindCertificateInCRL(pCertContext, hCRL, 0, 0, &pCrlEntry))  
		{  
			if(pCrlEntry != NULL)  
			{  
				Result* result = new Result("CertMsg.cpp",240,"证书已被吊销!","{}");
				return result; 
			}  
		}  
		else  
		{  
			string errorcode = getErrorCode();
			Result* result = new Result("CertMsg.cpp",240,"CRL未查找完成失败!",errorcode.length()==0?"{}":errorcode);
			return result;  
		}  
	}  
	else  
	{  
		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",240,"证书CRL无法创建!",errorcode.length()==0?"{}":errorcode);
		return result;  
	}  

	if(hCRL != NULL)  
	{  
		CertFreeCRLContext(hCRL);  
	}  

	return new Result(true);
}
//-----------------------------------------------------------
// 函数名称:
//     verifyCertIssuer
// 参数:
//    - PCCERT_CONTEXT pCertContext	待验证证书句柄
// 返回:
//     Result*	返回Result结构,包含正确结果或异常信息
// 说明:
//     验证证书的发行者合法性
//-----------------------------------------------------------
Result* CertMsg::verifyCertIssuer(PCCERT_CONTEXT pCertContext)
{
	HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");  
	if(hCertStore != NULL)  
	{  
		DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG;  
		PCCERT_CONTEXT hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, pCertContext, NULL, &dwFlags);  
		if(hIssuserCert != NULL)  
		{  
			BOOL bCheckOK = FALSE;  
			while(hIssuserCert != NULL)  
			{  
				// 校验证书签发者信息合法性  
				dwFlags = CERT_STORE_SIGNATURE_FLAG;  
				if(CertVerifySubjectCertificateContext(pCertContext, hIssuserCert, &dwFlags))  
				{  
					if(dwFlags == 0)  
					{  
						bCheckOK = TRUE;  
						break;  
					}  
				}  
				else  
				{  
					string errorcode = getErrorCode();
					Result* result = new Result("CertMsg.cpp",278,"验证证书签发者信息失败!",errorcode.length()==0?"{}":errorcode);
					return result;  
				}  

				hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, pCertContext, hIssuserCert, &dwFlags);  
			}  

			if(!bCheckOK)
			{
				string errorcode = getErrorCode();
				Result* result = new Result("CertMsg.cpp",278,"验证证书签发者信息全部未通过!",errorcode.length()==0?"{}":errorcode);
				return result;
			}

		}  
		else  
		{  
			string errorcode = getErrorCode();
			Result* result = new Result("CertMsg.cpp",270,"无证书签发者!",errorcode.length()==0?"{}":errorcode);
			return result;  
		}  

		if(hIssuserCert != NULL)  
		{  
			CertFreeCertificateContext(hIssuserCert);  
			hIssuserCert = NULL;  
		}  
	}  
	else  
	{  
		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",266,"打开ROOT证书库失败!",errorcode.length()==0?"{}":errorcode);
		return result;  
	}  

	if(hCertStore != NULL)  
	{  
		CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
		hCertStore = NULL;  
	}  
	return new Result(true);
}

//-----------------------------------------------------------
// 函数名称:
//     getCertIssuerNameOrSubjectName
// 参数:
//    - PCCERT_CONTEXT pCertContext	证书上下文
//    - int flag	指定获取证书名类型的flag标志
// 返回:
//     inline
//     string
// 说明:
//     根据标志获取指定证书的名字
//-----------------------------------------------------------
inline string getCertIssuerNameOrSubjectName(PCCERT_CONTEXT pCertContext,int flag)
{
	LPWSTR cert_name = new WCHAR[128];
	if(!(CertGetNameString(   
		pCertContext,   
		CERT_NAME_FRIENDLY_DISPLAY_TYPE,   
		flag,
		NULL,   
		cert_name,   
		128)))
	{
		return NULL;  
	}

	string s = ATL::CW2A(cert_name);

	if(cert_name) delete[] cert_name;

	return s;
}

//-----------------------------------------------------------
// 函数名称:
//     CertMsg::selectCertFromStoreToGetSN
// 参数:
//    - LPCWSTR title	选择证书框的标题
//    - LPCWSTR displayStr	选择证书库的提示消息
// 返回:
//     Result*	返回Result结构,包含错误信息或选择的证书序列号base64
// 说明:
//     让用户选择证书返回选中证书的序列号base64
//-----------------------------------------------------------
Result* CertMsg::selectCertFromStoreToGetSN(LPCWSTR title,LPCWSTR displayStr)
{
	HCERTSTORE       hCertStore = NULL;        
	PCCERT_CONTEXT   pCertContext = NULL;      
	TCHAR * pszStoreName = TEXT("MY");

	if (!( hCertStore = CertOpenSystemStore(
		NULL,
		pszStoreName)))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",386,"打开MY证书库失败!",errorcode.length()==0?"{}":errorcode);
		log->error("CertMsg.cpp 386 打开MY证书库失败-----------------")->error(errorcode);
		return result;  
	}
	if(!(pCertContext = CryptUIDlgSelectCertificateFromStore(
		hCertStore,      
		NULL,
		title,
		displayStr,
		CRYPTUI_SELECT_LOCATION_COLUMN,
		0,
		NULL)))
	{
		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",394,"选择证书失败!",errorcode.length()==0?"{}":errorcode);
		log->error("CertMsg.cpp 394 选择证书失败-----------------")->error(errorcode);
		return result;  
	}

	CRYPT_INTEGER_BLOB sn = pCertContext->pCertInfo->SerialNumber;

	string sn_base64 = Base64::base64_encode(sn.pbData,sn.cbData);

	string subjectName = getCertIssuerNameOrSubjectName(pCertContext,0);//获取证书使用者名
	string issuerName = getCertIssuerNameOrSubjectName(pCertContext,CERT_NAME_ISSUER_FLAG);//获取证书发行者名


	if(pCertContext)
	{
		CertFreeCertificateContext(pCertContext);
	}

	if(hCertStore)
	{
		if (!CertCloseStore(hCertStore,0))
		{
			string errorcode = getErrorCode();
			Result* result = new Result("CertMsg.cpp",538,"关闭证书库失败!",errorcode.length()==0?"{}":errorcode);
			log->error("CertMsg.cpp 538 关闭证书库失败-----------------")->error(errorcode);
			return result;  
		}
	}
	Result* result = new Result(sn_base64);
	string success_var = "{";
	success_var.append("\"subjectName\"");
	success_var.append(":");
	success_var.append("\"").append(subjectName).append("\"");
	success_var.append(",");

	success_var.append("\"issuerName\"");
	success_var.append(":");
	success_var.append("\"").append(issuerName).append("\"");

	success_var.append("}");
	result->setSuccessVar(success_var);
	return result;
}

//-----------------------------------------------------------
// 函数名称:
//     CertMsg::viewCert
// 参数:
//    - LPCWSTR tilte	证书查看窗口的标题
//    - string cert_tag_base64	
//			待查看证书的base64码或者待查看证书的SN base64,取决于flag
//	  - int flag	
//			FLAG_CERT_BASE64(0)则是通过证书base64查看,FLAG_CERT_SN_BASE64(1)则是从MY证书库查找指定序列号的证书并查看
// 返回:
//     Result*	异常或者正确返回,Result结构
// 说明:
//     查看base64码所代表的数字证书
//-----------------------------------------------------------
Result* CertMsg::viewCert(LPCWSTR tilte,string cert_tag_base64,int flag)
{
	int cert_len;
	PCCERT_CONTEXT  pCertContext = NULL;    
	BYTE* cert_bytes = NULL;
	HCRYPTPROV hProv;  
	int cert_sn_len;
	BYTE* cert_sn_bytes = NULL;
	HCERTSTORE store;
	if(flag==FLAG_CERT_BASE64)
	{
		//此时通过证书的base64码获取证书上下文
		cert_bytes = Base64::base64_decode(cert_tag_base64,cert_len);


		pCertContext = CertCreateCertificateContext(  
			X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,             
			cert_bytes,   
			cert_len);

	}
	else if(flag==FLAG_CERT_SN_BASE64)
	{
		//此时通过证书序列号base64码查找证书
		cert_sn_bytes = Base64::base64_decode(cert_tag_base64,cert_sn_len);

		if(!CryptAcquireContext(&hProv,
			NULL,
			CSP_NAME,
			PROV_RSA_FULL,
			CRYPT_VERIFYCONTEXT))
		{
			DWORD dwLastErr = GetLastError();

			if(NTE_BAD_KEYSET == dwLastErr) 
			{
				Result* result = new Result("CertMsg.cpp",486,"密钥库不存在,或者访问被拒绝!","{}");
				if(cert_sn_bytes) delete[] cert_sn_bytes;
				return result;
			}
			else{
				if(!CryptAcquireContext(&hProv,
					NULL,
					CSP_NAME,
					PROV_RSA_FULL,
					CRYPT_NEWKEYSET))
				{
					Map* map = new Map(1);
					map->put("errcode",dwLastErr);
					string errcode = map->toString();
					delete map;
					Result* result = new Result("CertMsg.cpp",502,"密钥库已存在,创建密钥库失败!",errcode);
					if(cert_sn_bytes) delete[] cert_sn_bytes;
					return result;
				}
			}
		}
		CRYPT_INTEGER_BLOB *blob = new CRYPT_INTEGER_BLOB();
		blob->pbData = cert_sn_bytes;
		blob->cbData = cert_sn_len;

		pCertContext = findCertInStore(hProv,blob,store);

	}

	if(!pCertContext) {  
		if(cert_bytes) delete[] cert_bytes;
		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",518,"创建证书上下文失败!",errorcode.length()==0?"{}":errorcode);

		if(cert_bytes) delete[] cert_bytes;
		if(cert_sn_bytes) delete[] cert_sn_bytes;

		if(store)
		{
			if (!CertCloseStore(store,0))
			{
				string errorcode = getErrorCode();
				Result* result = new Result("CertMsg.cpp",532,"关闭证书库失败!",errorcode.length()==0?"{}":errorcode);
				log->error("CertMsg.cpp 532 关闭证书库失败-----------------")->error(errorcode);
				return result;  
			}
		}

		if(hProv != NULL)  
		{  
			CryptReleaseContext(hProv, 0);  
			hProv = NULL;  
		}  
		return result;
	}

	//构建查看窗体的参数
	CRYPTUI_VIEWCERTIFICATE_STRUCT cuivc;
	memset(&cuivc, 0, sizeof(cuivc));
	cuivc.dwSize = sizeof(cuivc);
	cuivc.hwndParent = NULL;
	cuivc.dwFlags = CRYPTUI_DISABLE_ADDTOSTORE;
	cuivc.pCertContext = pCertContext;
	cuivc.szTitle = tilte;
	BOOL bPropertiesChanged;

	if(!CryptUIDlgViewCertificate(&cuivc,&bPropertiesChanged))
	{

		string errorcode = getErrorCode();
		Result* result = new Result("CertMsg.cpp",559,"打开证书查看窗口失败!",errorcode.length()==0?"{}":errorcode);

		if(cert_bytes) delete[] cert_bytes;
		if(cert_sn_bytes) delete[] cert_sn_bytes;
		if(pCertContext)
		{
			CertFreeCertificateContext(pCertContext);
		}

		if(store)
		{
			if (!CertCloseStore(store,0))
			{
				string errorcode = getErrorCode();
				Result* result = new Result("CertMsg.cpp",574,"关闭证书库失败!",errorcode.length()==0?"{}":errorcode);
				log->error("CertMsg.cpp 558 关闭证书库失败-----------------")->error(errorcode);
				return result;  
			}
		}

		if(hProv != NULL)  
		{  
			CryptReleaseContext(hProv, 0);  
			hProv = NULL;  
		}  

		return result;
	}

	if(cert_bytes) delete[] cert_bytes;
	if(cert_sn_bytes) delete[] cert_sn_bytes;
	if(pCertContext)
	{
		CertFreeCertificateContext(pCertContext);
	}

	if(store)
	{
		if (!CertCloseStore(store,0))
		{
			string errorcode = getErrorCode();
			Result* result = new Result("CertMsg.cpp",601,"关闭证书库失败!",errorcode.length()==0?"{}":errorcode);
			log->error("CertMsg.cpp 558 关闭证书库失败-----------------")->error(errorcode);
			return result;  
		}
	}

	if(hProv != NULL)  
	{  
		CryptReleaseContext(hProv, 0);  
		hProv = NULL;  
	}  
	return new Result(true);

}

//-----------------------------------------------------------
// 函数名称:
//     FileTimeToTime_t
// 参数:
//    - FILETIME ft	
//    - time_t *t
// 返回:
//     inline
//     void
// 说明:
//     FILETIME类型转换成time_t类型以便做时间差
//-----------------------------------------------------------
inline void FileTimeToTime_t( FILETIME ft, time_t *t ) 
{ 
	LONGLONG ll; 

	ULARGE_INTEGER ui; 
	ui.LowPart = ft.dwLowDateTime; 
	ui.HighPart = ft.dwHighDateTime; 

	ll = ft.dwHighDateTime << 32 + ft.dwLowDateTime; 

	*t = ((LONGLONG)(ui.QuadPart - 116444736000000000) / 10000000); 
} 

//-----------------------------------------------------------
// 函数名称:
//     GetDiffDays
// 参数:
//    - FILETIME t1
//    - FILETIME t2
// 返回:
//     inline
//     DWORD
// 说明:
//     计算两时间差,t2-t1的结果,结果为多少天
//-----------------------------------------------------------
inline DWORD GetDiffDays( FILETIME t1, FILETIME t2 ) 
{ 

	time_t tt1; 
	time_t tt2; 


	FileTimeToTime_t( t1, &tt1 ); 
	FileTimeToTime_t( t2, &tt2 ); 

	time_t difftime = tt2 - tt1; 

	return difftime / (24*3600L);// 除以每天24小时3600秒 
}

//-----------------------------------------------------------
// 函数名称:
//     getNow
// 参数:
//    - 无参数
// 返回:
//     inline
//     FILETIME
// 说明:
//     获取当前时间
//-----------------------------------------------------------
inline FILETIME getNow()
{
	FILETIME result;
	LPSYSTEMTIME   time = new SYSTEMTIME();
	GetSystemTime(time);
	SystemTimeToFileTime(time,&result);
	if(time) delete time;
	return result;
}
//-----------------------------------------------------------
// 函数名称:
//     getCertTimeWarn
// 参数:
//    - BYTE* target_SN_blob	目标证书的序列号字节数组
//    - int cblob	目标证书的序列号字节数组大小
//    - DWORD daysToWarn	剩余多少天过期时警告
//    - int &flag	
//			返回flag标签,
//			值为FLAG_BEFORE_NOT_BEFORE 尚未激活
//			值为FLAG_AFTER_NOT_AFTER	已经过期
//			值为FLAG_NEED_WARN	在警告范围内(daysToWarn),需要警告
//			值为FLAG_NOT_NEED_WARN	无需警告
// 返回:
//     Result*	返回Result结构,包含正确结果或异常信息
// 说明:
//     检查证书时间合法性并返回警告信息
//-----------------------------------------------------------
Result* CertMsg::getCertTimeWarn(BYTE* target_SN_blob,int cblob,DWORD daysToWarn,int &flag)
{
	HCRYPTPROV hProv;
	if(!CryptAcquireContext(&hProv,
		NULL,
		CSP_NAME,
		PROV_RSA_FULL,
		CRYPT_VERIFYCONTEXT))
	{
		DWORD dwLastErr = GetLastError();

		if(NTE_BAD_KEYSET == dwLastErr) 
		{
			Result* result = new Result("CertMsg.cpp",486,"密钥库不存在,或者访问被拒绝!","{}");
			return result;
		}
		else{
			if(!CryptAcquireContext(&hProv,
				NULL,
				CSP_NAME,
				PROV_RSA_FULL,
				CRYPT_NEWKEYSET))
			{
				Map* map = new Map(1);
				map->put("errcode",dwLastErr);
				string errcode = map->toString();
				delete map;
				Result* result = new Result("CertMsg.cpp",502,"密钥库已存在,创建密钥库失败!",errcode);
				return result;
			}
		}
	}
	CRYPT_INTEGER_BLOB *blob = new CRYPT_INTEGER_BLOB();
	blob->pbData = target_SN_blob;
	blob->cbData = cblob;

	HCERTSTORE store;
	PCCERT_CONTEXT pCertContext = NULL;
	pCertContext = findCertInStore(hProv,blob,store);

	FILETIME not_before_time = pCertContext->pCertInfo->NotBefore;
	FILETIME not_after_time = pCertContext->pCertInfo->NotAfter;
	FILETIME now = getNow();

	DWORD days_before = GetDiffDays(not_before_time,now);
	DWORD days_after = GetDiffDays(now,not_after_time); 

	DWORD days;

	if(days_before < 0)
	{
		flag = FLAG_BEFORE_NOT_BEFORE;
		days = -1 * days_before; //还有多少天才生效
	}
	else if(days_after < 0)
	{
		flag = FLAG_AFTER_NOT_AFTER;
		days = -1 * days_after; //过期多少天
	}
	else if(days_after > daysToWarn)
	{
		flag = FLAG_NOT_NEED_WARN;
		days = days_after; //还有多少天过期
	}
	else
	{
		flag = FLAG_NEED_WARN;
		days = days_after; //还有多少天过期
	}

	stringstream ss;
	ss << days;
	string d = "";
	ss >> d;

	if(store) 
		CertCloseStore(store,0);

	if(pCertContext)
		CertFreeCertificateContext(pCertContext);
	return new Result(d);
}



------------------------------下面为刚接触的版本,上面为修改后的版本--------------------------

STDMETHODIMP CUtil::ExportCert(BSTR* cert_base64_bstr)
{
	// TODO: Add your implementation code here
		// 准备数据
	HCRYPTPROV hProv;
	//	--------------------------------------------------------------------
	// get the CSP handle
	printf("The following phase of this program is signature.\n\n");
	if(CryptAcquireContext(
		&hProv, 
		NULL, 
		TEST_CSP_NAME,
		PROV_RSA_FULL, 
		0)) 
	{
		printf("CSP context acquired.\n");
	}
	else	//create if not exist
	{
		if(CryptAcquireContext(
			&hProv, 
			NULL, 
			TEST_CSP_NAME, 
			PROV_RSA_FULL, 
			CRYPT_NEWKEYSET)) 
		{
			printf("A new key container has been created.\n");
		}
		else
		{
		}
	}

	// 打开证书库
	HCERTSTORE hCertStore = CertOpenStore(
		CERT_STORE_PROV_SYSTEM,   // The store provider type.
		0,                        // The encoding type is not needed.
		hProv,               // Use the epassNG HCRYPTPROV.
		CERT_SYSTEM_STORE_CURRENT_USER,
		L"MY"
		);
	if(hCertStore == NULL)
	{

	}

	// 查找证书
	PCCERT_CONTEXT hCert = CertFindCertificateInStore(
		hCertStore,
		X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
		0,
		CERT_FIND_SUBJECT_STR,
		L"周绍禹",
		NULL);
	if(hCert == NULL)
	{

		CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
	}
	//将证书转成base64编码发送到接收方
	BYTE *newCert;
	newCert = new BYTE[hCert->cbCertEncoded];
	newCert = hCert->pbCertEncoded;
	string baseCert = base64_encode(newCert,hCert->cbCertEncoded);
	CComBSTR bstr(baseCert.c_str());
	*cert_base64_bstr = bstr;
	return S_OK;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值