From 7113263a00d8c9b09f0dfdb9590bfe2bab1bc776 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 26 Nov 2020 12:36:44 +0100 Subject: [PATCH] agent: Fix YK s/n and prettify the request card prompt for Yubikeys * agent/divert-scd.c (ask_for_card): Detect and re-format the Yubikey prompt. * scd/app.c (app_munge_serialno): Fix Yubikey s/n munging. (card_get_dispserialno): Ditto. * scd/app-openpgp.c (get_disp_serialno): Remove. (get_prompt_info): Use app_get_dispserialno.-- -- --- agent/divert-scd.c | 23 +++++++++++++++++++---- scd/app-openpgp.c | 26 +------------------------- scd/app.c | 28 +++++++++++++++++++--------- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 7587d4478..273f3a869 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -59,10 +59,25 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, if (len == 32 && !strncmp (want_sn, "D27600012401", 12)) { /* This is an OpenPGP card - reformat */ - memmove (want_sn, want_sn+16, 4); - want_sn[4] = ' '; - memmove (want_sn+5, want_sn+20, 8); - want_sn[13] = 0; + if (!strncmp (want_sn+16, "0006", 4)) + { + /* This is a Yubikey. Print the s/n as it would be printed + * on Yubikey 5. Example: D2760001240100000006120808620000 + * mmmm^^^^^^^^ */ + unsigned long sn; + + sn = atoi_4 (want_sn+20) * 10000; + sn += atoi_4 (want_sn+24); + snprintf (want_sn, 32, "%lu %03lu %03lu", + (sn/1000000ul), (sn/1000ul % 1000ul), (sn % 1000ul)); + } + else /* Default is the Zeitcontrol card print format. */ + { + memmove (want_sn, want_sn+16, 4); + want_sn[4] = ' '; + memmove (want_sn+5, want_sn+20, 8); + want_sn[13] = 0; + } } else if (len == 20 && want_sn[19] == '0') { diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 36301ee8d..a30a8e8b5 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1381,30 +1381,6 @@ get_disp_name (app_t app) } -/* Return the pretty formatted serialnumber. On error NULL is - * returned. */ -static char * -get_disp_serialno (app_t app) -{ - char *serial = app_get_serialno (app); - - /* For our OpenPGP cards we do not want to show the entire serial - * number but a nicely reformatted actual serial number. */ - if (serial && strlen (serial) > 16+12) - { - memmove (serial, serial+16, 4); - serial[4] = ' '; - /* memmove (serial+5, serial+20, 4); */ - /* serial[9] = ' '; */ - /* memmove (serial+10, serial+24, 4); */ - /* serial[14] = 0; */ - memmove (serial+5, serial+20, 8); - serial[13] = 0; - } - return serial; -} - - /* Return the number of remaining tries for the standard or the admin * pw. Returns -1 on card error. */ static int @@ -2324,7 +2300,7 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining) { char *serial, *disp_name, *rembuf, *tmpbuf, *result; - serial = get_disp_serialno (app); + serial = app_get_dispserialno (app, 0); if (!serial) return NULL; diff --git a/scd/app.c b/scd/app.c index 933ad46d6..8a809e888 100644 --- a/scd/app.c +++ b/scd/app.c @@ -1208,10 +1208,22 @@ app_munge_serialno (card_t card) buf[7] = 0; /* thus we use 0.0 and don't use this directly. */ buf[8] = 0; /* Manufacturer: Yubico (0x0006). */ buf[9] = 6; - buf[10] = (sn >> 24); - buf[11] = (sn >> 16); - buf[12] = (sn >> 8); - buf[13] = sn; + buf[13] = (sn % 10); + sn /= 10; + buf[13] |= (sn % 10) << 4; + sn /= 10; + buf[12] = (sn % 10); + sn /= 10; + buf[12] |= (sn % 10) << 4; + sn /= 10; + buf[11] = (sn % 10); + sn /= 10; + buf[11] |= (sn % 10) << 4; + sn /= 10; + buf[10] = (sn % 10); + sn /= 10; + buf[10] |= (sn % 10) << 4; + sn /= 10; buf[14] = 0; /* Last two bytes are RFU. */ buf[15] = 0; xfree (card->serialno); @@ -1311,15 +1323,13 @@ card_get_dispserialno (card_t card, int nofallback) else if (card && card->cardtype == CARDTYPE_YUBIKEY) { /* Get back the printed Yubikey number from the OpenPGP AID - * Example: D2760001240100000006008A77C10000 + * Example: D2760001240100000006120808620000 */ result = card_get_serialno (card); if (result && strlen (result) >= 28 && !strncmp (result+16, "0006", 4)) { - sn = xtoi_2 (result+20) * 16777216; - sn += xtoi_2 (result+22) * 65536; - sn += xtoi_2 (result+24) * 256; - sn += xtoi_2 (result+26); + sn = atoi_4 (result+20) * 10000; + sn += atoi_4 (result+24); if ((card->cardversion >> 16) >= 5) p = xtryasprintf ("%lu %03lu %03lu", (sn/1000000ul),