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

📄 clcache.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1998 Network Associates, Inc.
	All rights reserved.
	
	CLcache.c - passphrase caching routines
	
	Passphrase caching is implemented as user convenience.
	The pgplib preferences control whether caching is 
	enabled and for how long.  The code in this file implements
	the passphrase cache by keeping a global counter and a
	global pointer variable to the phrase.  When the
	phrase is entered or accessed, the counter is set to the
	current timeout value specified by the library preferences.
	A separate thread is created which awakes every second and
	decrements the counter.  When the counter reaches zero, the
	cache (string) is wiped, the string freed and the thread 
	terminates. 

	The caller to PGPclGetCachedPhrase is responsible for freeing
	the returned string buffer with PGPFreePhrase.
	

	$Id: CLcache.c,v 1.8 1999/04/13 17:29:53 wjb Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"	

#include "pgpclx.h"
#include <process.h>

#define SCRAMBLERLENGTH		256
#define CACHECLOCKPERIOD	500				// in milliseconds

// typedefs
typedef struct {
	BOOL				bCacheActive;
	INT					iCacheCounter;
	LPSTR				pszCachedPassphrase;
	PGPUInt32			iCachedPassphraseLength;
	PGPByte*			pCachedPasskey;
	PGPUInt32			iCachedPasskeyLength;

	PGPByte				CachedKeyID[kPGPMaxExportedKeyIDSize];
	PGPInt32			CachedKeyAlg;
	PGPHashAlgorithm	CachedHashAlg;
	UINT				uCachedOptions;
} CACHE, *PCACHE;

static CACHE	cacheDecryption;
static CACHE	cacheSigning;

static CHAR		szScrambler[SCRAMBLERLENGTH];
static BOOL		bScramblerInitialized = FALSE;

CRITICAL_SECTION	criticalSectionCache;

//___________________________
//
// Memory allocation routines
//

static VOID* 
secAlloc (PGPContextRef context, UINT uBytes) 
{
	return (PGPNewSecureData (PGPGetContextMemoryMgr (context), uBytes, 0));
}


static VOID 
secFree (VOID* p) 
{
	PGPFreeData (p);
}


//_____________________________________________________
//

static VOID
sEmptyCache (PCACHE pcache)
{
	if (pcache->pszCachedPassphrase) 
	{
		secFree (pcache->pszCachedPassphrase);
		pcache->pszCachedPassphrase = NULL;
		pcache->iCachedPassphraseLength = 0;
	}

	if (pcache->pCachedPasskey) 
	{
		secFree (pcache->pCachedPasskey);

		pcache->pCachedPasskey = NULL;
		pcache->iCachedPasskeyLength = 0;
	}
	
	pgpClearMemory (pcache->CachedKeyID, kPGPMaxExportedKeyIDSize);
	pcache->CachedKeyAlg = 0;
	pcache->CachedHashAlg = 0;
	pcache->uCachedOptions = 0;
}

//_____________________________________________________
//

static VOID 
sSetCacheDuration (PCACHE pcache, UINT uSecs)
{
	pcache->iCacheCounter = (uSecs * 1000) / CACHECLOCKPERIOD;
}

//_____________________________________________________
//

static BOOL 
sIsCacheValid (PCACHE pcache)
{
	if (pcache->bCacheActive) {
		if (pcache->pszCachedPassphrase || 
			pcache->pCachedPasskey) 
		{
			return TRUE;
		}
	}

	return FALSE;
}

//_____________________________________________________
//

static VOID 
sScrambleCache (PCACHE pcache)
{
	INT i;
	INT iLen;

	iLen = lstrlen (pcache->pszCachedPassphrase);
	pcache->iCachedPassphraseLength = iLen;
	for (i=0; i<iLen; i++) 
		pcache->pszCachedPassphrase[i] ^= szScrambler[i%SCRAMBLERLENGTH];

	iLen = pcache->iCachedPasskeyLength;
	for (i=0; i<iLen; i++) 
		pcache->pCachedPasskey[i] ^= szScrambler[i%SCRAMBLERLENGTH];
}


//_____________________________________________________
//

static PGPError 
sCopyCache (
		PCACHE			pcache,
		PGPContextRef	context,
		LPSTR*			pszPassphraseBuffer,
		PGPByte**		ppPasskeyBuffer,
		PGPUInt32*		piPasskeyLength)
{
	PGPError	err		= kPGPError_NoErr;
	INT			i;
	INT			iLen;

	if ((pcache->pCachedPasskey) && (ppPasskeyBuffer)) 
	{
		iLen = pcache->iCachedPasskeyLength;
		*ppPasskeyBuffer = secAlloc (context, iLen);

		if(*ppPasskeyBuffer) {
			for (i=0; i<iLen; i++) 
			{
				(*ppPasskeyBuffer)[i] = 
						pcache->pCachedPasskey[i] ^ 
							szScrambler[i%SCRAMBLERLENGTH];
			}
			*piPasskeyLength = iLen;
		}
		else 
			err = kPGPError_OutOfMemory;
	}

	if ((pcache->pszCachedPassphrase) && (pszPassphraseBuffer)) 
	{
		iLen = pcache->iCachedPassphraseLength;
		*pszPassphraseBuffer = secAlloc (context, iLen+1);

		if (*pszPassphraseBuffer) 
		{
			for (i=0; i<iLen; i++) 
			{
				(*pszPassphraseBuffer)[i] = 
						pcache->pszCachedPassphrase[i] ^ 
							szScrambler[i%SCRAMBLERLENGTH];
			}
			(*pszPassphraseBuffer)[iLen] = '\0';
		}
		else
			err = kPGPError_OutOfMemory;
	}

	return err;
}


