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

📄 pgptrustprop.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:
				newseg = pathAlloc(db);
				if( IsNull(newseg) ) {
					/* Out of memory */
					return NULL;
				}
				newseg->dest = userid->up;
				newseg->src = sigkey;
				newseg->next = NULL;
				newseg->confidence = 1.0;
				newpredt = pathAddSeg (predt, newseg);
				ppath = sFindPathsUserID (paireduserid, ppath, predh, newpredt,
					depth, maxdepth, timenow, db, altdb, userid->down);
				pathFree (newseg, db);
				*predt = NULL;
				if( IsNull(ppath) ) {
					/* Out of memory */
					return NULL;
				}
			}
		}
	}
	return ppath;
}


/*
 * Find all the paths from the starting key back to an axiomatically
 * trusted key.
 *
 * Returns	tail pointer for updated PathList
 *
 * start	starting key object for search backwards through web of trust
 * ppath	tail pointer of PathList to add our new paths to
 * predh	pointer to the (head of the) Path we will add to
 * predt	tail pointer to the Path we will add to
 * depth	length of path, counting segment added in sFindPathsUserID
 * maxdepth	maximum length of paths we allow
 * timenow	current timestamp
 * db		PGPKeyDB to use for memory allocations
 *
 */
static PathList **
sFindPathsKey (PGPKeyDBObj *start, PathList **ppath,
	Path **predh, Path **predt, unsigned depth,
    unsigned maxdepth, PGPUInt32 timenow, PGPKeyDB *db, PGPKeyDB *altdb)
{
	PGPKeyDBObj     *userid;
	PGPBoolean		firstuserid;
	PGPKeyInfo *	kinfo;
	PGPUserIDInfo *	uinfo;

	/* It's a key but not axiomatic */
	pgpAssert (OBJISKEY(start));
	kinfo = pgpKeyToKeyInfo( start );
	pgpAssert (!(kinfo->trust & PGP_KEYTRUSTF_BUCKSTOP));

	SETLOOKINGAT(kinfo);
	firstuserid = TRUE;
	for (userid = start->down; IsntNull(userid); userid = userid->next) {
		if( !pgpKeyDBObjIsReal( userid ) )
			continue;
		if( !OBJISUSERID(userid) )
			continue;
		uinfo = pgpUserIDToUserIDInfo( userid );
		if( (uinfo->confidence != 0 &&
			 uinfo->confidence != PGP_NEWTRUST_UNDEFINED) ||
			(kinfo->signedTrust != 0 && firstuserid) ) {
			ppath = sFindPathsUserID (userid, ppath, predh, predt,
						depth, maxdepth, timenow, db, altdb, NULL);
			if( IsNull(ppath) )			/* out of memory */
				break;
		}
		firstuserid = FALSE;
	}
	CLEARLOOKINGAT(kinfo);
	return ppath;
}



/*
 * Find all paths backwards from the specified target userid to some key
 * which is axiomatically trusted.
 *
 * Returns	tail pointer for new PathList
 *
 * userid	starting userid object for search backwards through web of trust
 * ppath	address of PathList pointer we set to point to head of PathList
 * maxdepth	maximum length of paths we allow
 * timenow	current timestamp
 * db		PGPKeyDB to use for memory allocations
 *
 */
static PathList **
sFindPathsBack (PGPKeyDBObj *userid, PathList **ppath, unsigned maxdepth,
	PGPUInt32 const timenow, PGPKeyDB *db, PGPKeyDB *altdb)
{
    Path           *phead = NULL,
                  **ptail = &phead;

	pgpAssert (OBJISUSERID(userid));
	/* Don't SETLOOKINGAT here; must allow use of endpoint key as signer */
	ppath = sFindPathsUserID (userid, ppath, &phead, ptail, 1, maxdepth,
		      timenow, db, altdb, NULL);
	return ppath;
}

/*
 * Test whether the given key has at least one userid with defined
 * confidence, or is confident by being signed by meta introducers, or
 * is confident by being axiomatic.
 */
static PGPBoolean
sKeyHasConfidence (PGPKeyDBObj *key)
{
	PGPKeyDBObj		*uid;
	PGPKeyInfo *	kinfo;
	PGPUserIDInfo *	uinfo;

	pgpAssert (OBJISKEY(key));

	if( pgpKeyAxiomatic (key) )
		return TRUE;

	kinfo = pgpKeyToKeyInfo( key );
	if( kinfo->signedTrust != 0 )
		return TRUE;

	/* True if any userids have defined confidence */
	for (uid = key->down; IsntNull(uid); uid = uid->next) {
		if( !pgpKeyDBObjIsReal( uid ) )
			continue;
		if( !OBJISUSERID(uid) )
				continue;
		uinfo = pgpUserIDToUserIDInfo( uid );
		if( uinfo->confidence != PGP_NEWTRUST_UNDEFINED &&
				   uinfo->confidence != 0 )
			return TRUE;
	}
	return FALSE;
}

#if 0
/*
 * Test whether the given userid has defined confidence, or is confident
 * because the parent key is axiomatic or signed by meta introducers.
 */
static PGPBoolean
sUserIDHasConfidence (PGPKeyDBObj *userid)
{
	PGPKeyDBObj		*key;
	PGPKeyInfo *	kinfo;
	PGPUserIDInfo *	uinfo;

	pgpAssert (OBJISUSERID(userid));

	key = userid->up;
	pgpAssert (OBJISKEY(key));

	if( pgpKeyAxiomatic (key) )
		return TRUE;

	kinfo = pgpKeyToKeyInfo( key );
	if( kinfo->signedTrust != 0 )
		return TRUE;

	uinfo = pgpUserIDToUserIDInfo( userid );
	if( uinfo->confidence != PGP_NEWTRUST_UNDEFINED &&
					uinfo->confidence != 0 )
		return TRUE;

	return FALSE;
}
#endif


/******************** Trust Model 2 Helpers *************************/



	PGPUInt16 
pgpKeyCalcTrust(PGPKeyDBObj *key)
{
	PGPUInt16 trust;
	double confidence;

	pgpAssert(OBJISKEY(key));

	confidence = pathKeyConfidence (key);
	if( confidence >= 1. )
		trust = PGP_TRUST_INFINITE;
	else
		trust = pgpDoubleToTrust (1. / (1.-confidence));
	return trust;
}
	       



/* Meta-Introducer and trust signature support */



/*
 * Given a signature of level >= 1, a current trust level, and an allowed
 * further recursion depth, calculate the signedTrust levels for the key,
 * and propagate further if level > 1.  depthLimit tells how many levels
 * max we can propagate, counting this as one.  That is used to enforce
 * both a maximum limit on how deep this process goes, and for each
 * MI/MMI etc. to limit how far forward trust goes depending on the
 * amount of "meta", that is, the level.
 *
 * A level of 0 means an ordinary signature; those aren't considered here.
 * A level of 1 means a trust signature, typically issued by a meta-
 * introducer, but also possibly by an axiomatic key.  Those are applied
 * here to form the signedTrust level on the key.  A simple maximum is
 * used to deal with multiple signed trusts on the key (e. if both a
 * MI and the user specified trust on the key).
 * A level of 2 means a meta introducer.  Any trust signatures by him
 * get propagated via one level of recursion.
 * Higher levels allow more levels of recursion.
 *
 * We apply several simplifications which future versions may enhance.
 * We only allow 2nd-level (meta and above) propagation if fully
 * trusted.  That is, meta introducers, and the user himself, can specify
 * partial trust levels.  But the MI, or an MMI, etc., must be given
 * full trust.  In this trust model we can't easily handle gracefully
 * degrading trust.
 */
static void
mntApplyTrustSig (PGPKeyDBObj const *sig, PGPByte trustValue,
				  PGPUInt32 depthLimit, int thresh, PGPUInt32 timenow)
{
	PGPKeyDBObj		*key;
	PGPKeyInfo *	kinfo;
	PGPSigInfo *	sinfo;
	PGPByte			trustVal;

	pgpAssert( OBJISSIG( sig ) );
	sinfo = pgpSigToSigInfo( sig );

	/* First calculate signed trust on this key. */

	/* Don't count nonexportable sigs by others */
	if( mntForeignSignature(sig) )
		return;

	/* For now support only full trust on meta introducer signatures */
	if( trustValue < thresh && sinfo->trustLevel >= 2 )
		return;

	/*
	 * See if trust signature is ruled out by regexp.
	 * (Note that this looks not at the sig's regexp, but at any on the
	 * signing key.  E. a meta introducer may include a regexp on a sig
	 * it issues.)
	 */
	if( !mntSigOKWithRegexp( sig )  )
		return;

	/* Find signed key */
	key = sig->up;
	while (!OBJISTOPKEY(key))
		key = key->up;
	
	kinfo = pgpKeyToKeyInfo( key );

	/*
	 * For now only use the maximum value of signed trusts, don't try
	 * to accumulate them.  Thorny problems!
	 */
	trustVal = sinfo->trustValue;

	/*
	 * Mark trust value.  If ours is used, copy any regexp associated with
	 * the signature.
	 * Have some heuristics to compare regexp and non-regexp sigs.
	 */
	if( SIGUSESREGEXP( sinfo ) ) {
		if( kinfo->signedTrust > 0 && IsNull(kinfo->regexp) ) {
			/* Key already has some non-regexp trust, so leave it */
		} else if( trustVal > kinfo->signedTrust ) {
			/* Key had no trust or regexp trust, and we are stronger */
			void *rexp = pgpSigRegexp( sig );
			/* Abort this chain if some problem parsing regexp */
			if( IsNull(rexp) )
				return;
			kinfo->signedTrust = trustVal;
			kinfo->regexp = rexp;
		}
	} else {
		if( IsntNull(kinfo->regexp) || trustVal > kinfo->signedTrust ) {
			/*
			 * Key had regexp trust, but we don't; or key had no regexp trust,
			 * but we are stronger.
			 */
			kinfo->regexp = NULL;
			kinfo->signedTrust = trustVal;
		}
	}
	
	/*
	 * Then, if level > 1 and we have not reached depthLimit,
	 * propagate forwards
	 */

	if( sinfo->trustLevel > 1 && depthLimit > 1 ) {
		PGPKeyDBObj const *keysig = kinfo->sigsby;
		while( IsntNull(keysig) ) {
			PGPKeyDBObj *newestsig;
			PGPSigInfo *newestsinfo;

			pgpAssert( OBJISSIG( keysig ) );
			newestsig = mntNewestSiblingSig(&keysig);
			if( !mntSigIsValid( newestsig, timenow ) )
				continue;
			newestsinfo = pgpSigToSigInfo( newestsig );

			/* Skip if not a trust sig */
			if( newestsinfo->trustLevel < 1 )
				continue;
			/* Skip if not a valid key sig */
			if( !mntSigIsValidTimeKeySig (newestsig, timenow) )
				continue;
			/*
			 * Here we have a good trust or metaintroducer si
			 * Propagate it forward.
			 */
			mntApplyTrustSig (newestsig, sinfo->trustValue,
					 pgpMin(sinfo->trustLevel-1, (PGPByte)depthLimit-1),
					 thresh, timenow);
		}
	}
}


/******************** Trust Propagation Main *************************/


	
/* Do preliminary work for trustprop */
	static PGPKeyDBObj const *
sPropagateTrustPass1( PGPKeyDB *db, PGPKeySetRef set, PGPKeyDB *altdb,
					  PGPUInt32 const timenow, PGPBoolean clearValidity,
					  PGPBoolean *bChanged, PGPKeySet *changedSet )
{
	PGPKeyDBObj const *list;
	PGPKeyDBObj *key, *child;
	PGPKeyDBObj *sig;
	PGPKeyInfo *kinfo;
	PGPKeyInfo *kinfo2;
	PGPUserIDInfo *uinfo;
	PGPSigInfo *sinfo;
	PGPSigInfo *sinfo2 = NULL;
	unsigned tmptrust;

	/*
	 * Preprocessing: reset all userid trusts to 0, and initialize list
	 * of trusted keys to the axiomatic ones.
	 */
	list = NULL;
	for (key = db->firstKeyInDB; IsntNull(key); key = key->next) {
		if( !pgpKeyDBObjIsReal( key ) )
			continue;
		if( !pgpKeySetIsMember( key, set ) )
			continue;
		pgpAssert(OBJISKEY(key));
		kinfo = pgpKeyToKeyInfo( key );
		kinfo->signedTrust = 0;
		CLEARLOOKINGAT(kinfo);
		for (child = key->down; IsntNull(child); child = child->next) {
			if( !pgpKeyDBObjIsReal( child ) )
				continue;
			if( !pgpKeySetIsMember( child, set ) )
				continue;
			if( clearValidity && OBJISUSERID(child) ) {
				uinfo = pgpUserIDToUserIDInfo( child );
				uinfo->valid = 0;
			}
		}
		/*
		 * Find each key's revoked status - find
		 * the most important self-signature.
		 */
		sig = 0;
		for (child = key->down; IsntNull(child); child = child->next) {
			if( !pgpKeyDBObjIsReal( child ) )
				continue;
			if( !pgpKeySetIsMember( child, set ) )
				continue;
			/*
			 * Ignore sigs by others, unchecked sigs,
			 * postdated sigs, and expired sigs.
			 * @@@ TODO: change the CHECKED and TRIED bits
			 * For untried revocation sigs, accept them if key's
			 * trust bits already show it as revoked.  PGP 2 does
			 * not store trust packets on revocation signatures, and so
			 * neither does this library, to avoid crashing older PGP's
			 * when they are run on our keyrings.
			 */
			if( OBJISSIG(child) ) {
				sinfo = pgpSigToSigInfo( child );
				if( mntSigIsValidTime(timenow, sinfo->tstamp,
									  sinfo->sigvalidity)) {
					/* Any revocation certificate wins, period. */
					if( sigRevokesKey(child) ) {
						sig = child;
						sinfo2 = sinfo;
						break;
					}
					/* Among other checked selfsigs, choose the most recent */
					if( sinfo->by == key
						&& (sinfo->trust & PGP_SIGTRUSTF_CHECKED) ) {
						if( IsNull(sig) || (sinfo2->tstamp < sinfo->tstamp) ) {
							sig = child;
							sinfo2 = sinfo;
						}
					}
				}
			}
		}
		sinfo = sinfo2;

		/* At this point sig holds most recent sig, or first revocation
		 * sig found, which is directly on the key.
		 */

		tmptrust = kinfo->trust;
		/* Revocation is a function of revocation certificates.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -