📄 pksplit.c
字号:
/*____________________________________________________________________________
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 + -