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

CA认证

开发平台:

Visual C++

  1. // CaCertWizardSheet.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "minica.h"
  5. #define _WIN32_WINNT  0x0400
  6. #include "wincrypt.h"
  7. #include "CaCertWizardSheet.h"
  8. #include "MiniMainDlg.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. // CCaCertWizardSheet property page
  18. IMPLEMENT_DYNCREATE(CCaCertWizardSheet, CPropertyPage)
  19. CCaCertWizardSheet::CCaCertWizardSheet() : CPropertyPage(CCaCertWizardSheet::IDD)
  20. {
  21. //{{AFX_DATA_INIT(CCaCertWizardSheet)
  22. // NOTE: the ClassWizard will add member initialization here
  23. //}}AFX_DATA_INIT
  24. m_HinstLib = LoadLibrary(TEXT("Cryptui.dll"));
  25. }
  26. CCaCertWizardSheet::~CCaCertWizardSheet()
  27. {
  28.     FreeLibrary(m_HinstLib); 
  29. m_ImgList.DeleteImageList();
  30. }
  31. void CCaCertWizardSheet::DoDataExchange(CDataExchange* pDX)
  32. {
  33. CPropertyPage::DoDataExchange(pDX);
  34. //{{AFX_DATA_MAP(CCaCertWizardSheet)
  35. DDX_Control(pDX, IDC_B_V, m_BV);
  36. DDX_Control(pDX, IDC_B_NEXT, m_BNext);
  37. DDX_Control(pDX, IDC_B_MADE, m_BMade);
  38. DDX_Control(pDX, IDC_B_LAST, m_BLast);
  39. DDX_Control(pDX, IDC_TAB_SHEET, m_CaWizardSheet);
  40. //}}AFX_DATA_MAP
  41. }
  42. BEGIN_MESSAGE_MAP(CCaCertWizardSheet, CPropertyPage)
  43. //{{AFX_MSG_MAP(CCaCertWizardSheet)
  44. ON_BN_CLICKED(IDC_B_V, OnBV)
  45. ON_BN_CLICKED(IDC_B_MADE, OnBMade)
  46. ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_SHEET, OnSelchangeTabSheet)
  47. ON_BN_CLICKED(IDC_B_LAST, OnBLast)
  48. ON_BN_CLICKED(IDC_B_NEXT, OnBNext)
  49. ON_WM_DESTROY()
  50. //}}AFX_MSG_MAP
  51. ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipNotify)
  52. END_MESSAGE_MAP()
  53. /////////////////////////////////////////////////////////////////////////////
  54. // CCaCertWizardSheet message handlers
  55. BOOL CCaCertWizardSheet::OnToolTipNotify( UINT id, NMHDR * pTTTStruct, LRESULT * pResult )
  56. {
  57. TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pTTTStruct;    
  58.     UINT nID = pTTTStruct->idFrom;
  59. CString strText;
  60. switch(nID)
  61. {
  62. case IDC_B_MADE:
  63. CCaCertInfoPage::stuCERTINFO CERTINFO;
  64. stuSUBJECT * pCERT = NULL;
  65. m_PageInfo.GetCert(pCERT,CERTINFO);
  66. pCERT->RemoveAll(pCERT); //释放证书结构
  67. CString strFormat;
  68. strFormat = (CERTINFO.uCertFormat == 1) ? "DER" : "PEM";
  69. strText.Format("制作数字证书r密钥长度:%dn 有效期:%dn 证书格式%s", 
  70. CERTINFO.uCertLen, CERTINFO.uCertDay, strFormat);
  71. _tcscpy(pTTT->szText, strText);//设置
  72. return TRUE;
  73. }
  74. return FALSE;
  75. }
  76. BOOL CCaCertWizardSheet::OnInitDialog() 
  77. {
  78. CPropertyPage::OnInitDialog();
  79. // TODO: Add extra initialization here
  80. CXPStyleButtonST::SetAllThemeHelper(this, ((CMiniCaApp *)AfxGetApp())->GetThemeHelperST());
  81. m_BLast.SetIcon(IDI_ICON_LAST);//上一步
  82. m_BLast.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
  83. m_BNext.SetIcon(IDI_ICON_NEXT);//下一步
  84. m_BNext.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
  85. m_BV.SetIcon(IDI_ICON13);//预览
  86. m_BV.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
  87. m_BMade.SetIcon(IDI_ICON12);//制作
  88. m_BMade.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
  89. // TODO: Add extra initialization here
  90. // CG: The following block was added by the ToolTips component.
  91. {
  92. // Create the ToolTip control.
  93. m_toolTip.Create(this);
  94. m_toolTip.AddTool(GetDlgItem(IDC_B_LAST), CMiniCaApp::NormalCode("返回上一步操作"));
  95. m_toolTip.AddTool(GetDlgItem(IDC_B_NEXT), CMiniCaApp::NormalCode("进入下一步操作"));
  96. m_toolTip.AddTool(GetDlgItem(IDC_B_V), CMiniCaApp::NormalCode("预览数字证书r密钥长度:384n 有效期:1天n 序号100"));
  97. m_toolTip.AddTool(GetDlgItem(IDC_B_MADE), LPSTR_TEXTCALLBACK);
  98. // TODO: Use one of the following forms to add controls:
  99. }
  100. // Tree initialization
  101. m_ImgList.Create(16,16,TRUE|ILC_COLOR24,16,1);
  102. HICON hIcon =  NULL;
  103. hIcon =  (HICON)::LoadImage(::AfxGetInstanceHandle(), 
  104. MAKEINTRESOURCE(IDI_ICON_CERTYPE), IMAGE_ICON, 16, 16, 0);
  105. m_ImgList.Add(hIcon);//0
  106. DestroyIcon(hIcon);
  107. hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), 
  108. MAKEINTRESOURCE(IDI_ICON_CERTINFO), IMAGE_ICON, 16, 16, 0);
  109. m_ImgList.Add(hIcon);//1
  110. DestroyIcon(hIcon);
  111. hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), 
  112. MAKEINTRESOURCE(IDI_ICON_CERTEXT), IMAGE_ICON, 16, 16, 0);
  113. m_ImgList.Add(hIcon);//2
  114. DestroyIcon(hIcon);
  115. hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), 
  116. MAKEINTRESOURCE(IDI_ICON_CERTREPORT), IMAGE_ICON, 16, 16, 0);
  117. m_ImgList.Add(hIcon);//3
  118. DestroyIcon(hIcon);
  119. hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), 
  120. MAKEINTRESOURCE(IDI_ICON_CERTSETUP), IMAGE_ICON, 16, 16, 0);
  121. m_ImgList.Add(hIcon);//4
  122. DestroyIcon(hIcon);
  123. hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), 
  124. MAKEINTRESOURCE(IDI_ICON_CERTMAN), IMAGE_ICON, 16, 16, 0);
  125. m_ImgList.Add(hIcon);//5
  126. DestroyIcon(hIcon);
  127. m_CaWizardSheet.SetImageList(&m_ImgList);
  128. m_CaWizardSheet.AddPage(MiniCT_0200, 0, &m_PageType, IDD_PROPPAGE_CATYPE); //MiniCT_0200 "类型"
  129. m_CaWizardSheet.AddPage(MiniCT_0201, 1, &m_PageInfo, IDD_PROPPAGE_CAINFO); //MiniCT_0201 "信息"
  130. m_CaWizardSheet.AddPage(MiniCT_0202, 2, &m_PageExt, IDD_PROPPAGE_CAEXT); //MiniCT_0202 "扩展"
  131. m_CaWizardSheet.AddPage(MiniCT_0203, 3, &m_PageReport, IDD_PROPPAGE_CAREPORT);//MiniCT_0203 "报告"
  132. m_CaWizardSheet.AddPage(MiniCT_0204, 4, &m_PageIniSet, IDD_PROPPAGE_CAINI); //MiniCT_0204 "配置"
  133. m_CaWizardSheet.AddPage(MiniCT_0205, 5, &m_PageMan, IDD_PROPPAGE_CAMAN); //MiniCT_0205 "管理"
  134. m_CaWizardSheet.Show();
  135. m_PageReport.GetWizard(&m_PageType, &m_PageInfo, &m_PageExt);
  136. //这里没有报告,原因在于CCertDB中会进行报告,并且对存储路径赋值
  137. //这里报告可能因为路径未赋值而出现报告显示错误的情况
  138. //m_PageReport.ViewWizardInfo();
  139. return TRUE;  // return TRUE unless you set the focus to a control
  140.               // EXCEPTION: OCX Property Pages should return FALSE
  141. }
  142. void CCaCertWizardSheet::OnBV() //數證预览,只生成DER格式的证书
  143. {
  144. // TODO: Add your control notification handler code here
  145. int type = -1;
  146. char out[256] = {0};
  147. char certBuf[10240] = {0};
  148. char keyBuf[10240] = {0};
  149. char p12Buf[10240] = {0};
  150. UINT certLen = 10240,
  151.  keyLen = 10240,
  152.  p12Len = 10240;
  153. DWORD lenCert=0,lenKey=0;//公钥长度,私钥长度
  154. CString strCert,strKey,strPwd;//公私钥路径或内容,p12密钥
  155. CString KUSAGE,EKUSAGE;
  156. m_PageType.GetCert(KUSAGE,EKUSAGE,type);
  157. stuSUBJECT * pCERT = NULL;
  158. CCaCertInfoPage::stuCERTINFO CERTINFO;
  159. m_PageInfo.GetCert(pCERT,CERTINFO);
  160. stuCERTEXT * pCertExt = NULL;
  161. m_PageExt.GetCert(pCertExt);
  162. AddMsg(MiniCT_0206, M_WARING); //MiniCT_0206 "生成数证预览,证书密钥长度384,证书序号100,有效期1........"
  163. if(type == 0)//根证书
  164. {
  165. if(MakeRoot(pCERT,"(MiniCA)",384,100,0,
  166. "",NULL,NULL,pCertExt,certBuf,
  167. &certLen,keyBuf,&keyLen,p12Buf,
  168. &p12Len,out, DER))
  169. {
  170. SelectViewCert(certBuf,certLen);
  171. }
  172. else
  173. AddMsg(out,M_ERROR);
  174. }
  175. else
  176. {
  177. char strCert[10240] = {0};
  178. char strKey[10240] = {0};
  179. if(((CMiniCaApp *)AfxGetApp())->GetRootCert(strCert, lenCert, strKey, lenKey,strPwd))
  180. {
  181. stuCertPair RootPair(strCert,lenCert,strKey,lenKey,strPwd.GetBuffer(0));
  182. strPwd.ReleaseBuffer();
  183. if(DirectCert(RootPair,384,100,0,1,"",pCERT,"(MiniCA)",KUSAGE.GetBuffer(0),
  184. EKUSAGE.GetBuffer(0),pCertExt,
  185. certBuf,&certLen,keyBuf,&keyLen,p12Buf,&p12Len,out, DER))
  186. {
  187. SelectViewCert(certBuf,certLen);
  188. }
  189. else
  190. AddMsg(out,M_ERROR);
  191. KUSAGE.ReleaseBuffer();
  192. EKUSAGE.ReleaseBuffer();
  193. }
  194. }
  195. pCERT->RemoveAll(pCERT); //删除证书结构
  196. pCertExt->RemoveAll(pCertExt); //删除扩展结构
  197. }
  198. void CCaCertWizardSheet::OnBMade() 
  199. {
  200. // TODO: Add your control notification handler code here
  201. int type = -1;
  202. CString KUSAGE,EKUSAGE;
  203. m_PageType.GetCert(KUSAGE,EKUSAGE,type);
  204. stuSUBJECT *pCERT = NULL;
  205. CCaCertInfoPage::stuCERTINFO CERTINFO;
  206. m_PageInfo.GetCert(pCERT,CERTINFO);
  207. stuCERTEXT * pCertExt = NULL;
  208. m_PageExt.GetCert(pCertExt);
  209. switch(type)
  210. {
  211. case 0://根证书
  212. MakeRootCert(pCERT,CERTINFO);
  213. break;
  214. default:
  215. MakeCert(pCERT,CERTINFO,type,KUSAGE,EKUSAGE, pCertExt);
  216. break;
  217. }
  218. pCERT->RemoveAll(pCERT); //释放证书结构
  219. pCertExt->RemoveAll(pCertExt); //释放证书扩展结构
  220. }
  221. BOOL CCaCertWizardSheet::ViewCert(char * cert,UINT uCertLen)
  222. {
  223. //首先获得函数地址 GetProcAddress
  224. //BOOL WINAPI CryptUIDlgViewContext(
  225. //DWORD dwContextType,
  226. //const void* pvContext,
  227. //HWND hwnd,
  228. //LPCWSTR pwszTitle,
  229. //DWORD dwFlags,
  230. //void* pvReserved
  231. //);
  232. typedef BOOL (WINAPI *ViewContext) (DWORD , const void * ,HWND , LPCWSTR , DWORD , void* ); //注意此地的WINAPI
  233. ViewContext CryptUIDlgViewContext; 
  234. if(m_HinstLib)
  235. {
  236. CryptUIDlgViewContext = (ViewContext) GetProcAddress(m_HinstLib, TEXT("CryptUIDlgViewContext")); 
  237.         // If the function address is valid, call the function.
  238.         if (NULL != CryptUIDlgViewContext) 
  239.         {
  240. PCCERT_CONTEXT pCertContext = NULL; //证书上下文 张凯棠 commer  (卡门) 台中县
  241. pCertContext = CertCreateCertificateContext(
  242. X509_ASN_ENCODING, // The encoding type.
  243. (UCHAR *)cert, // The encoded data from
  244. uCertLen// the certificate retrieved.
  245. );
  246. if (pCertContext == NULL)
  247. {
  248. return FALSE;
  249. }
  250. BSTR bstrTitle = MiniCT_0207.AllocSysString();
  251. (CryptUIDlgViewContext)(CERT_STORE_CERTIFICATE_CONTEXT,   // Display a certificate.
  252.  pCertContext,                     // Pointer to the certificate
  253.  m_hWnd,
  254.  bstrTitle, //MiniCT_0207 "MiniCA 证书预览"
  255.  0,
  256.  NULL);
  257. ::SysFreeString(bstrTitle);
  258. if (pCertContext != NULL)
  259. CertFreeCertificateContext(pCertContext);
  260.         }
  261. else 
  262. {
  263. ((CMiniMainDlg *)GetParent())->ViewCertInfo(cert,uCertLen);
  264. AddMsg(MiniCT_0208, M_WARING); //MiniCT_0208 "此操作系统不支持外部数证预览,已转入内部预览"
  265. }
  266. }
  267. return TRUE;
  268. }
  269. void CCaCertWizardSheet::SelectViewCert(char * pCert,UINT uLenCert)
  270. {
  271. if(m_HinstLib)
  272. {
  273. CRect Rect;
  274. GetDlgItem(IDC_B_V)->GetWindowRect(&Rect);
  275. // CPoint point;
  276. // GetCursorPos(&point); // 当前鼠标坐标
  277. BCMenu menu;
  278. menu.LoadMenu(IDR_MENU_VIEWCERT);
  279. menu.LoadToolbar(IDR_MINICAMENU);
  280. CLanguage::TranslateMenu(&menu, MAKEINTRESOURCE(IDR_MENU_VIEWCERT));
  281. CMenu* pPopup = menu.GetSubMenu(0);
  282. ASSERT(pPopup);
  283. UINT nSelection = pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL|
  284. TPM_NONOTIFY|TPM_RETURNCMD,Rect.left + Rect.Width()/2, Rect.top + Rect.Height()/2,
  285. this, NULL);
  286. menu.DestroyMenu();
  287. //返回菜单id
  288. if(nSelection == ID_MENUITEM_INSIDE)//MiniCA预览
  289. {
  290. AddMsg(MiniCT_0207); //MiniCT_0207 "MiniCA数证预览"
  291. ((CMiniMainDlg *)GetParent())->ViewCertInfo(pCert,uLenCert,0);
  292. }
  293. else if(nSelection == ID_MENUITEM_OUTSIDE)//系统预览
  294. {
  295. AddMsg(MiniCT_0209); //MiniCT_0209 "外部数证预览"
  296. ViewCert(pCert,uLenCert);
  297. }
  298. }
  299. else
  300. {
  301. AddMsg(MiniCT_0207); //MiniCT_0207 "MiniCA数证预览"
  302. ((CMiniMainDlg *)GetParent())->ViewCertInfo(pCert,uLenCert,0);
  303. }
  304. }
  305. void CCaCertWizardSheet::MakeRootCert(stuSUBJECT * pSUBJECT,CCaCertInfoPage::stuCERTINFO & CERTINFO)
  306. {
  307. CString m_Path(CERTINFO.cCertDir),m_ExtName(".cer");
  308. char out[256] = {0};
  309. char certBuf[10240] = {0};
  310. char keyBuf[10240] = {0};
  311. char p12Buf[10240] = {0};
  312. UINT certLen = 10240,
  313.  keyLen = 10240,
  314.  p12Len = 10240;
  315. //得到证书序号
  316. DWORD dCertSn = m_PageMan.GetCertSn();
  317. if(MakeRoot(pSUBJECT, "(MiniCA)",CERTINFO.uCertLen, dCertSn, CERTINFO.uCertDay,
  318. CERTINFO.cCertPwd, NULL, NULL, NULL, certBuf,
  319. &certLen, keyBuf, &keyLen, p12Buf, &p12Len, out, CERTINFO.uCertFormat))
  320. {
  321. UINT m_NameType = 0;
  322. CMiniMainDlg * pMain = (CMiniMainDlg *)AfxGetMainWnd();
  323. CCertDbPage * pDb = (CCertDbPage *)(pMain->GetPage("CCertDbPage"));
  324. if(pDb)
  325. {
  326. m_NameType = pDb->GetNameType();
  327. }
  328. CString strName;
  329. if(0 == m_NameType)//用户名
  330. {
  331. strName.Format("\R%s", pSUBJECT->GetCN());
  332. }
  333. else if(1 == m_NameType)//序号
  334. {
  335. strName.Format("\R%d", dCertSn);
  336. }
  337. else if(2 == m_NameType)//用户名 + 序号
  338. {
  339. strName.Format("\R%s%d", pSUBJECT->GetCN(), dCertSn);
  340. }
  341. else if(3 == m_NameType)//序号 + 用户名
  342. {
  343. strName.Format("\R%d%s", dCertSn, pSUBJECT->GetCN());
  344. }
  345. CString outCert = m_Path + strName + "Cert";
  346. outCert += m_ExtName;
  347. CString outKey = m_Path + strName + "Key";
  348. outKey += m_ExtName;
  349. CString p12 = m_Path  + strName + ".Pfx";
  350. FILE * pfc = fopen(outCert,"wb");
  351. if(pfc != NULL)
  352. {
  353. fwrite(certBuf,sizeof(char),certLen,pfc);
  354. fclose(pfc);
  355. pfc = fopen(outKey,"wb");
  356. if(pfc)
  357. {
  358. fwrite(keyBuf,sizeof(char),keyLen,pfc);
  359. fclose(pfc);
  360. AddMsg(MiniCT_0117); //MiniCT_0117
  361. }
  362. else
  363. {
  364. AddMsg(MiniCT_0116,M_ERROR); //MiniCT_0116
  365. return;
  366. }
  367. if(CERTINFO.bCertP12)
  368. {
  369. pfc = fopen(p12,"wb");
  370. if(pfc != 0)
  371. {
  372. fwrite(p12Buf,sizeof(char),p12Len,pfc);
  373. fclose(pfc);
  374. AddMsg(MiniCT_0119); //MiniCT_0119
  375. }
  376. else
  377. {
  378. AddMsg(MiniCT_0118); //MiniCT_0118
  379. return;
  380. }
  381. }
  382. }
  383. else
  384. {
  385. AddMsg(MiniCT_0115,M_ERROR); //MiniCT_0115
  386. return;
  387. }
  388. //证书信息保存进数据库
  389. m_PageMan.SaveDb(pSUBJECT, CERTINFO.uCertLen, 0, 
  390. CERTINFO.uCertDay, p12Buf, p12Len, CERTINFO.cCertPwd);
  391. }
  392. }
  393. void CCaCertWizardSheet::MakeCert(stuSUBJECT * pCERT,
  394.  CCaCertInfoPage::stuCERTINFO & CERTINFO,
  395.  const int type,
  396.  CString KUSAGE,CString EKUSAGE,
  397.  const stuCERTEXT * pCertExt)
  398. {
  399. DWORD lenCert=0,lenKey=0;//公钥长度,私钥长度
  400. CString strPwd;//公私钥路径或内容,p12密钥
  401. char cert[10240]={0},key[10240]={0},p12[10240]={0};
  402. UINT certl=10240,keyl=10240,p12l=10240;
  403. char out[256] = {0};
  404. int save = 0;
  405. CString m_Path(CERTINFO.cCertDir);
  406. CString pwd,path;
  407. char strCert[10240] = {0};
  408. char strKey[10240] = {0};
  409. if(((CMiniCaApp *)AfxGetApp())->GetRootCert(strCert, lenCert, strKey, lenKey,strPwd))
  410. {
  411. if(strlen(CERTINFO.cCertDir) == 0)//CSP
  412. {
  413. pwd = "";
  414. save = 0;
  415. }
  416. else
  417. {
  418. pwd.Format("%s",CERTINFO.cCertPwd);
  419. path.Format("%s",CERTINFO.cCertDir);
  420. save = 1;
  421. }
  422. stuCertPair RootPair(strCert,lenCert,strKey,lenKey,strPwd.GetBuffer(0));
  423. //是否生成证书成功了,如果成功则写入数据库,否则不写入
  424. DWORD dCertSn = m_PageMan.GetCertSn();
  425. if(dCertSn == -1)
  426. {
  427. AddMsg(MiniCT_0210,M_ERROR); //MiniCT_0210 "查询证书序号失败" 
  428. return;
  429. }
  430. //首先得到数据库里面的序号
  431. if(DirectCert(RootPair,CERTINFO.uCertLen,
  432. dCertSn,0,CERTINFO.uCertDay,pwd.GetBuffer(0),pCERT,"(MiniCA)",KUSAGE.GetBuffer(0),
  433. EKUSAGE.GetBuffer(0),pCertExt,
  434. cert,&certl,key,&keyl,p12,&p12l,out,CERTINFO.uCertFormat))
  435. {
  436. if(save)//磁盘
  437. {
  438. UINT m_NameType = 0;
  439. CMiniMainDlg * pMain = (CMiniMainDlg *)AfxGetMainWnd();
  440. CCertDbPage * pDb = (CCertDbPage *)(pMain->GetPage("CCertDbPage"));
  441. if(pDb)
  442. {
  443. m_NameType = pDb->GetNameType();
  444. }
  445. CString strName;
  446. if(0 == m_NameType)//用户名
  447. {
  448. strName.Format("\%s", pCERT->GetCN());
  449. }
  450. else if(1 == m_NameType)//序号
  451. {
  452. strName.Format("\%d", dCertSn);
  453. }
  454. else if(2 == m_NameType)//用户名 + 序号
  455. {
  456. strName.Format("\%s%d", pCERT->GetCN(), dCertSn);
  457. }
  458. else if(3 == m_NameType)//序号 + 用户名
  459. {
  460. strName.Format("\%d%s", dCertSn, pCERT->GetCN());
  461. }
  462. CString outCert = path + strName + "Cert.Cer";
  463. CString outKey = path + strName + "Key.Cer";
  464. CString p12path = path + strName + ".Pfx";
  465. FILE * pfc = fopen(outCert,"wb");
  466. if(!pfc)
  467. {
  468. AddMsg(MiniCT_0128,M_ERROR); //MiniCT_0128 "保存公钥文件失败"
  469. return;
  470. }
  471. fwrite(cert,sizeof(char),certl,pfc);
  472. fclose(pfc);
  473. pfc = fopen(outKey,"wb");
  474. if(!pfc)
  475. {
  476. AddMsg(MiniCT_0127,M_ERROR); //MiniCT_0127 "保存私钥文件失败"
  477. return;
  478. }
  479. fwrite(key,sizeof(char),keyl,pfc);
  480. fclose(pfc);
  481. AddMsg(MiniCT_0124); //MiniCT_0124 "生成证书成功"
  482. if(CERTINFO.bCertP12)
  483. {
  484. pfc = fopen(p12path,"wb");
  485. if(!pfc)
  486. {
  487. AddMsg(MiniCT_0126,M_ERROR); //MiniCT_0126 "保存PFX文件失败"
  488. return;
  489. }
  490. fwrite(p12,sizeof(char),p12l,pfc);
  491. fclose(pfc);
  492. AddMsg(MiniCT_0125); //MiniCT_0125 "证书PFX包制作成功"
  493. }
  494. }
  495. else//CSP
  496. {
  497. ImportCSP(p12,p12l,CERTINFO.cCertCsp,CERTINFO.cCertCon);
  498. //GetCspCertInfo(CERTINFO.cCertCsp,CERTINFO.cCertCon,0);
  499. }
  500. //证书信息保存进数据库
  501. m_PageMan.SaveDb(pCERT, CERTINFO.uCertLen, type, 
  502. CERTINFO.uCertDay, p12, p12l, pwd.GetBuffer(0));
  503. }
  504. else
  505. AddMsg(out,M_ERROR);
  506. }
  507. else
  508. AddMsg(MiniCT_0123,M_ERROR); //MiniCT_0123 "加载根证书失败"
  509. }
  510. void CCaCertWizardSheet::AddMsg(CString info, DWORD type)
  511. {
  512. ((CMiniMainDlg *)GetParent())->AddMsg(MiniCT_0000,info, type); //MiniCT_0000 "数证向导"
  513. }
  514. void  CCaCertWizardSheet::ShowError()
  515. {
  516. char Buffer[200];
  517. memset(Buffer,0,200);
  518. FormatMessage(                                                                                                                                                                                                                                                                                                                                                                                                     
  519. FORMAT_MESSAGE_FROM_SYSTEM,     // source and processing options
  520. NULL, // pointer to  message source
  521. GetLastError(), // requested message identifier
  522. 0, // language identifier for requested message
  523. Buffer, // pointer to message buffer
  524. 200, // maximum size of message buffer
  525. NULL // pointer to array of message inserts
  526. );
  527. AddMsg(Buffer,M_ERROR);
  528. }
  529. BOOL CCaCertWizardSheet::ImportCSP(char * memP12,UINT lenP12,CString szCSPName,CString szKeycon)
  530. {
  531. // TODO: Add your control notification handler code here
  532. long ret = 0;
  533. HCRYPTPROV hCryptProv = NULL; //指定CSP句柄
  534. BYTE  *szContainerName = NULL; //CONTAINER名称
  535. HCRYPTKEY hCryptKey = NULL ; //密钥句柄
  536. PCCERT_CONTEXT pCertContext = NULL; //证书上下文
  537. DWORD dwKeySpec;
  538. CRYPT_DATA_BLOB pPFX;
  539. HCERTSTORE hStore;
  540. HCRYPTKEY hUser;
  541. BYTE bData[10240];
  542. DWORD cbData = 10240;
  543. pPFX.cbData = lenP12;
  544. pPFX.pbData = (UCHAR *)memP12;
  545. // //new 改为动态调用
  546. //从PFX BLOB导入到指定证书库
  547. hStore = PFXImportCertStore(
  548. &pPFX,
  549. L"",  //Password
  550. CRYPT_EXPORTABLE); //得到证书库句柄
  551. if (hStore == NULL)
  552. {
  553. ShowError();
  554. return FALSE;
  555. }
  556. // search any certificate 通过证书库得到证书上下文 ---  也就是察看上面的文件中是否有证书信息
  557. if (!(pCertContext=CertFindCertificateInStore(
  558. hStore,
  559. X509_ASN_ENCODING,
  560. 0,
  561. CERT_FIND_ANY,
  562. NULL,
  563. NULL))) 
  564. {
  565. ShowError();
  566. return FALSE;
  567. }
  568. //new 改为动态调用
  569. // 对于指定证书上下文得到一个HCRYPTPROV句柄和 dwKeySpec 
  570. ret = CryptAcquireCertificatePrivateKey(//通过证书上下文得到CSP句柄
  571. pCertContext,
  572. CRYPT_ACQUIRE_CACHE_FLAG,
  573. NULL,
  574. &hCryptProv,//CSP句柄
  575. &dwKeySpec,//加密还是签名 AT_KEYEXCHANGE 1 AT_SIGNATURE 2 
  576. NULL
  577. );
  578. // CString strType;
  579. // strType.Format("密钥类型%d",dwKeySpec);
  580. // AfxMessageBox(strType);
  581. if (!ret)
  582. {
  583. ShowError();
  584. return FALSE;
  585. }
  586. ret = CryptGetUserKey(//得到密钥对句柄
  587. hCryptProv,
  588. dwKeySpec,
  589. &hUser
  590. );
  591. if (!ret)
  592. {
  593. ShowError();
  594. return FALSE;
  595. }
  596. ret = CryptExportKey( //将CSP中的密钥导出
  597. hUser,
  598. 0,
  599. PUBLICKEYBLOB,
  600. 0,
  601. bData,
  602. &cbData
  603. );  //PUBLICKEYBLOB -148         PRIVATEKEYBLOB - 596
  604. if (!ret)
  605. {
  606. ShowError();
  607. return FALSE;
  608. }
  609. CryptDestroyKey(hUser);
  610. CryptReleaseContext(hCryptProv, 0);
  611. hCryptProv = 0;
  612. if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, szKeycon,
  613. szCSPName, PROV_RSA_FULL, CRYPT_NEWKEYSET)))
  614. {
  615. long err = GetLastError();
  616. if(0x8009000f == err)//对象已经存在 
  617. {
  618. if(::MessageBox(this->m_hWnd,MiniCT_0211, MiniCT_0212,MB_ICONQUESTION | MB_YESNO)==IDYES)
  619. //MiniCT_0211 "证书对象已经存在,是否覆盖"
  620. //MiniCT_0212 ,"CSP提示"
  621. {
  622. if (CryptAcquireContext(&hCryptProv, szKeycon,
  623. szCSPName, PROV_RSA_FULL, CRYPT_DELETEKEYSET))//删除对象
  624. {
  625. if (RCRYPT_FAILED(CryptAcquireContext(&hCryptProv, szKeycon,
  626. szCSPName, PROV_RSA_FULL, CRYPT_NEWKEYSET)))//重新创建
  627. {
  628. ShowError();
  629. return FALSE;
  630. }
  631. }
  632. }
  633. else
  634. {
  635. return FALSE;
  636. }
  637. }
  638. else
  639. {
  640. ShowError();
  641. return FALSE;
  642. }
  643. }
  644. if (RCRYPT_FAILED(CryptImportKey(
  645. hCryptProv,
  646. bData,
  647. cbData,
  648. 0,
  649. 0,
  650. &hUser)))
  651. {
  652. ShowError();
  653. return FALSE;
  654. }
  655. CryptDestroyKey(hUser);
  656. /* if (RCRYPT_FAILED(CryptGetUserKey(hCryptProv,
  657. dwKeySpec,
  658. &hUser)))
  659. {
  660. if (GetLastError() == ERROR_INVALID_PARAMETER)
  661. {
  662. }
  663. else
  664. {
  665. }
  666. }
  667. if (RCRYPT_FAILED(CryptSetKeyParam(
  668. hUser,
  669. KP_CERTIFICATE,
  670. pCertContext->pbCertEncoded,
  671. 0)))
  672. {
  673. ShowError();
  674. return FALSE;
  675. }
  676. CryptDestroyKey(hUser);
  677. */
  678. if (RCRYPT_FAILED(CryptReleaseContext(hCryptProv, 0)))
  679. {
  680. ShowError();
  681. return FALSE;
  682. }
  683. CertFreeCertificateContext(pCertContext);
  684. CertCloseStore(hStore,0);
  685. AddMsg(MiniCT_0213); //MiniCT_0213 "证书导入CSP成功"
  686. return TRUE;
  687. }
  688. long CCaCertWizardSheet::GetCspCertInfo(LPTSTR szCSPName, LPTSTR ContainerName, DWORD KeySpec)
  689. {
  690. long ret = 0;
  691. HCRYPTPROV hCryptProv = NULL; //指定CSP句柄
  692. BYTE  *szContainerName = NULL; //CONTAINER名称
  693. /// DWORD cbContainerName, maxcbContainerName;//CONTAINER长度
  694. BYTE CertBuff[4096]; //证书信息
  695. HCRYPTKEY hCryptKey = NULL; //密钥句柄
  696. PCCERT_CONTEXT pCertContext = NULL; //证书上下文
  697. // DWORD dwKeySpec;
  698. // DWORD dwFlags;
  699. DWORD dwCertLength;
  700. // char PIN[10];
  701. __try
  702. {
  703. //取得指定CSP的访问句柄
  704. ret = CryptAcquireContext(&hCryptProv,
  705. ContainerName,
  706. szCSPName,
  707. PROV_RSA_FULL,
  708. 0);
  709. if (ret == 0)
  710. {
  711.  ShowError();
  712. __leave;
  713. }
  714. //取得CONTAINER的名字列表中最大长度
  715. /* ret = CryptGetProvParam(hCryptProv,
  716. PP_ENUMCONTAINERS,
  717. NULL, //取得最大的名称长度
  718. &cbContainerName, 
  719. 0);
  720. if (ret == 0)
  721. {
  722. ShowError();
  723. __leave;
  724. }
  725. maxcbContainerName = cbContainerName;
  726. szContainerName = (BYTE*)malloc(cbContainerName);
  727. // 读取第一个CONTAINER名字
  728. dwFlags = CRYPT_FIRST;
  729. cbContainerName = maxcbContainerName;
  730. ret = CryptGetProvParam(hCryptProv,
  731. PP_ENUMCONTAINERS,
  732. szContainerName,
  733. &cbContainerName,
  734. dwFlags);
  735. if (ret == 0)
  736. {
  737. ShowError();
  738. __leave;
  739. }
  740. memset(PIN, 0, 10);
  741. PIN[0]='0';
  742. PIN[1]='0';
  743. PIN[2]='0';
  744. PIN[3]='0';
  745. //设置PIN值
  746. ret = CryptSetProvParam(hCryptProv,
  747. PP_KEYEXCHANGE_PIN,
  748. (unsigned char *)PIN,
  749. 0);
  750. if (ret == 0)
  751. {
  752. ShowError();
  753. __leave;
  754. }
  755. */
  756. //读取CONTAINER中的KEY
  757. ret = CryptGetUserKey(hCryptProv,
  758. AT_KEYEXCHANGE, 
  759. &hCryptKey);
  760. if (ret == 0)
  761. {
  762. ShowError();
  763. __leave;
  764. }
  765. //取得指定密钥相关的证书
  766. dwCertLength = sizeof(CertBuff);
  767. ret = CryptGetKeyParam(hCryptKey,
  768. KP_CERTIFICATE,
  769. CertBuff,
  770. &dwCertLength,
  771. 0);
  772. if (ret == 0)
  773. {
  774. ShowError();
  775. __leave;
  776. }
  777. char temp[100] = {0};
  778. pCertContext = CertCreateCertificateContext(
  779. X509_ASN_ENCODING, // The encoding type.
  780. CertBuff, // The encoded data from
  781. // the certificate retrieved.
  782. dwCertLength );
  783. if (pCertContext == NULL) 
  784. {//Not X.509 Certification
  785. __leave;
  786. }
  787. //new 改为动态调用
  788. /* CertGetNameString(   
  789.    pCertContext,   
  790.    CERT_NAME_SIMPLE_DISPLAY_TYPE,   
  791.    0,
  792.    NULL,   
  793.    (char *)temp,   
  794.    128);
  795. CertGetNameString(   
  796.    pCertContext,   
  797.    CERT_NAME_EMAIL_TYPE,   
  798.    0,
  799.    NULL,   
  800.    (char *)temp,   
  801.    128);
  802. CertGetNameString(   
  803.    pCertContext,   
  804.    CERT_NAME_SIMPLE_DISPLAY_TYPE,   
  805.    CERT_NAME_ISSUER_FLAG,
  806.    NULL,   
  807.    (char *)temp,   
  808.    128);*/
  809. /* CryptUIDlgViewContext(
  810. CERT_STORE_CERTIFICATE_CONTEXT,   // Display a certificate.
  811. pCertContext,                     // Pointer to the certificate
  812. m_hWnd,
  813. L"MiniCA 证书预览",
  814. 0,
  815. NULL);*/
  816. __leave;
  817. }
  818. __finally
  819. {
  820. if(pCertContext)
  821. CertFreeCertificateContext(pCertContext);
  822. if (hCryptKey)
  823. CryptDestroyKey(hCryptKey);
  824. if (hCryptProv)
  825. CryptReleaseContext(hCryptProv,0);
  826. if (szContainerName)
  827. free(szContainerName);
  828. return ret;
  829. }
  830. }
  831. void CCaCertWizardSheet::OnSelchangeTabSheet(NMHDR* pNMHDR, LRESULT* pResult) 
  832. {
  833. // TODO: Add your control notification handler code here
  834. //NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  835. int iSelect = m_CaWizardSheet.GetCurSel();
  836. if(iSelect > 3)//屏蔽
  837. {
  838. GetDlgItem(IDC_B_LAST)->EnableWindow(FALSE);
  839. GetDlgItem(IDC_B_NEXT)->EnableWindow(FALSE);
  840. }
  841. else
  842. {
  843. GetDlgItem(IDC_B_LAST)->EnableWindow(TRUE);
  844. GetDlgItem(IDC_B_NEXT)->EnableWindow(TRUE);
  845. }
  846. m_PageReport.ViewWizardInfo();
  847. *pResult = 0;
  848. }
  849. void CCaCertWizardSheet::OnBLast() 
  850. {
  851. // TODO: Add your control notification handler code here
  852. int iSelect = m_CaWizardSheet.GetCurSel();
  853. if(iSelect >= 4)
  854. {
  855. return;
  856. }
  857. m_CaWizardSheet.SetCurSel(iSelect - 1);
  858. m_PageReport.ViewWizardInfo();
  859. }
  860. void CCaCertWizardSheet::OnBNext() 
  861. {
  862. // TODO: Add your control notification handler code here
  863. int iSelect = m_CaWizardSheet.GetCurSel();
  864. if(iSelect >= 3)
  865. return;
  866. m_CaWizardSheet.SetCurSel(iSelect + 1);
  867. m_PageReport.ViewWizardInfo();
  868. }
  869. //通过类名,返回制定属性页的对象指针
  870. CWnd * CCaCertWizardSheet::GetPage(CString strPageName)
  871. {
  872. //枚举属性页
  873. CRuntimeClass * prt = NULL;
  874. prt = m_PageType.GetRuntimeClass();
  875. if(strcmp( prt->m_lpszClassName, strPageName )  == 0 )
  876. return &m_PageType;
  877. prt = m_PageInfo.GetRuntimeClass();
  878. if(strcmp( prt->m_lpszClassName, strPageName )  == 0 )
  879. return &m_PageInfo;
  880. prt = m_PageExt.GetRuntimeClass();
  881. if(strcmp( prt->m_lpszClassName, strPageName )  == 0 )
  882. return &m_PageExt;
  883. prt = m_PageReport.GetRuntimeClass();
  884. if(strcmp( prt->m_lpszClassName, strPageName )  == 0 )
  885. return &m_PageReport;
  886. prt = m_PageIniSet.GetRuntimeClass();
  887. if(strcmp( prt->m_lpszClassName, strPageName )  == 0 )
  888. return &m_PageIniSet;
  889. prt = m_PageMan.GetRuntimeClass();
  890. if(strcmp( prt->m_lpszClassName, strPageName )  == 0 )
  891. return &m_PageMan;
  892. return NULL;
  893. }
  894. void CCaCertWizardSheet::OnDestroy() 
  895. {
  896. CPropertyPage::OnDestroy();
  897. // TODO: Add your message handler code here
  898. m_PageType.DestroyWindow();
  899. m_PageInfo.DestroyWindow();
  900. m_PageExt.DestroyWindow();
  901. m_PageMan.DestroyWindow();
  902. m_PageReport.DestroyWindow();
  903. m_PageIniSet.DestroyWindow();
  904. }
  905. void CCaCertWizardSheet::Language()
  906. {
  907. CLanguage::TranslateDialog(m_PageType.m_hWnd, MAKEINTRESOURCE(IDD_PROPPAGE_CATYPE));
  908. m_PageType.TranslateCT();
  909. CLanguage::TranslateDialog(m_PageInfo.m_hWnd, MAKEINTRESOURCE(IDD_PROPPAGE_CAINFO));
  910. m_PageInfo.TranslateCT();
  911. CLanguage::TranslateDialog(m_PageExt.m_hWnd, MAKEINTRESOURCE(IDD_PROPPAGE_CAEXT));
  912. m_PageExt.TranslateCT();
  913. CLanguage::TranslateDialog(m_PageReport.m_hWnd, MAKEINTRESOURCE(IDD_PROPPAGE_CAREPORT));
  914. m_PageReport.ViewWizardInfo();
  915. CLanguage::TranslateDialog(m_PageMan.m_hWnd, MAKEINTRESOURCE(IDD_PROPPAGE_CAMAN));
  916. m_PageMan.TranslateCT();
  917. CLanguage::TranslateDialog(m_PageIniSet.m_hWnd, MAKEINTRESOURCE(IDD_PROPPAGE_CAINI));
  918. m_PageIniSet.TranslateCT();
  919. CLanguage::TranslateDialog(this->m_hWnd, MAKEINTRESOURCE(IDD_PROPPAGE_CASHEET));
  920. m_CaWizardSheet.SetPageName(0, MiniCT_0200);
  921. m_CaWizardSheet.SetPageName(1, MiniCT_0201);
  922. m_CaWizardSheet.SetPageName(2, MiniCT_0202);
  923. m_CaWizardSheet.SetPageName(3, MiniCT_0203);
  924. m_CaWizardSheet.SetPageName(4, MiniCT_0204);
  925. m_CaWizardSheet.SetPageName(5, MiniCT_0205);
  926. //翻译STATIC
  927. SetDlgItemText(IDC_B_NEXT, MiniCT_10701);
  928. SetDlgItemText(IDC_B_LAST, MiniCT_10702);
  929. SetDlgItemText(IDC_B_MADE, MiniCT_10703);
  930. SetDlgItemText(IDC_B_V, MiniCT_10704);
  931. }
  932. BOOL CCaCertWizardSheet::PreTranslateMessage(MSG* pMsg) 
  933. {
  934. // TODO: Add your specialized code here and/or call the base class
  935. m_toolTip.RelayEvent(pMsg);
  936. return CPropertyPage::PreTranslateMessage(pMsg);
  937. }