aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--doc/gpgme.texi11
-rw-r--r--src/engine-gpg.c7
-rw-r--r--src/export.c17
-rw-r--r--src/gpgme-tool.c2
-rw-r--r--src/gpgme.h.in1
-rw-r--r--tests/run-export.c15
7 files changed, 51 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index e57637d5..1395c5db 100644
--- a/NEWS
+++ b/NEWS
@@ -5,11 +5,14 @@ Noteworthy changes in version 1.16.1 (unreleased)
* New context flag "import-filter". [#5739]
+ * New export mode to export secret subkeys. [#5757]
+
* qt: Extend ChangeExpiryJob to change expiration of primary key
and of subkeys at the same time. [#4717]
* Interface changes relative to the 1.16.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GPGME_EXPORT_MODE_SECRET_SUBKEY NEW.
gpgme_set_ctx_flag EXTENDED: New flag 'key-origin'.
gpgme_set_ctx_flag EXTENDED: New flag 'import-filter'.
qt: ChangeExpiryJob::Option NEW.
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 8c821989..216d3cde 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -4893,7 +4893,6 @@ OpenPGP key is exported in the OpenSSH public key format. This
accepts just a single key; to force the export of a specific subkey
a fingerprint pattern with an appended exclamation mark may be used.
-
@item GPGME_EXPORT_MODE_SECRET
@since{1.6.0}
@@ -4901,6 +4900,16 @@ Instead of exporting the public key, the secret key is exported. This
may not be combined with @code{GPGME_EXPORT_MODE_EXTERN}. For X.509
the export format is PKCS#8.
+@item GPGME_EXPORT_MODE_SECRET_SUBKEY
+@since{1.17.0}
+
+If this bit is set, then a secret subkey is exported. The subkey to
+export must be specified with fingerprint pattern with an appended
+exclamation mark. This is currently only allowed for OpenPGP keys.
+This flag may not be combined with @code{GPGME_EXPORT_MODE_EXTERN}.
+This flag is not supported by the export functions that take an array
+of keys.
+
@item GPGME_EXPORT_MODE_RAW
@since{1.6.0}
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index fd39ad76..f619a646 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -2354,7 +2354,8 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|GPGME_EXPORT_MODE_MINIMAL
|GPGME_EXPORT_MODE_SSH
- |GPGME_EXPORT_MODE_SECRET)))
+ |GPGME_EXPORT_MODE_SECRET
+ |GPGME_EXPORT_MODE_SECRET_SUBKEY)))
return gpg_error (GPG_ERR_NOT_SUPPORTED);
if ((mode & GPGME_EXPORT_MODE_MINIMAL))
@@ -2379,7 +2380,9 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
}
else
{
- if ((mode & GPGME_EXPORT_MODE_SECRET))
+ if ((mode & GPGME_EXPORT_MODE_SECRET_SUBKEY))
+ err = add_arg (gpg, "--export-secret-subkeys");
+ else if ((mode & GPGME_EXPORT_MODE_SECRET))
err = add_arg (gpg, "--export-secret-keys");
else
err = add_arg (gpg, "--export");
diff --git a/src/export.c b/src/export.c
index 637badf9..c5bcca6e 100644
--- a/src/export.c
+++ b/src/export.c
@@ -125,7 +125,8 @@ check_mode (gpgme_export_mode_t mode, gpgme_protocol_t protocol,
|GPGME_EXPORT_MODE_SECRET
|GPGME_EXPORT_MODE_SSH
|GPGME_EXPORT_MODE_RAW
- |GPGME_EXPORT_MODE_PKCS12)))
+ |GPGME_EXPORT_MODE_PKCS12
+ |GPGME_EXPORT_MODE_SECRET_SUBKEY)))
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
if ((mode & GPGME_EXPORT_MODE_SSH))
@@ -134,7 +135,8 @@ check_mode (gpgme_export_mode_t mode, gpgme_protocol_t protocol,
|GPGME_EXPORT_MODE_MINIMAL
|GPGME_EXPORT_MODE_SECRET
|GPGME_EXPORT_MODE_RAW
- |GPGME_EXPORT_MODE_PKCS12)))
+ |GPGME_EXPORT_MODE_PKCS12
+ |GPGME_EXPORT_MODE_SECRET_SUBKEY)))
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
}
@@ -151,6 +153,12 @@ check_mode (gpgme_export_mode_t mode, gpgme_protocol_t protocol,
return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */
}
+ if ((mode & GPGME_EXPORT_MODE_SECRET_SUBKEY))
+ {
+ if ((mode & GPGME_EXPORT_MODE_EXTERN))
+ return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
+ }
+
if ((mode & GPGME_EXPORT_MODE_EXTERN))
{
if (keydata)
@@ -369,6 +377,11 @@ export_keys_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t keys[],
if (!keys)
return gpg_error (GPG_ERR_INV_VALUE);
+ if ((mode & GPGME_EXPORT_MODE_SECRET_SUBKEY))
+ {
+ return gpg_error (GPG_ERR_INV_FLAG);
+ }
+
/* Create a list of pattern from the keys. */
for (idx=nkeys=0; keys[idx]; idx++)
if (keys[idx]->protocol == ctx->protocol)
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c
index 0dbc4a9e..b05664e3 100644
--- a/src/gpgme-tool.c
+++ b/src/gpgme-tool.c
@@ -2688,6 +2688,8 @@ cmd_export (assuan_context_t ctx, char *line)
mode |= GPGME_EXPORT_MODE_MINIMAL;
if (has_option (line, "--secret"))
mode |= GPGME_EXPORT_MODE_SECRET;
+ if (has_option (line, "--secret-subkey"))
+ mode |= GPGME_EXPORT_MODE_SECRET_SUBKEY;
if (has_option (line, "--raw"))
mode |= GPGME_EXPORT_MODE_RAW;
if (has_option (line, "--pkcs12"))
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 5c74afd6..8a9cd259 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -407,6 +407,7 @@ gpgme_pinentry_mode_t;
#define GPGME_EXPORT_MODE_RAW 32
#define GPGME_EXPORT_MODE_PKCS12 64
#define GPGME_EXPORT_MODE_SSH 256
+#define GPGME_EXPORT_MODE_SECRET_SUBKEY 512
typedef unsigned int gpgme_export_mode_t;
diff --git a/tests/run-export.c b/tests/run-export.c
index 623c7331..f071b8c2 100644
--- a/tests/run-export.c
+++ b/tests/run-export.c
@@ -128,6 +128,11 @@ main (int argc, char **argv)
mode |= GPGME_EXPORT_MODE_SECRET;
argc--; argv++;
}
+ else if (!strcmp (*argv, "--secret-subkey"))
+ {
+ mode |= GPGME_EXPORT_MODE_SECRET_SUBKEY;
+ argc--; argv++;
+ }
else if (!strcmp (*argv, "--raw"))
{
mode |= GPGME_EXPORT_MODE_RAW;
@@ -168,6 +173,16 @@ main (int argc, char **argv)
err = gpgme_op_export_ext (ctx, (const char**)argv, mode, out);
fail_if_err (err);
}
+ else if ((mode & GPGME_EXPORT_MODE_SECRET_SUBKEY))
+ {
+ keyarray[0] = NULL;
+
+ printf ("exporting secret subkeys!\n");
+
+ gpgme_set_armor (ctx, 1);
+ err = gpgme_op_export_ext (ctx, (const char**)argv, mode, out);
+ fail_if_err (err);
+ }
else
{
/* Lookup the keys as required by the export_keys function. */