📄 pgpkeyset.c
字号:
/*
* 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 + -