* scd/iso7816.c (iso7816_select_application_ext): Add flag die query FCP * scd/iso7816.h: define new response type flags * scd/app.c: apply new flags * scd/app-piv.c: ditto * scd/app-p15.c: query FCI during application selection and fallback to FCP if file ID tag 0x83 is not found.
-- Some cards (for example STARCOS 3.7 based D-Trust Cards 6.1/6.4) don't return the file ID of the application in the FCI response of the SELECT command (P2=0x00). Instead the file ID is only returned if the FCP is queried in the SELECT command (P2=0x04). If the file ID is not returned in the FCI, we will fall back to the FCP and then to the default home file ID if the FCP also fails. Signed-off-by: Mario Haustein <[email protected]> --- scd/app-p15.c | 48 +++++++++++++++++++++++++++++++++++++++++------- scd/app-piv.c | 4 ++-- scd/app.c | 2 +- scd/iso7816.c | 15 +++++++++++++-- scd/iso7816.h | 5 +++++ 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index f5c5f7a17..d12179bb4 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -6431,6 +6431,8 @@ app_select_p15 (app_t app) { int slot = app_get_slot (app); int rc; + const char *aid; + size_t aidlen; unsigned short def_home_df = 0; card_type_t card_type = CARD_TYPE_UNKNOWN; int direct = 0; @@ -6438,14 +6440,17 @@ app_select_p15 (app_t app) unsigned char *fci = NULL; size_t fcilen; - rc = iso7816_select_application_ext (slot, pkcs15_aid, sizeof pkcs15_aid, 1, - &fci, &fcilen); + aid = pkcs15_aid; + aidlen = sizeof pkcs15_aid; + rc = iso7816_select_application_ext (slot, aid, aidlen, + ISO7816_SELECT_FCI, &fci, &fcilen); if (rc) { /* D-TRUST Card 4.x uses a different AID. */ - rc = iso7816_select_application_ext (slot, pkcs15dtrust4_aid, - sizeof pkcs15dtrust4_aid, 1, - &fci, &fcilen); + aid = pkcs15dtrust4_aid; + aidlen = sizeof pkcs15dtrust4_aid; + rc = iso7816_select_application_ext (slot, aid, aidlen, + ISO7816_SELECT_FCI, &fci, &fcilen); } if (rc) { /* Not found: Try to locate it from 2F00. We use direct path @@ -6516,7 +6521,7 @@ app_select_p15 (app_t app) goto leave; } - /* Set the home DF from the FCI returned by the select. */ + /* Set the home DF from the FCI returned by the select. */ if (!def_home_df && fci) { const unsigned char *s; @@ -6525,14 +6530,43 @@ app_select_p15 (app_t app) s = find_tlv (fci, fcilen, 0x83, &n); if (s && n == 2) def_home_df = buf16_to_ushort (s); + else if (fcilen) + { + log_printhex (fci, fcilen, "fci:"); + log_info ("p15: select did not return the DF - querying FCP\n"); + } + } + + /* Set the home DF from the FCP returned by the select, when not already + * contained in the FCI. STARCOS 3.7 (at least the D-Trust Card 6.1/6.4 + * requires to request FCP instead of FCI. */ + if (!def_home_df) + { + const unsigned char *s; + size_t n; + + xfree (fci); + + fci = NULL; + fcilen = 0; + rc = iso7816_select_application_ext (slot, aid, aidlen, + ISO7816_SELECT_FCP, &fci, &fcilen); + + if (!rc && fci) + { + s = find_tlv (fci, fcilen, 0x83, &n); + if (s && n == 2) + def_home_df = buf16_to_ushort (s); + } else { if (fcilen) - log_printhex (fci, fcilen, "fci:"); + log_printhex (fci, fcilen, "fcp:"); log_info ("p15: select did not return the DF - using default\n"); def_home_df = DEFAULT_HOME_DF; } } + app->app_local->home_df = def_home_df; /* Store the card type. FIXME: We might want to put this into diff --git a/scd/app-piv.c b/scd/app-piv.c index f35815e58..a5f2d6219 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -3684,8 +3684,8 @@ app_select_piv (app_t app) /* Note that we select using the AID without the 2 octet version * number. This allows for better reporting of future specs. We * need to use the use-zero-for-P2-flag. */ - err = iso7816_select_application_ext (slot, piv_aid, sizeof piv_aid, 0x0001, - &apt, &aptlen); + err = iso7816_select_application_ext (slot, piv_aid, sizeof piv_aid, + ISO7816_SELECT_FCI, &apt, &aptlen); if (err) goto leave; diff --git a/scd/app.c b/scd/app.c index f08067e87..0329d3fb0 100644 --- a/scd/app.c +++ b/scd/app.c @@ -792,7 +792,7 @@ app_new_register (int slot, ctrl_t ctrl, const char *name, buf = NULL; if (!iso7816_select_application_ext (slot, otp_aid, sizeof otp_aid, - 1, &buf, &buflen) + ISO7816_SELECT_FCI, &buf, &buflen) && buflen > 3) card->cardversion = ((buf[0]<<16)|(buf[1]<<8)| buf[2]); } diff --git a/scd/iso7816.c b/scd/iso7816.c index 6634cd4a7..533e579de 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -152,9 +152,20 @@ iso7816_select_application_ext (int slot, const char *aid, size_t aidlen, unsigned int flags, unsigned char **result, size_t *resultlen) { + int p2; int sw; - sw = apdu_send (slot, 0, 0x00, CMD_SELECT_FILE, 4, - (flags&1)? 0:0x0c, aidlen, aid, + + switch (flags) + { + case ISO7816_SELECT_FCI: p2 = 0x00; break; + case ISO7816_SELECT_FCP: p2 = 0x04; break; + case ISO7816_SELECT_NORESP: + default: + p2 = 0x0c; + } + + sw = apdu_send (slot, 0, 0x00, CMD_SELECT_FILE, 4, p2, + aidlen, aid, result, resultlen); return map_sw (sw); } diff --git a/scd/iso7816.h b/scd/iso7816.h index 67b9f47ab..aef5c2092 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -29,6 +29,11 @@ #define ISO7816_CHANGE_REFERENCE_DATA 0x24 #define ISO7816_RESET_RETRY_COUNTER 0x2C +/* Flags to encode which data should be returned by SELECT */ +#define ISO7816_SELECT_NORESP 0 /* no response to SELECT */ +#define ISO7816_SELECT_FCI 1 /* query FCI (file control information) by SELECT */ +#define ISO7816_SELECT_FCP 2 /* query FCP (file control parameters) by SELECT */ + /* Error codes returned by iso7816_verify_status. A non-negative * number gives the number of left tries. * NB: The values are also used by the CHV-STATUS lines and thus are -- 2.52.0
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Gnupg-devel mailing list [email protected] https://lists.gnupg.org/mailman/listinfo/gnupg-devel
