aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-03-27 16:34:50 +0000
committerWerner Koch <[email protected]>2019-03-27 16:35:50 +0000
commit5a3055eb722e61126748e83564e1bba42807d722 (patch)
tree7e84d8a13e7afb5bfddd55c849139a7c42ee3452
parentgpg: Don't use EdDSA algo ID for ECDSA curves. (diff)
downloadgnupg-5a3055eb722e61126748e83564e1bba42807d722.tar.gz
gnupg-5a3055eb722e61126748e83564e1bba42807d722.zip
scd: Support reading the Yubikey 4 firmware version.
* scd/app.c (app_new_register): Detect yk4 version numbers. -- Having the version of the yubikey is important to select which other methods can be used with a Yubikey. Note that we do not detect the formfactor of a Yubikey 4 and instead use 0 for our serial number prefix. This does not affect app-openpgp becuase there we use the app specific serial number. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--scd/app.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/scd/app.c b/scd/app.c
index 81218f411..f0f6d7ecb 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -247,9 +247,12 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
* config. */
static char const yk_aid[] =
{ 0xA0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17 }; /*MGR*/
+ static char const otp_aid[] =
+ { 0xA0, 0x00, 0x00, 0x05, 0x27, 0x20, 0x01 }; /*OTP*/
unsigned char *buf;
size_t buflen;
- const unsigned char *s0, *s1;
+ const unsigned char *s0;
+ unsigned char formfactor;
size_t n;
if (!iso7816_select_application (slot, yk_aid, sizeof yk_aid,
@@ -269,29 +272,43 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
if (buflen > 1)
{
s0 = find_tlv (buf+1, buflen-1, 0x04, &n); /* Form factor */
- if (s0 && n == 1)
+ formfactor = (s0 && n == 1)? *s0 : 0;
+
+ s0 = find_tlv (buf+1, buflen-1, 0x02, &n); /* Serial */
+ if (s0 && n >= 4)
{
- s1 = find_tlv (buf+1, buflen-1, 0x02, &n); /* Serial */
- if (s1 && n >= 4)
+ app->serialno = xtrymalloc (3 + 1 + n);
+ if (app->serialno)
{
- app->serialno = xtrymalloc (3 + 1 + n);
- if (app->serialno)
- {
- app->serialnolen = 3 + 1 + n;
- app->serialno[0] = 0xff;
- app->serialno[1] = 0x02;
- app->serialno[2] = 0x0;
- app->serialno[3] = *s0;
- memcpy (app->serialno + 4, s1, n);
- /* Note that we do not clear the error
- * so that no further serial number
- * testing is done. After all we just
- * set the serial number. */
- }
+ app->serialnolen = 3 + 1 + n;
+ app->serialno[0] = 0xff;
+ app->serialno[1] = 0x02;
+ app->serialno[2] = 0x0;
+ app->serialno[3] = formfactor;
+ memcpy (app->serialno + 4, s0, n);
+ /* Note that we do not clear the error
+ * so that no further serial number
+ * testing is done. After all we just
+ * 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]);
+ }
+
+ s0 = find_tlv (buf+1, buflen-1, 0x05, &n); /* version */
+ if (s0 && n == 3)
+ app->cardversion = ((s0[0]<<16)|(s0[1]<<8)|s0[2]);
+ else if (!s0)
+ {
+ /* No version - this is not a Yubikey 5. We now
+ * switch to the OTP app and take the first
+ * three bytes of the reponse as version
+ * number. */
+ xfree (buf);
+ buf = NULL;
+ if (!iso7816_select_application_ext (slot,
+ otp_aid, sizeof otp_aid,
+ 1, &buf, &buflen)
+ && buflen > 3)
+ app->cardversion = ((buf[0]<<16)|(buf[1]<<8)|buf[2]);
}
}
xfree (buf);