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

📄 pgpkeyset.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * PGPKeySet implementation
 *
 * Copyright (C) 1996,1997 Network Associates Inc. and affiliated companies.
 * All rights reserved
 *
 * $Id: pgpKeySet.c,v 1.89.8.1 1999/06/04 00:28:55 heller Exp $
 */

#include "pgpConfig.h"

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <string.h>
#include <ctype.h>

#include "pgpKDBInt.h"
#include "pgpTypes.h"
#include "pgpDebug.h"
#include "pgpMem.h"
#include "pgpTimeDate.h"
#include "pgpUsuals.h"
#include "pgpMemPool.h"
#include "pgpRngMnt.h"
#include "pgpRngPub.h"
#include "pgpContext.h"
#include "pgpKeyIDPriv.h"
#include "pgpOptionListPriv.h"


	static void
sGetKeyID(
	PGPKeyRef	key,
	PGPKeyID *	keyID )
{
	RingSet const *	ringset;
	
	ringset	= pgpKeyDBRingSet (key->keyDB);
	
	ringKeyID8( ringset, key->key, NULL, keyID );
}

/* XXX Assumes that keyIDs are 8 bytes long */
	static int
compareKeyIDs(
	PGPKeyID const *	keyIDA,
	PGPKeyID const *	keyIDB)
{
#if 0
	int				i;
	for (i = 4; i < 8; i++)
	{
		if (keyIDA->bytes[i] > keyIDB->bytes[i])
			return 1;
		else if (keyIDA->bytes[i] < keyIDB->bytes[i])
			return -1;
	}
	for (i = 0; i < 4; i++)
	{
		if (keyIDA->bytes[i] > keyIDB->bytes[i])
			return 1;
		else if (keyIDA->bytes[i] < keyIDB->bytes[i])
			return -1;
	}
	return 0;
#else
	return( PGPCompareKeyIDs( keyIDA, keyIDB ) );
#endif
}

	static int
keyCompareByKeyID(void const *a, void const *b)
{
	PGPKey *	keyA = *(PGPKey **)a;
	PGPKey *	keyB = *(PGPKey **)b;
	
	PGPKeyID	rawA;
	PGPKeyID	rawB;
	
	int			result	= 1;

	sGetKeyID( keyA, &rawA );
	sGetKeyID( keyB, &rawB );

	result	= compareKeyIDs( &rawA, &rawB);
	
	return( result );
}

	static int
keyCompareByReverseKeyID(void const *a, void const *b)
{
	return -keyCompareByKeyID(a, b);
}

	PGPInt32
PGPCompareUserIDStrings(char const *a, char const *b)
{
	pgpAssert( IsntNull( a ) );
	pgpAssert( IsntNull( b ) );
	
	if ( IsNull( a ) || IsNull( b ) )
		return( 0 );
		
		
	for (;;)
	{
		while (*a && tolower(*a) == tolower(*b))
			a++, b++;
		while (*a && !isalnum((int) (*a)))
			a++;
		while (*b && !isalnum((int) (*b)))
			b++;
		if (!*a || tolower(*a) != tolower(*b))
			break;
		a++;
		b++;
	}
	return (uchar)tolower(*a) - (uchar)tolower(*b);
}

	static int
keyCompareByUserID(void const *a, void const *b)
{
	PGPKeyRef		keyA = *(PGPKey **)a;
	PGPKeyRef		keyB = *(PGPKey **)b;

	char			nameA[ kPGPMaxUserIDSize ];
	char			nameB[ kPGPMaxUserIDSize ];
	int				compareResult	= 0;
	PGPSize			actualLength;
	
	/* if we get an error, it's OK; we'll just end up comparing the first
		256 bytes */
	(void)PGPGetPrimaryUserIDNameBuffer( keyA,
		sizeof( nameA ), nameA, &actualLength );
	(void)PGPGetPrimaryUserIDNameBuffer( keyB,
			sizeof( nameB ), nameB, &actualLength );
			
	compareResult = PGPCompareUserIDStrings(nameA, nameB);
	
	if ( compareResult == 0 )
		compareResult	= keyCompareByKeyID(a, b);
		
	return compareResult;
}

	static int
keyCompareByReverseUserID(void const *a, void const *b)
{
	return -keyCompareByUserID(a, b);
}

	static int
keyCompareByValidity(void const *a, void const *b)
{
	PGPKey *		keyA = *(PGPKey **)a;
	PGPKey *		keyB = *(PGPKey **)b;

	PGPValidity		validityA;
	PGPValidity		validityB;
	PGPError		result;
	
	result = PGPGetPrimaryUserIDValidity(keyA, &validityA);
	pgpAssert(result == kPGPError_NoErr);
	result = PGPGetPrimaryUserIDValidity(keyB, &validityB);
	pgpAssert(result == kPGPError_NoErr);

	if (validityA < validityB)
		return 1;
	else if (validityA > validityB)
		return -1;
	else
		return keyCompareByKeyID(a, b);
}

	static int
keyCompareByReverseValidity(void const *a, void const *b)
{
	return -keyCompareByValidity(a, b);
}

	static int
keyCompareByTrust(void const *a, void const *b)
{
	PGPKey *		keyA = *(PGPKey **)a;
	PGPKey *		keyB = *(PGPKey **)b;

	PGPInt32		trustA;
	PGPInt32		trustB;
	PGPError		result;
	
	result = PGPGetKeyNumber(keyA, kPGPKeyPropTrust, &trustA);
	pgpAssert(result == kPGPError_NoErr);
	result = PGPGetKeyNumber(keyB, kPGPKeyPropTrust, &trustB);
	pgpAssert(result == kPGPError_NoErr);

	if (trustA < trustB)
		return 1;
	else if (trustA > trustB)
		return -1;
	else
		return keyCompareByKeyID(a, b);
}

	static int
keyCompareByReverseTrust(void const *a, void const *b)
{
	return -keyCompareByTrust(a, b);
}

	static int
keyCompareByEncryptKeySize(void const *a, void const *b)
{
	PGPKey *		keyA = *(PGPKey **)a;
	PGPKey *		keyB = *(PGPKey **)b;
	PGPSubKey *		subKeyA = NULL;
	PGPSubKey *		subKeyB = NULL;

	PGPInt32		keySizeA;
	PGPInt32		keySizeB;
	PGPError		err;
	
	err = pgpGetFirstSubKey(keyA, &subKeyA);
	if ( IsntPGPError( err ) )
		err = PGPGetSubKeyNumber(subKeyA, kPGPKeyPropBits, &keySizeA);
	else
		err = PGPGetKeyNumber(keyA, kPGPKeyPropBits, &keySizeA);
	pgpAssertNoErr( err );

	err = pgpGetFirstSubKey(keyB, &subKeyB);
	if ( IsntPGPError( err ) )
		err = PGPGetSubKeyNumber(subKeyB, kPGPKeyPropBits, &keySizeB);
	else
		err = PGPGetKeyNumber(keyB, kPGPKeyPropBits, &keySizeB);
	pgpAssertNoErr( err );
	
	if (keySizeA < keySizeB)
		return 1;
	else if (keySizeA > keySizeB)
		return -1;

	return keyCompareByKeyID(a, b);
}

	static int
keyCompareByReverseEncryptKeySize(void const *a, void const *b)
{
	return -keyCompareByEncryptKeySize(a, b);
}

	static int
keyCompareBySigKeySize(void const *a, void const *b)
{
	PGPKey *		keyA = *(PGPKey **)a;
	PGPKey *		keyB = *(PGPKey **)b;

	PGPInt32		keySizeA;
	PGPInt32		keySizeB;
	PGPError		result;
	
	result = PGPGetKeyNumber(keyA, kPGPKeyPropBits, &keySizeA);
	pgpAssert(result == kPGPError_NoErr);
	result = PGPGetKeyNumber(keyB, kPGPKeyPropBits, &keySizeB);
	pgpAssert(result == kPGPError_NoErr);

	if (keySizeA < keySizeB)
		return 1;
	else if (keySizeA > keySizeB)
		return -1;
	else
		return keyCompareByKeyID(a, b);
}

	static int
