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

📄 pgpkeylib.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * pgpKeyLib.c -- Initialization and cleanup functions related to the
 * keydb library
 *
 * Copyright (C) 1996,1997 Pretty Good Privacy, Inc. All rights reserved.
 *
 * $Id: pgpKeyLib.c,v 1.41.2.8 1997/06/13 04:15:24 hal Exp $
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#if MACINTOSH
#include "MacStrings.h"
#include "MacFiles.h"
#endif

#include "pgpKeyDB.h"
#include "pgpDebug.h"
#include "pgpKDBint.h"
#include "pgpEnv.h"
#include "pgpFileNames.h"
#include "pgpFileRef.h"
#include "pgpRndPool.h"
#include "pgpRndSeed.h"

#if defined(_WIN32) && !defined(NODLL)

/* In Windows, the DllMain function is called when a process or
thread attaches to, or detaches from, the DLL. Other platforms
should call pgpLibInit() and pgpLibCleanup () directly. */

#include "windows.h"

BOOL WINAPI DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call) {
#if !DEBUG
/* Malloc/free fails in debug mode because app hasn't set up leak context */
	case DLL_PROCESS_ATTACH:
		return (pgpLibInit () == PGPERR_OK);
#endif
	case DLL_PROCESS_DETACH:
		if (pgpLibSetup > 1)
			pgpLibSetup = 1;		/* force final cleanup */
		pgpLibCleanup ();
		return 1;
	}
	return 1;
}
#endif


/* Global variables for PGP library */
RingPool *			pgpRingPool;	/* RingPool used for all keysets */
PgpEnv *			pgpEnv;			/* User specified configuration values */
Boolean				pgpPrefsChanged = FALSE;
Boolean				pgpRngSeeded;	 /* Found a good randseed.bin */
int					pgpLibSetup;	/* # calls to pgpLibInit - pgpLibCleanup */
PgpRandomContext *	pgpRng;			/* Random number generator */

#if MACINTOSH	/* [ */

	static PGPFileRef *
RandSeedFileRef(void)
{
	FSSpec			fsSpec;
	
	if (FindPGPPreferencesFolder(kOnSystemDisk, &fsSpec.vRefNum,
								&fsSpec.parID) != noErr)
		return NULL;
	
	CopyPString("\pPGP Random Seed", fsSpec.name);
	return pgpNewFileRefFromFSSpec(&fsSpec);
}

#else	/* ] MACINTOSH [ */

	static PGPFileRef *
RandSeedFileRef(void)
{
	char const *	fileName;
	
	fileName = pgpenvGetString(pgpEnv, PGPENV_RANDSEED, NULL, NULL);
	if (fileName == NULL)
		return NULL;
	
	return pgpNewFileRefFromFullPath(fileName);
}

#endif	/* ] MACINTOSH */

/*
 * Initialize the PGP KeyDB library. This should be called for any
 * function which the user might call first, ones which don't rely on
 * the previous existence of KeySets and such.
 *
 * This sets up a global PgpEnv and RingPool, and initializes the fields
 * of the PgpEnv from the preference database.
 */
