aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2026-09-02 09:04:49 +0200
committerNIIBE Yutaka <[email protected]>2026-09-02 09:04:49 +0200
commitbb7113d03dfc971cacdaae1c0e8fffc2ea21e5df (patch)
tree63f3f06ff4ce34546501806640b5cecef6426c08
parentdirmngr: Make the LDAP upload flags also work for KS_SEARCH (diff)
downloadgnupg-bb7113d03dfc971cacdaae1c0e8fffc2ea21e5df.tar.gz
gnupg-bb7113d03dfc971cacdaae1c0e8fffc2ea21e5df.zip
scd: Add Nitrokey 3 to pcsc-shared interference detection.
* scd/app-common.h (CARDTYPE_NITROKEY): New. * scd/app-openpgp.c (do_reselect): It's only for Yubikey or Nitrokey. * scd/app-piv.c (struct app_local_s): Add nitrokey flag field. (do_reselect): It's only for Yubikey or Nitrokey. (app_select_piv): Check CARDTYPE_NITROKEY for the flag. * scd/app.c (strcardtype): Support CARDTYPE_NITROKEY. (check_application_conflict): Support CARDTYPE_NITROKEY. (app_new_register): Add detection of Nitrokey. (select_all_additional_applications_internal): Support CARDTYPE_NITROKEY. (check_external_interference): Likewise. -- Suggested-by: Artemii Bigdan GnuPG-bug-id: 8331 Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r--scd/app-common.h3
-rw-r--r--scd/app-openpgp.c3
-rw-r--r--scd/app-piv.c5
-rw-r--r--scd/app.c53
4 files changed, 49 insertions, 15 deletions
diff --git a/scd/app-common.h b/scd/app-common.h
index 03b6c4884..ac397c922 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -57,7 +57,8 @@ typedef enum
CARDTYPE_GNUK,
CARDTYPE_YUBIKEY,
CARDTYPE_ZEITCONTROL,
- CARDTYPE_SCE7 /* G+D SmartCafe Expert 7.0 */
+ CARDTYPE_SCE7, /* G+D SmartCafe Expert 7.0 */
+ CARDTYPE_NITROKEY
} cardtype_t;
/* List of supported card applications. The source code for each
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 7390bc97a..32e3d648b 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -6560,7 +6560,8 @@ do_reselect (app_t app, ctrl_t ctrl)
/* An extra check which should not be necessary because the caller
* should have made sure that a re-select is only called for
* appropriate cards. */
- if (APP_CARD(app)->cardtype != CARDTYPE_YUBIKEY)
+ if (APP_CARD(app)->cardtype != CARDTYPE_YUBIKEY
+ && APP_CARD(app)->cardtype != CARDTYPE_NITROKEY)
return gpg_error (GPG_ERR_NOT_SUPPORTED);
/* Note that the card can't cope with P2=0xCO, thus we need to pass
diff --git a/scd/app-piv.c b/scd/app-piv.c
index a5f2d6219..660430dbb 100644
--- a/scd/app-piv.c
+++ b/scd/app-piv.c
@@ -213,6 +213,7 @@ struct app_local_s {
struct
{
unsigned int yubikey:1; /* This is on a Yubikey. */
+ unsigned int nitrokey:1; /* This is on a nitrokey. */
} flags;
/* Keep track on whether we cache a certain PIN so that we get it
@@ -3644,7 +3645,7 @@ do_reselect (app_t app, ctrl_t ctrl)
/* An extra check which should not be necessary because the caller
* should have made sure that a re-select is only called for
* appropriate cards. */
- if (!app->app_local->flags.yubikey)
+ if (!app->app_local->flags.yubikey && !app->app_local->flags.nitrokey)
return gpg_error (GPG_ERR_NOT_SUPPORTED);
err = iso7816_select_application (app_get_slot (app),
@@ -3764,6 +3765,8 @@ app_select_piv (app_t app)
if (app->card->cardtype == CARDTYPE_YUBIKEY)
app->app_local->flags.yubikey = 1;
+ else if (app->card->cardtype == CARDTYPE_NITROKEY)
+ app->app_local->flags.nitrokey = 1;
/* If we don't have a s/n construct it from the CHUID. */
if (!APP_CARD(app)->serialno)
diff --git a/scd/app.c b/scd/app.c
index a33175969..edb1142d2 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -126,6 +126,7 @@ strcardtype (cardtype_t t)
case CARDTYPE_YUBIKEY: return "yubikey";
case CARDTYPE_ZEITCONTROL: return "zeitcontrol";
case CARDTYPE_SCE7: return "smartcafe";
+ case CARDTYPE_NITROKEY: return "nitrokey";
}
return "?";
}
@@ -597,7 +598,8 @@ check_application_conflict (card_t card, const char *name,
if (card->app->apptype == APPTYPE_UNDEFINED)
return 0;
- if (card->cardtype == CARDTYPE_YUBIKEY)
+ if (card->cardtype == CARDTYPE_YUBIKEY
+ || card->cardtype == CARDTYPE_NITROKEY)
{
if (card->app->apptype == APPTYPE_OPENPGP)
{
@@ -803,7 +805,7 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
else
card->cardtype = atr_to_cardtype (slot, NULL, 0);
}
- else /* Got 3F00 */
+ else if (!err) /* 3F00 selected successfully */
{
unsigned char *atr;
size_t atrlen;
@@ -822,12 +824,36 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
xfree (atr);
}
}
+ else /* 3F00 not available */
+ {
+ unsigned char *buffer;
+ size_t buflen;
+
+ /* Try to get the historical bytes by 0x5f52 (select
+ application is not required). This is heuristics to
+ identify Nitrokey. Note that its ATR and historical
+ bytes are unrelated. */
+ err = iso7816_get_data (slot, 0, 0x5f52, &buffer, &buflen);
+ if (err || buflen != 10)
+ err = GPG_ERR_CARD;
+ else if (!memcmp (buffer,
+ "\x00\x31\xF5\x73\xC0\x01\x60\x05\x90\x00", 10))
+ card->cardtype = CARDTYPE_NITROKEY;
+ else
+ err = GPG_ERR_CARD;
+ xfree (buffer);
+ if (err)
+ return err;
+ }
- if (!err && card->cardtype != CARDTYPE_YUBIKEY)
+ if (!err && card->cardtype != CARDTYPE_YUBIKEY
+ && card->cardtype != CARDTYPE_NITROKEY)
err = iso7816_select_file (slot, 0x2F02, 0);
- if (!err && card->cardtype != CARDTYPE_YUBIKEY)
+ if (!err && card->cardtype != CARDTYPE_YUBIKEY
+ && card->cardtype != CARDTYPE_NITROKEY)
err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
- if (!err && card->cardtype != CARDTYPE_YUBIKEY)
+ if (!err && card->cardtype != CARDTYPE_YUBIKEY
+ && card->cardtype != CARDTYPE_NITROKEY)
{
size_t n;
const unsigned char *p;
@@ -1172,7 +1198,8 @@ select_all_additional_applications_internal (ctrl_t ctrl, card_t card)
int i, j;
int any_new = 0;
- if (card->cardtype == CARDTYPE_YUBIKEY)
+ if (card->cardtype == CARDTYPE_YUBIKEY
+ || card->cardtype == CARDTYPE_NITROKEY)
{
candidates[0] = APPTYPE_OPENPGP;
candidates[1] = APPTYPE_PIV;
@@ -1745,15 +1772,17 @@ static int
check_external_interference (app_t app, ctrl_t ctrl)
{
/*
- * Only when a user is using Yubikey with pcsc-shared configuration,
- * we need this detection. Otherwise, the card/token is under full
- * control of scdaemon, there's no problem at all. However, if the
- * APDU command has been used we better also check whether the AID
- * is still valid.
+ * Only when a user is using Yubikey/Nitrokey with pcsc-shared
+ * configuration, we need this detection. Otherwise, the card/token
+ * is under full control of scdaemon, there's no problem at all.
+ * However, if the APDU command has been used we better also check
+ * whether the AID is still valid.
*/
if (app && app->card && app->card->maybe_check_aid)
app->card->maybe_check_aid = 0;
- else if (!opt.pcsc_shared || app->card->cardtype != CARDTYPE_YUBIKEY)
+ else if (!opt.pcsc_shared
+ || (app->card->cardtype != CARDTYPE_YUBIKEY
+ && app->card->cardtype != CARDTYPE_NITROKEY))
return 0;
if (app->fnc.check_aid)