keyCompareByReverseSigKeySize(void const *a, void const *b)
{
	return -keyCompareBySigKeySize(a, b);
}

	static int
keyCompareByCreation(void const *a, void const *b)
{
	PGPKey *		keyA = *(PGPKey **)a;
	PGPKey *		keyB = *(PGPKey **)b;

	PGPTime			creationA;
	PGPTime			creationB;
	PGPError		result;
	
	result = PGPGetKeyTime(keyA, kPGPKeyPropCreation, &creationA);
	pgpAssert(result == kPGPError_NoErr);
	result = PGPGetKeyTime(keyB, kPGPKeyPropCreation, &creationB);
	pgpAssert(result == kPGPError_NoErr);

	if (creationA < creationB)
		return 1;
	else if (creationA > creationB)
		return -1;
	else
		return keyCompareByKeyID(a, b);
}

	static int
keyCompareByReverseCreation(void const *a, void const *b)
{
	return -keyCompareByCreation(a, b);
}

	static int
keyCompareByExpiration(void const *a, void const *b)
{
	PGPKey *		keyA = *(PGPKey **)a;
	PGPKey *		keyB = *(PGPKey **)b;

	PGPTime			expirationA;
	PGPTime			expirationB;
	PGPError		result;
	
	result = PGPGetKeyTime(keyA, kPGPKeyPropExpiration, &expirationA);
	pgpAssert(result == kPGPError_NoErr);
	result = PGPGetKeyTime(keyB, kPGPKeyPropExpiration, &expirationB);
	pgpAssert(result == kPGPError_NoErr);

	if (expirationA == expirationB)
		return keyCompareByKeyID(a, b);
	else if (expirationA == kPGPExpirationTime_Never)
		return -1;
	else if (expirationB == kPGPExpirationTime_Never)
		return 1;
	else if (expirationA < expirationB)
		return 1;
	else	/* expirationA > expirationB */
		return -1;
}

	static int
keyCompareByReverseExpiration(void const *a, void const *b)
{
	return -keyCompareByExpiration(a, b);
}

/*
 * The compare functions must all return non-ambiguous answers (>0,<0)
 * because the add-key functionality uses a binary search to install
 * new keys.  If things are ambiguous then the order can change if some
 * keys are tied under the main search.  This is accomplished by doing
 * a secondary search on keyid if there is a tie on the main search
 * field.
 */

typedef int (*CompareFunc)(void const *, void const *);

static const CompareFunc compareFunc[] = {
	NULL,
	NULL,
	keyCompareByUserID,
	keyCompareByReverseUserID,
	keyCompareByKeyID,
	keyCompareByReverseKeyID,
	keyCompareByValidity,
	keyCompareByReverseValidity,
	keyCompareByTrust,
	keyCompareByReverseTrust,
	keyCompareByEncryptKeySize,
	keyCompareByReverseEncryptKeySize,
	keyCompareBySigKeySize,
	keyCompareByReverseSigKeySize,
	keyCompareByCreation,
	keyCompareByReverseCreation,
	keyCompareByExpiration,
	keyCompareByReverseExpiration };
/* #if PGP_DEBUG */
static PGPKeyOrdering sNumCompareFuncs = (PGPKeyOrdering)
		(sizeof(compareFunc) /  sizeof(compareFunc[0]));
/* #endif */

	PGPInt32
PGPCompareKeys(PGPKey *a, PGPKey *b, PGPKeyOrdering order)
{
	pgpa((
		pgpaPGPKeyValid(a),
		pgpaPGPKeyValid(b),
		pgpaAssert(order > 0 && order < sNumCompareFuncs
					&& order != kPGPAnyOrdering)));

	if ( ! ( pgpKeyIsValid( a ) && pgpKeyIsValid( b ) ) )
		return( 0 );
		
	return (*compareFunc[order])(&a, &b);
}

	static void
sortKeyList(PGPKeyList *list)
{
	pgpa((
		pgpaPGPKeyListValid(list),
		pgpaAssert(list->order > 0 && list->order < sNumCompareFuncs)));

	if (list->order != kPGPAnyOrdering)
		qsort(list->keys, list->keyCount, sizeof(list->keys[0]),
				compareFunc[list->order]);
}

/*
 * Keep in mind that the comparison functions are not guaranteed to
 * be total orderings, and so even if an element of the list has a
 * perfect match with <key>, the index returned might not contain a
 * perfect match.
 */
	static long
binarySearchKeyList(PGPKeyList *list, PGPKey *key)
{
	long		lo;
	long		hi;
	long		i;
	int			result;
	int			(*compare)(void const *, void const *);

	pgpa((
		pgpaPGPKeyListValid(list),
		pgpaPGPKeyValid(key),
		pgpaAssert(list->order > 0 && list->order < sNumCompareFuncs)));

	if (list->order == kPGPAnyOrdering)
		return list->keyCount;

	compare = compareFunc[list->order];

	lo = 0;
	hi = list->keyCount;

	while (lo < hi)
	{
		i = (lo + hi) / 2;
		result = (*compare)(&key, &list->keys[i]);
		if (result > 0)
			lo = i + 1;
		else if (result < 0)
			hi = i;
		else
			return i;
	}
	return lo;
}

/*
 * WARNING: This dependency reference counting scheme breaks down
 *   in the case of cyclical dependencies.  For instance, if you have
 *   two KeyDBs which both add keys to each other, then neither KeyDB
 *   will ever be deallocated because they have each incremented the
 *   other's refCount.  We check below for cycles involving just two
 *   KeyDBs, but cycles larger than that will cause a leak.  This will
 *   be fixed in a future implementation.
 */
	static PGPError
pgpKeyDBAddDependency(PGPKeyDB *db, PGPKeyDB *dependency)
{
	PGPError	result	= kPGPError_NoErr;
	long		i;

	if (db == dependency)
		return kPGPError_NoErr;
	for (i = 0; i < db->numKeyDBDependencies; i++)
		if (db->keyDBDependencies[i] == dependency)
			return kPGPError_NoErr;

#if PGP_DEBUG
	/* Check for cycles involving two KeyDBs */
	for (i = 0; i < dependency->numKeyDBDependencies; i++)
		pgpAssert(dependency->keyDBDependencies[i] != db);
#endif

	if (db->numKeyDBDependencies >= db->numKeyDBDependenciesAllocated)
	{
		result = pgpContextMemRealloc( pgpGetKeyDBContext( db ),
							(void **)&db->keyDBDependencies,
							db->numKeyDBDependenciesAllocated * 2
									* sizeof(PGPKeyDB *),
							0 );
		if (IsPGPError(result))
			return result;

		db->numKeyDBDependenciesAllocated *= 2;
	}
	db->keyDBDependencies[db->numKeyDBDependencies++] = dependency;
	pgpIncKeyDBRefCount(dependency);
	return kPGPError_NoErr;
}

	static void
pgpKeyDBReleaseDependencies(PGPKeyDB *db)
{
	long		i;

	for (i = 0; i < db->numKeyDBDependencies; i++)
		pgpFreeKeyDB(db->keyDBDependencies[i]);
	db->numKeyDBDependencies = 0;
}


/* Creates a new empty key database */
	PGPKeyDB *
pgpKeyDBCreateInternal(PGPContextRef context)
{
	PGPKeyDB *	db;

	db = (PGPKeyDB *)pgpContextMemAlloc( context,
		sizeof(PGPKeyDB), kPGPMemoryMgrFlags_Clear);
	if (db == NULL)
		return NULL;

	db->priv = NULL;
	db->refCount = 1;
	db->firstSetInDB = NULL;
	db->context = context;

	db->numKeyDBDependenciesAllocated = 4;
	db->keyDBDependencies = (PGPKeyDB **)pgpContextMemAlloc( context,
								db->numKeyDBDependenciesAllocated
										* sizeof(PGPKeyDB *),
								0 );
	if (db->keyDBDependencies == NULL)

⌨️ 快捷键说明

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