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

📄 pgpkeylib.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	/* Make sure trust and validity info is correct. This also
	ensures the keyrings are rewritten if ringFileOpen set
		the RINGFILEF_TRUSTCHANGED or RINGFILEF_DIRTY flags. */
	if ((errorVal = pgpCommitKeyRingChanges(set)) != PGPERR_OK)
		goto error;
	errorVal = PGPERR_OK;
	
error:
	if (dbsec != NULL)
		pgpFreeKeyDB(dbsec);
	if (dbpub != NULL)
		pgpFreeKeyDB(dbpub);
	if (dbunion != NULL)
		pgpFreeKeyDB(dbunion);
	if (set != NULL && errorVal != PGPERR_OK)
	{
		pgpFreeKeySet(set);
		set = NULL;
	}
	if (errorPtr != NULL)
	{
		pgpAssertAddrValid(errorPtr, PGPError);
		*errorPtr = errorVal;
	}
	return set;
}

/*
 * Open a single specified keyring file for user, return keyset for it.
 * If isMutable is false, keyrings are read only.
 * If isTrusted is false, trust packets are ignored.
 * If <errorPtr> is non-NULL, it is filled with an appropriate error code.
 */
PGPKeySet *
pgpOpenKeyRing(Boolean isMutable, Boolean isPrivate, Boolean isTrusted,
				PGPFileRef *fileRef, PGPError *errorPtr)
{
	PGPKeyDB	*db = NULL;
	PGPKeySet	 *set = NULL;
	PGPError		errorVal = PGPERR_OK;

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

	/* Create a key databases for this file. Don't bother with keypool.
	Private keyring is not trusted (no trust packets) */
	if ((db = pgpCreateFileKeyDB(fileRef, isTrusted, isPrivate, isMutable,
								pgpRingPool, &errorVal)) == NULL)
		goto error;

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

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

	/* Make sure trust and validity info is correct. This also
	ensures the keyrings are rewritten if ringFileOpen set
		the RINGFILEF_TRUSTCHANGED or RINGFILEF_DIRTY flags. */
	if ((errorVal = pgpCommitKeyRingChanges(set)) != PGPERR_OK)
		goto error;
	errorVal = PGPERR_OK;
	
error:
	if (db != NULL)
		pgpFreeKeyDB(db);
	if (set != NULL && errorVal != PGPERR_OK)
	{
		pgpFreeKeySet(set);
		set = NULL;
	}
	if (errorPtr != NULL)
	{
		pgpAssertAddrValid(errorPtr, PGPError);
		*errorPtr = errorVal;
	}
	return set;
}

/* Add keys to a keyset from a dynamically allocated binary key buffer */
static PGPKeySet *
pgpImportKeyX (byte *buffer, size_t length)
{
	PGPKeyDB *kdb;
	PGPKeySet *set;
	PGPError	error;

	/* Create a file type KeyDB from the buffer */
	kdb = pgpCreateMemFileKeyDB (buffer, length, pgpRingPool, &error);
	if (!kdb) {
		pgpMemFree (buffer);
		return NULL;
	}
	error = pgpBuildKeyPool (kdb, 0);
	if (error) {
		pgpFreeKeyDB (kdb);
		return NULL;
	}

	set = pgpKeyDBRootSet (kdb);
	pgpFreeKeyDB (kdb);
	return set;
}


/* Open the specified keyfile and add to the existing KeySet */
PGPKeySet *
pgpImportKeyFile (PGPFileRef *fileRef)
{
	byte	*filebuf;
	size_t		filebuflen;
	PGPError	err;

	err = pgpDearmorKeyFile (pgpEnv, fileRef, &filebuf, &filebuflen);
	if (err)
		return NULL;
	return pgpImportKeyX (filebuf, filebuflen);
}

/* Add the data from the specified memory buffer to the existing KeySet */
PGPKeySet *
pgpImportKeyBuffer (byte *buffer, size_t length)
{
	byte	*filebuf;
	size_t		filebuflen;
	PGPError	err;

	err = pgpDearmorKeyBuffer (pgpEnv, buffer, length, &filebuf, &filebuflen);
	if (err)
		return NULL;
	return pgpImportKeyX (filebuf, filebuflen);
}


/*
* Filter function for extraction. Remove any secret objects.
* If addmrks is true, also add any message recovery key objects to
* the set. This will cause MRK's to be extracted with the keys
* that use them.
* XXX THIS DOES NOT YET WORK. There is no RingSet available in which
* to look for MRK's. The export functions typically are called with
* just a memory RingSet. We need to add versions which take an extra
* PGPKeySet to flag that MRK's should be looked for there.
*/
static RingSet *
filterPubRingSet (RingSet *rset, PGPKeySet *keys, Boolean addmrks)
{
	RingSet		*rsetnew;	/* Set of recipients */
	RingSet		*rkeyset;	/* Set of message recovery keys */
	RingIterator *riter;		/* Iterator over adding sets */
	int				level;

	if (!rset)
		return NULL;
	rkeyset = NULL;
	rsetnew = ringSetCreate (ringSetPool (rset));
	if (!rsetnew)
		return NULL;
	riter = ringIterCreate (rset);
	if (!riter) {
		ringSetDestroy (rsetnew);
		return NULL;
	}
		/*
		* Copy objects in PGPKeySet to rsetnew except secret objects.
		* At the same time, accumulate any message recovery keys into
		* rkeyset.
		*/
	while ((level = ringIterNextObjectAnywhere(riter)) > 0) {
		RingObject *obj = ringIterCurrentObject (riter, level);
		/* Skip secret objects and non-members */
		if (ringObjectType (obj) == RINGTYPE_SEC)
			continue;
		if (!(*keys->isMember)(keys, obj))
			continue;
		ringSetAddObject (rsetnew, obj);
		/* For key objects, look for message recovery keys */
		if (addmrks && ringObjectType (obj) == RINGTYPE_KEY) {
			RingObject	*rkey;		/* Recovery key */
			unsigned		nrkeys;		/* Number of recovery keys */
			if (ringKeyRecoveryKey (obj, rset, 0, NULL, &nrkeys, NULL)) {
				/* Add to special set for recovery keys */
				while (nrkeys-- > 0) {
					rkey = ringKeyRecoveryKey (obj, rset, nrkeys, NULL,
						NULL, NULL);
					pgpAssert (rkey);
					if (!rkeyset) {
						rkeyset = ringSetCreate (ringSetPool(rset));
						if (!rkeyset) {
							ringIterDestroy (riter);
							ringSetDestroy (rsetnew);
							return NULL;
						}
					}
					ringSetAddObjectChildren (rkeyset, rset, rkey);
				}
			}
		}
	}
	ringIterDestroy (riter);

	/* Last, merge rkeyset into rsetnew, also stripping secrets */
	if (rkeyset) {
		ringSetFreeze (rkeyset);
		riter = ringIterCreate (rkeyset);
		if (!riter) {
			ringSetDestroy (rkeyset);
			ringSetDestroy (rsetnew);
			return NULL;
		}
		/* Loop over rsetnew iterator, adding non-secret objects */
		while ((level = ringIterNextObjectAnywhere(riter)) > 0) {
			RingObject *obj = ringIterCurrentObject (riter, level);
			if (ringObjectType (obj) == RINGTYPE_SEC)
				continue;
			ringSetAddObject (rsetnew, obj);
		}
		ringIterDestroy (riter);
		ringSetDestroy (rkeyset);
	}

	/* Return new set in frozen form */
	ringSetFreeze (rsetnew);
	return rsetnew;
}


/*
* Extract all keys in the specified KeySet to the specified file. This
* version always ascii armors them.
* Only extracts public portions of keys.
*/
PGPError
pgpExportKeyFile (PGPKeySet *keys, PGPFileRef *fileRef)
{
	RingSet		*rset,
				*rsetpub;
	FILE		*fp;
	PGPError	error;

	fp = pgpFileRefStdIOOpen(fileRef, (kPGPFileOpenStdWriteFlags
										| kPGPFileOpenTextMode),
							kPGPFileTypeExportedKeys, &error);
	if (!fp)
		return error;
	rset = pgpKeyDBRingSet (keys->keyDB);
	rsetpub = filterPubRingSet (rset, keys, FALSE);
	if (!rsetpub) {
		pgpStdIOClose (fp);
		pgpDeleteFile(fileRef);
		return PGPERR_NOMEM;
	}
	error = (PGPError)pgpWriteArmoredSetFile (fp, rsetpub, pgpEnv);
	pgpStdIOClose (fp);
	ringSetDestroy (rsetpub);
	return error;
}


/*
* Extract all keys in the specified KeySet to the specified memory
* buffer, which is of size *length. Return number of bytes written
* in *length. This version always ascii armors the keys.
* Only extracts public portions of keys.
*/
PGPError
pgpExportKeyBuffer (PGPKeySet *keys, byte *buffer, size_t *length)
{
	RingSet	*rset,
			*rsetpub;
	PGPError	error;

	rset = pgpKeyDBRingSet (keys->keyDB);
	rsetpub = filterPubRingSet (rset, keys, FALSE);
	if (!rsetpub) {
		return PGPERR_NOMEM;
	}
	error = (PGPError) pgpWriteArmoredSetBuffer (buffer, length, rsetpub,
		pgpEnv);
	ringSetDestroy (rsetpub);
	return error;
}


#if defined(_WIN32)

#define SEMAPHORENAME	("PGPkeysInstSem")
static HANDLE hSem;

/*
* Return TRUE if we have the interlock semaphore, FALSE if someone else
* has it
*/
Boolean
pgpOpenSemaphore ()
{

	/* If already been called, return false */
	if (hSem)
		return FALSE;

/* Create or open a named semaphore */
hSem = CreateSemaphore (NULL, 0, 1, SEMAPHORENAME);

	/* If another instance exists, close handle and return false */
if ((hSem != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
	CloseHandle(hSem);
		hSem = (HANDLE)0;
	return FALSE;
}

/* If new semaphore was created, return TRUE. */
return TRUE;
}

/* Clear the semaphore which keeps others from running */
void
pgpCloseSemaphore ()
{
	if (!hSem)
		return;

	CloseHandle (hSem);
	hSem = (HANDLE)0;
}

#else

/*
* Return TRUE if we have the interlock semaphore, FALSE if someone else
* has it
*/
Boolean
pgpOpenSemaphore ()
{
	return TRUE;
}

/* Release the interlock semaphore */
void
pgpCloseSemaphore ()
{
}

#endif


/*
* Local Variables:
* tab-width: 4
* End:
* vi: ts=4 sw=4
* vim: si
*/

⌨️ 快捷键说明

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