CertInfoPage.cpp
上传用户:dengkfang
上传日期:2008-12-30
资源大小:5233k
文件大小:20k
源码类别:

CA认证

开发平台:

Visual C++

  1. // CertInfoPage.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "minica.h"
  5. #include "CertInfoPage.h"
  6. #include "MiniMainDlg.h"
  7. #include <locale.h>
  8. #include "Evp.h"
  9. #include ".GenericClassLanguage.h"
  10. #include "minict.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CCertInfoPage property page
  18. const UINT uIniTextLen = 20;
  19. IMPLEMENT_DYNCREATE(CCertInfoPage, CPropertyPage)
  20. CCertInfoPage::CCertInfoPage() : CPropertyPage(CCertInfoPage::IDD)
  21. {
  22. //{{AFX_DATA_INIT(CCertInfoPage)
  23. //}}AFX_DATA_INIT
  24. }
  25. CCertInfoPage::~CCertInfoPage()
  26. {
  27. }
  28. void CCertInfoPage::DoDataExchange(CDataExchange* pDX)
  29. {
  30. CPropertyPage::DoDataExchange(pDX);
  31. //{{AFX_DATA_MAP(CCertInfoPage)
  32. // DDX_Control(pDX, IDC_EDIT_PATH, m_XpEdit);
  33. DDX_Control(pDX, IDC_CERTINFO_READ, m_Bread);
  34. DDX_Control(pDX, IDC_EDIT_INFO, m_RichEdit);
  35. DDX_Control(pDX, IDC_LIST_MOD, m_List);
  36. //}}AFX_DATA_MAP
  37. }
  38. BEGIN_MESSAGE_MAP(CCertInfoPage, CPropertyPage)
  39. //{{AFX_MSG_MAP(CCertInfoPage)
  40. ON_BN_CLICKED(IDC_CERTINFO_READ, OnBRead)
  41. ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_MOD, OnItemchangedListMod)
  42. //}}AFX_MSG_MAP
  43. END_MESSAGE_MAP()
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CCertInfoPage message handlers
  46. BOOL CCertInfoPage::OnInitDialog() 
  47. {
  48. CPropertyPage::OnInitDialog();
  49. m_Bread.SetThemeHelper(((CMiniCaApp *)AfxGetApp())->GetThemeHelperST());
  50. m_Bread.SetIcon(IDI_ICON_SELECTDIR);
  51. m_Bread.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
  52. // TODO: Add extra initialization here
  53. m_List.InsertColumn(0,MiniCT_1500,LVCFMT_LEFT,160); //字符域
  54. m_List.InsertColumn(1,MiniCT_1501,LVCFMT_LEFT,300); //"值"
  55. m_List.SetExtendedStyle(LVS_EX_UNDERLINECOLD|LVS_EX_FULLROWSELECT);
  56. CImageList * pImgList = ((CMiniCaApp *)AfxGetApp())->GetImgList();
  57. m_List.SetImageList(pImgList,LVSIL_SMALL);//用来改变LISTCTRL行宽度
  58. /* CHARFORMAT cfDefault;
  59. memset(&cfDefault,0,sizeof(cfDefault));
  60. cfDefault.cbSize=sizeof(cfDefault);
  61. cfDefault.dwMask=CFM_SIZE|CFM_SPACING;
  62. cfDefault.yHeight=200;
  63. m_RichEdit.SetDefaultCharFormat(cfDefault);//设置模式
  64. */
  65. // CG: The following block was added by the ToolTips component. { // Create the ToolTip control. m_toolTip.Create(this);
  66. // m_tooltip.AddTool(GetDlgItem(IDC_EDIT_PATH), CMiniCaApp::NormalCode("被解析的证书"));
  67. m_toolTip.AddTool(GetDlgItem(IDC_CERTINFO_READ), CMiniCaApp::NormalCode("选择要解析证书文件"));
  68. // TODO: Use one of the following forms to add controls: }
  69. if(!((CMiniCaApp *)AfxGetApp())->IsXpStyle())
  70. {
  71. ClassXP(GetDlgItem(IDC_EDIT_PATH)->m_hWnd,TRUE);
  72. }
  73. return TRUE;  // return TRUE unless you set the focus to a control
  74.               // EXCEPTION: OCX Property Pages should return FALSE
  75. }
  76. void CCertInfoPage::OnBRead() 
  77. {
  78. // TODO: Add your control notification handler code here
  79. CFileDialog dlgOpen(true,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, MiniCT_0721,NULL);
  80. CString strTitle = MiniCT_0719;
  81. dlgOpen.m_ofn.lpstrTitle = strTitle;//标题条
  82. if(dlgOpen.DoModal()!=IDOK) return;
  83. SetDlgItemText(IDC_EDIT_PATH,dlgOpen.GetPathName());
  84. char buf[256]={0};
  85. CString file = dlgOpen.GetPathName();
  86. if(!ViewCertInfo(file.GetBuffer(0), 0, NULL, buf))
  87. AddMsg(MiniCT_1502, M_ERROR);
  88. }
  89. void CCertInfoPage::OnItemchangedListMod(NMHDR* pNMHDR, LRESULT* pResult) 
  90. {
  91. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  92. // TODO: Add your control notification handler code here
  93. if (pNMListView->uChanged == LVIF_STATE)
  94. {
  95. if (pNMListView->uNewState)//选择改变
  96. {
  97. CString str=m_List.GetItemText(pNMListView->iItem,1);//得到内容
  98. if(strcmp(m_List.GetItemText(pNMListView->iItem,0), MiniCT_1510)==0)
  99. {
  100. CString strL,strR(m_strPubKey),strtemp;
  101. str.Empty();
  102. for(;;)
  103. {
  104. if(strlen(strR)==0)
  105. break;
  106. strL=strR.Left(4);
  107. strR=strR.Right(strR.GetLength()-4);
  108. strR.TrimLeft();
  109. strtemp.Format("%s ",strL);
  110. str+=strtemp;
  111. }
  112. }
  113. else
  114. {
  115. str.TrimRight("n");
  116. for(int nStart=0;;)
  117. {
  118. int state=str.Find("n",nStart);
  119. if(state==-1)
  120. break;
  121. str.Insert(state,"r");
  122. nStart=state+2;
  123. }
  124. }
  125. SetDlgItemText(IDC_EDIT_INFO,str);
  126. }
  127. }
  128. *pResult = 0;
  129. }
  130. BOOL CCertInfoPage::ViewCertInfo(char * cert, UINT certLen,void *x509, char *buf)
  131. {
  132. m_List.SetRedraw(FALSE);
  133. m_List.DeleteAllItems();
  134. SetDlgItemText(IDC_EDIT_INFO,"");
  135. if(certLen == 0 && x509 == 0)//表示拖动操作
  136. {
  137. SetDlgItemText(IDC_EDIT_PATH, cert);
  138. }
  139. stuCERTINFO info;
  140. if(!GetCertInfo(cert,certLen,x509,info,buf))
  141. {
  142. m_List.SetRedraw(TRUE);
  143. return FALSE;
  144. }
  145. CString str;
  146. int index=0;
  147. m_List.InsertItem(index, MiniCT_1503, 7); //版本
  148. str.Format("V%d",info.VER);
  149. m_List.SetItemText(index++,1,str);
  150. if(strlen(info.SN))//序号
  151. {
  152. m_List.InsertItem(index, MiniCT_1504, 7);//序列号
  153. str.Format("%04s",info.SN);
  154. m_List.SetItemText(index++,1,str);
  155. }
  156. if(strlen(info.SIGNATURE))//签名算法
  157. {
  158. m_List.InsertItem(index, MiniCT_1505, 7); //签名算法
  159. str.Format("%s",info.SIGNATURE);
  160. m_List.SetItemText(index++,1,str);
  161. }
  162. if(strlen(info.ISSUER))//颁发者
  163. {
  164. m_List.InsertItem(index, MiniCT_1506, 7); //颁发者
  165. str.Format("%s",info.ISSUER);
  166. m_List.SetItemText(index++,1,str);
  167. }
  168. if(strlen(info.NOTBEFORE))//起始日期
  169. {
  170. m_List.InsertItem(index, MiniCT_1507, 7);
  171. str.Format("%s",info.NOTBEFORE);
  172. m_List.SetItemText(index++,1,CMiniCaApp::NormalCode(str));
  173. }
  174. if(strlen(info.NOTAFTER))//中止日期
  175. {
  176. m_List.InsertItem(index, MiniCT_1508, 7);
  177. str.Format("%s",info.NOTAFTER);
  178. m_List.SetItemText(index++,1,CMiniCaApp::NormalCode(str));
  179. }
  180. if(strlen(info.SUBJECT))//主题
  181. {
  182. m_List.InsertItem(index, MiniCT_1509, 7);
  183. str.Format("%s",info.SUBJECT);
  184. m_List.SetItemText(index++,1,str);
  185. }
  186. if(strlen(info.PUBKEY))//公钥
  187. {
  188. m_List.InsertItem(index, MiniCT_1510, 7);
  189. str.Format("%s (%d Bits)",info.PUBTYPE,info.PUBLEN);
  190. m_List.SetItemText(index++,1,str);
  191. m_strPubKey.Format("%s",info.PUBKEY);//保存公钥
  192. }
  193. if(strlen(info.V3EXT))//扩展信息
  194. {
  195. str.Format("%s",info.V3EXT);
  196. CString strtemp,strL,strR(str),strl,strr;
  197. for(;;)
  198. {
  199. int state=strR.Find("rn");
  200. if(state==-1)
  201. break;
  202. strL=strR.Left(state);
  203. strR=strR.Right(strR.GetLength()-state-1);
  204. strR.TrimLeft();
  205. strtemp.Format("%s",strL);
  206. int j=strtemp.Find(":");
  207. strl=strtemp.Left(j);
  208. strr=strtemp.Right(strtemp.GetLength()-j-1);
  209. strr.TrimLeft();
  210. m_List.InsertItem(index,CMiniCaApp::NormalCode(strl),8);
  211. m_List.SetItemText(index++,1,CMiniCaApp::NormalCode(strr));
  212. }
  213. }
  214. if(strlen(info.THUMB))//缩微图算法
  215. {
  216. m_List.InsertItem(index, MiniCT_1511, 9);
  217. str.Format("%s",info.THUMB);
  218. m_List.SetItemText(index++,1,str);
  219. }
  220. if(strlen(info.THUMBPRINT))//缩微图
  221. {
  222. m_List.InsertItem(index, MiniCT_1512, 9);
  223. str.Format("%s",info.THUMBPRINT);
  224. CString strL,strR(str),strtemp;
  225. str.Empty();
  226. for(;;)
  227. {
  228. if(strlen(strR)==0)
  229. break;
  230. strL=strR.Left(4);
  231. strR=strR.Right(strR.GetLength()-4);
  232. strR.TrimLeft();
  233. strtemp.Format("%s ",strL);
  234. str+=strtemp;
  235. }
  236. m_List.SetItemText(index++,1,str);
  237. }
  238. m_List.SetRedraw();
  239. return TRUE;
  240. }
  241. void CCertInfoPage::AddMsg(CString info, DWORD type)
  242. {
  243. ((CMiniMainDlg *)GetParent())->AddMsg(MiniCT_0004,info, type); //"数证解析"
  244. }
  245. /*void CCertInfoPage::OnDropFiles(HDROP hDropInfo) 
  246. {
  247. //取得被拖动文件的数目
  248. UINT uiFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
  249.     for (UINT uiFile = 0; uiFile < uiFiles; uiFile++)
  250.     {
  251. //取得第uiFile个拖动文件名所占字节数
  252.         UINT uiLen = ::DragQueryFile(hDropInfo, uiFile, 0, 0);
  253.         TCHAR *pszFileName = new TCHAR[uiLen + 1];
  254.         ::DragQueryFile(hDropInfo, uiFile, pszFileName, uiLen + 1);
  255. SetDlgItemText(IDC_EDIT_PATH,pszFileName);
  256. char buf[256]={0};
  257. ViewCertInfo(pszFileName, NULL, buf);
  258.         delete[] pszFileName;
  259. }
  260. ::DragFinish(hDropInfo);
  261. }
  262. */
  263. BOOL CCertInfoPage::PreTranslateMessage(MSG* pMsg)
  264. {
  265. // CG: The following block was added by the ToolTips component. { // Let the ToolTip process this message. m_toolTip.RelayEvent(pMsg); } return CPropertyPage::PreTranslateMessage(pMsg); // CG: This was added by the ToolTips component.
  266. }
  267. void CCertInfoPage::Utf8ToAnsi(const UCHAR * lpsrc,const int srclen, LPSTR lpdst, int& dstlen)
  268. {
  269. WCHAR * Unicode;
  270.     int len = MultiByteToWideChar ( CP_UTF8 , 0 ,(char*) lpsrc ,-1 ,NULL,0);
  271.     Unicode = new WCHAR[len * sizeof(WCHAR)];
  272.     MultiByteToWideChar ( CP_UTF8 , 0 ,( char * ) lpsrc, -1, Unicode , len );
  273.     len = WideCharToMultiByte(CP_ACP,0,Unicode,-1,NULL,0,NULL,NULL);
  274.     dstlen = WideCharToMultiByte (CP_ACP,0,Unicode,-1,lpdst,len,NULL,NULL);
  275.     delete []Unicode;
  276. }
  277. BOOL CCertInfoPage::GetCertName(void *name,char * outName)
  278. {
  279. if(name == NULL) //X509_NAME_get_text_by_NID
  280. return FALSE;
  281. int num = X509_NAME_entry_count((X509_NAME *)name);
  282. X509_NAME_ENTRY * entry;
  283. ASN1_OBJECT * obj;
  284. ASN1_STRING * str;
  285. char objtmp[80] = {0};
  286. char  pmbbuf[3] = {0};
  287. int fn_nid = 0;
  288. const char * objbuf;
  289. setlocale(LC_CTYPE, ""); //NULL,””,”C”代表操作系统的缺省代码页 ; ”.ACP”,代表操作系统当前使用的代
  290. for(int i = 0 ;i < num;i ++)
  291. {
  292. entry = (X509_NAME_ENTRY *)X509_NAME_get_entry((X509_NAME *)name,i);
  293. obj = X509_NAME_ENTRY_get_object(entry);
  294. str = X509_NAME_ENTRY_get_data(entry);//得到 ASN1_STRING
  295. //判断str是否为UTF-8
  296. int len = 0;
  297. unsigned char * tmp = NULL; 
  298. if (str && ASN1_STRING_type(str) == V_ASN1_UTF8STRING)
  299. {
  300. len = ASN1_STRING_length(str);
  301. if (len >= 0)
  302. {
  303. tmp = (UCHAR *)OPENSSL_malloc(len+1);
  304. if (tmp)
  305. {
  306. memcpy(tmp, ASN1_STRING_data(str), len);
  307. tmp[len] = '';
  308. }
  309. }
  310. }
  311.     else /* not a UTF8 name */ ///////////转UTF-8
  312. {
  313. len = ASN1_STRING_to_UTF8(&tmp, str);
  314. }
  315. char buf[1024] = {0};
  316. int dstlen = 0;
  317. Utf8ToAnsi(tmp, len, buf, dstlen);
  318. OPENSSL_free(tmp);
  319. fn_nid = OBJ_obj2nid(obj);
  320. if(fn_nid == NID_undef)
  321. OBJ_obj2txt(objtmp, sizeof objtmp, obj, 1);
  322. else
  323. {
  324. objbuf = OBJ_nid2sn(fn_nid);
  325. strcpy(objtmp,objbuf);
  326. //objbuf = OBJ_nid2ln(fn_nid);
  327. }
  328. BIO *mem = BIO_new(BIO_s_mem());
  329. BIO_set_close(mem, BIO_CLOSE); 
  330. ASN1_STRING_print_ex(mem,str,ASN1_STRFLGS_ESC_QUOTE );
  331. BUF_MEM * bptr;
  332. BIO_get_mem_ptr(mem, &bptr);
  333. len = bptr->length;
  334. char * pbuf = new char[len+1];
  335. memset(pbuf,0,len+1);
  336. memcpy(pbuf,bptr->data,len);
  337. delete [] pbuf;
  338. if (mem != NULL) BIO_free(mem);
  339. OBJ_cleanup();
  340. strcat(outName,objtmp);//C
  341. strcat(outName,"=");//=
  342. strcat(outName,buf);
  343. strcat(outName," ");
  344. strcat(outName,"n");
  345. }
  346. return TRUE;
  347. }
  348. char * CCertInfoPage::GetCertTime(const ASN1_UTCTIME *s)
  349. {
  350. char buf[128]={0};
  351. char * p=buf;
  352. struct tm tm;
  353. memset(&tm,'',sizeof tm);
  354. #define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
  355. tm.tm_year=g2(s->data);
  356. if(tm.tm_year < 50)
  357. tm.tm_year+=100;
  358. tm.tm_mon=g2(s->data+2);
  359. tm.tm_mday=g2(s->data+4);
  360. tm.tm_hour=g2(s->data+6);
  361. tm.tm_min=g2(s->data+8);
  362. tm.tm_sec=g2(s->data+10);
  363. #undef g2
  364. TIME_ZONE_INFORMATION TimeZoneInformation;
  365. GetTimeZoneInformation(&TimeZoneInformation);
  366.  
  367. sprintf(buf,"%d-%02d-%02d %02d:%02d:%02d",tm.tm_year+1900,tm.tm_mon,tm.tm_mday,
  368. tm.tm_hour-(TimeZoneInformation.Bias)/60,tm.tm_min,tm.tm_sec);
  369. return p;
  370. }
  371. int CCertInfoPage::GetExtensions(BIO *bp,STACK_OF(X509_EXTENSION) *exts)
  372. {
  373. const UINT uLen = 82;
  374. char objtmp[uLen]={0};
  375. int fn_nid;
  376. int count=sk_X509_EXTENSION_num(exts);
  377. if( count<= 0) return 1;
  378. for (int i=0; i<count; i++)
  379. {
  380. ASN1_OBJECT *obj;
  381. X509_EXTENSION *ex;
  382. ex=sk_X509_EXTENSION_value(exts, i);
  383. /* if(i!=0)
  384. {
  385. if (BIO_printf(bp,"%*s",indent, "") <= 0) return 0;//indent空格长度
  386. }
  387. */ obj=X509_EXTENSION_get_object(ex);
  388. fn_nid = OBJ_obj2nid(obj);
  389. if(fn_nid==NID_undef)
  390. OBJ_obj2txt(objtmp, sizeof objtmp, obj, 1);
  391. else
  392. {
  393. switch(fn_nid)
  394. {
  395. case 82://"X509v3 Subject Key Identifier" 
  396. strncpy(objtmp, MiniCT_1513, uLen); //使用者密钥标识符
  397. break;
  398. case 83://"X509v3 Key Usage"  
  399. strncpy(objtmp, MiniCT_1514, uLen); //密钥用法
  400. break;
  401. case 84://"X509v3 Private Key Usage Period" 
  402. strncpy(objtmp, MiniCT_1515, uLen); //私钥周期
  403. break;
  404. case 85://"X509v3 Subject Alternative Name"
  405. strncpy(objtmp,MiniCT_1516, uLen); //使用者备用名称
  406. break;
  407. case 86://"X509v3 Issuer Alternative Name" 3 
  408. strncpy(objtmp, MiniCT_1517, uLen); //颁发机构备用名称
  409. break;
  410. case 87://"X509v3 Basic Constraints" 4
  411. strncpy(objtmp, MiniCT_1518, uLen); //基本限制
  412. break;
  413. case 88://"X509v3 CRL Number"
  414. strncpy(objtmp, MiniCT_1519, uLen); //CRL数量
  415. break;
  416. case 141://"X509v3 CRL Reason Code"
  417. strncpy(objtmp, MiniCT_1520, uLen); //CRL吊销原因
  418. break;
  419. case 103://"X509v3 CRL Distribution Points"
  420. strncpy(objtmp, MiniCT_1521, uLen); //CRL 分发点
  421. break;
  422. case 89://"X509v3 Certificate Policies"
  423. strncpy(objtmp, MiniCT_1522, uLen); //证书策略
  424. break;
  425. case 90://"X509v3 Authority Key Identifier"
  426. strncpy(objtmp, MiniCT_1523, uLen);
  427. break;
  428. case 126://"X509v3 Authority Key Identifier"
  429. strncpy(objtmp, MiniCT_1524, uLen); //增强型密钥用法
  430. break;
  431. case 177://Authority Information Access
  432. strncpy(objtmp, MiniCT_1525, uLen); //颁发机构信息访问
  433. break;
  434. default:
  435. i2t_ASN1_OBJECT(objtmp,sizeof(objtmp),obj);
  436. break;
  437. }
  438. }
  439. BIO_printf(bp,"%s: ",objtmp);//输入字符域
  440. if(!X509V3_EXT_print(bp, ex, X509_FLAG_COMPAT, 1))//输出可以识别项
  441. {
  442. M_ASN1_OCTET_STRING_print(bp,ex->value);//输出不可识别项目
  443. }
  444. BIO_puts(bp, "rn");//分割
  445. }
  446. return 1;
  447. }
  448. UINT CCertInfoPage::GetKeyLen(const void * px509)
  449. {
  450. UINT uReturn = 0;
  451. X509 * x509 = NULL;
  452. if(px509 != NULL)
  453. x509 = (X509 *)px509;
  454. //得到公钥
  455. EVP_PKEY * pkey = NULL;
  456. pkey = X509_get_pubkey(x509);
  457. if(pkey == NULL)
  458. {
  459. return 0;
  460. }
  461. if(EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA)/////////RSA
  462. {
  463. RSA * rsa = EVP_PKEY_get1_RSA(pkey);
  464. if(rsa != NULL)
  465. {
  466. //公钥长度 
  467. uReturn = EVP_PKEY_bits(pkey);
  468. RSA_free(rsa);
  469. }
  470. }
  471. return uReturn;
  472. }
  473. BOOL CCertInfoPage::GetSubjectInfo(const void * px509,char * name,char * msg)
  474. {
  475. X509 * x509=NULL;
  476. if(px509!=NULL)
  477. x509=(X509 *)px509;
  478. BOOL b = GetCertName(X509_get_subject_name(x509),(char *)name);
  479. if(!b)
  480. {
  481. strncpy(msg, MiniCT_1526, 24); //取得证书个体名称失败
  482. }
  483. return b;
  484. }
  485. //得到证书信息
  486. BOOL CCertInfoPage::GetCertInfo(const char * pCert,
  487.  const UINT certLen,
  488.  const void * px509,
  489.  stuCERTINFO & certinfo,
  490.  char * msg)
  491. {
  492. BOOL bFreeX509 = FALSE; //是否释放X509标识,如果内部合成的,最后释放,如果外部传入的,不释放
  493. BOOL bRet = TRUE; //操作结果
  494. char buf[255] = {0};
  495. UINT bits = 0;
  496. char * certBuf = NULL;
  497. X509 * x509 = NULL;
  498. EVP_PKEY * pkey = NULL;
  499. char * stringval = NULL;
  500. BIO * mem = NULL;
  501. BUF_MEM *bptr = NULL;
  502. X509_CINF *ci = NULL;
  503. int len = 0;
  504. int type ;
  505. if(pCert)
  506. len = strlen(pCert);
  507. if(px509 != NULL)
  508. x509 = (X509 *)px509;
  509. else if(len != 0)
  510. {
  511. x509 = CCertKey::LoadCert((char *)pCert,certLen,"",msg);
  512. if (x509 == NULL)
  513. {
  514. strncpy(msg, MiniCT_1527, uIniTextLen); //转换证书失败
  515. bRet =  FALSE;
  516. goto err;
  517. }
  518. bFreeX509 = TRUE;
  519. }
  520. else
  521. {
  522. strncpy(msg, MiniCT_1528, uIniTextLen); //没有任何证书信息
  523. bRet =  FALSE;
  524. goto err;
  525. }
  526. ci = x509->cert_info;
  527. mem = BIO_new(BIO_s_mem());
  528. BIO_set_close(mem, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
  529. //版本
  530. certinfo.VER=X509_get_version(x509)+1;
  531. //序列号
  532. stringval = i2s_ASN1_INTEGER(NULL,X509_get_serialNumber(x509)); //leak
  533. sprintf(certinfo.SN,"0%X",atoi(stringval));
  534. OPENSSL_free(stringval);
  535. //签名算法
  536. i2t_ASN1_OBJECT(certinfo.SIGNATURE,1024,ci->signature->algorithm);
  537. //颁发者
  538. GetCertName(X509_get_issuer_name(x509),certinfo.ISSUER);
  539. //起始日期
  540. strcpy(certinfo.NOTBEFORE,GetCertTime(X509_get_notBefore(x509)));
  541. //中止日期
  542. strcpy(certinfo.NOTAFTER,GetCertTime(X509_get_notAfter(x509)));
  543. //主题
  544. GetCertName(X509_get_subject_name(x509),certinfo.SUBJECT);
  545. //得到公钥
  546. pkey = X509_get_pubkey(x509);
  547. if(pkey == NULL)
  548. {
  549. strncpy(msg, MiniCT_1529, uIniTextLen); //取得公钥失败
  550. bRet =  FALSE;
  551. goto err;
  552. }
  553. type = EVP_PKEY_type(pkey->type);
  554. if(type==EVP_PKEY_RSA)/////////RSA
  555. {
  556. // char * sign=BN_bn2hex(pkey->pkey.rsa->n);
  557. //转换公钥rsa->der->数字
  558. strcpy(certinfo.PUBTYPE,"RSA");
  559. RSA * rsa = EVP_PKEY_get1_RSA(pkey);
  560. if(rsa != NULL)
  561. {
  562. //公钥长度 
  563. bits = EVP_PKEY_bits(pkey);
  564. certinfo.PUBLEN = bits;
  565. certBuf = new char[bits+1];
  566. i2d_RSAPublicKey_bio(mem,rsa);
  567. BIO_get_mem_ptr(mem, &bptr);
  568. UINT len = bptr->length;
  569. char * pbuf = new char[len+1];
  570. memset(pbuf,0,len+1);
  571. memcpy(pbuf,bptr->data,len);
  572. for(DWORD i = 0, j = 0; i < len, j < len*2; i++, j+=2)
  573. {
  574. unsigned char t = pbuf[i];
  575. sprintf((char *)&certBuf[j],"%X",t>>4);
  576. sprintf((char *)&certBuf[j+1],"%X",t&0x0F);
  577. }
  578. UINT keylen = sizeof(certinfo.PUBKEY);
  579. if(keylen < len*2)
  580. strncpy(certinfo.PUBKEY,certBuf,keylen);
  581. else
  582. strncpy(certinfo.PUBKEY,certBuf,bits+1);
  583. delete []pbuf;
  584. delete []certBuf;
  585. RSA_free(rsa);
  586. }
  587. else
  588. strncpy(certinfo.PUBKEY, MiniCT_1530, uIniTextLen); //取得RSA失败
  589. }
  590. else if(type == EVP_PKEY_DSA)/////////DSA
  591. {
  592. // char * sign=BN_bn2hex(pkey->pkey.rsa->n);
  593. //转换公钥rsa->der->数字
  594. strcpy(certinfo.PUBTYPE,"DSA");
  595. DSA * dsa = EVP_PKEY_get1_DSA(pkey);
  596. if(dsa!=NULL)
  597. {
  598. //公钥长度 
  599. bits=BN_num_bits(dsa->pub_key);
  600. certinfo.PUBLEN=bits;
  601. certBuf=new char[bits+1];
  602. i2d_DSA_PUBKEY_bio(mem,dsa);
  603. BIO_get_mem_ptr(mem, &bptr);
  604. UINT len=bptr->length;
  605. char * pbuf=new char[len+1];
  606. memset(pbuf,0,len+1);
  607. memcpy(pbuf,bptr->data,len);
  608. for(DWORD i = 0,j = 0; i < len, j<len*2; i++, j+=2)
  609. {
  610. unsigned char t = pbuf[i];
  611. sprintf((char *)&certBuf[j],"%X",t>>4);
  612. sprintf((char *)&certBuf[j+1],"%X",t&0x0F);
  613. }
  614. UINT keylen = sizeof(certinfo.PUBKEY);
  615. if(keylen < len*2)
  616. strncpy(certinfo.PUBKEY,certBuf,keylen);
  617. else
  618. strncpy(certinfo.PUBKEY,certBuf,bits+1);
  619. delete []pbuf;
  620. DSA_free(dsa);
  621. }
  622. else
  623. strncpy(certinfo.PUBKEY, MiniCT_1531, uIniTextLen); //取得DSA失败
  624. }
  625. //扩展信息
  626. BIO_reset(mem);//恢复bio
  627. if(GetExtensions(mem,ci->extensions))
  628. {
  629. BIO_get_mem_ptr(mem, &bptr);
  630. UINT len = bptr->length;
  631. char * pbuf = new char[len+1];
  632. memset(pbuf, 0, len+1);
  633. memcpy(pbuf, bptr->data, len);
  634. if(sizeof(certinfo.V3EXT) < len)
  635. strncpy(certinfo.V3EXT, pbuf, sizeof(certinfo.V3EXT));
  636. else
  637. strncpy(certinfo.V3EXT, pbuf, len);
  638. delete [] pbuf;
  639. }
  640. else
  641. strncpy(certinfo.V3EXT, MiniCT_1532, uIniTextLen); //取得扩展信息失败
  642. //取得证书摘要
  643. if(len!=0)
  644. {
  645. strcpy(certinfo.THUMB,"sha1");
  646. unsigned char md_value[MAX_MD_SIZE]="";
  647. UINT md_len=0;
  648. if(!CEvp::Digest("sha1",(char *)pCert,certLen,md_value,&md_len,msg))
  649. strncpy(certinfo.THUMBPRINT, MiniCT_1533, uIniTextLen); //缩微图失败
  650. else
  651. {
  652. char buf[MAX_MD_SIZE*2+1]="";
  653. for(unsigned i=0;i<md_len;i++)
  654. {
  655. sprintf((char *)&buf[i*2],"%02X",md_value[i]);//02x标示1个16进制变为2个字符,空补零
  656. }
  657. strcpy(certinfo.THUMBPRINT,buf);
  658. }
  659. }
  660. err:
  661. if(x509 && bFreeX509)
  662. {
  663. X509_free(x509); //////////////////
  664. }
  665. if (mem != NULL)
  666. BIO_free_all(mem);
  667. if(pkey)
  668. EVP_PKEY_free(pkey); /////////////////
  669. return bRet;
  670. }
  671. void CCertInfoPage::TranslateCT() //繙譯諸如樹型控件,列錶控件等內容
  672. {
  673. SetDlgItemText(IDC_CERTINFO_READ, MiniCT_10901);
  674. }