diff options
author | Werner Koch <wk@gnupg.org> | 2018-07-06 11:40:16 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2018-07-06 11:40:16 +0200 |
commit | 135e46ea480d749b8a9692f71d4d0bfdadd8ee2f (patch) | |
tree | 81edcf8983b699aaaf900b0be9028918b45b3d40 /g10/trust.c | |
parent | po: Add flag options for xgettext. (diff) | |
download | gnupg2-135e46ea480d749b8a9692f71d4d0bfdadd8ee2f.tar.xz gnupg2-135e46ea480d749b8a9692f71d4d0bfdadd8ee2f.zip |
gpg: Move key cleaning functions to a separate file.
* g10/trust.c (mark_usable_uid_certs, clean_sigs_from_uid)
(clean_uid_from_key, clean_one_uid, clean_key): Move to ...
* g10/key-clean.c: new file.
* g10/key-clean.h: New.
* g10/Makefile.am (gpg_sources): Add new files.
* g10/export.c, g10/import.c, g10/keyedit.c, g10/trustdb.c: Include
new header.
* g10/trustdb.h (struct key_item, is_in_klist): Move to ...
* g10/keydb.h: here.
--
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g10/trust.c')
-rw-r--r-- | g10/trust.c | 388 |
1 files changed, 0 insertions, 388 deletions
diff --git a/g10/trust.c b/g10/trust.c index 6d4f0e74b..bd1c89458 100644 --- a/g10/trust.c +++ b/g10/trust.c @@ -437,391 +437,3 @@ get_validity_string (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid) return _("revoked"); return trust_value_to_string (trustlevel); } - - - -/* - * Mark the signature of the given UID which are used to certify it. - * To do this, we first revmove all signatures which are not valid and - * from the remain ones we look for the latest one. If this is not a - * certification revocation signature we mark the signature by setting - * node flag bit 8. Revocations are marked with flag 11, and sigs - * from unavailable keys are marked with flag 12. Note that flag bits - * 9 and 10 are used for internal purposes. - */ -void -mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, - u32 *main_kid, struct key_item *klist, - u32 curtime, u32 *next_expire) -{ - kbnode_t node; - PKT_signature *sig; - - /* First check all signatures. */ - for (node=uidnode->next; node; node = node->next) - { - int rc; - - node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12); - if (node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY) - break; /* ready */ - if (node->pkt->pkttype != PKT_SIGNATURE) - continue; - sig = node->pkt->pkt.signature; - if (main_kid - && sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1]) - continue; /* ignore self-signatures if we pass in a main_kid */ - if (!IS_UID_SIG(sig) && !IS_UID_REV(sig)) - continue; /* we only look at these signature classes */ - if(sig->sig_class>=0x11 && sig->sig_class<=0x13 && - sig->sig_class-0x10<opt.min_cert_level) - continue; /* treat anything under our min_cert_level as an - invalid signature */ - if (klist && !is_in_klist (klist, sig)) - continue; /* no need to check it then */ - if ((rc=check_key_signature (ctrl, keyblock, node, NULL))) - { - /* we ignore anything that won't verify, but tag the - no_pubkey case */ - if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY) - node->flag |= 1<<12; - continue; - } - node->flag |= 1<<9; - } - /* Reset the remaining flags. */ - for (; node; node = node->next) - node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12); - - /* kbnode flag usage: bit 9 is here set for signatures to consider, - * bit 10 will be set by the loop to keep track of keyIDs already - * processed, bit 8 will be set for the usable signatures, and bit - * 11 will be set for usable revocations. */ - - /* For each cert figure out the latest valid one. */ - for (node=uidnode->next; node; node = node->next) - { - KBNODE n, signode; - u32 kid[2]; - u32 sigdate; - - if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY) - break; - if ( !(node->flag & (1<<9)) ) - continue; /* not a node to look at */ - if ( (node->flag & (1<<10)) ) - continue; /* signature with a keyID already processed */ - node->flag |= (1<<10); /* mark this node as processed */ - sig = node->pkt->pkt.signature; - signode = node; - sigdate = sig->timestamp; - kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1]; - - /* Now find the latest and greatest signature */ - for (n=uidnode->next; n; n = n->next) - { - if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n->pkt->pkttype == PKT_SECRET_SUBKEY) - break; - if ( !(n->flag & (1<<9)) ) - continue; - if ( (n->flag & (1<<10)) ) - continue; /* shortcut already processed signatures */ - sig = n->pkt->pkt.signature; - if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1]) - continue; - n->flag |= (1<<10); /* mark this node as processed */ - - /* If signode is nonrevocable and unexpired and n isn't, - then take signode (skip). It doesn't matter which is - older: if signode was older then we don't want to take n - as signode is nonrevocable. If n was older then we're - automatically fine. */ - - if(((IS_UID_SIG(signode->pkt->pkt.signature) && - !signode->pkt->pkt.signature->flags.revocable && - (signode->pkt->pkt.signature->expiredate==0 || - signode->pkt->pkt.signature->expiredate>curtime))) && - (!(IS_UID_SIG(n->pkt->pkt.signature) && - !n->pkt->pkt.signature->flags.revocable && - (n->pkt->pkt.signature->expiredate==0 || - n->pkt->pkt.signature->expiredate>curtime)))) - continue; - - /* If n is nonrevocable and unexpired and signode isn't, - then take n. Again, it doesn't matter which is older: if - n was older then we don't want to take signode as n is - nonrevocable. If signode was older then we're - automatically fine. */ - - if((!(IS_UID_SIG(signode->pkt->pkt.signature) && - !signode->pkt->pkt.signature->flags.revocable && - (signode->pkt->pkt.signature->expiredate==0 || - signode->pkt->pkt.signature->expiredate>curtime))) && - ((IS_UID_SIG(n->pkt->pkt.signature) && - !n->pkt->pkt.signature->flags.revocable && - (n->pkt->pkt.signature->expiredate==0 || - n->pkt->pkt.signature->expiredate>curtime)))) - { - signode = n; - sigdate = sig->timestamp; - continue; - } - - /* At this point, if it's newer, it goes in as the only - remaining possibilities are signode and n are both either - revocable or expired or both nonrevocable and unexpired. - If the timestamps are equal take the later ordered - packet, presuming that the key packets are hopefully in - their original order. */ - - if (sig->timestamp >= sigdate) - { - signode = n; - sigdate = sig->timestamp; - } - } - - sig = signode->pkt->pkt.signature; - if (IS_UID_SIG (sig)) - { /* this seems to be a usable one which is not revoked. - * Just need to check whether there is an expiration time, - * We do the expired certification after finding a suitable - * certification, the assumption is that a signator does not - * want that after the expiration of his certificate the - * system falls back to an older certification which has a - * different expiration time */ - const byte *p; - u32 expire; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL ); - expire = p? sig->timestamp + buf32_to_u32(p) : 0; - - if (expire==0 || expire > curtime ) - { - signode->flag |= (1<<8); /* yeah, found a good cert */ - if (next_expire && expire && expire < *next_expire) - *next_expire = expire; - } - } - else - signode->flag |= (1<<11); - } -} - - -static int -clean_sigs_from_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, - int noisy, int self_only) -{ - int deleted = 0; - kbnode_t node; - u32 keyid[2]; - - log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY - || keyblock->pkt->pkttype == PKT_SECRET_KEY); - - keyid_from_pk (keyblock->pkt->pkt.public_key, keyid); - - /* Passing in a 0 for current time here means that we'll never weed - out an expired sig. This is correct behavior since we want to - keep the most recent expired sig in a series. */ - mark_usable_uid_certs (ctrl, keyblock, uidnode, NULL, NULL, 0, NULL); - - /* What we want to do here is remove signatures that are not - considered as part of the trust calculations. Thus, all invalid - signatures are out, as are any signatures that aren't the last of - a series of uid sigs or revocations It breaks down like this: - coming out of mark_usable_uid_certs, if a sig is unflagged, it is - not even a candidate. If a sig has flag 9 or 10, that means it - was selected as a candidate and vetted. If a sig has flag 8 it - is a usable signature. If a sig has flag 11 it is a usable - revocation. If a sig has flag 12 it was issued by an unavailable - key. "Usable" here means the most recent valid - signature/revocation in a series from a particular signer. - - Delete everything that isn't a usable uid sig (which might be - expired), a usable revocation, or a sig from an unavailable - key. */ - - for (node=uidnode->next; - node && node->pkt->pkttype==PKT_SIGNATURE; - node=node->next) - { - int keep; - - keep = self_only? (node->pkt->pkt.signature->keyid[0] == keyid[0] - && node->pkt->pkt.signature->keyid[1] == keyid[1]) : 1; - - /* Keep usable uid sigs ... */ - if ((node->flag & (1<<8)) && keep) - continue; - - /* ... and usable revocations... */ - if ((node->flag & (1<<11)) && keep) - continue; - - /* ... and sigs from unavailable keys. */ - /* disabled for now since more people seem to want sigs from - unavailable keys removed altogether. */ - /* - if(node->flag & (1<<12)) - continue; - */ - - /* Everything else we delete */ - - /* At this point, if 12 is set, the signing key was unavailable. - If 9 or 10 is set, it's superseded. Otherwise, it's - invalid. */ - - if (noisy) - log_info ("removing signature from key %s on user ID \"%s\": %s\n", - keystr (node->pkt->pkt.signature->keyid), - uidnode->pkt->pkt.user_id->name, - node->flag&(1<<12)? "key unavailable": - node->flag&(1<<9)? "signature superseded" - /* */ :"invalid signature" ); - - delete_kbnode (node); - deleted++; - } - - return deleted; -} - - -/* This is substantially easier than clean_sigs_from_uid since we just - have to establish if the uid has a valid self-sig, is not revoked, - and is not expired. Note that this does not take into account - whether the uid has a trust path to it - just whether the keyholder - themselves has certified the uid. Returns true if the uid was - compacted. To "compact" a user ID, we simply remove ALL signatures - except the self-sig that caused the user ID to be remove-worthy. - We don't actually remove the user ID packet itself since it might - be resurrected in a later merge. Note that this function requires - that the caller has already done a merge_keys_and_selfsig(). - - TODO: change the import code to allow importing a uid with only a - revocation if the uid already exists on the keyring. */ - -static int -clean_uid_from_key (kbnode_t keyblock, kbnode_t uidnode, int noisy) -{ - kbnode_t node; - PKT_user_id *uid = uidnode->pkt->pkt.user_id; - int deleted = 0; - - log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY - || keyblock->pkt->pkttype == PKT_SECRET_KEY); - log_assert (uidnode->pkt->pkttype==PKT_USER_ID); - - /* Skip valid user IDs, compacted user IDs, and non-self-signed user - IDs if --allow-non-selfsigned-uid is set. */ - if (uid->created - || uid->flags.compacted - || (!uid->flags.expired && !uid->flags.revoked && opt.allow_non_selfsigned_uid)) - return 0; - - for (node=uidnode->next; - node && node->pkt->pkttype == PKT_SIGNATURE; - node=node->next) - { - if (!node->pkt->pkt.signature->flags.chosen_selfsig) - { - delete_kbnode (node); - deleted = 1; - uidnode->pkt->pkt.user_id->flags.compacted = 1; - } - } - - if (noisy) - { - const char *reason; - char *user = utf8_to_native (uid->name, uid->len, 0); - - if (uid->flags.revoked) - reason = _("revoked"); - else if (uid->flags.expired) - reason = _("expired"); - else - reason = _("invalid"); - - log_info ("compacting user ID \"%s\" on key %s: %s\n", - user, keystr_from_pk (keyblock->pkt->pkt.public_key), - reason); - - xfree (user); - } - - return deleted; -} - - -/* Needs to be called after a merge_keys_and_selfsig() */ -void -clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, - int noisy, int self_only, int *uids_cleaned, int *sigs_cleaned) -{ - int dummy = 0; - - log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY - || keyblock->pkt->pkttype == PKT_SECRET_KEY); - log_assert (uidnode->pkt->pkttype==PKT_USER_ID); - - if (!uids_cleaned) - uids_cleaned = &dummy; - - if (!sigs_cleaned) - sigs_cleaned = &dummy; - - /* Do clean_uid_from_key first since if it fires off, we don't have - to bother with the other. */ - *uids_cleaned += clean_uid_from_key (keyblock, uidnode, noisy); - if (!uidnode->pkt->pkt.user_id->flags.compacted) - *sigs_cleaned += clean_sigs_from_uid (ctrl, keyblock, uidnode, - noisy, self_only); -} - - -/* NB: This function marks the deleted nodes only and the caller is - * responsible to skip or remove them. */ -void -clean_key (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only, - int *uids_cleaned, int *sigs_cleaned) -{ - kbnode_t node; - - merge_keys_and_selfsig (ctrl, keyblock); - - for (node = keyblock->next; - node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY); - node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - clean_one_uid (ctrl, keyblock, node, noisy, self_only, - uids_cleaned, sigs_cleaned); - } - - /* Remove bogus subkey binding signatures: The only signatures - * allowed are of class 0x18 and 0x28. */ - log_assert (!node || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY)); - for (; node; node = node->next) - { - if (is_deleted_kbnode (node)) - continue; - if (node->pkt->pkttype == PKT_SIGNATURE - && !(IS_SUBKEY_SIG (node->pkt->pkt.signature) - || IS_SUBKEY_REV (node->pkt->pkt.signature))) - { - delete_kbnode (node); - if (sigs_cleaned) - ++*sigs_cleaned; - } - } -} |