aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-03-05 16:40:08 +0000
committerWerner Koch <[email protected]>2019-03-05 16:40:08 +0000
commit8d4af54ddd039d47e9c4803559193fcca97f0a46 (patch)
tree574703e89a3e6f899765c4660d0f353c1bec52c9
parentscd: Rename a shared info field name. (diff)
downloadgnupg-8d4af54ddd039d47e9c4803559193fcca97f0a46.tar.gz
gnupg-8d4af54ddd039d47e9c4803559193fcca97f0a46.zip
card: Print card version. Check for bad Yubikeys.
* scd/app.c (app_new_register): Set card version for Yubikeys. (app_write_learn_status): Print CARDVERSION and APPVERSION. * tools/card-call-scd.c (learn_status_cb): Detect them. * tools/gpg-card.h (struct card_info_s): Add appversion and cardversion. * tools/gpg-card.c (list_openpgp): Remove version printing from serial number. (print_a_version): New. (list_card): Print card and app version. (cmd_generate): Do not allow broken Yubikeys. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--scd/app.c20
-rw-r--r--scd/command.c2
-rw-r--r--tools/card-call-scd.c16
-rw-r--r--tools/gpg-card.c40
-rw-r--r--tools/gpg-card.h2
5 files changed, 67 insertions, 13 deletions
diff --git a/scd/app.c b/scd/app.c
index ada1eb963..2ee104d9e 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -263,6 +263,9 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
* set the serial number. */
}
}
+ s1 = find_tlv (buf+1, buflen-1, 0x05, &n); /* version */
+ if (s1 && n == 3)
+ app->cardversion = ((s1[0]<<16)|(s1[1]<<8)|s1[2]);
}
}
xfree (buf);
@@ -632,7 +635,7 @@ app_get_serialno (app_t app)
}
-/* Write out the application specifig status lines for the LEARN
+/* Write out the application specific status lines for the LEARN
command. */
gpg_error_t
app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
@@ -645,10 +648,17 @@ app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
/* We do not send CARD and APPTYPE if only keypairinfo is requested. */
- if (app->cardtype && !(flags & 1))
- send_status_direct (ctrl, "CARDTYPE", app->cardtype);
- if (app->apptype && !(flags & 1))
- send_status_direct (ctrl, "APPTYPE", app->apptype);
+ if (!(flags &1))
+ {
+ if (app->cardtype)
+ send_status_direct (ctrl, "CARDTYPE", app->cardtype);
+ if (app->cardversion)
+ send_status_printf (ctrl, "CARDVERSION", "%X", app->cardversion);
+ if (app->apptype)
+ send_status_direct (ctrl, "APPTYPE", app->apptype);
+ if (app->appversion)
+ send_status_printf (ctrl, "APPVERSION", "%X", app->appversion);
+ }
err = lock_app (app, ctrl);
if (err)
diff --git a/scd/command.c b/scd/command.c
index 5b2ca6c29..0d1a5cd3f 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1120,7 +1120,7 @@ static const char hlp_genkey[] =
"\n"
" 'p' and 'n' are the names of the RSA parameters; '-' is used to\n"
" indicate that HEXDATA is the first chunk of a parameter given\n"
- " by the next KEY-DATA.\n"
+ " by the next KEY-DATA. Only used by GnuPG version < 2.1.\n"
"\n"
"--force is required to overwrite an already existing key. The\n"
"KEY-CREATED-AT is required for further processing because it is\n"
diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c
index f7dbfd6ec..0a01bf5ca 100644
--- a/tools/card-call-scd.c
+++ b/tools/card-call-scd.c
@@ -818,7 +818,7 @@ learn_status_cb (void *opaque, const char *line)
parm->chvusage[0] = byte1;
parm->chvusage[1] = byte2;
}
- break;
+ break;
case 10:
if (!memcmp (keyword, "PUBKEY-URL", keywordlen))
@@ -880,6 +880,13 @@ learn_status_cb (void *opaque, const char *line)
xfree (buf);
}
+ else if (!memcmp (keyword, "APPVERSION", keywordlen))
+ {
+ unsigned int val = 0;
+
+ sscanf (line, "%x", &val);
+ parm->appversion = val;
+ }
break;
case 11:
@@ -944,6 +951,13 @@ learn_status_cb (void *opaque, const char *line)
}
}
}
+ else if (!memcmp (keyword, "CARDVERSION", keywordlen))
+ {
+ unsigned int val = 0;
+
+ sscanf (line, "%x", &val);
+ parm->cardversion = val;
+ }
break;
case 12:
diff --git a/tools/gpg-card.c b/tools/gpg-card.c
index bd450c0bb..89cefdeb6 100644
--- a/tools/gpg-card.c
+++ b/tools/gpg-card.c
@@ -781,11 +781,6 @@ list_openpgp (card_info_t info, estream_t fp)
return;
}
- tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n",
- info->serialno[12] == '0'?"":info->serialno+12,
- info->serialno[13],
- info->serialno[14] == '0'?"":info->serialno+14,
- info->serialno[15]);
tty_fprintf (fp, "Manufacturer .....: %s\n",
get_manufacturer (xtoi_2(info->serialno+16)*256
+ xtoi_2 (info->serialno+18)));
@@ -941,6 +936,25 @@ list_piv (card_info_t info, estream_t fp)
}
+
+static void
+print_a_version (estream_t fp, const char *prefix, unsigned int value)
+{
+ unsigned int a, b, c, d;
+ a = ((value >> 24) & 0xff);
+ b = ((value >> 16) & 0xff);
+ c = ((value >> 8) & 0xff);
+ d = ((value ) & 0xff);
+
+ if (a)
+ tty_fprintf (fp, "%s %u.%u.%u.%u\n", prefix, a, b, c, d);
+ else if (b)
+ tty_fprintf (fp, "%s %u.%u.%u\n", prefix, b, c, d);
+ else
+ tty_fprintf (fp, "%s %u.%u\n", prefix, c, d);
+}
+
+
/* Print all available information about the current card. */
static void
list_card (card_info_t info)
@@ -951,6 +965,8 @@ list_card (card_info_t info)
info->reader? info->reader : "[none]");
if (info->cardtype)
tty_fprintf (fp, "Card type ........: %s\n", info->cardtype);
+ if (info->cardversion)
+ print_a_version (fp, "Card firmware ....:", info->cardversion);
tty_fprintf (fp, "Serial number ....: %s\n",
info->serialno? info->serialno : "[none]");
tty_fprintf (fp, "Application type .: %s%s%s%s\n",
@@ -959,9 +975,11 @@ list_card (card_info_t info)
info->apptype == APP_TYPE_UNKNOWN && info->apptypestr
? info->apptypestr:"",
info->apptype == APP_TYPE_UNKNOWN && info->apptypestr? ")":"");
+ if (info->appversion)
+ print_a_version (fp, "Version ..........:", info->appversion);
if (info->serialno && info->dispserialno
&& strcmp (info->serialno, info->dispserialno))
- tty_fprintf (fp, "Displayed S/N ....: %s\n", info->dispserialno);
+ tty_fprintf (fp, "Displayed s/n ....: %s\n", info->dispserialno);
switch (info->apptype)
{
@@ -2044,6 +2062,16 @@ cmd_generate (card_info_t info, char *argstr)
keyref = keyref_buffer;
}
+ /* Special checks. */
+ if ((info->cardtype && !strcmp (info->cardtype, "yubikey"))
+ && info->cardversion >= 0x040200 && info->cardversion < 0x040305)
+ {
+ log_error ("On-chip key generation on this YubiKey has been blocked.\n");
+ log_info ("Please see <https://yubi.co/ysa201701> for details\n");
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+ goto leave;
+ }
+
/* Divert to dedicated functions. */
if (info->apptype == APP_TYPE_OPENPGP)
{
diff --git a/tools/gpg-card.h b/tools/gpg-card.h
index 3a86a67ec..099ea5448 100644
--- a/tools/gpg-card.h
+++ b/tools/gpg-card.h
@@ -142,8 +142,10 @@ struct card_info_s
int error; /* private. */
char *reader; /* Reader information. */
char *cardtype; /* NULL or type of the card. */
+ unsigned int cardversion; /* Firmware version of the card. */
char *apptypestr; /* Malloced application type string. */
app_type_t apptype;/* Translated from APPTYPESTR. */
+ unsigned int appversion; /* Version of the application. */
char *serialno; /* malloced hex string. */
char *dispserialno;/* malloced string. */
char *disp_name; /* malloced. */