📄 pgprngpub.c
字号:
RingSet const * set,
PGPByte pkalg,
PGPByte const * keyID)
{
RingKey *key;
RingKey *bestKey = NULL;
if ((pkalg|1) == 3) /* viacrypt */
pkalg = 1;
for (key = set->pool->hashtable[keyID[0]]; key; key = key->util)
{
if ((((key->pkalg|1) == 3) ? 1 : key->pkalg) == pkalg &&
memcmp(keyID, &key->keyID[4], 4) == 0)
{
if (pgpIsRingSetMember(set, (union RingObject *)key))
{
if( IsNull( bestKey ) )
{
bestKey = key;
}
else
{
/* Non-unique match. Fail */
bestKey = NULL;
break;
}
}
}
}
if( IsntNull( bestKey ) )
{
ringObjectHold((union RingObject *)bestKey);
}
return (union RingObject *)bestKey;
}
#else
union RingObject *
ringKeyById4(
RingSet const * set,
PGPByte pkalg,
PGPByte const * keyID)
{
union RingObject *key, *subkey;
union RingObject *bestKey = NULL;
if ((pkalg|1) == 3) /* viacrypt */
pkalg = 1;
for (key = set->pool->keys; key; key = key->g.next)
{
if ((((key->k.pkalg|1) == 3) ? 1 : key->k.pkalg) == pkalg &&
memcmp(keyID, &key->k.keyID[4], 4) == 0)
{
if (pgpIsRingSetMember(set, key))
{
if( IsNull( bestKey ) )
{
bestKey = key;
}
else
{
/* Non-unique match. Fail */
bestKey = NULL;
goto exit;
}
}
}
for (subkey = key->g.down; subkey; subkey = subkey->g.next)
{
if ((((subkey->k.pkalg|1) == 3) ? 1 : subkey->k.pkalg) == pkalg &&
memcmp(keyID, &subkey->k.keyID[4], 4) == 0)
{
if (pgpIsRingSetMember(set, subkey))
{
if( IsNull( bestKey ) )
{
bestKey = subkey;
}
else
{
/* Non-unique match. Fail */
bestKey = NULL;
goto exit;
}
}
}
}
}
exit:
if( IsntNull( bestKey ) )
{
ringObjectHold( bestKey );
}
return bestKey;
}
#endif
/*** Access functions for information about objects ***/
int
ringKeyError(RingSet const *set, union RingObject *key)
{
PGPByte const *p;
PGPSize len;
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
if (!(key->g.flags & KEYF_ERROR))
return 0;
p = (PGPByte const *)ringFetchObject(set, key, &len);
if (!p)
return ringSetError(set)->error;
return ringKeyParse(set->pool->context, p, len, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, 0);
}
unsigned
ringKeyBits(RingSet const *set, union RingObject *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
return key->k.keybits;
}
PGPUInt32
ringKeyCreation(RingSet const *set, union RingObject *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
return key->k.tstamp;
}
PGPUInt32
ringKeyExpiration(RingSet const *set, union RingObject *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
if (key->k.tstamp == 0 || key->k.validity == 0)
return 0; /* valid indefinitely */
else
return key->k.tstamp + (key->k.validity * 3600 * 24);
}
/*
* If called for a subkey, force to just encryption.
* If called for a key with a subkey, return the "or" of both.
* Else just do the key itself.
* Internal form of ringKeyUse - if unExpired is true, check that the
* subkeys are unexpired before saying it has encryption usage.
* ringKeyUse and ringKeyUnexpiredUse are macros that call this now.
*/
int
ringKeyUseInternal(RingSet const *set, union RingObject *key,
PGPBoolean unExpired)
{
int use;
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
use = pgpKeyUse(pgpPkalgByNumber(key->k.pkalg));
if (OBJISSUBKEY(key))
use &= PGP_PKUSE_ENCRYPT;
for (key=key->g.down; key; key=key->g.next) {
if (pgpIsRingSetMember(set, key) &&
OBJISSUBKEY(key) && ringSubkeyValid(set, key, unExpired))
use |= pgpKeyUse(pgpPkalgByNumber(key->k.pkalg));
}
return use;
}
PGPByte
ringKeyTrust(RingSet const *set, union RingObject *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
if (!(key->g.flags & (RINGOBJF_TRUST)))
ringMntValidateKey (set, key);
return pgpMax(key->k.trust & kPGPKeyTrust_Mask,
key->k.signedTrust & kPGPKeyTrust_Mask);
}
void
ringKeySetTrust(RingSet const *set, union RingObject *key, PGPByte trust)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
pgpAssert(trust==kPGPKeyTrust_Unknown || trust==kPGPKeyTrust_Never ||
trust==kPGPKeyTrust_Marginal || trust==kPGPKeyTrust_Complete);
pgpAssert (!(key->k.trust & PGP_KEYTRUSTF_BUCKSTOP));
if (key->k.trust & (PGP_KEYTRUSTF_REVOKED | PGP_KEYTRUSTF_EXPIRED))
return;
if ((key->k.trust & kPGPKeyTrust_Mask) != trust) {
key->k.trust = (key->k.trust & ~kPGPKeyTrust_Mask) + trust;
key->g.flags |= RINGOBJF_TRUSTCHANGED;
ringPoolMarkTrustChanged (set->pool, &key->g.mask);
}
key->g.flags |= RINGOBJF_TRUST;
}
/*
* Used to set a key as an "axiomatic" key, that is, one for which
* we hold the private key. This also involves setting each name on that
* key as having complete validity.
*/
void
ringKeySetAxiomatic(RingSet const *set, union RingObject *key)
{
union RingObject *name = NULL;
(void)name;
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
if (!ringKeyIsSec (set, key) ||
key->k.trust & (PGP_KEYTRUSTF_BUCKSTOP | PGP_KEYTRUSTF_REVOKED))
return; /* already axiomatic or can't set */
key->k.trust &= ~kPGPKeyTrust_Mask;
key->k.trust |= (PGP_KEYTRUSTF_BUCKSTOP | kPGPKeyTrust_Ultimate);
ringPoolMarkTrustChanged (set->pool, &key->g.mask);
key->g.flags |= (RINGOBJF_TRUSTCHANGED | RINGOBJF_TRUST);
#if PGPTRUSTMODEL>0
/* Make sure all names have axiomatic confidence */
for (name=key->g.down; name; name=name->g.next) {
if (OBJISNAME(name) && pgpIsRingSetMember(set, name))
name->n.confidence = PGP_NEWTRUST_INFINITE;
}
#endif
}
/* Reset an axiomatic key. Trust is set to undefined. */
void
ringKeyResetAxiomatic (RingSet const *set, union RingObject *key)
{
union RingObject *name = NULL;
(void)name;
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
if (!(key->k.trust & PGP_KEYTRUSTF_BUCKSTOP))
return; /* not axiomatic */
key->k.trust &= ~PGP_KEYTRUSTF_BUCKSTOP;
key->k.trust = (key->k.trust & ~kPGPKeyTrust_Mask) +
kPGPKeyTrust_Undefined;
ringPoolMarkTrustChanged (set->pool, &key->g.mask);
key->g.flags |= (RINGOBJF_TRUSTCHANGED | RINGOBJF_TRUST);
#if PGPTRUSTMODEL>0
/* Make sure all names have undefined confidence */
for (name=key->g.down; name; name=name->g.next) {
if (OBJISNAME(name) && pgpIsRingSetMember(set, name))
name->n.confidence = PGP_NEWTRUST_UNDEFINED;
}
#endif
}
int
ringKeyAxiomatic(RingSet const *set, union RingObject *key)
{
(void)set; /* Avoid warning */
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
return key->k.trust & PGP_KEYTRUSTF_BUCKSTOP;
}
/* Return TRUE if the key is a subkey */
int
ringKeyIsSubkey (RingSet const *set, union RingObject const *key)
{
(void)set;
return OBJISSUBKEY(key);
}
int
ringKeyDisabled(RingSet const *set, union RingObject *key)
{
(void)set; /* Avoid warning */
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
return key->k.trust & PGP_KEYTRUSTF_DISABLED;
}
void
ringKeyDisable(RingSet const *set, union RingObject *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
if (!(key->k.trust & PGP_KEYTRUSTF_DISABLED)) {
key->k.trust |= PGP_KEYTRUSTF_DISABLED;
key->g.flags |= RINGOBJF_TRUSTCHANGED;
ringPoolMarkTrustChanged (set->pool, &key->g.mask);
}
key->g.flags |= RINGOBJF_TRUST;
}
void
ringKeyEnable(RingSet const *set, union RingObject *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
if (key->k.trust & PGP_KEYTRUSTF_DISABLED) {
key->k.trust &= ~PGP_KEYTRUSTF_DISABLED;
key->g.flags |= RINGOBJF_TRUSTCHANGED;
ringPoolMarkTrustChanged (set->pool, &key->g.mask);
}
key->g.flags |= RINGOBJF_TRUST;
}
int
ringKeyRevoked(RingSet const *set, union RingObject *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
#if PGPTRUSTMODEL>0
if (!(key->g.flags & (RINGOBJF_TRUST)))
ringMntValidateKey (set, key);
#endif
return key->k.trust & PGP_KEYTRUSTF_REVOKED;
}
/*
* Return true if the specified signature has been revoked, that is,
* if there is a newer signature by the same key which is of type
* UID_REVOKE, or if it has been revoked by CRL.
*/
int
ringSigRevoked (RingSet const *set, union RingObject *sig)
{
RingObject *parent,
*sibling;
(void)set; /* Avoid warning */
pgpAssert (OBJISSIG(sig));
pgpAssert(pgpIsRingSetMember(set, sig));
/* Sigs can be declared irrevocable at creation time */
if (!SIGISREVOCABLE(&sig->s))
return FALSE;
/* Check revoked flag */
if (sig->s.trust & PGP_SIGTRUSTF_REVOKEDBYCRL)
return TRUE;
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 (RingPool const *pool)
{
(void)pool;
#if PGPTRUSTMODEL==0
return PGPTRUST0;
#endif
#if PGPTRUSTMODEL==1
return PGPTRUST1;
#endif
#if PGPTRUSTMODEL==2
return PGPTRUST2;
#endif
}
PGPUInt16
ringKeyConfidence(RingSet const *set, union RingObject *key)
{
#if PGPTRUSTMODEL==0
(void)set;
(void)key;
pgpAssert(0);
return 0;
#else
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
/* Don't try on-the-fly validation, assume it's been done */
/* if (!(key->g.flags & (RINGOBJF_TRUST))) */
/* ringMntValidateKey (set, key); */
/* ringKeyCalcTrust handles revoked/expired keys */
return ringKeyCalcTrust (set, key);
#endif
}
void
ringKeyID8(
RingSet const *set,
union RingObject const *key,
PGPByte *pkalg,
PGPKeyID *keyID)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
if (pkalg) {
*pkalg = key->k.pkalg;
if ((*pkalg | 1) == 3) /* ViaCrypt */
*pkalg = 1;
}
if (keyID)
{
pgpNewKeyIDFromRawData( key->k.keyID, 8, keyID );
}
}
void
ringKeyID4(
RingSet const *set,
union RingObject const *key,
PGPByte *pkalg,
PGPKeyID *keyID)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
if (pkalg) {
*pkalg = key->k.pkalg;
if ((*pkalg | 1) == 3) /* ViaCrypt */
*pkalg = 1;
}
if (keyID)
{
pgpNewKeyIDFromRawData( &key->k.keyID[4], 4, keyID );
}
}
PGPBoolean
ringKeyV3(RingSet const *set, union RingObject const *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
(void)set;
return !!KEYISV3(&key->k);
}
int
ringKeyFingerprint16(RingSet const *set, union RingObject *key,
PGPByte *buf)
{
PGPByte const *p;
PGPSize len;
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
p = (PGPByte const *)ringFetchObject(set, key, &len);
if (!p)
return ringSetError(set)->error;
return ringKeyParseFingerprint16(set->pool->context, p, len, buf);
}
int
ringKeyFingerprint20(RingSet const *set, union RingObject *key,
PGPByte *buf)
{
PGPSize objlen;
PGPByte const *objbuf;
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
objbuf = (PGPByte const *)ringFetchObject(set, key, &objlen);
return pgpFingerprint20HashBuf(set->pool->context, objbuf, objlen, buf);
}
/* This does a 20 byte fingerprint based solely on the numeric material */
int
ringKeyFingerprint20n(RingSet const *set, union RingObject *key,
PGPByte *buf)
{
PGPSize objlen;
unsigned int numlen;
PGPByte const *objbuf, *numbuf;
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
objbuf = (PGPByte const *)ringFetchObject(set, key, &objlen);
numbuf = ringKeyParseNumericData(objbuf, objlen, &numlen);
return pgpFingerprint20HashBuf(set->pool->context, numbuf, numlen, buf);
}
int
ringKeyAddSigsby(RingSet const *set, union RingObject *key,
RingSet *dest)
{
RingSig *sig;
int i = 0;
pgpAssert(OBJISTOPKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
pgpAssert(RINGSETISMUTABLE(dest));
for (sig = &key->k.sigsby->s; sig; sig = sig->nextby) {
if (pgpIsRingSetMember(set, (union RingObject *)sig)) {
i++;
ringSetAddObject(dest, (union RingObject *)sig);
}
}
return i;
}
/* Return TRUE if the key has a secret in the given set */
int
ringKeyIsSec(RingSet const *set, union RingObject *key)
{
pgpAssert(OBJISKEY(key));
pgpAssert(pgpIsRingSetMember(set, key));
for (key = key->g.down; key; key = key->g.next)
if (pgpIsRingSetMember(set, key) && OBJISSEC(key))
return 1;
return 0;
}
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -