diff options
Diffstat (limited to '')
-rw-r--r-- | g10/trustdb.c | 76 |
1 files changed, 68 insertions, 8 deletions
diff --git a/g10/trustdb.c b/g10/trustdb.c index f69055756..d5e4e2333 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1644,7 +1644,7 @@ clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy) int clean_uids_from_key(KBNODE keyblock,int noisy) { - int uidcount=0,delete_until_next,deleted=0; + int uidcount=0,delete_until_next=0,deleted=0; KBNODE node; assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY); @@ -1667,11 +1667,12 @@ clean_uids_from_key(KBNODE keyblock,int noisy) { if(node->pkt->pkttype==PKT_USER_ID) { + PKT_user_id *uid=node->pkt->pkt.user_id; + /* Skip valid user IDs, and non-self-signed user IDs if --allow-non-selfsigned-uid is set. */ - if(node->pkt->pkt.user_id->created - || (!node->pkt->pkt.user_id->is_expired - && !node->pkt->pkt.user_id->is_revoked + if(uid->created + || (!uid->is_expired && !uid->is_revoked && opt.allow_non_selfsigned_uid)) delete_until_next=0; else @@ -1682,12 +1683,11 @@ clean_uids_from_key(KBNODE keyblock,int noisy) if(noisy) { char *reason; - char *user=utf8_to_native(node->pkt->pkt.user_id->name, - node->pkt->pkt.user_id->len,0); + char *user=utf8_to_native(uid->name,uid->len,0); - if(node->pkt->pkt.user_id->is_revoked) + if(uid->is_revoked) reason=_("revoked"); - else if(node->pkt->pkt.user_id->is_expired) + else if(uid->is_expired) reason=_("expired"); else reason=_("invalid"); @@ -1708,6 +1708,66 @@ clean_uids_from_key(KBNODE keyblock,int noisy) return deleted; } +/* Another cleaning function. This only cleans encrypt-only subkeys + since an expired/revoked encryption key is basically useless, but + an expired/revoked key that can sign is still needed to verify old + signatures. */ +int +clean_subkeys_from_key(KBNODE keyblock,int noisy) +{ + int delete_until_next=0,deleted=0; + KBNODE node; + char *main_key=NULL; + + assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY); + + merge_keys_and_selfsig(keyblock); + + if(noisy) + main_key=m_strdup(keystr(keyblock->pkt->pkt.public_key->keyid)); + + for(node=keyblock->next;node;node=node->next) + { + if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY) + { + PKT_public_key *pk=node->pkt->pkt.public_key; + + /* If it is valid, not expired, and not revoked, leave it + alone. If a key can make signatures, leave it alone. */ + if(pk->pubkey_usage!=PUBKEY_USAGE_ENC + || (pk->is_valid && !pk->has_expired && !pk->is_revoked)) + delete_until_next=0; + else + { + delete_until_next=1; + deleted++; + + if(noisy) + { + char *reason; + + if(pk->is_revoked) + reason=_("revoked"); + else if(pk->has_expired) + reason=_("expired"); + else + reason=_("invalid"); + + log_info("removing subkey %s from key %s: %s\n", + keystr_from_pk(pk),main_key,reason); + } + } + } + + if(delete_until_next) + delete_kbnode(node); + } + + m_free(main_key); + + return deleted; +} + /* Used by validate_one_keyblock to confirm a regexp within a trust signature. Returns 1 for match, and 0 for no match or regex error. */ |