-
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
Resetting library state #3018
Comments
May need to turn off in |
I have only one session in my application and closing/opening it does not fix the problem.
I'll try your suggestion regarding |
The PKCS11 module is loaded and run within a process. The PCSC For more info, Google for: SCardBeginTransaction The other problem you may be seeing is the card driver and pkcs15 layers may not be updating the pkcs11 data when you update or delete an object. What card are you using? |
Yes, this is what I'm talking about. My application may be working with several readers simultaneously and
I tried that and it didn't work. Here's the debugging output when reproducing the problem via The first call (no cache present):
Then I do
We can see that
but it goes down to
This code path doesn't even look at the
Nitrokey 3C NFC, which gets recognized as a generic OpenPGP card. I will now try a hackish solution - to fool If you have idea how to properly fix this on OpenSC, I'm also open to suggestions and ready to do the work. |
Ah, missed that part. It brought me to |
From OpenPGP Smart Card Application V3.4.1 It looks like you are trying to change the openpgp DO:
but not by going through the card-openpgp.c or pkcs15-openpgp.c where this may have been cached. An opensc debug log would show if DO 0053 was read. This is similar to DO 0101 accept to write DO 0101, PW1 is needed, but to write 005E PW3 is needed. See comments: It appears OpenSC can not update any of the DOs: Name (5B), Language preference (5F2D), or Sex (5F35). I assume you are not using pkcs11 to initialize the card. If you are then in All of the following could work with any card, not just openpgp:
C_SetAttributeValue which would then cause the calls to All of the above would work with any card that needs to refresh its data . Not an easy problem to solve. I like the CKO_VENDOR_DEFINED object. |
But the problem is not specific to pkcs15 DOs. PKCS11 data objects are also not being refreshed, see my example with consecutive |
Either of these problems have to be fixed in the openpgp software or as suggeste4d above or via Or you remove the card after doing the updates and reinsert if you need to continue. Or if you can find some other package that can handle the 005E and generating keys Or you do the login mapping from what is on the card in the login software without having to use the 005E. It is still not clear what your long running daemon is trying to do and why it is allowed to modify the card. You can submit also submit a PR. |
Is it guaranteed that CK_SLOT_ID for the given reader will stay same after this? |
The commands are used from C_initToken after the token is initialize so you get the data from the token. The token appears as if it was physically removed but the reader is still there. The application then has to go looking for it again. So you could identify the token from the CK_TOKEN_INFO label and/or serialnumber assuming you have not changed them. The same code is used if the token was physically removed and reinserted. (Physical removal may also remove the reader is part of the token.) The code make no assumption that the token has not been modified or it is same token being inserted. PKCS11 does not keep track of the time between removal and reinsertion. But you are guaranteed that when you find it again, you are now looking at data from the card, and not cached in the driver. (But OpenSC might be caching files in you home directory, so make sure it is off.) |
@arrowd You had said the generate keypair had the same problem. But your examples does not include a CKA_ID or CKA_LABEL . Please have a look at gen_keypair which adds CKA_ID and CKA_LABEL at https://github.com/OpenSC/OpenSC/blob/master/src/tools/pkcs11-tool.c#L3101-L3117 So it is not clear what key was generated. Also note pkcs11-tool also has a delete object which you may have to call first to delete any existing key or other other object. Also note that specific applets like openpgp only support specific CKA _ID values of 01, 02 and 03. for keys. If you can git around this issue with keys, it might be possible to add code to handle updating the 005E via pkcs11. OpenSC spy and debug logs would be helpful. |
Another option for your daemon is to start a subprocess to do required operations, passing the token label or serial number. Using a Nitro start test card, previously initialized by GnuPG's gpg-card:
Note above changes the login data to Doug but their command did not refresh the data.
Now it does show the login "Doug". |
Here is a possible solution. update the card, close all sessions then call from your pkcs11 application: There are two slot listed for openpgp, one for each pin so it may call the code twice. I tested if from pkcs11-tools as listed below, not the best place to do it. Use at your own risk.
|
pgp_erase_card() uses TERMINATE DF and ACTIVATE FILE to delete the card's contents. However, this doesn't clean up the card driver's internal caching of the card's data ( This will be re-initialized along with the card handles when C_Finalize + C_Initialized are called. Note that creating and deleting a session does not cause re-initialization of the internal handles. If you want to improve OpenSC, you may want to fix the state-keeping in card-openpgp.c around the internal pgp_blobs. If you want a quick solution, simply call C_Initialize after erasing the card (either through C_InitToken or via openpgp-tool). |
@frank, you are right, the card drivers should do this, there maybe other card drivers that have the same problem. The quick solution for most people is to just remove the token and reinsert. @arrowd is not looking for a quick solution, with his daemon process. But PKCS11 does not define a way to simulate removal and insertion. OpenSC's I said about the above patch "Use at your own risk." (which should not be in OpenSC) because if one was to call As best I can tell @arrowd is trying to use OpenSC's OpenPGP pkcs15 or pkcs11 code does not have a way to update many of the "DOs" i.e. blobs defined by OpenPGP. Whatever is done, looks like a lot of work, with little reward. It is not clear to me if using the "Login data (5E)" is even a good idea. Maybe using certificates issued by a good PKI infrastructure could be used to map to local login names as done with most other tokens. |
Thanks everyone for your input. For now I settled with the following hack:
The former call is possible because I put it into the library's export list. I probably should use some better entry point instead of that. I will use this hack for now as I need to proceed with my daemon.
Like I said in #3018 (comment) , the problem can also be observed when using only PKCS11 API. From my (uneducated) POV the core issue is that libopensc caches a lot of stuff without having a proper way to reset the cache. If you agree on that and give me an idea on how to properly fix it within OpenSC, I will try to find spare time to do that. Otherwise I'll just stick to my hack. Thanks again, the whole thread was quite helpful. |
I tried to describe the faulty cache above (#3018 (comment)). I think a fix could be quite simple... please try #3024 |
@arrowd, could you please provide a debug log when running the two subsequent calls to |
I started with inserting a token with a key pair already generated. The scenario is following:
Here are the logs: Act I: Getting the public key
Act II: Logging in as SO
Act III: Generating a new pair
Act IV: Getting the public key again
Note that Act V: Getting the public key after token reinsertion (skipping the initialization log)
|
You are basically replacing an old key with a new key, which is not what C_GenerateKeyPair does. It only creates objects and, in particular, we should actually return an error in your case:
Maybe we should check the ID for an existing object and return CKR_ATTRIBUTE_VALUE_INVALID in that case, but I'm not sure if we need to be so strict. |
Oh, that makes sense. I will try adding appropriate |
I tried the Right before the
When running this I only got |
I think it would be good to open a new issue for that, with a) a pkcs11-spy trace to see the order of commands and b) an opensc debug log to see what's happening under the hood. thank you. |
I'm writing a daemon-like application that runs for a long time and make calls to OpenSC via both PKCS11 API and the internal one (
sc_*
). I know that I shouldn't really usesc_*
stuff, but the bug I'm going to explain here can also be reproduced with pureC_*
functions.The core of the problem is OpenSC seems to cache quite a lot of stuff and there is no way to tell it to "reload". This can be illustrated with the following example:
As you can see, the
erase
command actually cleared out the3F00/005e
EF, but this change can't be seen by the library until I restart the program (read: reinitialize the library).A related example with PKCS11 API is following:
Running
pkcs11-tool
oropenpgp-tool
between steps 4 and 5 confirms that keys are actually changed on-card, it is just the application doesn't see the change.To sum this up, I need to trigger the same reloading/recaching process inside the library as when the token is physically reattached to the host. Or am I fundametally missing something?
The text was updated successfully, but these errors were encountered: