您的位置:首页 > 其它

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

2011-07-13 21:32 537 查看
注:下面的代码中用了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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