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

📄 pgprngmnt.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			newseg = pathAlloc(pool);
			if (!newseg) {
				/* Out of memory */
				return NULL;
			}
			newseg->dest = name->g.up;
			newseg->src = sigkey;
			newseg->next = NULL;
			newseg->confidence = 1.0;
			newpredt = pathAddSeg (predt, newseg);
			ppath = ringFindPathsName (pairedname, ppath, predh, newpredt,
				depth, maxdepth, confset, allset, timenow, pool, name->g.down);
			pathFree (newseg, pool);
			*predt = NULL;
			if (!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 ringFindPathsName
 * maxdepth	maximum length of paths we allow
 * confset	ringset for trusted keys
 * allset	ringset for all keys
 * timenow	current timestamp
 * pool		ringpool to use for memory allocations
 *
 */
static PathList **
ringFindPathsKey (RingObject *start, PathList **ppath,
	Path **predh, Path **predt, unsigned depth,
    unsigned maxdepth, RingSet const *confset, RingSet const *allset,
	PGPUInt32 timenow, RingPool *pool)
{
	RingObject     *name;
	PGPBoolean		firstname;

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

	SETLOOKINGAT(&start->k);
	firstname = TRUE;
	for (name = start->g.down; name; name = name->g.next) {
		if (!OBJISNAME(name))
			continue;
		if ((name->n.confidence != 0 &&
			 name->n.confidence != PGP_NEWTRUST_UNDEFINED) ||
			(start->k.signedTrust != 0 && firstname)) {
			ppath = ringFindPathsName (name, ppath, predh, predt,
						depth, maxdepth, confset, allset, timenow, pool, NULL);
			if (!ppath)				/* out of memory */
				break;
		}
		firstname = FALSE;
	}
	CLEARLOOKINGAT(&start->k);
	return ppath;
}



/*
 * Find all paths backwards from the specified target name to some key
 * which is axiomatically trusted.
 *
 * Returns	tail pointer for new PathList
 *
 * name		starting name 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
 * confset	ringset for trusted keys
 * allset	ringset for all keys
 * timenow	current timestamp
 * pool		ringpool to use for memory allocations
 *
 */
static PathList **
ringFindPathsBack (RingObject *name, PathList **ppath, unsigned maxdepth,
	RingSet const *confset, RingSet const *allset, PGPUInt32 const timenow,
	RingPool *pool)
{
    Path           *phead = NULL,
                  **ptail = &phead;

	pgpAssert (OBJISNAME(name));
	pgpAssert (pgpIsRingSetMember(allset, name));
	/* Don't SETLOOKINGAT here; must allow use of endpoint key as signer */
	ppath = ringFindPathsName (name, ppath, &phead, ptail, 1, maxdepth,
		      confset, allset, timenow, pool, NULL);
	return ppath;
}

/*
 * Create a copy of the given ringSet, but containing only keys which have
 * at least one name with defined confidence, or which are confident by
 * being signed by meta introducers.
 */
static RingSet *
ringSetConfidentSet (RingSet const *set)
{
	RingSet		   	*trustedset;
	RingIterator	*iter;

	trustedset = ringSetCreate (ringSetPool (set));
	if (!trustedset)
		return 0;
	iter = ringIterCreate (set);
	if (!iter) {
		ringSetDestroy (trustedset);
		return 0;
	}
	ringSetAddSet (trustedset, set);
	while (ringIterNextObject (iter, 1)) {
		int goodconf = 0;				/* True if key has a conf. name */
		RingObject *key = ringIterCurrentObject (iter, 1);
		while (ringIterNextObject (iter, 2)) {
			union RingObject *nameobj;
			nameobj = ringIterCurrentObject (iter, 2);
			if (!OBJISNAME(nameobj))
				continue;
			/* Remove names with undefined or zero confidence */
			if (key->k.signedTrust != 0) {
				/* Need to keep sig-based trusted introducer names */
				goodconf = 1;
			} else if (ringKeyAxiomatic (set, key)) {
				goodconf = 1;
			} else if (nameobj->n.confidence == PGP_NEWTRUST_UNDEFINED ||
					   nameobj->n.confidence == 0) {
				ringSetRemObject (trustedset, nameobj);
			} else {
				goodconf = 1;
			}
		}
		if (!goodconf) {
			ringSetRemObject (trustedset, ringIterCurrentObject (iter, 1));
		}
	}
	ringIterDestroy (iter);
	ringSetFreeze (trustedset);
	return trustedset;
}

#endif /* PGPTRUSTMODEL==2 */


/********************** Trust Model 0 ***************************/


#if PGPTRUSTMODEL==0

/*
 * Add "inc" trust to the name signed by the given sig.
 * If the trust passes "thresh", mark the name with the level
 * and add the key that owns it to the list.  Return the expanded list.
 *
 * TODO: Do something sensible with signatures on keys.
 */
static RingKey const *
mntDoSig(RingSig const *sig, RingKey const *list,
	int const inc, int const thresh, PGPUInt32 const timenow, int const level)
{
	union RingObject *name, *key;
	PGPByte sigtype;

	(void)timenow;	/* Avoid warning */
	pgpAssert(mntSigIsValid(timenow, sig->tstamp, sig->sigvalidity));

	name = sig->up;
	if (!OBJISNAME(name)) {
		/* @@@ do anything with sigs on keys? */
		return list;
	}

#if 0
	/*  Ignore self-signature */
	key = name->n.up;
	pgpAssert(OBJISKEY(key));
	if (key == sig->by)
	    return list;
#endif

	sigtype = sig->type & 0xF0;
	if (sigtype != PGP_SIGTYPE_KEY_GENERIC)
		return list;

#if PRINT_PROGRESS
	printf("  Trust %d/%d -> %d/%d on name ",
	       name->n.trustval, thresh,
	       name->trustval + inc, thresh);
	(void)ringTtyPutString(name->name, name->len, -1u, stdout, '"', '"');
	putchar('\n');
#endif
	name->n.trustval += inc;
	/*
	 * If we are not yet at the valid level or have already
	 * marked this name as validated, bail out.
	 */
	if (name->n.trustval < thresh || NAMELEVEL(&name->n))
		return list;
	/* Passed threshold - label with certification level. */
	NAMESETLEVEL(&name->n, level);
	key = name->n.up;
	pgpAssert(OBJISKEY(key));
	if (key->g.flags & KEYF_TRUSTED ||	 /* Already listed? */
	    key->k.trust & (PGP_KEYTRUSTF_REVOKED | PGP_KEYTRUSTF_EXPIRED))
		return list;
#if PRINT_PROGRESS
	ringKeyIDprint(stdout,
"    Potential introducer: first userID trust >= 1 on keyID ",
			       key->keyID);
#endif
	key->k.util = (RingKey *)list;
	key->g.flags |= KEYF_TRUSTED;
	return &key->k;
}


/*
 * Look for other keys signed by the grandparent of sig which have the same
 * name.  Propagate the same trust to those names.  (Don't do it if they
 * have a sig by the same signing key.)  The reasoning is that the same
 * person owns both keys, he has the same name, so sigs on the first name
 * can be treated as though they are on the other name.  This will facilitate
 * moving to a new key from an old one.
 *
 * One issue not dealt with here is that if the grandparent key here is also
 * a trusted introducer, trust will move to the destination key in two ways:
 * here, by direct "pair propagation" from signatures on that key's names
 * which match the names here; and also by normal trust propagation due to
 * the signature.  This could end up counting some trust twice, although
 * in this trust model it doesn't look like it introduces any significant
 * weaknesses.
 */

static RingKey const *
mntDoMatchingNames(RingSig const *sig, RingKey const *list,
	RingSet const *set, int const inc, int const thresh,
	PGPUInt32 const timenow,
	int const level)
{
	RingObject			*name;		/* Name which sig is on */
	RingObject			*key;		/* Key which name is on */
	RingObject			*propsig;	/* All sigs by key */
	RingObject			*propname;	/* Name which propsig is on */
	RingObject			*propkey;	/* Key which propname is on */
	RingObject			*namesig;	/* All sigs on propname */
	PGPByte				 sigtype;
	PGPByte				 selfsigfound;

	pgpAssert(mntSigIsValid(timenow, sig->tstamp, sig->sigvalidity));

	/* Ignore sigs not on names */
	name = sig->up;
	if (!OBJISNAME(name))
		return list;

	/* Ignore self signatures, invalid keys, and keys which don't sign */
	key = name->n.up;
	pgpAssert(OBJISKEY(key));
	if (key == sig->by)
	    return list;
	if (key->k.trust & (PGP_KEYTRUSTF_REVOKED | PGP_KEYTRUSTF_EXPIRED))
		return list;

	/* Ignore funny kinds of sigantures */
	sigtype = sig->type & 0xF0;
	if (sigtype != PGP_SIGTYPE_KEY_GENERIC)
		return list;
		
	/*
	 * As a short-term security precaution, only propagate for fully valid
	 * names.  The problem is that otherwise, someone could have two keys,
	 * A and B, which both are marginally valid.  If both A and B sign key
	 * C which has the same name, the marginally valid signatures combine
	 * to give full validity to C.  We have a solution to this but it is
	 * complex.  For now we will only do propagation from names which are
	 * fully valid, which will mean that only fully valid keys get their
	 * trust propagated to matching names.
	 */
	if (!NAMELEVEL(&name->n))
		return list;

	/* Look for other keys with same name */
	for (propsig = key->k.sigsby; propsig;
						propsig = (RingObject *)propsig->s.nextby) {
		if (!pgpIsRingSetMember(set, propsig))
			continue;
		propname = propsig->s.up;

		/* Ignore sigs not on names */
		if (!OBJISNAME(propname))
			continue;
		propkey = propname->n.up;

		/* Ignore nonkeys(?) or self sigs */
		if (!OBJISKEY(propkey) || propkey == key)
			continue;

		/* Make sure signature is valid */
		if (!mntSigIsValidKeySig(propsig, set, timenow))
			continue;

		/* See if names match */
		if (ringNamesDiffer (set, name, propname))
			continue;

		/* Skip if name already has a sig from our signer */
		/* Also, this must be the newest sig by us */
		/* Also, it must have a self signature */
		selfsigfound = 0;
		for (namesig=propname->n.down; namesig; namesig=namesig->s.next) {
			if (!OBJISSIG(namesig) || !pgpIsRingSetMember(set, namesig))
				continue;
			if (namesig->s.by == sig->by)
				break;		/* Break out with nonnull namesig on match */
			if (namesig != propsig && namesig->s.by == key
						&& namesig->s.tstamp >= propsig->s.tstamp)
				break;		/* Break outwith nonnull namesig if not newest */
			/* Check for valid self signature */
			if (namesig->s.by == propkey
				&& mntSigIsValidKeySig(namesig, set, timenow)) {
				selfsigfound = 1;
			}
		}

		/* If namesig is non-null it had a matching sig, skip this name */
		/* Also if there was no self signature */
		if (namesig || !selfsigfound)
			continue;

		/* OK, we have a name suitable for propagating trust to */
		list = mntDoSig(&propsig->s, list, inc, thresh, timenow, level);
	}
	return list;
}


/*
 * Add "inc" trust to each name signed by a valid signature on
 * the "sigs" list.  If the trust passes "thresh", add the resultant
 * key to the list.  Return the expanded list.
 *
 * Signatures that are expired or have been superseded are weeded out.
 * Note that a postdated signature does not supersede one dated yesterday!
 */
static RingKey const *
mntWalkSigList(RingSig const *sigs, RingKey const *list,
	RingSet const *set, int const inc, int const signedinc,
	int const thresh, PGPUInt32 const timenow, int const level)
{
	RingSig const *cur;
	int effectivetrustinc;

	while (sigs) {
		/* Find the first valid checked signature in the set. */
		if (!(sigs->trust & PGP_SIGTRUSTF_CHECKED)
			|| (sigs->trust & PGP_SIGTRUSTF_REVOKEDBYCRL)
			|| !pgpIsRingSetMember(set, (RingObject *)sigs)
		    || !mntSigIsValid(timenow, sigs->tstamp, sigs->sigvalidity)
			|| mntForeignSignature(sigs, set))
		{
			sigs = sigs->nextby;
			continue;
		}
		/* The first candidate signature */
		cur = mntNewestValidSiblingSig( &sigs, set, timenow );

		/* Don't count signedinc if signature is limited by regexp */
		if (signedinc <= 0 || !mntSigOKWithRegexp( set, cur ) )
			effectivetrustinc = inc;
		else
			effectivetrustinc = pgpMax( inc, signedinc );

		if( effectivetrustinc <= 0 )
			continue;

		/* Do the trust computations on the resultant signature. */
		list = mntDoSig(cur, list, effectivetrustinc, thresh, timenow, level);

		/* Propagate sig info also to linked keys with matching names */
		list = mntDoMatchingNames(cur, list, set, effectivetrustinc, thresh,
								  timenow, level);

	}
	return list;
}

/*

⌨️ 快捷键说明

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