diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2020-10-23 09:31:03 +0200 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2020-10-23 09:31:03 +0200 |
commit | 2d4de4b6f06c87cd0f72b2a0d09950e1b50841b2 (patch) | |
tree | 9faa40f8ed13ff74dea166d30f05fcfff67b31bb /scd | |
parent | scd: Use app_get_serialno for app_getattr. (diff) | |
download | gnupg2-2d4de4b6f06c87cd0f72b2a0d09950e1b50841b2.tar.xz gnupg2-2d4de4b6f06c87cd0f72b2a0d09950e1b50841b2.zip |
scd: Handle Yubikey's multiple apps and serialno.
* scd/app-common.h (yubikey_get_serialno): New.
* scd/app-openpgp.c (yubikey_get_serialno): New.
* scd/app.c (card_get_serialno): Use OpenPGP app's serialno,
when it's enabled for Yubikey.
(send_serialno_and_app_status): Use card_get_serialno, not
directly accessing ->serialno.
--
GnuPG-bug-id: 5100
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'scd')
-rw-r--r-- | scd/app-common.h | 1 | ||||
-rw-r--r-- | scd/app-openpgp.c | 33 | ||||
-rw-r--r-- | scd/app.c | 45 |
3 files changed, 72 insertions, 7 deletions
diff --git a/scd/app-common.h b/scd/app-common.h index d245b8b0a..a9a6bd065 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -237,6 +237,7 @@ gpg_error_t app_send_card_list (ctrl_t ctrl); gpg_error_t app_send_active_apps (card_t card, ctrl_t ctrl); char *card_get_serialno (card_t card); char *app_get_serialno (app_t app); +char *yubikey_get_serialno (app_t app); void app_dump_state (void); void application_notify_card_reset (int slot); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 8085fa812..b75ee6457 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1383,6 +1383,39 @@ get_disp_name (app_t app) } +/* + * Yubikey has its own serial number at app->serialno. When Yubikey + * is used for OpenPGP card app, we get the serial number for OpenPGP + * card from its AID data object. + */ +char * +yubikey_get_serialno (app_t app) +{ + void *relptr; + unsigned char *buffer; + size_t buflen; + char *serial; + + relptr = get_one_do (app, 0x004F, &buffer, &buflen, NULL); + if (!relptr) + return NULL; + if (buflen != 16) + { + xfree (relptr); + return NULL; + } + + serial = xtrymalloc (32 + 1); + if (!serial) + return NULL; + + serial[32] = 0; + bin2hex (buffer, buflen, serial); + xfree (relptr); + return serial; +} + + /* Return the pretty formatted serialnumber. On error NULL is * returned. */ static char * @@ -1191,7 +1191,30 @@ card_get_serialno (card_t card) if (!card->serialnolen) serial = xtrystrdup ("FF7F00"); + else if (card->cardtype == CARDTYPE_YUBIKEY) + { + app_t a; + + for (a = card->app; a; a = a->next) + if (a->apptype == APPTYPE_OPENPGP) + break; + + /* Found the OpenPGP app */ + if (a->apptype == APPTYPE_OPENPGP) + { + if (card->app != a) + run_reselect (NULL, card, a, card->app); + + serial = yubikey_get_serialno (a); + + if (card->app != a) + run_reselect (NULL, card, card->app, a); + } + else + goto other; + } else + other: serial = bin2hex (card->serialno, card->serialnolen, NULL); return serial; @@ -2107,15 +2130,15 @@ send_serialno_and_app_status (card_t card, int with_apps, ctrl_t ctrl) { gpg_error_t err; app_t a; - char buf[65]; + char *serial; char *p; membuf_t mb; int any = 0; - if (DIM (buf) < 2 * card->serialnolen + 1) + serial = card_get_serialno (card); + if (!serial) return 0; /* Oops. */ - bin2hex (card->serialno, card->serialnolen, buf); if (with_apps) { /* Note that in case the additional applications have not yet been @@ -2123,10 +2146,13 @@ send_serialno_and_app_status (card_t card, int with_apps, ctrl_t ctrl) * "SERIALNO --all", we do that here. */ err = select_all_additional_applications_internal (ctrl, card); if (err) - return err; + { + xfree (serial); + return err; + } init_membuf (&mb, 256); - put_membuf_str (&mb, buf); + put_membuf_str (&mb, serial); for (a = card->app; a; a = a->next) { if (!a->fnc.with_keygrip) @@ -2145,13 +2171,18 @@ send_serialno_and_app_status (card_t card, int with_apps, ctrl_t ctrl) put_membuf (&mb, "", 1); p = get_membuf (&mb, NULL); if (!p) - return gpg_error_from_syserror (); + { + err = gpg_error_from_syserror (); + xfree (serial); + return err; + } send_status_direct (ctrl, "SERIALNO", p); xfree (p); } else - send_status_direct (ctrl, "SERIALNO", buf); + send_status_direct (ctrl, "SERIALNO", serial); + xfree (serial); return 0; } |