core: New export mode to export as OpenSSH public key.
* src/gpgme.h.in (GPGME_EXPORT_MODE_SSH): New. * src/export.c (export_ext_start): Allow for new mode. * src/engine-gpg.c (export_common): Implement. * tests/run-export.c (status_cb): New. (main): New options --status and --ssh. -- GnuPG-bug-id: 4310 Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
8589091682
commit
7f9e0ca57b
3
NEWS
3
NEWS
@ -3,6 +3,8 @@ Noteworthy changes in version 1.14.0 (unreleased)
|
||||
|
||||
* New keylist mode to force the engine to return the keygrip. [#4820]
|
||||
|
||||
* New export mode to export as OpenSSH public key. [#4310]
|
||||
|
||||
* New context flag "extended-edit" to enable expert key edit. [#4734]
|
||||
|
||||
* Deprecate the anyway non working trustlist functions. [#4834]
|
||||
@ -23,6 +25,7 @@ Noteworthy changes in version 1.14.0 (unreleased)
|
||||
* Interface changes relative to the 1.13.1 release:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
GPGME_KEYLIST_MODE_WITH_KEYGRIP NEW.
|
||||
GPGME_EXPORT_MODE_SSH NEW.
|
||||
gpgme_user_id_t EXTENDED: New field 'uidhash'.
|
||||
cpp: UserID::remark NEW.
|
||||
cpp: UserID::remarks NEW.
|
||||
|
@ -4679,6 +4679,14 @@ If this bit is set, the smallest possible key is exported. For OpenPGP
|
||||
keys it removes all signatures except for the latest self-signatures.
|
||||
For X.509 keys it has no effect.
|
||||
|
||||
@item GPGME_EXPORT_MODE_SSH
|
||||
@since{1.4.0}
|
||||
|
||||
If this bit is set, the latest authentication key of the requested
|
||||
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}
|
||||
|
@ -2330,6 +2330,7 @@ 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)))
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
|
||||
@ -2345,6 +2346,15 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
|
||||
|
||||
if (err)
|
||||
;
|
||||
else if ((mode & GPGME_EXPORT_MODE_SSH))
|
||||
{
|
||||
if (have_gpg_version (gpg, "2.1.11"))
|
||||
err = add_arg (gpg, "--export-ssh-key");
|
||||
else
|
||||
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
if (!err)
|
||||
err = add_data (gpg, keydata, 1, 1);
|
||||
}
|
||||
else if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
||||
{
|
||||
err = add_arg (gpg, "--send-keys");
|
||||
|
@ -218,6 +218,7 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
|
||||
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|
||||
|GPGME_EXPORT_MODE_MINIMAL
|
||||
|GPGME_EXPORT_MODE_SECRET
|
||||
|GPGME_EXPORT_MODE_SSH
|
||||
|GPGME_EXPORT_MODE_RAW
|
||||
|GPGME_EXPORT_MODE_PKCS12)))
|
||||
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
|
||||
@ -478,4 +479,3 @@ gpgme_op_export_keys (gpgme_ctx_t ctx,
|
||||
|
||||
return TRACE_ERR (err);
|
||||
}
|
||||
|
||||
|
@ -407,6 +407,7 @@ gpgme_pinentry_mode_t;
|
||||
#define GPGME_EXPORT_MODE_RAW 32
|
||||
#define GPGME_EXPORT_MODE_PKCS12 64
|
||||
#define GPGME_EXPORT_MODE_NOUID 128 /* Experimental(!)*/
|
||||
#define GPGME_EXPORT_MODE_SSH 256
|
||||
|
||||
typedef unsigned int gpgme_export_mode_t;
|
||||
|
||||
|
@ -38,14 +38,25 @@
|
||||
static int verbose;
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
status_cb (void *opaque, const char *keyword, const char *value)
|
||||
{
|
||||
(void)opaque;
|
||||
fprintf (stderr, "status_cb: %s %s\n", keyword, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
show_usage (int ex)
|
||||
{
|
||||
fputs ("usage: " PGM " [options] USERIDS\n\n"
|
||||
"Options:\n"
|
||||
" --verbose run in verbose mode\n"
|
||||
" --status print status lines from the backend\n"
|
||||
" --openpgp use OpenPGP protocol (default)\n"
|
||||
" --cms use X.509 protocol\n"
|
||||
" --ssh export as ssh public key\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"
|
||||
@ -67,6 +78,7 @@ main (int argc, char **argv)
|
||||
gpgme_data_t out;
|
||||
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
|
||||
gpgme_export_mode_t mode = 0;
|
||||
int print_status = 0;
|
||||
|
||||
if (argc)
|
||||
{ argc--; argv++; }
|
||||
@ -86,6 +98,11 @@ main (int argc, char **argv)
|
||||
verbose = 1;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--status"))
|
||||
{
|
||||
print_status = 1;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--openpgp"))
|
||||
{
|
||||
protocol = GPGME_PROTOCOL_OpenPGP;
|
||||
@ -101,6 +118,11 @@ main (int argc, char **argv)
|
||||
mode |= GPGME_EXPORT_MODE_EXTERN;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--ssh"))
|
||||
{
|
||||
mode |= GPGME_EXPORT_MODE_SSH;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--secret"))
|
||||
{
|
||||
mode |= GPGME_EXPORT_MODE_SECRET;
|
||||
@ -129,52 +151,68 @@ main (int argc, char **argv)
|
||||
err = gpgme_new (&ctx);
|
||||
fail_if_err (err);
|
||||
gpgme_set_protocol (ctx, protocol);
|
||||
|
||||
/* Lookup the keys. */
|
||||
err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0);
|
||||
fail_if_err (err);
|
||||
|
||||
while (!(err = gpgme_op_keylist_next (ctx, &key)))
|
||||
if (print_status)
|
||||
{
|
||||
printf ("keyid: %s (fpr: %s)\n",
|
||||
key->subkeys?nonnull (key->subkeys->keyid):"?",
|
||||
key->subkeys?nonnull (key->subkeys->fpr):"?");
|
||||
|
||||
if (keyidx < DIM (keyarray)-1)
|
||||
keyarray[keyidx++] = key;
|
||||
else
|
||||
{
|
||||
fprintf (stderr, PGM": too many keys"
|
||||
"- skipping this key\n");
|
||||
gpgme_key_unref (key);
|
||||
}
|
||||
gpgme_set_status_cb (ctx, status_cb, NULL);
|
||||
gpgme_set_ctx_flag (ctx, "full-status", "1");
|
||||
}
|
||||
if (gpgme_err_code (err) != GPG_ERR_EOF)
|
||||
fail_if_err (err);
|
||||
err = gpgme_op_keylist_end (ctx);
|
||||
fail_if_err (err);
|
||||
keyarray[keyidx] = NULL;
|
||||
|
||||
result = gpgme_op_keylist_result (ctx);
|
||||
if (result->truncated)
|
||||
{
|
||||
fprintf (stderr, PGM ": key listing unexpectedly truncated\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Now for the actual export. */
|
||||
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
||||
printf ("sending keys to keyserver\n");
|
||||
if ((mode & GPGME_EXPORT_MODE_SECRET))
|
||||
printf ("exporting secret keys!\n");
|
||||
|
||||
err = gpgme_data_new (&out);
|
||||
fail_if_err (err);
|
||||
|
||||
gpgme_set_armor (ctx, 1);
|
||||
err = gpgme_op_export_keys (ctx, keyarray, mode,
|
||||
(mode & GPGME_KEYLIST_MODE_EXTERN)? NULL:out);
|
||||
fail_if_err (err);
|
||||
if ((mode & GPGME_EXPORT_MODE_SSH))
|
||||
{
|
||||
mode = GPGME_EXPORT_MODE_SSH; /* Set only this bit for this test. */
|
||||
keyarray[0] = NULL;
|
||||
|
||||
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. */
|
||||
err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0);
|
||||
fail_if_err (err);
|
||||
|
||||
while (!(err = gpgme_op_keylist_next (ctx, &key)))
|
||||
{
|
||||
printf ("keyid: %s (fpr: %s)\n",
|
||||
key->subkeys?nonnull (key->subkeys->keyid):"?",
|
||||
key->subkeys?nonnull (key->subkeys->fpr):"?");
|
||||
|
||||
if (keyidx < DIM (keyarray)-1)
|
||||
keyarray[keyidx++] = key;
|
||||
else
|
||||
{
|
||||
fprintf (stderr, PGM": too many keys"
|
||||
"- skipping this key\n");
|
||||
gpgme_key_unref (key);
|
||||
}
|
||||
}
|
||||
if (gpgme_err_code (err) != GPG_ERR_EOF)
|
||||
fail_if_err (err);
|
||||
err = gpgme_op_keylist_end (ctx);
|
||||
fail_if_err (err);
|
||||
keyarray[keyidx] = NULL;
|
||||
|
||||
result = gpgme_op_keylist_result (ctx);
|
||||
if (result->truncated)
|
||||
{
|
||||
fprintf (stderr, PGM ": key listing unexpectedly truncated\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Now for the actual export. */
|
||||
if ((mode & GPGME_EXPORT_MODE_EXTERN))
|
||||
printf ("sending keys to keyserver\n");
|
||||
if ((mode & GPGME_EXPORT_MODE_SECRET))
|
||||
printf ("exporting secret keys!\n");
|
||||
|
||||
gpgme_set_armor (ctx, 1);
|
||||
err = gpgme_op_export_keys (ctx, keyarray, mode,
|
||||
(mode & GPGME_KEYLIST_MODE_EXTERN)? NULL:out);
|
||||
fail_if_err (err);
|
||||
}
|
||||
|
||||
fflush (NULL);
|
||||
if (!(mode & GPGME_KEYLIST_MODE_EXTERN))
|
||||
|
Loading…
Reference in New Issue
Block a user