📄 pgpkeyset.c
字号:
}
/*
* Return a ringset holding the keys (and subsidiary objects) in the
* corresponding keyset. This differs from pgpKeyDBRingSet in that it
* only includes the keys in the keyset, not all those in the keydb.
* The returned ringset must be deleted after being used. If freezeit
* is true, the ringset is returned frozen, else it is returned
* mutable.
*/
PGPError
pgpKeySetRingSet(PGPKeySet *keys, PGPBoolean freezeit, RingSet const **ringset)
{
PGPKeyList *list = NULL;
PGPKeyIter *iter = NULL;
PGPKey *key;
RingSet const *kdbSet;
RingSet *rset = NULL;
PGPError err = kPGPError_NoErr;
kdbSet = pgpKeyDBRingSet( keys->keyDB );
rset = ringSetCreate( ringSetPool( kdbSet ) );
if( IsNull( rset ) ) {
err = ringSetError( kdbSet )->error;
goto error;
}
if (keys->isMember == rootSetIsMember) {
/* In simple case, can just make a copy of root set */
ringSetAddSet( rset, kdbSet );
} else {
/* Else iterate over all keys in set */
if( IsPGPError( err = PGPOrderKeySet( keys, kPGPAnyOrdering,
&list ) ) )
goto error;
if( IsPGPError( err = PGPNewKeyIter( list, &iter ) ) )
goto error;
while( IsntPGPError( PGPKeyIterNext( iter, &key ) ) ) {
RingObject *keyobj = key->key;
pgpAssert( IsntNull( keyobj ) );
ringSetAddObjectChildren( rset, kdbSet, keyobj );
}
PGPFreeKeyIter( iter );
PGPFreeKeyList( list );
}
if( freezeit )
ringSetFreeze( rset );
*ringset = (RingSet const *) rset;
return kPGPError_NoErr;
error:
if( IsntNull( iter ) )
PGPFreeKeyIter( iter );
if( IsntNull( list ) )
PGPFreeKeyList( list );
if( IsntNull( rset ) )
ringSetDestroy( rset );
return err;
}
PGPBoolean
pgpKeyDBIsMutable(PGPKeyDB *db)
{
pgpa(pgpaPGPKeyDBValid(db));
return (*db->isMutable)(db);
}
PGPBoolean
pgpKeyDBIsDirty(PGPKeyDB *db)
{
pgpa(pgpaPGPKeyDBValid(db));
return (*db->isDirty)(db);
}
/*
* Call this when we have made a change to the keys in the changedkeys set,
* to force those keys to be resorted in all lists depending on the db
*/
PGPError
pgpKeyDBChanged(PGPKeyDB *db, RingSet *changedkeys)
{
return db->changed(db, changedkeys);
}
PGPError
pgpCommitKeyDB(PGPKeyDB *db)
{
RingSet const * rset;
PGPError error;
int count;
pgpa(pgpaPGPKeyDBValid(db));
if ( !pgpKeyDBIsMutable( db ) )
return kPGPError_ItemIsReadOnly;
/*
* Don't do the automatic sigcheck and trust propagation on in-memory
* db's. This is not only unnecessary, but it clears the axiomatic bit
* on any keys which are in the memory set as public keys but not as
* secret keys.
*/
if( db->typeMagic != PGPKDBMEMMAGIC )
{
rset = pgpKeyDBRingSet (db);
if (!rset)
return kPGPError_OutOfMemory;
/* XXX This can take a while, need a progress bar? */
error = ringPoolCheck (rset, rset, FALSE, FALSE, 0, 0);
if (error)
return error;
count = ringMnt (rset, 0, PGPGetTime());
if (count < 0)
return (PGPError) count;
}
error = db->commit(db);
if (error)
return error;
pgpKeyDBReleaseDependencies(db);
return kPGPError_NoErr;
}
PGPError
pgpPropagateTrustKeyDB(PGPKeyDB *db)
{
RingSet const *rset;
int result;
PGPError err = kPGPError_NoErr;
pgpa(pgpaPGPKeyDBValid(db));
rset = pgpKeyDBRingSet (db);
result = ringMnt (rset, 0, PGPGetTime());
/* this is obviously extremely ugly rngMnt() should be fixed */
if ( result < 0 )
err = (PGPError)result;
else
err = kPGPError_NoErr;
return( err );
}
/* Callback for checking function */
typedef struct PGPKeyCheckState {
PGPContextRef context;
PGPEventHandlerProcPtr progress;
PGPUserValue userValue;
PGPUInt32 total;
PGPUInt32 sofar;
} PGPKeyCheckState;
static PGPError
checkKeyDBCallback(void *arg, RingIterator *iter, int status)
{
PGPKeyCheckState *s = (PGPKeyCheckState *)arg;
PGPError err = kPGPError_NoErr;
PGPOptionListRef newOptionList = NULL;
(void) iter;
(void) status;
if (IsntNull (s->progress)) {
err = pgpEventNull (s->context, &newOptionList,
s->progress, s->userValue, ++s->sofar, s->total);
if (IsntNull (newOptionList))
pgpFreeOptionList (newOptionList);
}
return err;
}
PGPError
pgpCheckKeyDB (
PGPKeyDB *dbToCheck,
PGPKeyDB *dbSigning,
PGPBoolean checkAll,
PGPEventHandlerProcPtr progress,
PGPUserValue userValue
)
{
RingSet const *rsetToCheck,
*rsetSigning;
PGPKeyCheckState s;
pgpa(pgpaPGPKeyDBValid(dbToCheck));
pgpa(pgpaPGPKeyDBValid(dbSigning));
rsetToCheck = pgpKeyDBRingSet (dbToCheck);
rsetSigning = pgpKeyDBRingSet (dbSigning);
if (!rsetToCheck || !rsetSigning)
return kPGPError_OutOfMemory;
pgpClearMemory (&s, sizeof(s));
if( IsntNull( progress ) ) {
s.context = dbToCheck->context;
s.progress = progress;
s.userValue = userValue;
s.sofar = 0;
s.total = ringPoolCheckCount(rsetToCheck, rsetSigning, checkAll,
FALSE);
}
return ringPoolCheck (rsetToCheck, rsetSigning, checkAll, FALSE,
checkKeyDBCallback, &s);
}
PGPError
pgpRevertKeyDB(PGPKeyDB *db)
{
pgpa(pgpaPGPKeyDBValid(db));
return db->revert(db);
}
PGPError
pgpReloadKeyDB(PGPKeyDB *db)
{
pgpa(pgpaPGPKeyDBValid(db));
return db->reload(db);
}
PGPError
PGPCommitKeyRingChanges(PGPKeySet *keys)
{
PGPValidateKeySet( keys );
return pgpCommitKeyDB(keys->keyDB);
}
PGPError
PGPPropagateTrust(PGPKeySet *keys)
{
PGPValidateKeySet( keys );
return pgpPropagateTrustKeyDB(keys->keyDB);
}
PGPError
PGPRevertKeyRingChanges(PGPKeySet *keys)
{
PGPValidateKeySet( keys );
return pgpRevertKeyDB(keys->keyDB);
}
/* Check all sigs in keyset */
PGPError
PGPCheckKeyRingSigs(
PGPKeySetRef keysToCheck,
PGPKeySetRef keysSigning,
PGPBoolean checkAll,
PGPEventHandlerProcPtr progress,
PGPUserValue userValue
)
{
RingSet const *rsetToCheck = NULL,
*rsetSigning = NULL;
PGPKeyCheckState s;
PGPError err = kPGPError_NoErr;
PGPValidateKeySet( keysToCheck );
PGPValidateKeySet( keysSigning );
err = pgpKeySetRingSet (keysToCheck, TRUE, &rsetToCheck);
if( IsPGPError( err ) )
goto error;
err = pgpKeySetRingSet (keysSigning, TRUE, &rsetSigning);
if( IsPGPError( err ) )
goto error;
pgpClearMemory (&s, sizeof(s));
if( IsntNull( progress ) ) {
s.context = PGPGetKeySetContext( keysToCheck );
s.progress = progress;
s.userValue = userValue;
s.sofar = 0;
s.total = ringPoolCheckCount(rsetToCheck, rsetSigning, checkAll,
FALSE);
}
err = ringPoolCheck (rsetToCheck, rsetSigning, checkAll, FALSE,
checkKeyDBCallback, &s);
error:
if( IsntNull( rsetToCheck ) )
ringSetDestroy( (RingSet *)rsetToCheck );
if( IsntNull( rsetSigning ) )
ringSetDestroy( (RingSet *)rsetSigning );
return err;
}
PGPError
PGPReloadKeyRings(PGPKeySetRef keys)
{
PGPValidateKeySet( keys );
return pgpReloadKeyDB(keys->keyDB);
}
PGPError
PGPIncKeySetRefCount(PGPKeySetRef keys)
{
PGPValidateKeySet( keys );
keys->refCount++;
return( kPGPError_NoErr );
}
PGPError
PGPNewKeySet(
PGPContextRef context,
PGPKeySetRef *newSetOut)
{
PGPKeyDB *memdb;
PGPValidatePtr( newSetOut );
*newSetOut = NULL;
PGPValidateContext( context );
memdb = pgpKeyDBCreate(context);
if ( IsNull( memdb ) )
return kPGPError_OutOfMemory;
*newSetOut = pgpKeyDBRootSet (memdb);
pgpFreeKeyDB( memdb );
return kPGPError_NoErr;
}
/* Add all the objects in the second key set into the first. */
PGPError
PGPAddKeys (
PGPKeySetRef keysToAdd,
PGPKeySetRef set )
{
PGPKeyList *kladd = NULL;
PGPKeyIter *kiadd = NULL;
RingSet *tmpset = NULL;
PGPError err = kPGPError_NoErr;
PGPValidateKeySet( set );
PGPValidateKeySet( keysToAdd );
if ( !PGPKeySetIsMutable( set ) )
{
err = kPGPError_ItemIsReadOnly;
goto error;
}
err = pgpKeyDBAddDependency(set->keyDB, keysToAdd->keyDB);
if ( IsPGPError( err ) )
goto error;
err = pgpKeySetRingSet (keysToAdd, FALSE, (RingSet const **)&tmpset);
if( IsPGPError( err ) )
{
err = kPGPError_OutOfMemory;
goto error;
}
err = pgpAddObjects (set->keyDB, tmpset);
if ( IsPGPError( err ) )
goto error;
error:
if (tmpset)
ringSetDestroy (tmpset);
if (kiadd)
PGPFreeKeyIter (kiadd);
if (kladd)
PGPFreeKeyList (kladd);
return err;
}
/* Remove all objects in the second set from the first */
PGPError
PGPRemoveKeys (
PGPKeySetRef keysToRemove,
PGPKeySetRef set )
{
PGPKeyList *klrem = NULL;
PGPKeyIter *kirem = NULL;
PGPKey *key = NULL;
RingObject *keyobj = NULL;
PGPError err = kPGPError_NoErr;
PGPValidateKeySet( set );
PGPValidateKeySet( keysToRemove );
if ( !PGPKeySetIsMutable( set ) )
{
err = kPGPError_ItemIsReadOnly;
goto error;
}
err = PGPOrderKeySet (keysToRemove, kPGPAnyOrdering, &klrem );
if ( IsPGPError( err ) )
goto error;
err = PGPNewKeyIter (klrem, &kirem );
if ( IsPGPError( err ) )
goto error;
while ((err = PGPKeyIterNext( kirem, &key )) == kPGPError_NoErr )
{
keyobj = key->key;
err = pgpRemoveObject (set->keyDB, keyobj);
if ( IsPGPError( err ) )
goto error;
}
pgpAssert( err == kPGPError_EndOfIteration );
if ( err == kPGPError_EndOfIteration )
err = kPGPError_NoErr;
error:
if (kirem)
PGPFreeKeyIter (kirem);
if (klrem)
PGPFreeKeyList (klrem);
return err;
}
PGPError
PGPFreeKeySet(PGPKeySet *keys)
{
PGPContextRef context = NULL;
PGPValidateKeySet( keys );
context = PGPGetKeySetContext( keys );
PGPValidateContext( context );
keys->refCount--;
if (keys->refCount <= 0)
{
(*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);
pgpFreeKeyDB (keys->keyDB);
pgpContextMemFree( context, keys);
}
return( kPGPError_NoErr );
}
PGPBoolean
PGPKeySetIsMutable(PGPKeySet *keys)
{
pgpa(pgpaPGPKeySetValid(keys));
if ( ! pgpKeySetIsValid( keys ) )
return( FALSE );
return pgpKeyDBIsMutable(keys->keyDB);
}
PGPBoolean
PGPKeySetNeedsCommit(PGPKeySet *keys)
{
pgpa(pgpaPGPKeySetValid(keys));
if ( ! pgpKeySetIsValid( keys ) )
return( FALSE );
return pgpKeyDBIsDirty(keys->keyDB);
}
/* Defines when a key should be expanded or collapsed. If set to 1,
keys are expanded by pgpBuildKeyPool. If set to 2, they are expanded
when referenced by an iterator, or when the key refCount is explicitly
incremented by the app. */
PGPError
pgpIncKeyRefCount(PGPKey *key)
{
pgpa(pgpaAddrValid(key, PGPKey));
if ( IsNull( key ) )
return( kPGPError_BadParams );
key->refCount++;
if (key->refCount == 1)
return pgpExpandKey (key);
return kPGPError_NoErr;
}
PGPError
pgpFreeKey(PGPKey *key)
{
PGPError err = kPGPError_NoErr;
pgpa(pgpaPGPKeyValid(key));
PGPValidateKey( key );
PGPValidateParam( key->refCount >= 1 );
if (key->refCount == 1)
err = pgpCollapseKey (key);
key->refCount--;
if (key->refCount <= 0)
deallocKey(key->keyDB, key);
return err;
}
PGPError
PGPCountKeys(
PGPKeySetRef keys,
PGPUInt32 * numKeys )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -