-
Notifications
You must be signed in to change notification settings - Fork 709
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
OpenSC Minidriver with PIVApplet + ECC keys on Win11: error on slot 9c - public key does not match private key #3159
Comments
PS: I already saw #2592 and found it is probably not related. PPS: While reviewing the logs again I can also see, that the key management key is verified correctly, but card authentication is not as well. I added the card to the registry this way, "AllID ..." is just an artificial name starting with "A" - not a real world product. It took me a while until I tracked down everything, so I had to conduct a few experiments.
|
Looks like it should work. Here are some things to look at:
PIV specs call for the 9C key to require a pin verify just before the the signature operation at line 18120 in the debug log:
In PKCS11 this is called CKA_ALWAYS_AUTHENTICATE, in PKCS15 it is called user-consent You also also modify (You could try with an RSA key for 9C as i think it will work with RSA.) Also look if there us an option to turn this off for PivApplet. Also try to sign with pkcs11-tool as a test. |
Hi @dengert, thanks for your reply and suggestions.
same result at slot 9c:
But it's trying to use "test-PA" - thats PIV Authentication (9A), not digital signature (9C):
How do I force PKCS-11 to use test-DS / 9C? |
BTW: the "serial number" from the Yubico piv-tool is a Yubikey serial number - out of spec for PIV-II. The PIVApplet just generates one at random during install. Most YubiKeyPIV-compatible extensions are implemented and working: PIN policy Version indicator (we pretend to be a YK5) Fetch serial number (randomly generated) Set management key |
Okay, it is "--id 2" similar to the slot enumeration of the minidriver
Definitely this "context specific PIN" is missing from the mini driver tests. |
Thanks for pointing out the 0x6982. I gave it a try and modified PivApplet to use P_DEFAULT (0), which is P_ONCE, instead of P_ALWAYS for slot 0x9C. At least now certutil -scinfo says "private key verified" for slot 0x9C. But PKCS#11 now hangs. |
Not sure what "modified PivApplet to use P_DEFAULT (0), which is P_ONCE" does. This Windows policy for ECC keys for login maybe the problem: Also says: Windows also looks at keyUsage bits in certificates, and may also be looking at certificate chains and trusted root CA. I tried |
I modified https://github.com/arekinath/PivApplet/blob/master/src/net/cooperi/pivapplet/PivApplet.java#L449 to change the PIN-behavior of slot 9C. The group policy to enable ECC certificates is long in place. The Active Directory CA is of course trusted and >7 years in place, the keyUsage bits are correct. As said in the initial post I was using GIDS for years already and I managed to get it working with a Yubikey and ECC P256. Yes, scinfo should prompt twice if the minidriver forwards the 0x6982 condition to the upper application layer, so it can prompt the user. The OpenSC mini driver is simply not doing this. You proved it yourself with the Idemia Card and Idemias PIV MD. |
As you already know, the OpenSC PIV for minidriver is not installed by default. This was because Microsoft provides a way to use PIV cards. Have you tried letting Microsoft discover that you have a PIV card? I assume you have, because you are trying to use the OpenSC version. in your original opensc-debug.log starting at 13273:
So it looks like it worked as expected for 9A key. Since you said it fails for 9C even with RSA, so it looks like it has a problem. I will look closer tomorrow. Its a holiday in the U.S today. |
Have a nice holiday @dengert and thanks for your fast reply. :-) I did try to let the PIV layer know about the card, it also get's registered in the PIV device ATR cache in this case: As you already imagined it didn't work out, but with the link you provided you're starting to convince me to try I try to figure out if I can get a debug log from the logon process. I have an almost identical certificate of the Yubikey The Yubikey certutil -scinfo shows it hides away 9C, 9D, 9E and only expose 9A. This sheds a new light on my Thanks & best, |
@ckahlo can you try setting these in the From In your original opensc-debug.log The log is all from the same process P:3304 and same thread T:9952 and runs for 49 seconds.
Starting here at line 18021:
in NIST sp800-73-4 (and older versions) : The use of the '7E" discovery object is inserted between the PIN verify command and the signature key operation. When used with PKCS11, the upper levels tests if a key has the “PIN Always” and asks the user for the PIN and verifies just before the sign command. This may not be happening with minidriver, and/or the lower level code is not notified it is needed to take action like it does with PKCS11. The use of logout in d7fadae may also complicate this. |
The PKCS#11 workflow often includes PIN verification status requests between the actual verification and creation of the signature. To support the "PIN Always"/"OCC Always" mode, the PIV driver explicitly disabled the status query APDU: OpenSC/src/libopensc/card-piv.c Lines 6003 to 6013 in cd3e8b9
So similarly, you would need such special treatment when checking whether the applet is selected in That being said, the conditions for this special treatment should be refined to something like IF logged in with "PIN Always"/"OCC Always" THEN avoid unnecessary APDUs. Also, the logged-in-state should be reset in this case if some APDU was sent - in best case the signature APDU, in worst case some other APDU that cannot be avoided. This refinement should also applied to the existing code referenced above, I think. |
Windows appears to have a different way to handle the "PIN Always"/"OCC Always" type of key, by using We do not install the OpenSC PIV entries in the registry, as most vendors provide their own minidriver, or people just use the Microsoft PIV support. Also note the applet was installed on a "NXP P71D321 / J3R180 variant" device that is not listed on https://github.com/arekinath/PivApplet. If this device is PIV complaint it should work with the Windows PIV support. I would still like an opensc debug log using what @ckahlo added:
I would set debug = 9; to show any pin commands, and set the pin_cache_counter much higher as it applies to all uses. It would show up in a line like this from the original debug log line15893:
@chahlo, Are you doing this for your employer or just for yourself? |
Hi @dengert, Hi @frankmorgner, a couple of very well-known names in here :-) All the best, |
PS: the J3R180 ist not that far away from J3H145. It's a follow-up, functional superset, much faster. |
Sure, I do remember you very well, in particular for the little projects, for example with the BSI, that were very interesting from a technical point of view, even though they may not have had the expected impact. Currently, the biggest problem for OpenSC is the lack support with the heterogenous infrastructure. Apple was constantly changing things in the last couple of years and MS infrastructure didn't get any simpler as well. So your comments and testing are very welcome. |
TODO That being said, the conditions for this special treatment should be refined to something like IF logged in with "PIN Always"/"OCC Always" THEN avoid unnecessary APDUs. Also, the logged-in-state should be reset in this case if some APDU was sent - in best case the signature APDU, in worst case some other APDU that cannot be avoided. This refinement should also applied to the existing code referenced above, I think. fixes OpenSC#3159
TODO That being said, the conditions for this special treatment should be refined to something like IF logged in with "PIN Always"/"OCC Always" THEN avoid unnecessary APDUs. Also, the logged-in-state should be reset in this case if some APDU was sent - in best case the signature APDU, in worst case some other APDU that cannot be avoided. This refinement should also applied to the existing code referenced above, I think. fixes OpenSC#3159
I've pushed #3163 with a quick fix. If everything goes well, you may pull the Windows installer from AppVeyor. |
Stupid question, but did none of the prebuilt CAPs fit your needs? |
I can send @ckahlo one J2A080 card (JCOP 2.4.1R3, GP 2.2.1, contact-only, |
When a content specific C_Login is done, PIV driver gets an extra lock before doing the verify. This lock is held until the next request by the application to do any operation, which is expected to be a crypto operation. This avoids this situation: "like IF logged in with "PIN Always"/"OCC Always" THEN avoid unnecessary APDUs" No unnecessary APDUs like checking status or login state are done as the PC/SC lock is being held. When the calling application, which knows it is doing a context specific login and should only do a crypto operation, requests any APDU, that APDU is done, and the lock is released, and
The use of the extra lock means the I believe the code current addresses the above, except with minidriver. With the minidriver, If I am reading the Microsoft docs correctly, the application could be made aware that a verify is needed before the crypto operation, by using the treating the 9C key as requiring |
Indeed, support for an equivalent of CKA_ALWAYS_AUTHENTICATE is not implemented in minidriver. Since CKA_ALWAYS_AUTHENTICATE is associated with the keys themselves and PinCacheAlwaysPrompt is associated to the PIN that unlocks the key, this cannot done in a straight forward way. I think the best approach would be to create an additional virtual PIN that differs from the normal PIN only in the PIN_CACHE_POLICY_TYPE. Then all keys with user_consent map to the virtual PIN, keys without map to the normal PIN. The objects and their mapping are initialized in md_set_cmapfile(). For the virtual PIN, SC_AC_CONTEXT_SPECIFIC can then be set before validation. This change, however, needs to be implemented with care, because many places need to be touched that previously looked at the id of the PIN only. I closed #3163 because it doesn't provide a general solution for keys with user consent, but I still believe it would solve the issue for PIV. So if you're in to quick-and-dirty solutions, you may still want to have a look. Speaking of quick and dirty solutions, locking the card at the driver level and requiring a subsequent call for unlocking, can break in many ways: If anything goes wrong in between those calls, you will not be able to clean up the lock and the card is unusable within OpenSC and for any other process. It would be better to check the state and avoid commands as described above without locking the card. This discussion, however, should be done elswhere. |
@maciejsszmigiero as author of the multiple pin support in OpenSC minidriver in bd9cdd2 It also looks like we would need to flag any keys where the Then when the CSP requests a PIN verify using the MD_ROLE_USER_ALWAYS_AUTHENTICATE role to pass this to pkcs15 . Any advice would be helpful. |
@ckahlo have a look at #3167 which has a potential fix. If you want to use the same MSI files I used which can be found by looking at #3167 in the "Some checks were not successful" box (near the bottom), make sure all all checks are shown, then scroll down to "continuous-integration/appveyor/pr — AppVeyor build succeeded" at the bottom, and click on Details. This will take you to https://ci.appveyor.com/project/frankmorgner/opensc/builds/49934816 |
First, I don't think that setting PinCacheAlwaysPrompt for the signature PIN in general is useful for all the card, because if possible PIN caching is a desired feature. But I do agree that creating a "virtual" PIN for keys with required user consent helps in setting the correct PIN caching policy. Second, your approach in #3167 requires modifications of the card driver level of creating the virtual PIN, but that will be hard to do for every existing driver. My advice would be, to create virtual PINs in the minidriver rather than the card driver based on the existing card profile. I described the approach already above. In md_set_cmapfile() more PINs than the standard roles are already created if the card has more available. Here, you would now add one virtual PIN for every normal PIN that has some key with user consent. Then, associate that key with the new virtual PIN instead of the normal PIN. This potentially doubles the number of pin_objs in VENDOR_SPECIFIC and should allow setting the cache policy for every underlying card driver without modifying anything else than minidriver.c I will not be able to test this since I don't have any card with that configuration. I can supply some code that might work if someone is interested. |
I think it depends whether there are (or can be) cards where there are multiple sign PINs and only some of these need PIN caching off. If not, then probably re-using By the way, as I commented here, I don't think we should unconditionally set |
@frankmorgner @maciejsszmigiero Thanks for the comments. As noted in comment in the code: Using a No other card driver uses PKCS15 has the concept of The PIV cards have been around since 2004, and the card enforces this policy of no APDUs between verify and crypto operation when using the 9C key. Note that PIV have only one user key which must be re-authenticated. Yubico has this not standard feature to turn this on or off for any key as well a touch policy, So that would require additional changes in the In regards to pin caching, in my test I turn off the OpenSC caching off, to see what Windows would do. OpenSC pin caching will not work with a pin-pad reader. The simple Only the Note that PIV is one of the most popular types of cards with multiple card manufacture's providing Windows minidrivers to support vendor specific features, and Windows has its own PIV support. So OpenSC does not install the register profiles for PIV. In regards to setting an extra lock to force the verify and crypto into the same SCardTransmission, card-piv.c will release it in a number of places. The only real problem would be if the application did a verify and never did any other operation, not a likely situation as the point doing a re-verify is to do a crypt operation immediately after. |
This sounds like #3159 and #3167 because the keys are set at https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/pkcs15-jpki.c#L168 The PKCS15 user_consent = 1 is the equivalent of PKCS11 CKA_ALWAYS_AUTHNETICATE. What is output of You could try the MSI files as liksted here: #3159 (comment) |
Hi there,
Problem Description
after using @vletoux GIDS applet for quite a while (thanks :)!) I wanted to migrate to ECC and PIV because I need integration with
the OS - such as logon, VPN, TLS, SSH. Unfortunately I could only manage to get a Yubikey running with Active Directory CA
credentials in a manual process with a custom CA template - so I could verify AD and client are prepared to handle at least ECCP256 and do workstation logon. (enrollment for ECC doesn't really seem to work anyway ...?)
I am using the Yubico piv-tool below because I need to generate CSRs and the OpenSC toolchain lacks functionality for that.
So I chose https://github.com/arekinath/PivApplet and compiled it with the settings:
put it on a NXP P71D321 / J3R180 variant:
...\tools> .\gp.exe -dvil -install C:\Users\ck\git\PivApplet\bin\PivApplet.cap
check the status
initialize the attestation, card authentication and key management keys
generate keypairs for PIV authentication and digital signature (testcase here, simulating the exact same problem with real CA)
check the results and getting errors, resembling what I observed before:
The certificates show up nicely:
I tracked the issue down to the second key slot, being assigned to the 9c ("digital signature") slot in the PIV applet.
I'm attaching all I've got from the logs.
Proposed Resolution
Slot 9c needs to work to do smartcard logon - while TLS client authenticaton may work with slot 9a many other things (VPN, RDP) do not.
Steps to reproduce
For piv-init initcard I do:
For piv-init selfsign I do:
Logs
see https://gist.github.com/ckahlo/bc00b88d911364a584069dd237601967 for scinfo -v -privatekey
see opensc-debug.txt attached
opensc-debug.txt
Thank you!
The text was updated successfully, but these errors were encountered: