mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
agent: handle SSH operation by KEYGRIP.
* agent/command-ssh.c (card_key_available): Supply KEYINFO argument. Call agent_card_readkey by KEYGRIP of KEYINFO. Don't use $AUTHKEYID, but IDSTR of KEYINFO. (ssh_handler_request_identities): Follow the change of card_key_available. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
c31266716d
commit
15028627a1
@ -2374,17 +2374,16 @@ ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check whether a smartcard is available and whether it has a usable
|
/* Check whether a key of KEYGRIP on smartcard is available and
|
||||||
key. Store a copy of that key at R_PK and return 0. If no key is
|
whether it has a usable key. Store a copy of that key at R_PK and
|
||||||
available store NULL at R_PK and return an error code. If CARDSN
|
return 0. If no key is available store NULL at R_PK and return an
|
||||||
is not NULL, a string with the serial number of the card will be
|
error code. If CARDSN is not NULL, a string with the serial number
|
||||||
a malloced and stored there. */
|
of the card will be a malloced and stored there. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
|
card_key_available (ctrl_t ctrl, const struct card_key_info_s *keyinfo,
|
||||||
|
gcry_sexp_t *r_pk, char **cardsn)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
char *authkeyid;
|
|
||||||
char *serialno = NULL;
|
|
||||||
unsigned char *pkbuf;
|
unsigned char *pkbuf;
|
||||||
size_t pkbuflen;
|
size_t pkbuflen;
|
||||||
gcry_sexp_t s_pk;
|
gcry_sexp_t s_pk;
|
||||||
@ -2394,48 +2393,12 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
|
|||||||
if (cardsn)
|
if (cardsn)
|
||||||
*cardsn = NULL;
|
*cardsn = NULL;
|
||||||
|
|
||||||
/* First see whether a card is available and whether the application
|
|
||||||
is supported. */
|
|
||||||
err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
|
|
||||||
if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
|
|
||||||
{
|
|
||||||
/* Ask for the serial number to reset the card. */
|
|
||||||
err = agent_card_serialno (ctrl, &serialno, NULL);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
if (opt.verbose)
|
|
||||||
log_info (_("error getting serial number of card: %s\n"),
|
|
||||||
gpg_strerror (err));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
log_info (_("detected card with S/N: %s\n"), serialno);
|
|
||||||
err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
|
|
||||||
}
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
log_error (_("no authentication key for ssh on card: %s\n"),
|
|
||||||
gpg_strerror (err));
|
|
||||||
xfree (serialno);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the S/N if we don't have it yet. Use the fast getattr method. */
|
|
||||||
if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
|
|
||||||
{
|
|
||||||
log_error (_("error getting serial number of card: %s\n"),
|
|
||||||
gpg_strerror (err));
|
|
||||||
xfree (authkeyid);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the public key. */
|
/* Read the public key. */
|
||||||
err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
|
err = agent_card_readkey (ctrl, keyinfo->keygrip, &pkbuf);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
|
log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
|
||||||
xfree (serialno);
|
|
||||||
xfree (authkeyid);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2446,33 +2409,19 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
|
|||||||
log_error ("failed to build S-Exp from received card key: %s\n",
|
log_error ("failed to build S-Exp from received card key: %s\n",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
xfree (pkbuf);
|
xfree (pkbuf);
|
||||||
xfree (serialno);
|
|
||||||
xfree (authkeyid);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ssh_key_grip (s_pk, grip);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
log_debug ("error computing keygrip from received card key: %s\n",
|
|
||||||
gcry_strerror (err));
|
|
||||||
xfree (pkbuf);
|
|
||||||
gcry_sexp_release (s_pk);
|
|
||||||
xfree (serialno);
|
|
||||||
xfree (authkeyid);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hex2bin (keyinfo->keygrip, grip, sizeof (grip));
|
||||||
if ( agent_key_available (grip) )
|
if ( agent_key_available (grip) )
|
||||||
{
|
{
|
||||||
/* (Shadow)-key is not available in our key storage. */
|
/* (Shadow)-key is not available in our key storage. */
|
||||||
err = agent_write_shadow_key (grip, serialno, authkeyid, pkbuf, 0);
|
err = agent_write_shadow_key (grip, keyinfo->serialno,
|
||||||
|
keyinfo->idstr, pkbuf, 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
xfree (pkbuf);
|
xfree (pkbuf);
|
||||||
gcry_sexp_release (s_pk);
|
gcry_sexp_release (s_pk);
|
||||||
xfree (serialno);
|
|
||||||
xfree (authkeyid);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2483,27 +2432,24 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
|
|||||||
|
|
||||||
/* If the card handler is able to return a short serialnumber,
|
/* If the card handler is able to return a short serialnumber,
|
||||||
use that one, else use the complete serialno. */
|
use that one, else use the complete serialno. */
|
||||||
if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
|
if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn,
|
||||||
|
keyinfo->keygrip))
|
||||||
{
|
{
|
||||||
*cardsn = xtryasprintf ("cardno:%s", dispsn);
|
*cardsn = xtryasprintf ("cardno:%s", dispsn);
|
||||||
xfree (dispsn);
|
xfree (dispsn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*cardsn = xtryasprintf ("cardno:%s", serialno);
|
*cardsn = xtryasprintf ("cardno:%s", keyinfo->serialno);
|
||||||
if (!*cardsn)
|
if (!*cardsn)
|
||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
xfree (pkbuf);
|
xfree (pkbuf);
|
||||||
gcry_sexp_release (s_pk);
|
gcry_sexp_release (s_pk);
|
||||||
xfree (serialno);
|
|
||||||
xfree (authkeyid);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree (pkbuf);
|
xfree (pkbuf);
|
||||||
xfree (serialno);
|
|
||||||
xfree (authkeyid);
|
|
||||||
*r_pk = s_pk;
|
*r_pk = s_pk;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2576,26 +2522,9 @@ ssh_handler_request_identities (ctrl_t ctrl,
|
|||||||
|
|
||||||
for (keyinfo = keyinfo_list; keyinfo; keyinfo = keyinfo->next)
|
for (keyinfo = keyinfo_list; keyinfo; keyinfo = keyinfo->next)
|
||||||
{
|
{
|
||||||
char *serialno0;
|
|
||||||
char *cardsn;
|
char *cardsn;
|
||||||
|
|
||||||
/*
|
if (card_key_available (ctrl, keyinfo, &key_public, &cardsn))
|
||||||
* 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)
|
|
||||||
log_info (_("error getting serial number of card: %s\n"),
|
|
||||||
gpg_strerror (err));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
xfree (serialno0);
|
|
||||||
if (card_key_available (ctrl, &key_public, &cardsn))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
err = ssh_send_key_public (key_blobs, key_public, cardsn);
|
err = ssh_send_key_public (key_blobs, key_public, cardsn);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user