📄 clrecon.c
字号:
/*____________________________________________________________________________
Copyright (C) 1998 Network Associates, Inc.
All rights reserved.
CLrecon.c - reconstitute key shares routines
$Id: CLrecon.c,v 1.40 1999/01/08 23:33:05 pbj Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h" /* or pgpConfig.h in the CDK */
// project header files
#include "pgpclx.h"
#include "pgpkmx.h"
// pgp header files
#include "PGPskep.h"
#include "pgpShareFile.h"
// system header files
#include <commdlg.h>
// external globals
extern HINSTANCE g_hInst;
extern CHAR g_szHelpFile[MAX_PATH];
// constant definitions
#define INITIAL_SHAREKEY_COLUMNWIDTH 250
#define UNKNOWN_SHARES_NEEDED 999999
// typedefs
typedef struct {
PGPContextRef context;
PGPtlsContextRef tlsContext;
HWND hwndDlg;
HWND hwndList;
HIMAGELIST hIml;
PGPKeySetRef keyset;
PGPKeyRef keyToReconstitute;
PGPKeyID keyidToReconstitute;
PGPKeyRef keyAuthenticating;
PGPKeySetRef keysetDecryption;
PGPUInt32 iKeyIDCount;
PGPKeyID* keyidsDecryption;
PGPKeySetRef keysetToAdd;
CHAR szAuthUserID[kPGPMaxUserIDSize+1];
LPSTR pszPhraseAuth;
PGPByte* pPasskeyAuth;
PGPSize sizePasskeyAuth;
UINT uNeededShares;
UINT uCollectedShares;
PGPShareRef sharesCombined;
PGPskepRef skep;
INT iIconIndex;
BOOL bServerMode;
BOOL bStop;
BOOL bUserCancel;
BOOL bUserOK;
BOOL bBadPassphrase;
CRITICAL_SECTION critsecAddShare;
} RECONKEYSTRUCT, *PRECONKEYSTRUCT;
// help IDs
static DWORD aIds[] = {
IDC_NETWORK, IDH_PGPCLRECON_STARTNETWORK, // must be first ID
IDC_KEYTORECON, IDH_PGPCLRECON_KEYTORECON,
IDC_SHAREHOLDERS, IDH_PGPCLRECON_SHAREHOLDERLIST,
IDC_SHARESCOLLECTED,IDH_PGPCLRECON_SHARESCOLLECTED,
IDC_SHARESNEEDED, IDH_PGPCLRECON_SHARESNEEDED,
IDC_STATUS, IDH_PGPCLRECON_NETWORKSTATUS,
IDC_AUTHENTICATION, IDH_PGPCLRECON_NETWORKAUTHENTICATION,
IDC_SHAREFILE, IDH_PGPCLRECON_SELECTSHAREFILE,
0,0
};
// ______________________________________________
//
// Initialize ListView
static VOID
sInitKeyList (PRECONKEYSTRUCT prks)
{
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) {
prks->hIml = ImageList_Create (16, 16, ILC_COLOR|ILC_MASK,
NUM_BITMAPS, 0);
hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES4BIT));
ImageList_AddMasked (prks->hIml, hBmp, RGB(255, 0, 255));
DeleteObject (hBmp);
}
else {
prks->hIml = ImageList_Create (16, 16, ILC_COLOR24|ILC_MASK,
NUM_BITMAPS, 0);
hBmp = LoadBitmap (g_hInst, MAKEINTRESOURCE (IDB_IMAGES24BIT));
ImageList_AddMasked (prks->hIml, hBmp, RGB(255, 0, 255));
DeleteObject (hBmp);
}
ListView_SetImageList (prks->hwndList, prks->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 (prks->hwndList, 0, &lvC) == -1) return;
LoadString (g_hInst, IDS_SHARES, sz, sizeof(sz));
lvC.cx = 50;
lvC.iSubItem = 1;
if (ListView_InsertColumn (prks->hwndList, 1, &lvC) == -1) return;
}
// ______________________________________________
//
// decode event handler
static PGPError
sHandlerDecode (
PGPContextRef context,
PGPEvent* event,
PGPUserValue userValue)
{
PGPError err = kPGPError_NoErr;
PRECONKEYSTRUCT prks;
switch (event->type) {
case kPGPEvent_PassphraseEvent:
{
LPSTR psz = NULL;
PGPByte* pbyte = NULL;
PGPSize size;
UINT uLen;
CHAR szPrompt[64];
prks = (PRECONKEYSTRUCT)userValue;
if (!prks->bBadPassphrase)
LoadString (g_hInst, IDS_DECRYPTSHARESPROMPT,
szPrompt, sizeof(szPrompt));
else
LoadString (g_hInst, IDS_BADSHAREFILEPASSPHRASE,
szPrompt, sizeof(szPrompt));
if (event->data.passphraseData.fConventional) {
err = KMGetKeyPhrase (context, prks->tlsContext,
prks->hwndDlg, szPrompt, prks->keyset,
NULL, &psz, &pbyte, &size);
prks->iIconIndex = IDX_HEAD;
}
else {
err = KMGetDecryptionPhrase (context, prks->tlsContext,
prks->hwndDlg, szPrompt, prks->keyset,
NULL, prks->keysetDecryption,
prks->iKeyIDCount, prks->keyidsDecryption,
&prks->keysetToAdd, &psz, &pbyte, &size);
prks->iIconIndex = IDX_DSAUSERID;
}
if (IsntPGPError (err)) {
if (psz) {
uLen = lstrlen (psz);
PGPAddJobOptions (event->job,
PGPOPassphraseBuffer (context, psz, uLen),
PGPOLastOption (context));
}
else {
PGPAddJobOptions (event->job,
PGPOPasskeyBuffer (context, pbyte, size),
PGPOLastOption (context));
}
}
if (psz)
KMFreePhrase (psz);
if (pbyte)
KMFreePasskey (pbyte, size);
// If passphrase event comes up again, the passphrase
// must have been bad
prks->bBadPassphrase = TRUE;
}
break;
case kPGPEvent_RecipientsEvent:
{
PGPUInt32 i;
PGPEventRecipientsData *pData = &event->data.recipientsData;
prks = (PRECONKEYSTRUCT)userValue;
// Save recipient key set for passphrase dialog
prks->keysetDecryption = pData->recipientSet;
PGPIncKeySetRefCount (prks->keysetDecryption);
// Save unknown keyids
if (pData->keyCount > 0) {
prks->iKeyIDCount = pData->keyCount;
prks->keyidsDecryption =
(PGPKeyID *)clAlloc (pData->keyCount * sizeof(PGPKeyID));
for (i=0; i<pData->keyCount; i++) {
prks->keyidsDecryption[i] = pData->keyIDArray[i];
}
}
}
break;
}
return err;
}
// ______________________________________________
//
// add shareholder to listview control
static BOOL
sAddShareHolderToList (
PRECONKEYSTRUCT prks,
LPSTR pszName,
UINT uShares)
{
LV_ITEM lvI;
INT iItem;
CHAR sz[16];
// figure item index to use
iItem = ListView_GetItemCount (prks->hwndList);
// insert listview item
lvI.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE;
lvI.state = 0;
lvI.stateMask = 0;
lvI.iImage = prks->iIconIndex;
lvI.iItem = iItem;
lvI.iSubItem = 0;
lvI.pszText = pszName;
lvI.cchTextMax = 0;
iItem = ListView_InsertItem (prks->hwndList, &lvI);
if (iItem == -1) {
return FALSE;
}
else {
// add strings for Shares column
wsprintf (sz, "%i", uShares);
ListView_SetItemText (prks->hwndList, iItem, 1, sz);
return TRUE;
}
}
// ______________________________________________
//
// add share file to list
static VOID
sAddShareFile (
HWND hwnd,
PRECONKEYSTRUCT prks)
{
PFLFileSpecRef fileref = NULL;
PGPShareFileRef sharefileref = NULL;
PGPOptionListRef optionsDecode = NULL;
PGPShareRef shares = NULL;
PGPShareRef sharesTemp = NULL;
PGPError err = kPGPError_NoErr;
OPENFILENAME ofn;
LPSTR p;
CHAR szFile[MAX_PATH];
CHAR szName[kPGPMaxUserIDSize+1];
CHAR sz[256];
CHAR szTitle[64];
PGPUInt32 size;
PGPUInt32 uNumShares;
UINT uThreshold;
PGPKeyID keyid;
// initialize
prks->keysetToAdd = kInvalidPGPKeySetRef;
prks->keysetDecryption = kInvalidPGPKeySetRef;
prks->iKeyIDCount = 0;
prks->keyidsDecryption = NULL;
// prompt user for name of share file to send
szFile[0] = '\0';
LoadString (g_hInst, IDS_SHAREFILEFILTER, sz, sizeof(sz));
while (p = strrchr (sz, '@')) *p = '\0';
LoadString (g_hInst, IDS_SHAREFILECAPTION, szTitle, sizeof(szTitle));
ofn.lStructSize = sizeof (OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.hInstance = (HANDLE)g_hInst;
ofn.lpstrFilter = sz;
ofn.lpstrCustomFilter = (LPTSTR)NULL;
ofn.nMaxCustFilter = 0L;
ofn.nFilterIndex = 1L;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof (szFile);
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = szTitle;
ofn.Flags = OFN_HIDEREADONLY;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = "";
ofn.lCustData = 0;
EnterCriticalSection (&prks->critsecAddShare);
if (GetOpenFileName (&ofn)) {
err = PFLNewFileSpecFromFullPath (
PGPGetContextMemoryMgr (prks->context), szFile, &fileref);
if (IsPGPError (err)) goto AddCleanup;
err = PGPOpenShareFile (fileref, &sharefileref);
if (IsPGPError (err)) goto AddCleanup;
err = PGPGetShareFileSharedKeyID (sharefileref, &keyid);
if (IsPGPError (err)) goto AddCleanup;
if (PGPCompareKeyIDs (&keyid, &(prks->keyidToReconstitute))) {
PGPclMessageBox (prks->hwndDlg, IDS_CAPTION,
IDS_SHAREKEYMISMATCH, MB_OK|MB_ICONEXCLAMATION);
goto AddCleanup;
}
// check that threshold corresponds to other share files
uThreshold = PGPGetShareThresholdInFile (sharefileref);
if (prks->uNeededShares != UNKNOWN_SHARES_NEEDED) {
if (uThreshold != prks->uNeededShares) {
PGPclMessageBox (prks->hwndDlg, IDS_CAPTION,
IDS_SHARENUMMISMATCH, MB_OK|MB_ICONEXCLAMATION);
goto AddCleanup;
}
}
err = PGPGetShareFileUserID (sharefileref,
sizeof(szName), szName, &size);
if (IsPGPError (err)) goto AddCleanup;
uNumShares = PGPGetNumSharesInFile (sharefileref);
// decrypt specified share file
prks->bBadPassphrase = FALSE;
PGPBuildOptionList (prks->context, &optionsDecode,
PGPOKeySetRef (prks->context, prks->keyset),
PGPOEventHandler (prks->context, sHandlerDecode, prks),
PGPOLastOption (prks->context));
err = PGPCopySharesFromFile (prks->context, sharefileref,
optionsDecode, &shares);
if (IsPGPError (err)) goto AddCleanup;
// add shares to collection
if (prks->sharesCombined) {
err = PGPCombineShares (shares,
prks->sharesCombined, &sharesTemp);
if (IsPGPError (err))
goto AddCleanup;
PGPFreeShares (prks->sharesCombined);
prks->sharesCombined = sharesTemp;
}
else {
prks->sharesCombined = shares;
shares = NULL;
}
// share is OK, add it to list
prks->uNeededShares = uThreshold;
SetDlgItemInt (prks->hwndDlg, IDC_SHARESNEEDED,
prks->uNeededShares, FALSE);
prks->uCollectedShares += uNumShares;
SetDlgItemInt (hwnd, IDC_SHARESCOLLECTED,
prks->uCollectedShares, FALSE);
sAddShareHolderToList (prks, szName, uNumShares);
}
AddCleanup :
LeaveCriticalSection (&prks->critsecAddShare);
if (shares)
PGPFreeShares (shares);
if (sharefileref)
PGPFreeShareFile (sharefileref);
if (fileref)
PFLFreeFileSpec (fileref);
if (optionsDecode)
PGPFreeOptionList(optionsDecode);
if (PGPKeySetRefIsValid (prks->keysetDecryption))
PGPFreeKeySet (prks->keysetDecryption);
if (prks->keyidsDecryption)
clFree (prks->keyidsDecryption);
switch (err) {
case kPGPClientError_IdenticalShares :
PGPclMessageBox (hwnd, IDS_CAPTION, IDS_DUPLICATESHARES,
MB_OK|MB_ICONEXCLAMATION);
break;
case kPGPClientError_DifferentSharePool :
PGPclMessageBox (hwnd, IDS_CAPTION, IDS_SHARENUMMISMATCH,
MB_OK|MB_ICONEXCLAMATION);
break;
case kPGPClientError_DifferentSplitKeys :
PGPclMessageBox (hwnd, IDS_CAPTION, IDS_SHAREKEYMISMATCH,
MB_OK|MB_ICONEXCLAMATION);
break;
default:
PGPclErrorBox (hwnd, err);
}
if (PGPKeySetRefIsValid (prks->keysetToAdd)) {
if (IsntPGPError (err)) {
PGPclQueryAddKeys (prks->context, prks->tlsContext, hwnd,
prks->keysetToAdd, prks->keyset);
}
PGPFreeKeySet (prks->keysetToAdd);
}
}
// ______________________________________________
//
// SKEP event handler
static PGPError
sHandlerSKEP (
PGPskepRef skep,
PGPskepEvent* event,
PGPUserValue userValue)
{
BOOL bCancel = FALSE;
PRECONKEYSTRUCT prks;
UINT uID;
UINT u;
CHAR sz[64];
LPSTR psz;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -