diff options
-rw-r--r-- | doc/gpg.texi | 10 | ||||
-rw-r--r-- | g10/export.c | 29 | ||||
-rw-r--r-- | g10/import.c | 60 | ||||
-rw-r--r-- | g10/misc.c | 2 | ||||
-rw-r--r-- | g10/options.h | 2 |
5 files changed, 94 insertions, 9 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi index 7f55cc7e3..843e91c5c 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2342,6 +2342,11 @@ opposite meaning. The options are: on the keyring. This option is the same as running the @option{--edit-key} command "clean" after import. Defaults to no. + @item import-drop-uids + Do not import any user ids or their binding signatures. This option + can be used to update only the subkeys or other non-user id related + information. + @item repair-keys. After import, fix various problems with the keys. For example, this reorders signatures, and strips duplicate signatures. Defaults to yes. @@ -2506,6 +2511,11 @@ opposite meaning. The options are: running the @option{--edit-key} command "minimize" before export except that the local copy of the key is not modified. Defaults to no. + @item export-drop-uids + Do no export any user id or attribute packets or their associates + signatures. Note that due to missing user ids the resulting output is + not strictly RFC-4880 compliant. + @item export-pka Instead of outputting the key material output PKA records suitable to put into DNS zone files. An ORIGIN line is printed before each diff --git a/g10/export.c b/g10/export.c index e94e959fb..b140e28cb 100644 --- a/g10/export.c +++ b/g10/export.c @@ -97,7 +97,7 @@ cleanup_export_globals (void) } -/* Option parser for export options. See parse_options fro +/* Option parser for export options. See parse_options for details. */ int parse_export_options(char *str,unsigned int *options,int noisy) @@ -114,6 +114,8 @@ parse_export_options(char *str,unsigned int *options,int noisy) N_("remove unusable parts from key during export")}, {"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL, N_("remove as much as possible from key during export")}, + {"export-drop-uids", EXPORT_DROP_UIDS, NULL, + N_("Do not export user id or attribute packets")}, {"export-pka", EXPORT_PKA_FORMAT, NULL, NULL }, {"export-dane", EXPORT_DANE_FORMAT, NULL, NULL }, @@ -136,14 +138,20 @@ parse_export_options(char *str,unsigned int *options,int noisy) int rc; rc = parse_options (str, options, export_opts, noisy); - if (rc && (*options & EXPORT_BACKUP)) + if (!rc) + return 0; + + /* Alter other options we want or don't want for restore. */ + if ((*options & EXPORT_BACKUP)) { - /* Alter other options we want or don't want for restore. */ *options |= (EXPORT_LOCAL_SIGS | EXPORT_ATTRIBUTES | EXPORT_SENSITIVE_REVKEYS); *options &= ~(EXPORT_CLEAN | EXPORT_MINIMAL | EXPORT_PKA_FORMAT | EXPORT_DANE_FORMAT); } + /* Dropping uids also means to drop attributes. */ + if ((*options & EXPORT_DROP_UIDS)) + *options &= ~(EXPORT_ATTRIBUTES); return rc; } @@ -1575,7 +1583,7 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, if (node->pkt->pkttype == PKT_COMMENT) continue; - /* Skip ring trust packets - they should not ne here anyway. */ + /* Skip ring trust packets - they should not be here anyway. */ if (node->pkt->pkttype == PKT_RING_TRUST) continue; @@ -1650,6 +1658,19 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, } } + /* Don't export user ids (and attributes)? This is not RFC-4880 + * compliant but we allow it anyway. */ + if ((options & EXPORT_DROP_UIDS) + && node->pkt->pkttype == PKT_USER_ID) + { + /* Skip until we get to something that is not a user id (or + * attrib) or a signature on it. */ + while (kbctx->next && kbctx->next->pkt->pkttype == PKT_SIGNATURE) + kbctx = kbctx->next; + + continue; + } + /* Don't export attribs? */ if (!(options & EXPORT_ATTRIBUTES) && node->pkt->pkttype == PKT_USER_ID diff --git a/g10/import.c b/g10/import.c index dbf600079..1f334dcb8 100644 --- a/g10/import.c +++ b/g10/import.c @@ -121,6 +121,7 @@ static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, static int delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, unsigned int options); static int any_uid_left (kbnode_t keyblock); +static int remove_all_uids (kbnode_t *keyblock); static int merge_blocks (ctrl_t ctrl, unsigned int options, kbnode_t keyblock_orig, kbnode_t keyblock, u32 *keyid, @@ -181,6 +182,9 @@ parse_import_options(char *str,unsigned int *options,int noisy) {"import-minimal",IMPORT_MINIMAL|IMPORT_CLEAN,NULL, N_("remove as much as possible from key after import")}, + {"import-drop-uids", IMPORT_DROP_UIDS, NULL, + N_("Do not import user id or attribute packets")}, + {"import-export", IMPORT_EXPORT, NULL, N_("run import filters and export key immediately")}, @@ -1728,7 +1732,9 @@ import_one (ctrl_t ctrl, } - if (!uidnode ) + /* Unless import-drop-uids has been requested we don't allow import + * of a key without UIDs. */ + if (!uidnode && !(options & IMPORT_DROP_UIDS)) { if (!silent) log_error( _("key %s: no user ID\n"), keystr_from_pk(pk)); @@ -1755,7 +1761,11 @@ import_one (ctrl_t ctrl, return 0; } - collapse_uids(&keyblock); + /* Remove or collapse the user ids. */ + if ((options & IMPORT_DROP_UIDS)) + remove_all_uids (&keyblock); + else + collapse_uids (&keyblock); /* Clean the key that we're about to import, to cut down on things that we have to clean later. This has no practical impact on the @@ -1802,7 +1812,10 @@ import_one (ctrl_t ctrl, } } - if (!delete_inv_parts (ctrl, keyblock, keyid, options ) ) + /* Delete invalid parts and without the drop otions bail out if + * there are no user ids. */ + if (!delete_inv_parts (ctrl, keyblock, keyid, options) + && !(options & IMPORT_DROP_UIDS) ) { if (!silent) { @@ -3417,14 +3430,51 @@ any_uid_left (kbnode_t keyblock) -/**************** +/* Delete all user ids from KEYBLOCK. + * Returns: True if the keyblock has changed. */ +static int +remove_all_uids (kbnode_t *keyblock) +{ + kbnode_t node; + int any = 0; + + for (node = *keyblock; node; node = node->next) + { + if (is_deleted_kbnode (node)) + continue; + + if (node->pkt->pkttype != PKT_USER_ID) + continue; + + /* We are at the first user id. Delete everything up to the + * first subkey. */ + for (; node; node = node->next) + { + if (is_deleted_kbnode (node)) + continue; + + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY) + break; + delete_kbnode (node); + any = 1; + } + break; /* All done. */ + } + + commit_kbnode (keyblock); + return any; +} + + +/* * It may happen that the imported keyblock has duplicated user IDs. * We check this here and collapse those user IDs together with their * sigs into one. * Returns: True if the keyblock has changed. */ int -collapse_uids( kbnode_t *keyblock ) +collapse_uids (kbnode_t *keyblock) { kbnode_t uid1; int any=0; diff --git a/g10/misc.c b/g10/misc.c index d7a3ee3f2..89b21e257 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1521,6 +1521,8 @@ optlen(const char *s) return strlen(s); } + +/* Note: This function returns true on success. */ int parse_options(char *str,unsigned int *options, struct parse_options *opts,int noisy) diff --git a/g10/options.h b/g10/options.h index 7defbda76..faaf53503 100644 --- a/g10/options.h +++ b/g10/options.h @@ -360,6 +360,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define IMPORT_RESTORE (1<<10) #define IMPORT_REPAIR_KEYS (1<<11) #define IMPORT_DRY_RUN (1<<12) +#define IMPORT_DROP_UIDS (1<<13) #define EXPORT_LOCAL_SIGS (1<<0) #define EXPORT_ATTRIBUTES (1<<1) @@ -370,6 +371,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define EXPORT_PKA_FORMAT (1<<6) #define EXPORT_DANE_FORMAT (1<<7) #define EXPORT_BACKUP (1<<10) +#define EXPORT_DROP_UIDS (1<<13) #define LIST_SHOW_PHOTOS (1<<0) #define LIST_SHOW_POLICY_URLS (1<<1) |