Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental: PKCS#11 Support for Multiple Applications on One Card #1263

Closed
dengert opened this issue Feb 7, 2018 · 26 comments
Closed

Experimental: PKCS#11 Support for Multiple Applications on One Card #1263

dengert opened this issue Feb 7, 2018 · 26 comments

Comments

@dengert
Copy link
Member

dengert commented Feb 7, 2018

The Yubikey is the first card where two different applications are supported
by different card-.c and pkcs15-.c drivers. OpenSC in the past has assumed
that there would be only one card driver per card. pkcs11/slot.c is modified
to allow for each slot to have a different card driver.

Commit dengert@dff1973 is built upon PRs #1243 and #1256

@mouse07410 @Jakuje and @frankmorgner I would be interested in your comments on the design and any testing you may want to do. Testing would be much easier when #1243 and #1256 are committed to master.

It is a proof of concept:

  • It only selects the Yubikey and assumes the only applications that could
    be on the card are PIV-II and OpenPGP. This needs to be generalized or added
    to the opensc.conf.

  • There may be locking issues. Each card driver has its only card_lock, but share
    the reader-pcsc.c lock. A multi-threaded application might have sessions
    open to both drivers and there could be a dead lock situation. (not easy to test.)

  • Each application uses one or more slots, and the default is 4 slots per card.

  • It is not well tested.

A Yubikey 4 with both PIV and OpenPGP and another reader with a PIV card where used in testing.

 pkcs11-tool --module /opt/ossl-1.1/lib/opensc-pkcs11.so -L
Available slots:
Slot 0 (0x0): Yubico Yubikey 4 CCID 00 00
  token label        : deengert
  token manufacturer : piv_II
  token model        : PKCS#15 emulated
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 0.0
  firmware version   : 0.0
  serial num         : dd03ee39c98b1e1d
  pin min/max        : 4/8
Slot 1 (0x1): Yubico Yubikey 4 CCID 00 00
  token label        : User PIN (OpenPGP card)
  token manufacturer : Yubico
  token model        : PKCS#15 emulated
  token flags        : login required, token initialized, PIN initialized
  hardware version   : 2.1
  firmware version   : 2.1
  serial num         : 000604035448
  pin min/max        : 6/127
Slot 2 (0x2): Yubico Yubikey 4 CCID 00 00
  token label        : User PIN (sig) (OpenPGP card)
  token manufacturer : Yubico
  token model        : PKCS#15 emulated
  token flags        : login required, token initialized, PIN initialized
  hardware version   : 2.1
  firmware version   : 2.1
  serial num         : 000604035448
  pin min/max        : 6/127
Slot 3 (0x4): SCM Microsystems Inc. SCR 355 [CCID Interface] 01 00
  token label        : Test Cardholder
  token manufacturer : piv_II
  token model        : PKCS#15 emulated
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 0.0
  firmware version   : 0.0
  serial num         : c9d45c86501843e2
  pin min/max        : 4/8

Slot 0 is the Yubikey PIV
Slot 1 and 2 are the Yubikey OpenPGP
Slot 4 is a different reader with a PIV card.

@dengert
Copy link
Member Author

dengert commented Feb 7, 2018

Now that #1243 has been merged into master, #1256 has been rebased, and this
dengert@dff1973
is now:
dengert@ab7a975
It is in this branch https://github.com/dengert/OpenSC/tree/pkcs11-multi-application

@Jakuje
Copy link
Member

Jakuje commented Feb 7, 2018

From the previous discussion I had a feeling it will be significantly more complicated. So you are saying, that there will not be needed any changes in the pkcs11/pkcs15/card/reader structures as you were explaining previously (because of using virtual slots?) or it is just not yet being done and these parts are simulated by the hardcoded AIDs in piv/pgp_init()?

We should certainly avoid the potential deadlocks in multi-thread applications. I believe it can be simply achieved by following the same order (never use the card_lock(), when the driver lock is acquired), isn't it?

In the code, I am wondering about the card_removed() change. You basically moved the code block into the cycle so we are able to clean all the virtual slots. Is this related to this change, or this should have been there just for the sake of virtual slots?

@dengert
Copy link
Member Author

dengert commented Feb 7, 2018

In effect each application gets its own virtual(s) slots. I need to look closer using GDB to see if the OpenPGP's two virtual slots share the same sc_card_t. If they don't there there should be no additional changes needed for locking. If they do share the same sc_card_t (and I think they do) because the virtual slot is added for the Sign PIN), then there may need to be additional changes and testing.

When the card->lock goes from 0 to 1, the reader lock is called.

 412         if (card->lock_count == 0) {
 413                 if (card->reader->ops->lock != NULL) {
 414                         r = card->reader->ops->lock(card->reader);

The different card drivers can not share the same SCARDHANDLE pcsc_card when calling SCardBeginTransaction, because the first thing they do is change the AID. They need to lock each other out and lock other processes out too. The reader-pcsc.c pcsc-lock appears to not check if the priv->locked is already set.

So this PR may need to be at a virtual reader level, so each card driver has its own SCARDHANDLE pcsc_card. Or the reader can have an array of SCARDHANDLEs

The card_removed() was added to the sc_card_t would be cleaned up too.

This is experimental, and needs to be a group effort, as there are still lots of questions.
After typing this response, it looks like the locking is at the wrong level. Rather than virtual slots, we need virtual readers for the different card drivers.

The issues or how to recognize if a card has multiple applications still need to be addressed, at whatever level the locking is done. If it based on EF.DIR which some cards might support, there has to be some card driver that reads the EF.DIR. But the Yubikey does not support EF.DIR and each application could return a different EF.DIR as teh EF.DIR may not be for the card but for the application.

I am going to look at virtual readers or at an array of parts of pcsc_private_data that need to be duplicated.

@dengert
Copy link
Member Author

dengert commented Feb 19, 2018

I have added a new version of this request. See
https://github.com/dengert/OpenSC/tree/pkcs11-multi-application

It has each card driver use its own pcsc reader, so each card application gets its own sc_reader_t, and its own PCSC handle and its own PCSC lock.

For example with a Yubikey 4:

/opt/ossl-1.1/bin/pkcs11-tool --module /opt/ossl-1.1/lib/opensc-pkcs11.so -L
Available slots:
Slot 0 (0x0): Yubico Yubikey 4 CCID 00 00
  token label        : deengert
  token manufacturer : piv_II
  token model        : PKCS#15 emulated
  token flags        : login required, rng, token initialized, PIN initialized
  hardware version   : 0.0
  firmware version   : 0.0
  serial num         : dd03ee39c98b1e1d
  pin min/max        : 4/8
Slot 1 (0x4): Yubico Yubikey 4 CCID 00 00[1]
  token label        : User PIN (OpenPGP card)
  token manufacturer : Yubico
  token model        : PKCS#15 emulated
  token flags        : login required, token initialized, PIN initialized
  hardware version   : 2.1
  firmware version   : 2.1
  serial num         : 000604035448
  pin min/max        : 6/127
Slot 2 (0x5): Yubico Yubikey 4 CCID 00 00[1]
  token label        : User PIN (sig) (OpenPGP card)
  token manufacturer : Yubico
  token model        : PKCS#15 emulated
  token flags        : login required, token initialized, PIN initialized
  hardware version   : 2.1
  firmware version   : 2.1
  serial num         : 000604035448
  pin min/max        : 6/127

The first slot has Slot 0 (0x0): Yubico Yubikey 4 CCID 00 00 for the.
calls to sc_connect_card_ext test there are any more card drivers that might support this card..
If so they get another reader, with [N] added to the name. (The first could have a [0] too.)
In the OpenPGP driver there are two pins, so there are 2 virtual slots for the reader.
Slot 1 (0x4): Yubico Yubikey 4 CCID 00 00[1] and Slot 2 (0x5): Yubico Yubikey 4 CCID 00 00[1]

This has the promise to work with threads, but needs a lot of work and testing and maybe some mutexes too.

@mouse07410
Copy link
Contributor

Is this PR in addition to our instead of #1256?

@dengert
Copy link
Member Author

dengert commented Feb 19, 2018 via email

@mouse07410
Copy link
Contributor

@dengert I'd like your opinion. I'm using Apple Mail with GPGTools to use both S/MIME (via PIV applet) and OpenPGP (via OpenPGP applet).

Problem: I can sign as many S/MIME emails as I want, but (usually) only one OpenPGP email - on the attempt to sign another OpenPGP email it fails. I have to re-insert the token, and sometimes also "touch" it with gpg --card-status to sign the next outgoing OpenPGP email. Switching back to S/MIME is no-problem.

opensc-debug.log file is empty, even though I suspect that tokend was used. Attaching scdaemon.log that contains some errors, which might help finding the cause of this problem.
scdaemon.log.txt

@dengert
Copy link
Member Author

dengert commented May 6, 2018

Is your scdaemon.txt with or without the patch in this PR? Without this PR you would have to be using two different OPENSC_DRIVER= variables or different opensc.conf to force different drivers. It looks like one of the applets is not selecting its AID when needed. i.e. interference for the other process.

This PR needs a lot of testing and discussion. It may not be the best way to support multiple card drivers accessing the same card for multiple applets from PKCS#11.

@mouse07410
Copy link
Contributor

mouse07410 commented May 6, 2018

Is your scdaemon.txt with or without the patch in this PR?

After checking, it appears that it's without this PR - or rather without this patch. BTW, it would be nice if your fork were rebased, so the patch could be applied cleanly...

you would have to be using two different OPENSC_DRIVER=... variables

I see. That would be possible (though unpleasant) for two different apps that want to access the token roughly at the same time. But it won't work for a single app like Apple Mail that wants to use both applets - not at the same time, but during the same run/invocation.

@dengert
Copy link
Member Author

dengert commented May 6, 2018 via email

@dengert
Copy link
Member Author

dengert commented May 16, 2018

A new version of this experimental code is rebased on 0.18.0 today:
https://github.com/dengert/OpenSC/tree/pkcs11-multi-application-2 with one commit dengert@fe88b41

The older pkcs11-multi-application is obsolete and will be removed. Use the pkcs11-multi-application-2 branch.

@eugene-bright
Copy link
Contributor

I've applied patch 97a3144 to OpenSC-0.18.0 on my Gentoo Linux.
I have a custom made card with OpenPGP applet and IsoApplet.
After starting gpg-agent with gpg --card-status command I can no longer see card certificates with openvpn --show-pkcs11-ids.
And vise versa if OpenVPN has occupied the card then gpg complains:

# gpg --card-status
gpg: selecting openpgp failed: No such device
gpg: OpenPGP card not available: No such device

@eugene-bright
Copy link
Contributor

After reboot OpenVPN stopped working:

Tue Aug 21 20:35:15 2018 PKCS#11: Cannot perform signature 32:'CKR_DATA_INVALID'
Tue Aug 21 20:35:15 2018 OpenSSL: error:14099006:SSL routines:ssl3_send_client_verify:EVP lib
Tue Aug 21 20:35:15 2018 TLS_ERROR: BIO read tls_read_plaintext error
Tue Aug 21 20:35:15 2018 TLS Error: TLS object -> incoming plaintext read error
Tue Aug 21 20:35:15 2018 TLS Error: TLS handshake failed
Tue Aug 21 20:35:15 2018 SIGUSR1[soft,tls-error] received, process restarting

After the patch removal the problem has gone.
Multiapplet support is a must have feature, but I found current patch 97a3144 deleterious.

@mouse07410
Copy link
Contributor

In addition to this patch you need a patched scdaemon because GnuPG developers refused to allow opening the device in Shared mode. So if gpg gets hold of it - OpenSC won't be able to no matter what. I personally think their decision was pig-headed.

If you were on Mac, you could use GPGTools that fixed this problem.

It would be nice if you could try this patch with a modified gpg.

@eugene-bright
Copy link
Contributor

eugene-bright commented Aug 21, 2018

Patch 97a3144 breaks OpenVPN even in the absence of running gpg-agent (should I recompile OpenVPN?).
I'm on Gentoo Linux and can apply almost any patches to a running system in a few clicks.
If I managed to run OpenVPN with patch 97a3144 I would like to know where to find additional patches for GnuPG. Could you help me with it?

@dengert
Copy link
Member Author

dengert commented Aug 21, 2018

This PR is expecting other applications to use pcsc in shared mode. It also expects that any application or driver can use SCardBeginTransaction to determine if its applet is active, check the login state and make it active and login if needed then do what commands it has to do then end the transaction with leave not reset.

As pointed out by others the GnuPG code does not do this, It would by interesting to know what OpenVPN does. the OpenSC openpgp driver, OpenSC PIV driver, and maybe the CAC driver work as expected. The isoApplet may not do this.

Cards such as Yubico with a PIV and OpenPGP or card with CAC and a PIV applets are the main targets today.

opensc-debug.log logs would be helpfull to see what the OpenSC side is doing. PCSC traces would show all the PCSC activity but are much harder to read.

@mouse07410
Copy link
Contributor

Re. Open VPN: if it attempts to open the token in Exclusive mode, then yes - it would need patching.

Re. GnuPG: check https://www.gpgtools.org and look as the sources - that's about as much as I know.

@eugene-bright
Copy link
Contributor

Thanks!

Currently the patch cause OpenVPN malfunction and I'm concerned with it. I will try to figure out the cause of errors when I find some time.

@frankmorgner
Copy link
Member

The lack of activity shows that this seems to add a feature that doesn't actually solve a problem. Most cards, only support a single PKI application, and those which have more than one application aren't used simultaneously within OpenSC... I think we should to close this as won't fix...

@dengert
Copy link
Member Author

dengert commented Nov 4, 2021

I would call it a wishlist.

It does solve a problem in that within one application, the application could use OpenSC PKCS11 to access two different applets on the same device using OpenSC drivers. P11-kit comes close, but it requires the OpenSC PKCS11 to handle one applet and some other PKCS11 module handle the other.

It was designed to work with cards with multiple apps, such as Yubico with PIV and GnuPGP, or PIV and CAC, or what ever else comes along. This would then allow OpenSC PKCS11 module called from one application like a browser, e-mail, PAM, etc to not require extra modifications.

Right now different applications can use different OpenSC drivers if the list of drivers, is provided in opensc.conf or via environment variables.

The code is complicated because OpenSC was original written were there was only one program on a card, Now multiple applets on a card are common. Te code modifies the driver selection loop in card.c when called via PKCS11 so each applet gets its own slot(s). and how PCSC locking is done.

Another approach would be via p11-kit if it could load multiple instances of the OpenSC PKCS11 module each having a different opensc.conf. If these used share static data there may be more work involved.

I have not tested it lately as no one is pushing for it.

@frankmorgner
Copy link
Member

Now multiple applets on a card are common.

Multiple applets on cards may be common in the sense that there are somewhat seperated in runtime and functionality on the card itself. But looking from the user's perspective, there's typically only a single application that holds X.509 certificates and keys.

Another approach would be via p11-kit if it could load multiple instances of the OpenSC PKCS11 module each having a different opensc.conf. If these used share static data there may be more work involved.

Indeed, that would be another way of solving this. In OpenSC we could simply build multiple pkcs11 modules, one for every card driver... Since concurrency separation exists between the modules, multiple card applications should work out of the box.

I have not tested it lately as no one is pushing for it.

I want to get this out of my head. If there's no need for this, we don't need to think about it and close this issue...

@eugene-bright
Copy link
Contributor

I have a concurrent usage scenario with isoapplet for OpenVPN and ykneo-openpgp for GPG, but do not have much time currently to work on it.
Further more, as GPG locks the card I have little hope to make concurrency work anyway.

@frankmorgner
Copy link
Member

I have a concurrent usage scenario with isoapplet for OpenVPN and ykneo-openpgp for GPG, but do not have much time currently to work on it. Further more, as GPG locks the card I have little hope to make concurrency work anyway.

How many people do you know that build their own java card configurations?

@eugene-bright
Copy link
Contributor

:) feel free to close the ticket.
I will come back if needed.

@mouse07410
Copy link
Contributor

My use case: dealing with email that includes both S/MIME and OpenPGP pieces. Applications (e.g., Thunderbird) usually support this and allow choosing per-individual-email-piece.

@dengert
Copy link
Member Author

dengert commented Nov 5, 2021

@frankmorgner wrote:

How many people do you know that build their own java card configurations?

Too many! And they like to write PIV-like applets. And vendor's too.

If you want to get it out of your head, call it a wishlist. Even if you close it, multiple applets on cards are still problematic.

@frankmorgner frankmorgner closed this as not planned Won't fix, can't repro, duplicate, stale Jan 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants