📄 pgpkeyset.c
字号:
PGPKey * key;
PGPUInt32 count = 0;
PGPError err = kPGPError_NoErr;
PGPValidatePtr( numKeys );
*numKeys = 0;
PGPValidateKeySet( keys );
for (key = keys->keyDB->firstKeyInDB; key; key = key->nextKeyInDB)
{
pgpa(pgpaPGPKeyValid(key));
if (PGPKeySetIsMember(key, keys))
count++;
}
*numKeys = count;
return( err );
}
PGPError
PGPOrderKeySet(
PGPKeySet * keys,
PGPKeyOrdering order,
PGPKeyListRef * outRef )
{
PGPKeyList * list;
PGPKey * key;
PGPUInt32 count;
PGPUInt32 i;
PGPError err = kPGPError_NoErr;
PGPContextRef context = PGPGetKeySetContext( keys );
PGPValidatePtr( outRef );
*outRef = NULL;
PGPValidateKeySet( keys );
/* 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 = (PGPKey **)pgpContextMemAlloc( context,
count * sizeof(PGPKey *), kPGPMemoryMgrFlags_Clear);
if (list->keys == NULL)
{
pgpContextMemFree( context, list);
return kPGPError_OutOfMemory;
}
list->refCount = 1;
list->keySet = keys;
list->order = order;
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->nextKeyInDB)
{
pgpa(pgpaPGPKeyValid(key));
if (PGPKeySetIsMember( key, keys ))
{
pgpAssert(i < count);
list->keys[i++] = key;
}
}
pgpAssert(i == count);
sortKeyList(list);
*outRef = list;
return( err );
}
PGPError
PGPIncKeyListRefCount(PGPKeyList *list)
{
PGPValidateKeyList( list );
list->refCount++;
return( kPGPError_NoErr );
}
PGPError
PGPFreeKeyList(PGPKeyList *list)
{
PGPContextRef context = NULL;
PGPValidateKeyList( list );
context = PGPGetKeyListContext( 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 );
}
static PGPError
pgpGetKeyByKeyID(
PGPKeySetRef keys,
PGPKeyID const *keyIDIn,
PGPPublicKeyAlgorithm pubKeyAlgorithm,
PGPKeyRef * outRef )
{
PGPKeyDB * db;
RingSet const * ringSet;
long lo;
long hi;
long i;
PGPKey ** keyArray;
PGPKeyID keyIDABytes;
PGPKeyID keyIDBBytes;
PGPKeyID keyIDMasterBytes;
PGPKeyID keyIDBytes;
int comparison;
PGPError err = kPGPError_ItemNotFound;
PGPKeyRef resultKey = NULL;
PGPValidatePtr( outRef );
*outRef = NULL;
PGPValidateKeySet( keys );
PGPValidatePtr( keyIDIn );
PGPValidateParam( pubKeyAlgorithm == kPGPPublicKeyAlgorithm_Invalid ||
(pubKeyAlgorithm >= kPGPPublicKeyAlgorithm_First &&
pubKeyAlgorithm <= kPGPPublicKeyAlgorithm_Last ) );
keyIDBytes = *keyIDIn;
db = keys->keyDB;
ringSet = pgpKeyDBRingSet(db);
/* We may be called to match a subkey; if so replace keyid with master's */
if( pubKeyAlgorithm != kPGPPublicKeyAlgorithm_Invalid )
{
RingObject const *ringObj;
if( ((PGPKeyIDPriv *) keyIDIn)->length == 4 )
{
ringObj = ringKeyById4 (ringSet, (PGPByte)pubKeyAlgorithm,
pgpGetKeyBytes( &keyIDBytes ) );
}
else
{
ringObj = ringKeyById8 (ringSet, (PGPByte)pubKeyAlgorithm,
pgpGetKeyBytes( &keyIDBytes ) );
}
if( IsNull( ringObj ) )
return( kPGPError_ItemNotFound );
if( ringKeyIsSubkey( ringSet, ringObj ) )
{
/* It's a subkey, replace it with the master key */
ringObj = ringKeyMasterkey( ringSet, ringObj );
ringKeyID8( ringSet, ringObj, NULL, &keyIDMasterBytes );
keyIDBytes = keyIDMasterBytes;
}
}
if (db->keysByKeyID == NULL)
{
PGPKeySet * rootSet;
if ((rootSet = pgpKeyDBRootSet(db)) != NULL)
{
err = PGPOrderKeySet(rootSet, kPGPKeyIDOrdering, &db->keysByKeyID );
if ( IsPGPError( err ) )
return( err );
/* rootSet will stick around until the keylist is freed */
PGPFreeKeySet(rootSet);
/*
* Undo the additional refCount created by the existence of
* rootSet. Otherwise the keyDB will never be freed because
* of the cycle in the reference graph. When the keyDB is
* actually freed, if keysByKeyID exists, refCount will be
* incremented again before freeing keysByKeyID.
*/
if (db->keysByKeyID != NULL)
db->refCount--;
}
if (db->keysByKeyID == NULL)
return kPGPError_OutOfMemory;
}
pgpa((
pgpaPGPKeyListValid(db->keysByKeyID),
pgpaAssert(db->keysByKeyID->order == kPGPKeyIDOrdering)));
keyArray = db->keysByKeyID->keys;
keyIDABytes = keyIDBytes;
if( ((PGPKeyIDPriv *) keyIDIn)->length == 4 )
{
/*
** Search the list linearly in the 4-byte case because the list
** is sorted by the full 8-byute ID
*/
for( i = 0; i < db->keysByKeyID->keyCount; i++ )
{
PGPKeyRef key;
key = keyArray[ i ];
ringKeyID4( ringSet, key->key, NULL, &keyIDBBytes );
comparison = compareKeyIDs( &keyIDABytes, &keyIDBBytes);
if( comparison == 0 && PGPKeySetIsMember( key, keys) )
{
if( PGPKeyRefIsValid( resultKey ) )
{
/* Only one match allowed. Fail */
resultKey = kInvalidPGPKeyRef;
break;
}
else
{
resultKey = key;
}
}
}
}
else
{
lo = 0;
hi = db->keysByKeyID->keyCount;
while (lo < hi)
{
PGPKeyRef key;
i = (lo + hi) / 2;
key = keyArray[ i ];
ringKeyID8( ringSet, key->key, NULL, &keyIDBBytes );
comparison = compareKeyIDs( &keyIDABytes, &keyIDBBytes);
if (comparison > 0)
lo = i + 1;
else if (comparison < 0)
hi = i;
else if (PGPKeySetIsMember( keyArray[i], keys))
{
resultKey = keyArray[i];
break;
}
else
break;
}
}
if ( IsNull( resultKey ) )
{
err = kPGPError_ItemNotFound;
}
else
{
err = kPGPError_NoErr;
}
*outRef = resultKey;
pgpAssert( ( IsntPGPError( err ) && IsntNull( *outRef ) ) ||
( IsPGPError( err ) && IsNull( *outRef ) ));
return( err );
}
PGPError
PGPGetKeyByKeyID(
PGPKeySetRef keys,
PGPKeyID const * keyIDIn,
PGPPublicKeyAlgorithm pubKeyAlgorithm,
PGPKeyRef * outRef )
{
PGPError err = kPGPError_NoErr;
PGPValidatePtr( outRef );
*outRef = NULL;
PGPValidateKeySet( keys );
PGPValidatePtr( keyIDIn );
err = pgpGetKeyByKeyID( keys, keyIDIn, pubKeyAlgorithm, outRef );
if ( IsntPGPError( err ) )
{
pgpIncKeyRefCount( *outRef );
}
pgpAssertErrWithPtr( err, *outRef );
return( err );
}
PGPBoolean
pgpKeyDBIsValid( PGPKeyDB const * keyDB)
{
return( IsntNull( keyDB ) && keyDB->fixedMagic == kPGPKeyDBMagic );
}
PGPBoolean
pgpKeySetIsValid( PGPKeySet const * keySet)
{
return( IsntNull( keySet ) && keySet->magic == kPGPKeySetMagic );
}
PGPBoolean
pgpKeyListIsValid( PGPKeyList const * keyList)
{
return( IsntNull( keyList ) && keyList->magic == kPGPKeyListMagic );
}
PGPBoolean
pgpKeyIterIsValid( PGPKeyIter const * keyIter)
{
return( IsntNull( keyIter ) &&
keyIter->magic == kPGPKeyIterMagic );
}
PGPBoolean
pgpKeyIsValid( PGPKey const * key)
{
PGPBoolean isValid;
isValid = IsntNull( key ) &&
pgpOptionalMagicMatches( key, kPGPKeyMagic ) &&
key->refCount > 0 &&
pgpKeyDBIsValid( key->keyDB );
return( isValid );
}
PGPBoolean
pgpSubKeyIsValid(
PGPSubKey const * subKey)
{
PGPBoolean isValid;
isValid = IsntNull( subKey ) &&
pgpOptionalMagicMatches( subKey, kPGPSubKeyMagic ) &&
pgpKeyIsValid( subKey->key );
return( isValid );
}
PGPBoolean
pgpUserIDIsValid(
PGPUserID const * userID)
{
PGPBoolean isValid;
isValid = IsntNull( userID ) &&
pgpOptionalMagicMatches( userID, kPGPUserIDMagic ) &&
pgpKeyIsValid( userID->key );
return( isValid );
}
PGPBoolean
pgpSigIsValid(
PGPSig const * cert)
{
return( IsntNull( cert ) &&
pgpOptionalMagicMatches( cert, kPGPCertMagic ) );
}
#if PGP_DEBUG /* [ */
PGPBoolean
pgpaInternalPGPKeyDBValid(
pgpaCallPrefixDef,
PGPKeyDB const * keyDB,
char const * varName)
{
pgpaAddrValid(keyDB, PGPKeyDB);
pgpaFailIf(keyDB->refCount <= 0, (pgpaFmtPrefix, "refCount <= 0"));
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPGPKeyDBValid failed on %s (%p)", varName, keyDB));
return pgpaFailed;
}
PGPBoolean
pgpaInternalPGPKeySetValid(
pgpaCallPrefixDef,
PGPKeySet const * keySet,
char const * varName)
{
pgpaAddrValid(keySet, PGPKeySet);
pgpaFailIf(keySet->refCount <= 0, (pgpaFmtPrefix, "refCount <= 0"));
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPGPKeySetValid failed on %s (%p)", varName, keySet));
return pgpaFailed;
}
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;
}
PGPBoolean
pgpaInternalPGPKeyIterValid(
pgpaCallPrefixDef,
PGPKeyIter const * keyIter,
char const * varName)
{
pgpaAddrValid(keyIter, PGPKeyIter);
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPGPKeyIterValid failed on %s (%p)", varName, keyIter));
return pgpaFailed;
}
PGPBoolean
pgpaInternalPGPKeyValid(
pgpaCallPrefixDef,
PGPKey const * key,
char const * varName)
{
pgpaAddrValid(key, PGPKey);
pgpaFailIf(key->refCount <= 0, (pgpaFmtPrefix, "refCount <= 0"));
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPGPKeyValid failed on %s (%p)", varName, key));
return pgpaFailed;
}
PGPBoolean
pgpaInternalPGPSubKeyValid(
pgpaCallPrefixDef,
PGPSubKey const * subKey,
char const * varName)
{
pgpaAddrValid(subKey, PGPSubKey);
/* pgpaFailIf(subKey->refCount <= 0, (pgpaFmtPrefix, "refCount <= 0")); */
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPGPSubKeyValid failed on %s (%p)", varName, subKey));
return pgpaFailed;
}
PGPBoolean
pgpaInternalPGPUserIDValid(
pgpaCallPrefixDef,
PGPUserID const * userID,
char const * varName)
{
pgpaAddrValid(userID, PGPUserID);
/* pgpaFailIf(userID->refCount <= 0, (pgpaFmtPrefix, "refCount <= 0")); */
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPGPUserIDValid failed on %s (%p)", varName, userID));
return pgpaFailed;
}
PGPBoolean
pgpaInternalPGPCertValid(
pgpaCallPrefixDef,
PGPSig const * cert,
char const * varName)
{
pgpaAddrValid(cert, PGPSig);
/* pgpaFailIf(cert->refCount <= 0, (pgpaFmtPrefix, "refCount <= 0")); */
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPGPCertValid failed on %s (%p)", varName, cert));
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 + -