diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2016-10-20 05:05:15 +0200 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2016-10-20 05:05:15 +0200 |
commit | 82cbab906a3e72a98fdc16096f2f0451465969a2 (patch) | |
tree | 03b9e3b4a87abb2082ec628445b438520248337b /agent/command.c | |
parent | dirmngr: improve VERSIONCHECK (diff) | |
download | gnupg2-82cbab906a3e72a98fdc16096f2f0451465969a2.tar.xz gnupg2-82cbab906a3e72a98fdc16096f2f0451465969a2.zip |
agent: Add --card option for READKEY.
* agent/findkey.c (agent_write_shadow_key): New.
* agent/command-ssh.c (card_key_available): Use agent_write_shadow_key.
* agent/learncard.c (agent_handle_learn): Likewise.
* agent/command.c (cmd_readkey): Add --card option.
--
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'agent/command.c')
-rw-r--r-- | agent/command.c | 69 |
1 files changed, 57 insertions, 12 deletions
diff --git a/agent/command.c b/agent/command.c index 1ecdf20cd..a291d5b68 100644 --- a/agent/command.c +++ b/agent/command.c @@ -988,8 +988,10 @@ cmd_genkey (assuan_context_t ctx, char *line) static const char hlp_readkey[] = "READKEY <hexstring_with_keygrip>\n" + " --card <keyid>\n" "\n" - "Return the public key for the given keygrip."; + "Return the public key for the given keygrip or keyid.\n" + "With --card, private key file with card information will be created."; static gpg_error_t cmd_readkey (assuan_context_t ctx, char *line) { @@ -997,10 +999,57 @@ cmd_readkey (assuan_context_t ctx, char *line) int rc; unsigned char grip[20]; gcry_sexp_t s_pkey = NULL; + unsigned char *pkbuf = NULL; + size_t pkbuflen; if (ctrl->restricted) return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + if (has_option_name (line, "--card")) + { + const char *keyid; + char *serialno = NULL; + + keyid = skip_options (line); + + rc = agent_card_getattr (ctrl, "SERIALNO", &serialno); + if (rc) + { + log_error (_("error getting serial number of card: %s\n"), + gpg_strerror (rc)); + goto leave; + } + + pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL); + rc = agent_card_readkey (ctrl, keyid, &pkbuf); + if (rc) + goto leave; + rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)pkbuf, pkbuflen); + if (rc) + goto leave; + + if (!gcry_pk_get_keygrip (s_pkey, grip)) + { + rc = gcry_pk_testkey (s_pkey); + if (rc == 0) + rc = gpg_error (GPG_ERR_INTERNAL); + + goto leave; + } + + rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0); + if (rc) + goto leave; + + rc = assuan_send_data (ctx, pkbuf, pkbuflen); + + leave: + xfree (serialno); + xfree (pkbuf); + gcry_sexp_release (s_pkey); + return leave_cmd (ctx, rc); + } + rc = parse_keygrip (ctx, line, grip); if (rc) return rc; /* Return immediately as this is already an Assuan error code.*/ @@ -1008,20 +1057,16 @@ cmd_readkey (assuan_context_t ctx, char *line) rc = agent_public_key_from_file (ctrl, grip, &s_pkey); if (!rc) { - size_t len; - unsigned char *buf; - - len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xtrymalloc (len); - if (!buf) + pkbuflen = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); + assert (pkbuflen); + pkbuf = xtrymalloc (pkbuflen); + if (!pkbuf) rc = gpg_error_from_syserror (); else { - len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - rc = assuan_send_data (ctx, buf, len); - xfree (buf); + gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, pkbuf, pkbuflen); + rc = assuan_send_data (ctx, pkbuf, pkbuflen); + xfree (pkbuf); } gcry_sexp_release (s_pkey); } |