1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

gpg: New export-filter export-revocs

* g10/options.h (EXPORT_REVOCS): New.
* g10/export.c (export_select_filter): New.
(struct export_filter_attic_s): Add field.
(cleanup_export_globals): Cleanup.
(parse_export_options): Add option "export-revocs".
(parse_and_set_export_filter): Parse the select type.
(do_export_revocs): New.
(do_export_stream): Add a way to select things for export.
This commit is contained in:
Werner Koch 2022-11-28 12:43:11 +01:00
parent a4698d0fb2
commit c985b52e71
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 124 additions and 6 deletions

View File

@ -2710,6 +2710,11 @@ opposite meaning. The options are:
running the @option{--edit-key} command "minimize" before export except running the @option{--edit-key} command "minimize" before export except
that the local copy of the key is not modified. Defaults to no. that the local copy of the key is not modified. Defaults to no.
@item export-revocs
Export only standalone revocation certificates of the key. This
option does not export revocations of 3rd party certificate
revocations.
@item export-dane @item export-dane
Instead of outputting the key material output OpenPGP DANE records Instead of outputting the key material output OpenPGP DANE records
suitable to put into DNS zone files. An ORIGIN line is printed before suitable to put into DNS zone files. An ORIGIN line is printed before

View File

@ -63,15 +63,17 @@ struct export_stats_s
}; };
/* A global variable to store the selector created from /* Global variables to store the selectors created from
* --export-filter keep-uid=EXPR. * --export-filter keep-uid=EXPR.
* --export-filter drop-subkey=EXPR. * --export-filter drop-subkey=EXPR.
* --export-filter select=EXPR.
* *
* FIXME: We should put this into the CTRL object but that requires a * FIXME: We should put this into the CTRL object but that requires a
* lot more changes right now. * lot more changes right now.
*/ */
static recsel_expr_t export_keep_uid; static recsel_expr_t export_keep_uid;
static recsel_expr_t export_drop_subkey; static recsel_expr_t export_drop_subkey;
static recsel_expr_t export_select_filter;
/* An object used for a linked list to implement the /* An object used for a linked list to implement the
@ -81,6 +83,7 @@ struct export_filter_attic_s
struct export_filter_attic_s *next; struct export_filter_attic_s *next;
recsel_expr_t export_keep_uid; recsel_expr_t export_keep_uid;
recsel_expr_t export_drop_subkey; recsel_expr_t export_drop_subkey;
recsel_expr_t export_select_filter;
}; };
static struct export_filter_attic_s *export_filter_attic; static struct export_filter_attic_s *export_filter_attic;
@ -105,6 +108,8 @@ cleanup_export_globals (void)
export_keep_uid = NULL; export_keep_uid = NULL;
recsel_release (export_drop_subkey); recsel_release (export_drop_subkey);
export_drop_subkey = NULL; export_drop_subkey = NULL;
recsel_release (export_select_filter);
export_select_filter = NULL;
} }
@ -128,6 +133,9 @@ parse_export_options(char *str,unsigned int *options,int noisy)
{"export-dane", EXPORT_DANE_FORMAT, NULL, NULL }, {"export-dane", EXPORT_DANE_FORMAT, NULL, NULL },
{"export-revocs", EXPORT_REVOCS, NULL,
N_("export only revocation certificates") },
{"backup", EXPORT_BACKUP, NULL, {"backup", EXPORT_BACKUP, NULL,
N_("use the GnuPG key backup format")}, N_("use the GnuPG key backup format")},
{"export-backup", EXPORT_BACKUP, NULL, NULL }, {"export-backup", EXPORT_BACKUP, NULL, NULL },
@ -184,6 +192,8 @@ parse_export_options(char *str,unsigned int *options,int noisy)
* *
* - secret :: 1 for a secret subkey, else 0. * - secret :: 1 for a secret subkey, else 0.
* - key_algo :: Public key algorithm id * - key_algo :: Public key algorithm id
*
* - select :: The key is only exported if the filter returns true.
*/ */
gpg_error_t gpg_error_t
parse_and_set_export_filter (const char *string) parse_and_set_export_filter (const char *string)
@ -197,6 +207,8 @@ parse_and_set_export_filter (const char *string)
err = recsel_parse_expr (&export_keep_uid, string+9); err = recsel_parse_expr (&export_keep_uid, string+9);
else if (!strncmp (string, "drop-subkey=", 12)) else if (!strncmp (string, "drop-subkey=", 12))
err = recsel_parse_expr (&export_drop_subkey, string+12); err = recsel_parse_expr (&export_drop_subkey, string+12);
else if (!strncmp (string, "select=", 7))
err = recsel_parse_expr (&export_select_filter, string+7);
else else
err = gpg_error (GPG_ERR_INV_NAME); err = gpg_error (GPG_ERR_INV_NAME);
@ -217,6 +229,8 @@ push_export_filters (void)
export_keep_uid = NULL; export_keep_uid = NULL;
item->export_drop_subkey = export_drop_subkey; item->export_drop_subkey = export_drop_subkey;
export_drop_subkey = NULL; export_drop_subkey = NULL;
item->export_select_filter = export_select_filter;
export_select_filter = NULL;
item->next = export_filter_attic; item->next = export_filter_attic;
export_filter_attic = item; export_filter_attic = item;
} }
@ -235,6 +249,7 @@ pop_export_filters (void)
cleanup_export_globals (); cleanup_export_globals ();
export_keep_uid = item->export_keep_uid; export_keep_uid = item->export_keep_uid;
export_drop_subkey = item->export_drop_subkey; export_drop_subkey = item->export_drop_subkey;
export_select_filter = item->export_select_filter;
} }
@ -1872,6 +1887,78 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
} }
/* Helper for do_export_stream which writes the own revocations
* certificates (if any) from KEYBLOCK to OUT. */
static gpg_error_t
do_export_revocs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
iobuf_t out, unsigned int options, int *any)
{
gpg_error_t err = 0;
kbnode_t kbctx, node;
PKT_signature *sig;
(void)ctrl;
/* NB: walk_kbnode skips packets marked as deleted. */
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); )
{
if (node->pkt->pkttype != PKT_SIGNATURE)
continue;
sig = node->pkt->pkt.signature;
/* We are only interested in revocation certifcates. */
if (!(IS_KEY_REV (sig) || IS_UID_REV (sig) || IS_SUBKEY_REV (sig)))
continue;
if (!(sig->keyid[0] == keyid[0] && sig->keyid[1] == keyid[1]))
continue; /* Not a self-signature. */
/* Do not export signature packets which are marked as not
* exportable. */
if (!(options & EXPORT_LOCAL_SIGS)
&& !sig->flags.exportable)
continue; /* not exportable */
/* Do not export packets with a "sensitive" revocation key
* unless the user wants us to. */
if (!(options & EXPORT_SENSITIVE_REVKEYS)
&& sig->revkey)
{
int i;
for (i = 0; i < sig->numrevkeys; i++)
if ((sig->revkey[i].class & 0x40))
break;
if (i < sig->numrevkeys)
continue;
}
if (!sig->flags.checked)
{
log_info ("signature not marked as checked - ignored\n");
continue;
}
if (!sig->flags.valid)
{
log_info ("signature not not valid - ignored\n");
continue;
}
err = build_packet (out, node->pkt);
if (err)
{
log_error ("build_packet(%d) failed: %s\n",
node->pkt->pkttype, gpg_strerror (err));
goto leave;
}
*any = 1;
}
leave:
return err;
}
/* For secret key export we need to setup a decryption context. /* For secret key export we need to setup a decryption context.
* Returns 0 and the context at r_cipherhd. */ * Returns 0 and the context at r_cipherhd. */
static gpg_error_t static gpg_error_t
@ -2066,13 +2153,33 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
NULL, NULL); NULL, NULL);
commit_kbnode (&keyblock); commit_kbnode (&keyblock);
} }
else if (export_keep_uid || export_drop_subkey) else if (export_keep_uid || export_drop_subkey || export_select_filter)
{ {
/* Need to merge so that for example the "usage" property /* Need to merge so that for example the "usage" property
* has been setup. */ * has been setup. */
merge_keys_and_selfsig (ctrl, keyblock); merge_keys_and_selfsig (ctrl, keyblock);
} }
if (export_select_filter)
{
int selected = 0;
struct impex_filter_parm_s parm;
parm.ctrl = ctrl;
for (parm.node = keyblock; parm.node; parm.node = parm.node->next)
{
if (recsel_select (export_select_filter,
impex_filter_getval, &parm))
{
selected = 1;
break;
}
}
if (!selected)
continue; /* Skip this keyblock. */
}
if (export_keep_uid) if (export_keep_uid)
{ {
commit_kbnode (&keyblock); commit_kbnode (&keyblock);
@ -2088,6 +2195,11 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
} }
/* And write it. */ /* And write it. */
if ((options & EXPORT_REVOCS))
err = do_export_revocs (ctrl, keyblock, keyid,
out_help? out_help : out,
options, any);
else
err = do_export_one_keyblock (ctrl, keyblock, keyid, err = do_export_one_keyblock (ctrl, keyblock, keyid,
out_help? out_help : out, out_help? out_help : out,
secret, options, stats, any, secret, options, stats, any,

View File

@ -406,6 +406,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
#define EXPORT_CLEAN (1<<5) #define EXPORT_CLEAN (1<<5)
#define EXPORT_DANE_FORMAT (1<<7) #define EXPORT_DANE_FORMAT (1<<7)
#define EXPORT_BACKUP (1<<10) #define EXPORT_BACKUP (1<<10)
#define EXPORT_REVOCS (1<<11)
#define LIST_SHOW_PHOTOS (1<<0) #define LIST_SHOW_PHOTOS (1<<0)
#define LIST_SHOW_POLICY_URLS (1<<1) #define LIST_SHOW_POLICY_URLS (1<<1)