PGPError
pgpLibInit(void)
{
	char const *randseed;	 	/* Name of randseed file */
	PGPFileRef *randSeedRef;	/* File reference to randseed file */
	FILE	*rs;			 	/* Handle to randseed file */
	PGPError	result;

	if (pgpLibSetup) {
		pgpLibSetup += 1;		 /* Allow nesting */
		/* Reload prefs on every init call unless we've changed the prefs */
		return pgpPrefsChanged ? PGPERR_OK : pgpLoadPrefs();
	}

	pgpEnv = pgpenvCreate();
	if (!pgpEnv)
		return PGPERR_NOMEM;
	pgpAssertAddrValid(pgpEnv, VoidAlign);

	/* Set pgpEnv defaults */

	/* Default verbosity level */
	pgpenvSetInt(pgpEnv, PGPENV_VERBOSE, 1, PGPENV_PRI_PRIVDEFAULT);

	/* Read info from preference file */
	result = pgpLoadPrefs();
	if (result != PGPERR_OK)
		return result;

	/* Figure out where randseed file is */
	randseed = pgpenvGetString (pgpEnv, PGPENV_RANDSEED, NULL, NULL);
	if (!randseed) {
		char *pubdir, *rseed;
		char const *pubring;
		pubring = pgpenvGetString (pgpEnv, PGPENV_PUBRING, NULL, NULL);
		pgpAssert (pubring && *pubring);
		pubdir = pgpFileNameDirectory (pubring);
		rseed = pgpFileNameBuild (pubdir, "randseed.bin", NULL);
		pgpenvSetString (pgpEnv, PGPENV_RANDSEED, rseed,
						PGPENV_PRI_PRIVDEFAULT);
		pgpFree (rseed);
		pgpFree (pubdir);
	}

	pgpRng = pgpRandomCreate ();
	if (!pgpRng) {
	pgpenvDestroy (pgpEnv);
		return PGPERR_NOMEM;
	}

	/* Read in the randseed file, set pgpRngSeeded if succeed */
	randSeedRef = RandSeedFileRef();
	rs = pgpFileRefStdIOOpen(randSeedRef, kPGPFileOpenReadWritePerm,
							kPGPFileTypeNone, NULL);
	pgpFreeFileRef(randSeedRef);
	if (rs) {
		result = pgpRandSeedRead (rs, NULL);
		pgpStdIOClose (rs);
	} else {
		result = PGPERR_RANDSEED_TOOSMALL;
	}
	pgpRngSeeded = (result == PGPERR_OK);

	pgpRingPool = ringPoolCreate(pgpEnv);
	if (!pgpRingPool) {
		pgpenvDestroy (pgpEnv);
		pgpRandomDestroy (pgpRng);
		return PGPERR_NOMEM;
	}
	pgpAssertAddrValid(pgpRingPool, VoidAlign);
	pgpLibSetup = 1;
	return PGPERR_OK;
}

/* This should be called by the application when it is through with the
 * Aurora library. It should also be called by the operating system if
 * possible when the application exits.
 * Calls to pgpLibInit and pgpLibCleanup can be paired. pgpLibCleanup will
 * output any changed prefs and update the random seed file any time it
 * is called, but only release resources on the last call.
 */
void
pgpLibCleanup(void)
{
	PGPFileRef *randSeedRef;	/* File reference to randseed file */
	FILE	*rs;			 	/* Handle to randseed file */
	
	/* If not open, just return */ 	
if (!pgpLibSetup)
		return;
	
	/* Decrement open count, if goes to zero close things */
	pgpLibSetup -= 1;
	
	pgpSavePrefs();
	
	if (pgpLibSetup)
		return;

	/* Update random data */
	pgpRandPoolKeystroke (0);	 /* Get current time into rand pool */

	/*
	* Don't write out randseed.bin if we didn't read one and haven't
	* accumulated significant entropy. Otherwise we might produce
	* weak session keys on future runs.
	*/
	if (pgpRngSeeded
		|| pgpRandPoolInflow() >= PGP_SEED_MIN_BYTES*8) {
		randSeedRef = RandSeedFileRef();
		rs = pgpFileRefStdIOOpen(randSeedRef, kPGPFileOpenStdWriteFlags,
								kPGPFileTypeRandomSeed, NULL);
		pgpFreeFileRef(randSeedRef);
		if (rs) {
			pgpRandSeedWrite (rs, NULL, NULL);
			pgpStdIOClose (rs);
		}
	}

	ringPoolDestroy (pgpRingPool);
	pgpenvDestroy (pgpEnv);
	pgpRandomDestroy (pgpRng);
	pgpRingPool = NULL;
	pgpEnv = NULL;
	pgpRng = NULL;
	pgpRngSeeded = FALSE;
	pgpLibSetup = FALSE;
}

PGPError
pgpGetKeyRingFileRefs(PGPFileRef **pubRef, PGPFileRef **privRef)
{
	PGPError		result = PGPERR_OK;

	if (privRef != NULL)
		*privRef = NULL;
	if (pubRef != NULL)
		*pubRef = NULL;

	if (privRef != NULL)
	{
		*privRef = pgpGetPrefFileRef(kPGPPrefPrivRingRef);
		if (*privRef == NULL)
			goto memError;
	}

	if (pubRef != NULL)
	{
		*pubRef = pgpGetPrefFileRef(kPGPPrefPubRingRef);
		if (*pubRef == NULL)
			goto memError;
	}
	return PGPERR_OK;
memError:
	result = PGPERR_NOMEM;
	if (privRef != NULL && *privRef != NULL)
	{
		pgpFreeFileRef(*privRef);
		*privRef = NULL;
	}
	if (pubRef != NULL && *pubRef != NULL)
	{
		pgpFreeFileRef(*pubRef);
		*pubRef = NULL;
	}
	return result;
}

/*
 * Open default keyrings for user, return keyset for it.
 * If isMutable is false, keyrings are read only.
 * If <errorPtr> is non-NULL, it is filled with an appropriate error code.
 */
PGPKeySet *
pgpOpenDefaultKeyRings(Boolean isMutable, PGPError *errorPtr)
{
	PGPFileRef *secFileRef = NULL;	/* File reference for secret keyring */
	PGPFileRef *pubFileRef = NULL;	/* File reference for public keyring */
	PGPKeySet	 *set = NULL;
	PGPError		errorVal = PGPERR_OK;

	pgpAssertMsg(pgpLibSetup > 0,
			"pgpOpenDefaultKeyRings: pgpLibInit hasn't been called");

	if (pgpGetKeyRingFileRefs(&pubFileRef, &secFileRef) != PGPERR_OK)
	{
		errorVal = PGPERR_NO_FILE;
		goto error;
	}
	set = pgpOpenKeyRingPair(isMutable, pubFileRef, secFileRef, &errorVal);
	
error:
	if (secFileRef != NULL)
		pgpFreeFileRef(secFileRef);
	if (pubFileRef != NULL)
		pgpFreeFileRef(pubFileRef);
	if (set != NULL && errorVal != PGPERR_OK)
	{
		pgpFreeKeySet(set);
		set = NULL;
	}
	if (errorPtr != NULL)
	{
		pgpAssertAddrValid(errorPtr, PGPError);
		*errorPtr = errorVal;
	}
	return set;
}

/*
 * Open the specified keyrings for user, return keyset for it.
 * If isMutable is false, keyrings are read only.
 * If <errorPtr> is non-NULL, it is filled with an appropriate error code.
 */
PGPKeySet *
pgpOpenKeyRingPair(Boolean isMutable, PGPFileRef *pubFileRef,
					PGPFileRef *secFileRef, PGPError *errorPtr)
{
	PGPKeyDB		*dbsec = NULL,		/* KeyDB for secret keyring */
					*dbpub = NULL,		/* KeyDB for public keyring */
					*dbunion = NULL;		/* KeyDB for union of both keyrings */
	PGPKeySet		*set = NULL;
	PGPError		errorVal = PGPERR_OK;

	pgpAssertMsg(pgpLibSetup > 0,
			"pgpOpenKeyRingPair: pgpLibInit hasn't been called");

	/* Create key databases for these files. Don't bother with keypool.
	Private keyring is not trusted (no trust packets) */
	if ((dbsec = pgpCreateFileKeyDB(secFileRef, 0, 1, isMutable,
								pgpRingPool, &errorVal)) == NULL)
		goto error;
	if ((dbpub = pgpCreateFileKeyDB(pubFileRef, 1, 0, isMutable,
								pgpRingPool, &errorVal)) == NULL)
		goto error;

	/* Create union database for these two files */
	if ((dbunion = pgpCreateUnionKeyDB(&errorVal)) == NULL)
		goto error;
	
	if ((errorVal = pgpUnionKeyDBAdd(dbunion, dbsec)) != PGPERR_OK)
		goto error;
	dbsec = NULL;	 /* dbunion now has responsibility for freeing dbsec */
	
	if ((errorVal = pgpUnionKeyDBAdd(dbunion, dbpub)) != PGPERR_OK)
		goto error;
	dbpub = NULL;	 /* dbunion now has responsibility for freeing dbsec */

	if ((errorVal = pgpBuildKeyPool(dbunion, 0)) != PGPERR_OK)
		goto error;

	if ((set = pgpKeyDBRootSet(dbunion)) == NULL)
	{
		errorVal = PGPERR_NOMEM;	/* XXX Improve error */
		goto error;

⌨️ 快捷键说明

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