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));