📄 pgptrustprop.c
字号:
Make sure axiomatic (buckstop) bit is not set. */
if( IsntNull(sig) && sinfo->type == PGP_SIGTYPE_KEY_REVOKE ) {
tmptrust &= ~(PGP_KEYTRUSTF_BUCKSTOP | kPGPKeyTrust_Mask);
tmptrust |= kPGPKeyTrust_Never | PGP_KEYTRUSTF_REVOKED;
}
else
tmptrust &= ~PGP_KEYTRUSTF_REVOKED;
/* Check if key has expired */
if( kinfo->creationtime < timenow && kinfo->validityperiod > 0 &&
(unsigned)((timenow - kinfo->creationtime)/86400) >=
kinfo->validityperiod ) {
tmptrust &= ~(PGP_KEYTRUSTF_BUCKSTOP | kPGPKeyTrust_Mask);
tmptrust |= kPGPKeyTrust_Never | PGP_KEYTRUSTF_EXPIRED;
}
else
tmptrust &= ~PGP_KEYTRUSTF_EXPIRED;
if( kinfo->trust != tmptrust ) {
kinfo->trust = (PGPByte)tmptrust;
*bChanged = TRUE;
if( IsntNull( changedSet ) )
PGPAddKey( key, changedSet );
}
/* Check any subkeys for revocation or expiration. */
for (child = key->down; IsntNull(child); child = child->next) {
if( !pgpKeyDBObjIsReal( child ) )
continue;
if( !pgpKeySetIsMember( child, set ) )
continue;
if( OBJISSUBKEY(child) ) {
kinfo2 = pgpKeyToKeyInfo( child );
tmptrust = kinfo2->trust;
tmptrust &= ~(PGP_KEYTRUSTF_REVOKED | PGP_KEYTRUSTF_EXPIRED);
for (sig = child->down; IsntNull(sig); sig = sig->next) {
if( !pgpKeyDBObjIsReal( sig ) )
continue;
if( !pgpKeySetIsMember( sig, set ) )
continue;
if( OBJISSIG(sig) ) {
sinfo = pgpSigToSigInfo( sig );
if( sigRevokesKey(sig) &&
mntSigIsValidTime (timenow, sinfo->tstamp,
sinfo->sigvalidity) ) {
tmptrust |= PGP_KEYTRUSTF_REVOKED;
break;
}
}
}
if( kinfo2->creationtime < timenow &&
kinfo2->validityperiod > 0 &&
(unsigned)((timenow - kinfo2->creationtime)/86400) >=
kinfo2->validityperiod )
tmptrust |= PGP_KEYTRUSTF_EXPIRED;
if( kinfo2->trust != tmptrust ) {
kinfo2->trust = (PGPByte) tmptrust;
if( IsntNull( changedSet ) )
PGPAddKey( key, changedSet );
*bChanged = TRUE;
}
}
}
/* Search for axiomatic keys at root of graph. Buckstop bit must be
set, and key must not be revoked or expired. */
if( kinfo->trust & PGP_KEYTRUSTF_BUCKSTOP
&& !(kinfo->trust & (PGP_KEYTRUSTF_REVOKED|PGP_KEYTRUSTF_EXPIRED))
/* && !(kinfo->trust & PGP_KEYTRUSTF_DISABLED) */ )
{
/* Make sure key marked as axiomatic has a secret component.
(This may not be true if a public keyring is opened, but
*not* its corresponding secret keyring). If not, reset
the buckstop bit and set trust to 'never'. */
tmptrust = kinfo->trust & ~PGP_KEYTRUSTF_BUCKSTOP;
if( pgpKeyIsSec( key ) )
tmptrust |= PGP_KEYTRUSTF_BUCKSTOP;
if( !(tmptrust & PGP_KEYTRUSTF_BUCKSTOP) ) {
/* Don't have private key */
tmptrust &= ~kPGPKeyTrust_Mask;
tmptrust |= kPGPKeyTrust_Never;
kinfo->trust = tmptrust;
if( IsntNull( changedSet ) )
PGPAddKey( key, changedSet );
*bChanged = TRUE;
} else {
/* Yes, we do have private key */
/* Link into list via util field */
kinfo->util = (PGPKeyDBObj *)list;
list = key;
/* Make sure all userids on axiomatic key are fully valid */
/* XXX (Really should only do this on self-signed userids! */
for (child = key->down; IsntNull(child);
child = child->next) {
if( !pgpKeyDBObjIsReal( child ) )
continue;
if( !pgpKeySetIsMember( child, set ) )
continue;
if( OBJISUSERID(child) ) {
uinfo = pgpUserIDToUserIDInfo( child );
uinfo->valid = (PGPUInt16) PGP_TRUST_INFINITE;
}
}
}
}
}
if( IsntNull( altdb ) )
{
/* Also add axiomatic keys from backup DB to the list for meta
* introducer trust purposes
*/
for (key = altdb->firstKeyInDB; IsntNull(key); key = key->next) {
if( !pgpKeyDBObjIsReal( key ) )
continue;
kinfo = pgpKeyToKeyInfo( key );
if( kinfo->trust & PGP_KEYTRUSTF_BUCKSTOP
&& !(kinfo->trust & (PGP_KEYTRUSTF_REVOKED
|PGP_KEYTRUSTF_EXPIRED))
/* && !(kinfo->trust & PGP_KEYTRUSTF_DISABLED) */ )
{
if( pgpKeyIsSec( key ) )
{
kinfo->util = (PGPKeyDBObj *)list;
list = key;
}
}
}
}
return list;
}
/*
* Run the trust propagation pass on the keyrin
* If changedSet is not null, add keys to it that we change
*/
PGPError
pgpPropagateTrustInternal(PGPKeySet *set, PGPKeyDB *altdb,
PGPUInt32 const timenow, PGPKeySet *changedSet)
{
PGPKeyDB *db;
PGPContextRef context;
PGPEnv *pgpEnv;
PGPUInt32 certdepth;
PGPKeyDBObj const *list;
PGPKeyDBObj *key, *child;
PGPKeyDBObj *sig;
PGPKeyInfo *kinfo;
PGPKeyInfo *axkeyinfo;
PGPUserIDInfo *uinfo;
PGPSigInfo *sinfo;
PGPSigInfo *newestsiginfo;
unsigned tmptrust;
unsigned t;
unsigned long count; /* Count of keys needing trust assigned */
PGPUInt16 validity;
PGPKeyDBObj const *axkey;
PathList *pathlist = NULL;
PGPKeyDBObj *userid;
double confidence;
PGPBoolean bChanged = FALSE;
/* Get depth we will follow */
db = PGPPeekKeySetKeyDB( set );
context = PGPPeekKeyDBContext( db );
pgpEnv = pgpContextGetEnvironment( context );
certdepth = pgpenvGetInt(pgpEnv, PGPENV_CERTDEPTH, NULL, NULL);
list = sPropagateTrustPass1( db, set, altdb, timenow, TRUE, &bChanged,
changedSet );
/* The actual trust computation */
pgpKeyDBListSigsBy(db); /* Canonicalize sigsby pointers */
/* Propagate meta introducer trust forwards first */
/* At this point, "list" contains axiomatic keys */
for (axkey = list; IsntNull(axkey)
&& IsntNull(axkeyinfo = pgpKeyToKeyInfo(axkey));
axkey = axkeyinfo->util) {
PGPKeyDBObj const *axsig = axkeyinfo->sigsby;
while (IsntNull(axsig)) {
PGPKeyDBObj *newestsig;
pgpAssert( OBJISSIG( axsig ) );
newestsig = mntNewestSiblingSig(&axsig);
pgpAssert( OBJISSIG( newestsig ) );
if( !mntSigIsValid( newestsig, timenow ) )
continue;
newestsiginfo = pgpSigToSigInfo( newestsig );
/* Skip if not a trust sig */
if( newestsiginfo->trustLevel < 1 )
continue;
/* Skip if not a valid key sig */
if( !mntSigIsValidTimeKeySig (newestsig, timenow) )
continue;
/*
* Here we have a good trust or metaintroducer signature by us.
* Propagate it forward.
*/
mntApplyTrustSig (newestsig, PGP_NEWTRUST_INFINITE,
certdepth, pgpenvCompleteTrust(pgpEnv), timenow);
}
}
/* Find a path back from each userid which sets its validity */
for (key = db->firstKeyInDB; IsntNull(key); key = key->next) {
if( !pgpKeyDBObjIsReal( key ) )
continue;
if( !pgpKeySetIsMember( key, set ) )
continue;
pgpAssert(OBJISKEY(key));
kinfo = pgpKeyToKeyInfo( key );
for (userid = key->down; IsntNull(userid); userid = userid->next) {
if( !pgpKeyDBObjIsReal( userid ) )
continue;
if( !OBJISUSERID(userid) )
continue;
if( !pgpKeySetIsMember( userid, set ) )
continue;
uinfo = pgpUserIDToUserIDInfo( userid );
/* Calculate "real" validity for userids. If the key
is axiomatic, this will be overidden when the
validity is returned by pgpUserIDValidity. */
/* Don't automatically mark axiomatic keys' userids as trusted */
#if 0
if( kinfo->trust & PGP_KEYTRUSTF_BUCKSTOP
&& !(kinfo->trust &
(PGP_KEYTRUSTF_REVOKED|PGP_KEYTRUSTF_EXPIRED)
/* && !(kinfo->trust & PGP_KEYTRUSTF_DISABLED) */) ) {
uinfo->valid = PGP_TRUST_INFINITE;
continue;
}
#endif
/*
* Find all paths back from this userid, among only trusted
* introducers, to an axiomatic key.
*/
sFindPathsBack (userid, &pathlist, certdepth,
timenow, db, altdb);
if( IsntNull(pathlist) ) {
pathlist = pathListPrune (pathlist, TOTALPATHMAX, db);
#ifdef DEBUGPATH
fprintf (stdout, "Found path for ");
pgpDebugPrintKey (stdout, key);
fprintf (stdout, "\n");
#endif
confidence = pathListConfidence (pathlist, db);
if( confidence >= 1. )
uinfo->valid = PGP_TRUST_INFINITE;
else
uinfo->valid = pgpDoubleToTrust (1. / (1.-confidence));
pathListFreeAll (pathlist, db);
pathlist = NULL;
}
}
}
memPoolEmpty(&db->pathpool);
db->paths = NULL;
db->pathlists = NULL;
/* Postprocessing: set the various trust bytes, */
count = 0;
for (key = db->firstKeyInDB; IsntNull(key); key = key->next) {
PGPKeyDBObjRef altkey;
PGPKeyInfo *altkinfo;
if( !pgpKeyDBObjIsReal( key ) )
continue;
if( !pgpKeySetIsMember( key, set ) )
continue;
pgpAssert( OBJISKEY( key ) );
kinfo = pgpKeyToKeyInfo( key );
/* Find corresponding key in other db if it exists */
altkey = NULL;
altkinfo = NULL;
if( IsntNull( altdb ) )
{
PGPKeyID keyid;
pgpKeyID8( key, NULL, &keyid );
pgpGetKeyByKeyID(altdb, &keyid, FALSE, FALSE, &altkey );
if( IsntNull( altkey ) )
altkinfo = pgpKeyToKeyInfo( altkey );
}
tmptrust = kinfo->trust & kPGPKeyTrust_Mask;
/* Set the signature trusts to match the key */
for (sig = kinfo->sigsby; IsntNull(sig); sig = sinfo->nextby) {
pgpAssert( OBJISSIG( sig ) );
pgpAssert( pgpKeyDBObjIsReal( sig ) );
sinfo = pgpSigToSigInfo( sig );
/* Trust is either key's, or NEVER if it's a bad sig */
t = sinfo->trust & ~kPGPKeyTrust_Mask;
if( sinfo->trust & PGP_SIGTRUSTF_CHECKED )
t |= tmptrust;
else
t |= kPGPKeyTrust_Never;
if( sinfo->trust != t )
{
sinfo->trust = t;
if( IsntNull( changedSet ) )
PGPAddKey( PGPPeekKeyDBObjKey(sig), changedSet );
bChanged = TRUE;
}
}
/* Update each userid's validity byte */
for (child = key->down; IsntNull(child); child = child->next) {
if( !pgpKeyDBObjIsReal( child ) )
continue;
if( !OBJISUSERID(child) )
continue;
if( !pgpKeySetIsMember( child, set ) )
continue;
uinfo = pgpUserIDToUserIDInfo( child );
if( kinfo->trust & PGP_KEYTRUSTF_REVOKED )
validity = 0;
else if( uinfo->valid == PGP_TRUST_INFINITE )
validity = PGP_NEWTRUST_INFINITE;
else {
validity = uinfo->valid >> TRUST_CERTSHIFT;
if( validity > PGP_NEWTRUST_MAX )
validity = PGP_NEWTRUST_MAX;
}
/* Take max of validity from this and from other keydb */
if( IsntNull( altkey ) ) {
PGPByte const *uidbuf;
PGPSize uidbuflen;
PGPKeyDBObjRef altchild;
uidbuf = pgpFetchObject( child, &uidbuflen );
altchild = pgpFindMatchingChild( altkey, uidbuf, uidbuflen );
if( IsntNull( altchild ) ) {
PGPUserIDInfo *altchildinfo;
altchildinfo = pgpUserIDToUserIDInfo( altchild );
validity = pgpMax( validity, altchildinfo->validity );
}
}
if( validity != uinfo->validity ) {
uinfo->validity = (PGPByte) validity;
if( IsntNull( changedSet ) )
PGPAddKey( key, changedSet );
bChanged = TRUE;
}
tmptrust = pgpTrustExternToOld( pgpEnv, (PGPUInt8) validity );
tmptrust = pgpTrustOldKeyToUserID( tmptrust );
t = tmptrust | (uinfo->oldvalidity &
(PGP_USERIDTRUSTF_WARNONLY|PGP_USERIDTRUSTF_PRIMARY));
if( t != uinfo->oldvalidity ) {
uinfo->oldvalidity = t;
if( IsntNull( changedSet ) )
PGPAddKey( key, changedSet );
bChanged = TRUE;
}
/* Reset valid with adjusted value. */
if( uinfo->validity == PGP_NEWTRUST_INFINITE )
uinfo->valid = PGP_TRUST_INFINITE;
else
uinfo->valid =
uinfo->validity << TRUST_CERTSHIFT;
}
}
/* Clean up after regexp processing */
mntClearKeyRegexps( db );
if( bChanged )
pgpKeyDBChanged( db, TRUE );
/* Et voila, we're done! */
return kPGPError_NoErr;
}
/* Do just the part of trust-prop that handles level > 0 trust */
PGPError
pgpPropagateSignedKeyTrust( PGPKeyDB *db )
{
PGPContextRef context;
PGPEnv *pgpEnv;
PGPUInt32 certdepth;
PGPKeyDBObj const *list;
PGPSigInfo *newestsiginfo;
PGPKeyDBObj const *axkey;
PGPKeyInfo *axkeyinfo;
PGPUInt32 timenow = PGPGetTime();
PGPBoolean bChanged = FALSE;
/* Get depth we will follow */
context = PGPPeekKeyDBContext( db );
pgpEnv = pgpContextGetEnvironment( context );
certdepth = pgpenvGetInt(pgpEnv, PGPENV_CERTDEPTH, NULL, NULL);
list = sPropagateTrustPass1( db, PGPPeekKeyDBRootKeySet( db ), NULL,
timenow, FALSE, &bChanged, NULL );
pgpKeyDBListSigsBy(db); /* Canonicalize sigsby pointers */
/* Propagate meta introducer trust forwards */
/* At this point, "list" contains axiomatic keys */
for (axkey = list; IsntNull(axkey)
&& IsntNull(axkeyinfo = pgpKeyToKeyInfo(axkey));
axkey = axkeyinfo->util) {
PGPKeyDBObj const *axsig = axkeyinfo->sigsby;
while (IsntNull(axsig)) {
PGPKeyDBObj *newestsig;
pgpAssert( OB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -