📄 pgpkeyset.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
PGPKeySet implementation
$Id: pgpKeySet.c,v 1.44 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"
PGPBoolean
pgpKeySetIsMember(PGPKeyDBObj *obj, PGPKeySet *set)
{
pgpa((
pgpaPGPKeySetValid(set),
pgpaPGPKeyDBObjValid(obj)));
if ( !pgpKeyDBObjIsReal( obj ) )
return( FALSE );
return set->isMember(set, obj);
}
PGPBoolean
PGPKeySetIsMember(PGPKeyDBObj *obj, PGPKeySet *set)
{
pgpa((
pgpaPGPKeySetValid(set),
pgpaPGPKeyDBObjValid(obj)));
if ( ! ( pgpKeySetIsValid( set ) && pgpKeyDBObjIsValid( obj ) ) )
return( FALSE );
pgpEnterBooleanFunction( FALSE );
return pgpKeySetIsMember( obj, set );
}
#if 0
PGPError
PGPUnionKeySets(PGPKeySetRef set1, PGPKeySetRef set2, PGPKeySetRef *newSet)
{
PGPError err = kPGPError_NoErr;
PGPValidatePtr( newSet );
*newSet = NULL;
PGPValidateKeySet( set1 );
PGPValidateKeySet( set2 );
if (set1->keyDB != set2->keyDB)
return kPGPError_KeyDBMismatch;
pgpEnterPGPErrorFunction();
if (set1->makeUnion == set2->makeUnion && IsntNull(set1->makeUnion))
err = set1->makeUnion(set1, set2, newSet);
else
err = pgpGenericUnionOfKeySets(set1, set2, newSet);
return err;
}
#endif
/* This does a union into the second set, overwriting it */
PGPError
PGPAddKeys(PGPKeySetRef set, PGPKeySetRef dest)
{
PGPKeySetRef newSet;
PGPKeySetRef destCopy;
PGPError err = kPGPError_NoErr;
PGPValidateKeySet( set );
PGPValidateKeySet( dest );
pgpEnterPGPErrorFunction();
if (set->keyDB != dest->keyDB)
return kPGPError_KeyDBMismatch;
/* Special case - union into root set makes no change */
if( dest->keyDB->rootSet == dest )
return kPGPError_NoErr;
if( dest->refCount != 1 )
{
pgpDebugMsg( "PGPAddKeys can't overwrite dest if it is in use" );
return kPGPError_BadParams;
}
/* Make an independent copy of dest for union to point at */
err = pgpNewKeySetInternal(set->keyDB, &destCopy);
if( IsPGPError( err ) )
return err;
destCopy->priv = dest->priv;
destCopy->firstListInSet = dest->firstListInSet;
destCopy->filterSubObjects = dest->filterSubObjects;
destCopy->isMember = dest->isMember;
destCopy->isEmpty = dest->isEmpty;
destCopy->makeUnion = dest->makeUnion;
destCopy->destroy = dest->destroy;
if (set->makeUnion == destCopy->makeUnion && IsntNull(set->makeUnion))
err = set->makeUnion(set, destCopy, &newSet);
else
err = pgpGenericUnionOfKeySets(set, destCopy, &newSet);
/* Decrement ref count on destCopy, freeing it if appropriate */
PGPFreeKeySet( destCopy );
if( IsPGPError( err ) )
return err;
/* Overwrite contents of dest with newset */
dest->priv = newSet->priv;
dest->firstListInSet = newSet->firstListInSet;
dest->filterSubObjects = newSet->filterSubObjects;
dest->isMember = newSet->isMember;
dest->isEmpty = newSet->isEmpty;
dest->makeUnion = newSet->makeUnion;
dest->destroy = newSet->destroy;
newSet->priv = NULL;
PGPFreeKeySet( newSet );
return kPGPError_NoErr;
}
/* Make a union of a single-key set and the dest, overwriting dest */
PGPError
PGPAddKey(PGPKeyDBObjRef key, PGPKeySet *dest)
{
PGPKeySetRef oneset;
PGPError err = kPGPError_NoErr;
PGPValidateKeyDBObj( key );
PGPValidateKeySet( dest );
if( PGPPeekKeyDBObjKeyDB( key ) != dest->keyDB )
return kPGPError_KeyDBMismatch;
pgpEnterPGPErrorFunction();
/* Special case - union into root set makes no change */
if( dest->keyDB->rootSet == dest )
return kPGPError_NoErr;
/* Else create keyset from key and use addkeys */
err = PGPNewOneKeySet( key, &oneset );
if( IsPGPError( err ) )
return err;
err = PGPAddKeys( oneset, dest );
PGPFreeKeySet( oneset );
return err;
}
PGPError
pgpNewKeySetInternal(
PGPKeyDBRef db,
PGPKeySetRef * newSet)
{
PGPKeySet * set;
PGPContextRef context = PGPPeekKeyDBContext(db);
pgpa(pgpaPGPKeyDBValid(db));
*newSet = NULL; /* In case there's an error */
set = (PGPKeySet *)pgpContextMemAlloc(context,
sizeof(PGPKeySet), kPGPMemoryMgrFlags_Clear);
if (IsNull(set))
return kPGPError_OutOfMemory;
set->priv = NULL;
set->refCount = 1;
set->keyDB = db;
set->firstListInSet = NULL;
set->magic = kPGPKeySetMagic;
set->prevSetInDB = NULL;
set->nextSetInDB = db->firstSetInDB;
if (set->nextSetInDB)
set->nextSetInDB->prevSetInDB = set;
db->firstSetInDB = set;
*newSet = set;
return kPGPError_NoErr;
}
static PGPBoolean
rootSetIsMember(PGPKeySet *set, PGPKeyDBObjRef key)
{
pgpa((
pgpaPGPKeySetValid(set),
pgpaAddrValid(key, char))); /* XXX use better align check */
return PGPPeekKeyDBObjKeyDB(key) == set->keyDB;
}
static PGPBoolean
rootSetIsEmpty(PGPKeySet *set)
{
pgpa((pgpaPGPKeySetValid(set)));
return IsNull( set->keyDB->firstKeyInDB );
}
static PGPError
rootSetMakeUnion(PGPKeySetRef set1, PGPKeySetRef set2, PGPKeySetRef *newSet)
{
(void)set2; /* Avoid warning */
PGPIncKeySetRefCount(set1);
*newSet = set1;
return kPGPError_NoErr;
}
static void
rootSetDestroy(PGPKeySet *set)
{
(void)set; /* Avoid warning */
}
PGPKeySet *
pgpRootSet(PGPKeyDB * db)
{
PGPKeySet * set;
(void)pgpNewKeySetInternal(db, &set);
if (IsntNull(set))
{
set->isMember = rootSetIsMember;
set->isEmpty = rootSetIsEmpty;
set->makeUnion = rootSetMakeUnion;
set->destroy = rootSetDestroy;
}
return set;
}
PGPError
PGPNewKeySet( PGPKeyDB *db, PGPKeySetRef *pset )
{
PGPKeySet *set;
PGPValidateKeyDB( db );
PGPValidatePtr( pset );
*pset = NULL;
pgpEnterPGPErrorFunction();
set = pgpRootSet( db );
if( set == NULL )
return kPGPError_OutOfMemory;
*pset = set;
return kPGPError_NoErr;
}
PGPError
PGPIncKeySetRefCount(PGPKeySetRef keys)
{
PGPValidateKeySet( keys );
pgpEnterPGPErrorFunction();
/* Root set doesn't get refcounted */
if( keys->keyDB->rootSet != keys )
keys->refCount++;
return( kPGPError_NoErr );
}
/* Add all the objects in the first key set into the second keydb. */
/* This may be run on front end or on back end */
PGPError
pgpCopyKeys_internal (
PGPKeySetRef keysToAdd,
PGPKeyDBRef destdb,
PGPKeySetRef *destKeySet )
{
PGPKeyIter *iter = NULL;
PGPKeyDBObj *obj;
PGPKeyDBObj *newobj;
PGPKeySet *newset = NULL;
PGPKeySet *oneset;
PGPUInt32 nkeys;
PGPError err = kPGPError_NoErr;
/* Clear db add cache */
pgpClearMemory( destdb->oldobjs, sizeof(destdb->oldobjs) );
pgpClearMemory( destdb->newobjs, sizeof(destdb->newobjs) );
if( IsntNull( destKeySet ) )
{
PGPCountKeysInKeyDB( destdb, &nkeys );
if( nkeys != 0 )
{
err = PGPNewEmptyKeySet( destdb, &newset );
if ( IsPGPError( err ) )
goto error;
}
}
/*
* Shortcut if we can flatten source key set, do the add in one
* call (more calls needed to resync though).
*/
if( pgpFrontEndKeyDB( destdb ) &&
pgpKeySetIsFlattenable( keysToAdd ) )
{
PGPUInt32 * keylist;
PGPUInt32 * newkeylist = NULL;
PGPSize keylistsize;
PGPSize newkeylistsize;
PGPUInt32 numKeys;
PGPUInt32 * keyArray;
PGPSize keyArraySize;
PGPBoolean neednewkeylist;
PGPBoolean allNewKeys;
if( IsntNull( newset ) )
PGPFreeKeySet( newset );
/* Always need new key list so we can refresh returned keys */
neednewkeylist = TRUE; /*IsntNull( destKeySet ) && nkeys != 0;*/
err = pgpKeySetFlatten( keysToAdd, &keylist, &keylistsize );
if( IsPGPError( err ) )
return err;
err = pgpCopyKeys_back( PGPPeekKeyDBContext(destdb),
PGPPeekKeySetKeyDB(keysToAdd)->id, destdb->id,
keylist, keylistsize, neednewkeylist,
&newkeylist, &newkeylistsize );
if( IsPGPError( err ) )
return err;
/* Update front-end copy of destdb */
err = pgpKeyDBArray_back( PGPPeekKeyDBContext(destdb), destdb->id,
&numKeys, &keyArray, &keyArraySize );
if( IsPGPError( err ) )
{
if( IsntNull( newkeylist ) )
PGPFreeData( newkeylist );
return err;
}
allNewKeys = IsNull(destdb->firstKeyInDB);
err = pgpAddFromKeyArray( destdb, NULL, keyArray, numKeys, allNewKeys);
if( IsntNull( keyArray ) )
PGPFreeData( keyArray );
if( IsPGPError( err ) )
{
if( IsntNull( newkeylist ) )
PGPFreeData( newkeylist );
return err;
}
/* Set destKeySet if requested */
if( IsntNull( destKeySet ) )
{
if( nkeys == 0 )
{
/* Want root key set */
err = PGPNewKeySet( destdb, destKeySet );
} else {
err = pgpKeySetUnflatten( destdb, newkeylist,
newkeylistsize, destKeySet );
}
}
/* Frees list */
pgpKeyRefreshFromList( destdb, newkeylist, newkeylistsize );
/* No need to call pgpKeyDBChanged, was called in AddFromKeyArray */
return err;
}
err = PGPNewKeyIterFromKeySet( keysToAdd, &iter );
if ( IsPGPError( err ) )
goto error;
while( IsntPGPError( pgpKeyIterNextObject( iter, &obj ) ) ) {
err = pgpKeyDBAddObject( destdb, obj, &newobj );
if ( IsPGPError( err ) )
goto error;
if( pgpFrontEndKeyDB( destdb ) )
pgpKeyDBObjRefresh( newobj, FALSE );
if( IsntNull( newset ) && nkeys != 0 )
{
err = PGPNewOneKeySet( newobj, &oneset );
if ( IsPGPError( err ) )
goto error;
err = PGPAddKeys( oneset, newset );
PGPFreeKeySet( oneset );
if ( IsPGPError( err ) )
goto error;
}
}
PGPFreeKeyIter( iter );
iter = NULL;
if( pgpFrontEndKeyDB( destdb ) )
{
PGPUInt32 numKeys;
PGPUInt32 * keyArray;
PGPSize keyArraySize;
/* Refresh from back end in case got some dummy keys */
err = pgpKeyDBArray_back( PGPPeekKeyDBContext(destdb), destdb->id,
&numKeys, &keyArray, &keyArraySize );
if( IsPGPError( err ) )
goto error;
err = pgpAddFromKeyArray( destdb, NULL, keyArray, numKeys, FALSE );
if( IsntNull( keyArray ) )
PGPFreeData( keyArray );
if( IsPGPError( err ) )
goto error;
}
if( IsntNull( destKeySet ) )
{
if( nkeys == 0 )
{
err = PGPNewKeySet( destdb, destKeySet );
} else {
*destKeySet = newset;
newset = NULL;
}
}
pgpKeyDBChanged( destdb, TRUE );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -