Created
April 26, 2023 13:52
-
-
Save apatard/2049a50505a482c3e1e7906cba40fd72 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
scdaemon: Allow to switch between piv and openpgp apps for Nitrokey 3 | |
Nitrokey 3 token have a piv and openpgp applications, like Yubikey. | |
So add minimal glue to allow switching between them. | |
Tested with Nitrokey 3 firmware v1.3.1-test.20230417 and | |
gpg --card-status && pkcs11-tool --list-slots && gpg --card-status. | |
The scdaemon configuration was: | |
debug-all | |
debug-ccid-driver | |
log-file /root/scdaemon.log | |
disable-ccid | |
pcsc-shared | |
pcsc-driver /usr/lib/x86_64-linux-gnu/libpcsclite.so.1 | |
[ The adding certs to the PIV application has not tested. Only pkcs15-tool | |
list commands like --list-pins or -C has been used ] | |
Signed-off-by: Arnaud Patard <apatard@hupstream.com> | |
Index: gnupg2/scd/app-common.h | |
=================================================================== | |
--- gnupg2.orig/scd/app-common.h | |
+++ gnupg2/scd/app-common.h | |
@@ -55,6 +55,7 @@ typedef enum | |
{ | |
CARDTYPE_GENERIC = 0, | |
CARDTYPE_GNUK, | |
+ CARDTYPE_NK3, | |
CARDTYPE_YUBIKEY, | |
CARDTYPE_ZEITCONTROL | |
Index: gnupg2/scd/app.c | |
=================================================================== | |
--- gnupg2.orig/scd/app.c | |
+++ gnupg2/scd/app.c | |
@@ -110,6 +110,7 @@ strcardtype (cardtype_t t) | |
{ | |
case CARDTYPE_GENERIC: return "generic"; | |
case CARDTYPE_GNUK: return "gnuk"; | |
+ case CARDTYPE_NK3: return "nitrokey3"; | |
case CARDTYPE_YUBIKEY: return "yubikey"; | |
case CARDTYPE_ZEITCONTROL: return "zeitcontrol"; | |
} | |
@@ -509,7 +510,7 @@ check_application_conflict (card_t card, | |
if (card->app->apptype == APPTYPE_UNDEFINED) | |
return 0; | |
- if (card->cardtype == CARDTYPE_YUBIKEY) | |
+ if (card->cardtype == CARDTYPE_YUBIKEY || card->cardtype == CARDTYPE_NK3) | |
{ | |
if (card->app->apptype == APPTYPE_OPENPGP) | |
{ | |
@@ -680,6 +681,8 @@ app_new_register (int slot, ctrl_t ctrl, | |
card->cardtype = CARDTYPE_GNUK; | |
else if (atrlen == 21 && atr[7] == 0x75) | |
card->cardtype = CARDTYPE_ZEITCONTROL; | |
+ else if (atrlen >= 16 && !memcmp(&atr[5], "Nitrokey", 8)) | |
+ card->cardtype = CARDTYPE_NK3; | |
xfree (atr); | |
} | |
} | |
@@ -1031,7 +1034,7 @@ select_all_additional_applications_inter | |
int i, j; | |
int any_new = 0; | |
- if (card->cardtype == CARDTYPE_YUBIKEY) | |
+ if (card->cardtype == CARDTYPE_YUBIKEY || card->cardtype == CARDTYPE_NK3) | |
{ | |
candidates[0] = APPTYPE_OPENPGP; | |
candidates[1] = APPTYPE_PIV; | |
@@ -1610,9 +1613,7 @@ check_external_interference (app_t app, | |
* 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) | |
+ if (!opt.pcsc_shared || (app->card->cardtype != CARDTYPE_YUBIKEY && app->card->cardtype != CARDTYPE_NK3)) | |
return 0; | |
if (app->fnc.check_aid) | |
@@ -1651,7 +1652,7 @@ maybe_switch_app (ctrl_t ctrl, card_t ca | |
if (!card->app) | |
return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); | |
- if (card->maybe_check_aid && card->app->fnc.reselect | |
+ if (card->app->fnc.reselect | |
&& check_external_interference (card->app, ctrl)) | |
{ | |
if (DBG_APP) | |
Index: gnupg2/scd/app-openpgp.c | |
=================================================================== | |
--- gnupg2.orig/scd/app-openpgp.c | |
+++ gnupg2/scd/app-openpgp.c | |
@@ -6350,7 +6350,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_CARD(app)->cardtype != CARDTYPE_YUBIKEY) | |
+ if (APP_CARD(app)->cardtype != CARDTYPE_YUBIKEY && APP_CARD(app)->cardtype != CARDTYPE_NK3) | |
return gpg_error (GPG_ERR_NOT_SUPPORTED); | |
/* Note that the card can't cope with P2=0xCO, thus we need to pass | |
Index: gnupg2/scd/app-piv.c | |
=================================================================== | |
--- gnupg2.orig/scd/app-piv.c | |
+++ gnupg2/scd/app-piv.c | |
@@ -211,6 +211,7 @@ struct app_local_s { | |
struct | |
{ | |
unsigned int yubikey:1; /* This is on a Yubikey. */ | |
+ unsigned int nk3:1; /* This is on a Nitrokey3. */ | |
} flags; | |
/* Keep track on whether we cache a certain PIN so that we get it | |
@@ -3607,7 +3608,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.nk3) | |
return gpg_error (GPG_ERR_NOT_SUPPORTED); | |
err = iso7816_select_application (app_get_slot (app), | |
@@ -3711,6 +3712,8 @@ app_select_piv (app_t app) | |
if (app->card->cardtype == CARDTYPE_YUBIKEY) | |
app->app_local->flags.yubikey = 1; | |
+ if (app->card->cardtype == CARDTYPE_NK3) | |
+ app->app_local->flags.nk3 = 1; | |
/* FIXME: Parse the optional and conditional DOs in the APT. */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment