示例#1
0
VOID CALLBACK UpdateTimerProc(HWND hwnd, 
							  UINT uMsg, 
							  UINT idEvent, 
							  DWORD dwTime)
{
	PGPMemoryMgrRef memoryMgr;
	PGPBoolean		bUpdateAllKeys;
	PGPBoolean		bUpdateTrustedIntroducers;
	PGPBoolean		bUpdateCRLs;
	PGPError		err = kPGPError_NoErr;

	if (idEvent != LAUNCHKEYS_TIMER)
		return;

	err = PGPNewMemoryMgr(0, &memoryMgr);
	if (IsPGPError(err))
	{
		PGPclErrorBox(hwnd, err);
		return;
	}

	err = PGPclCheckAutoUpdate(memoryMgr, FALSE, 
			&bUpdateAllKeys, &bUpdateTrustedIntroducers, &bUpdateCRLs);
	if (IsPGPError(err))
	{
		PGPclErrorBox(hwnd, err);
		return;
	}

	if (bUpdateAllKeys || bUpdateTrustedIntroducers || bUpdateCRLs)
		DoLaunchKeys(hwnd);

	PGPFreeMemoryMgr(memoryMgr);
	return;
}
示例#2
0
BOOL 
KMDisableOnServer (PKEYMAN pKM) 
{
	PGPKeySetRef			keysetDisable	= kInvalidPGPKeySetRef;
	PGPError				err				= kPGPError_BadParams;
	PGPKeyServerKeySpace	space;

	if (pKM->ulOptionFlags & KMF_PENDINGBUCKET)
		space = kPGPKeyServerKeySpace_Normal;
	else
		space = kPGPKeyServerKeySpace_Default;

	KMGetSelectedKeys (pKM, &keysetDisable, NULL);
	if (PGPRefIsValid (keysetDisable)) {
		err = PGPclDisableKeysOnServer (pKM->Context, pKM->tlsContext,
					pKM->hWndParent, &pKM->keyserver, 
					space, pKM->KeySetMain, keysetDisable);
		PGPFreeKeySet (keysetDisable);
	}

	if (IsPGPError (err)) PGPclErrorBox (NULL, err);
	else {
		KMMessageBox (pKM->hWndParent, IDS_PGP, IDS_DISABLEONSERVEROK,
								MB_OK|MB_ICONINFORMATION);
	}

	return TRUE;
}
示例#3
0
BOOL 
KMAddCertificate (PKEYMAN pKM) 
{
	PGPKeySetRef	keysetKey		= kInvalidPGPKeySetRef;
	PGPKeyRef		key				= kInvalidPGPKeyRef;
	PGPUserIDRef	userid			= kInvalidPGPUserIDRef;
	PGPError		err;

	if (KMSelectedFlags (pKM) == OBJECT_USERID)
	{
		userid = (PGPUserIDRef)KMFocusedObject (pKM);
		key = KMGetKeyFromUserID (pKM, userid);
	}
	else
	{
		key = (PGPKeyRef)KMFocusedObject (pKM);
		PGPGetPrimaryUserID (key, &userid);
	}

	PGPNewSingletonKeySet (key, &keysetKey);
	if (PGPRefIsValid (keysetKey)) 
	{
		err = PGPclSendCertificateRequestToServer (
									pKM->Context, 
									pKM->tlsContext,
									pKM->hWndParent, 
									pKM->KeySetMain,
									userid,
									keysetKey);
		PGPFreeKeySet (keysetKey);
	}

	if (err == kPGPError_InvalidProperty)
	{
		if (KMIsThisTheOnlyUserID (pKM, userid))
			KMMessageBox (pKM->hWndParent, IDS_CAPTION, 
					IDS_CANTDERIVEATTRIBUTESONLY, MB_OK|MB_ICONEXCLAMATION);
		else
			KMMessageBox (pKM->hWndParent, IDS_CAPTION, 
					IDS_CANTDERIVEATTRIBUTES, MB_OK|MB_ICONEXCLAMATION);
	}
	else if (IsPGPError (err))
	{
		PGPclErrorBox (pKM->hWndParent, err);
	}
	else
	{
		KMMessageBox (pKM->hWndParent, IDS_PGP, 
				IDS_CERTIFICATEREQUESTED, MB_OK|MB_ICONINFORMATION);
	}

	return TRUE;
}
示例#4
0
BOOL 
KMSendToServer (PKEYMAN pKM, UINT uServerFlags) 
{
	PGPKeySetRef	keysetSend		= kInvalidPGPKeySetRef;
	PGPError		err				= kPGPError_BadParams;
	INT				iKeyCount;

	if ((uServerFlags == PGPCL_SPECIFIEDSERVER) && 
		(pKM->keyserver.structSize == 0))
	{
		uServerFlags = PGPCL_USERIDBASEDSERVER;
	}

	KMGetSelectedKeys (pKM, &keysetSend, &iKeyCount);
	if (PGPRefIsValid (keysetSend)) {
		err = PGPclSendKeysToServer (pKM->Context, pKM->tlsContext, 
					pKM->hWndParent, uServerFlags, &pKM->keyserver, 
					pKM->KeySetMain, keysetSend);
		PGPFreeKeySet (keysetSend);
	}

	if (err == kPGPError_ServerKeyAlreadyExists) {
		if (iKeyCount > 1) {
			KMMessageBox (pKM->hWndParent, IDS_CAPTION, 
						IDS_KEYSALREADYONSERVER, MB_OK|MB_ICONINFORMATION);
		}
		else {
			KMMessageBox (pKM->hWndParent, IDS_CAPTION, 
						IDS_KEYALREADYONSERVER, MB_OK|MB_ICONINFORMATION);
		}
	}
	else if (IsPGPError (err)) {
		PGPclErrorBox (NULL, err);
	}
	else {
		KMMessageBox (pKM->hWndParent, IDS_PGP, IDS_UPLOADOK,
								MB_OK|MB_ICONINFORMATION);
	}

	return TRUE;
}
示例#5
0
BOOL InitPGPsc(HWND hwnd,void **PGPsc,void **PGPtls)
{
	PGPError err;
	PGPContextRef context;
	PGPtlsContextRef tls;
	DWORD OLERetVal;

	err=PGPNewContext( kPGPsdkAPIVersion, &context );

	if( IsPGPError(err) )
	{
		if(err == kPGPError_IncompatibleAPI)
		{
			PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_WRONGSDK,
					MB_OK|MB_ICONSTOP);
		}
		else
		if(err == kPGPError_FeatureNotAvailable)
		{
			PGPscMessageBox (hwnd,IDS_PGPERROR,IDS_EVALEXPIRED,
					MB_OK|MB_ICONSTOP);
		}
		else
			PGPclErrorBox(hwnd,err);

		return FALSE;
	}

	if(IsPGPError(PGPclIsExpired(hwnd)))
		return FALSE;

	err=PGPNewTLSContext (context, &tls);

	if( IsPGPError(err) )
	{
		PGPclErrorBox(hwnd,err);
		return FALSE;
	}

	err=PGPclInitLibrary(context);

	if(err==kPGPError_UserAbort)
		return FALSE;

	if( IsPGPError(err) )
	{
		PGPclErrorBox(hwnd,err);
		return FALSE;
	}

	OLERetVal=OleInitialize (NULL);

	switch(OLERetVal)
	{
		case S_OK:
			// The COM library and additional functionality were 
			// initialized successfully on this apartment. 
			break;

		case S_FALSE:
		{
			// The COM library is already initialized on this 
			// apartment.
			break;
		}

		case OLE_E_WRONGCOMPOBJ:
		{
			MessageBox(hwnd,
				"The versions of COMPOBJ.DLL and OLE2.DLL on\n"
				"your machine are incompatible with each other.",
				"OLE Error",MB_OK);
			return FALSE;
		}

		default:
		{
			MessageBox(hwnd,
				"Error initializing OLE.",
				"OLE Error",MB_OK);
			return FALSE;
		}
	}

	*PGPsc=(void *)context;
	*PGPtls=(void *)tls;

	g_uPurgePassphraseCacheMessage = 
		RegisterWindowMessage (PURGEPASSPHRASECACEHMSG);

	return TRUE;
}
示例#6
0
VOID 
PKBackup (HWND hWnd) 
{
	BOOL			bFileError;
	HKEY			hKey;
	LONG			lResult;
	DWORD			dwValueType, dwSize;
	OPENFILENAME	OpenFileName;
	CHAR			szFile[MAX_PATH];
	CHAR			szDir[MAX_PATH];
	CHAR			sz256[256];
	CHAR			szDefExt[8];
	CHAR			szFilter[256];
	PGPError		err;
	PGPFileSpecRef	fileref;
	LPSTR			lpsz;
	CHAR*			p;

	do {
		bFileError = FALSE;

		lResult = RegOpenKeyEx (HKEY_CURRENT_USER, 
			"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\"
			"Shell Folders", 
			0, KEY_READ, &hKey);
		if (lResult == ERROR_SUCCESS) {

		// backup public keyring file
			dwSize = sizeof(szDir);
			lResult = RegQueryValueEx (hKey, "Desktop", 0, &dwValueType, 
				(LPBYTE)&szDir, &dwSize);
			if (lResult != ERROR_SUCCESS) 
				LoadString (g_hInst, IDS_BACKUPDEFAULTDIR, 
											szDir, sizeof(szDir));
			OpenFileName.lStructSize       = sizeof (OPENFILENAME);
			OpenFileName.hwndOwner         = hWnd;
			OpenFileName.hInstance         = (HANDLE)g_hInst;
			LoadString (g_hInst, IDS_PUBBACKUPFILTER, 
				szFilter, sizeof(szFilter));
			while (p = strrchr (szFilter, '@')) *p = '\0';
			OpenFileName.lpstrFilter       = szFilter;
			OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
			OpenFileName.nMaxCustFilter    = 0L;
			OpenFileName.nFilterIndex      = 1L;
	
			err = PGPsdkPrefGetFileSpec (g_Context, 
						kPGPsdkPref_PublicKeyring, &fileref);
			if (IsntPGPError (PGPclErrorBox (NULL, err))) {
				PGPGetFullPathFromFileSpec (fileref, &lpsz);
				p = strrchr (lpsz, '\\');
				if (p) {
					p++;
					lstrcpy (szFile, p);
				}
				else lstrcpy (szFile, lpsz);
				p = strrchr (szFile, '.');
				if (p) *p = '\0';
				PGPFreeData (lpsz);
				PGPFreeFileSpec (fileref);
			}
			else {
				LoadString (g_hInst, IDS_PUBBACKUPDEFAULTFILE, 
									szFile, sizeof(szFile));
			}
					
			OpenFileName.lpstrFile         = szFile;
			OpenFileName.nMaxFile          = sizeof (szFile);
			OpenFileName.lpstrFileTitle    = NULL;
			OpenFileName.nMaxFileTitle     = 0;
			OpenFileName.lpstrInitialDir   = szDir;
			LoadString (g_hInst, IDS_PUBBACKUPCAPTION, sz256, 
												sizeof(sz256));
			OpenFileName.lpstrTitle        = sz256;
			OpenFileName.Flags			   = OFN_HIDEREADONLY|
											 OFN_OVERWRITEPROMPT|
											 OFN_NOREADONLYRETURN|
											 OFN_NOCHANGEDIR;
			OpenFileName.nFileOffset       = 0;
			OpenFileName.nFileExtension    = 0;
			LoadString (g_hInst, IDS_DEFPUBKEYRINGEXTENSION, 
									szDefExt, sizeof(szDefExt));
			OpenFileName.lpstrDefExt       = szDefExt;
			OpenFileName.lCustData         = 0;
	
			if (GetSaveFileName (&OpenFileName)) { 
				err = PGPsdkPrefGetFileSpec (g_Context, 
						kPGPsdkPref_PublicKeyring, &fileref);
				if (IsntPGPError (PGPclErrorBox (NULL, err))) {
	
					PGPGetFullPathFromFileSpec (fileref, &lpsz);
					if (!CopyFile (lpsz, szFile, FALSE)) 
						bFileError = TRUE;
					PGPFreeData (lpsz);
					PGPFreeFileSpec (fileref);
	
				}
				else bFileError = TRUE;
	
				if (bFileError) {
					PKMessageBox (hWnd, IDS_CAPTION, IDS_BACKUPERROR, 
										MB_OK|MB_ICONSTOP);
				}
			}

			if (bFileError) continue;
	
			// backup private keyring file
			lstrcpy (szDir, szFile);
			p = strrchr (szDir, '\\');
			if (p) *p = '\0';
			OpenFileName.lStructSize       = sizeof (OPENFILENAME);
			OpenFileName.hwndOwner         = hWnd;
			OpenFileName.hInstance         = (HANDLE)g_hInst;
			LoadString (g_hInst, IDS_BACKUPFILTER, 
				szFilter, sizeof(szFilter));
			while (p = strrchr (szFilter, '@')) *p = '\0';
			OpenFileName.lpstrFilter       = szFilter;
			OpenFileName.lpstrCustomFilter = (LPTSTR)NULL;
			OpenFileName.nMaxCustFilter    = 0L;
			OpenFileName.nFilterIndex      = 1L;
	
			err = PGPsdkPrefGetFileSpec (g_Context, 
						kPGPsdkPref_PrivateKeyring, &fileref);
			if (IsntPGPError (PGPclErrorBox (NULL, err))) {
				PGPGetFullPathFromFileSpec (fileref, &lpsz);
				p = strrchr (lpsz, '\\');
				if (p) {
					p++;
					lstrcpy (szFile, p);
				}
				else lstrcpy (szFile, lpsz);
				p = strrchr (szFile, '.');
				if (p) *p = '\0';
				PGPFreeData (lpsz);
				PGPFreeFileSpec (fileref);
			}
			else {
				LoadString (g_hInst, IDS_BACKUPDEFAULTFILE, 
									szFile, sizeof(szFile));
			}
	
			OpenFileName.lpstrFile         = szFile;
			OpenFileName.nMaxFile          = sizeof (szFile);
			OpenFileName.lpstrFileTitle    = NULL;
			OpenFileName.nMaxFileTitle     = 0;
			OpenFileName.lpstrInitialDir   = szDir;
			LoadString (g_hInst, IDS_BACKUPCAPTION, sz256, sizeof(sz256));
			OpenFileName.lpstrTitle        = sz256;
			OpenFileName.Flags			   = OFN_HIDEREADONLY|
											 OFN_OVERWRITEPROMPT|
											 OFN_NOREADONLYRETURN|
											 OFN_NOCHANGEDIR;
			OpenFileName.nFileOffset       = 0;
			OpenFileName.nFileExtension    = 0;
			LoadString (g_hInst, IDS_DEFKEYRINGEXTENSION, 
									szDefExt, sizeof(szDefExt));
			OpenFileName.lpstrDefExt       = szDefExt;
			OpenFileName.lCustData         = 0;
	
			if (GetSaveFileName (&OpenFileName)) { 
				err = PGPsdkPrefGetFileSpec (g_Context, 
						kPGPsdkPref_PrivateKeyring, &fileref);
				if (IsntPGPError (PGPclErrorBox (NULL, err))) {

					PGPGetFullPathFromFileSpec (fileref, &lpsz);
					if (!CopyFile (lpsz, szFile, FALSE)) 
						bFileError = TRUE;
					PGPFreeData (lpsz);
					PGPFreeFileSpec (fileref);
	
				}
				else bFileError = TRUE;
	
				if (bFileError) {
					PKMessageBox (hWnd, IDS_CAPTION, IDS_BACKUPERROR, 
										MB_OK|MB_ICONSTOP);
				}
			}
		}
	} while (bFileError);
	
	return;
}
示例#7
0
BOOL 
KMRetrieveCertificate (PKEYMAN pKM) 
{
	PGPKeySetRef	keysetKey		= kInvalidPGPKeySetRef;
	PGPKeySetRef	keysetReturned	= kInvalidPGPKeySetRef;
	PGPUserIDRef	userid			= kInvalidPGPUserIDRef;
	PGPKeyRef		key				= kInvalidPGPKeyRef;
	PGPError		err;

	if (KMSelectedFlags (pKM) == OBJECT_USERID)
	{
		userid = (PGPUserIDRef)KMFocusedObject (pKM);
		key = KMGetKeyFromUserID (pKM, userid);
	}
	else
	{
		key = (PGPKeyRef)KMFocusedObject (pKM);
		PGPGetPrimaryUserID (key, &userid);
	}

	PGPNewSingletonKeySet (key, &keysetKey);
	if (PGPRefIsValid (keysetKey)) 
	{
		err = PGPclRetrieveCertificateFromServer (
									pKM->Context, 
									pKM->tlsContext,
									pKM->hWndParent, 
									pKM->KeySetMain,
									keysetKey,
									userid,
									&keysetReturned);
		PGPFreeKeySet (keysetKey);
	}
	if (err == kPGPError_UserAbort) 
		return FALSE;

	if (IsPGPError (err)) 
	{
		PGPclErrorBox (pKM->hWndParent, err);
	}
	else 
	{
		if (PGPRefIsValid (keysetReturned)) 
		{
			PGPUInt32 u;

			PGPCountKeys (keysetReturned, &u);
			if (u > 0) 
			{
#if 0	// <- set to "1" to enable selective import dialog
				PGPclQueryAddKeys (pKM->Context, pKM->tlsContext,
							pKM->hWndParent, keysetReturned, pKM->KeySetDisp);
#else
				if (pKM->ulOptionFlags & KMF_ENABLECOMMITS) 
				{
					PGPAddKeys (keysetReturned, pKM->KeySetDisp);
					KMCommitKeyRingChanges (pKM);
					KMLoadKeyRingIntoTree (pKM, FALSE, TRUE, FALSE);
					InvalidateRect (pKM->hWndTree, NULL, TRUE);

					KMMessageBox (pKM->hWndParent, IDS_PGP,
							IDS_CERTRETRIEVALSUCCESS, 
							MB_OK|MB_ICONINFORMATION);
				}
#endif
			}
			else 
			{
				KMMessageBox (pKM->hWndParent, IDS_CAPTION,
						IDS_CERTRETRIEVALFAIL, MB_OK|MB_ICONEXCLAMATION);
			}
			PGPFreeKeySet (keysetReturned);
		}
	}
	return TRUE;
}
示例#8
0
BOOL 
KMGetFromServerInternal (
		PKEYMAN		pKM, 
		BOOL		bQueryAdd, 
		BOOL		bWarn,
		BOOL		bGetSigners) 
{
	SERVERSTRUCT	ss;
	PGPKeySetRef	keysetGet		= kInvalidPGPKeySetRef;
	PGPKeySetRef	keysetFound		= kInvalidPGPKeySetRef;
	PGPError		err				= kPGPError_NoErr;

	ss.context = pKM->Context;
	ss.pKM = pKM;
	ss.icount = 0;

	// get selected keys
	if ((KMFocusedObjectType (pKM) == OBJECT_KEY) ||
		(KMFocusedObjectType (pKM) == OBJECT_USERID) ||
		(!bGetSigners)) 
	{
		KMGetSelectedKeys (pKM, &keysetGet, NULL);
		if (PGPRefIsValid (keysetGet)) {
			err = PGPclUpdateKeySetFromServer (pKM->Context, 
										pKM->tlsContext,
										pKM->hWndParent, 
										keysetGet,
										PGPCL_USERIDBASEDSERVER,
										pKM->KeySetMain,
										&keysetFound);
			PGPFreeKeySet (keysetGet);
		}
	}

	// get signing keys
	else {
		KMGetSelectedKeys (pKM, NULL, &ss.icount);
		if (ss.icount) {
			ss.pkeyidList = 
				(PGPKeyID*)malloc ((ss.icount) * sizeof(PGPKeyID));
			ss.icount = 0;
			ss.lpfnCallback = sAddKeyIDToList;
			TreeList_IterateSelected (pKM->hWndTree, &ss);
			err = PGPclSearchServerForKeyIDs (pKM->Context,
								pKM->tlsContext,
								pKM->hWndParent, 
								ss.pkeyidList,
								ss.icount, 
								PGPCL_DEFAULTSERVER,
								pKM->KeySetMain,
								&keysetFound);
			free (ss.pkeyidList);
		}
	}

	if (err == kPGPError_UserAbort) return FALSE;

	if (IsPGPError (err)) {
		if (bWarn) PGPclErrorBox (NULL, err);
	}
	else {
		if (PGPRefIsValid (keysetFound)) {
			PGPUInt32 u;
			PGPCountKeys (keysetFound, &u);
			if (u > 0) {
				if (bQueryAdd) {
					PGPclQueryAddKeys (pKM->Context, pKM->tlsContext,
							pKM->hWndParent, keysetFound, pKM->KeySetDisp);
				}
				else {
					if (pKM->ulOptionFlags & KMF_ENABLECOMMITS) {
						PGPAddKeys (keysetFound, pKM->KeySetDisp);
						PGPCommitKeyRingChanges (pKM->KeySetDisp);
					}
				}
			}
			else {
				KMMessageBox (pKM->hWndParent, IDS_CAPTION,
						IDS_SERVERSEARCHFAIL, MB_OK|MB_ICONEXCLAMATION);
			}
			PGPFreeKeySet (keysetFound);
		}
	}

	return TRUE;
}
示例#9
0
PGPError PGPclExport 
PGPclUpdateKeySetFromServer (
		PGPContextRef		context,
		PGPtlsContextRef	tlsContext,
		HWND				hwndParent, 
		PGPKeySetRef		keysetToUpdate,
		UINT				uServer,
		PGPKeySetRef		keysetMain,
		PGPKeySetRef*		pkeysetResult)
{
	PGPError				err				= kPGPError_NoErr;
	PGPKeySetRef			keysetCollect	= kInvalidPGPKeySetRef;
	PGPOptionListRef		optionSearch	= kInvalidPGPOptionListRef;
	PGPKeyListRef			keylist			= kInvalidPGPKeyListRef;
	PGPKeyIterRef			keyiter			= kInvalidPGPKeyIterRef;
	PGPKeySetRef			keyset			= kInvalidPGPKeySetRef;

	PGPKeyID				keyid;

	// initialize return keyset
	PGPValidatePtr (pkeysetResult);
	*pkeysetResult = kInvalidPGPKeySetRef;

	if (uServer == PGPCL_USERIDBASEDSERVER) {
		PGPKeyRef		key			= kInvalidPGPKeyRef;

		CHAR			szUserID[kPGPMaxUserIDSize+1];
		PGPSize			size;

		err = PGPNewKeySet (context, &keysetCollect); CKERR;
		err = PGPOrderKeySet (keysetToUpdate, 
								kPGPAnyOrdering, &keylist); CKERR;
		err = PGPNewKeyIter (keylist, &keyiter); CKERR;

		while (	IsntPGPError (err) &&
				IsntPGPError (PGPKeyIterNext (keyiter, &key)) && 
				PGPKeyRefIsValid (key))
		{
			err = PGPGetPrimaryUserIDNameBuffer (key, kPGPMaxUserIDSize,
							szUserID, &size); CKERR;

			err = PGPGetKeyIDFromKey (key, &keyid); CKERR;

			optionSearch = PGPOUIKeyServerSearchKeyIDList (context,
								1, &keyid);

			if (PGPOptionListRefIsValid (optionSearch)) {

				err = sQueryServerInternal (hwndParent,
											context,
											tlsContext,
											optionSearch,
											uServer,
											szUserID,
											keysetMain,
											&keyset); 

				if (IsPGPError (PGPclErrorBox (hwndParent, err)))
					err = kPGPError_NoErr;

				if (IsntPGPError (err))
				{
					if (PGPKeySetRefIsValid (keyset))
					{	
						err = PGPAddKeys (keyset, keysetCollect);
						if (IsntPGPError (PGPclErrorBox (hwndParent, err))) 
						{
							err = PGPCommitKeyRingChanges (keysetCollect);
							PGPclErrorBox (hwndParent, err);
						}
					}
				}

				if (PGPKeySetRefIsValid (keyset))
				{
					PGPFreeKeySet (keyset);
					keyset = kInvalidPGPKeySetRef;
				}
			}
		}

		if (PGPKeySetRefIsValid (keysetCollect)) 
		{	
			*pkeysetResult = keysetCollect;
			keysetCollect = kInvalidPGPKeySetRef;
		}
	}

	else { 
		optionSearch = PGPOUIKeyServerSearchKeySet (context, keysetToUpdate);

		if (PGPOptionListRefIsValid (optionSearch)) {

			err = sQueryServerInternal (hwndParent,
										context,
										tlsContext,
										optionSearch,
										uServer,
										"",
										keysetMain,
										&keysetCollect);

			if (IsntPGPError (err)) 
			{	
				*pkeysetResult = keysetCollect;
				keysetCollect = kInvalidPGPKeySetRef;
			}
		}
	}

done :
	if (PGPKeyListRefIsValid (keylist))
		PGPFreeKeyList (keylist);
	if (PGPKeyIterRefIsValid (keyiter))
		PGPFreeKeyIter (keyiter);
	if (PGPKeySetRefIsValid (keyset))
		PGPFreeKeySet (keyset);
	if (PGPKeySetRefIsValid (keysetCollect))
		PGPFreeKeySet (keysetCollect);

	return err;
}
示例#10
0
static BOOL 
sSplitKey (PSPLITKEYSTRUCT psks)
{
	PGPShareRef			shares				= NULL;
	PGPSize				sizePasskey			= 0;
	PGPByte*			pPasskey			= NULL;
	LPSTR				pszPhraseKeyToSplit	= NULL;
	PGPByte*			pPasskeyToSplit		= NULL;
	PGPSize				sizePasskeyToSplit	= 0;
	CHAR				szEmptyString[]		= {""};
	HWND				hwndProgress		= NULL;
	BOOL				bRetVal				= TRUE;

	PGPError				err;
	PGPKeyRef				keyToSplit;
	BROWSEINFO				bi;
	LPITEMIDLIST			pidl;
	LPMALLOC				pMalloc;
	CHAR					szFolder[MAX_PATH];
	CHAR					sz[kPGPMaxUserIDSize + 32];
	INT						iItem;
	INT						iNumItems;
	LV_ITEM					lvI;
	PSHAREHOLDERSTRUCT		pshs;
	HCURSOR					hcursorOld;
	SPLITKEYPROGRESSSTRUCT	skps;

	// get keyref from keyring
	err = PGPGetKeyByKeyID (psks->pKM->KeySetMain, &(psks->keyidToSplit),
							psks->keyalgToSplit, &keyToSplit);
	if (IsPGPError (err)) {
		KMMessageBox (psks->hwndDlg, IDS_CAPTIONERROR, IDS_SPLITKEYGONE, 
						MB_OK|MB_ICONERROR);
		bRetVal = FALSE;
		goto SplitKeyCleanup;
	}

	// get task allocator
	if (SHGetMalloc(&pMalloc) != NOERROR) return FALSE;

	// get prompt string
	LoadString (g_hInst, IDS_SAVESHARES, sz, sizeof(sz));

	// initialize structure
	bi.hwndOwner = psks->hwndDlg;
	bi.pidlRoot = NULL;
	bi.pszDisplayName = szFolder;
	bi.lpszTitle = sz;
	bi.ulFlags = BIF_RETURNONLYFSDIRS;
	bi.lpfn = NULL;
	bi.lParam = 0;

	// allow user to browse
	pidl = SHBrowseForFolder (&bi);
	if (pidl == NULL) return FALSE;
	SHGetPathFromIDList (pidl, szFolder);
	pMalloc->lpVtbl->Free(pMalloc, pidl);

	// get passphrase of key to split
	LoadString (g_hInst, IDS_SPLITKEYPHRASEPROMPT, sz, sizeof(sz));
	err = KMGetKeyPhrase (psks->pKM->Context, psks->pKM->tlsContext,
			psks->hwndDlg, sz, 
			psks->pKM->KeySetMain, keyToSplit,
			&pszPhraseKeyToSplit, &pPasskeyToSplit, 
			&sizePasskeyToSplit);
	PGPclErrorBox (NULL, err);

	if (IsPGPError (err)) {
		bRetVal = FALSE;
		goto SplitKeyCleanup;
	}

	// make sure that this is what user wants to do
	if (KMMessageBox (psks->hwndDlg, IDS_CAPTION, IDS_SPLITKEYCONFIRMATION,
						MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
		bRetVal = FALSE;
		goto SplitKeyCleanup;
	}

	// post progress dialog
	iNumItems = ListView_GetItemCount (psks->hwndList);
	skps.iNumSteps = iNumItems +2;
	hwndProgress = CreateDialogParam (g_hInst, 
						MAKEINTRESOURCE(IDD_SPLITKEYPROGRESS),
						psks->hwndDlg, sSplitKeyProgressDlgProc,
						(LPARAM)&skps);
	LoadString (g_hInst, IDS_CREATINGSHARES, sz, sizeof(sz));
	SendMessage (hwndProgress, WM_APP, 1, (LPARAM)sz);

	// create the shares
	err = PGPCreateShares (	psks->pKM->Context, 
							keyToSplit, 
							psks->uThreshold, 
							psks->uTotalShares, 
							&shares);

	if (IsPGPError (PGPclErrorBox (NULL, err))) {
		bRetVal = FALSE;
		goto SplitKeyCleanup;
	}

	// get the passkey from the shares
	err = PGPGetPasskeyFromShares (shares, &pPasskey, &sizePasskey);
	if (IsntPGPError (PGPclErrorBox (NULL, err))) {

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

		// save share file for each item in listview
		for (iItem=0; iItem<iNumItems; iItem++) {
			lvI.mask = LVIF_PARAM;
			lvI.iItem = iItem;
			lvI.iSubItem = 0;
			ListView_GetItem(psks->hwndList, &lvI);

			// update progress dialog
			pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
			LoadString (g_hInst, IDS_SAVINGSHARES, sz, sizeof(sz));
			lstrcat (sz, pshs->szUserID);
			SendMessage (hwndProgress, WM_APP, iItem+2, (LPARAM)sz);

			err = sSaveSharesToFile (pshs, psks->pKM->Context, shares,
										psks->pKM->KeySetMain, szFolder);
			if (IsPGPError (err)) break;
		}

		// update progress dialog
		LoadString (g_hInst, IDS_SPLITTINGKEY, sz, sizeof(sz));
		SendMessage (hwndProgress, WM_APP, iNumItems+2, (LPARAM)sz);

		SetCursor (hcursorOld);
		PGPclErrorBox (NULL, err);

		if (IsPGPError (err)) {
///			delete files;
		}
		else {
			err = sChangeKeyPhrase (psks->pKM->Context, 
					psks->pKM->KeySetMain, keyToSplit, 
					pszPhraseKeyToSplit, pPasskeyToSplit, sizePasskeyToSplit,
					pPasskey, sizePasskey);
			PGPclErrorBox (NULL, err);
			KMCommitKeyRingChanges (psks->pKM); 
			KMUpdateKeyInTree (psks->pKM, keyToSplit, FALSE);
			KMSelectKey (psks->pKM, keyToSplit, TRUE);
		}
	}

	// cleanup
SplitKeyCleanup :
	if (hwndProgress)
		DestroyWindow (hwndProgress);

	if (pszPhraseKeyToSplit) 
		KMFreePhrase (pszPhraseKeyToSplit);

	if (pPasskeyToSplit)
		KMFreePasskey (pPasskeyToSplit, sizePasskeyToSplit);

	if (pPasskey)
		PGPFreeData (pPasskey);

	if (shares != NULL)
		PGPFreeShares (shares);

	return (bRetVal);
}
示例#11
0
BOOL 
KMAddRevoker (PKEYMAN pKM) 
{
	PGPKeySetRef	keysetToChoose		= kInvalidPGPKeySetRef;
	PGPKeySetRef	keysetToRemove		= kInvalidPGPKeySetRef;
	PGPKeySetRef	keysetThisKey		= kInvalidPGPKeySetRef;
	PGPKeySetRef	keysetSelected		= kInvalidPGPKeySetRef;
	PGPFilterRef	filterRSA			= kInvalidPGPFilterRef;
	PGPError		err					= kPGPError_NoErr;
	PGPByte*		pbyte				= NULL;
	BOOL			bRet				= FALSE;
	PGPUInt32		uCount				= 0;
	PGPBoolean		bSyncWithServer		= FALSE;

	PGPPrefRef		prefref;
	PGPSize			size;
	PGPKeyRef		key;
	CHAR			szPrompt[256];


	key = (PGPKeyRef)KMFocusedObject (pKM);

	PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context), &prefref);
	PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnAdd, 
						&bSyncWithServer);
	PGPclCloseClientPrefs (prefref, FALSE);

	err = PGPNewKeySet (pKM->Context, &keysetToChoose); CKERR;
	err = PGPAddKeys (pKM->KeySetMain, keysetToChoose); CKERR;
	err = PGPCommitKeyRingChanges (keysetToChoose); CKERR;

	err = PGPNewKeyEncryptAlgorithmFilter (pKM->Context, 
						kPGPPublicKeyAlgorithm_RSA, &filterRSA); CKERR;
	err = PGPFilterKeySet (pKM->KeySetMain, 
						filterRSA, &keysetToRemove); CKERR;

	err = PGPCommitKeyRingChanges (keysetToRemove); CKERR;
	err = PGPRemoveKeys (keysetToRemove, keysetToChoose); CKERR;
	err = PGPCommitKeyRingChanges (keysetToChoose); CKERR;

	err = PGPCountKeys (keysetToChoose, &uCount); CKERR;
	if (uCount <= 1) {
		KMMessageBox (pKM->hWndParent, IDS_PGP, IDS_NOTENOUGHKEYSTOADDREVOKER,
						MB_OK|MB_ICONINFORMATION);
		goto done;
	}

	err = PGPFreeKeySet (keysetToRemove); CKERR;
	err = PGPNewSingletonKeySet (key, &keysetToRemove); CKERR;
	err = PGPRemoveKeys (keysetToRemove, keysetToChoose); CKERR;

	err = PGPCommitKeyRingChanges (keysetToChoose); CKERR;

	LoadString (g_hInst, IDS_ADDREVOKERPROMPT, szPrompt, sizeof(szPrompt));
	err = PGPclSelectKeys (pKM->Context, pKM->tlsContext, 
					pKM->hWndParent, szPrompt,
					keysetToChoose, pKM->KeySetMain, &keysetSelected);

	if (IsntPGPError (err) && PGPKeySetRefIsValid (keysetSelected))
	{
		if (KMMessageBox (pKM->hWndParent, IDS_CAPTION, 
				IDS_ADDREVOKERCONFIRM, MB_YESNO|MB_ICONEXCLAMATION) == IDYES) 
		{
			err = KMGetKeyPhrase (pKM->Context, pKM->tlsContext,
									pKM->hWndParent, NULL, 
									pKM->KeySetMain, key, 
									NULL, &pbyte, &size); CKERR;

			// update from server
			if (IsntPGPError (err) && bSyncWithServer) {
				if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
					if (KMMessageBox (pKM->hWndParent, IDS_CAPTION, 
								IDS_QUERYCONTINUEADDING, 	
								MB_YESNO|MB_ICONEXCLAMATION) == IDNO) 
					{
						err = kPGPError_UserAbort;
					}
				}
			}
		
			if (IsntPGPError (err)) {
				err = PGPAddKeyOptions (key, 
					PGPORevocationKeySet (pKM->Context, keysetSelected),
					pbyte ?
						PGPOPasskeyBuffer (pKM->Context, pbyte, size) :
						PGPONullOption (pKM->Context),
					PGPOLastOption (pKM->Context)); CKERR;
			}
		}
		else
			err = kPGPError_UserAbort;
	}

	// send to server
	if (IsntPGPError (err) && bSyncWithServer) {
		KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
	}

	if (IsntPGPError (err)) {
		KMCommitKeyRingChanges (pKM);
		bRet = TRUE;

		if (bSyncWithServer) {
			KMMessageBox (pKM->hWndParent, IDS_PGP, IDS_ADDEDSENTREVOKERS,
						MB_OK|MB_ICONINFORMATION);
		}
		else {
			KMMessageBox (pKM->hWndParent, IDS_PGP, IDS_ADDEDREVOKERS,
						MB_OK|MB_ICONINFORMATION);
		}
	}

done :
	if (NULL!=(int) (pbyte))
		KMFreePasskey (pbyte, size);
	if (PGPKeySetRefIsValid (keysetToChoose))
		PGPFreeKeySet (keysetToChoose);
	if (PGPKeySetRefIsValid (keysetToRemove))
		PGPFreeKeySet (keysetToRemove);
	if (PGPKeySetRefIsValid (keysetThisKey))
		PGPFreeKeySet (keysetThisKey);
	if (PGPKeySetRefIsValid (keysetSelected))
		PGPFreeKeySet (keysetSelected);
	if (PGPFilterRefIsValid (filterRSA))
		PGPFreeFilter (filterRSA);

	PGPclErrorBox (pKM->hWndParent, err);

	return bRet;
}
示例#12
0
BOOL 
KMRevokeCert (PKEYMAN pKM) 
{
	BOOL				bRetVal		= TRUE;
	PGPByte*			pPasskey	= NULL;

	PGPSize				sizePasskey;
	PGPSigRef			cert;
	PGPKeyRef			keySigning, keyParent;
	PGPError			err;
	CHAR				sz128[128];
	REVOKECERTSTRUCT	rcs;
	PGPPrefRef			prefref;

	cert = (PGPSigRef) KMFocusedObject (pKM);

	err = PGPGetSigCertifierKey (cert, pKM->KeySetMain, &keySigning);
	if (err == kPGPError_ItemNotFound) {
		keySigning = NULL;
		err = kPGPError_NoErr;
	}

	if (IsntPGPError (PGPclErrorBox (NULL, err))) {
		if (!keySigning) {
			KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_CERTKEYNOTONRING, 
							MB_OK|MB_ICONEXCLAMATION);
			return FALSE;
		}

		rcs.pKM = pKM;
		rcs.key = KMGetKeyFromCert (pKM, cert);

		PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context), 
						&prefref);
		PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnRevocation, 
						&(rcs.bSyncWithServer));
		PGPclCloseClientPrefs (prefref, FALSE);

		if (DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_REVOKECERT), 
							pKM->hWndParent, sRevokeCertDlgProc, 
							(LPARAM)&rcs)) {
			return FALSE;
		}
		
		// get valid passphrase
		LoadString (g_hInst, IDS_SIGNKEYPASSPHRASE, sz128, 128); 
		err = KMGetKeyPhrase (pKM->Context, pKM->tlsContext,
						pKM->hWndParent, sz128,
						pKM->KeySetMain, keySigning,
						NULL, &pPasskey, &sizePasskey);
		PGPclErrorBox (NULL, err);

		// now we have a valid passphrase, if required
		if (IsntPGPError (err)) {

			// update from server
			if (rcs.bSyncWithServer) {
				if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
					if (KMMessageBox (pKM->hWndParent, IDS_CAPTION, 
									IDS_QUERYCONTINUEREVOKINGCERT, 
									MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
						bRetVal = FALSE;
					}
				}
			}
		
			if (bRetVal) {

				// make sure we have enough entropy
				PGPclRandom (pKM->Context, pKM->hWndParent, 0);

				err = PGPRevokeSig (
						(PGPSigRef) KMFocusedObject (pKM), 
						pKM->KeySetMain,
						pPasskey ? 
							PGPOPasskeyBuffer (pKM->Context, 
								pPasskey, sizePasskey) :
							PGPONullOption (pKM->Context),
						PGPOLastOption (pKM->Context));
						
				if (IsntPGPError (PGPclErrorBox (NULL, err))) {
					keyParent = KMGetKeyFromCert (pKM, cert);
					KMUpdateKeyInTree (pKM, keyParent, FALSE);

					KMCommitKeyRingChanges (pKM);
					KMUpdateAllValidities (pKM);

					// send key to server, if selected
					if (rcs.bSyncWithServer) {
						KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
					}
				}
				else bRetVal = FALSE;
			}
		}
		else bRetVal = FALSE;
	}
	else bRetVal = FALSE;

	if (pPasskey) {
		KMFreePasskey (pPasskey, sizePasskey);
		pPasskey = NULL;
	}

	return bRetVal;
}
示例#13
0
BOOL 
KMRevokeKey (PKEYMAN pKM) 
{
	BOOL			bRetVal				= TRUE;
	PGPError		err					= kPGPError_NoErr;
	LPSTR			pszPhrase			= NULL;
	PGPByte*		pPasskey			= NULL;
	PGPKeySetRef	keysetRevokers		= kInvalidPGPKeySetRef;
	PGPKeyRef		keyRevoker			= kInvalidPGPKeyRef;
	PGPBoolean		bSecret				= FALSE;
	PGPBoolean		bSplit				= FALSE;
	PGPBoolean		bSyncWithServer		= FALSE;

	PGPSize			sizePasskey;
	PGPKeyRef		key;
	PGPKeyRef		keyToRevoke;
	PGPKeyRef		keyDef;
	CHAR			sz128[128];
	PGPPrefRef		prefref;
	PGPUInt32		u, uNumRevokers;

	keyToRevoke = (PGPKeyRef) KMFocusedObject (pKM);
	PGPGetDefaultPrivateKey (pKM->KeySetMain, &keyDef);

	PGPclOpenClientPrefs (PGPGetContextMemoryMgr (pKM->Context), &prefref);
	PGPGetPrefBoolean (prefref, kPGPPrefKeyServerSyncOnRevocation, 
						&bSyncWithServer);
	PGPclCloseClientPrefs (prefref, FALSE);

	if (keyToRevoke == keyDef) {
		if (KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_REVCONFDEFKEY,
			MB_YESNO|MB_TASKMODAL|MB_DEFBUTTON2|MB_ICONWARNING)==IDNO) 
			return FALSE;
	}
	else {
		if (KMMessageBox (pKM->hWndParent, IDS_CAPTION, IDS_REVOKECONFIRM, 
						MB_YESNO|MB_ICONEXCLAMATION) == IDNO) 
			return FALSE;
	}

	err = PGPGetKeyBoolean (keyToRevoke, 
				kPGPKeyPropIsSecret, &bSecret); CKERR;

	if (bSecret) {
		keyRevoker = keyToRevoke;
		err = PGPGetKeyBoolean (keyToRevoke, 
						kPGPKeyPropIsSecretShared, &bSplit); CKERR;
	}
	else {
		err = PGPCountRevocationKeys (keyToRevoke, &uNumRevokers);  CKERR;
		for (u = 0; u < uNumRevokers; u++) {
			err = PGPGetIndexedRevocationKey (keyToRevoke, pKM->KeySetMain,
					u, &key, NULL); CKERR;
			if (PGPKeyRefIsValid (key)) {
				err = PGPGetKeyBoolean (key, 
						kPGPKeyPropIsSecret, &bSecret); CKERR;
				err = PGPGetKeyBoolean (key, 
						kPGPKeyPropIsSecretShared, &bSplit); CKERR;
				if (bSecret) {
					keyRevoker = key;
					if (!bSplit) 
						break;
				}
			}
		}
	}

	if (!PGPKeyRefIsValid (keyRevoker))
		goto done;

	// get valid passphrase
	LoadString (g_hInst, IDS_SELKEYPASSPHRASE, sz128, 128); 
	err = KMGetKeyPhrase (pKM->Context, pKM->tlsContext,
						pKM->hWndParent, sz128,
						pKM->KeySetMain, keyRevoker,
						&pszPhrase, &pPasskey, &sizePasskey);
	PGPclErrorBox (NULL, err);

	// now we have a valid passphrase, if required
	if (IsntPGPError (err)) {

		// update from server
		if (bSyncWithServer) {
			if (!KMGetFromServerInternal (pKM, FALSE, FALSE, FALSE)) {
				if (KMMessageBox (pKM->hWndParent, IDS_CAPTION, 
									IDS_QUERYCONTINUEREVOKINGKEY, 
									MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
					bRetVal = FALSE;
				}
			}
		}
		
		if (bRetVal) {

			// make sure we have enough entropy
			PGPclRandom (pKM->Context, pKM->hWndParent, 0);

			if (bSplit) {
				err = sRevokeKeySplit (pKM->Context, 
									pKM->KeySetMain,
									keyToRevoke, 
									pPasskey, sizePasskey);
			}
			else {
				err = sRevokeKeyNormal (pKM->Context, 
									pKM->KeySetMain,
									keyToRevoke, 
									pszPhrase);
			}
						
			if (IsntPGPError (PGPclErrorBox (NULL, err))) {
				KMCommitKeyRingChanges (pKM);
				KMUpdateKeyInTree (pKM, keyToRevoke, FALSE);
				KMUpdateAllValidities (pKM);
				InvalidateRect (pKM->hWndTree, NULL, TRUE);

				// send to server
				if (bSyncWithServer) {
					KMSendToServer (pKM, PGPCL_DEFAULTSERVER);
				}
			}
			else bRetVal = FALSE;
		}
	}
	else bRetVal = FALSE;

done :
	if (NULL!=(int) (pszPhrase))
		KMFreePhrase (pszPhrase);
	if (NULL!=(int) (pPasskey)) 
		KMFreePasskey (pPasskey, sizePasskey);
	if (PGPKeySetRefIsValid (keysetRevokers))
		PGPFreeKeySet (keysetRevokers);

	PGPclErrorBox (pKM->hWndParent, err);

	return bRetVal;
}
示例#14
0
PGPError  
KMGetDecryptionPhrase (
		PGPContextRef		context,
		PGPtlsContextRef	tlsContext,
		HWND				hwnd, 
		LPSTR				szPrompt,
		PGPKeySetRef		keysetMain,
		PGPKeyRef*			pkey,
		PGPKeySetRef		keysetDecryption,
		PGPUInt32			iKeyIDCount,
		PGPKeyID*			keyidsDecryption,
		PGPKeySetRef*		pkeysetToAdd,
		LPSTR*				ppszPhrase,
		PGPByte**			ppPasskeyBuffer,
		PGPUInt32*			piPasskeyLength) 
{
	PGPError	err				= kPGPError_BadParams;
	PGPBoolean	bSplit			= FALSE;
	LPSTR		psz;

	if (!ppPasskeyBuffer) return err;
	if (!piPasskeyLength) return err;

	psz = NULL;
	*ppPasskeyBuffer = NULL;
	*piPasskeyLength = 0;

	if (pkey) 
		if (*pkey)
			PGPGetKeyBoolean (*pkey, kPGPKeyPropIsSecretShared, &bSplit);

	do {
		if (bSplit) {
			err=PGPclReconstituteKey(
				context,			// in context
				tlsContext,			// in TLS context
				hwnd,				// in hwnd of parent
				keysetMain,			// in keyset
				*pkey,				// in key
				ppPasskeyBuffer,	// out passkey buffer
				piPasskeyLength);	// out passkey length
		}
		else {
			err = PGPclGetPhrase (
				context,			// in context
				keysetMain,			// in main keyset
				hwnd,				// in hwnd of parent
				szPrompt,			// in prompt
				&psz,				// out phrase
				keysetDecryption,	// in keyset
				keyidsDecryption,	// in keyids
				iKeyIDCount,		// in keyid count
				pkey,				// in/out key
				NULL,				// out options
				PGPCL_DECRYPTION,	// in flags
				ppPasskeyBuffer,	// out passkey buffer
				piPasskeyLength,	// out passkey length
				0,0,				// in min length/quality
				tlsContext,			// in tlsContext,
				pkeysetToAdd,		// out AddedKeys
				NULL);

		}

		if (IsPGPError (err)) {
			if (psz) {
				PGPFreeData (psz);
				psz = NULL;
			}
			if (*ppPasskeyBuffer) {
				PGPFreeData (*ppPasskeyBuffer);
				*ppPasskeyBuffer = NULL;
			}
			PGPclErrorBox (hwnd, err);
		}
		else {
			if (ppszPhrase) *ppszPhrase = psz;
			else KMFreePhrase (psz);
		}

	} while (err == kPGPError_BadPassphrase);

	return err;
}
BOOL 
EncryptSignRichEditText(char** ppBuffer, 
						long* pLength, 
						BOOL bEncrypt, 
						BOOL bSign, 
						char** pAddresses, 
						long NumAddresses,
						char* pAttachments,
						char** ppOutAttachments)
{
	BOOL ReturnValue = FALSE;
	void* pOutput = NULL;
	long outSize = 0;
	PGPError error = kPGPError_NoErr;
	PGPOptionListRef userOptions = NULL;
	PGPclRecipientDialogStruct *prds = NULL;	
	char szExe[256];
	char szDll[256];

	LoadString(g_hinst, IDS_EXE, szExe, sizeof(szExe));
	LoadString(g_hinst, IDS_DLL, szDll, sizeof(szDll));

	// allocate a recipient dialog structure
	prds = (PGPclRecipientDialogStruct *) 
			calloc(sizeof(PGPclRecipientDialogStruct), 1);

	if (!prds)
	{
		PGPclErrorBox(g_hwndEudoraMainWindow, kPGPError_OutOfMemory);
		return FALSE;
	}

	error =	PGPclOpenDefaultKeyrings(g_pgpContext, 
				kPGPOpenKeyDBFileOptions_Mutable, &(prds->keydbOriginal));

	if (IsPGPError(error))
		error =	PGPclOpenDefaultKeyrings(g_pgpContext, 
					kPGPOpenKeyDBFileOptions_None, &(prds->keydbOriginal));

	if (IsPGPError(error))
	{
		char szTitle[255];
		char szBuffer[1024];
		
		LoadString(g_hinst, IDS_DLL, szTitle, 254);
		LoadString(g_hinst, IDS_Q_NOKEYRINGS, szBuffer, 1023);
		
		if (MessageBox(g_hwndEudoraMainWindow, szBuffer, szTitle, MB_YESNO))
		{
			char szPath[MAX_PATH];
			
			PGPclGetPath(kPGPclPGPkeysExeFile, szPath, MAX_PATH-1);
			PGPclExecute(szPath, SW_SHOW);
		}
		
		return S_FALSE;
	}

	if(prds && bEncrypt)
	{
		char szTitle[256]		= {0x00};	// title for recipient dialog
		UINT recipientReturn	= FALSE;	// recipient dialog result

		LoadString(GetModuleHandle("PGPplugin.dll"), 
			IDS_TITLE_RECIPIENTDIALOG, szTitle, sizeof(szTitle));

		if( IsntPGPError(error) )
		{
			prds->context			= g_pgpContext;
			prds->tlsContext		= g_tlsContext;
			prds->Version			= kPGPCurrentRecipVersion;
			prds->hwndParent		= g_hwndEudoraMainWindow;
			prds->szTitle			= szTitle;
			prds->dwOptions			= kPGPclASCIIArmor;	

			prds->dwDisableFlags	= kPGPclDisableWipeOriginal |
									  kPGPclDisableASCIIArmor |
									  kPGPclDisableSelfDecryptingArchive |
									  kPGPclDisableInputIsText;

			prds->dwNumRecipients	= NumAddresses;	
			prds->szRecipientArray	= pAddresses;

			// If shift is pressed, force the dialog to pop.
			if (GetAsyncKeyState( VK_CONTROL) & 0x8000)
				prds->dwDisableFlags |= kPGPclDisableAutoMode;

			// See who we wish to encrypt this to
			recipientReturn = PGPclRecipientDialog( prds );
		}

		if (prds->keydbAdded != NULL)
		{
			PGPUInt32 numKeys;
			PGPKeySetRef keySet;

			PGPNewKeySet(prds->keydbAdded, &keySet);
			PGPCountKeys(keySet, &numKeys);
			if (numKeys > 0)
				PGPclImportKeys(g_pgpContext, g_tlsContext, prds->hwndParent,
					keySet, prds->keydbOriginal, 
					kPGPclNoDialogForValidSingletons);

			PGPFreeKeySet(keySet);
			PGPFreeKeyDB(prds->keydbAdded);
			prds->keydbAdded = NULL;
		}

		if (!recipientReturn)
		{
			if (prds->keydbSelected != NULL)
				PGPFreeKeyDB(prds->keydbSelected);

			PGPFreeKeyDB(prds->keydbOriginal);
			free(prds);
			return FALSE;
		}
	}

	if( IsntPGPError(error) )
	{
		error = EncryptSignBuffer(g_hinst, g_hwndEudoraMainWindow,
					g_pgpContext, g_tlsContext, szExe, szDll,
					*ppBuffer, *pLength, prds, NULL, &userOptions, &pOutput,
					&outSize, bEncrypt, bSign, FALSE, FALSE);
	}
	else
	{
		PGPclEncDecErrorBox(g_hwndEudoraMainWindow, error);
	}

	*pLength = outSize;

	if( IsntPGPError(error) )
	{
		if( pOutput )
		{
			*ppBuffer = (char*)HeapReAlloc(	GetProcessHeap(), 
											HEAP_ZERO_MEMORY, 
											*ppBuffer, 
											*pLength + 1);

			if(*ppBuffer)
			{
				ReturnValue = TRUE;
				memcpy(*ppBuffer, (char*)pOutput, *pLength);
				*(*ppBuffer + *pLength) = 0x00; // NULL terminate the string
				memset(pOutput, 0x00, *pLength);
			}
			else 
			{
				error = kPGPError_OutOfMemory;
			}

			PGPFreeData(pOutput);
		}
	}
	
	// are there attachments?
	if(IsntPGPError(error) && pAttachments && *pAttachments) 
	{
		error = EncryptAttachments(	pAttachments, 
									ppOutAttachments,
									prds,
									userOptions,
									bEncrypt,
									bSign);

	}

	if(userOptions != NULL)
	{
		PGPFreeOptionList(userOptions);
	}

	if (prds)
	{
		if (prds->keydbSelected != NULL)
			PGPFreeKeyDB(prds->keydbSelected);

		PGPFreeKeyDB(prds->keydbOriginal);
		free(prds);
	}

	return ReturnValue;
}