clsel509.c

来自「PGP8.0源码 请认真阅读您的文件包然后写出其具体功能」· C语言 代码 · 共 448 行

C
448
字号
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	PNselect.c - key selection dialog

	$Id: CLsel509.c,v 1.10 2002/08/06 20:09:19 dallen Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"

// project header files
#include "PGPclx.h"
#include "pgpImageList.h"

#define TOP_LIST_OFFSET			32
#define HOR_LIST_OFFSET			8
#define BOTTOM_LIST_OFFSET		48
#define BOTTOM_BUTTON_OFFSET	10
#define BUTTON_HEIGHT			24
#define BUTTON_WIDTH			70
#define BUTTON_SPACING			10

// External globals
extern HINSTANCE	g_hInst;
extern HIMAGELIST	g_hilKeys;


typedef struct {
	PGPKeyDBObjRef	key;
	PGPKeyDBObjRef	sig;
} X509CERT, *PX509CERT;

typedef struct {
	PGPContextRef	context;
	LPSTR			pszPrompt;
	UINT			uFlags;
	PGPKeySetRef	keyset;
	PGPKeyDBRef		keydbMain;
	PGPKeyDBObjRef	keySelected;
	PGPKeyDBObjRef	sigSelected;
	HCURSOR			hcursor;
} X509SELECTSTRUCT, *PX509SELECTSTRUCT;

// local globals
static DWORD aIds[] = {			// Help IDs
	IDOK,				IDH_PGPCLX509_SELECT,
	IDC_X509CERTLIST,	IDH_PGPCLX509_SELECTLIST,
	0,0
};


//	____________________________________
//
//	initialize the list view control

static VOID
sInitCertList (
		HWND				hwnd,
		PX509SELECTSTRUCT	pxss)
{
	LV_COLUMN		lvc;
	RECT			rc;

	// Associate the image list with the tree view control.
	ListView_SetImageList (GetDlgItem (hwnd, IDC_X509CERTLIST),
			g_hilKeys, LVSIL_SMALL);

	// add column
	GetClientRect (GetDlgItem (hwnd, IDC_X509CERTLIST), &rc);
	lvc.mask = LVCF_WIDTH;
	lvc.cx = rc.right - rc.left;
	ListView_InsertColumn (GetDlgItem (hwnd, IDC_X509CERTLIST), 0, &lvc);
}


//	____________________________________
//
//	load the list view control with certs

static VOID
sLoadCertList (
		HWND				hwnd,
		PX509SELECTSTRUCT	pxss)
{
	PGPKeyIterRef	keyiter			= kInvalidPGPKeyIterRef;
	PGPFilterRef	filterPGP		= kInvalidPGPFilterRef;
	PGPKeyDBObjRef	key				= kInvalidPGPKeyDBObjRef;
	PGPError		err				= kPGPError_NoErr;

	PGPKeyDBObjRef	userid;
	PGPKeyDBObjRef	sig;
	PGPSize			size;
	PX509CERT		pcert;

	PGPBoolean		bIsX509;
	LV_ITEM			lvi;
	CHAR			sz[kPGPMaxUserIDSize +1];

	ListView_DeleteAllItems (GetDlgItem (hwnd, IDC_X509CERTLIST));

	lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
	lvi.iItem = 0;
	lvi.iSubItem = 0;
	lvi.pszText = sz;

	// then get X509 auth key
	err = PGPNewKeyIterFromKeySet (pxss->keyset, &keyiter); CKERR;
	err = PGPKeyIterNextKeyDBObj (keyiter,
			kPGPKeyDBObjType_Key, &key); CKERR;
	while (key)
	{
		PGPKeyIterNextKeyDBObj (keyiter,
				kPGPKeyDBObjType_UserID, &userid);
		while (userid)
		{
			PGPKeyIterNextKeyDBObj (keyiter,
					kPGPKeyDBObjType_Signature, &sig);
			while (sig)
			{
				lvi.iImage = PGPclDetermineCertIcon (sig, NULL, &bIsX509);
				if (bIsX509)
				{
					err = kPGPError_NoErr;

					if (pxss->uFlags & kPGPclSelectX509CACertsOnly)
					{
						PGPKeyDBObjRef	sigSigner;

						err = PGPGetSigX509CertifierSig (sig,
								pxss->keydbMain, &sigSigner);
						if (sigSigner != sig)
							err = kPGPError_UserAbort;
					}

					if (IsntPGPError (err))
					{
						PGPGetKeyDBObjDataProperty (sig,
								kPGPSigProperty_X509LongName,
								sz, sizeof(sz), &size);
						sz[min(sizeof(sz)-1, size)] = '\0';

						pcert = PGPNewData (
								PGPPeekContextMemoryMgr (pxss->context),
								sizeof(X509CERT), kPGPMemoryMgrFlags_Clear);
						if (pcert)
						{
							pcert->key = key;
							pcert->sig = sig;

							lvi.lParam = (LPARAM)pcert;
							ListView_InsertItem (
								GetDlgItem (hwnd, IDC_X509CERTLIST), &lvi);
						}
					}
				}

				PGPKeyIterNextKeyDBObj (keyiter,
						kPGPKeyDBObjType_Signature, &sig);
			}
			PGPKeyIterNextKeyDBObj (keyiter,
					kPGPKeyDBObjType_UserID, &userid);
		}
		PGPKeyIterNextKeyDBObj (keyiter,
				kPGPKeyDBObjType_Key, &key);
	}
	InvalidateRect (GetDlgItem (hwnd, IDC_X509CERTLIST), NULL, FALSE);

done :
	if (PGPKeyIterRefIsValid (keyiter))
		PGPFreeKeyIter (keyiter);
}


