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

📄 pksplit.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	PKSplit.c - code for splitting secret keys.

	$Id: PKSplit.c,v 1.26 2002/11/01 15:52:08 pbj Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"

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

// system header files
#include <shlobj.h>

// pgp header files
#include "pgpFileUtilities.h"
#include "pgpShareFile.h"

#include "pgpUnicodeWin32.h"
#include "UTF8Edit.h"
#include "keydrawitem.h"

// constant definitions
#define INITIAL_SHAREKEY_COLUMNWIDTH	250
#define MAX_TOTAL_SHARES				255
#define MAX_SHARES						99
#define MAX_SHARES_LEN					2
#define MAX_MODIFIERS					99

// typedefs
typedef struct {
	INT		iNumSteps;
} SPLITKEYPROGRESSSTRUCT;


// external globals
extern HINSTANCE		g_hinst;
extern HIMAGELIST		g_hilKeys;
extern PGPContextRef	g_context;
extern PGPtlsContextRef	g_tlscontext;

// local global
static PSPLITKEYSTRUCT psksList = NULL;

static DWORD aSplitIds[] = {			// Help IDs
	IDC_KEYTOSPLIT,			IDH_PGPPK_KEYTOSPLIT,
	IDC_SHAREHOLDERS,		IDH_PGPPK_SHAREHOLDERS,
	IDC_CURRENTSHAREHOLDER,	IDH_PGPPK_SELECTEDSHAREHOLDER,
	IDC_SHARES,				IDH_PGPPK_SELECTEDSHARES,
	IDC_REMOVESHAREHOLDER,	IDH_PGPPK_REMOVESHARES,
	IDC_ADDSHAREHOLDER,		IDH_PGPPK_ADDSHARES,
	IDC_TOTALSHARES,		IDH_PGPPK_TOTALSHARES,
	IDC_THRESHOLD,			IDH_PGPPK_SPLITTHRESHOLD,
	IDOK,					IDH_PGPPK_SPLIT,
    0,0
};

static DWORD aNewShareIds[] = {			// Help IDs
    IDC_NEWSHAREHOLDER,		IDH_PGPPK_NEWSHAREHOLDER,
    0,0
};

//	_______________________________________________
//
//  add shareholder to listview control

static BOOL
sAddShareHolder (
		PSPLITKEYSTRUCT		psks,
		PSHAREHOLDERSTRUCT	pshs,
		INT					iImage,
		HWND				hwndList)
{
	LV_ITEM		lvI;
	INT			iItem;
	CHAR		sz[16];

	// see if we're over the limit
	if ((psks->uTotalShares + pshs->uShares) > MAX_TOTAL_SHARES)
	{
		MessageBeep (MB_ICONASTERISK);
		return FALSE;
	}

	// figure item index to use
	iItem = ListView_GetItemCount (hwndList);

	// insert listview item
	lvI.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE|LVIF_PARAM;
	lvI.state = 0;
	lvI.stateMask = 0;
	lvI.iImage = iImage;

	lvI.iItem = iItem;
	lvI.iSubItem = 0;
	lvI.pszText	= pshs->szUserID;
	lvI.cchTextMax = 0;
	lvI.lParam = (LPARAM)pshs;

	iItem = ListView_InsertItem (hwndList, &lvI);
	if (iItem == -1)
		return FALSE;
	else
	{
		// add strings for Shares column
		wsprintf (sz, "%i", pshs->uShares);
		ListView_SetItemText (hwndList, iItem, 1, sz);
		return TRUE;
	}
}


//	_______________________________________________
//
//  destroy shareholder data structures from listview control

static BOOL
sIsKeyIDAlreadyInList (
		PGPKeyID*				pkeyid,
		PSPLITKEYSTRUCT			psks)
{
	INT					iNumItems;
	INT					iIndex;
	LV_ITEM				lvI;
	PSHAREHOLDERSTRUCT	pshs;

	iNumItems = ListView_GetItemCount (psks->hwndList);
	for (iIndex=0; iIndex<iNumItems; iIndex++)
	{
		lvI.mask = LVIF_PARAM;
		lvI.iItem = iIndex;
		lvI.iSubItem = 0;
		ListView_GetItem (psks->hwndList, &lvI);

		pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
		if (pshs->bPublicKey)
		{
			if (PGPCompareKeyIDs (&pshs->keyid, pkeyid) == 0)
				return TRUE;
		}
	}

	return FALSE;
}


//	_______________________________________________
//
//  Drop text key(s)

