summaryrefslogtreecommitdiffstats
path: root/agent/command.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2016-10-20 05:05:15 +0200
committerNIIBE Yutaka <gniibe@fsij.org>2016-10-20 05:05:15 +0200
commit82cbab906a3e72a98fdc16096f2f0451465969a2 (patch)
tree03b9e3b4a87abb2082ec628445b438520248337b /agent/command.c
parentdirmngr: improve VERSIONCHECK (diff)
downloadgnupg2-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.c69
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);
}