//_____________________________________________________
//
//  thread to clear cache after delay period
//	This routine is executed as a separate thread.  The
//	routine wakes up every second and decrements the
//	counter.  Whenthe counter reaches zero, the cache 
//	is purged and the flag is set to indicate cache is 
//	not active.

static VOID
sClearDecryptionCacheThread (PVOID pvoid) 
{
	while (cacheDecryption.iCacheCounter > 0) {
		Sleep (CACHECLOCKPERIOD);
		cacheDecryption.iCacheCounter--;
	}

	EnterCriticalSection (&criticalSectionCache);

	sEmptyCache (&cacheDecryption);
	cacheDecryption.bCacheActive = FALSE;

	LeaveCriticalSection (&criticalSectionCache);
}

	
//_____________________________________________________
//
//  thread to clear signing cache after delay period
//	This routine is executed as a separate thread.  The
//	routine wakes up every second and decrements the
//	counter.  Whenthe counter reaches zero, the cache 
//	is purged and the flag is set to indicate cache is 
//	not active.

static VOID 
sClearSigningCacheThread (PVOID pvoid) 
{
	while (cacheSigning.iCacheCounter > 0) {
		Sleep (CACHECLOCKPERIOD);
		cacheSigning.iCacheCounter--;
	}

	EnterCriticalSection (&criticalSectionCache);

	sEmptyCache (&cacheSigning);
	cacheSigning.bCacheActive = FALSE;

	LeaveCriticalSection (&criticalSectionCache);
}

	
//_____________________________________________________
//
//	PGPGetCachedDecryptionPhrase
//	This routine is called to get either cached phrase 
//	(if available) or prompt user for phrase.
//
//

PGPError PGPclExport
PGPclGetCachedDecryptionPhrase (
		PGPContextRef		context, 
		PGPtlsContextRef	tlsContext,
		PGPKeySetRef		keysetMain,
		HWND				hwnd, 
		LPSTR				szPrompt, 
		BOOL				bForceUserInput,
		LPSTR*				pszBuffer,
		PGPKeySetRef		keysetEncryptedTo,
		PGPKeyID*			pkeyidEncryptedTo,
		UINT				uKeyIDCount,
		PGPByte**			ppPasskeyBuffer,
		PGPUInt32*			piPasskeyLength,
		PGPKeySetRef*		pkeysetAdded,
		char *				szTitle) 
{
	PGPBoolean		bCacheEnabled		= FALSE;
	PGPUInt32		uCacheSecs			= 0;
	PGPError		err					= kPGPError_NoErr;

	DWORD			dw;
	PGPPrefRef		prefref;

	// Get needed preferences
	err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (context), &prefref);
	if (IsntPGPError (err))
	{
		PGPGetPrefBoolean (prefref, 
							kPGPPrefDecryptCacheEnable, &bCacheEnabled);
		PGPGetPrefNumber (prefref, 
							kPGPPrefDecryptCacheSeconds, &uCacheSecs);
		PGPclCloseClientPrefs (prefref, FALSE);
	}

	EnterCriticalSection (&criticalSectionCache);

	// use phrase from cache
	if (!bForceUserInput && 
		bCacheEnabled && 
		sIsCacheValid (&cacheDecryption))
	{
		// copy passphrase/passkey to caller's buffers
		err = sCopyCache (&cacheDecryption, context, pszBuffer, 
									ppPasskeyBuffer, piPasskeyLength);
		// reset cache duration
		sSetCacheDuration (&cacheDecryption, uCacheSecs);
	}

	// cache is disabled or empty, get phrase from user
	else 
	{
		sEmptyCache (&cacheDecryption);

		err = PGPclGetPhrase (context, keysetMain, hwnd, szPrompt, 
								&cacheDecryption.pszCachedPassphrase, 
								keysetEncryptedTo, 
								pkeyidEncryptedTo, uKeyIDCount,
								NULL, NULL, PGPCL_DECRYPTION,
								&cacheDecryption.pCachedPasskey,
								&cacheDecryption.iCachedPasskeyLength,
								0, 0, tlsContext, pkeysetAdded,szTitle);

		// user entered phrase -- setup cache
		if ((IsntPGPError (err)) && 
			(cacheDecryption.pszCachedPassphrase || 
							cacheDecryption.pCachedPasskey)) 
		{
			// scramble cache contents
			sScrambleCache (&cacheDecryption);

			// copy data to caller's buffers
			err = sCopyCache (&cacheDecryption, context, pszBuffer, 
										ppPasskeyBuffer, piPasskeyLength);

			if (bCacheEnabled) {
				// set cache duration

⌨️ 快捷键说明

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