aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-04-03 15:45:35 +0000
committerWerner Koch <[email protected]>2019-04-03 15:45:35 +0000
commit2c9b68f28de1ce9a6a18d091caba01ddd4707774 (patch)
treeafc99495166052529ebc54c0d6ce87d758a4fb0d
parentscd: New options --info and --info-only for READKEY. (diff)
downloadgnupg-2c9b68f28de1ce9a6a18d091caba01ddd4707774.tar.gz
gnupg-2c9b68f28de1ce9a6a18d091caba01ddd4707774.zip
gpg: Improve the code to decrypt using PIV cards.
* g10/call-agent.c (agent_scd_keypairinfo): Add arg 'keyref'. * g10/keygen.c (ask_algo): Adjust. * g10/skclist.c (enum_secret_keys): Request the keyref directly. -- This improves commit ec6a6779236a89d4784a6bb7de0def9cc0f9e8a4 to avoid looping over all keypairinfos. This way scdaemon does not need to compute all the keypairinfos for all keys of a card. This patch is possible due the enhanced READKEY command in scdaemon. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--g10/call-agent.c13
-rw-r--r--g10/call-agent.h3
-rw-r--r--g10/keygen.c2
-rw-r--r--g10/skclist.c33
4 files changed, 26 insertions, 25 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c
index f603d491a..f6c7d3951 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -824,13 +824,15 @@ scd_keypairinfo_status_cb (void *opaque, const char *line)
/* Read the keypairinfo lines of the current card directly from
* scdaemon. The list is returned as a string made up of the keygrip,
* a space and the keyref. The flags of the string carry the usage
- * bits. */
+ * bits. If KEYREF is not NULL, only a single string is returned
+ * which matches the given keyref. */
gpg_error_t
-agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
+agent_scd_keypairinfo (ctrl_t ctrl, const char *keyref, strlist_t *r_list)
{
gpg_error_t err;
strlist_t list = NULL;
struct default_inq_parm_s inq_parm;
+ char line[ASSUAN_LINELENGTH];
*r_list = NULL;
err= start_agent (ctrl, 1);
@@ -839,7 +841,12 @@ agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list)
memset (&inq_parm, 0, sizeof inq_parm);
inq_parm.ctx = agent_ctx;
- err = assuan_transact (agent_ctx, "SCD LEARN --keypairinfo",
+ if (keyref)
+ snprintf (line, DIM(line), "SCD READKEY --info-only %s", keyref);
+ else
+ snprintf (line, DIM(line), "SCD LEARN --keypairinfo");
+
+ err = assuan_transact (agent_ctx, line,
NULL, NULL,
default_inq_cb, &inq_parm,
scd_keypairinfo_status_cb, &list);
diff --git a/g10/call-agent.h b/g10/call-agent.h
index c0018a595..c4d0a9de1 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -85,7 +85,8 @@ void agent_release_card_info (struct agent_card_info_s *info);
int agent_scd_learn (struct agent_card_info_s *info, int force);
/* Get the keypariinfo directly from scdaemon. */
-gpg_error_t agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list);
+gpg_error_t agent_scd_keypairinfo (ctrl_t ctrl, const char *keyref,
+ strlist_t *r_list);
/* Return list of cards. */
int agent_scd_cardlist (strlist_t *result);
diff --git a/g10/keygen.c b/g10/keygen.c
index 6ea4e72c6..22ac6f0b5 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -2254,7 +2254,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
tty_printf (_("Serial number of the card: %s\n"), serialno);
xfree (serialno);
- err = agent_scd_keypairinfo (ctrl, &keypairlist);
+ err = agent_scd_keypairinfo (ctrl, NULL, &keypairlist);
if (err)
{
tty_printf (_("error reading the card: %s\n"),
diff --git a/g10/skclist.c b/g10/skclist.c
index b4f83ea1a..c13566e2b 100644
--- a/g10/skclist.c
+++ b/g10/skclist.c
@@ -450,38 +450,31 @@ enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
/* KEY-FPR not supported by the card - get
* the key using the keygrip. */
char *keyref;
- strlist_t kplist, sl;
+ strlist_t kplist;
const char *s;
int i;
err = agent_scd_getattr_one ("$ENCRKEYID", &keyref);
if (!err)
{
- err = agent_scd_keypairinfo (ctrl, &kplist);
+ err = agent_scd_keypairinfo (ctrl, keyref,
+ &kplist);
if (!err)
{
- for (sl = kplist; sl; sl = sl->next)
- if ((s = strchr (sl->d, ' '))
- && !strcmp (s+1, keyref))
- break;
- if (sl)
- {
- c->fpr2[0] = '&';
- for (i=1, s=sl->d;
- (*s && *s != ' '
- && i < sizeof c->fpr2 - 3);
- s++, i++)
- c->fpr2[i] = *s;
- c->fpr2[i] = 0;
- name = c->fpr2;
- }
- else /* Restore error. */
- err = gpg_error (GPG_ERR_INV_NAME);
+ c->fpr2[0] = '&';
+ for (i=1, s=kplist->d;
+ (*s && *s != ' '
+ && i < sizeof c->fpr2 - 3);
+ s++, i++)
+ c->fpr2[i] = *s;
+ c->fpr2[i] = 0;
+ name = c->fpr2;
free_strlist (kplist);
}
+ xfree (keyref);
}
- xfree (keyref);
}
+
if (err)
log_error ("error retrieving key from card: %s\n",
gpg_strerror (err));