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 + -
显示快捷键?