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

📄 pgpkeylist.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
字号:
/*____________________________________________________________________________
        Copyright (C) 2002 PGP Corporation
        All rights reserved.

        PGPKeyList implementation

        $Id: pgpKeyList.c,v 1.16 2002/08/06 20:11:00 dallen Exp $
____________________________________________________________________________*/

#include "pgpConfig.h"

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

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

#include "pgpTypes.h"
#include "pgpDebug.h"
#include "pgpKeyPriv.h"
#include "pgpMem.h"
#include "pgpTimeDate.h"
#include "pgpUsuals.h"
#include "pgpMemPool.h"
#include "pgpContext.h"
#include "pgpOptionListPriv.h"



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

	pgpKeyID8( keyA, NULL, &rawA );
	pgpKeyID8( keyB, NULL, &rawB );

	result	= PGPCompareKeyIDs( &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)
{
	pgpEnterZeroFunction();

	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(*a))
			a++;
		while (*b && !isalnum(*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)
{
	PGPKeyDBObj *		keyA = *(PGPKeyDBObj **)a;
	PGPKeyDBObj *		keyB = *(PGPKeyDBObj **)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)PGPGetPrimaryUserIDName( keyA, nameA, sizeof( nameA ),
									&actualLength );
	(void)PGPGetPrimaryUserIDName( keyB, nameB, sizeof( 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)
{
	PGPKeyDBObj *		keyA = *(PGPKeyDBObj **)a;
	PGPKeyDBObj *		keyB = *(PGPKeyDBObj **)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)
{
	PGPKeyDBObj *		keyA = *(PGPKeyDBObj **)a;
	PGPKeyDBObj *		keyB = *(PGPKeyDBObj **)b;

	PGPInt32		trustA;
	PGPInt32		trustB;
	PGPError		result;
	
	result = pgpGetKeyNumber(keyA, kPGPKeyProperty_Trust, &trustA);
	pgpAssert(result == kPGPError_NoErr);
	result = pgpGetKeyNumber(keyB, kPGPKeyProperty_Trust, &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)
{
	PGPKeyDBObj *		keyA = *(PGPKeyDBObj **)a;
	PGPKeyDBObj *		keyB = *(PGPKeyDBObj **)b;
	PGPKeyDBObj *		subKeyA = NULL;
	PGPKeyDBObj *		subKeyB = NULL;

	PGPInt32			keySizeA;
	PGPInt32			keySizeB;
	PGPError			err;
	
	err = pgpGetFirstSubKey(keyA, &subKeyA);
	if ( IsntPGPError( err ) )
		err = pgpGetSubKeyNumber(subKeyA, kPGPSubKeyProperty_Bits, &keySizeA);
	else
		err = pgpGetKeyNumber(keyA, kPGPKeyProperty_Bits, &keySizeA);
	pgpAssertNoErr( err );

	err = pgpGetFirstSubKey(keyB, &subKeyB);
	if ( IsntPGPError( err ) )
		err = pgpGetSubKeyNumber(subKeyB, kPGPSubKeyProperty_Bits, &keySizeB);
	else
		err = pgpGetKeyNumber(keyB, kPGPKeyProperty_Bits, &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)
{
	PGPKeyDBObj *		keyA = *(PGPKeyDBObj **)a;
	PGPKeyDBObj *		keyB = *(PGPKeyDBObj **)b;

	PGPInt32		keySizeA;
	PGPInt32		keySizeB;
	PGPError		result;
	
	result = pgpGetKeyNumber(keyA, kPGPKeyProperty_Bits, &keySizeA);
	pgpAssert(result == kPGPError_NoErr);
	result = pgpGetKeyNumber(keyB, kPGPKeyProperty_Bits, &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)
{
	PGPKeyDBObj *		keyA = *(PGPKeyDBObj **)a;
	PGPKeyDBObj *		keyB = *(PGPKeyDBObj **)b;

	PGPTime			creationA;
	PGPTime			creationB;
	PGPError		result;
	
	result = pgpGetKeyTime(keyA, kPGPKeyProperty_Creation, &creationA);
	pgpAssert(result == kPGPError_NoErr);
	result = pgpGetKeyTime(keyB, kPGPKeyProperty_Creation, &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)
{
	PGPKeyDBObj *		keyA = *(PGPKeyDBObj **)a;
	PGPKeyDBObj *		keyB = *(PGPKeyDBObj **)b;

	PGPTime			expirationA;
	PGPTime			expirationB;
	PGPError		result;
	
	result = pgpGetKeyTime(keyA, kPGPKeyProperty_Expiration, &expirationA);
	pgpAssert(result == kPGPError_NoErr);
	result = pgpGetKeyTime(keyB, kPGPKeyProperty_Expiration, &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);
}

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

static const CompareFunc compareFunc[] = {
	NULL,
	NULL,
	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(PGPKeyDBObj *a, PGPKeyDBObj *b, PGPKeyOrdering order)
{
	pgpEnterZeroFunction();

	pgpa((
		pgpaPGPKeyValid(a),
		pgpaPGPKeyValid(b),
		pgpaAssert(order > 0 && (2*order) < sNumCompareFuncs
					&& order != kPGPKeyOrdering_Any)));

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

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

	if (list->order != kPGPKeyOrdering_Any)
		qsort(list->keys, list->keyCount, sizeof(list->keys[0]),
				compareFunc[2*list->order+list->reverse]);
}

#if 0
/*
 * 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, PGPKeyDBObj *key)
{
	long		lo;
	long		hi;
	long		i;
	int			result;
	int			(*compare)(void const *, void const *);

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

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

	compare = compareFunc[2*list->order+list->reverse];

	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;
}
#endif


	PGPError
PGPOrderKeySet(
	PGPKeySet *		keys,
	PGPKeyOrdering	order,
	PGPBoolean		reverse,
	PGPKeyListRef *	outRef )
{
	PGPKeyList *	list;
	PGPKeyDBObj *		key;
	PGPUInt32		count;
	PGPUInt32		i;
	PGPError		err	= kPGPError_NoErr;
	PGPContextRef	context	= PGPPeekKeySetContext( keys );
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateKeySet( keys );

	pgpEnterPGPErrorFunction();

/*	list = pgpNew(PGPKeyList); */
	list = (PGPKeyList *)pgpContextMemAlloc( context,
		sizeof(PGPKeyList), kPGPMemoryMgrFlags_Clear );
	if (list == NULL)
		return kPGPError_OutOfMemory;

	list->magic	= kPGPKeyListMagic;
	
	(void)PGPCountKeys(keys, &count );
	list->keyCount = count;
	list->keys = (PGPKeyDBObj **)pgpContextMemAlloc( context,
		count * sizeof(PGPKeyDBObj *), kPGPMemoryMgrFlags_Clear);
	if (list->keys == NULL)
	{
		pgpContextMemFree( context, list);
		return kPGPError_OutOfMemory;
	}
	
	list->refCount = 1;
	list->keySet = keys;
	list->order = order;
	list->reverse = reverse?1:0;
	list->prevListInSet = NULL;
	list->nextListInSet = keys->firstListInSet;

	if( IsntNull( list->nextListInSet ) )
		list->nextListInSet->prevListInSet = list;
		
	keys->firstListInSet = list;
	list->firstIterInList = NULL;

	PGPIncKeySetRefCount(keys);

	i = 0;
	for (key = keys->keyDB->firstKeyInDB; key; key = key->next)
	{
		pgpa(pgpaPGPKeyValid(key));
		if( !pgpKeyDBObjIsReal(key) )
			continue;
		if (pgpKeySetIsMember( key, keys ))
		{
			pgpAssert(i < count);
			list->keys[i++] = key;
		}
	}
	pgpAssert(i == count);

	sortKeyList(list);

	*outRef	= list;
	return( err );
}


/* Call this to recalculate the list contents */
	PGPError
pgpUpdateList(PGPKeyList *list)
{
	PGPKeySet *		keys;
	PGPKeyDBObj *	key;
	void *			vkeys;
	PGPUInt32		count;
	PGPUInt32		i;
	PGPError		err	= kPGPError_NoErr;
	PGPContextRef	context;
	
	PGPValidateKeyList( list );

	/* Pick up fields from list */
	keys = list->keySet;
	context	= PGPPeekKeySetContext( keys );

	/* Reallocate array */
	(void)PGPCountKeys(keys, &count );
	vkeys = (void *)list->keys;
	err = pgpContextMemRealloc( context, &vkeys,
				count * sizeof(PGPKeyDBObj *), kPGPMemoryMgrFlags_Clear);
	if (IsPGPError( err ))
		return err;
	
	list->keys = (PGPKeyDBObj **)vkeys;
	list->keyCount = count;

	i = 0;
	for (key = keys->keyDB->firstKeyInDB; key; key = key->next)
	{
		pgpa(pgpaPGPKeyValid(key));
		if( !pgpKeyDBObjIsReal(key) )
			continue;
		if (pgpKeySetIsMember( key, keys ))
		{
			pgpAssert(i < count);
			list->keys[i++] = key;
		}
	}
	pgpAssert(i == count);

	sortKeyList(list);

	return( err );
}



	PGPError
PGPIncKeyListRefCount(PGPKeyList *list)
{
	PGPValidateKeyList( list );

	pgpEnterPGPErrorFunction();

	list->refCount++;
	
	return( kPGPError_NoErr );
}

	PGPError
PGPFreeKeyList(PGPKeyList *list)
{
	PGPContextRef	context	= NULL;
	
	PGPValidateKeyList( list );
	
	pgpEnterPGPErrorFunction();

	context	= PGPPeekKeyListContext( list );

	list->refCount--;
	if (list->refCount <= 0)
	{
		list->magic	= ~ list->magic;	/* mark as invalid */
		
		if (list->prevListInSet)
			list->prevListInSet->nextListInSet = list->nextListInSet;
		else
			list->keySet->firstListInSet = list->nextListInSet;
		if (list->nextListInSet)
			list->nextListInSet->prevListInSet = list->prevListInSet;

		pgpAssert(list->firstIterInList == NULL);

		pgpContextMemFree( context, list->keys);
		PGPFreeKeySet(list->keySet);
		pgpContextMemFree( context, list);
	}
	return( kPGPError_NoErr );
}



	PGPBoolean
pgpKeyListIsValid( PGPKeyList const *	keyList)
{
	return( IsntNull( keyList ) && keyList->magic == kPGPKeyListMagic );
}



#if PGP_DEBUG	/* [ */
	PGPBoolean
pgpaInternalPGPKeyListValid(
	pgpaCallPrefixDef,
	PGPKeyList const *	keyList,
	char const *		varName)
{
	pgpaAddrValid(keyList, PGPKeyList);
	pgpaFailIf(keyList->refCount <= 0, (pgpaFmtPrefix, "refCount <= 0"));
	pgpaFmtMsg((pgpaFmtPrefix,
			"pgpaPGPKeyListValid failed on %s (%p)", varName, keyList));

	return pgpaFailed;
}



#endif /* ] PGP_DEBUG */

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

⌨️ 快捷键说明

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