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

📄 pgptrustprop.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:
		   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 + -