/* * * * 文件名称: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; }