diff options
author | Werner Koch <[email protected]> | 2020-06-03 14:24:44 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2020-06-03 14:25:59 +0000 |
commit | 4f6e0e12cbd3444b9e6ea5e4b92ea5b3072a3e17 (patch) | |
tree | 276274d0eea567faf6ffd44da8d6040577478a57 /tools/card-keys.c | |
parent | gpg: Improve generation of keys stored on card (brainpool,cv25519). (diff) | |
download | gnupg-4f6e0e12cbd3444b9e6ea5e4b92ea5b3072a3e17.tar.gz gnupg-4f6e0e12cbd3444b9e6ea5e4b92ea5b3072a3e17.zip |
card: Improve openpgp key writing in "writecert".
* tools/card-keys.c (struct export_key_status_parm_s): New.
(export_key_status_cb): New.
(get_minimal_openpgp_key): New.
* tools/gpg-card.c (cmd_writecert): Allow writing a keyblock directly
from an existing gpg key.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'tools/card-keys.c')
-rw-r--r-- | tools/card-keys.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/tools/card-keys.c b/tools/card-keys.c index 4706cb320..3027de9c7 100644 --- a/tools/card-keys.c +++ b/tools/card-keys.c @@ -557,3 +557,96 @@ test_get_matching_keys (const char *hexgrip) release_keyblock (keyblock); return 0; } + + + + +struct export_key_status_parm_s +{ + const char *fpr; + int found; + int count; +}; + + +static void +export_key_status_cb (void *opaque, const char *keyword, char *args) +{ + struct export_key_status_parm_s *parm = opaque; + + if (!strcmp (keyword, "EXPORTED")) + { + parm->count++; + if (!ascii_strcasecmp (args, parm->fpr)) + parm->found = 1; + } +} + + +/* Get a key by fingerprint from gpg's keyring. The binary key is + * returned as a new memory stream at R_KEY. */ +gpg_error_t +get_minimal_openpgp_key (estream_t *r_key, const char *fingerprint) +{ + gpg_error_t err; + ccparray_t ccp; + const char **argv = NULL; + estream_t key = NULL; + struct export_key_status_parm_s parm = { NULL }; + + *r_key = NULL; + + key = es_fopenmem (0, "w+b"); + if (!key) + { + err = gpg_error_from_syserror (); + log_error ("error allocating memory buffer: %s\n", gpg_strerror (err)); + goto leave; + } + + ccparray_init (&ccp, 0); + + ccparray_put (&ccp, "--no-options"); + if (!opt.verbose) + ccparray_put (&ccp, "--quiet"); + else if (opt.verbose > 1) + ccparray_put (&ccp, "--verbose"); + ccparray_put (&ccp, "--batch"); + ccparray_put (&ccp, "--status-fd=2"); + ccparray_put (&ccp, "--always-trust"); + ccparray_put (&ccp, "--no-armor"); + ccparray_put (&ccp, "--export-options=export-minimal"); + ccparray_put (&ccp, "--export"); + ccparray_put (&ccp, "--"); + ccparray_put (&ccp, fingerprint); + + ccparray_put (&ccp, NULL); + argv = ccparray_get (&ccp, NULL); + if (!argv) + { + err = gpg_error_from_syserror (); + goto leave; + } + parm.fpr = fingerprint; + err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL, + NULL, key, + export_key_status_cb, &parm); + if (!err && parm.count > 1) + err = gpg_error (GPG_ERR_TOO_MANY); + else if (!err && !parm.found) + err = gpg_error (GPG_ERR_NOT_FOUND); + if (err) + { + log_error ("export failed: %s\n", gpg_strerror (err)); + goto leave; + } + + es_rewind (key); + *r_key = key; + key = NULL; + + leave: + es_fclose (key); + xfree (argv); + return err; +} |