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

📄 certimportdlg.cpp

📁 证书导入工具
💻 CPP
字号:
// CertImportDlg.cpp : implementation file
//

#include "stdafx.h"
#include "CertImport.h"
#include "CertImportDlg.h"


#define UNICODE
#define _UNICODE

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)


// You have to update the SDK for getting the latest version for the files BasesTD.h, 
// wincrypt.h and Crypt32.lib

#include <stdio.h>
#include <windows.h> 

#include <wincrypt.h>


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

// Global function for free handles...
void FreeHandles(HANDLE hfile, HANDLE hsection, HCERTSTORE hFileStore, void* pfx, PCCERT_CONTEXT pctx, 	HCERTSTORE pfxStore, HCERTSTORE myStore )
{

	if (myStore) 
		CertCloseStore(myStore, 0);
	
	if (pfxStore) 
		CertCloseStore(pfxStore, CERT_CLOSE_STORE_FORCE_FLAG);

	if(pctx)
		CertFreeCertificateContext(pctx);

	if (pfx) 
		UnmapViewOfFile(pfx);

	if (hFileStore) 
		CertCloseStore(hFileStore, 0);

	if (hsection) 
		CloseHandle(hsection);

	if (INVALID_HANDLE_VALUE != hfile) 
		CloseHandle(hfile);

}



class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCertImportDlg dialog

CCertImportDlg::CCertImportDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCertImportDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCertImportDlg)
	m_pathCA = _T("");
	m_pathPer = _T("");
	m_pwd = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCertImportDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCertImportDlg)
	DDX_Text(pDX, IDC_EDIT_CA, m_pathCA);
	DDX_Text(pDX, IDC_EDIT_PER, m_pathPer);
	DDX_Text(pDX, IDC_EDIT_PWD, m_pwd);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCertImportDlg, CDialog)
	//{{AFX_MSG_MAP(CCertImportDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON4, OnImport)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCertImportDlg message handlers

BOOL CCertImportDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CCertImportDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CCertImportDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CCertImportDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CCertImportDlg::OnOK() 
{
	// TODO: Add extra validation here
	
	// First we import the CA Certificate...
	if(ImportCACert())
		// And after the personal 
		if(ImportPerCert())
			AfxMessageBox("Certificates imported correctly.");

	CDialog::OnOK();
}

void CCertImportDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	UpdateData(true);
	CFileDialog dlg(TRUE,
					NULL,
					NULL,
					OFN_HIDEREADONLY,
					"Personal Security certificates (*.p12)|*.p12|All files (*.*)|*.*||",
					NULL);

	if(dlg.DoModal() == IDOK)
	{
		m_pathPer = dlg.GetPathName();
		UpdateData(false);
	}
}

void CCertImportDlg::OnButton2() 
{
	// TODO: Add your control notification handler code here
	UpdateData(true);
	CFileDialog dlg(TRUE,
					NULL,
					NULL,
					OFN_HIDEREADONLY,
					"CA Security certificates (*.der)|*.der|All files (*.*)|*.*||",
					NULL);

	if(dlg.DoModal() == IDOK)
	{
		m_pathCA = dlg.GetPathName();
		UpdateData(false);
	}
	
}


// This function imports a CA certificate...
int CCertImportDlg::ImportCACert()
{
	HCERTSTORE pfxStore = 0;
	HCERTSTORE myStore = 0;
	HCERTSTORE hFileStore = 0;
	HANDLE hsection = 0;
	void* pfx = NULL;
	HANDLE hfile = INVALID_HANDLE_VALUE;
	PCCERT_CONTEXT pctx = NULL;

	// Get path of the CA certificate from the edit box
	UpdateData(true);

	// Open it...
	hfile = CreateFile(m_pathCA, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
	
	// FOR WINDOWS 98 ....	
	// hfile = CreateFile(m_pathCA, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

	if (INVALID_HANDLE_VALUE == hfile) 
	{
		AfxMessageBox("Certificate not found. Check that the path indicated is correct.", MB_ICONERROR);
		return 0;
	}

	hsection = CreateFileMapping(hfile, 0, PAGE_READONLY, 0, 0, 0);

	if (!hsection) 
	{
		AfxMessageBox("Error in 'CreateFileMapping'", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);		
		return 0;
	}

	pfx = MapViewOfFile(hsection, FILE_MAP_READ, 0, 0, 0);

	if (!pfx) 
	{
		AfxMessageBox("Error in 'MapViewOfFile'", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);	
		return 0;
	}

	pctx = CertCreateCertificateContext(MY_ENCODING_TYPE, (BYTE*)pfx, GetFileSize(hfile,0));

	if(pctx == NULL)
	{
		AfxMessageBox("Error in 'CertCreateCertificateContext'", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);	
		return 0;
	}

	// we open the store for the CA
	hFileStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, L"Root" );
		
	if (!hFileStore) 
	{
		AfxMessageBox("Error in 'CertOpenStore'", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);	
		return 0;
	}

	if(!CertAddCertificateContextToStore(hFileStore, pctx, CERT_STORE_ADD_NEW, 0))
	{
		
		DWORD err = GetLastError();

		if (CRYPT_E_EXISTS == err) 
		{
			if(AfxMessageBox("An equivalent previous personal certificate already exists. Overwrite ? (Yes/No)", MB_YESNO) == IDYES)
			{
				if (!CertAddCertificateContextToStore(hFileStore, pctx, CERT_STORE_ADD_REPLACE_EXISTING, 0)) 
				{
					AfxMessageBox("Error in 'CertAddCertificateContextToStore'", MB_ICONERROR);
					FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);	
					return 0;

				}
			}
		}
		else 
		{
			AfxMessageBox("Error in 'CertAddCertificateContextToStore'", MB_ICONERROR);
			FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);	
			return 0;
		}
	}

	return 1;
}


int CCertImportDlg::ImportPerCert()
{
	HANDLE hfile = INVALID_HANDLE_VALUE;
	HANDLE hsection = 0;
	void* pfx = 0;
	HCERTSTORE pfxStore = 0;
	HCERTSTORE hFileStore = 0;
	HCERTSTORE myStore = 0;
	PCCERT_CONTEXT pctx = 0;
	bool recognizedPFX;

	UpdateData(true);

	// get the handle to the file...
	hfile = CreateFile(m_pathPer, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
	
	// FOR WINDOWS 98
	// hfile = CreateFile(ruta , GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

	if (INVALID_HANDLE_VALUE == hfile) 
	{
		AfxMessageBox("Certificate not found. Check that the path indicated is correct.", MB_ICONERROR);
		return 0;
	}

	// now we create a file mapping object for that file
	hsection = CreateFileMapping(hfile, 0, PAGE_READONLY, 0, 0, 0);

	if (!hsection) 
	{
		AfxMessageBox("Error in 'CreateFileMapping'", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);
		return 0;
	}

	// we map into pfx a view of the file that we previously open
	pfx = MapViewOfFile(hsection, FILE_MAP_READ, 0, 0, 0);

	if (!pfx) 
	{
		AfxMessageBox("Error in 'MapViewOfFile'", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);
		return 0;

	}

	// and with that view we make a blob ...
	CRYPT_DATA_BLOB blob;
	blob.cbData = GetFileSize(hfile, 0);
	blob.pbData = (BYTE*)pfx;
	recognizedPFX = false;

	try 
	{
		// ... and after we try to decode that blob to see if pfx is recognized...
		if (PFXIsPFXBlob(&blob)) 
			recognizedPFX = true;
	}
	
	catch (...) 
	{
	}

	if (!recognizedPFX) 
	{
		AfxMessageBox("This certificate is not valid.", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);		
		return 0;
	}

	wchar_t password[128];

	// We get the password that the user typed in the edit box...
	GetPassword(password);
			
	// We import the certificate store from the blob. I needed it to exportable...
	pfxStore = PFXImportCertStore(&blob, password, CRYPT_MACHINE_KEYSET | CRYPT_EXPORTABLE);

	// FOR WINDOWS 98 is not valid the flag CRYPT_MACHINE_KEYSET
	// pfxStore = PFXImportCertStore(&blob, password, CRYPT_EXPORTABLE);
	
	if (!pfxStore) 
	{
		AfxMessageBox("Error in PFXImportCertStore. Probably password incorrect.", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);
		return 0;
	}

	// and we open de certificate store where we want to save the certificate
	// I choose "My" for the personal store...
	myStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY");

	// FOR WINDOWS 98
	// myStore = CertOpenSystemStore(NULL, L"MY");

	if (!myStore) 
	{
		AfxMessageBox("Error in 'CertOpenSystemStore'", MB_ICONERROR);
		FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);
		return 0;
	}
	

	// while exist certificates in the pfxStore store....
	while (0 != (pctx = CertEnumCertificatesInStore(pfxStore, pctx))) 
	{
		
		wchar_t name[128];
		
		// we get the friendly name of the certificate...
		if (!CertGetNameString(pctx, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, 0, name, sizeof name / sizeof *name)) 
		{
			AfxMessageBox("Error in 'CertGetNameString'", MB_ICONERROR);
		}
		
		// and we try to add it to the store got before with CertOpenStore
		if (!CertAddCertificateContextToStore(myStore, pctx, CERT_STORE_ADD_NEW, 0)) 
		{
			DWORD err = GetLastError();

			// Maybe theres another equal certificate already added
			if (CRYPT_E_EXISTS == err) 
			{
				if(AfxMessageBox("An equivalent previous personal certificate already exists. Overwrite ? (Yes/No)", MB_YESNO) == IDYES)
				{
					if (!CertAddCertificateContextToStore(myStore, pctx, CERT_STORE_ADD_REPLACE_EXISTING, 0)) 
					{
						AfxMessageBox("Error in 'CertAddCertificateContextToStore'", MB_ICONERROR);
						FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);
						return 0;
					}
				}
			}
			else 
			{
				AfxMessageBox("Error en 'CertAddCertificateContextToStore'", MB_ICONERROR);
				FreeHandles(hfile, hsection, hFileStore, pfx, pctx, pfxStore, myStore);
				return 0;
			}
		}
	}

	return 1;
}

void CCertImportDlg::GetPassword(wchar_t* pwd) 
{
	UpdateData(TRUE);
	int pwdlong = m_pwd.GetLength();
	int x;

	for(x=0; x<pwdlong ; x++)
		pwd[x] = m_pwd.GetAt(x);

	pwd[x] = L'\0';

}


void CCertImportDlg::OnImport() 
{
	// TODO: Add your control notification handler code here
	// First we import the CA Certificate...
	if(ImportCACert())
		// And after the personal 
		if(ImportPerCert())
		{
			AfxMessageBox("Certificates imported correctly.");
			EndDialog(1);
		}
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -