cryptoAPI接口(五)------------获取证书--演示 CryptUIDlgViewCertificate

来源:互联网 发布:淘宝店招装修 编辑:程序博客网 时间:2024/06/07 00:09
  1. /* 
  2.  
  3.  
  4. * 文件名称:CertMsg.cpp 
  5. * 摘    要: 
  6. *       对证书一系列操作的封装,包括查找证书,验证证书合法性等 
  7.  
  8. * 作    者:周绍禹 
  9. * 创建日期:2012年2月29日 
  10. */  
  11. #include "StdAfx.h"  
  12. #include "CertMsg.h"  
  13. #include "base64.h"  
  14. #include <sstream>  
  15. #include "Map.h"  
  16. #include "generic.h"  
  17. #include <atlconv.h>  
  18. #include <atlbase.h>   
  19. #include <atlstr.h>  
  20. #include <Cryptuiapi.h>  
  21. #pragma comment (lib, "crypt32.lib")  
  22. #pragma comment (lib, "Cryptui.lib")  
  23. CertMsg::CertMsg():CSP_NAME(FEITIAN_CSP_NAME)  
  24. {  
  25.     log = new Log("CertMsg");  
  26. }  
  27.   
  28.   
  29. CertMsg::~CertMsg()  
  30. {  
  31.     delete log;  
  32.   
  33. }  
  34.   
  35.   
  36. //-----------------------------------------------------------  
  37. // 函数名称:  
  38. //     findCertInStore  
  39. // 参数:  
  40. //    - HCRYPTPROV hProv    上下文句柄  
  41. //    - CRYPT_INTEGER_BLOB *target  目标证书序列号  
  42. //    - HCERTSTORE &hCertStore  返回当前的证书库,需要关闭  
  43. // 返回:  
  44. //     PCCERT_CONTEXT   返回查找到的证书  
  45. // 说明:  
  46. //     从证书库中查找指定序列号的证书并返回,需要手动释放证书库和证书  
  47. //-----------------------------------------------------------  
  48. PCCERT_CONTEXT CertMsg::findCertInStore(HCRYPTPROV hProv,CRYPT_INTEGER_BLOB *target,HCERTSTORE &hCertStore)  
  49. {  
  50.     // 打开证书库    
  51.     hCertStore = CertOpenStore(    
  52.         CERT_STORE_PROV_SYSTEM,   // The store provider type.    
  53.         0,                        // The encoding type is not needed.    
  54.         hProv,               // Use the epassNG HCRYPTPROV.    
  55.         CERT_SYSTEM_STORE_CURRENT_USER,    
  56.         L"MY"    
  57.         );    
  58.     if(hCertStore == NULL)    
  59.     {    
  60.         log->info("------------------\n打开MY证书库失败!");  
  61.         string errorcode = getErrorCode();  
  62.         return NULL;  
  63.     }    
  64.     PCCERT_CONTEXT hCert;  
  65.     // 查找与参数匹配的序号的证书    
  66.     hCert = CertFindCertificateInStore(    
  67.         hCertStore,    
  68.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,    
  69.         0,    
  70.         CERT_FIND_ANY,    
  71.         NULL,    
  72.         NULL);  
  73.   
  74.     bool getTarget = false;  
  75.   
  76.   
  77.   
  78.     if(hCert == NULL)    
  79.     {    
  80.         //证书库无证书  
  81.         log->info("------------------\n查找证书失败!");  
  82.         if(hCertStore)  
  83.             CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);    
  84.         return NULL;  
  85.     }  
  86.     else if(!CertCompareIntegerBlob (&(hCert->pCertInfo->SerialNumber),target))  
  87.     {  
  88.         //第一个获取到的证书序号不匹配,继续查询  
  89.         while( hCert = CertFindCertificateInStore(    
  90.             hCertStore,    
  91.             X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,    
  92.             0,    
  93.             CERT_FIND_ANY,    
  94.             NULL,    
  95.             hCert))  
  96.         {  
  97.             if(CertCompareIntegerBlob (&(hCert->pCertInfo->SerialNumber),target))  
  98.             {  
  99.                 getTarget = true;  
  100.                 break;  
  101.             }  
  102.         }  
  103.     }  
  104.     else  
  105.     {  
  106.         //第一个查到的即是匹配的证书  
  107.         getTarget = true;  
  108.     }  
  109.   
  110.   
  111.   
  112.     if(!getTarget)  
  113.     {  
  114.         log->info("------------------\n查找证书失败!");  
  115.         return NULL;  
  116.     }  
  117.   
  118.     return hCert;  
  119. }  
  120.   
  121. //-----------------------------------------------------------  
  122. // 函数名称:  
  123. //     exportCert  
  124. // 参数:  
  125. //    - BYTE* target_SN_blob    目标证书的序列号字节数组  
  126. //    - int cblob   目标证书的序列号字节数组大小  
  127. // 返回:  
  128. //     Result*  返回Result结构,包含正确结果或异常信息  
  129. // 说明:  
  130. //     导出指定序列号的证书,返回的Result结构中包含异常信息或者成功返回证书的base64码  
  131. //-----------------------------------------------------------  
  132. Result* CertMsg::exportCert(BYTE* target_SN_blob,int cblob)  
  133. {  
  134.     CRYPT_INTEGER_BLOB *target = new CRYPT_INTEGER_BLOB();  
  135.     target->cbData = cblob;  
  136.     target->pbData = target_SN_blob;  
  137.   
  138.     // 准备数据    
  139.     HCRYPTPROV hProv;    
  140.     log->info("------------------\nThe following phase of this program is signature.\n");    
  141.     if(!CryptAcquireContext(    
  142.         &hProv,     
  143.         NULL,     
  144.         CSP_NAME,    
  145.         PROV_RSA_FULL,     
  146.         CRYPT_VERIFYCONTEXT))     
  147.     {  
  148.         DWORD dwLastErr = GetLastError();  
  149.   
  150.         if(NTE_BAD_KEYSET == dwLastErr)   
  151.         {  
  152.             Result* result = new Result("CertMsg.cpp",100,"密钥库不存在,或者访问被拒绝!","{}");  
  153.             return result;  
  154.         }  
  155.         else{  
  156.             if(!CryptAcquireContext(&hProv,  
  157.                 NULL,  
  158.                 this->CSP_NAME,  
  159.                 PROV_RSA_AES,  
  160.                 CRYPT_NEWKEYSET))  
  161.             {  
  162.                 Map* map = new Map(1);  
  163.                 map->put("errcode",dwLastErr);  
  164.                 string errcode = map->toString();  
  165.                 delete map;  
  166.                 Result* result = new Result("CertMsg.cpp",115,"密钥库已存在,创建密钥库失败!",errcode);  
  167.                 return result;  
  168.             }  
  169.         }  
  170.   
  171.     }    
  172.     HCERTSTORE hCertStore;  
  173.     PCCERT_CONTEXT hCert = findCertInStore(hProv,target,hCertStore);  
  174.   
  175.     if(hCert==NULL)  
  176.     {  
  177.         if(hCertStore)  
  178.             CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);   
  179.   
  180.         string errorcode = getErrorCode();  
  181.         Result* result = new Result("CertMsg.cpp",132,"查找证书失败!",errorcode.length()==0?"{}":errorcode);  
  182.         return result;  
  183.     }  
  184.   
  185.     //将证书转成base64编码发送到接收方    
  186.     BYTE *newCert;    
  187.     newCert = hCert->pbCertEncoded;    
  188.     string baseCert = Base64::base64_encode(newCert,hCert->cbCertEncoded);    
  189.   
  190.     if(target) delete target;  
  191.     Result* result = new Result(baseCert);  
  192.     if(hCert)  
  193.         CertFreeCertificateContext(hCert);  
  194.     if(hCertStore)  
  195.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);    
  196.     if(hProv) CryptReleaseContext(hProv,0);  
  197.     return result;    
  198. }  
  199. //-----------------------------------------------------------  
  200. // 函数名称:  
  201. //     acquirePrivateKey  
  202. // 参数:  
  203. //    - HCRYPTPROV hProv    当前上下文句柄  
  204. //    - BYTE* target_SN_blob    目标证书的序列号字节码  
  205. //    - int cblob   目标证书序列号字节码的大小  
  206. //    - HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *hKeyProv   返回私钥句柄  
  207. //    - DWORD *dwKeyType    返回私钥类型参数  
  208. // 返回:  
  209. //     Result*  返回Result结构,包含正确结果或异常信息  
  210. // 说明:  
  211. //     获取证书对应的私钥句柄以及类型参数  
  212. //-----------------------------------------------------------  
  213. Result* CertMsg::acquirePrivateKey(HCRYPTPROV hProv,BYTE* target_SN_blob,int cblob,HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *hKeyProv, DWORD *dwKeyType)  
  214. {  
  215.     CRYPT_INTEGER_BLOB *target = new CRYPT_INTEGER_BLOB();  
  216.     target->cbData = cblob;  
  217.     target->pbData = target_SN_blob;  
  218.     HCERTSTORE hCertStore;  
  219.   
  220.     PCCERT_CONTEXT hCert = findCertInStore(hProv,target,hCertStore);  
  221.   
  222.     if(hCert==NULL)  
  223.     {  
  224.         if(hCertStore)  
  225.             CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);   
  226.         string errorcode = getErrorCode();  
  227.         Result* result = new Result("CertMsg.cpp",159,"查找证书失败!",errorcode.length()==0?"{}":errorcode);  
  228.         return result;  
  229.     }  
  230.   
  231.     // 请求证书私钥服务    
  232.     BOOL bFreeKeyProv = FALSE;    
  233.     if(!CryptAcquireCertificatePrivateKey(hCert, 0, 0, hKeyProv, dwKeyType, &bFreeKeyProv))    
  234.     {    
  235.         if(hCertStore)  
  236.             CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);   
  237.         CertFreeCertificateContext(hCert);    
  238.         string errorcode = getErrorCode();  
  239.         Result* result = new Result("CertMsg.cpp",170,"获取私钥失败!",errorcode.length()==0?"{}":errorcode);  
  240.         return result;  
  241.     }   
  242.   
  243.   
  244.     if(target) delete target;  
  245.     if(hCert)  
  246.         CertFreeCertificateContext(hCert);  
  247.     if(hCertStore)  
  248.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);   
  249.     return new Result(true);  
  250. }  
  251.   
  252. //-----------------------------------------------------------  
  253. // 函数名称:  
  254. //     verifyCert  
  255. // 参数:  
  256. //    - string sn_base64    待验证证书的序列号base64  
  257. //    - string crl_base64   吊销列表base64  
  258. // 返回:  
  259. //     Result*  
  260. // 说明:  
  261. //     验证证书合法性,查找到证书后进行验证  
  262. //-----------------------------------------------------------  
  263. Result* CertMsg::verifyCert(string sn_base64,string crl_base64)  
  264. {  
  265.     // 准备数据    
  266.     HCRYPTPROV hProv;    
  267.     HCERTSTORE certStore;  
  268.     log->info("------------------\nThe following phase of this program is signature.\n");    
  269.     if(!CryptAcquireContext(    
  270.         &hProv,     
  271.         NULL,     
  272.         CSP_NAME,    
  273.         PROV_RSA_FULL,     
  274.         CRYPT_VERIFYCONTEXT))     
  275.     {  
  276.         DWORD dwLastErr = GetLastError();  
  277.   
  278.         if(NTE_BAD_KEYSET == dwLastErr)   
  279.         {  
  280.             Result* result = new Result("CertMsg.cpp",100,"密钥库不存在,或者访问被拒绝!","{}");  
  281.             return result;  
  282.         }  
  283.         else{  
  284.             if(!CryptAcquireContext(&hProv,  
  285.                 NULL,  
  286.                 this->CSP_NAME,  
  287.                 PROV_RSA_AES,  
  288.                 CRYPT_NEWKEYSET))  
  289.             {  
  290.                 Map* map = new Map(1);  
  291.                 map->put("errcode",dwLastErr);  
  292.                 string errcode = map->toString();  
  293.                 delete map;  
  294.                 Result* result = new Result("CertMsg.cpp",115,"密钥库已存在,创建密钥库失败!",errcode);  
  295.                 return result;  
  296.             }  
  297.         }  
  298.   
  299.     }    
  300.     int sn_length = 0;  
  301.     BYTE* sn_bytes = Base64::base64_decode(sn_base64,sn_length);  
  302.     CRYPT_INTEGER_BLOB* blob = new CRYPT_INTEGER_BLOB();  
  303.     blob->cbData = sn_length;  
  304.     blob->pbData = sn_bytes;  
  305.   
  306.     PCCERT_CONTEXT certContext = findCertInStore(hProv,blob,certStore);  
  307.   
  308.     Result* result = verifyCert(certContext,crl_base64);  
  309.   
  310.     if(sn_bytes) delete[] sn_bytes;  
  311.     if(hProv) CryptReleaseContext(hProv,0);  
  312.     if(certContext)  
  313.         CertFreeCertificateContext(certContext);  
  314.     if(certStore)  
  315.         CertCloseStore(certStore, CERT_CLOSE_STORE_FORCE_FLAG);    
  316.     return result;  
  317. }  
  318. //-----------------------------------------------------------  
  319. // 函数名称:  
  320. //     verifyCert  
  321. // 参数:  
  322. //    - PCCERT_CONTEXT pCertContext 待验证证书句柄  
  323. //    - string crl_base64   序列化吊销列表的base64码  
  324. // 返回:  
  325. //     Result*  返回Result结构,包含正确结果或异常信息  
  326. // 说明:  
  327. //     验证证书合法性,分别调用  
  328. //      verifyCertTime,verifyCertCRL,verifyCertIssuer  
  329. //      验证证书的时间,吊销列表以及发行者  
  330. //-----------------------------------------------------------  
  331. Result* CertMsg::verifyCert(PCCERT_CONTEXT pCertContext,string crl_base64)  
  332. {  
  333.     Result* result_time = verifyCertTime(pCertContext);  
  334.     if(!result_time->isSuccess())  
  335.         return result_time;  
  336.   
  337.     Result* result_CRL = verifyCertCRL(pCertContext,crl_base64);  
  338.     if(!result_CRL->isSuccess())  
  339.         return result_CRL;  
  340.   
  341.     Result* result_issuer = verifyCertIssuer(pCertContext);  
  342.     if(!result_issuer->isSuccess())  
  343.         return result_CRL;  
  344.   
  345.     return new Result(true);  
  346. }  
  347. //-----------------------------------------------------------  
  348. // 函数名称:  
  349. //     verifyCertTime  
  350. // 参数:  
  351. //    - PCCERT_CONTEXT pCertContext 待验证证书句柄  
  352. // 返回:  
  353. //     Result*  返回Result结构,包含正确结果或异常信息  
  354. // 说明:  
  355. //     验证证书的时间合法性  
  356. //-----------------------------------------------------------  
  357. Result* CertMsg::verifyCertTime(PCCERT_CONTEXT pCertContext)  
  358. {  
  359.     int nRetCode = CertVerifyTimeValidity(NULL, pCertContext->pCertInfo);    
  360.   
  361.     string message = "";  
  362.     Result* result;  
  363.   
  364.     if(nRetCode < 0)    
  365.     {    
  366.         message = "证书尚未激活!";  
  367.         result = new Result("CertMsg.cpp",190,message,"{}");  
  368.     }    
  369.   
  370.     if(nRetCode > 0)    
  371.     {    
  372.         message = "证书已过期!";  
  373.         result = new Result("CertMsg.cpp",190,message,"{}");  
  374.     }    
  375.   
  376.     if(nRetCode == 0)    
  377.     {    
  378.         message = "证书时间合法!";  
  379.         result = new Result(message);  
  380.     }    
  381.     return result;  
  382. }  
  383. //-----------------------------------------------------------  
  384. // 函数名称:  
  385. //     verifyCertCRL  
  386. // 参数:  
  387. //    - PCCERT_CONTEXT pCertContext 待验证证书句柄  
  388. //    - string crl_base64   序列化吊销列表的base64码  
  389. // 返回:  
  390. //     Result*  返回Result结构,包含正确结果或异常信息  
  391. // 说明:  
  392. //     验证证书的吊销列表合法性  
  393. //-----------------------------------------------------------  
  394. Result* CertMsg::verifyCertCRL(PCCERT_CONTEXT pCertContext,string crl_base64)  
  395. {  
  396.     BYTE *pbCRL = NULL;    
  397.     int cbCRL;  
  398.     pbCRL = Base64::base64_decode(crl_base64,cbCRL);    
  399.     PCCRL_CONTEXT hCRL = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,pbCRL,cbCRL);    
  400.     if(hCRL != NULL)    
  401.     {    
  402.         if(!CertIsValidCRLForCertificate(pCertContext, hCRL, 0, NULL))    
  403.         {    
  404.             Result* result = new Result("CertMsg.cpp",239,"证书CRL与证书不匹配","{}");  
  405.             return result;  
  406.         }    
  407.   
  408.         //检查CRL是否包含该证书    
  409.         PCRL_ENTRY pCrlEntry = NULL;    
  410.         if(CertFindCertificateInCRL(pCertContext, hCRL, 0, 0, &pCrlEntry))    
  411.         {    
  412.             if(pCrlEntry != NULL)    
  413.             {    
  414.                 Result* result = new Result("CertMsg.cpp",240,"证书已被吊销!","{}");  
  415.                 return result;   
  416.             }    
  417.         }    
  418.         else    
  419.         {    
  420.             string errorcode = getErrorCode();  
  421.             Result* result = new Result("CertMsg.cpp",240,"CRL未查找完成失败!",errorcode.length()==0?"{}":errorcode);  
  422.             return result;    
  423.         }    
  424.     }    
  425.     else    
  426.     {    
  427.         string errorcode = getErrorCode();  
  428.         Result* result = new Result("CertMsg.cpp",240,"证书CRL无法创建!",errorcode.length()==0?"{}":errorcode);  
  429.         return result;    
  430.     }    
  431.   
  432.     if(hCRL != NULL)    
  433.     {    
  434.         CertFreeCRLContext(hCRL);    
  435.     }    
  436.   
  437.     return new Result(true);  
  438. }  
  439. //-----------------------------------------------------------  
  440. // 函数名称:  
  441. //     verifyCertIssuer  
  442. // 参数:  
  443. //    - PCCERT_CONTEXT pCertContext 待验证证书句柄  
  444. // 返回:  
  445. //     Result*  返回Result结构,包含正确结果或异常信息  
  446. // 说明:  
  447. //     验证证书的发行者合法性  
  448. //-----------------------------------------------------------  
  449. Result* CertMsg::verifyCertIssuer(PCCERT_CONTEXT pCertContext)  
  450. {  
  451.     HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");    
  452.     if(hCertStore != NULL)    
  453.     {    
  454.         DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG;    
  455.         PCCERT_CONTEXT hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, pCertContext, NULL, &dwFlags);    
  456.         if(hIssuserCert != NULL)    
  457.         {    
  458.             BOOL bCheckOK = FALSE;    
  459.             while(hIssuserCert != NULL)    
  460.             {    
  461.                 // 校验证书签发者信息合法性    
  462.                 dwFlags = CERT_STORE_SIGNATURE_FLAG;    
  463.                 if(CertVerifySubjectCertificateContext(pCertContext, hIssuserCert, &dwFlags))    
  464.                 {    
  465.                     if(dwFlags == 0)    
  466.                     {    
  467.                         bCheckOK = TRUE;    
  468.                         break;    
  469.                     }    
  470.                 }    
  471.                 else    
  472.                 {    
  473.                     string errorcode = getErrorCode();  
  474.                     Result* result = new Result("CertMsg.cpp",278,"验证证书签发者信息失败!",errorcode.length()==0?"{}":errorcode);  
  475.                     return result;    
  476.                 }    
  477.   
  478.                 hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, pCertContext, hIssuserCert, &dwFlags);    
  479.             }    
  480.   
  481.             if(!bCheckOK)  
  482.             {  
  483.                 string errorcode = getErrorCode();  
  484.                 Result* result = new Result("CertMsg.cpp",278,"验证证书签发者信息全部未通过!",errorcode.length()==0?"{}":errorcode);  
  485.                 return result;  
  486.             }  
  487.   
  488.         }    
  489.         else    
  490.         {    
  491.             string errorcode = getErrorCode();  
  492.             Result* result = new Result("CertMsg.cpp",270,"无证书签发者!",errorcode.length()==0?"{}":errorcode);  
  493.             return result;    
  494.         }    
  495.   
  496.         if(hIssuserCert != NULL)    
  497.         {    
  498.             CertFreeCertificateContext(hIssuserCert);    
  499.             hIssuserCert = NULL;    
  500.         }    
  501.     }    
  502.     else    
  503.     {    
  504.         string errorcode = getErrorCode();  
  505.         Result* result = new Result("CertMsg.cpp",266,"打开ROOT证书库失败!",errorcode.length()==0?"{}":errorcode);  
  506.         return result;    
  507.     }    
  508.   
  509.     if(hCertStore != NULL)    
  510.     {    
  511.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);    
  512.         hCertStore = NULL;    
  513.     }    
  514.     return new Result(true);  
  515. }  
  516.   
  517. //-----------------------------------------------------------  
  518. // 函数名称:  
  519. //     getCertIssuerNameOrSubjectName  
  520. // 参数:  
  521. //    - PCCERT_CONTEXT pCertContext 证书上下文  
  522. //    - int flag    指定获取证书名类型的flag标志  
  523. // 返回:  
  524. //     inline  
  525. //     string  
  526. // 说明:  
  527. //     根据标志获取指定证书的名字  
  528. //-----------------------------------------------------------  
  529. inline string getCertIssuerNameOrSubjectName(PCCERT_CONTEXT pCertContext,int flag)  
  530. {  
  531.     LPWSTR cert_name = new WCHAR[128];  
  532.     if(!(CertGetNameString(     
  533.         pCertContext,     
  534.         CERT_NAME_FRIENDLY_DISPLAY_TYPE,     
  535.         flag,  
  536.         NULL,     
  537.         cert_name,     
  538.         128)))  
  539.     {  
  540.         return NULL;    
  541.     }  
  542.   
  543.     string s = ATL::CW2A(cert_name);  
  544.   
  545.     if(cert_name) delete[] cert_name;  
  546.   
  547.     return s;  
  548. }  
  549.   
  550. //-----------------------------------------------------------  
  551. // 函数名称:  
  552. //     CertMsg::selectCertFromStoreToGetSN  
  553. // 参数:  
  554. //    - LPCWSTR title   选择证书框的标题  
  555. //    - LPCWSTR displayStr  选择证书库的提示消息  
  556. // 返回:  
  557. //     Result*  返回Result结构,包含错误信息或选择的证书序列号base64  
  558. // 说明:  
  559. //     让用户选择证书返回选中证书的序列号base64  
  560. //-----------------------------------------------------------  
  561. Result* CertMsg::selectCertFromStoreToGetSN(LPCWSTR title,LPCWSTR displayStr)  
  562. {  
  563.     HCERTSTORE       hCertStore = NULL;          
  564.     PCCERT_CONTEXT   pCertContext = NULL;        
  565.     TCHAR * pszStoreName = TEXT("MY");  
  566.   
  567.     if (!( hCertStore = CertOpenSystemStore(  
  568.         NULL,  
  569.         pszStoreName)))  
  570.     {  
  571.         string errorcode = getErrorCode();  
  572.         Result* result = new Result("CertMsg.cpp",386,"打开MY证书库失败!",errorcode.length()==0?"{}":errorcode);  
  573.         log->error("CertMsg.cpp 386 打开MY证书库失败-----------------")->error(errorcode);  
  574.         return result;    
  575.     }  
  576.     if(!(pCertContext = CryptUIDlgSelectCertificateFromStore(  
  577.         hCertStore,        
  578.         NULL,  
  579.         title,  
  580.         displayStr,  
  581.         CRYPTUI_SELECT_LOCATION_COLUMN,  
  582.         0,  
  583.         NULL)))  
  584.     {  
  585.         string errorcode = getErrorCode();  
  586.         Result* result = new Result("CertMsg.cpp",394,"选择证书失败!",errorcode.length()==0?"{}":errorcode);  
  587.         log->error("CertMsg.cpp 394 选择证书失败-----------------")->error(errorcode);  
  588.         return result;    
  589.     }  
  590.   
  591.     CRYPT_INTEGER_BLOB sn = pCertContext->pCertInfo->SerialNumber;  
  592.   
  593.     string sn_base64 = Base64::base64_encode(sn.pbData,sn.cbData);  
  594.   
  595.     string subjectName = getCertIssuerNameOrSubjectName(pCertContext,0);//获取证书使用者名  
  596.     string issuerName = getCertIssuerNameOrSubjectName(pCertContext,CERT_NAME_ISSUER_FLAG);//获取证书发行者名  
  597.   
  598.   
  599.     if(pCertContext)  
  600.     {  
  601.         CertFreeCertificateContext(pCertContext);  
  602.     }  
  603.   
  604.     if(hCertStore)  
  605.     {  
  606.         if (!CertCloseStore(hCertStore,0))  
  607.         {  
  608.             string errorcode = getErrorCode();  
  609.             Result* result = new Result("CertMsg.cpp",538,"关闭证书库失败!",errorcode.length()==0?"{}":errorcode);  
  610.             log->error("CertMsg.cpp 538 关闭证书库失败-----------------")->error(errorcode);  
  611.             return result;    
  612.         }  
  613.     }  
  614.     Result* result = new Result(sn_base64);  
  615.     string success_var = "{";  
  616.     success_var.append("\"subjectName\"");  
  617.     success_var.append(":");  
  618.     success_var.append("\"").append(subjectName).append("\"");  
  619.     success_var.append(",");  
  620.   
  621.     success_var.append("\"issuerName\"");  
  622.     success_var.append(":");  
  623.     success_var.append("\"").append(issuerName).append("\"");  
  624.   
  625.     success_var.append("}");  
  626.     result->setSuccessVar(success_var);  
  627.     return result;  
  628. }  
  629.   
  630. //-----------------------------------------------------------  
  631. // 函数名称:  
  632. //     CertMsg::viewCert  
  633. // 参数:  
  634. //    - LPCWSTR tilte   证书查看窗口的标题  
  635. //    - string cert_tag_base64    
  636. //          待查看证书的base64码或者待查看证书的SN base64,取决于flag  
  637. //    - int flag      
  638. //          FLAG_CERT_BASE64(0)则是通过证书base64查看,FLAG_CERT_SN_BASE64(1)则是从MY证书库查找指定序列号的证书并查看  
  639. // 返回:  
  640. //     Result*  异常或者正确返回,Result结构  
  641. // 说明:  
  642. //     查看base64码所代表的数字证书  
  643. //-----------------------------------------------------------  
  644. Result* CertMsg::viewCert(LPCWSTR tilte,string cert_tag_base64,int flag)  
  645. {  
  646.     int cert_len;  
  647.     PCCERT_CONTEXT  pCertContext = NULL;      
  648.     BYTE* cert_bytes = NULL;  
  649.     HCRYPTPROV hProv;    
  650.     int cert_sn_len;  
  651.     BYTE* cert_sn_bytes = NULL;  
  652.     HCERTSTORE store;  
  653.     if(flag==FLAG_CERT_BASE64)  
  654.     {  
  655.         //此时通过证书的base64码获取证书上下文  
  656.         cert_bytes = Base64::base64_decode(cert_tag_base64,cert_len);  
  657.   
  658.   
  659.         pCertContext = CertCreateCertificateContext(    
  660.             X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,               
  661.             cert_bytes,     
  662.             cert_len);  
  663.   
  664.     }  
  665.     else if(flag==FLAG_CERT_SN_BASE64)  
  666.     {  
  667.         //此时通过证书序列号base64码查找证书  
  668.         cert_sn_bytes = Base64::base64_decode(cert_tag_base64,cert_sn_len);  
  669.   
  670.         if(!CryptAcquireContext(&hProv,  
  671.             NULL,  
  672.             CSP_NAME,  
  673.             PROV_RSA_FULL,  
  674.             CRYPT_VERIFYCONTEXT))  
  675.         {  
  676.             DWORD dwLastErr = GetLastError();  
  677.   
  678.             if(NTE_BAD_KEYSET == dwLastErr)   
  679.             {  
  680.                 Result* result = new Result("CertMsg.cpp",486,"密钥库不存在,或者访问被拒绝!","{}");  
  681.                 if(cert_sn_bytes) delete[] cert_sn_bytes;  
  682.                 return result;  
  683.             }  
  684.             else{  
  685.                 if(!CryptAcquireContext(&hProv,  
  686.                     NULL,  
  687.                     CSP_NAME,  
  688.                     PROV_RSA_FULL,  
  689.                     CRYPT_NEWKEYSET))  
  690.                 {  
  691.                     Map* map = new Map(1);  
  692.                     map->put("errcode",dwLastErr);  
  693.                     string errcode = map->toString();  
  694.                     delete map;  
  695.                     Result* result = new Result("CertMsg.cpp",502,"密钥库已存在,创建密钥库失败!",errcode);  
  696.                     if(cert_sn_bytes) delete[] cert_sn_bytes;  
  697.                     return result;  
  698.                 }  
  699.             }  
  700.         }  
  701.         CRYPT_INTEGER_BLOB *blob = new CRYPT_INTEGER_BLOB();  
  702.         blob->pbData = cert_sn_bytes;  
  703.         blob->cbData = cert_sn_len;  
  704.   
  705.         pCertContext = findCertInStore(hProv,blob,store);  
  706.   
  707.     }  
  708.   
  709.     if(!pCertContext) {    
  710.         if(cert_bytes) delete[] cert_bytes;  
  711.         string errorcode = getErrorCode();  
  712.         Result* result = new Result("CertMsg.cpp",518,"创建证书上下文失败!",errorcode.length()==0?"{}":errorcode);  
  713.   
  714.         if(cert_bytes) delete[] cert_bytes;  
  715.         if(cert_sn_bytes) delete[] cert_sn_bytes;  
  716.   
  717.         if(store)  
  718.         {  
  719.             if (!CertCloseStore(store,0))  
  720.             {  
  721.                 string errorcode = getErrorCode();  
  722.                 Result* result = new Result("CertMsg.cpp",532,"关闭证书库失败!",errorcode.length()==0?"{}":errorcode);  
  723.                 log->error("CertMsg.cpp 532 关闭证书库失败-----------------")->error(errorcode);  
  724.                 return result;    
  725.             }  
  726.         }  
  727.   
  728.         if(hProv != NULL)    
  729.         {    
  730.             CryptReleaseContext(hProv, 0);    
  731.             hProv = NULL;    
  732.         }    
  733.         return result;  
  734.     }  
  735.   
  736.     //构建查看窗体的参数  
  737.     CRYPTUI_VIEWCERTIFICATE_STRUCT cuivc;  
  738.     memset(&cuivc, 0, sizeof(cuivc));  
  739.     cuivc.dwSize = sizeof(cuivc);  
  740.     cuivc.hwndParent = NULL;  
  741.     cuivc.dwFlags = CRYPTUI_DISABLE_ADDTOSTORE;  
  742.     cuivc.pCertContext = pCertContext;  
  743.     cuivc.szTitle = tilte;  
  744.     BOOL bPropertiesChanged;  
  745.   
  746.     if(!CryptUIDlgViewCertificate(&cuivc,&bPropertiesChanged))  
  747.     {  
  748.   
  749.         string errorcode = getErrorCode();  
  750.         Result* result = new Result("CertMsg.cpp",559,"打开证书查看窗口失败!",errorcode.length()==0?"{}":errorcode);  
  751.   
  752.         if(cert_bytes) delete[] cert_bytes;  
  753.         if(cert_sn_bytes) delete[] cert_sn_bytes;  
  754.         if(pCertContext)  
  755.         {  
  756.             CertFreeCertificateContext(pCertContext);  
  757.         }  
  758.   
  759.         if(store)  
  760.         {  
  761.             if (!CertCloseStore(store,0))  
  762.             {  
  763.                 string errorcode = getErrorCode();  
  764.                 Result* result = new Result("CertMsg.cpp",574,"关闭证书库失败!",errorcode.length()==0?"{}":errorcode);  
  765.                 log->error("CertMsg.cpp 558 关闭证书库失败-----------------")->error(errorcode);  
  766.                 return result;    
  767.             }  
  768.         }  
  769.   
  770.         if(hProv != NULL)    
  771.         {    
  772.             CryptReleaseContext(hProv, 0);    
  773.             hProv = NULL;    
  774.         }    
  775.   
  776.         return result;  
  777.     }  
  778.   
  779.     if(cert_bytes) delete[] cert_bytes;  
  780.     if(cert_sn_bytes) delete[] cert_sn_bytes;  
  781.     if(pCertContext)  
  782.     {  
  783.         CertFreeCertificateContext(pCertContext);  
  784.     }  
  785.   
  786.     if(store)  
  787.     {  
  788.         if (!CertCloseStore(store,0))  
  789.         {  
  790.             string errorcode = getErrorCode();  
  791.             Result* result = new Result("CertMsg.cpp",601,"关闭证书库失败!",errorcode.length()==0?"{}":errorcode);  
  792.             log->error("CertMsg.cpp 558 关闭证书库失败-----------------")->error(errorcode);  
  793.             return result;    
  794.         }  
  795.     }  
  796.   
  797.     if(hProv != NULL)    
  798.     {    
  799.         CryptReleaseContext(hProv, 0);    
  800.         hProv = NULL;    
  801.     }    
  802.     return new Result(true);  
  803.   
  804. }  
  805.   
  806. //-----------------------------------------------------------  
  807. // 函数名称:  
  808. //     FileTimeToTime_t  
  809. // 参数:  
  810. //    - FILETIME ft   
  811. //    - time_t *t  
  812. // 返回:  
  813. //     inline  
  814. //     void  
  815. // 说明:  
  816. //     FILETIME类型转换成time_t类型以便做时间差  
  817. //-----------------------------------------------------------  
  818. inline void FileTimeToTime_t( FILETIME ft, time_t *t )   
  819. {   
  820.     LONGLONG ll;   
  821.   
  822.     ULARGE_INTEGER ui;   
  823.     ui.LowPart = ft.dwLowDateTime;   
  824.     ui.HighPart = ft.dwHighDateTime;   
  825.   
  826.     ll = ft.dwHighDateTime << 32 + ft.dwLowDateTime;   
  827.   
  828.     *t = ((LONGLONG)(ui.QuadPart - 116444736000000000) / 10000000);   
  829. }   
  830.   
  831. //-----------------------------------------------------------  
  832. // 函数名称:  
  833. //     GetDiffDays  
  834. // 参数:  
  835. //    - FILETIME t1  
  836. //    - FILETIME t2  
  837. // 返回:  
  838. //     inline  
  839. //     DWORD  
  840. // 说明:  
  841. //     计算两时间差,t2-t1的结果,结果为多少天  
  842. //-----------------------------------------------------------  
  843. inline DWORD GetDiffDays( FILETIME t1, FILETIME t2 )   
  844. {   
  845.   
  846.     time_t tt1;   
  847.     time_t tt2;   
  848.   
  849.   
  850.     FileTimeToTime_t( t1, &tt1 );   
  851.     FileTimeToTime_t( t2, &tt2 );   
  852.   
  853.     time_t difftime = tt2 - tt1;   
  854.   
  855.     return difftime / (24*3600L);// 除以每天24小时3600秒   
  856. }  
  857.   
  858. //-----------------------------------------------------------  
  859. // 函数名称:  
  860. //     getNow  
  861. // 参数:  
  862. //    - 无参数  
  863. // 返回:  
  864. //     inline  
  865. //     FILETIME  
  866. // 说明:  
  867. //     获取当前时间  
  868. //-----------------------------------------------------------  
  869. inline FILETIME getNow()  
  870. {  
  871.     FILETIME result;  
  872.     LPSYSTEMTIME   time = new SYSTEMTIME();  
  873.     GetSystemTime(time);  
  874.     SystemTimeToFileTime(time,&result);  
  875.     if(time) delete time;  
  876.     return result;  
  877. }  
  878. //-----------------------------------------------------------  
  879. // 函数名称:  
  880. //     getCertTimeWarn  
  881. // 参数:  
  882. //    - BYTE* target_SN_blob    目标证书的序列号字节数组  
  883. //    - int cblob   目标证书的序列号字节数组大小  
  884. //    - DWORD daysToWarn    剩余多少天过期时警告  
  885. //    - int &flag     
  886. //          返回flag标签,  
  887. //          值为FLAG_BEFORE_NOT_BEFORE 尚未激活  
  888. //          值为FLAG_AFTER_NOT_AFTER  已经过期  
  889. //          值为FLAG_NEED_WARN    在警告范围内(daysToWarn),需要警告  
  890. //          值为FLAG_NOT_NEED_WARN    无需警告  
  891. // 返回:  
  892. //     Result*  返回Result结构,包含正确结果或异常信息  
  893. // 说明:  
  894. //     检查证书时间合法性并返回警告信息  
  895. //-----------------------------------------------------------  
  896. Result* CertMsg::getCertTimeWarn(BYTE* target_SN_blob,int cblob,DWORD daysToWarn,int &flag)  
  897. {  
  898.     HCRYPTPROV hProv;  
  899.     if(!CryptAcquireContext(&hProv,  
  900.         NULL,  
  901.         CSP_NAME,  
  902.         PROV_RSA_FULL,  
  903.         CRYPT_VERIFYCONTEXT))  
  904.     {  
  905.         DWORD dwLastErr = GetLastError();  
  906.   
  907.         if(NTE_BAD_KEYSET == dwLastErr)   
  908.         {  
  909.             Result* result = new Result("CertMsg.cpp",486,"密钥库不存在,或者访问被拒绝!","{}");  
  910.             return result;  
  911.         }  
  912.         else{  
  913.             if(!CryptAcquireContext(&hProv,  
  914.                 NULL,  
  915.                 CSP_NAME,  
  916.                 PROV_RSA_FULL,  
  917.                 CRYPT_NEWKEYSET))  
  918.             {  
  919.                 Map* map = new Map(1);  
  920.                 map->put("errcode",dwLastErr);  
  921.                 string errcode = map->toString();  
  922.                 delete map;  
  923.                 Result* result = new Result("CertMsg.cpp",502,"密钥库已存在,创建密钥库失败!",errcode);  
  924.                 return result;  
  925.             }  
  926.         }  
  927.     }  
  928.     CRYPT_INTEGER_BLOB *blob = new CRYPT_INTEGER_BLOB();  
  929.     blob->pbData = target_SN_blob;  
  930.     blob->cbData = cblob;  
  931.   
  932.     HCERTSTORE store;  
  933.     PCCERT_CONTEXT pCertContext = NULL;  
  934.     pCertContext = findCertInStore(hProv,blob,store);  
  935.   
  936.     FILETIME not_before_time = pCertContext->pCertInfo->NotBefore;  
  937.     FILETIME not_after_time = pCertContext->pCertInfo->NotAfter;  
  938.     FILETIME now = getNow();  
  939.   
  940.     DWORD days_before = GetDiffDays(not_before_time,now);  
  941.     DWORD days_after = GetDiffDays(now,not_after_time);   
  942.   
  943.     DWORD days;  
  944.   
  945.     if(days_before < 0)  
  946.     {  
  947.         flag = FLAG_BEFORE_NOT_BEFORE;  
  948.         days = -1 * days_before; //还有多少天才生效  
  949.     }  
  950.     else if(days_after < 0)  
  951.     {  
  952.         flag = FLAG_AFTER_NOT_AFTER;  
  953.         days = -1 * days_after; //过期多少天  
  954.     }  
  955.     else if(days_after > daysToWarn)  
  956.     {  
  957.         flag = FLAG_NOT_NEED_WARN;  
  958.         days = days_after; //还有多少天过期  
  959.     }  
  960.     else  
  961.     {  
  962.         flag = FLAG_NEED_WARN;  
  963.         days = days_after; //还有多少天过期  
  964.     }  
  965.   
  966.     stringstream ss;  
  967.     ss << days;  
  968.     string d = "";  
  969.     ss >> d;  
  970.   
  971.     if(store)   
  972.         CertCloseStore(store,0);  
  973.   
  974.     if(pCertContext)  
  975.         CertFreeCertificateContext(pCertContext);  
  976.     return new Result(d);  

  1. }  


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

[cpp] view plain copy
 print?
  1. STDMETHODIMP CUtil::ExportCert(BSTR* cert_base64_bstr)  
  2. {  
  3.     // TODO: Add your implementation code here  
  4.         // 准备数据  
  5.     HCRYPTPROV hProv;  
  6.     //  --------------------------------------------------------------------  
  7.     // get the CSP handle  
  8.     printf("The following phase of this program is signature.\n\n");  
  9.     if(CryptAcquireContext(  
  10.         &hProv,   
  11.         NULL,   
  12.         TEST_CSP_NAME,  
  13.         PROV_RSA_FULL,   
  14.         0))   
  15.     {  
  16.         printf("CSP context acquired.\n");  
  17.     }  
  18.     else    //create if not exist  
  19.     {  
  20.         if(CryptAcquireContext(  
  21.             &hProv,   
  22.             NULL,   
  23.             TEST_CSP_NAME,   
  24.             PROV_RSA_FULL,   
  25.             CRYPT_NEWKEYSET))   
  26.         {  
  27.             printf("A new key container has been created.\n");  
  28.         }  
  29.         else  
  30.         {  
  31.         }  
  32.     }  
  33.   
  34.     // 打开证书库  
  35.     HCERTSTORE hCertStore = CertOpenStore(  
  36.         CERT_STORE_PROV_SYSTEM,   // The store provider type.  
  37.         0,                        // The encoding type is not needed.  
  38.         hProv,               // Use the epassNG HCRYPTPROV.  
  39.         CERT_SYSTEM_STORE_CURRENT_USER,  
  40.         L"MY"  
  41.         );  
  42.     if(hCertStore == NULL)  
  43.     {  
  44.   
  45.     }  
  46.   
  47.     // 查找证书  
  48.     PCCERT_CONTEXT hCert = CertFindCertificateInStore(  
  49.         hCertStore,  
  50.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,  
  51.         0,  
  52.         CERT_FIND_SUBJECT_STR,  
  53.         L"周绍禹",  
  54.         NULL);  
  55.     if(hCert == NULL)  
  56.     {  
  57.   
  58.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  59.     }  
  60.     //将证书转成base64编码发送到接收方  
  61.     BYTE *newCert;  
  62.     newCert = new BYTE[hCert->cbCertEncoded];  
  63.     newCert = hCert->pbCertEncoded;  
  64.     string baseCert = base64_encode(newCert,hCert->cbCertEncoded);  
  65.     CComBSTR bstr(baseCert.c_str());  
  66.     *cert_base64_bstr = bstr;  
  67.     return S_OK;  
  68. }  

0 0
原创粉丝点击