aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/gpg.texi10
-rw-r--r--g10/export.c29
-rw-r--r--g10/import.c60
-rw-r--r--g10/misc.c2
-rw-r--r--g10/options.h2
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)