Page MenuHome GnuPG

SCDaemon Not reselect applet and reauthenticate when the card send Security Not Sastisfied
Closed, ResolvedPublic

Description

With the switch PCSC-SHARED is used. The problem is when the card is deauthenticated by other apps the scdeamon not reauthenticate when the card send security_not_sastisfied. If the SCDaemon require to enter the pin was a good correction and augment the compatibility with other apps when the card is used by more than one application. The best solution is to reselect AID and reauthenticate with pin query. Because presently if the card is not authentication for decryption. SCDaemon fail and no pin was queried and the only solution is to kill daemon for the daemon redo all selection and redo the authentication.

It's more friendly to query pin more often than the app crash. I have adjusted my card app for is more friendly with the current implementation of smartcard daemon. But if windows need a card to crypt or sign. The last command is deauth all pin. This causes the next decryption command from GnuPGP the card send Security not satisfied error 0x6982. When this arrives the Deamon freeze and not prompt the user to reenter the pin. This can hang kleopatra and other GnuPgp app. The temporary solution is to kill the daemon. And the system prompt to insert cards and reprompt to send pin. All it's OK until another application use the card and deauth all pin.

For all majority of applet if bad applet is selected and try to use security perform apdu the system return 0x6982 security not satisfied. In this case the reselection of applet is the more secure way for the compatibility.

The trigger needed was if the card send SW 0x6982 on any decryption tentative the system resend the select apdu for the applet and demand the pin to the user. For signature was perfect if need pin for all sign option is enabled. Another corrective measure is to implement the all crypt operation need pin option is not good but can do the job. It's not the best because if the wrong applet is selected the next command will fail.

Details

Version
2.3.1.52157

Event Timeline

Sanmilie created this task.
Sanmilie created this object in space S1 Public.

I'd like to support your use case. Could you please tell me about: How can we distinguish normal failure of 6982 and unusual failure of other application interference which results 6982?

Possible way would be: (for newer card/token of OpenPGPcard 3.4 or later) before crypto operations, we can ask card/token if authentication state is consistent to the one of scdaemon and if not reselect AID.

When a card sends 0x6982 in general rule is not really an error is a warning to say, your security environment was not correctly initialized.
This is true with almost applet. (PIV – GIDS – OPenPGP)
The instruction 0x2A to perform security operation return 0x6982 when pin is not authenticated or key is badly selected. This not decrement pin counter.

Situation checking:
for detecting is the good applet is selected you can get data for AID
APDU : 00 CA 00 4F 00 00 |Get AID
Compare OpenPGP RID if OK the good applet is selected other applet throw error on this command or return a bad information.
If Error or bad Data
reselect applet AID
Restore security environment because all information on deselect applet is clearer
Require Pin to perform security operation.

Presently the specification the card not say if the pin is already authenticated or not it’s returning only pin retry counter. Info Block Data C4 and info for using the PW01. PW01 for crypto as no parameter.

Adjustment with no modification on specification
Case 1: GIDS or another applet perturbs OpenPGP operation.

  1. User sends email with OpenPGP
  2. SCDaemon start and initialize security environment.
  3. SCDaemon prompt for Pin for signature
  4. User decrypts email
  5. SCDaemon prompt for Pin for CryptoKey
  6. SCDaemon retain the status of card is Authenticated for decryption operation
  7. User decrypts other email
  8. No pin prompt and the email was decrypted correctly
  9. Users need to sing Acrobat Doc
  10. Windows selects GIDS applet for signing. This trig garbage manager to clear ram for OpenPGP applet. All pin is automatically Deauthenticated.
  11. GIDS perform Crypto Opration.
  12. GIDs deauthenticate all pin
  13. User return to email and try to decrypt another email
  14. SCDaemon try to use 0x2A to perform security operation with the cached info
  15. Card says 0x6982 (the actual state the perform security operation is sent to GIDS applet not OpenPGP is normal operation fails with 0x6982 because the security environment is not settled for GIDS.
  16. At this moment the SCDaemon freeze and not able to return in valid position.

The corrective path

  1. When the error 0x6982 is triggering the SCDaemon try to validate the current selected applet by requesting AID data from the card APDU : 00 CA 00 4F 00 00 |Get AID
  2. Card Fail to return because it’s GIDS is selected.
  3. SCDaemon reselect AID for OPENPGP APDU 00 a4 04 00 06 d27600012401
  4. SCDaemon recall Get AID APDU : 00 CA 00 4F 00 00 |Get AID and compare the serial number with the cached serial number if OK. Clear pin cache status to all pin is unauthenticated
  5. Restore security environment with demand pin to users for the current command Get Pinstatus for checking if the pin is blocked or not Info block C4
  6. SCDaemon validate pin and retry to decrypt.

All is restored. And SCdamon can do normal operation

Case 2: Pin authentication perturbation on crypto with the good applet is selected (OpenPGP is default applet selected)
User sends email with OpenPGP

  1. SCDaemon start and initialize security environment.
  2. SCDaemon prompt for Pin for signature
  3. Email is send
  4. User decrypts email
  5. SCDaemon prompt for Pin for CryptoKey (in fact the pin is already validated by signature)
  6. SCDaemon retain the status of card is Authenticated for decryption operation
  7. User decrypts other email
  8. No pin prompt and the email was decrypted correctly
  9. Users need to use FIDO applet for WebAuthn
  10. Chrome selects FIDO applet
  11. Chrome performs FIDO operation.
  12. Chrome select default applet send 00 a4 04 00 00 – By this way it reselect OpenGPG because OpenPGP is default selected applet. (This is a trigger form Chrome it reselect default applet when it finishes all own operation.
  13. User tries to decrypt email
  14. SCDaemon try to use 0x2A to perform security operation with the cached info for decryption with crypt pin normally already authenticated
  15. Card say 0x6982 (the actual state the perform security operation is sending openpgp applet with a not authenticated pin.

At this moment the SCDaemon freeze and not able to return in valid position
The corrective path

  1. When the error 0x6982 is triggering the SCDaemon try to validate the current selected applet by requesting AID data from the card APDU : 00 CA 00 4F 00 00 |Get AID
  2. Card return data + success, SCDaemon Compare the serial number with the cached serial number if OK. Clear pin cache status to all pin is unauthenticated
  3. Restore security environment with demand pin to users for the current command Get Pinstatus for checking if the pin is blocked or not Info block C4
  4. SCDaemon validate pin and retry to decrypt.

All is restored. And SCdamon can do normal operation

Complementary Info
Presently after reading the specs x amount of time the only easy method to detect if the OpenPGP applet is selected is to get data 0x4F this return the full serial number by validating the RID you can determine the right application.
If the applet return OpenPGP AID the good applet is presently selected.
Because the PGP as not actually the method to query the card if the pin is already authenticated or not. The Pin Status Block says only if the pin is blocked or not and if the PW1 needs to be prompt at each signature.
In the case 2 the only time all its correct if the user sends email with signatures before trying to decrypt email because if the flag is set for prompt pin for all signatures the pin remain in authenticated value after the signature and subsequent call for decryption was OK. The problem it’s the same the flag is set for prompt pin for all signatures is not set.
The mess with the PW01. Because the PW01 is used to decrypt and signature the card cannot enforce the pin deauthicated after each signature if the card enforce this the SCDaemon fail with the subsequent decryption after signature. And leave ScDaemon in inconsistent state.
Problem Is Described at Figure 9.3 - 9.4 Pages 96-97
The SCDeamon expect the pin is validated if the status in cache is validated event if the pin is needed for each signature. With this trigger, the card is left in shared mode with an authenticated pin and can by use by others without pin prompting. This leaves the private key for signature ready for another command. This because the card cannot enforce the deautehnticated pin after each signature.
The solution is to use another pin for crypto-operation to grant the signature cannot be made without users pin validation.

I have tried the case 1 with log activated
Windows switches applet for signing Adobe Acrobat doc.
This is the log from agent - Say Bad NIP but he never tries to use the nip SCDaemon have tried to decrypt only.
gpg-agent[8496]: DBG: agent_put_cache '1//'.-1 (mode 6) requested ttl=-1
gpg-agent[8496]: DBG: chan_0x000001c0 <- S SERIALNO D2760001240103045343000000010000
gpg-agent[8496]: DBG: chan_0x000001c0 <- OK
gpg-agent[8496]: DBG: chan_0x000001c0 -> KEYINFO BBD342CA5B0F978DA17F2AD9F5A1E95FF50C129E
gpg-agent[8496]: DBG: chan_0x000001c0 <- S KEYINFO BBD342CA5B0F978DA17F2AD9F5A1E95FF50C129E T D2760001240103045343000000010000 OPENPGP.2
gpg-agent[8496]: DBG: chan_0x000001c0 <- OK
gpg-agent[8496]: DBG: chan_0x000001c0 -> SETDATA 4F0E7600C2C497A06288DF49B7EA1BC723E04FAC360D6D6C4F4DC1B48DEC13A53556229CDC4562E349C9B5E71365561A941761D1D2C709A16488903AA60925A7B103DEF6B6AE46814370AE815BFBE4A30EC443904C1D63E21ABF5B0B39B8484F3CB4235AEDA04F78F14308AE3DEF52309FB745BC65E3075D19C01C789C8F58931D957D7C26BE7DCEF6B880B362251246FA4E1A2830A13AD94635CC4CE14B0F253481F38C39BA5CC748FDF03F9D936B9C8DE6BF7E49AFF4BE3A84A4E4547FADD4C9F1634416641FF804F3503CC924098F1C4CAA908FD272737312A4D5BE59C644EE1633AA248DC996EF67BA5E087DB6312BD2014BFAFD62FD08C7D45E3AFD431C
gpg-agent[8496]: DBG: chan_0x000001c0 <- OK
gpg-agent[8496]: DBG: chan_0x000001c0 -> PKDECRYPT BBD342CA5B0F978DA17F2AD9F5A1E95FF50C129E
gpg-agent[8496]: DBG: chan_0x000001c0 <- ERR 100663383 Mauvais code personnel <SCD>
gpg-agent[8496]: smartcard decryption failed: Mauvais code personnel
gpg-agent[8496]: command 'PKDECRYPT' failed: Mauvais code personnel <SCD>
gpg-agent[8496]: DBG: chan_0x00000270 -> ERR 100663383 Mauvais code personnel <SCD>

This is the log from SCDaemon
2021-06-17 01:52:38 scdaemon[7412] DBG: apdu_open_reader: HID Global OMNIKEY 3x21 Smart Card Reader 0
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 -> S SERIALNO D2760001240103045343000000010000
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 -> OK
2021-06-17 01:52:38 scdaemon[7412] DBG: enter: apdu_get_status: slot=0 hang=0
2021-06-17 01:52:38 scdaemon[7412] pcsc_get_status_change failed: cancelled (0x80100002)
2021-06-17 01:52:38 scdaemon[7412] DBG: leave: apdu_get_status => sw=0x10010 status=0
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 <- KEYINFO BBD342CA5B0F978DA17F2AD9F5A1E95FF50C129E
2021-06-17 01:52:38 scdaemon[7412] DBG: slot 1, app openpgp: calling with_keygrip(status)
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 -> S KEYINFO BBD342CA5B0F978DA17F2AD9F5A1E95FF50C129E T D2760001240103045343000000010000 OPENPGP.2
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 -> OK
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 <- SETDATA 4F0E7600C2C497A06288DF49B7EA1BC723E04FAC360D6D6C4F4DC1B48DEC13A53556229CDC4562E349C9B5E71365561A941761D1D2C709A16488903AA60925A7B103DEF6B6AE46814370AE815BFBE4A30EC443904C1D63E21ABF5B0B39B8484F3CB4235AEDA04F78F14308AE3DEF52309FB745BC65E3075D19C01C789C8F58931D957D7C26BE7DCEF6B880B362251246FA4E1A2830A13AD94635CC4CE14B0F253481F38C39BA5CC748FDF03F9D936B9C8DE6BF7E49AFF4BE3A84A4E4547FADD4C9F1634416641FF804F3503CC924098F1C4CAA908FD272737312A4D5BE59C644EE1633AA248DC996EF67BA5E087DB6312BD2014BFAFD62FD08C7D45E3AFD431C
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 -> OK
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 <- PKDECRYPT BBD342CA5B0F978DA17F2AD9F5A1E95FF50C129E
2021-06-17 01:52:38 scdaemon[7412] DBG: slot 1, app openpgp: calling with_keygrip(lookup)
2021-06-17 01:52:38 scdaemon[7412] DBG: slot 1: have=openpgp want=openpgp keyref=BBD342CA5B0F978DA17F2AD9F5A1E95FF50C129E
2021-06-17 01:52:38 scdaemon[7412] DBG: slot 1 app openpgp: calling decipher(BBD342CA5B0F978DA17F2AD9F5A1E95FF50C129E)
2021-06-17 01:52:38 scdaemon[7412] DBG: send apdu: c=00 i=2A p1=80 p2=86 lc=257 le=256 em=-254
2021-06-17 01:52:38 scdaemon[7412] DBG: PCSC_data: 102a8086fe004f0e7600c2c497a06288df49b7ea1bc723e04fac360d6d6c4f4d \
2021-06-17 01:52:38 scdaemon[7412] DBG: c1b48dec13a53556229cdc4562e349c9b5e71365561a941761d1d2c709a16488 \
2021-06-17 01:52:38 scdaemon[7412] DBG: 903aa60925a7b103def6b6ae46814370ae815bfbe4a30ec443904c1d63e21abf \
2021-06-17 01:52:38 scdaemon[7412] DBG: 5b0b39b8484f3cb4235aeda04f78f14308ae3def52309fb745bc65e3075d19c0 \
2021-06-17 01:52:38 scdaemon[7412] DBG: 1c789c8f58931d957d7c26be7dcef6b880b362251246fa4e1a2830a13ad94635 \
2021-06-17 01:52:38 scdaemon[7412] DBG: cc4ce14b0f253481f38c39ba5cc748fdf03f9d936b9c8de6bf7e49aff4be3a84 \
2021-06-17 01:52:38 scdaemon[7412] DBG: a4e4547fadd4c9f1634416641ff804f3503cc924098f1c4caa908fd272737312 \
2021-06-17 01:52:38 scdaemon[7412] DBG: a4d5be59c644ee1633aa248dc996ef67ba5e087db6312bd2014bfafd62fd08c7 \
2021-06-17 01:52:38 scdaemon[7412] DBG: d45e3a
2021-06-17 01:52:38 scdaemon[7412] DBG: response: sw=6982 datalen=0
2021-06-17 01:52:38 scdaemon[7412] operation decipher result: Mauvais code personnel
2021-06-17 01:52:38 scdaemon[7412] app_decipher failed: Mauvais code personnel
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 -> ERR 100663383 Mauvais code personnel <SCD>
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 <- BYE
2021-06-17 01:52:38 scdaemon[7412] DBG: chan_0x000002e8 -> OK closing connection
2021-06-17 01:52:38 scdaemon[7412] gestionnaire pour le descripteur 744 terminé

In this case the agent and daemon assume, the pin is already validated but he calls the bad applet. All security status is reset on GIDS. GIDS on 0x2a instruction say security not satisfied. It’s OK… because Openpgp has not validated if the right applet is selected. When PCSC-SHARED mode the smartcard client never assume the right applet was by default selected. In addition, need to restore the security environment. At this time the only possibility to make the SCDeamon on the right track is to kill when he restarts SCDaemon reselect the OPenPGP applet and reset the security environment to UNauth and prompt users for pin.

In the second case when the applet is reselected correctly, create a signature restore the security environment in line with the cache. Because the pin need to validate is the same for Crypt and Sign. When the signature was made, the card security says the PW01 is already authenticated. This is valid for decrypt and sign. Options simulating the real need of pin for each signature but in reality is little a fake option. The client force to revalidate pin but the card is already authenticated. If I connect readers with other apps, I can send a security perform signature and the card was success to create the signature.

Normally, for mitigating this factor the app cache pin and resend pin to the card before each crypto-operation.
PIV and GIDS use Security management for key selection and key was assigned to pin by type of security operation. The system normally need to send pin before any 0x2A instruction.

gniibe lowered the priority of this task from High to Normal.Jun 17 2021, 9:44 AM

I don't think we should do automatic error recovery from 6982 to retry decryption/signing, inside CMD_PSO (0x2A) operation.

All that we can do here is detecting the failure because of other AID selection by PCSC_SHARED, and do our best not to keep scdaemon inconsistent state.

If something more user friendly is required, it could be possible for higher layer (SCDaemon's command handling) to check verification status beforehand, and do error recovery there.

Let me add the tag "yubikey".
I think that it could be solved in different level, if I were the device manufacturer; And it would give users the best solution.

(1) For "Chrome select default applet send 00 a4 04 00 00 ", from view point of users, it's just a bug of use of FIDO device. Just remove this handling, then OpenPGP card application works fine.

(2) A device could have another CCID interface, each CCID interface to each card, to avoid interference at CCID layer.

(3) Or, a device could have another card within a single CCID device. This can avoid interference for multiple applications in a single card.

Being said, that I am going to implement a workaround of detecting interference and recovery in scdaemon. But please note that this is workaround for specific (questionable) implementation of a device. It is not recommended for other device implementations of token to follow the design of multiple applications in a single card, in that way.

Here is the reference to GID specification:
https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn642100(v=vs.85)?redirectedfrom=MSDN

PIV/GID/OpenPGP card all support 0x4F data object as AID.
So, we can use this data object if application selected is the right one.

For the problem of external application switch, please test this:

diff --git a/scd/app-common.h b/scd/app-common.h
index dffe1200d..d6e6f4c0a 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -194,6 +194,8 @@ struct app_ctx_s {
                       void *pincb_arg);
     gpg_error_t (*with_keygrip) (app_t app, ctrl_t ctrl, int action,
                                  const char *keygrip_str, int capability);
+    gpg_error_t (*check_aid) (app_t app, ctrl_t ctrl,
+                              const unsigned char *aid, size_t aidlen);
   } fnc;
 };
 
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index feea1905b..1fa865f69 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -6134,6 +6134,18 @@ do_reselect (app_t app, ctrl_t ctrl)
 }
 
 
+/* Check if AID is the correct one.  */
+static gpg_error_t
+do_check_aid (app_t app, ctrl_t ctrl, const unsigned char *aid, size_t aidlen)
+{
+  if (aidlen >= sizeof openpgp_aid
+      && memcmp (aid, openpgp_aid, sizeof openpgp_aid) == 0)
+    return 0;
+
+  return gpg_error (GPG_ERR_WRONG_CARD);
+}
+
+
 /* Select the OpenPGP application on the card in SLOT.  This function
    must be used before any other OpenPGP application functions. */
 gpg_error_t
@@ -6322,6 +6334,7 @@ app_select_openpgp (app_t app)
       app->fnc.change_pin = do_change_pin;
       app->fnc.check_pin = do_check_pin;
       app->fnc.with_keygrip = do_with_keygrip;
+      app->fnc.check_aid = do_check_aid;
    }
 
 leave:
diff --git a/scd/app-piv.c b/scd/app-piv.c
index 143cc047a..241c26b8b 100644
--- a/scd/app-piv.c
+++ b/scd/app-piv.c
@@ -3609,6 +3609,18 @@ do_reselect (app_t app, ctrl_t ctrl)
 }
 
 
+/* Check if AID is the correct one.  */
+static gpg_error_t
+do_check_aid (app_t app, ctrl_t ctrl, const unsigned char *aid, size_t aidlen)
+{
+  if (aidlen >= sizeof piv_aid
+      && memcmp (aid, piv_aid, sizeof piv_aid) == 0)
+    return 0;
+
+  return gpg_error (GPG_ERR_WRONG_CARD);
+}
+
+
 /* Select the PIV application on the card in SLOT.  This function must
  * be used before any other PIV application functions. */
 gpg_error_t
@@ -3713,7 +3725,7 @@ app_select_piv (app_t app)
   app->fnc.change_pin = do_change_chv;
   app->fnc.check_pin = do_check_chv;
   app->fnc.with_keygrip = do_with_keygrip;
-
+  app->fnc.check_aid = do_check_aid;
 
 leave:
   xfree (apt);
diff --git a/scd/app.c b/scd/app.c
index 113669cb7..4407efc4c 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -1435,6 +1435,38 @@ run_reselect (ctrl_t ctrl, card_t c, app_t a, app_t a_prev)
 }
 
 
+/*
+ * Check external interference before each use of the application on
+ * card.  Returns -1 when detecting some external interference.
+ * Returns 0 if not.
+ *
+ * Note: This can't be perfect.  At most, it may be possibly useful
+ * kludge, in some limited situations.
+ */
+static int
+check_external_interference (app_t app, ctrl_t ctrl)
+{
+  if (app->fnc.check_aid)
+    {
+      unsigned char *aid;
+      size_t aidlen;
+      gpg_error_t err;
+      int slot = app_get_slot (app);
+
+      err = iso7816_get_data (slot, 0, 0x004F, &aid, &aidlen);
+      if (err)
+        return -1;
+
+      err = app->fnc.check_aid (app, ctrl, aid, aidlen);
+      xfree (aid);
+      if (err)
+        return -1;
+    }
+
+  return 0;
+}
+
+
 /* Check that the card has been initialized and whether we need to
  * switch to another application on the same card.  Switching means
  * that the new active app will be moved to the head of the list at
@@ -1490,7 +1522,9 @@ maybe_switch_app (ctrl_t ctrl, card_t card, const char *keyref)
             if (app->apptype == apptype)
               break;
           if (!app_prev && ctrl->current_apptype == card->app->apptype)
-            return 0;  /* Already the first app - no need to switch.  */
+            if (card->cardtype != CARDTYPE_YUBIKEY
+                || check_external_interference (app, ctrl) == 0)
+              return 0;  /* Already the first app - no need to switch.  */
         }
       else if (strlen (keyref) == 40)
         {
@@ -1503,7 +1537,9 @@ maybe_switch_app (ctrl_t ctrl, card_t card, const char *keyref)
                                            KEYGRIP_ACTION_LOOKUP, keyref, 0))
               break;
           if (!app_prev && ctrl->current_apptype == card->app->apptype)
-            return 0;   /* Already the first app - no need to switch.  */
+            if (card->cardtype != CARDTYPE_YUBIKEY
+                || check_external_interference (app, ctrl) == 0)
+              return 0;   /* Already the first app - no need to switch.  */
         }
     }

Ok, I test this, this seem can be corrected 90% of all possible interference with another application on multi-applet smartcard in shared readers context. I left you the feel back when have tested… thank for the prompt response.

Ok i have seen a problem with a double check here

/* Reselect the application. This is used by cards which support

  • on-the-fly switching between applications. */

static gpg_error_t
do_reselect (app_t app, ctrl_t ctrl)
{

  gpg_error_t err;

  (void)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)  <--------------------
	  //  return gpg_error (GPG_ERR_NOT_SUPPORTED);           <-------------------- I remove this for the test because it not perform the switch with this check

  /* Note that the card can't cope with P2=0xCO, thus we need to pass
   * a special flag value. */
  err = iso7816_select_application (app_get_slot (app),
                                    openpgp_aid, sizeof openpgp_aid, 0x0001);
  if (!err)
    {
      app->did_chv1 = 0;
      app->did_chv2 = 0;
      app->did_chv3 = 0;
    }
  return err;

}

i'am not able to test... i can't build for win32. i have some trouble with my mingw32 installation and the miss match with library for build a functional version of gnupg for win32.
seem missing dll after make install folder. do you have instruction to setup dev environment for build win32 binary ? I use a ubuntu with minwg32. ntbtls seem missing ksba but libksba is already install verion 1.6.0 other project detect correctly ksba. it's seem is a little bit complicated juste for building scd project. a make it working correctly on windows environements.

If your token/card is not Yubikey and when it is possible to improve your token/card implementation, I would suggest not follow what Yubikey does for multiple applications; No multiple applications, but each feature with independent access (card+CCID, another card+different CCID, FIDO+HID, ...).

And please make sure not to interfere. It's not wise for an FIDO applet to do CCID access, just don't do that.

It's not a device is a card. NXP P71 security chips on the card in the 250Kb Rom with GlobalPlateform 2.1.1 It is not possible for a card to change CCID by applet. Card depends of reader CCID. When the card is on NFC readers, the FIDO applet is accessible not when it is on contact readers. But, when I am in NFC FIDO share the CCID. For the user point of view having multiple card for each applet is a bad thing to devices for one user. User search presently for multipurpose devices. DOOR, Login, Email-crypt, ledger. Actually for app is not recommended to use a reader in exclusive mode. By designs the card is stateless and for memory management deselect applet free mem from other applet. Presently in the best case the card has 144-255 KB of eeprom and 2k or ram.

Because the media is a card. The CCID is maintained by the reader. I’m controlled only the applet and applet selection. This is because the GIDS and PID use the APDU security management. This APDU is used to reset the context with the app cache before use perform security. Pin was not cached by applet but be the app. If the app not detect the deselection app can expect the pin was authenticated. But, if detect the deselection the app need to perform sanitation on the security context. This is the same for key slot selection. Normally key and crypto algorithm selection is selected by the manage security APDU.

This was my first recommendation is to take corrective action when the error arrives to minimize the number of APDU sends to the card. However, in shared context all apps can use the card. In addition, by design the minidriver was a multiple manager. Each app load an instance of minidriver DLL. In the same applet, all share the security context.
With a little applet than Fido or OpenPGP is wasting the card memory to use the card only for that applet. Fido uses two key slots for U2F and FIDO2 can by use with minimal storage by registration. OpenPGP use for three slots only limited data storage. GIDS can be used by 20 key slots. For Multi network Admin more than six slots is used for login. I chose to implement OPenpgp for the ability to offer for my user the 2-email security norm. With the login. GIDS implementation is very useful for windows integration.

An option with my implementation of Openpgp is to select GIDS Key shared slots for crypto-only. This can permit decrypting smime email on outlook with openpgp or without pgp.

All card implementation of JCOP cards can by containing multi applets. By this the apps have the ability to maintain the status and the ability to reselect the applet when he detects bad applet selection.

Yubikey have the same problem because the usbdevice is in fact a smart card reader. In the same was having Gemalto USB Smartcard readers for cut-Sim card. By the way Yubikey control the USB implementation and he can set CCID by applet. But I am only card programmer is not possible for a card without devices to control de CCID. When the card is on NFC fields, all my applet share the CCID of the NFC reader is the same fact for the contact reader but I have deactivated FIDO if my card is in the contact reader.

Thank you for your explanation.

pcsc_shared is a corner case, at most. It may help some users in some situations, but it's hard to support all cases perfectly, because it has fundamental race conditions between multiple uses.

Anyway, I updated the patch, which is now D534: scdaemon patch to support some situation with PCSC_SHARED (not all). This patch assumes that it is identified as Yubikey. It needs more update(s) to support card/token other than Yubikey.

In fact, the trigger is not yubikey but the pcsc-shared flag... If the pcsc-shared flag is enabled, you do check for interference because you are in shared condition. It is not really a race condition because you can put the driver in transaction mode. It’s more a turn-by-turn games but you can lose the card context status between turn.
If you lock the patch only for yubikey I’m not able to test with my device. You can add my manufacturer ID in the test please.

The SCardBeginTransaction function starts a transaction.
The function waits for the completion of all other transactions before it begins. After the transaction starts, all other applications are blocked from accessing the smart card while the transaction is in progress.
The SCardEndTransaction function completes a previously declared transaction, allowing other applications to resume interactions with the card.

This API protect you between turn. This assumes you a finish all APDU sequence before releasing the card to other players. Presently you have set to my cards the ID 0x5343 For testing I need to pass in the interference check with my card too.
I have some problem building win32… if you can build the test for me, it’s very appressed and I do all round test for every case I know with multi-applet card. Combo EFS – GUNPG, Acrobat – GNUPG, Ledger app – GNUPG. I can do for you a complete rapport for each test and the result if GNUPG can retrieve all function and the interaction with the user.
Objective User not get error… and SCDaemon maintain the ability to perform GNUPG operation without any problem.

Yannick LaRue
SSE Carte à Puce Inc.

There are multiple issues here.

(1) I agree that (in future) SCardBeginTransaction/SCardEndTransaction is better to guarantee no race for PCSC_SHARED. Please note that current codebase is not using SCardBeginTransaction/SCardEndTransaction.

(2) PCSC_SHARED is (for now) a kind of kludge to help Yubikey users.
For other use cases, I think that adding specific support is needed.

(3) In this particular ticket, I try to improve PCSC_SHARED situation in a limited way.

I think that introducing SCardBeginTransaction/SCardEndTransaction should be done by another ticket. Adding other use cases for other card/token can be continued in this ticket, after (3).

You need to protect only 2 critical set of ADPU sequence Sign and Decrypt. All other can be done not safely and have a minor impact. Get generation and cards unlock can be profitable with the transaction mode... but is very rare user makes another use of the card in same time he start that’s command. The check external interference can protect from a bad start. I have started this ticket because my card suffer in exclusive mode render the use of openpgp not really usable. When my card is an pcsc-shared mode, all it's OK but the daemon not able to restore after external interference. The correction proposed is OK but I have made recommendations because this can cause a bad applet switch... if the state does not restore before trying to switch applet all it's OK. I am not actually able to set directly differential code but I have described in the patch the change I have made and this make my card very happy. Not problems and the pin was queried if another application makes interference.

With a card with two applet PIV and OpenPGP… I play with 2 key for email decryption. If I have received a PGP email, I do it with the OpemPGP applet and if I am receiving a s/mime email a play with the PIV key. OpenPGP Daemon can handle this 2 applet. This situation is not a yubikey related is related by any multi-applet JCOP card or any Multi applet GlobalPlateform card… This can be made in case a large number of tokens. When I use PIV for windows login and other use Adobe decryption, etc. If I want to use Openpgp soft and ScDaemon it imperative the ScDaemon is in pcsc-shared mode. This makes OpenPgp vulnerable to the other application interference. In checking in the first task in the maybe_switch_app this restore the actual selected app and the rest can be performed as intended. In the worst case, this correction cause no damage if the applet not respond correctly… This can cause only to resent reselect before every operation and this is OK for cards… the real lost is 30 ms before every operation in this worst case. But this assure the operation perform as intended. This is the goal for the user not seen an error.

I continue my test with different applet implementation. PKCS15 – PIV – OpenPGP – Gemalto Applet – FIDO - GIDS.

FWIW: We have always refused to support shared mode because we anticipated such problems. However, we have a customer using their own cards along with card maintenance software of them. For their purposes PCSC_SHARED works just fine makes and this is why I decided to add --pcsc-shared along with a warning that it is in general not a good idea.

@gniibe and me recently talked about the situation and we agreed that we will add the transaction thing, because it is the Right Thing to do for PC/SC and on Windows, where it seems to work as expected. However, we won't backport this to 2.2 and we need to take care not to break things. In addition the interference check will also be added because, as you noted, it seems to handle most cases

werner claimed this task.