mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-24 22:09:57 +01:00
agent: SSH: SCD KEYINFO to list available keys.
* agent/agent.h (agent_card_cardlist): Remove. (agent_card_keyinfo): Add CAP argument. * agent/call-scd.c (card_cardlist_cb): Remove. (agent_card_cardlist): Remove. (agent_card_keyinfo): Support CAP constraint. * agent/command-ssh.c (card_key_list): Remove. (ssh_handler_request_identities): Use SCD KEYINFO command. * agent/command.c (cmd_keyinfo): Follow the API change. * agent/divert-scd.c (ask_for_card): Likewise. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
fbf97a7856
commit
57b8ed61ab
@ -614,14 +614,13 @@ gpg_error_t agent_card_writekey (ctrl_t ctrl, int force, const char *serialno,
|
||||
const char *, char*, size_t),
|
||||
void *getpin_cb_arg);
|
||||
gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result);
|
||||
gpg_error_t agent_card_cardlist (ctrl_t ctrl, strlist_t *result);
|
||||
int agent_card_scd (ctrl_t ctrl, const char *cmdline,
|
||||
int (*getpin_cb)(void *, const char *,
|
||||
const char *, char*, size_t),
|
||||
void *getpin_cb_arg, void *assuan_context);
|
||||
void agent_card_free_keyinfo (struct card_key_info_s *l);
|
||||
gpg_error_t agent_card_keyinfo (ctrl_t ctrl, const char *keygrip,
|
||||
struct card_key_info_s **result);
|
||||
int cap, struct card_key_info_s **result);
|
||||
void agent_card_killscd (void);
|
||||
|
||||
|
||||
|
@ -1360,78 +1360,6 @@ agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
|
||||
|
||||
|
||||
|
||||
struct card_cardlist_parm_s {
|
||||
int error;
|
||||
strlist_t list;
|
||||
};
|
||||
|
||||
/* Callback function for agent_card_cardlist. */
|
||||
static gpg_error_t
|
||||
card_cardlist_cb (void *opaque, const char *line)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
struct card_cardlist_parm_s *parm = opaque;
|
||||
const char *keyword = line;
|
||||
int keywordlen;
|
||||
|
||||
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
|
||||
;
|
||||
while (spacep (line))
|
||||
line++;
|
||||
|
||||
if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
|
||||
{
|
||||
const char *s;
|
||||
int n;
|
||||
|
||||
for (n=0,s=line; hexdigitp (s); s++, n++)
|
||||
;
|
||||
|
||||
if (!n || (n&1) || *s)
|
||||
parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
|
||||
else
|
||||
add_to_strlist (&parm->list, line);
|
||||
}
|
||||
else if (keywordlen == 12 && !memcmp (keyword, "PINCACHE_PUT", keywordlen))
|
||||
err = handle_pincache_put (line);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Call the scdaemon to retrieve list of available cards. On success
|
||||
the allocated strlist is stored at RESULT. On error an error code is
|
||||
returned and NULL stored at RESULT. */
|
||||
gpg_error_t
|
||||
agent_card_cardlist (ctrl_t ctrl, strlist_t *result)
|
||||
{
|
||||
int err;
|
||||
struct card_cardlist_parm_s parm;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
|
||||
*result = NULL;
|
||||
|
||||
memset (&parm, 0, sizeof parm);
|
||||
strcpy (line, "GETINFO card_list");
|
||||
|
||||
err = start_scd (ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = assuan_transact (ctrl->scd_local->ctx, line,
|
||||
NULL, NULL, NULL, NULL,
|
||||
card_cardlist_cb, &parm);
|
||||
if (!err && parm.error)
|
||||
err = parm.error;
|
||||
|
||||
if (!err)
|
||||
*result = parm.list;
|
||||
else
|
||||
free_strlist (parm.list);
|
||||
|
||||
return unlock_scd (ctrl, err);
|
||||
}
|
||||
|
||||
|
||||
struct card_keyinfo_parm_s {
|
||||
int error;
|
||||
struct card_key_info_s *list;
|
||||
@ -1552,21 +1480,32 @@ agent_card_free_keyinfo (struct card_key_info_s *l)
|
||||
}
|
||||
|
||||
/* Call the scdaemon to check if a key of KEYGRIP is available, or
|
||||
retrieve list of available keys on cards. On success the allocated
|
||||
structure is stored at RESULT. On error an error code is returned
|
||||
retrieve list of available keys on cards. With CAP, we can limit
|
||||
keys with specified capability. On success, the allocated
|
||||
structure is stored at RESULT. On error, an error code is returned
|
||||
and NULL is stored at RESULT. */
|
||||
gpg_error_t
|
||||
agent_card_keyinfo (ctrl_t ctrl, const char *keygrip,
|
||||
agent_card_keyinfo (ctrl_t ctrl, const char *keygrip, int cap,
|
||||
struct card_key_info_s **result)
|
||||
{
|
||||
int err;
|
||||
struct card_keyinfo_parm_s parm;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
char *list_option;
|
||||
|
||||
*result = NULL;
|
||||
|
||||
switch (cap)
|
||||
{
|
||||
case 0: list_option = "--list"; break;
|
||||
case GCRY_PK_USAGE_SIGN: list_option = "--list=sign"; break;
|
||||
case GCRY_PK_USAGE_ENCR: list_option = "--list=encr"; break;
|
||||
case GCRY_PK_USAGE_AUTH: list_option = "--list=auth"; break;
|
||||
default: return gpg_error (GPG_ERR_INV_VALUE);
|
||||
}
|
||||
|
||||
memset (&parm, 0, sizeof parm);
|
||||
snprintf (line, sizeof line, "KEYINFO %s", keygrip ? keygrip : "--list");
|
||||
snprintf (line, sizeof line, "KEYINFO %s", keygrip ? keygrip : list_option);
|
||||
|
||||
err = start_scd (ctrl);
|
||||
if (err)
|
||||
|
@ -2374,34 +2374,6 @@ ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
card_key_list (ctrl_t ctrl, char **r_serialno, strlist_t *result)
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
*r_serialno = NULL;
|
||||
*result = NULL;
|
||||
|
||||
err = agent_card_serialno (ctrl, r_serialno, NULL);
|
||||
if (err)
|
||||
{
|
||||
if (gpg_err_code (err) != GPG_ERR_ENODEV && opt.verbose)
|
||||
log_info (_("error getting serial number of card: %s\n"),
|
||||
gpg_strerror (err));
|
||||
|
||||
/* Nothing available. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = agent_card_cardlist (ctrl, result);
|
||||
if (err)
|
||||
{
|
||||
xfree (*r_serialno);
|
||||
*r_serialno = NULL;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Check whether a smartcard is available and whether it has a usable
|
||||
key. Store a copy of that key at R_PK and return 0. If no key is
|
||||
available store NULL at R_PK and return an error code. If CARDSN
|
||||
@ -2582,9 +2554,18 @@ ssh_handler_request_identities (ctrl_t ctrl,
|
||||
if (!opt.disable_scdaemon)
|
||||
{
|
||||
char *serialno;
|
||||
strlist_t card_list, sl;
|
||||
struct card_key_info_s *keyinfo_list;
|
||||
struct card_key_info_s *keyinfo;
|
||||
|
||||
/* Scan device(s), and get list of KEYGRIP. */
|
||||
err = agent_card_serialno (ctrl, &serialno, NULL);
|
||||
if (!err)
|
||||
{
|
||||
xfree (serialno);
|
||||
err = agent_card_keyinfo (ctrl, NULL, GCRY_PK_USAGE_AUTH,
|
||||
&keyinfo_list);
|
||||
}
|
||||
|
||||
err = card_key_list (ctrl, &serialno, &card_list);
|
||||
if (err)
|
||||
{
|
||||
if (opt.verbose)
|
||||
@ -2593,12 +2574,18 @@ ssh_handler_request_identities (ctrl_t ctrl,
|
||||
goto scd_out;
|
||||
}
|
||||
|
||||
for (sl = card_list; sl; sl = sl->next)
|
||||
for (keyinfo = keyinfo_list; keyinfo; keyinfo = keyinfo->next)
|
||||
{
|
||||
char *serialno0;
|
||||
char *cardsn;
|
||||
|
||||
err = agent_card_serialno (ctrl, &serialno0, sl->d);
|
||||
/*
|
||||
* FIXME: Do access by KEYGRIP directly, not by $AUTHKEYID.
|
||||
* In scdaemon, implement SCD READKEY <KEYGRIP> and
|
||||
* SCD GETATTR <KEYGRIP>.
|
||||
* Then, no switch of foreground card occurrs.
|
||||
*/
|
||||
err = agent_card_serialno (ctrl, &serialno0, keyinfo->serialno);
|
||||
if (err)
|
||||
{
|
||||
if (opt.verbose)
|
||||
@ -2619,16 +2606,14 @@ ssh_handler_request_identities (ctrl_t ctrl,
|
||||
xfree (cardsn);
|
||||
if (err)
|
||||
{
|
||||
xfree (serialno);
|
||||
free_strlist (card_list);
|
||||
agent_card_free_keyinfo (keyinfo_list);
|
||||
goto out;
|
||||
}
|
||||
|
||||
key_counter++;
|
||||
}
|
||||
|
||||
xfree (serialno);
|
||||
free_strlist (card_list);
|
||||
agent_card_free_keyinfo (keyinfo_list);
|
||||
}
|
||||
|
||||
scd_out:
|
||||
|
@ -1307,7 +1307,7 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
|
||||
if (opt_with_ssh || list_mode == 2)
|
||||
cf = ssh_open_control_file ();
|
||||
|
||||
agent_card_keyinfo (ctrl, NULL, &keyinfo_on_cards);
|
||||
agent_card_keyinfo (ctrl, NULL, 0, &keyinfo_on_cards);
|
||||
|
||||
if (list_mode == 2)
|
||||
{
|
||||
|
@ -77,7 +77,7 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info,
|
||||
struct card_key_info_s *keyinfo;
|
||||
|
||||
xfree (serialno);
|
||||
err = agent_card_keyinfo (ctrl, hexgrip, &keyinfo);
|
||||
err = agent_card_keyinfo (ctrl, hexgrip, 0, &keyinfo);
|
||||
if (!err)
|
||||
{
|
||||
/* Key for GRIP found, use it directly. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user