[PATCH GnuPG 1/2] scd: allow to query FCP when selecting an application
Mario Haustein
mario.haustein at hrz.tu-chemnitz.de
Sun Jan 4 17:06:54 CET 2026
* 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 <mario.haustein at hrz.tu-chemnitz.de>
---
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 870 bytes
Desc: This is a digitally signed message part.
URL: <https://lists.gnupg.org/pipermail/gnupg-devel/attachments/20260104/975a1199/attachment.sig>
More information about the Gnupg-devel
mailing list