Re-sending this (with some edits) since I think the first attempt a few days ago disappeared due to a mail misconfig on my side: Hi, I was giving the PIV support in master a try last night, but the current code for parsing APT objects 0x4F and 0x79 stopped me short. It appears that SP-800-73-x is not too clear about the format of these objects. Many current cards (such as the Yubikey 5 series) apparently have only the PIX in DO 0x4F and only the RID in object 0x79/0x4F. However, other cards as well as the PivApplet Javacard applet have the full AID in 0x4F (which actually seems closer to what the standard says). PivApplet also has the full AID in 0x79/0x4F, but this is probably incorrect. (Here is a long discussion of the matter from an OpenSC author: https://github.com/arekinath/PivApplet/issues/43#issuecomment-772649709) Anyway, I think it would be useful for GnuPG 2.3 to support both formats, since both appear in the wild currently. I have attached the diff I used to make a PivApplet card pass the initial probe. It also still works for a Yubikey 5. (The retry counter in gpg-card also shows an error for PivApplet because app-piv.c queries the Global PIN even though the Discovery Object doesn't indicate support for it. I couldn't try actual sign/encrypt operations yet since card-keys.c can't read certs from gpg/gpgsm.) -Valtteri diff --git a/scd/app-piv.c b/scd/app-piv.c index 36324e630..d36c5c63f 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -3641,20 +3641,23 @@ app_select_piv (app_t app) } s = find_tlv (apt, aptlen, 0x4F, &n); - if (!s || n != 6 || memcmp (s, piv_aid+5, 4)) + /* Some cards (new Yubikey) return only the PIX, while others + * (old Yubikey, PivApplet) return the RID+PIX. */ + if (!s || !((n == 6 && memcmp (s, piv_aid+5, 4) == 0) || + (n == 11 && memcmp (s, piv_aid, 9) == 0))) { /* The PIX does not match. */ log_error ("piv: missing or invalid DO 0x4F in APT\n"); err = gpg_error (GPG_ERR_CARD); goto leave; } - if (s[4] != 1 || s[5] != 0) + if (s[n-2] != 1 || s[n-1] != 0) { log_error ("piv: unknown PIV version %u.%u\n", s[4], s[5]); err = gpg_error (GPG_ERR_CARD); goto leave; } - app->appversion = ((s[4] << 8) | s[5]); + app->appversion = ((s[n-2] << 8) | s[n-1]); s = find_tlv (apt, aptlen, 0x79, &n); if (!s || n < 7) @@ -3664,7 +3667,9 @@ app_select_piv (app_t app) goto leave; } s = find_tlv (s, n, 0x4F, &n); - if (!s || n != 5 || memcmp (s, piv_aid, 5)) + /* Some cards may also return the full AID instead of just + * the 5-byte RID here. */ + if (!s || !(n == 5 || n == 11) || memcmp (s, piv_aid, 5)) { /* The RID does not match. */ log_error ("piv: missing or invalid DO 0x79.4F in APT\n"); _______________________________________________ Gnupg-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gnupg-devel |
Free forum by Nabble | Edit this page |