📄 kmshare.c
字号:
/*____________________________________________________________________________
Copyright (C) 1998 Network Associates, Inc.
All rights reserved.
KMShare.c - code for splitting secret keys.
$Id: KMShare.c,v 1.48 1998/10/21 20:49:07 pbj Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"
// project header files
#include "pgpkmx.h"
// system header files
#include "shlobj.h"
// pgp header files
#include "pgpFileUtilities.h"
#include "pgpShareFile.h"
// constant definitions
#define INITIAL_SHAREKEY_COLUMNWIDTH 250
#define MAX_TOTAL_SHARES 255
#define MAX_SHARES 99
#define MAX_SHARES_LEN 2
// typedefs
typedef struct {
INT iNumSteps;
} SPLITKEYPROGRESSSTRUCT;
// external globals
extern HINSTANCE g_hInst;
extern CHAR g_szHelpFile[MAX_PATH];
// local global
static PSPLITKEYSTRUCT psksList = NULL;
static DWORD aSplitIds[] = { // Help IDs
IDC_KEYTOSPLIT, IDH_PGPCLSPLIT_KEYTOSPLIT,
IDC_SHAREHOLDERS, IDH_PGPCLSPLIT_SHAREHOLDERS,
IDC_CURRENTSHAREHOLDER, IDH_PGPCLSPLIT_SELECTEDSHAREHOLDER,
IDC_SHARES, IDH_PGPCLSPLIT_SELECTEDSHARES,
IDC_REMOVESHAREHOLDER, IDH_PGPCLSPLIT_REMOVESHARES,
IDC_ADDSHAREHOLDER, IDH_PGPCLSPLIT_ADDSHARES,
IDC_TOTALSHARES, IDH_PGPCLSPLIT_TOTALSHARES,
IDC_THRESHOLD, IDH_PGPCLSPLIT_THRESHOLD,
IDOK, IDH_PGPCLSPLIT_SPLIT,
0,0
};
static DWORD aNewShareIds[] = { // Help IDs
IDC_NEWSHAREHOLDER, IDH_PGPCLSPLIT_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,
PGPPublicKeyAlgorithm keyalg,
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->keyalg == keyalg) {
if (PGPCompareKeyIDs (&pshs->keyid, pkeyid) == 0) {
return TRUE;
}
}
}
return FALSE;
}
// _______________________________________________
//
// Drop text key(s)
BOOL
KMSplitDropKeys (
PSPLITKEYSTRUCT psks,
HANDLE hMem)
{
PGPKeySetRef keyset = NULL;
PGPKeyListRef keylist = NULL;
PGPKeyIterRef keyiter = NULL;
LPSTR pMem = NULL;
PGPError err;
PGPKeyRef key;
PGPKeyID keyid;
BOOL bKeys;
PGPBoolean bKeyIsUsable;
size_t sLen;
PSHAREHOLDERSTRUCT pshs;
PGPPublicKeyAlgorithm alg;
bKeys = FALSE;
if (hMem) {
pMem = GlobalLock (hMem);
if (pMem) {
sLen = lstrlen (pMem);
err = PGPImportKeySet (psks->pKM->Context, &keyset,
PGPOInputBuffer (psks->pKM->Context, pMem, sLen),
PGPOLastOption (psks->pKM->Context));
if (IsPGPError (err)) goto SplitDropCleanup;
err = PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
if (IsPGPError (err)) goto SplitDropCleanup;
err = PGPNewKeyIter (keylist, &keyiter);
if (IsPGPError (err)) goto SplitDropCleanup;
PGPKeyIterNext (keyiter, &key);
while (key) {
bKeyIsUsable = FALSE;
PGPGetKeyNumber (key, kPGPKeyPropAlgID, &alg);
PGPGetKeyIDFromKey (key, &keyid);
// key must either not be RSA or RSA ops must be enabled
PGPGetKeyBoolean (key, kPGPKeyPropCanEncrypt, &bKeyIsUsable);
// key must not be the same one that is being split
if (alg == psks->keyalgToSplit) {
if (PGPCompareKeyIDs (&keyid, &(psks->keyidToSplit))==0)
bKeyIsUsable = FALSE;
}
// key must not already be in list
if (sIsKeyIDAlreadyInList (&keyid, alg, psks))
bKeyIsUsable = FALSE;
if (bKeyIsUsable) {
bKeys = TRUE;
pshs = KMAlloc (sizeof(SHAREHOLDERSTRUCT));
if (pshs) {
PGPSize size;
pshs->bPublicKey = TRUE;
pshs->pszPassphrase = NULL;
pshs->uShares = 1;
PGPGetPrimaryUserIDNameBuffer (key,
sizeof(pshs->szUserID), pshs->szUserID, &size);
PGPGetKeyIDFromKey (key, &(pshs->keyid));
PGPGetKeyNumber (key,
kPGPKeyPropAlgID, &(pshs->keyalg));
if (sAddShareHolder (psks, pshs,
KMDetermineUserIDIcon (key, NULL, 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 {
KMFree (pshs);
}
}
}
PGPKeyIterNext (keyiter, &key);
}
SplitDropCleanup :
if (keyiter)
PGPFreeKeyIter (keyiter);
if (keylist)
PGPFreeKeyList (keylist);
if (keyset)
PGPFreeKeySet (keyset);
if (pMem)
GlobalUnlock (hMem);
}
}
return bKeys;
}
// _______________________________________________
//
// Initialize ListView
static VOID
sInitKeyList (PSPLITKEYSTRUCT psks)
{
LV_COLUMN lvC;
CHAR sz[256];
HBITMAP hBmp;
HDC hDC;
INT iNumBits;
// create image list
hDC = GetDC (NULL); // DC for desktop
iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES);
ReleaseDC (NULL, hDC);
if (iNumBits <= 8) {
psks->hIml = ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,
NUM_BITMAPS, 0);
hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
ImageList_AddMasked (psks->hIml, hBmp, RGB(255, 0, 255));
DeleteObject (hBmp);
}
else {
psks->hIml = ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,
NUM_BITMAPS, 0);
hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
ImageList_AddMasked (psks->hIml, hBmp, RGB(255, 0, 255));
DeleteObject (hBmp);
}
ListView_SetImageList (psks->hwndList, psks->hIml, 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 hDlg, 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 (hDlg, IDC_TOTALSHARES, psks->uTotalShares, FALSE);
SendMessage (hDlg, WM_COMMAND,
MAKEWPARAM (IDC_THRESHOLD, EN_CHANGE), 0);
KMFreePhrase (pshs->pszPassphrase);
KMFree (pshs);
ListView_DeleteItem (psks->hwndList, iIndex);
}
}
// _______________________________________________
//
// add share holder dialog message procedure
static BOOL CALLBACK
sAddShareHolderDlgProc (HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PSPLITKEYSTRUCT psks;
PSHAREHOLDERSTRUCT pshs;
switch (uMsg) {
case WM_INITDIALOG :
// save address of struct
SetWindowLong (hDlg, GWL_USERDATA, lParam);
return TRUE;
case WM_HELP:
WinHelp (((LPHELPINFO) lParam)->hItemHandle, g_szHelpFile,
HELP_WM_HELP, (DWORD) (LPSTR) aNewShareIds);
break;
case WM_CONTEXTMENU:
WinHelp ((HWND) wParam, g_szHelpFile, HELP_CONTEXTMENU,
(DWORD) (LPVOID) aNewShareIds);
break;
case WM_COMMAND :
switch (LOWORD(wParam)) {
case IDCANCEL :
EndDialog (hDlg, 0);
break;
case IDOK :
psks = (PSPLITKEYSTRUCT)GetWindowLong (hDlg, GWL_USERDATA);
pshs = KMAlloc (sizeof(SHAREHOLDERSTRUCT));
if (pshs) {
CHAR szPrompt[64];
PGPError err;
pshs->bPublicKey = FALSE;
pshs->keyalg = 0;
pshs->pszPassphrase = NULL;
pshs->uShares = 1;
GetDlgItemText (hDlg, IDC_NEWSHAREHOLDER,
pshs->szUserID, sizeof(pshs->szUserID));
LoadString (g_hInst, IDS_SHAREPHRASEPROMPT,
szPrompt, sizeof (szPrompt));
err = KMGetConfirmationPhrase (psks->pKM->Context, hDlg,
szPrompt, psks->pKM->KeySetMain,
1, 0, &(pshs->pszPassphrase));
// wjb changed min length to 1 for passphrase
if (IsntPGPError (err)) {
if (sAddShareHolder (
psks, pshs, IDX_HEAD, psks->hwndList)) {
psks->uTotalShares += pshs->uShares;
EndDialog (hDlg, 1);
}
else {
KMFreePhrase (pshs->pszPassphrase);
KMFree (pshs);
EndDialog (hDlg, 0);
}
}
}
else
EndDialog (hDlg, 0);
break;
}
return TRUE;
}
return FALSE;
}
// _______________________________________________
//
// pop dialog for adding conventional encryption shareholder
static VOID
sAddShareHolderToList (HWND hDlg, PSPLITKEYSTRUCT psks)
{
if (DialogBoxParam (g_hInst, MAKEINTRESOURCE (IDD_ADDSHAREHOLDER),
hDlg, sAddShareHolderDlgProc, (LPARAM)psks)) {
SetDlgItemInt (hDlg, IDC_TOTALSHARES, psks->uTotalShares, FALSE);
SendMessage (hDlg, 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -