pgprngpub.c

来自「著名的加密软件的应用于电子邮件中」· C语言 代码 · 共 2,518 行 · 第 1/4 页

C
2,518
字号

	(void)set;	/* Avoid warning */
	pgpAssert (OBJISSIG(sig));
	pgpAssert (sig->g.mask & set->mask);

	parent = sig->g.up;
	for (sibling = parent->g.down; sibling ; sibling = sibling->g.next) {
		if (!OBJISSIG(sibling) || sibling == sig)
			continue;
		if (sibling->s.by == sig->s.by) {
			if (sibling->s.trust & PGP_SIGTRUSTF_CHECKED) {
				if (sibling->s.tstamp > sig->s.tstamp) {
					if (sibling->s.type == PGP_SIGTYPE_KEY_UID_REVOKE) {
						/* Valid revocation */
						return TRUE;
					}
				}
			}
		}
	}
	return FALSE;
}


PgpTrustModel
pgpTrustModel (struct RingPool const *pool)
{
	(void)pool;
#if PGPTRUSTMODEL==0
	return PGPTRUST0;
#endif
#if PGPTRUSTMODEL==1
	return PGPTRUST1;
#endif
#if PGPTRUSTMODEL==2
	return PGPTRUST2;
#endif
}

word16
ringKeyConfidence(struct RingSet const *set, union RingObject *key)
{
#if PGPTRUSTMODEL==0
	(void)set;
	(void)key;
	pgpAssert(0);
	return 0;
#else
	pgpAssert(OBJISKEY(key));
	pgpAssert(key->g.mask & set->mask);
	(void)set;
	if (!(key->g.flags & (RINGOBJF_TRUST)))
		ringMntValidateKey (set, key);
	/* ringKeyCalcTrust handles revoked/expired keys */
	return ringKeyCalcTrust (set, key);
#endif
}

void
ringKeyID8(struct RingSet const *set, union RingObject const *key,
	byte *pkalg, byte *buf)
{
	pgpAssert(OBJISKEY(key));
	pgpAssert(key->g.mask & set->mask);
	(void)set;
	if (pkalg) {
		*pkalg = key->k.pkalg;
		if ((*pkalg | 1) == 3)		/* ViaCrypt */
			*pkalg = 1;
	}
	if (buf)
		memcpy(buf, key->k.keyID, 8);
}

int
ringKeyFingerprint16(struct RingSet const *set, union RingObject *key,
	byte *buf)
{
	byte const *p;
	size_t len;

	pgpAssert(OBJISKEY(key));
	pgpAssert(key->g.mask & set->mask);

	p = (byte const *)ringFetchObject(set, key, &len);
	if (!p)
		return ringSetError(set)->error;
	return ringKeyParseFingerprint16(p, len, buf);
}

int
ringKeyFingerprint20(struct RingSet const *set, union RingObject *key,
	byte *buf)
{
	size_t objlen;
	byte const *objbuf;

	pgpAssert(OBJISKEY(key));
	pgpAssert(key->g.mask & set->mask);

	objbuf = (byte const *)ringFetchObject(set, key, &objlen);
	return pgpFingerprint20HashBuf(objbuf, objlen, buf);
}

int
ringKeyAddSigsby(struct RingSet const *set, union RingObject *key,
	struct RingSet *dest)
{
	struct RingSig *sig;
	int i = 0;

	pgpAssert(OBJISKEY(key));
	pgpAssert(key->g.mask & set->mask);
	pgpAssert(RINGSETISMUTABLE(dest));

	for (sig = &key->k.sigsby->s; sig; sig = sig->nextby) {
		if (sig->mask & set->mask) {
			i++;
			ringSetAddObject(dest, (union RingObject *)sig);
		}
	}
	return i;
}

/* Return TRUE if the key has a secret in the given set */
int
ringKeyIsSec(struct RingSet const *set, union RingObject *key)
{
	pgpAssert(OBJISKEY(key));
	pgpAssert(key->g.mask & set->mask);

	for (key = key->g.down; key; key = key->g.next)
		if ((key->g.mask & set->mask) && OBJISSEC(key))
			return 1;
	return 0;
}

