📄 cacertwizardsheet.cpp
字号:
// CaCertWizardSheet.cpp : implementation file
//
#include "stdafx.h"
#include "minica.h"
#define _WIN32_WINNT 0x0400
#include "wincrypt.h"
#include "CaCertWizardSheet.h"
#include "MiniMainDlg.h"
#include ".\GenericClass\Language.h"
#include "minict.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCaCertWizardSheet property page
IMPLEMENT_DYNCREATE(CCaCertWizardSheet, CPropertyPage)
CCaCertWizardSheet::CCaCertWizardSheet() : CPropertyPage(CCaCertWizardSheet::IDD)
{
//{{AFX_DATA_INIT(CCaCertWizardSheet)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_HinstLib = LoadLibrary(TEXT("Cryptui.dll"));
}
CCaCertWizardSheet::~CCaCertWizardSheet()
{
FreeLibrary(m_HinstLib);
m_ImgList.DeleteImageList();
}
void CCaCertWizardSheet::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCaCertWizardSheet)
DDX_Control(pDX, IDC_B_V, m_BV);
DDX_Control(pDX, IDC_B_NEXT, m_BNext);
DDX_Control(pDX, IDC_B_MADE, m_BMade);
DDX_Control(pDX, IDC_B_LAST, m_BLast);
DDX_Control(pDX, IDC_TAB_SHEET, m_CaWizardSheet);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCaCertWizardSheet, CPropertyPage)
//{{AFX_MSG_MAP(CCaCertWizardSheet)
ON_BN_CLICKED(IDC_B_V, OnBV)
ON_BN_CLICKED(IDC_B_MADE, OnBMade)
ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_SHEET, OnSelchangeTabSheet)
ON_BN_CLICKED(IDC_B_LAST, OnBLast)
ON_BN_CLICKED(IDC_B_NEXT, OnBNext)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipNotify)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCaCertWizardSheet message handlers
BOOL CCaCertWizardSheet::OnToolTipNotify( UINT id, NMHDR * pTTTStruct, LRESULT * pResult )
{
TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pTTTStruct;
UINT nID = pTTTStruct->idFrom;
CString strText;
switch(nID)
{
case IDC_B_MADE:
CCaCertInfoPage::stuCERTINFO CERTINFO;
stuSUBJECT * pCERT = NULL;
m_PageInfo.GetCert(pCERT,CERTINFO);
pCERT->RemoveAll(pCERT); //释放证书结构
CString strFormat;
strFormat = (CERTINFO.uCertFormat == 1) ? "DER" : "PEM";
strText.Format("制作数字证书\r密钥长度:%d\n 有效期:%d\n 证书格式%s",
CERTINFO.uCertLen, CERTINFO.uCertDay, strFormat);
_tcscpy(pTTT->szText, strText);//设置
return TRUE;
}
return FALSE;
}
BOOL CCaCertWizardSheet::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: Add extra initialization here
CXPStyleButtonST::SetAllThemeHelper(this, ((CMiniCaApp *)AfxGetApp())->GetThemeHelperST());
m_BLast.SetIcon(IDI_ICON_LAST);//上一步
m_BLast.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
m_BNext.SetIcon(IDI_ICON_NEXT);//下一步
m_BNext.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
m_BV.SetIcon(IDI_ICON13);//预览
m_BV.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
m_BMade.SetIcon(IDI_ICON12);//制作
m_BMade.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
// TODO: Add extra initialization here
// CG: The following block was added by the ToolTips component.
{
// Create the ToolTip control.
m_toolTip.Create(this);
m_toolTip.AddTool(GetDlgItem(IDC_B_LAST), CMiniCaApp::NormalCode("返回上一步操作"));
m_toolTip.AddTool(GetDlgItem(IDC_B_NEXT), CMiniCaApp::NormalCode("进入下一步操作"));
m_toolTip.AddTool(GetDlgItem(IDC_B_V), CMiniCaApp::NormalCode("预览数字证书\r密钥长度:384\n 有效期:1天\n 序号100"));
m_toolTip.AddTool(GetDlgItem(IDC_B_MADE), LPSTR_TEXTCALLBACK);
// TODO: Use one of the following forms to add controls:
}
// Tree initialization
m_ImgList.Create(16,16,TRUE|ILC_COLOR24,16,1);
HICON hIcon = NULL;
hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDI_ICON_CERTYPE), IMAGE_ICON, 16, 16, 0);
m_ImgList.Add(hIcon);//0
DestroyIcon(hIcon);
hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDI_ICON_CERTINFO), IMAGE_ICON, 16, 16, 0);
m_ImgList.Add(hIcon);//1
DestroyIcon(hIcon);
hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDI_ICON_CERTEXT), IMAGE_ICON, 16, 16, 0);
m_ImgList.Add(hIcon);//2
DestroyIcon(hIcon);
hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDI_ICON_CERTREPORT), IMAGE_ICON, 16, 16, 0);
m_ImgList.Add(hIcon);//3
DestroyIcon(hIcon);
hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDI_ICON_CERTSETUP), IMAGE_ICON, 16, 16, 0);
m_ImgList.Add(hIcon);//4
DestroyIcon(hIcon);
hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDI_ICON_CERTMAN), IMAGE_ICON, 16, 16, 0);
m_ImgList.Add(hIcon);//5
DestroyIcon(hIcon);
m_CaWizardSheet.SetImageList(&m_ImgList);
m_CaWizardSheet.AddPage(MiniCT_0200, 0, &m_PageType, IDD_PROPPAGE_CATYPE); //MiniCT_0200 "类型"
m_CaWizardSheet.AddPage(MiniCT_0201, 1, &m_PageInfo, IDD_PROPPAGE_CAINFO); //MiniCT_0201 "信息"
m_CaWizardSheet.AddPage(MiniCT_0202, 2, &m_PageExt, IDD_PROPPAGE_CAEXT); //MiniCT_0202 "扩展"
m_CaWizardSheet.AddPage(MiniCT_0203, 3, &m_PageReport, IDD_PROPPAGE_CAREPORT);//MiniCT_0203 "报告"
m_CaWizardSheet.AddPage(MiniCT_0204, 4, &m_PageIniSet, IDD_PROPPAGE_CAINI); //MiniCT_0204 "配置"
m_CaWizardSheet.AddPage(MiniCT_0205, 5, &m_PageMan, IDD_PROPPAGE_CAMAN); //MiniCT_0205 "管理"
m_CaWizardSheet.Show();
m_PageReport.GetWizard(&m_PageType, &m_PageInfo, &m_PageExt);
//这里没有报告,原因在于CCertDB中会进行报告,并且对存储路径赋值
//这里报告可能因为路径未赋值而出现报告显示错误的情况
//m_PageReport.ViewWizardInfo();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CCaCertWizardSheet::OnBV() //數證预览,只生成DER格式的证书
{
// TODO: Add your control notification handler code here
int type = -1;
char out[256] = {0};
char certBuf[10240] = {0};
char keyBuf[10240] = {0};
char p12Buf[10240] = {0};
UINT certLen = 10240,
keyLen = 10240,
p12Len = 10240;
DWORD lenCert=0,lenKey=0;//公钥长度,私钥长度
CString strCert,strKey,strPwd;//公私钥路径或内容,p12密钥
CString KUSAGE,EKUSAGE;
m_PageType.GetCert(KUSAGE,EKUSAGE,type);
stuSUBJECT * pCERT = NULL;
CCaCertInfoPage::stuCERTINFO CERTINFO;
m_PageInfo.GetCert(pCERT,CERTINFO);
stuCERTEXT * pCertExt = NULL;
m_PageExt.GetCert(pCertExt);
AddMsg(MiniCT_0206, M_WARING); //MiniCT_0206 "生成数证预览,证书密钥长度384,证书序号100,有效期1........"
if(type == 0)//根证书
{
if(MakeRoot(pCERT,"(MiniCA)",384,100,0,
"",NULL,NULL,pCertExt,certBuf,
&certLen,keyBuf,&keyLen,p12Buf,
&p12Len,out, DER))
{
SelectViewCert(certBuf,certLen);
}
else
AddMsg(out,M_ERROR);
}
else
{
char strCert[10240] = {0};
char strKey[10240] = {0};
if(((CMiniCaApp *)AfxGetApp())->GetRootCert(strCert, lenCert, strKey, lenKey,strPwd))
{
stuCertPair RootPair(strCert,lenCert,strKey,lenKey,strPwd.GetBuffer(0));
strPwd.ReleaseBuffer();
if(DirectCert(RootPair,384,100,0,1,"",pCERT,"(MiniCA)",KUSAGE.GetBuffer(0),
EKUSAGE.GetBuffer(0),pCertExt,
certBuf,&certLen,keyBuf,&keyLen,p12Buf,&p12Len,out, DER))
{
SelectViewCert(certBuf,certLen);
}
else
AddMsg(out,M_ERROR);
KUSAGE.ReleaseBuffer();
EKUSAGE.ReleaseBuffer();
}
}
pCERT->RemoveAll(pCERT); //删除证书结构
pCertExt->RemoveAll(pCertExt); //删除扩展结构
}
void CCaCertWizardSheet::OnBMade()
{
// TODO: Add your control notification handler code here
int type = -1;
CString KUSAGE,EKUSAGE;
m_PageType.GetCert(KUSAGE,EKUSAGE,type);
stuSUBJECT *pCERT = NULL;
CCaCertInfoPage::stuCERTINFO CERTINFO;
m_PageInfo.GetCert(pCERT,CERTINFO);
stuCERTEXT * pCertExt = NULL;
m_PageExt.GetCert(pCertExt);
switch(type)
{
case 0://根证书
MakeRootCert(pCERT,CERTINFO);
break;
default:
MakeCert(pCERT,CERTINFO,type,KUSAGE,EKUSAGE, pCertExt);
break;
}
pCERT->RemoveAll(pCERT); //释放证书结构
pCertExt->RemoveAll(pCertExt); //释放证书扩展结构
}
BOOL CCaCertWizardSheet::ViewCert(char * cert,UINT uCertLen)
{
//首先获得函数地址 GetProcAddress
//BOOL WINAPI CryptUIDlgViewContext(
//DWORD dwContextType,
//const void* pvContext,
//HWND hwnd,
//LPCWSTR pwszTitle,
//DWORD dwFlags,
//void* pvReserved
//);
typedef BOOL (WINAPI *ViewContext) (DWORD , const void * ,HWND , LPCWSTR , DWORD , void* ); //注意此地的WINAPI
ViewContext CryptUIDlgViewContext;
if(m_HinstLib)
{
CryptUIDlgViewContext = (ViewContext) GetProcAddress(m_HinstLib, TEXT("CryptUIDlgViewContext"));
// If the function address is valid, call the function.
if (NULL != CryptUIDlgViewContext)
{
PCCERT_CONTEXT pCertContext = NULL; //证书上下文 张凯棠 commer (卡门) 台中县
pCertContext = CertCreateCertificateContext(
X509_ASN_ENCODING, // The encoding type.
(UCHAR *)cert, // The encoded data from
uCertLen// the certificate retrieved.
);
if (pCertContext == NULL)
{
return FALSE;
}
BSTR bstrTitle = MiniCT_0207.AllocSysString();
(CryptUIDlgViewContext)(CERT_STORE_CERTIFICATE_CONTEXT, // Display a certificate.
pCertContext, // Pointer to the certificate
m_hWnd,
bstrTitle, //MiniCT_0207 "MiniCA 证书预览"
0,
NULL);
::SysFreeString(bstrTitle);
if (pCertContext != NULL)
CertFreeCertificateContext(pCertContext);
}
else
{
((CMiniMainDlg *)GetParent())->ViewCertInfo(cert,uCertLen);
AddMsg(MiniCT_0208, M_WARING); //MiniCT_0208 "此操作系统不支持外部数证预览,已转入内部预览"
}
}
return TRUE;
}
void CCaCertWizardSheet::SelectViewCert(char * pCert,UINT uLenCert)
{
if(m_HinstLib)
{
CRect Rect;
GetDlgItem(IDC_B_V)->GetWindowRect(&Rect);
// CPoint point;
// GetCursorPos(&point); // 当前鼠标坐标
BCMenu menu;
menu.LoadMenu(IDR_MENU_VIEWCERT);
menu.LoadToolbar(IDR_MINICAMENU);
CLanguage::TranslateMenu(&menu, MAKEINTRESOURCE(IDR_MENU_VIEWCERT));
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup);
UINT nSelection = pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL|
TPM_NONOTIFY|TPM_RETURNCMD,Rect.left + Rect.Width()/2, Rect.top + Rect.Height()/2,
this, NULL);
menu.DestroyMenu();
//返回菜单id
if(nSelection == ID_MENUITEM_INSIDE)//MiniCA预览
{
AddMsg(MiniCT_0207); //MiniCT_0207 "MiniCA数证预览"
((CMiniMainDlg *)GetParent())->ViewCertInfo(pCert,uLenCert,0);
}
else if(nSelection == ID_MENUITEM_OUTSIDE)//系统预览
{
AddMsg(MiniCT_0209); //MiniCT_0209 "外部数证预览"
ViewCert(pCert,uLenCert);
}
}
else
{
AddMsg(MiniCT_0207); //MiniCT_0207 "MiniCA数证预览"
((CMiniMainDlg *)GetParent())->ViewCertInfo(pCert,uLenCert,0);
}
}
void CCaCertWizardSheet::MakeRootCert(stuSUBJECT * pSUBJECT,CCaCertInfoPage::stuCERTINFO & CERTINFO)
{
CString m_Path(CERTINFO.cCertDir),m_ExtName(".cer");
char out[256] = {0};
char certBuf[10240] = {0};
char keyBuf[10240] = {0};
char p12Buf[10240] = {0};
UINT certLen = 10240,
keyLen = 10240,
p12Len = 10240;
//得到证书序号
DWORD dCertSn = m_PageMan.GetCertSn();
if(MakeRoot(pSUBJECT, "(MiniCA)",CERTINFO.uCertLen, dCertSn, CERTINFO.uCertDay,
CERTINFO.cCertPwd, NULL, NULL, NULL, certBuf,
&certLen, keyBuf, &keyLen, p12Buf, &p12Len, out, CERTINFO.uCertFormat))
{
UINT m_NameType = 0;
CMiniMainDlg * pMain = (CMiniMainDlg *)AfxGetMainWnd();
CCertDbPage * pDb = (CCertDbPage *)(pMain->GetPage("CCertDbPage"));
if(pDb)
{
m_NameType = pDb->GetNameType();
}
CString strName;
if(0 == m_NameType)//用户名
{
strName.Format("\\R%s", pSUBJECT->GetCN());
}
else if(1 == m_NameType)//序号
{
strName.Format("\\R%d", dCertSn);
}
else if(2 == m_NameType)//用户名 + 序号
{
strName.Format("\\R%s%d", pSUBJECT->GetCN(), dCertSn);
}
else if(3 == m_NameType)//序号 + 用户名
{
strName.Format("\\R%d%s", dCertSn, pSUBJECT->GetCN());
}
CString outCert = m_Path + strName + "Cert";
outCert += m_ExtName;
CString outKey = m_Path + strName + "Key";
outKey += m_ExtName;
CString p12 = m_Path + strName + ".Pfx";
FILE * pfc = fopen(outCert,"wb");
if(pfc != NULL)
{
fwrite(certBuf,sizeof(char),certLen,pfc);
fclose(pfc);
pfc = fopen(outKey,"wb");
if(pfc)
{
fwrite(keyBuf,sizeof(char),keyLen,pfc);
fclose(pfc);
AddMsg(MiniCT_0117); //MiniCT_0117
}
else
{
AddMsg(MiniCT_0116,M_ERROR); //MiniCT_0116
return;
}
if(CERTINFO.bCertP12)
{
pfc = fopen(p12,"wb");
if(pfc != 0)
{
fwrite(p12Buf,sizeof(char),p12Len,pfc);
fclose(pfc);
AddMsg(MiniCT_0119); //MiniCT_0119
}
else
{
AddMsg(MiniCT_0118); //MiniCT_0118
return;
}
}
}
else
{
AddMsg(MiniCT_0115,M_ERROR); //MiniCT_0115
return;
}
//证书信息保存进数据库
m_PageMan.SaveDb(pSUBJECT, CERTINFO.uCertLen, 0,
CERTINFO.uCertDay, p12Buf, p12Len, CERTINFO.cCertPwd);
}
}
void CCaCertWizardSheet::MakeCert(stuSUBJECT * pCERT,
CCaCertInfoPage::stuCERTINFO & CERTINFO,
const int type,
CString KUSAGE,CString EKUSAGE,
const stuCERTEXT * pCertExt)
{
DWORD lenCert=0,lenKey=0;//公钥长度,私钥长度
CString strPwd;//公私钥路径或内容,p12密钥
char cert[10240]={0},key[10240]={0},p12[10240]={0};
UINT certl=10240,keyl=10240,p12l=10240;
char out[256] = {0};
int save = 0;
CString m_Path(CERTINFO.cCertDir);
CString pwd,path;
char strCert[10240] = {0};
char strKey[10240] = {0};
if(((CMiniCaApp *)AfxGetApp())->GetRootCert(strCert, lenCert, strKey, lenKey,strPwd))
{
if(strlen(CERTINFO.cCertDir) == 0)//CSP
{
pwd = "";
save = 0;
}
else
{
pwd.Format("%s",CERTINFO.cCertPwd);
path.Format("%s",CERTINFO.cCertDir);
save = 1;
}
stuCertPair RootPair(strCert,lenCert,strKey,lenKey,strPwd.GetBuffer(0));
//是否生成证书成功了,如果成功则写入数据库,否则不写入
DWORD dCertSn = m_PageMan.GetCertSn();
if(dCertSn == -1)
{
AddMsg(MiniCT_0210,M_ERROR); //MiniCT_0210 "查询证书序号失败"
return;
}
//首先得到数据库里面的序号
if(DirectCert(RootPair,CERTINFO.uCertLen,
dCertSn,0,CERTINFO.uCertDay,pwd.GetBuffer(0),pCERT,"(MiniCA)",KUSAGE.GetBuffer(0),
EKUSAGE.GetBuffer(0),pCertExt,
cert,&certl,key,&keyl,p12,&p12l,out,CERTINFO.uCertFormat))
{
if(save)//磁盘
{
UINT m_NameType = 0;
CMiniMainDlg * pMain = (CMiniMainDlg *)AfxGetMainWnd();
CCertDbPage * pDb = (CCertDbPage *)(pMain->GetPage("CCertDbPage"));
if(pDb)
{
m_NameType = pDb->GetNameType();
}
CString strName;
if(0 == m_NameType)//用户名
{
strName.Format("\\%s", pCERT->GetCN());
}
else if(1 == m_NameType)//序号
{
strName.Format("\\%d", dCertSn);
}
else if(2 == m_NameType)//用户名 + 序号
{
strName.Format("\\%s%d", pCERT->GetCN(), dCertSn);
}
else if(3 == m_NameType)//序号 + 用户名
{
strName.Format("\\%d%s", dCertSn, pCERT->GetCN());
}
CString outCert = path + strName + "Cert.Cer";
CString outKey = path + strName + "Key.Cer";
CString p12path = path + strName + ".Pfx";
FILE * pfc = fopen(outCert,"wb");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -