Over the last few years, card vendors are offering cards with multiple applets on the same card. Yubico and MyEID in particular and there will by others. But users have problems using the applets concurrently and especially from different applications. (Some examples: OpenPGP, CAC and PIV)
We have talked about how to support these concurrently in OpenSC, but any concurrent use comes down to: Does the card support this and can the card keep the security state active and separate.
ISO 7816 -4 "5.4.2 Logical channels" states:
"This clause specifies a mechanism whereby in the interindustry class, C-RPs can refer to logical channels.
Each logical channel has its own security status (see 9.3) and validity area (see 7.2)."
4 channels have bee defined for years. 19 channels are defined in later versions of ISO 7816-4:2013.
So one way to support multiple concurrent applets is to use Logical channels. But it is not clear if any of these cards can support this internally. I have seen some Oberthur cards where the ATR Historical bytes say the card supports logical channels. But the Yubico and MyEID both put their company name in the historical bytes and there is no indication.
I am asking Yubico and MyEID if thety support logical channels, or would they be willing to add support for logical channels and work with OpenSC to support this.
I am also asking if anyone knows of any other cards with multiple applets, that do support chaining.
Open Platform for example?
Issues:
Card must support logical channels. - (Vendor issue) We need at least one type of card for testing.
PCSC locks on the card and not on a logical channel, so middleware can not hold locks for very long.
Allocation of channels. ISO 7816 MANAGE CHANNEL command (70) can be used, and for any of the cards OpenSC could always use a channel other then zero, as other middleware may be using only channel zero.
A card-reset resets the whole card, so must be avoided. MANAGE CHANNEL. to reset the channel might be a replacement for card reset, and could be used for a "logout".
I bring this up for discussion because it needs vendor input as will as OpenSC input.
Unfortunately, there doesn't seem to be much interest in solving concurrent access to multiple applications on a card. And quite frankly, I don't think it this is currently needed given the typical smart card use today.
Please re-open if there is new input!
@frankmorgner In https://github.com/OpenSC/OpenSC/pull/1232#issuecomment-356605500
You may not consider this a priority but I do. We do have many users complaining about trying to use two applications at the same time, usually PIV and OpenPGP. Aventra has a MyEID card with PIV applet, and there will be others.
So I am reopening this issue.
Just to be clear, her is what I said:
Its not easy to test but it is one of things we should support. Basically as part of any begin transaction on a card with multiple AIDs the first command should be to reselect the AID.
I disagree, this problem is not a priority for me. If you're using only OpenSC the worst that can happen is that the applet gets selected twice. The same holds for scdaemon if it uses the card non-exclusively (in exclusive use the card would not be available for OpenSC in the first place). If you're using a different Middlware or program, then, indeed, it can get complicated. Do you some other middleware that people are using together with OpenSC? I don't; and until today, we didn't get any issue reports about such a situation.
We may eventually do something against resetting the card, but deselecting cannot be easily detected nor can it be easily prevented. Hence, we would have a gigantic workload for a problem that's virtually non-existent (and I don't even mention the possibility of introducing new bugs with the new complexity).
@dengert, your problem description is clear. And yes, it may lead to some problems. However, I believe
Do you know a use case or some user who has actually experienced some problem related to this issue?
Well you asked who has complained. See the mail thread: "[Opensc-devel] OpenSC and Yubikey 4 (OpenPGP)"
The question in this thread was on how to use the OpenPGP applet instead of the PIV applet on the Yubikey Neo. The solution was to edit opensc.conf accordingly, problem solved. Note that:
If I understand correctly, then you want to expose both applications of the Neo at the same time. Sure, this may be useful for a minority of users. Most users will use the PGP applet together with Gnupg, and the PIV applet with OpenSC.
Anyway, if you want to implement this, just go ahead! Since OpenSC would have full control about which applet is selected, concurrency is easily avoided. I'll happily review a pull request! But since you stated that "Some opensc/openpgp developer" (other than you) should implement this, I just do not see it happening.
However, I believe
- that users only use a single application from such tokens,
They do, because there is no simple way to use more of them. For example from OpenSC, the applet detection ends after the first one is detected and from PKCS#11, there is no way how to pass driver selection. But could we go down the road with detection and populate another "virtual" slot if we find other applet?
- don't use multiple middleware implementations at the same time and in consequence
The GnuPG scdaemon is one example of different middleware directly touching PCSC layer. I really wanted to use both of them on my yubikey for SSH authentication (pushing to github) and commit signing using GnuPG, but it does not work and therefore I am stuck with the PIV only now.
- don't experience concorrency issues related to the problem description.
If users should use smart card for simplification of their workflow, it should work with multiple applications. But it quite much does not work out of the box. Users need to set up disconnect_action = leave; in opensc.conf so one closing session would not kill all the others. Would it make sense to change here the default value? Are there any possible drawbacks? So far I did not discover any problem with this setup with various cards I have around.
Quite inspiring comments came from NdK in parallel thread. Yes, we are experts who know how things work, how to fix them for us. But if we want more users to use smart cards, we need to make it simple and working in common cases and with Yubikey I believe this is very common use case.
I am currently looking into the problems and what can be done, but I can not guarantee that I will be able to work on all of the parts, either because of the lack of the time, or lack of the internal code knowledge.
Here are some major items, I see, in OpenSC and PCSC that are hindering the support of concurrent use of applications on a single card:
(1) OpenSC was originally written when one card had one application and it was a PKCS#15. Since then cards can emulate PKCS#15, and a card application may define only a subset of valid commands . The PIV and OpenPGP for example do emulation.
The sc_card_t contains information about both the card and the application. To support multiple applications I believe the sc_card_t needs to be split into a card only part (sc_cardc_t) and a chain of multiple application parts (sc_carda_t) ( Names to be chosen later.) sc_cardc_t has things like ATR, and lock count. To support older cards with single applications, maybe a sc_card_t contains a sc_cardc_t and a sc_carda_t with a pointer to the sc_cardc_t that represents the single sc_card_c_t for the card and a link list of sc_card_t that contain the application's sc_carda_t.
And alternate approach with less code change but not as readable is to have just a link list of sc_card_t structures, with an addition of a pointer to the head sc_card_t. The head or only `sc-card_t would point to itself. Any function that deals with the card would then point to the head structure to do thing like locking.
This is a big refactoring task. Once that is done the work to support multiple concurrent applications can begin.
(2) The selection/detection of cards that could support multiple applications should be changed. It appears that the only common element in in all of this (ISO7816-4 8.1 Card Identification) is the use of the SELECT AID. Not all cards may support the EF.DIR, or add the compact header in the ATR for 31 to contain the Card service data. This may be a challenge to determine if a card does or does not support
an application without actually doing a SELECT AID which might cause problems in non OpenSC middleware that is also accessing the card. It appears pkcs15.c does some of this but only after the card driver is selected. This needs to be done earlier, as some of what we call card drivers are really non-pkcs15 application drivers, tuned to support only the subset of card commands that the application says it supports.
With the above in place opensc-tool, pkcs15-tool could use the select driver or select application much like they do now. PKCS#11 would create slots for each reader, where each reader would have one sc_cardc_t and multiple sc_carda_t structures. So slots are assigned as needed to each sc_carda_t
Locking is at the sc_cardc_t level, but card removal, power lot or reset need to be passed at the sc_carda_t level.
(3) A somewhat separate issue is the use of disconnect = leave in a multiuser system. A multiuser system really requires PCSC to support Section 2.4 of pcsc1_v2.01.02 which talks about 2.4.1 System, 2.4.2 User, 2.4.3 Process and 2.4.4 Terminal. These outline how to restrict access to a card at the PCSC level to only the processes of a user that is allowed to access the reader and/or card. (The use of Secure Messaging also supports security to restrict the access to the processes that know the PIN. But not all cards have SM.)
@LudovicRousseau Is this supported? What would it take to support it on Linux? Linux already has support to allow only the user at the compute to access the keyboard, mouse, DVD, camera and microphone. What would it take add smart card reader?
@frankmorgner In regard to:
""Some opensc/openpgp developer" (other than you) should implement this, I just do not see it happening."
What I was expecting is any one of the users of the OpenPGP application would step up and get involved. I was not expecting you to do it. It takes a lot of testing. Even if one user steps up and says they are willing to test, I can take a stab it adding the SELECT AID commands where I think they are needed. I see much of the discussions on [OpenSC-devel] so they may not be seeing the github [OpenSC/OpenSC] discussions. I will send an email to [OpenSC-devel] to see if anyone is interested.
@mouse07410 are you interested in this?
For example, in Fedora, we have Polkit policy, which avoids other non-local/non-authorized users/processes talking to the smart cards. Not sure if it works the same way elsewhere, or if the Tokend or other facilitators ensure something similar.
https://access.redhat.com/blogs/766093/posts/1976313
Also as I have the Yuibikey, I am able to review and test changes/results.
Polkit looks like the type of control I was talking about. And it looks like it is available on Ubuntu. So that looks like (3) is already done and available on multiple platforms. Should OpenSC or PCSC have a wiki page on this? (They may already be there I did not look closely. )
The mod that I was going to try and add to card-openpgp.c was to do a SELECT AID as the first command after a sCardBeginTransaction to make sure the OpenPGP AID is selected. That does not address (1) or (2) but will be needed and does address if some other process causing a diffrent AID to be selected when not expected.
One way to simulate interference is to issue this command in a different window
while one of the applications is waiting for user input such as a PIN.
On a ubikey4 with uninitialized PIV and OpenPGP card applications the default driver
that can issue a SELECT AID command directly is used first for PIV then for OpenPGP
doug@XUbuntu-16:/opt/ossl-1.1/bin$ ./opensc-tool -c default -s "00 A4 04 00 09 A0 00 00 03 08 00 00 10 00"
Using reader with a card: Yubico Yubikey 4 OTP+U2F+CCID 00 00
Sending: 00 A4 04 00 09 A0 00 00 03 08 00 00 10 00
Received (SW1=0x90, SW2=0x00):
61 11 4F 06 00 00 10 00 01 00 79 07 4F 05 A0 00 a.O.......y.O...
00 03 08 ...
doug@XUbuntu-16:/opt/ossl-1.1/bin$ ./opensc-tool -c default -s "00 A4 04 00 06 D2 76 00 01 24 01 00"
Using reader with a card: Yubico Yubikey 4 OTP+U2F+CCID 00 00
Sending: 00 A4 04 00 06 D2 76 00 01 24 01 00
Received (SW1=0x90, SW2=0x00)
doug@XUbuntu-16:/opt/ossl-1.1/bin$
Note: that the PIV returned the template, the OpenPGP did not as expected.
disconnect = leave by default if we logout in PKCS#11/Tokend on disconnection (or unpower if the card doesn't support logout). Minidriver does this already; I'm not sure with the other two.That said, I'd like to take a step back and, again, look at what people actually want to do. Nobody wants to use this and that applet, nobody wants to store keys here and certificates there. People, want to sign commits (@Jakuje) and they want to login with a card via SSH (NdK) and they want to encrypt mails and they want to login to some server with a card. Of course, they ideally only want to use a single card, no configuration and always with the same user experience.
Imagine that all this technical work we already discussed has been implemented in OpenSC by some still unknown, but surely very talented and yet bored enough (or paid good) guy that has time to pull this trick, are we finally able to use ssh, gpg and firefox without further configuration of OpenSC? With all this introduction my answer, of course, is: No! gpg's scdaemon will still force an exclusive connection so OpenSC doesn't come into play and all this amazing work just goes unnoticed.
Actually, I think that the mere existence of all these applets on those tokens stems from the believe that the application dictates the technology to use. I think, a token should just be a key container and the key should be usable everywhere! Coming back to the good IT department, I've talked about in response to NdK's mail, we should look at the whole picture and check what we could configure today! Has anyone tried to use OpenSC's PKCS#11 module for gpg (see gnupg-pkcs11); has anyone tried to use firefox with scdaemon, (see scd-pkcs11? The former would allow using the Yubikey's PIV applet for everything, the latter would use the OpenPGP applet for everything.
Of course, they ideally only want to use a single card, no configuration and always with the same user experience.
Of course. And it sort of works now - but it is missing SELECT AID so the reliability suffers, AFAICT.
gpg'sscdaemonwill still force an exclusive connection so OpenSC doesn't come into play and all this amazing work just goes unnoticed.
GnuPG developers are boneheaded enough to persist in their refusal to add an scdaemon configuration parameter that would allow shared access. GPGTools developers were smart enough to understand the need, and to add that capability. So at least on Mac there's scdaemon that allows shared access - and that's where "all this amazing work" would be noticed rather quickly.
And perhaps somebody would fork the generic GnuPG scdaemon and add on-demand shared access.
That said, I'd like to take a step back and, again, look at what people actually want to do...
What people? I want to be able to:
Some people want only some items from the above, some may want none.
...The former would allow using the Yubikey's PIV applet for everything, the latter would use the OpenPGP applet for everything...
Point taken. But I may want to separate my keys that are used for different purposes, rather than mush them into one. My signing keys are different from my encrypting keys, my PIV keys aren't the same as my PGP keys... Sure I could derive one from another, but I prefer a different solution.
@dengert wrote:
" (3) A somewhat separate issue is the use of disconnect = leave in a multiuser system. A multiuser system really requires PCSC to support Section 2.4 of pcsc1_v2.01.02 which talks about 2.4.1 System, 2.4.2 User, 2.4.3 Process and 2.4.4 Terminal. These outline how to restrict access to a card at the PCSC level to only the processes of a user that is allowed to access the reader and/or card. "
The PC/SC workgroup documentation are not specification, just guides for implementers.
The parameter your wrote about is dwScope for SCardEstablishContext().
Windows only supports 2 values (SCARD_SCOPE_USER and SCARD_SCOPE_SYSTEM) from the 4 described in PCSC pcsc1_v2.01.01.pdf. See https://msdn.microsoft.com/fr-fr/library/windows/desktop/aa379479(v=vs.85).aspx
pcsc-lite only supports 1 value: SCARD_SCOPE_SYSTEM http://pcsclite.alioth.debian.org/api/group__API.html#gaa1b8970169fd4883a6dc4a8f43f19b67
From the MSDN documentation I am not sure to understand what SCARD_SCOPE_USER is used for. My best guess is that it is related to SCardListCards() to list cards (https://msdn.microsoft.com/fr-fr/library/windows/desktop/aa379789(v=vs.85).aspx). The function SCardListCards() is not supported in pcsc-lite. So dwScope has no use-case for pcsc-lite.
SCARD_SCOPE_USER does not prevent the use of the card or reader to a specific user. SCARD_SCOPE_USER is used in SCardEstablishContext() so _before_ any mention of a specific card or reader.
I don't think that PC/SC can help restrict the access to a specific user. PolKit is a much better solution for that.
@dengert and @LudovicRousseau, thank you for the comments about the disconnect=leave option. Even if we would not be able to change it globally everywhere, I believe we can assume in Fedora out of the box that this access control is in place and we are safe to change that as a first step to working concurrent access to smart cards.
Has anyone tried to use OpenSC's PKCS#11 module for gpg (see gnupg-pkcs11); has anyone tried to use firefox with scdaemon, (see scd-pkcs11? The former would allow using the Yubikey's PIV applet for everything, the latter would use the OpenPGP applet for everything.
I did not try that yet and I share the same concerns as @mouse07410 -- the keys should be separated for separate use cases. We can't achieve it for all the above use cases (most will go through PIV), but separating GPG is certainly good approach, since there is a way.
And once we would have the possibility to work with OpenPGP card through OpenSC, we can use different drop-in replacement scdaemon that talks to the card through PKCS#11 and OpenSC:
http://gnupg-pkcs11.sourceforge.net/index.html
I did not personally try this either, but I certainly plan to try it since master can talk to the OpenPGP applet on Yubikey finally. From the description it sounds like the right thing to do.
To the third proposed option from @frankmorgner, I am not sure how much work would it safe and how much confusion would it introduce. At this moment there are several places where token/driver-specific information show up. The applets also have different PINs, so it would show up all the keys in virtual slots for each pin? That would be very confusing. On the other hand, when we would be able to add a logic that would allow PINs to cover specific keys/objects, we would basically back to the same place where we started, but with "virtual slots" instead of "slots", isn't it? But I can not estimate how complicated change would it be or if it would still go without the changes proposed by @dengert above.
@LudovicRousseau, @Jakuje Thanks for the input on PCSC and PolKit. PolKit appears to address the multiuser system issues with disconnect = leave on systems that have PolKit or something similar.
Looks like openSUSE, Debian and Ubuntu have PolicyKit the predecessor of PolKit. From Google it looks like people are trying to use PolicyKit on MaxOS. Does MacOS have something else? @mouse07410
In any case the issue is being addressed outside of OpenSC. TODO Should OpenSC have a configure option to set the default for disconnect =
@Jakuje and @mouse07410 see the comment above this patch in: https://github.com/OpenSC/OpenSC/pull/1232#issuecomment-357297831
This forces a SELECT AID in case some other middleware has switch the OPenPGP AID.
In a comment to #1239 I've summerized why I don't think unconditional re-selection applet is a good way to solve this issue.
Here are two different ideas:
Catch Error codes that are unknown for the specific card, which indicates that the applet has been de-selected. E.g. we may catch 6D00, which is typically thrown by JCOP, not by the OpenPGP applet or PIV applet. Each card driver may implement a different check, depending on how specific the documentation is for the specific command. For example, in sc-hsm I'm using the VERIFY command to check if our connection is still alive, which also works without SM.
Detect a reset of the command by propagating SCARD_W_RESET_CARD: In the Minidriver we're simply re-initializing if we're detecting a change of the SCARD handles. Similarly, we could react if reader-pcsc.c tells us that the card has been reset... Therefor we could add a flag to sc_card_t or sc_context_t, for example, to propagate this event from the lowest (PC/SC) to the highest software layer (PKCS#11).
In https://github.com/OpenSC/OpenSC/pull/1239#issuecomment-357735636 I too have summerized why I think reselection is needed, and ways to use sc_lock and sc_lock to avoid excessive use or re-selection. I also outlined how to use opensc-tool -c default with multiple -s parameters to test what a card can and can not do.
(1.) "Catching error codes..." such as 6D00. The driver does some of that, for example piv_pin_cmd if a verify fails it will try and recover by doing select AID.
3320 /* if access to applet is know to be reset by other driver we select_aid and try again */
3321 if ( priv->card_issues & CI_OTHER_AID_LOSE_STATE && priv->pin_cmd_verify_sw1 == 0x6DU) {
3322 sc_log(card->ctx, "AID may be lost doing piv_find_aid and retry pin_cmd");
3323 piv_find_aid(card, priv->aid_file); /* return not tested */
3324
3325 priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */
3326 r = iso_drv->ops->pin_cmd(card, data, tries_left);
3327 priv->pin_cmd_verify = 0;
3328 }
The command most likely to fail is a verify, because a transaction can not be held for the length of time it takes a user to type the PIN.
This same type logic could be added to card-openpgp.c
(2.) "Detect a reset of the command by..." That is exactly what the _card_reader_lock_obtained code does. It passes in was_reset so the card driver that supports _card_reader_lock_obtained can do something with it.
Look at piv_card_reader_lock_obtained`
3391 SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
3392 if (was_reset > 0) {
3393 if (priv)
3394 priv->logged_in = SC_PIN_STATE_UNKNOWN;
3395
3396 r = piv_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen);
3397 }
But the card-openpgp.c does not have any code to maintain the logged_in state like the PIV does. If it did the pgp_card_reader_lock_obtained would not have to do so many select_aid commands.
The pgp_card_reader_lock_obtained in the PR is there for testing to see if @mouse07410 and @Jakuje get improved functionality. It can be changed as needed.
Yes, detecting a reset should work with what we currently have (2), I think you're right. That leaves detecting deselection without resets (1) on the table.
Most helpful comment
@frankmorgner In https://github.com/OpenSC/OpenSC/pull/1232#issuecomment-356605500
You may not consider this a priority but I do. We do have many users complaining about trying to use two applications at the same time, usually PIV and OpenPGP. Aventra has a MyEID card with PIV applet, and there will be others.
So I am reopening this issue.