/*
 * Return TRUE if the key comes only from sources where it has secret
 * objects. In other words, the key comes from a secret key ring. This
 * is used in adding that key so that we only add it to the secret ring,
 * which is necessary due to complications relating to the "version bug".
 * Otherwise if we add a secret keyring we may end up putting the key on
 * the pubring, and it could have the incorrect version.
 * (See pgpRngRead.c for discussion of the version bug.)
 * Don't count if just on MEMRING, otherwise newly created keys return TRUE.
 */
int
ringKeyIsSecOnly(struct RingSet const *set, union RingObject *key)
{
	struct RingPool *pool = set->pool;
	int keyfilemask = key->g.mask & pool->filemask;
	int secfilemask = 0;

	if (keyfilemask == MEMRINGMASK)
		return 0;		 	/* Newly generated keys */

	for (key = key->g.down; key; key = key->g.next) {
		if ((key->g.mask & set->mask) && OBJISSEC(key)) {
			secfilemask = key->g.mask & pool->filemask;
		}
	}
	return !(keyfilemask & ~secfilemask);
}


/*
 * Return the most recent subkey associated with the key, if there is one.
 */
union RingObject *
ringKeySubkey(struct RingSet const *set, union RingObject const *key)
{
	ringmask mask = set->mask;
	union RingObject *obj, *best = NULL;
	word32 objtime, besttime = 0;

	pgpAssert(OBJISKEY(key));
	for (obj = key->g.down; obj; obj = obj->g.next) {
		if ((obj->g.mask & mask) && OBJISSUBKEY(obj)
		&& ringSubkeyValid(set, obj)) {
			objtime = ringKeyCreation(set, obj);
			if (besttime <= objtime) {
				best = obj;
				besttime = objtime;
			}
		}
	}
	return best;
}

/* Given a subkey, return its master key */
union RingObject *
ringKeyMasterkey (struct RingSet const *set, union RingObject const *subkey)
{
	(void)set;

	pgpAssert (OBJISSUBKEY(subkey));
	pgpAssert (OBJISTOPKEY(subkey->g.up));
	return subkey->g.up;
}


/*
 * Given a public key on the keyring, get the corresponding PgpPubKey.
 * Use is a usage code which limits the kinds of keys we will accept.
 * For keys which have subkeys this chooses which one to use. If use is
 * 0 we do a straight conversion of the key or subkey; if nonzero we
 * verify that the key has the required use. Return NULL if we can't
 * get a key with the required use.
 */
struct PgpPubKey *
ringKeyPubKey(struct RingSet const *set, union RingObject *key, int use)
{
	byte const *p;
	size_t len;
	struct PgpPubKey *pub;
	union RingObject *subkey = NULL;
	unsigned vsize;
	int i;

	pgpAssert(OBJISKEY(key));
	pgpAssert(key->g.mask & set->mask);

	/* Select between subkey and key if necessary */
	if (use && (OBJISSUBKEY(key)
			|| ((subkey=ringKeySubkey(set, key)) != NULL))) {
		if (use == PGP_PKUSE_SIGN_ENCRYPT) {
			ringSimpleErr(set->pool, PGPERR_PUBKEY_UNIMP);
			return NULL;
		}
		if (use == PGP_PKUSE_ENCRYPT) {
			if (OBJISTOPKEY(key)) {
				pgpAssert(subkey);
				key = subkey;
				pgpAssert (OBJISSUBKEY(key));
			}
		} else if (use == PGP_PKUSE_SIGN) {
			if (OBJISSUBKEY(key)) {
				key = key->g.up;
				pgpAssert (OBJISTOPKEY(key));
			}
		}
	}

	/* Verify key satisfies required usage */
	if (use && ((pgpKeyUse(pgpPkalgByNumber(key->k.pkalg)) & use) != use)){
		ringSimpleErr(set->pool, PGPERR_PUBKEY_UNIMP);
		return NULL;
	}

	p = (byte const *)ringFetchObject(set, key, &len);
	if (!p)
		return NULL;
	if (key->g.flags & KEYF_ERROR || len < 8) {
		i = ringKeyParse(p, len, NULL, NULL, NULL, NULL, NULL, 0);
		ringSimpleErr(set->pool, i);
		return NULL;
		}
		/*
	* A key starts with 5 or 7 bytes of data, an algorithm byte, and
	* the public components.
		*/
	if (p[0] == PGPVERSION_3) {
		vsize = 0;
	} else {
		vsize = 2;
	}
	pgpAssert(p[5+vsize] == key->k.pkalg);	/* Checked by ringKeyVerify */
	pub = pgpPubKeyFromBuf(p[5+vsize], p+6+vsize, len-6-vsize, &i);
	if (!pub) {
		ringSimpleErr(set->pool, i);
		return NULL;
	}
	memcpy(pub->keyID, key->k.keyID, sizeof(key->k.keyID));
	return pub;
}

/*
 * Return the version for a secret key. Also permissible to pass a key.
 * This should be used when we edit a pass phrase to preserve the version
 * number and avoid the infamous "version bug".
 */
PgpVersion
ringSecVersion (struct RingSet const *set, union RingObject *sec)
{
	byte *secdata;
	size_t secdatalen;

	if (!OBJISSEC(sec)) {
		sec = ringBestSec(set, sec);
		if (!sec) {
			ringSimpleErr(set->pool, PGPERR_NO_SECKEY);
			return (PgpVersion)0;
		}
	}
	secdata = (byte *)ringFetchObject (set, sec, &secdatalen);
	return (PgpVersion)secdata[0];
}


/*
 * Given a secret on a keyring, get a struct PgpSecKey (possibly locked).
 * As a hack to help the lazy programmer, you can also pass a key.
 * Use is a usage code which limits the kinds of keys we will accept.
 * For keys which have subkeys this chooses which one to use.
 */
struct PgpSecKey *
ringSecSecKey(struct RingSet const *set, union RingObject *sec, int use)
{
	byte const *p;
	size_t len;
	struct PgpSecKey *seckey;
	union RingObject *key;
	union RingObject *subkey = NULL;
	unsigned vsize;
	int i;

	if (OBJISSEC(sec)) {
		key = sec->g.up;
	} else {
		key = sec;
}
	pgpAssert(OBJISKEY(key));
	pgpAssert(sec->g.mask & set->mask);

	/* Select between subkey and key if necessary */
	if (use	&& (OBJISSUBKEY(key)
			|| ((subkey=ringKeySubkey(set, key)) != NULL))) {
		int newkey = 0;
		if (use == PGP_PKUSE_SIGN_ENCRYPT) {
			ringSimpleErr(set->pool, PGPERR_PUBKEY_UNIMP);
			return NULL;
		}
		if (use == PGP_PKUSE_ENCRYPT) {
			if (OBJISTOPKEY(key)) {
				pgpAssert(subkey);
				key = subkey;
				pgpAssert (OBJISSUBKEY(key));
				newkey = 1;
			}
		} else if (use == PGP_PKUSE_SIGN) {
			if (OBJISSUBKEY(key)) {
				key = key->g.up;
				pgpAssert (OBJISTOPKEY(key));
				newkey = 1;
			}
		}
		if (newkey || !OBJISSEC(sec)) {
			sec = ringBestSec(set, key);
			if (!sec) {
				ringSimpleErr(set->pool, PGPERR_NO_SECKEY);
				return NULL;
			}
		}
	} else if (OBJISKEY(sec)) {
		sec = ringBestSec(set, sec);
		if (!sec) {
			ringSimpleErr(set->pool, PGPERR_NO_SECKEY);
			return NULL;
		}
	}

	/* Verify key satisfies required usage */
	if (use && ((pgpKeyUse(pgpPkalgByNumber(key->k.pkalg)) & use) != use)){
		ringSimpleErr(set->pool, PGPERR_PUBKEY_UNIMP);
		return NULL;
	}

	p = (byte const *)ringFetchObject(set, sec, &len);
	if (!p)
		return NULL;
	if (sec->g.up->g.flags & KEYF_ERROR || len < 8) {
		i = ringKeyParse(p, len, NULL, NULL, NULL, NULL, NULL, 0);
		ringSimpleErr(set->pool, i);
		return NULL;
	}
	if (p[0] == PGPVERSION_3) {
		vsize = 0;
	} else {
		vsize = 2;
	}
	pgpAssert(p[5+vsize] == sec->g.up->k.pkalg); /* Checked by ringKeyVerify */
	seckey = pgpSecKeyFromBuf(p[5+vsize], p+6+vsize, len-6-vsize, &i);
	if (!seckey) {
		ringSimpleErr(set->pool, i);
		return NULL;
	}
	memcpy(seckey->keyID, sec->g.up->k.keyID, sizeof(sec->g.up->k.keyID));
	return seckey;
}


/* There ain't much to know about a name... */
char const *
ringNameName(struct RingSet const *set, union RingObject *name, size_t *lenp)
{
	pgpAssert(OBJISNAME(name));
	return (char const *)ringFetchObject(set, name, lenp);
}

/* Return the validity (*not* the trust) of a name */

byte
ringNameTrust(struct RingSet const *set, union RingObject *name)
{
union RingObject *key;
	
pgpAssert(OBJISNAME(name));
pgpAssert(name->g.mask & set->mask);
(void)set;
key = name->g.up;
pgpAssert(OBJISTOPKEY(key));
/* Force returned value if key is revoked, expired, or axiomatic */
if (key->k.trust & (PGP_KEYTRUSTF_REVOKED | PGP_KEYTRUSTF_EXPIRED))
return PGP_NAMETRUST_UNTRUSTED;
if (key->k.trust & PGP_KEYTRUSTF_BUCKSTOP)
return PGP_NAMETRUST_COMPLETE;
if (!(name->g.flags & (RINGOBJF_TRUST)))
ringMntValidateName (set, name);
return name->n.trust & PGP_NAMETRUST_MASK;
}

int
ringNameWarnonly(struct RingSet const *set, union RingObject *name)
{
	pgpAssert(OBJISNAME(name));
	pgpAssert(name->g.mask & set->mask);
	(void)set;
	return name->n.trust & PGP_NAMETRUSTF_WARNONLY;
}

void
ringNameSetWarnonly(struct RingSet const *set, union RingObject *name)
{
	pgpAssert(OBJISNAME(name));
	pgpAssert(name->g.mask & set->mask);
	if (!(name->n.trust & PGP_NAMETRUSTF_WARNONLY)) {
		name->n.trust |= PGP_NAMETRUSTF_WARNONLY;
		name->g.flags |= RINGOBJF_TRUSTCHANGED;
		ringPoolMarkTrustChanged (set->pool, name->g.mask);
	}
	name->g.flags |= RINGOBJF_TRUST;
}

word16
ringNameValidity(struct RingSet const *set, union RingObject *name)
{
#if PGPTRUSTMODEL==0
    (void)set;
    (void)name;
    pgpAssert(0);
    return 0;
#else
union RingObject *key;
pgpAssert(OBJISNAME(name));
pgpAssert(name->g.mask & set->mask);
(void)set;
key = name->g.up;
pgpAssert (OBJISTOPKEY(key));
/* Force returned value if key is revoked, expired, or axiomatic */
if (key->k.trust & (PGP_KEYTRUSTF_REVOKED | PGP_KEYTRUSTF_EXPIRED))
	return 0;
if (key->k.trust & PGP_KEYTRUSTF_BUCKSTOP)
	return PGP_TRUST_INFINITE;
if (!(name->g.flags & (RINGOBJF_TRUST)))
    ringMntValidateName (set, name);
return ringTrustToIntern (name->n.validity);
#endif
}

word16
ringNameConfidence(struct RingSet const *set, union RingObject *name)
{
#if PGPTRUSTMODEL==0
	(void)set;
	(void)name;
	pgpAssert(0);
	return 0;
#else
	pgpAssert(OBJISNAME(name));
	pgpAssert(name->g.mask & set->mask);
	(void)set;
	return ringTrustToIntern (name->n.confidence);
#endif
}

int
ringNameConfidenceUndefined(struct RingSet const *set, union RingObject *name)
{
#if PGPTRUSTMODEL==0
	(void)set;
	(void)name;
	pgpAssert(0);
	return 0;
#else
	pgpAssert(OBJISNAME(name));
	pgpAssert(name->g.mask & set->mask);
	(void)set;
	return (name->n.confidence == PGP_NEWTRUST_UNDEFINED);
#endif
}


void
ringNameSetConfidence(struct RingSet const *set, union RingObject *name,
		word16 confidence)
{
#if PGPTRUSTMODEL==0
	(void)set;
	(void)name;
	(void)confidence;
	pgpAssert(0);
#else
	pgpAssert(OBJISNAME(name));
	pgpAssert(name->g.mask & set->mask);

	confidence = (word16) ringTrustToExtern (confidence);
	
	if (!(name->n.flags2 & NAMEF2_NEWTRUST) ||
	name->n.confidence != confidence) {
		name->n.confidence = (byte) confidence;
		name->n.flags2 |= NAMEF2_NEWTRUST;
		name->g.flags |= RINGOBJF_TRUSTCHANGED;
		ringPoolMarkTrustChanged (set->pool, name->g.mask);
	}
	name->g.flags |= RINGOBJF_TRUST;
#endif
}

int
ringSigError(struct RingSet const *set, union RingObject *sig)
{
	byte const *p;
	size_t len;

	pgpAssert(OBJISSIG(sig));
	pgpAssert(sig->g.mask & set->mask);

	if (!(sig->g.flags & SIGF_ERROR))
		return 0;

	p = (byte const *)ringFetchObject(set, sig, &len);
	if (!p)
		return ringSetError(set)->error;
	return ringSigParse(p, len, NULL, NULL, NULL, NULL, NULL,
		NULL, NULL, NULL);
}

union RingObject *
ringSigMaker(struct RingSet const *sset, union RingObject *sig,
	struct RingSet const *kset)
{
	(void)sset;	/* Avoid warning */
	pgpAssert(OBJISSIG(sig));
	pgpAssert(sig->g.mask & sset->mask);

	sig = sig->s.by;
	pgpAssert(OBJISKEY(sig));	 /* "sig" is now a key! */
	if (!(sig->g.mask & kset->mask))
		return NULL;
	ringObjectHold(sig);
	return sig;
}

void
ringSigID8(struct RingSet const *set, union RingObject const *sig,
	byte *pkalg, byte *buf)
{
	pgpAssert(OBJISSIG(sig));
	pgpAssert(sig->g.mask & set->mask);
	(void)set;
	sig = sig->s.by;
	pgpAssert(OBJISKEY(sig));
	if (pkalg) {
		*pkalg = sig->k.pkalg;
		if ((*pkalg | 1) == 3)
			*pkalg = 1;	/* ViaCrypt */
	}
	if (buf)
		memcpy(buf, sig->k.keyID, 8);
}

byte
ringSigTrust(struct RingSet const *set, union RingObject *sig)
{
	pgpAssert(OBJISSIG(sig));
	pgpAssert(sig->g.mask & set->mask);
	(void)set;
	if (ringSigError (set, sig))
		return PGP_SIGTRUST_INVALID;
	if (sig->s.by == NULL)
		return PGP_SIGTRUST_NOKEY;
	if (!(sig->s.trust & PGP_SIGTRUSTF_TRIED))
		return PGP_SIGTRUST_UNTRIED;
	if (!(sig->s.trust & PGP_SIGTRUSTF_CHECKED))
		return PGP_SIGTRUST_BAD;
	if (!(sig->g.flags & (RINGOBJF_TRUST))) {
		ringMntValidateKey (set, sig->s.by);
		return sig->s.by->k.trust & PGP_KEYTRUST_MASK;
		}
		else
			return sig->s.trust & PGP_KEYTRUST_MASK;
}

int
ringSigChecked(struct RingSet const *set, union RingObject *sig)
{
	pgpAssert(OBJISSIG(sig));
	pgpAssert(sig->g.mask & set->mask);
	(void)set;
	return sig->s.trust & PGP_SIGTRUSTF_CHECKED;
}

int
ringSigTried(struct RingSet const *set, union RingObject *sig)
{
	pgpAssert(OBJISSIG(sig));
	pgpAssert(sig->g.mask & set->mask);
	(void)set;
	return sig->s.trust & PGP_SIGTRUSTF_TRIED;
}

/* Call ringSigTrust to get sig status, then call this function if
   sig is good and the confidence is required. */

word16
ringSigConfidence(struct RingSet const *set, union RingObject *sig)
{
#if PGPTRUSTMODEL==0
	(void)set;

⌨️ 快捷键说明

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