diff options
author | NIIBE Yutaka <[email protected]> | 2020-01-13 07:47:23 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2020-01-13 07:47:23 +0000 |
commit | 15028627a1655b7ad1835fbd0a32cf30debe807a (patch) | |
tree | 8ead9295a237c5f3f02036864457f9ffa08961d1 /agent/command-ssh.c | |
parent | agent: Extend agent_card_getattr with KEYGRIP. (diff) | |
download | gnupg-15028627a1655b7ad1835fbd0a32cf30debe807a.tar.gz gnupg-15028627a1655b7ad1835fbd0a32cf30debe807a.zip |
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 <[email protected]>
Diffstat (limited to 'agent/command-ssh.c')
-rw-r--r-- | agent/command-ssh.c | 101 |
1 files changed, 15 insertions, 86 deletions
diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 0e3a50947..243ce76bb 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -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 - 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 - is not NULL, a string with the serial number of the card will be - a malloced and stored there. */ +/* Check whether a key of KEYGRIP on 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 is not NULL, a string with the serial number + of the card will be a malloced and stored there. */ 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; - char *authkeyid; - char *serialno = NULL; unsigned char *pkbuf; size_t pkbuflen; gcry_sexp_t s_pk; @@ -2394,48 +2393,12 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) if (cardsn) *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. */ - err = agent_card_readkey (ctrl, authkeyid, &pkbuf); + err = agent_card_readkey (ctrl, keyinfo->keygrip, &pkbuf); if (err) { if (opt.verbose) log_info (_("no suitable card key found: %s\n"), gpg_strerror (err)); - xfree (serialno); - xfree (authkeyid); 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", gpg_strerror (err)); 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; } + hex2bin (keyinfo->keygrip, grip, sizeof (grip)); if ( agent_key_available (grip) ) { /* (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) { xfree (pkbuf); gcry_sexp_release (s_pk); - xfree (serialno); - xfree (authkeyid); 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, 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); xfree (dispsn); } else - *cardsn = xtryasprintf ("cardno:%s", serialno); + *cardsn = xtryasprintf ("cardno:%s", keyinfo->serialno); if (!*cardsn) { err = gpg_error_from_syserror (); xfree (pkbuf); gcry_sexp_release (s_pk); - xfree (serialno); - xfree (authkeyid); return err; } } xfree (pkbuf); - xfree (serialno); - xfree (authkeyid); *r_pk = s_pk; return 0; } @@ -2576,26 +2522,9 @@ ssh_handler_request_identities (ctrl_t ctrl, for (keyinfo = keyinfo_list; keyinfo; keyinfo = keyinfo->next) { - char *serialno0; char *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)) + if (card_key_available (ctrl, keyinfo, &key_public, &cardsn)) continue; err = ssh_send_key_public (key_blobs, key_public, cardsn); |