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

📄 pgpkeyset.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 2 页
字号:

error:
	if( IsntNull(iter) )
		PGPFreeKeyIter (iter);
	if( IsntNull(newset) )
		PGPFreeKeySet (newset);
		
	return err;
}


/* Add all the objects in the first key set into the second keydb. */
	PGPError
PGPCopyKeys (
	PGPKeySetRef	keysToAdd,
	PGPKeyDBRef		destdb,
	PGPKeySetRef	*destKeySet )
{
	if( IsntNull( destKeySet ) )
		*destKeySet = kInvalidPGPKeySetRef;
		
	PGPValidateKeyDB( destdb );
	PGPValidateKeySet( keysToAdd );

	pgpEnterPGPErrorFunction();

	return pgpCopyKeys_internal( keysToAdd, destdb, destKeySet );
}


/* Like PGPCopyKeys, but just one key */
	PGPError
PGPCopyKeyDBObj (
	PGPKeyDBObjRef	obj,
	PGPKeyDBRef		keydb,
	PGPKeyDBObjRef	*destObj)
{
	PGPKeySetRef	oneset;
	PGPKeySetRef	newset;
	PGPError		err	= kPGPError_NoErr;

	if( IsntNull( destObj ) )
		*destObj = kInvalidPGPKeyDBObjRef;
		
	PGPValidateKeyDBObj( obj );
	PGPValidateKeyDB( keydb );

	pgpEnterPGPErrorFunction();

	err = PGPNewOneKeySet( obj, &oneset );
	if( IsPGPError( err ) )
		return err;
	err = PGPCopyKeys( oneset, keydb, (IsntNull(destObj)?&newset:NULL) );
	PGPFreeKeySet( oneset );

	if( IsntPGPError(err) && IsntNull( destObj ) )
	{
		*destObj = pgpFirstKeyInKeySet( newset );
		PGPFreeKeySet( newset );
	}

	return err;
}



/* Remove all objects in the set from its keydb */
	PGPError
PGPDeleteKeys (
	PGPKeySetRef	keysToRemove)
{
	PGPKeyIter			*iter = NULL;
	PGPKeyDB			*db;
	PGPKeyDBObj			*obj;
	PGPError			err = kPGPError_NoErr;

	PGPValidateKeySet( keysToRemove );

	pgpEnterPGPErrorFunction();

	db = PGPPeekKeySetKeyDB( keysToRemove );

	err = PGPNewKeyIterFromKeySet( keysToRemove, &iter );
	if ( IsPGPError( err ) )
		goto error;

	while( IsntPGPError( pgpKeyIterNextObject( iter, &obj ) ) ) {
		/* May have been deleted when parent was */
		if( !pgpKeyDBObjIsDeleted( obj ) )
		{
			err = pgpKeyDBRemoveObject( db, obj );
			if ( IsPGPError( err ) )
				goto error;
		}
	}

	pgpKeyDBChanged( db, TRUE );
	PGPFreeKeyIter( iter );
	iter = NULL;

error:
	if (iter)
		PGPFreeKeyIter (iter);
	return err;
}

	PGPError
pgpFreeKeySet(PGPKeySet *keys, PGPBoolean bForce)
{

	/* Root set doesn't get refcounted */
	if( keys->keyDB->rootSet != keys )
		keys->refCount--;

	if (keys->refCount <= 0  ||  bForce)
	{
		(*keys->destroy)(keys);
		keys->magic	= ~keys->magic;	/* mark as invalid */
		
		if (keys->prevSetInDB)
			keys->prevSetInDB->nextSetInDB = keys->nextSetInDB;
		else
			keys->keyDB->firstSetInDB = keys->nextSetInDB;
		if (keys->nextSetInDB)
			keys->nextSetInDB->prevSetInDB = keys->prevSetInDB;

		pgpAssert(keys->firstListInSet == NULL);

		PGPFreeData( keys);
	}
	
	return( kPGPError_NoErr );
}

	PGPError
PGPFreeKeySet(PGPKeySet *keys)
{
	PGPValidateKeySet( keys );
	
	pgpEnterPGPErrorFunction();

	return pgpFreeKeySet( keys, FALSE );
}



	PGPError
PGPCountKeys(
	PGPKeySetRef	keys,
	PGPUInt32 *		numKeys )
{
	PGPKeyDBObj *		key;
	PGPUInt32		count = 0;
	PGPError		err	= kPGPError_NoErr;
	
	PGPValidatePtr( numKeys );
	*numKeys	= 0;
	PGPValidateKeySet( keys );

	pgpEnterPGPErrorFunction();

	for (key = keys->keyDB->firstKeyInDB; key; key = key->next)
	{
		pgpa(pgpaPGPKeyValid(key));
		if (pgpKeySetIsMember(key, keys))
			count++;
	}
	
	*numKeys = count;

	return( err );
}


	PGPBoolean
pgpKeySetIsEmpty(
	PGPKeySetRef	keys )
{
	pgpa(pgpaPGPKeySetValid(keys));
	return keys->isEmpty( keys );
}

	PGPKeyDBObj *
pgpFirstKeyInKeySet( PGPKeySet const * keySet )
{
	PGPKeyDBObj *	key;
	PGPKeyDB *		kdb;

	kdb = keySet->keyDB;

	for( key = kdb->firstKeyInDB; IsntNull(key); key = key->next )
		if( pgpKeySetIsMember( key, (PGPKeySet *)keySet ) )
			break;

	return key;
}


/* Sort keylist by keyid, only in back end for efficiency */
	static int
sCompareKeylistEntry( const void *ent1, const void *ent2 )
{
	PGPKeyDBObj *		obj1;
	PGPKeyDBObj *		obj2;
	PGPKeyID			keyid1, keyid2;

	obj1 = *(PGPKeyDBObj **) ent1;
	obj2 = *(PGPKeyDBObj **) ent2;

	pgpAssert( !pgpFrontEndKey( obj1 ) );
	pgpAssert( !pgpFrontEndKey( obj2 ) );

	PGPGetKeyID( obj1, &keyid1 );
	PGPGetKeyID( obj2, &keyid2 );
	
	return PGPCompareKeyIDs( &keyid1, &keyid2 );
}


	static void
sSortKeylist( PGPUInt32 *keylist, PGPSize keylistcount )
{
	qsort( keylist, keylistcount, sizeof(PGPUInt32),
		   sCompareKeylistEntry );
}


/* True if keyset is such that all keys contain all sub objects */
	PGPBoolean
pgpKeySetIsFlattenable( PGPKeySet const *set )
{
	PGPKeyIter *iter;
	PGPKeyDBObj *obj;
	PGPBoolean keyinset = FALSE;
	PGPError err;

	if( IsNull( set ) )
		return TRUE;

	/* Iterate over all keys in underlying keydb */
	if( IsPGPError( err = PGPNewKeyIterFromKeyDB(
							PGPPeekKeySetKeyDB((PGPKeySet*)set), &iter ) ) )
		return FALSE;

	/* If find an obj not in set when key was in set, can't do it */
	while( IsntPGPError( pgpKeyIterNextObject( iter, &obj ) ) )
	{
		/* Skip dummy objects */
		if( !pgpKeyDBObjIsReal( obj ) )
			continue;
		/* Skip if we find a key that is not a member */
		if( OBJISTOPKEY( obj ) )
		{
			keyinset = pgpKeySetIsMember( obj, (PGPKeySet *)set );
		} else {
			if( keyinset && !pgpKeySetIsMember( obj, (PGPKeySet *)set ) )
			{
				PGPFreeKeyIter( iter );
				return FALSE;
			}
		}
	}
	PGPFreeKeyIter( iter );
	return TRUE;
}



/* Create a list of all keyids of keys in key set */
	PGPError
pgpKeySetFlatten( PGPKeySet const *set, PGPUInt32 **keylist,
	PGPSize *keylistsize )
{
	PGPKeyIter *iter;
	PGPUInt32 *list;
	PGPSize size;
	PGPUInt32 nkeys;
	PGPUInt32 i;
	PGPKeyDBObjRef key;
	PGPContextRef context;
	PGPBoolean front;
	PGPError err;

	if( IsNull( set ) )
	{
		*keylist = NULL;
		*keylistsize = 0;
		return kPGPError_NoErr;
	}

	front = pgpFrontEndKeyDB( set->keyDB );

	PGPCountKeys( (PGPKeySet *)set, &nkeys );
	size = nkeys * sizeof(PGPUInt32);

	context = PGPPeekKeySetContext( (PGPKeySet *)set );

	list = (PGPUInt32 *)pgpContextMemAlloc( context, size, 0 );

	if( IsPGPError( err = PGPNewKeyIterFromKeySet( (PGPKeySet *)set, &iter )))
	{
		PGPFreeData( list );
		return err;
	}

	i = 0;
	while( IsntPGPError( PGPKeyIterNextKeyDBObj( iter, kPGPKeyDBObjType_Key,
												 &key ) ) )
	{
		list[i++] = front ? pgpKeyDBObjID( key ) : (PGPUInt32)key;
	}
	PGPFreeKeyIter( iter );

	pgpAssert( i == nkeys );

	/* Sort lists on back end */
	if( !front )
		sSortKeylist( list, nkeys );

	*keylist = list;
	*keylistsize = size;
	return kPGPError_NoErr;
}

/* Flatten and free the keyset */
	PGPError
pgpKeySetFlattenFree( PGPKeySet *set, PGPUInt32 **keylist,
	PGPSize *keylistsize )
{
	PGPError err;
	err = pgpKeySetFlatten( set, keylist, keylistsize );
	if( IsntNull( set ) )
		PGPFreeKeySet( set );
	return err;
}


/* Create a new keyset from a keylist, which is already sorted by keyid */
	PGPError
pgpKeySetUnflatten( PGPKeyDB *db, PGPUInt32 *keylist, PGPSize keylistsize,
	PGPKeySetRef *pset)
{
	PGPKeySetRef set;
	PGPBoolean front;
	PGPUInt32 keylistcount;
	PGPError err = kPGPError_NoErr;

	keylistcount = keylistsize / sizeof(PGPUInt32);

	front = pgpFrontEndKeyDB( db );

	/* Sort lists on back end */
	if( !front )
	{
		sSortKeylist( keylist, keylistcount );
	} else {
		/* Translate backend key_ids into key pointers */
		PGPUInt32 obj;
		PGPUInt32 i;
		for( i=0; i<keylistcount; ++i )
		{
			PGPFindNode( db->idToObj, keylist[i], (PGPUserValue *)&obj );
			keylist[i] = obj;
		}
	}

	if( keylistcount == 0 )
		err = PGPNewEmptyKeySet( db, &set );
	else
		err = pgpNewKeyListSet( db, (PGPKeyDBObjRef *)keylist, keylistcount,
								&set );

	if( IsntPGPError( err ) )
		*pset = set;
	return err;
}

/* Also free keylist */
	PGPError
pgpKeySetUnflattenFree( PGPKeyDB *db, PGPUInt32 *keylist, PGPSize keylistsize,
	PGPKeySetRef *pset)
{
	PGPError err;
	err = pgpKeySetUnflatten( db, keylist, keylistsize, pset );
	if( IsntNull( keylist ) )
		PGPFreeData( keylist );
	return err;
}

/* Refresh key objs in the keyset, i.e. mark them as being obsolete */
	PGPError
pgpKeySetRefreshFree( PGPKeySet *set )
{
	PGPKeyIter *iter;
	PGPKeyDBObjRef key;
	PGPError err;
	
	if( IsPGPError( err = PGPNewKeyIterFromKeySet( (PGPKeySet *)set, &iter )))
	{
		PGPFreeKeySet( set );
		return err;
	}

	while( IsntPGPError( PGPKeyIterNextKeyDBObj( iter, kPGPKeyDBObjType_Key,
												 &key ) ) )
	{
		(void) pgpKeyDBObjRefresh( key, TRUE );
	}
	PGPFreeKeyIter( iter );
	PGPFreeKeySet( set );
	
	return kPGPError_NoErr;
}

	PGPBoolean
pgpKeySetIsValid( PGPKeySet const *	keySet)
{
	return( IsntNull( keySet ) && keySet->magic == kPGPKeySetMagic );
}

#if PGP_DEBUG	/* [ */
	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;
}
#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 + -