//	____________________________________
//
//	free the data structures associated with the list

static VOID
sDestroyCertList (
		HWND				hwnd,
		PX509SELECTSTRUCT	pxss)
{
	HWND		hwndList;
	INT			i, iNumItems;
	LV_ITEM		lvi;

	hwndList = GetDlgItem (hwnd, IDC_X509CERTLIST);
	iNumItems = ListView_GetItemCount (hwndList);

	lvi.mask = LVIF_PARAM;
	for (i=0; i<iNumItems; i++)
	{
		lvi.iItem = i;
		ListView_GetItem (hwndList, &lvi);
		if (lvi.lParam)
		{
			PGPFreeData ((PVOID)lvi.lParam);
		}
	}
}


//	____________________________________
//
//	size the list control and move the buttons

static VOID
sSizeControls (
		HWND	hwnd,
		WORD	wXsize,
		WORD	wYsize)
{
	HDWP	hdwp;
	HWND	hwndList;
	RECT	rc;

	// size the list control accordingly
	hdwp = BeginDeferWindowPos (3);
	hwndList = GetDlgItem (hwnd, IDC_X509CERTLIST);
	DeferWindowPos (hdwp,
		hwndList, NULL,
		HOR_LIST_OFFSET, TOP_LIST_OFFSET,
		wXsize - (2*HOR_LIST_OFFSET),
		wYsize - BOTTOM_LIST_OFFSET - TOP_LIST_OFFSET,
		SWP_NOZORDER);

	// move the "cancel" button
	DeferWindowPos (hdwp,
		GetDlgItem (hwnd, IDCANCEL), NULL,
		wXsize - HOR_LIST_OFFSET - BUTTON_WIDTH,
		wYsize - BOTTOM_BUTTON_OFFSET - BUTTON_HEIGHT,
		BUTTON_WIDTH, BUTTON_HEIGHT,
		SWP_NOZORDER);

	// move the "OK" button
	DeferWindowPos (hdwp,
		GetDlgItem (hwnd, IDOK), NULL,
		wXsize - HOR_LIST_OFFSET - BUTTON_SPACING - 2*BUTTON_WIDTH,
		wYsize - BOTTOM_BUTTON_OFFSET - BUTTON_HEIGHT,
		BUTTON_WIDTH, BUTTON_HEIGHT,
		SWP_NOZORDER);

	EndDeferWindowPos (hdwp);

	// reset column width
	GetClientRect (hwndList, &rc);
	ListView_SetColumnWidth (hwndList, 0, rc.right);
}


//	____________________________________
//
//	dialog proc of X509 certificate selection dialog

static BOOL CALLBACK
sX509SelectDlgProc (
		HWND	hwnd,
		UINT	uMsg,
		WPARAM	wParam,
		LPARAM	lParam)
{
	PX509SELECTSTRUCT	pxss;

	switch (uMsg) {
	case WM_INITDIALOG :
	{
		RECT	rc;

		SetWindowLong (hwnd, GWL_USERDATA, lParam);
		pxss = (PX509SELECTSTRUCT)GetWindowLong (hwnd, GWL_USERDATA);

		if (pxss->pszPrompt)
			SetDlgItemText (hwnd, IDC_SELECTPROMPT, pxss->pszPrompt);

		GetClientRect (hwnd, &rc);
		sSizeControls (hwnd, (WORD)rc.right, (WORD)rc.bottom);

		sInitCertList (hwnd, pxss);
		sLoadCertList (hwnd, pxss);

		if (pxss->hcursor)
			SetCursor (pxss->hcursor);

		return TRUE;
	}

	case WM_DESTROY :
		pxss = (PX509SELECTSTRUCT)GetWindowLong (hwnd, GWL_USERDATA);
		sDestroyCertList (hwnd, pxss);
		ListView_SetImageList (GetDlgItem (hwnd, IDC_X509CERTLIST),
				NULL, LVSIL_SMALL);
		break;

	case WM_SIZE :
		sSizeControls (hwnd, LOWORD(lParam), HIWORD(lParam));
		return 0;

	case WM_NOTIFY :
		if (wParam == IDC_X509CERTLIST)
		{
			NM_LISTVIEW* pnmlv = (NM_LISTVIEW*)lParam;

			switch (pnmlv->hdr.code) {

			case LVN_ITEMCHANGED :
				pxss = (PX509SELECTSTRUCT)GetWindowLong (hwnd, GWL_USERDATA);
				if (pnmlv->iItem >= 0)
				{
					if (pnmlv->uNewState & LVIS_SELECTED)
					{
						PX509CERT pcert;

						pcert = (PX509CERT)pnmlv->lParam;
						pxss->keySelected = pcert->key;
						pxss->sigSelected = pcert->sig;

						EnableWindow (GetDlgItem (hwnd, IDOK), TRUE);
					}
					else
					{
						pxss->keySelected = kInvalidPGPKeyDBObjRef;
						pxss->sigSelected = kInvalidPGPKeyDBObjRef;
						EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
					}
				}
				break;
			}
		}
		break;

	case WM_HELP :
	case WM_CONTEXTMENU :
		return PGPclHtmlHelp (hwnd, uMsg, wParam, lParam, 
				(char*)kPGPclHelpFile, aIds);

	case WM_COMMAND :
		pxss = (PX509SELECTSTRUCT)GetWindowLong (hwnd, GWL_USERDATA);

		switch (LOWORD (wParam)) {

		case IDOK :
			EndDialog (hwnd, 1);
			break;

		case IDCANCEL :
			EndDialog (hwnd, 0);
			break;
		}
		break;
	}

	return FALSE;
}


//	___________________________________________________
//
//  Display and handle selection of X509 keypair dialog

PGPError PGPclExport
PGPclSelectX509Cert (
		PGPContextRef		context,
		HWND				hwndParent,
		LPSTR				pszPrompt,
		PGPKeySetRef		keysetRoot,
		PGPUInt32			uFlags,
		PGPKeyDBObjRef*		psigCert)
{

	PGPKeySetRef	keysetX509		= kInvalidPGPKeySetRef;
	PGPKeyDBObjRef	keySelected		= kInvalidPGPKeyDBObjRef;
	PGPFilterRef	filter			= kInvalidPGPFilterRef;
	PGPFilterRef	filter2			= kInvalidPGPFilterRef;
	PGPError		err				= kPGPError_NoErr;
	HCURSOR			hcursorOld		= NULL;

	PGPUInt32		uNumKeys;

	hcursorOld = SetCursor (LoadCursor (NULL, IDC_WAIT));

	err = PGPNewKeyDBObjBooleanFilter (context,
			kPGPSigProperty_IsX509, TRUE, &filter); CKERR;

	if (uFlags & kPGPclSelectX509CanSignOnly)
	{
		err = PGPNewKeyDBObjBooleanFilter (context,
				kPGPKeyProperty_CanSign, TRUE, &filter2); CKERR;
		err = PGPIntersectFilters (filter, filter2, &filter); CKERR;
		filter2 = kInvalidPGPFilterRef;
	}

	if (uFlags & kPGPclSelectX509NoSplitKeys)
	{
		err = PGPNewKeyDBObjBooleanFilter (context,
				kPGPKeyProperty_IsSecretShared, FALSE, &filter2); CKERR;
		err = PGPIntersectFilters (filter, filter2, &filter); CKERR;
		filter2 = kInvalidPGPFilterRef;
	}

	err = PGPFilterKeySet (keysetRoot, filter, &keysetX509); CKERR;

	err = PGPCountKeys (keysetX509, &uNumKeys); CKERR;
	if (uNumKeys > 0)
	{
		X509SELECTSTRUCT	xss;

		xss.context			= context;
		xss.pszPrompt		= pszPrompt;
		xss.uFlags			= uFlags;
		xss.keyset			= keysetX509;
		xss.keydbMain		= PGPPeekKeySetKeyDB (keysetRoot);
		xss.keySelected		= kInvalidPGPKeyDBObjRef;
		xss.sigSelected		= kInvalidPGPKeyDBObjRef;
		xss.hcursor			= hcursorOld;
		
		hcursorOld = NULL;

		if (DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_SELECTX509CERT),
					hwndParent, sX509SelectDlgProc, (LPARAM)&xss))
		{
			err = kPGPError_NoErr;
		}
		else
			err = kPGPError_UserAbort;

		*psigCert = xss.sigSelected;
	}
	else
	{
		PGPclMessageBox (hwndParent, IDS_CAPTIONALERT, 
				IDS_NOX509CERTS, MB_OK|MB_ICONEXCLAMATION);
		err = kPGPError_UserAbort;
	}

done:
	if (PGPFilterRefIsValid (filter))
		PGPFreeFilter (filter);
	if (PGPFilterRefIsValid (filter2))
		PGPFreeFilter (filter2);
	if (PGPKeySetRefIsValid (keysetX509))
		PGPFreeKeySet (keysetX509);
	if (hcursorOld)
		SetCursor (hcursorOld);

	return err;
}

⌨️ 快捷键说明

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