mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-28 22:49:59 +01:00
gpg: Let export-clean remove expired subkeys.
* g10/key-clean.h (KEY_CLEAN_NONE, KEY_CLEAN_INVALID) (KEY_CLEAN_ENCR, KEY_CLEAN_AUTHENCR, KEY_CLEAN_ALL): New. * g10/key-clean.c (clean_one_subkey): New. (clean_all_subkeys): Add arg CLEAN_LEVEL. * g10/import.c (import_one): Call clean_all_subkeys with KEY_CLEAN_NONE. * g10/export.c (do_export_stream): Call clean_all_subkeys depedning on the export clean options. -- GnuPG-bug-id: 3622 Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
6c3567196f
commit
c2fd65ec84
11
g10/export.c
11
g10/export.c
@ -2003,15 +2003,18 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Always do the cleaning on the public key part if requested.
|
/* Always do the cleaning on the public key part if requested.
|
||||||
* Note that both export-clean and export-minimal only apply to
|
* A designated revocation is never stripped, even with
|
||||||
* UID sigs (0x10, 0x11, 0x12, and 0x13). A designated
|
* export-minimal set. */
|
||||||
* revocation is never stripped, even with export-minimal set. */
|
|
||||||
if ((options & EXPORT_CLEAN))
|
if ((options & EXPORT_CLEAN))
|
||||||
{
|
{
|
||||||
merge_keys_and_selfsig (ctrl, keyblock);
|
merge_keys_and_selfsig (ctrl, keyblock);
|
||||||
clean_all_uids (ctrl, keyblock, opt.verbose,
|
clean_all_uids (ctrl, keyblock, opt.verbose,
|
||||||
(options&EXPORT_MINIMAL), NULL, NULL);
|
(options&EXPORT_MINIMAL), NULL, NULL);
|
||||||
clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
|
clean_all_subkeys (ctrl, keyblock, opt.verbose,
|
||||||
|
(options&EXPORT_MINIMAL)? KEY_CLEAN_ALL
|
||||||
|
/**/ : KEY_CLEAN_AUTHENCR,
|
||||||
|
NULL, NULL);
|
||||||
|
commit_kbnode (&keyblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (export_keep_uid)
|
if (export_keep_uid)
|
||||||
|
@ -1764,7 +1764,8 @@ import_one (ctrl_t ctrl,
|
|||||||
merge_keys_and_selfsig (ctrl, keyblock);
|
merge_keys_and_selfsig (ctrl, keyblock);
|
||||||
clean_all_uids (ctrl, keyblock,
|
clean_all_uids (ctrl, keyblock,
|
||||||
opt.verbose, (options&IMPORT_MINIMAL), NULL, NULL);
|
opt.verbose, (options&IMPORT_MINIMAL), NULL, NULL);
|
||||||
clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
|
clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE,
|
||||||
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_kbnode_flags( keyblock );
|
clear_kbnode_flags( keyblock );
|
||||||
@ -1910,7 +1911,8 @@ import_one (ctrl_t ctrl,
|
|||||||
merge_keys_and_selfsig (ctrl, keyblock);
|
merge_keys_and_selfsig (ctrl, keyblock);
|
||||||
clean_all_uids (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
|
clean_all_uids (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
|
||||||
&n_uids_cleaned,&n_sigs_cleaned);
|
&n_uids_cleaned,&n_sigs_cleaned);
|
||||||
clean_all_subkeys (ctrl, keyblock, opt.verbose, NULL, NULL);
|
clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE,
|
||||||
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unless we are in restore mode apply meta data to the
|
/* Unless we are in restore mode apply meta data to the
|
||||||
@ -2001,7 +2003,8 @@ import_one (ctrl_t ctrl,
|
|||||||
clean_all_uids (ctrl, keyblock_orig, opt.verbose,
|
clean_all_uids (ctrl, keyblock_orig, opt.verbose,
|
||||||
(options&IMPORT_MINIMAL),
|
(options&IMPORT_MINIMAL),
|
||||||
&n_uids_cleaned,&n_sigs_cleaned);
|
&n_uids_cleaned,&n_sigs_cleaned);
|
||||||
clean_all_subkeys (ctrl, keyblock_orig, opt.verbose, NULL, NULL);
|
clean_all_subkeys (ctrl, keyblock_orig, opt.verbose, KEY_CLEAN_NONE,
|
||||||
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n_uids || n_sigs || n_subk || n_sigs_cleaned || n_uids_cleaned)
|
if (n_uids || n_sigs || n_subk || n_sigs_cleaned || n_uids_cleaned)
|
||||||
|
108
g10/key-clean.c
108
g10/key-clean.c
@ -408,24 +408,101 @@ clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function only marks the deleted nodes and the caller is
|
/* Helper for clean_all_subkeys. */
|
||||||
* responsible to skip or remove them. Needs to be called after a
|
static int
|
||||||
* merge_keys_and_selfsig. */
|
clean_one_subkey (ctrl_t ctrl, kbnode_t subkeynode, int noisy, int clean_level)
|
||||||
void
|
|
||||||
clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy,
|
|
||||||
int *subkeys_cleaned, int *sigs_cleaned)
|
|
||||||
{
|
{
|
||||||
kbnode_t node;
|
kbnode_t node;
|
||||||
|
PKT_public_key *pk = subkeynode->pkt->pkt.public_key;
|
||||||
|
unsigned int use = pk->pubkey_usage;
|
||||||
|
int do_clean = 0;
|
||||||
|
|
||||||
|
(void)ctrl;
|
||||||
|
(void)noisy;
|
||||||
|
|
||||||
|
log_assert (subkeynode->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||||
|
|| subkeynode->pkt->pkttype == PKT_SECRET_SUBKEY);
|
||||||
|
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("\tchecking subkey %08lX [%c%c%c%c%c]\n",
|
||||||
|
(ulong) keyid_from_pk (pk, NULL),
|
||||||
|
(use & PUBKEY_USAGE_ENC)? 'e':'-',
|
||||||
|
(use & PUBKEY_USAGE_SIG)? 's':'-',
|
||||||
|
(use & PUBKEY_USAGE_CERT)? 'c':'-',
|
||||||
|
(use & PUBKEY_USAGE_AUTH)? 'a':'-',
|
||||||
|
(use & PUBKEY_USAGE_UNKNOWN)? '?':'-');
|
||||||
|
|
||||||
|
if (!pk->flags.valid)
|
||||||
|
{
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("\tsubkey not valid\n");
|
||||||
|
if (clean_level == KEY_CLEAN_INVALID)
|
||||||
|
do_clean = 1;
|
||||||
|
}
|
||||||
|
if (pk->has_expired)
|
||||||
|
{
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("\tsubkey has expired\n");
|
||||||
|
if (clean_level == KEY_CLEAN_ALL)
|
||||||
|
do_clean = 1;
|
||||||
|
else if (clean_level == KEY_CLEAN_AUTHENCR
|
||||||
|
&& (use & (PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH))
|
||||||
|
&& !(use & (PUBKEY_USAGE_SIG | PUBKEY_USAGE_CERT)))
|
||||||
|
do_clean = 1;
|
||||||
|
else if (clean_level == KEY_CLEAN_ENCR
|
||||||
|
&& (use & PUBKEY_USAGE_ENC)
|
||||||
|
&& !(use & (PUBKEY_USAGE_SIG | PUBKEY_USAGE_CERT
|
||||||
|
| PUBKEY_USAGE_AUTH)))
|
||||||
|
do_clean = 1;
|
||||||
|
}
|
||||||
|
if (pk->flags.revoked)
|
||||||
|
{
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("\tsubkey has been revoked (keeping)\n");
|
||||||
|
/* Avoid any cleaning because revocations are important. */
|
||||||
|
do_clean = 0;
|
||||||
|
}
|
||||||
|
if (!do_clean)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("\t=> removing this subkey\n");
|
||||||
|
|
||||||
|
delete_kbnode (subkeynode);
|
||||||
|
for (node = subkeynode->next;
|
||||||
|
node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||||
|
|| node->pkt->pkttype == PKT_SECRET_SUBKEY);
|
||||||
|
node = node->next)
|
||||||
|
delete_kbnode (node);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This function only marks the deleted nodes and the caller is
|
||||||
|
* responsible to skip or remove them. Needs to be called after a
|
||||||
|
* merge_keys_and_selfsig. CLEAN_LEVEL is one of the KEY_CLEAN_*
|
||||||
|
* values. */
|
||||||
|
void
|
||||||
|
clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy, int clean_level,
|
||||||
|
int *subkeys_cleaned, int *sigs_cleaned)
|
||||||
|
{
|
||||||
|
kbnode_t first_subkey, node;
|
||||||
|
|
||||||
|
if (DBG_LOOKUP)
|
||||||
|
log_debug ("clean_all_subkeys: checking key %08lX\n",
|
||||||
|
(ulong) keyid_from_pk (keyblock->pkt->pkt.public_key, NULL));
|
||||||
|
|
||||||
for (node = keyblock->next; node; node = node->next)
|
for (node = keyblock->next; node; node = node->next)
|
||||||
if (!is_deleted_kbnode (node)
|
if (!is_deleted_kbnode (node)
|
||||||
&& (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
&& (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||||
|| node->pkt->pkttype == PKT_SECRET_SUBKEY))
|
|| node->pkt->pkttype == PKT_SECRET_SUBKEY))
|
||||||
break;
|
break;
|
||||||
|
first_subkey = node;
|
||||||
|
|
||||||
/* Remove bogus subkey binding signatures: The only signatures
|
/* Remove bogus subkey binding signatures: The only signatures
|
||||||
* allowed are of class 0x18 and 0x28. */
|
* allowed are of class 0x18 and 0x28. */
|
||||||
for (; node; node = node->next)
|
for (node = first_subkey; node; node = node->next)
|
||||||
{
|
{
|
||||||
if (is_deleted_kbnode (node))
|
if (is_deleted_kbnode (node))
|
||||||
continue;
|
continue;
|
||||||
@ -438,4 +515,21 @@ clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy,
|
|||||||
++*sigs_cleaned;
|
++*sigs_cleaned;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do the selected cleaning. */
|
||||||
|
if (clean_level > KEY_CLEAN_NONE)
|
||||||
|
{
|
||||||
|
for (node = first_subkey; node; node = node->next)
|
||||||
|
{
|
||||||
|
if (is_deleted_kbnode (node))
|
||||||
|
continue;
|
||||||
|
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||||
|
|| node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
||||||
|
if (clean_one_subkey (ctrl, node, noisy, clean_level))
|
||||||
|
{
|
||||||
|
if (subkeys_cleaned)
|
||||||
|
++*subkeys_cleaned;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,18 @@
|
|||||||
|
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
|
|
||||||
|
/* No explict cleaning. */
|
||||||
|
#define KEY_CLEAN_NONE 0
|
||||||
|
/* Remove only invalid subkeys (ie. missing key-bindings) */
|
||||||
|
#define KEY_CLEAN_INVALID 1
|
||||||
|
/* Remove expired encryption keys */
|
||||||
|
#define KEY_CLEAN_ENCR 2
|
||||||
|
/* Remove expired authentication and encryption keys. */
|
||||||
|
#define KEY_CLEAN_AUTHENCR 3
|
||||||
|
/* Remove all expired subkeys. */
|
||||||
|
#define KEY_CLEAN_ALL 4
|
||||||
|
|
||||||
|
|
||||||
void mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
|
void mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
|
||||||
u32 *main_kid, struct key_item *klist,
|
u32 *main_kid, struct key_item *klist,
|
||||||
u32 curtime, u32 *next_expire);
|
u32 curtime, u32 *next_expire);
|
||||||
@ -32,7 +44,8 @@ void clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode,
|
|||||||
int *uids_cleaned, int *sigs_cleaned);
|
int *uids_cleaned, int *sigs_cleaned);
|
||||||
void clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
|
void clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only,
|
||||||
int *uids_cleaned,int *sigs_cleaned);
|
int *uids_cleaned,int *sigs_cleaned);
|
||||||
void clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy,
|
void clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock,
|
||||||
|
int noisy, int clean_level,
|
||||||
int *subkeys_cleaned, int *sigs_cleaned);
|
int *subkeys_cleaned, int *sigs_cleaned);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user