BOOL
PKSplitDropKeys (
		PSPLITKEYSTRUCT psks,
		HANDLE	hMem)
{
	PGPKeyDBRef				keydb		= kInvalidPGPKeyDBRef;
	PGPKeyIterRef			keyiter		= kInvalidPGPKeyIterRef;
	LPSTR					pMem		= NULL;

	PGPError				err;
	PGPKeyDBObjRef			key;
	PGPKeyID				keyid;
	BOOL					bKeys;
	PGPBoolean				bKeyIsUsable;
	size_t					sLen;
	PSHAREHOLDERSTRUCT		pshs;

	bKeys = FALSE;

	if (hMem)
	{
		pMem = GlobalLock (hMem);
		if (pMem)
		{
			sLen = lstrlen (pMem);
			err = PGPImport (g_context, &keydb,
					PGPOInputBuffer (g_context, pMem, sLen),
					PGPOLastOption (g_context));
			if (IsPGPError (err))
				goto SplitDropCleanup;

			err = PGPNewKeyIterFromKeyDB (keydb, &keyiter);
			if (IsPGPError (err))
				goto SplitDropCleanup;

			PGPKeyIterNextKeyDBObj (keyiter, kPGPKeyDBObjType_Key, &key);

			while (key)
			{
				bKeyIsUsable = FALSE;

				// key must either not be RSA or RSA ops must be enabled
				PGPGetKeyDBObjBooleanProperty (key, 
						kPGPKeyProperty_CanEncrypt, &bKeyIsUsable);

				// key must not be the same one that is being split
				PGPGetKeyID (key, &keyid);
				if (PGPCompareKeyIDs (&keyid, &(psks->keyidToSplit)) == 0)
					bKeyIsUsable = FALSE;

				// key must not already be in list
				if (sIsKeyIDAlreadyInList (&keyid, psks))
					bKeyIsUsable = FALSE;

				if (bKeyIsUsable)
				{
					bKeys = TRUE;
					pshs = pkAlloc (sizeof(SHAREHOLDERSTRUCT));
					if (pshs)
					{
						PGPSize			size;
						PGPKeyDBObjRef	userid;

						pshs->bPublicKey = TRUE;
						pshs->pszPassphrase = NULL;
						pshs->uShares = 1;

						PGPclGetPrimaryUserIDNameUTF8 (key,
							pshs->szUserID, sizeof(pshs->szUserID), &size);
						PGPGetKeyID (key, &(pshs->keyid));

						PGPGetPrimaryUserID (key, &userid);

						if (sAddShareHolder (psks, pshs,
								PGPclDetermineUserIDIcon (userid, NULL),
								psks->hwndList))
						{
							psks->uTotalShares += pshs->uShares;
							SetDlgItemInt (psks->hwndDlg, IDC_TOTALSHARES,
									psks->uTotalShares, FALSE);
							SendMessage (psks->hwndDlg, WM_COMMAND,
									MAKEWPARAM(IDC_THRESHOLD, EN_CHANGE), 0);
						}
						else
							pkFree (pshs);
					}
				}

				PGPKeyIterNextKeyDBObj (keyiter, kPGPKeyDBObjType_Key, &key);
			}

SplitDropCleanup :
			if (keyiter)
				PGPFreeKeyIter (keyiter);
			if (keydb)
				PGPFreeKeyDB (keydb);
			if (pMem)
				GlobalUnlock (hMem);
		}
	}

	return bKeys;
}


//	_______________________________________________
//
//  Initialize ListView

static VOID
sInitKeyList (PSPLITKEYSTRUCT psks)
{

	LV_COLUMN	lvC;
	CHAR		sz[256];

	ListView_SetImageList (psks->hwndList, g_hilKeys, LVSIL_SMALL);

	lvC.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
	lvC.fmt = LVCFMT_LEFT;
	lvC.pszText = sz;

	LoadString (g_hinst, IDS_USERID, sz, sizeof(sz));
	lvC.cx = INITIAL_SHAREKEY_COLUMNWIDTH;
	lvC.iSubItem = 0;
	if (ListView_InsertColumn (psks->hwndList, 0, &lvC) == -1) return;

	LoadString (g_hinst, IDS_SHARES, sz, sizeof(sz));
	lvC.cx = 50;
	lvC.iSubItem = 1;
	if (ListView_InsertColumn (psks->hwndList, 1, &lvC) == -1) return;
}

//	_______________________________________________
//
//  remove shareholder from listview control

static VOID
sRemoveShareHolderFromList (HWND hwnd, PSPLITKEYSTRUCT psks)
{
	INT					iIndex;
	LV_ITEM				lvI;
	PSHAREHOLDERSTRUCT	pshs;

	iIndex = ListView_GetNextItem (psks->hwndList, -1, LVNI_SELECTED);

	if (iIndex > -1)
	{
		lvI.mask = LVIF_PARAM;
		lvI.iItem = iIndex;
		lvI.iSubItem = 0;
		ListView_GetItem (psks->hwndList, &lvI);

		// update total shares
		pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
		psks->uTotalShares -= pshs->uShares;
		SetDlgItemInt (hwnd, IDC_TOTALSHARES, psks->uTotalShares, FALSE);
		SendMessage (hwnd, WM_COMMAND,
				MAKEWPARAM (IDC_THRESHOLD, EN_CHANGE), 0);

		PGPclFreePhrase (pshs->pszPassphrase);
		pkFree (pshs);

		ListView_DeleteItem (psks->hwndList, iIndex);
	}
}


//	_______________________________________________
//
// add share holder dialog message procedure

static BOOL CALLBACK
sAddShareHolderDlgProc (HWND hwnd,
					   UINT uMsg,
					   WPARAM wParam,
					   LPARAM lParam)
{
	PSPLITKEYSTRUCT		psks;
	PSHAREHOLDERSTRUCT	pshs;

	switch (uMsg) {

	case WM_INITDIALOG :
		// save address of struct
		SetWindowLong (hwnd, GWL_USERDATA, lParam);
		UTF8EditInit (GetDlgItem (hwnd, IDC_NEWSHAREHOLDER));
		return TRUE;

	case WM_DESTROY :
		UTF8EditDestroy (GetDlgItem (hwnd, IDC_NEWSHAREHOLDER));
		return FALSE;

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

	case WM_COMMAND :
		switch (LOWORD(wParam)) {

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

		case IDOK :
			psks = (PSPLITKEYSTRUCT)GetWindowLong (hwnd, GWL_USERDATA);
			pshs = pkAlloc (sizeof(SHAREHOLDERSTRUCT));
			if (pshs)
			{
				CHAR		szPrompt[64];
				PGPError	err;

				pshs->bPublicKey = FALSE;
				pshs->pszPassphrase = NULL;
				pshs->uShares = 1;

				UTF8EditGetText (GetDlgItem (hwnd, IDC_NEWSHAREHOLDER), 
						pshs->szUserID, sizeof(pshs->szUserID));

				LoadString (g_hinst, IDS_SHAREPHRASEPROMPT,
						szPrompt, sizeof (szPrompt));
				err = PGPclGetConfirmationPhrase (g_context, hwnd,
						szPrompt, psks->ppks->keydbMain,
						1, 0, &(pshs->pszPassphrase));

				if (IsntPGPError (err))
				{
					if (sAddShareHolder (
							psks, pshs, IDX_HEAD, psks->hwndList))
					{
						psks->uTotalShares += pshs->uShares;
						EndDialog (hwnd, 1);
					}
					else
					{
						PGPclFreePhrase (pshs->pszPassphrase);
						pkFree (pshs);
						EndDialog (hwnd, 0);
					}
				}
			}
			else
				EndDialog (hwnd, 0);
			break;

		default :
			if (HIWORD(wParam) == EN_UPDATE)
			{
				EnableWindow (GetDlgItem (hwnd, IDOK), 
						(UTF8EditGetTextLength (GetDlgItem (
							hwnd, IDC_NEWSHAREHOLDER)) > 0));
			}
			break;
		}
		return TRUE;
	}
	return FALSE;
}


//	_______________________________________________
//
//  pop dialog for adding conventional encryption shareholder

static VOID
sAddShareHolderToList (HWND hwnd, PSPLITKEYSTRUCT psks)
{
	if (DialogBoxParam (g_hinst, MAKEINTRESOURCE (IDD_ADDSHAREHOLDER),
		hwnd, sAddShareHolderDlgProc, (LPARAM)psks))
	{
		SetDlgItemInt (hwnd, IDC_TOTALSHARES, psks->uTotalShares, FALSE);
		SendMessage (hwnd, WM_COMMAND,
				MAKEWPARAM (IDC_THRESHOLD, EN_CHANGE), 0);
	}
}


//	_______________________________________________
//
//  destroy shareholder data structures from listview control

static VOID
sDestroyShareHolders (PSPLITKEYSTRUCT psks)
{
	INT					iNumItems;
	INT					iIndex;
	LV_ITEM				lvI;
	PSHAREHOLDERSTRUCT	pshs;

	iNumItems = ListView_GetItemCount (psks->hwndList);
	for (iIndex=0; iIndex<iNumItems; iIndex++)
	{
		lvI.mask = LVIF_PARAM;
		lvI.iItem = iIndex;
		lvI.iSubItem = 0;
		ListView_GetItem (psks->hwndList, &lvI);

		pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
		PGPclFreePhrase (pshs->pszPassphrase);

		pkFree (pshs);
	}
}


//	_______________________________________________
//
//  destroy dialog struct and remove from list

static VOID
sDestroySplitKeyStruct (PSPLITKEYSTRUCT psksToDestroy)
{
	PSPLITKEYSTRUCT* ppsks;

	ppsks = psksToDestroy->pHeadOfList;

	while (*ppsks)
	{
		if (*ppsks == psksToDestroy)
		{
			*ppsks = psksToDestroy->next;
			pkFree (psksToDestroy);
			return;
		}
		ppsks = &((*ppsks)->next);
	}
}


//	_______________________________________________
//

⌨️ 快捷键说明

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