Add an export secret key feature.
* src/gpgme.h.in (GPGME_EXPORT_MODE_SECRET): New. (GPGME_EXPORT_MODE_RAW): New. (GPGME_EXPORT_MODE_PKCS12): New. * src/export.c (export_start, export_ext_start): Allow new flags. * src/engine-gpg.c (export_common): Support secret key export. * src/engine-gpgsm.c (gpgsm_export, gpgsm_export_ext): Ditto. * src/gpgme-tool.c (cmd_export): Add options --secret, --raw, and --pkcs12. * tests/run-export.c (main): Likewise. -- Note that exporting secret X.509 keys requires GnuPG 2.1.8. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
ccbaccbf2e
commit
2b632bbb78
@ -3700,6 +3700,21 @@ keys it removes all signatures except for the latest self-signatures.
|
|||||||
For X.509 keys it has no effect.
|
For X.509 keys it has no effect.
|
||||||
|
|
||||||
|
|
||||||
|
@item GPGME_EXPORT_MODE_SECRET
|
||||||
|
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_RAW
|
||||||
|
If this flag is used with @code{GPGME_EXPORT_MODE_SECRET} for an X.509
|
||||||
|
key the export format will be changed to PKCS#1. This flag may not be
|
||||||
|
used with OpenPGP.
|
||||||
|
|
||||||
|
@item GPGME_EXPORT_MODE_PKCS12
|
||||||
|
If this flag is used with @code{GPGME_EXPORT_MODE_SECRET} for an X.509
|
||||||
|
key the export format will be changed to PKCS#12 which also includes
|
||||||
|
the certificate. This flag may not be used with OpenPGP.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@ -1793,7 +1793,8 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
|
|||||||
gpgme_error_t err = 0;
|
gpgme_error_t err = 0;
|
||||||
|
|
||||||
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|
||||||
|GPGME_EXPORT_MODE_MINIMAL)))
|
|GPGME_EXPORT_MODE_MINIMAL
|
||||||
|
|GPGME_EXPORT_MODE_SECRET)))
|
||||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
|
||||||
if ((mode & GPGME_EXPORT_MODE_MINIMAL))
|
if ((mode & GPGME_EXPORT_MODE_MINIMAL))
|
||||||
@ -1807,6 +1808,9 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_SECRET))
|
||||||
|
err = add_arg (gpg, "--export-secret-keys");
|
||||||
|
else
|
||||||
err = add_arg (gpg, "--export");
|
err = add_arg (gpg, "--export");
|
||||||
if (!err && use_armor)
|
if (!err && use_armor)
|
||||||
err = add_arg (gpg, "--armor");
|
err = add_arg (gpg, "--armor");
|
||||||
|
@ -1289,17 +1289,23 @@ gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
|
|||||||
if (!gpgsm)
|
if (!gpgsm)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
if (mode)
|
|
||||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
|
||||||
|
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
pattern = "";
|
pattern = "";
|
||||||
|
|
||||||
cmd = malloc (7 + strlen (pattern) + 1);
|
cmd = malloc (7 + 9 + 9 + strlen (pattern) + 1);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
strcpy (cmd, "EXPORT ");
|
strcpy (cmd, "EXPORT ");
|
||||||
strcpy (&cmd[7], pattern);
|
if ((mode & GPGME_EXPORT_MODE_SECRET))
|
||||||
|
{
|
||||||
|
strcat (cmd, "--secret ");
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_RAW))
|
||||||
|
strcat (cmd, "--raw ");
|
||||||
|
else if ((mode & GPGME_EXPORT_MODE_PKCS12))
|
||||||
|
strcat (cmd, "--pkcs12 ");
|
||||||
|
}
|
||||||
|
strcat (cmd, pattern);
|
||||||
|
|
||||||
gpgsm->output_cb.data = keydata;
|
gpgsm->output_cb.data = keydata;
|
||||||
err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
|
err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
|
||||||
@ -1323,16 +1329,13 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
|
|||||||
engine_gpgsm_t gpgsm = engine;
|
engine_gpgsm_t gpgsm = engine;
|
||||||
gpgme_error_t err = 0;
|
gpgme_error_t err = 0;
|
||||||
char *line;
|
char *line;
|
||||||
/* Length is "EXPORT " + p + '\0'. */
|
/* Length is "EXPORT " + "--secret " + "--pkcs12 " + p + '\0'. */
|
||||||
int length = 7 + 1;
|
int length = 7 + 9 + 9 + 1;
|
||||||
char *linep;
|
char *linep;
|
||||||
|
|
||||||
if (!gpgsm)
|
if (!gpgsm)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
if (mode)
|
|
||||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
|
||||||
|
|
||||||
if (pattern && *pattern)
|
if (pattern && *pattern)
|
||||||
{
|
{
|
||||||
const char **pat = pattern;
|
const char **pat = pattern;
|
||||||
@ -1357,7 +1360,15 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
|
|||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
strcpy (line, "EXPORT ");
|
strcpy (line, "EXPORT ");
|
||||||
linep = &line[7];
|
if ((mode & GPGME_EXPORT_MODE_SECRET))
|
||||||
|
{
|
||||||
|
strcat (line, "--secret ");
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_RAW))
|
||||||
|
strcat (line, "--raw ");
|
||||||
|
else if ((mode & GPGME_EXPORT_MODE_PKCS12))
|
||||||
|
strcat (line, "--pkcs12 ");
|
||||||
|
}
|
||||||
|
linep = &line[strlen (line)];
|
||||||
|
|
||||||
if (pattern && *pattern)
|
if (pattern && *pattern)
|
||||||
{
|
{
|
||||||
|
35
src/export.c
35
src/export.c
@ -120,9 +120,24 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
|
|||||||
op_data_t opd;
|
op_data_t opd;
|
||||||
|
|
||||||
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|
||||||
|GPGME_EXPORT_MODE_MINIMAL)))
|
|GPGME_EXPORT_MODE_MINIMAL
|
||||||
|
|GPGME_EXPORT_MODE_SECRET
|
||||||
|
|GPGME_EXPORT_MODE_RAW
|
||||||
|
|GPGME_EXPORT_MODE_PKCS12)))
|
||||||
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
|
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
|
||||||
|
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_SECRET))
|
||||||
|
{
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
||||||
|
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_RAW)
|
||||||
|
&& (mode & GPGME_EXPORT_MODE_PKCS12))
|
||||||
|
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
|
||||||
|
|
||||||
|
if (ctx->protocol != GPGME_PROTOCOL_CMS
|
||||||
|
&& (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12)))
|
||||||
|
return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */
|
||||||
|
}
|
||||||
|
|
||||||
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
||||||
{
|
{
|
||||||
@ -199,9 +214,25 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
|
|||||||
op_data_t opd;
|
op_data_t opd;
|
||||||
|
|
||||||
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|
||||||
|GPGME_EXPORT_MODE_MINIMAL)))
|
|GPGME_EXPORT_MODE_MINIMAL
|
||||||
|
|GPGME_EXPORT_MODE_SECRET
|
||||||
|
|GPGME_EXPORT_MODE_RAW
|
||||||
|
|GPGME_EXPORT_MODE_PKCS12)))
|
||||||
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
|
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
|
||||||
|
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_SECRET))
|
||||||
|
{
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
||||||
|
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_RAW)
|
||||||
|
&& (mode & GPGME_EXPORT_MODE_PKCS12))
|
||||||
|
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
|
||||||
|
|
||||||
|
if (ctx->protocol != GPGME_PROTOCOL_CMS
|
||||||
|
&& (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12)))
|
||||||
|
return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */
|
||||||
|
}
|
||||||
|
|
||||||
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
||||||
{
|
{
|
||||||
if (keydata)
|
if (keydata)
|
||||||
|
@ -3054,7 +3054,7 @@ cmd_import (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
static const char hlp_export[] =
|
static const char hlp_export[] =
|
||||||
"EXPORT [--extern] [--minimal] [<pattern>]\n"
|
"EXPORT [--extern] [--minimal] [--secret [--pkcs12] [--raw]] [<pattern>]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Export the keys described by PATTERN. Write the\n"
|
"Export the keys described by PATTERN. Write the\n"
|
||||||
"the output to the object set by the last OUTPUT command.";
|
"the output to the object set by the last OUTPUT command.";
|
||||||
@ -3082,6 +3082,12 @@ cmd_export (assuan_context_t ctx, char *line)
|
|||||||
mode |= GPGME_EXPORT_MODE_EXTERN;
|
mode |= GPGME_EXPORT_MODE_EXTERN;
|
||||||
if (has_option (line, "--minimal"))
|
if (has_option (line, "--minimal"))
|
||||||
mode |= GPGME_EXPORT_MODE_MINIMAL;
|
mode |= GPGME_EXPORT_MODE_MINIMAL;
|
||||||
|
if (has_option (line, "--secret"))
|
||||||
|
mode |= GPGME_EXPORT_MODE_SECRET;
|
||||||
|
if (has_option (line, "--raw"))
|
||||||
|
mode |= GPGME_EXPORT_MODE_RAW;
|
||||||
|
if (has_option (line, "--pkcs12"))
|
||||||
|
mode |= GPGME_EXPORT_MODE_PKCS12;
|
||||||
|
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
|
@ -392,6 +392,9 @@ gpgme_pinentry_mode_t;
|
|||||||
/* The available export mode flags. */
|
/* The available export mode flags. */
|
||||||
#define GPGME_EXPORT_MODE_EXTERN 2
|
#define GPGME_EXPORT_MODE_EXTERN 2
|
||||||
#define GPGME_EXPORT_MODE_MINIMAL 4
|
#define GPGME_EXPORT_MODE_MINIMAL 4
|
||||||
|
#define GPGME_EXPORT_MODE_SECRET 16
|
||||||
|
#define GPGME_EXPORT_MODE_RAW 32
|
||||||
|
#define GPGME_EXPORT_MODE_PKCS12 64
|
||||||
|
|
||||||
typedef unsigned int gpgme_export_mode_t;
|
typedef unsigned int gpgme_export_mode_t;
|
||||||
|
|
||||||
|
@ -43,7 +43,12 @@ show_usage (int ex)
|
|||||||
fputs ("usage: " PGM " [options] USERIDS\n\n"
|
fputs ("usage: " PGM " [options] USERIDS\n\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" --verbose run in verbose mode\n"
|
" --verbose run in verbose mode\n"
|
||||||
|
" --openpgp use OpenPGP protocol (default)\n"
|
||||||
|
" --cms use X.509 protocol\n"
|
||||||
" --extern send keys to the keyserver (TAKE CARE!)\n"
|
" --extern send keys to the keyserver (TAKE CARE!)\n"
|
||||||
|
" --secret export secret keys instead of public keys\n"
|
||||||
|
" --raw use PKCS#1 as secret key format\n"
|
||||||
|
" --pkcs12 use PKCS#12 as secret key format\n"
|
||||||
, stderr);
|
, stderr);
|
||||||
exit (ex);
|
exit (ex);
|
||||||
}
|
}
|
||||||
@ -59,6 +64,7 @@ main (int argc, char **argv)
|
|||||||
gpgme_key_t keyarray[100];
|
gpgme_key_t keyarray[100];
|
||||||
int keyidx = 0;
|
int keyidx = 0;
|
||||||
gpgme_data_t out;
|
gpgme_data_t out;
|
||||||
|
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
|
||||||
gpgme_export_mode_t mode = 0;
|
gpgme_export_mode_t mode = 0;
|
||||||
|
|
||||||
if (argc)
|
if (argc)
|
||||||
@ -79,9 +85,34 @@ main (int argc, char **argv)
|
|||||||
verbose = 1;
|
verbose = 1;
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (*argv, "--openpgp"))
|
||||||
|
{
|
||||||
|
protocol = GPGME_PROTOCOL_OpenPGP;
|
||||||
|
argc--; argv++;
|
||||||
|
}
|
||||||
|
else if (!strcmp (*argv, "--cms"))
|
||||||
|
{
|
||||||
|
protocol = GPGME_PROTOCOL_CMS;
|
||||||
|
argc--; argv++;
|
||||||
|
}
|
||||||
else if (!strcmp (*argv, "--extern"))
|
else if (!strcmp (*argv, "--extern"))
|
||||||
{
|
{
|
||||||
mode |= GPGME_KEYLIST_MODE_EXTERN;
|
mode |= GPGME_EXPORT_MODE_EXTERN;
|
||||||
|
argc--; argv++;
|
||||||
|
}
|
||||||
|
else if (!strcmp (*argv, "--secret"))
|
||||||
|
{
|
||||||
|
mode |= GPGME_EXPORT_MODE_SECRET;
|
||||||
|
argc--; argv++;
|
||||||
|
}
|
||||||
|
else if (!strcmp (*argv, "--raw"))
|
||||||
|
{
|
||||||
|
mode |= GPGME_EXPORT_MODE_RAW;
|
||||||
|
argc--; argv++;
|
||||||
|
}
|
||||||
|
else if (!strcmp (*argv, "--pkcs12"))
|
||||||
|
{
|
||||||
|
mode |= GPGME_EXPORT_MODE_PKCS12;
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
}
|
}
|
||||||
else if (!strncmp (*argv, "--", 2))
|
else if (!strncmp (*argv, "--", 2))
|
||||||
@ -92,11 +123,11 @@ main (int argc, char **argv)
|
|||||||
if (!argc)
|
if (!argc)
|
||||||
show_usage (1);
|
show_usage (1);
|
||||||
|
|
||||||
init_gpgme (GPGME_PROTOCOL_OpenPGP);
|
init_gpgme (protocol);
|
||||||
|
|
||||||
err = gpgme_new (&ctx);
|
err = gpgme_new (&ctx);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP);
|
gpgme_set_protocol (ctx, protocol);
|
||||||
|
|
||||||
/* Lookup the keys. */
|
/* Lookup the keys. */
|
||||||
err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0);
|
err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0);
|
||||||
@ -131,8 +162,10 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now for the actual export. */
|
/* Now for the actual export. */
|
||||||
if ((mode & GPGME_KEYLIST_MODE_EXTERN))
|
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
||||||
printf ("sending keys to keyserver\n");
|
printf ("sending keys to keyserver\n");
|
||||||
|
if ((mode & GPGME_EXPORT_MODE_SECRET))
|
||||||
|
printf ("exporting secret keys!\n");
|
||||||
|
|
||||||
err = gpgme_data_new (&out);
|
err = gpgme_data_new (&out);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
Loading…
Reference in New Issue
Block a user