⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cacertwizardsheet.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -