From: Bob B. <fig...@gm...> - 2018-12-19 03:08:48
|
Hi, Just some question about how the OpenSC PKCS# 11 (DLL) handles the multiple applications using it. The scenario is I have two applications, application A and application B loading the same DLL. Application B loops continuously, calling C_WaitForSlotEvent and C_GetTokenInfo, basically it just checks for the insert and remove events from the smart card. Application A can call C_InitPIN and C_InitToken. The conflict happens when, while the application B is checking for smart card events, application A then calls C_InitToken, which deletes the smart card contents, and formats it to be a new card, (and possibly deleting the PKCS# 15 objects) and the next call to C_OpenSession fails returning CKR_TOKEN_NOT_PRESENT error. When I try to check the logs, the state of the smart card become ABSENT , I can see this during the C_InitToken, when sc_detect_card_presence is called. When I try to run application A, and call C_InitToken without the application B running, I do not encounter this issue, and the smart card does not become ABSENT but instead I can see from the logs that its state become CHANGED. I am not sure if this is the expected behavior or where or how I should handle it. I am not sure if this is also an issue on the OpenSC PKCS# 11 DLL or the smart card. I tried to look at the available documentation but couldn't find an answer to this, Your expert opinion is greatly appreciated. Thanks, fightingsibuyas |
From: Douglas E E. <dee...@gm...> - 2018-12-19 13:05:23
|
The OpenSC PKCS#11 relies on the PCSC layer to lock access to the card across multiple applications. https://github.com/OpenSC/OpenSC/wiki/PCSC-and-pcsc-lite http://ludovic.rousseau.free.fr/softwares/pcsc-tools/ https://docs.microsoft.com/en-us/windows/desktop/secauthn/smart-card-and-reader-access-functions In regards to one application modifying the card while another application is waiting for events, the event will contain a SCARD_W_* return. The application (A) that modified the card in such a drastic way should do a card reset, that will cause the the event returned to (B) will cause (B) to start over. https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/authentication-return-values Doing do a C_InitToken is like formatting your hard drive. Most applications can not copy with this. In other words don't do it while other applications are running. On 12/18/2018 9:06 PM, Bob Backlund wrote: > Hi, > > Just some question about how the OpenSC PKCS# 11 (DLL) handles the multiple applications using it. > > The scenario is I have two applications, application A and application B loading the same DLL. > > Application B loops continuously, calling C_WaitForSlotEvent and C_GetTokenInfo, basically it just checks for the insert and remove events from the smart card. > > Application A can call C_InitPIN and C_InitToken. > > The conflict happens when, while the application B is checking for smart card events, application A then calls C_InitToken, which deletes the smart card contents, and formats it to be a new card, (and > possibly deleting the PKCS# 15 objects) and the next call to C_OpenSession fails returning CKR_TOKEN_NOT_PRESENT error. > > When I try to check the logs, the state of the smart card become ABSENT , I can see this during the C_InitToken, when sc_detect_card_presence is called. > > When I try to run application A, and call C_InitToken without the application B running, I do not encounter this issue, and the smart card does not become ABSENT but instead I can see from the logs > that its state become CHANGED. > > I am not sure if this is the expected behavior or where or how I should handle it. I am not sure if this is also an issue on the OpenSC PKCS# 11 DLL or the smart card. I tried to look at the available > documentation but couldn't find an answer to this, > > Your expert opinion is greatly appreciated. > > > Thanks, > > fightingsibuyas > > > _______________________________________________ > Opensc-devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/opensc-devel > -- Douglas E. Engert <DEE...@gm...> |
From: Bob B. <fig...@gm...> - 2018-12-28 04:00:04
|
Hi Douglas, Thank you for your reply. I understand that the "OpenSC PKCS#11 relies on the PCSC layer to lock access" but I think the issue lies on the lock used for the Windows system, on the pkcs11-global.c, I can see that the type of lock used is Critical Section as opposed to Mutex. It was mentioned on the Microsoft documentation that ; *A critical section object provides synchronization similar to that provided by a mutex object, except that a critical section can be used only by the threads of a single process. Critical section objects cannot be shared across processes.* Correct me if I'm wrong, but I think, to be able to handle "multiple applications" we may need to use Mutex instead of the default Critical Section. If that is the case how am able to do it in the OpenSC layer, do I just change the implementation to use Mutex instead of Critical Section (by changing the flow in the function pointer)? I am not sure if what I am saying makes sense, my apologies if this is something I over complicate. I appreciate your help on this. *Source: https://docs.microsoft.com/en-us/windows/desktop/Sync/critical-section-objects <https://docs.microsoft.com/en-us/windows/desktop/Sync/critical-section-objects>* Thanks, Jared On Wed, Dec 19, 2018 at 9:05 PM Douglas E Engert <dee...@gm...> wrote: > The OpenSC PKCS#11 relies on the PCSC layer to lock access to the card > across multiple applications. > > https://github.com/OpenSC/OpenSC/wiki/PCSC-and-pcsc-lite > > http://ludovic.rousseau.free.fr/softwares/pcsc-tools/ > > > https://docs.microsoft.com/en-us/windows/desktop/secauthn/smart-card-and-reader-access-functions > > In regards to one application modifying the card while another application > is waiting for events, > the event will contain a SCARD_W_* return. > > The application (A) that modified the card in such a drastic way should do > a card reset, > that will cause the the event returned to (B) will cause (B) to start over. > > > https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/authentication-return-values > > Doing do a C_InitToken is like formatting your hard drive. Most > applications can not copy with this. > In other words don't do it while other applications are running. > > > On 12/18/2018 9:06 PM, Bob Backlund wrote: > > Hi, > > > > Just some question about how the OpenSC PKCS# 11 (DLL) handles the > multiple applications using it. > > > > The scenario is I have two applications, application A and application B > loading the same DLL. > > > > Application B loops continuously, calling C_WaitForSlotEvent and > C_GetTokenInfo, basically it just checks for the insert and remove events > from the smart card. > > > > Application A can call C_InitPIN and C_InitToken. > > > > The conflict happens when, while the application B is checking for smart > card events, application A then calls C_InitToken, which deletes the smart > card contents, and formats it to be a new card, (and > > possibly deleting the PKCS# 15 objects) and the next call to > C_OpenSession fails returning CKR_TOKEN_NOT_PRESENT error. > > > > When I try to check the logs, the state of the smart card become ABSENT > , I can see this during the C_InitToken, when sc_detect_card_presence is > called. > > > > When I try to run application A, and call C_InitToken without the > application B running, I do not encounter this issue, and the smart card > does not become ABSENT but instead I can see from the logs > > that its state become CHANGED. > > > > I am not sure if this is the expected behavior or where or how I should > handle it. I am not sure if this is also an issue on the OpenSC PKCS# 11 > DLL or the smart card. I tried to look at the available > > documentation but couldn't find an answer to this, > > > > Your expert opinion is greatly appreciated. > > > > > > Thanks, > > > > fightingsibuyas > > > > > > _______________________________________________ > > Opensc-devel mailing list > > Ope...@li... > > https://lists.sourceforge.net/lists/listinfo/opensc-devel > > > > -- > > Douglas E. Engert <DEE...@gm...> > > > > _______________________________________________ > Opensc-devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/opensc-devel > |
From: Douglas E E. <dee...@gm...> - 2018-12-28 13:20:59
|
I will deffer to others on the use critical section. But it my understanding that opensc locking is meant for a single process. There is no intent to do a global lock across other processes in the system. PCSC is used to do that. I still contend that what you may be seeing is Application A that just did a C_InitToken should do a SCardDisconnect() with SCARD_RESET_CARD or SCARD_UNPOWER_CARD so other applications that are waiting for an event will be notified by PCSC that a reset was done. reader-pcsc.c in pcsc_disconnect() has: 606 if (!priv->gpriv->cardmod && !(reader->ctx->flags & SC_CTX_FLAG_TERMINATE)) { That may be the problem on windows. opensc.conf also has "disconnect_action = leave|reset|unpower;" but what is missing is a way to do a SCARD_RESET_CARD or SCARD_UNPOWER_CARD only in special situations such as C_InitToken. And all the actions required to do C_InitToken need to be done under one transaction or the session needs to be exclusive rather then shared. On 12/27/2018 10:00 PM, Bob Backlund wrote: > Hi Douglas, > > Thank you for your reply. > > I understand that the "OpenSC PKCS#11 relies on the PCSC layer to lock access" but I think the issue lies on the lock used for the Windows system, on the pkcs11-global.c, I can see that the type of > lock used is Critical Section as opposed to Mutex. It was mentioned on the Microsoft documentation that ; > /A critical section object provides synchronization similar to that provided by a mutex object, except that a critical section can be used *only by the threads of a single process*. Critical section > objects *cannot be shared across processes*. > / > > Correct me if I'm wrong, but I think, to be able to handle "multiple applications" we may need to use Mutex instead of the default Critical Section. If that is the case how am able to do it in the > OpenSC layer, do I just change the implementation to use Mutex instead of Critical Section (by changing the flow in the function pointer)? > > I am not sure if what I am saying makes sense, my apologies if this is something I over complicate. > > I appreciate your help on this. > > *Source: https://docs.microsoft.com/en-us/windows/desktop/Sync/critical-section-objects* > > > Thanks, > > Jared > > On Wed, Dec 19, 2018 at 9:05 PM Douglas E Engert <dee...@gm... <mailto:dee...@gm...>> wrote: > > The OpenSC PKCS#11 relies on the PCSC layer to lock access to the card across multiple applications. > > https://github.com/OpenSC/OpenSC/wiki/PCSC-and-pcsc-lite > > http://ludovic.rousseau.free.fr/softwares/pcsc-tools/ > > https://docs.microsoft.com/en-us/windows/desktop/secauthn/smart-card-and-reader-access-functions > > In regards to one application modifying the card while another application is waiting for events, > the event will contain a SCARD_W_* return. > > The application (A) that modified the card in such a drastic way should do a card reset, > that will cause the the event returned to (B) will cause (B) to start over. > > https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/authentication-return-values > > Doing do a C_InitToken is like formatting your hard drive. Most applications can not copy with this. > In other words don't do it while other applications are running. > > > On 12/18/2018 9:06 PM, Bob Backlund wrote: > > Hi, > > > > Just some question about how the OpenSC PKCS# 11 (DLL) handles the multiple applications using it. > > > > The scenario is I have two applications, application A and application B loading the same DLL. > > > > Application B loops continuously, calling C_WaitForSlotEvent and C_GetTokenInfo, basically it just checks for the insert and remove events from the smart card. > > > > Application A can call C_InitPIN and C_InitToken. > > > > The conflict happens when, while the application B is checking for smart card events, application A then calls C_InitToken, which deletes the smart card contents, and formats it to be a new > card, (and > > possibly deleting the PKCS# 15 objects) and the next call to C_OpenSession fails returning CKR_TOKEN_NOT_PRESENT error. > > > > When I try to check the logs, the state of the smart card become ABSENT , I can see this during the C_InitToken, when sc_detect_card_presence is called. > > > > When I try to run application A, and call C_InitToken without the application B running, I do not encounter this issue, and the smart card does not become ABSENT but instead I can see from the > logs > > that its state become CHANGED. > > > > I am not sure if this is the expected behavior or where or how I should handle it. I am not sure if this is also an issue on the OpenSC PKCS# 11 DLL or the smart card. I tried to look at the > available > > documentation but couldn't find an answer to this, > > > > Your expert opinion is greatly appreciated. > > > > > > Thanks, > > > > fightingsibuyas > > > > > > _______________________________________________ > > Opensc-devel mailing list > > Ope...@li... <mailto:Ope...@li...> > > https://lists.sourceforge.net/lists/listinfo/opensc-devel > > > > -- > > Douglas E. Engert <DEE...@gm... <mailto:DEE...@gm...>> > > > > _______________________________________________ > Opensc-devel mailing list > Ope...@li... <mailto:Ope...@li...> > https://lists.sourceforge.net/lists/listinfo/opensc-devel > > > > _______________________________________________ > Opensc-devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/opensc-devel > -- Douglas E. Engert <DEE...@gm...> |
From: Douglas E E. <dee...@gm...> - 2018-12-28 13:39:39
|
One more comment. It should also be possible to use ScardEndTransaction() with SCARD_RESET_CARD or SCARD_UNPOWER_CARD at the end of the C_InitToken transaction. On 12/28/2018 7:20 AM, Douglas E Engert wrote: > I will deffer to others on the use critical section. But it my understanding that opensc locking is meant > for a single process. There is no intent to do a global lock across other processes in the system. PCSC is > used to do that. > > I still contend that what you may be seeing is Application A that just did a C_InitToken should > do a SCardDisconnect() with SCARD_RESET_CARD or SCARD_UNPOWER_CARD so other applications that are waiting > for an event will be notified by PCSC that a reset was done. > > reader-pcsc.c in pcsc_disconnect() has: > 606 if (!priv->gpriv->cardmod && !(reader->ctx->flags & SC_CTX_FLAG_TERMINATE)) { > That may be the problem on windows. > > opensc.conf also has "disconnect_action = leave|reset|unpower;" but what is missing is a way to do a > SCARD_RESET_CARD or SCARD_UNPOWER_CARD only in special situations such as C_InitToken. And all the > actions required to do C_InitToken need to be done under one transaction or the session needs to be > exclusive rather then shared. > > > > On 12/27/2018 10:00 PM, Bob Backlund wrote: >> Hi Douglas, >> >> Thank you for your reply. >> >> I understand that the "OpenSC PKCS#11 relies on the PCSC layer to lock access" but I think the issue lies on the lock used for the Windows system, on the pkcs11-global.c, I can see that the type of >> lock used is Critical Section as opposed to Mutex. It was mentioned on the Microsoft documentation that ; >> /A critical section object provides synchronization similar to that provided by a mutex object, except that a critical section can be used *only by the threads of a single process*. Critical section >> objects *cannot be shared across processes*. >> / >> >> Correct me if I'm wrong, but I think, to be able to handle "multiple applications" we may need to use Mutex instead of the default Critical Section. If that is the case how am able to do it in the >> OpenSC layer, do I just change the implementation to use Mutex instead of Critical Section (by changing the flow in the function pointer)? >> >> I am not sure if what I am saying makes sense, my apologies if this is something I over complicate. >> >> I appreciate your help on this. >> >> *Source: https://docs.microsoft.com/en-us/windows/desktop/Sync/critical-section-objects* >> >> >> Thanks, >> >> Jared >> >> On Wed, Dec 19, 2018 at 9:05 PM Douglas E Engert <dee...@gm... <mailto:dee...@gm...>> wrote: >> >> The OpenSC PKCS#11 relies on the PCSC layer to lock access to the card across multiple applications. >> >> https://github.com/OpenSC/OpenSC/wiki/PCSC-and-pcsc-lite >> >> http://ludovic.rousseau.free.fr/softwares/pcsc-tools/ >> >> https://docs.microsoft.com/en-us/windows/desktop/secauthn/smart-card-and-reader-access-functions >> >> In regards to one application modifying the card while another application is waiting for events, >> the event will contain a SCARD_W_* return. >> >> The application (A) that modified the card in such a drastic way should do a card reset, >> that will cause the the event returned to (B) will cause (B) to start over. >> >> https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/authentication-return-values >> >> Doing do a C_InitToken is like formatting your hard drive. Most applications can not copy with this. >> In other words don't do it while other applications are running. >> >> >> On 12/18/2018 9:06 PM, Bob Backlund wrote: >> > Hi, >> > >> > Just some question about how the OpenSC PKCS# 11 (DLL) handles the multiple applications using it. >> > >> > The scenario is I have two applications, application A and application B loading the same DLL. >> > >> > Application B loops continuously, calling C_WaitForSlotEvent and C_GetTokenInfo, basically it just checks for the insert and remove events from the smart card. >> > >> > Application A can call C_InitPIN and C_InitToken. >> > >> > The conflict happens when, while the application B is checking for smart card events, application A then calls C_InitToken, which deletes the smart card contents, and formats it to be a new >> card, (and >> > possibly deleting the PKCS# 15 objects) and the next call to C_OpenSession fails returning CKR_TOKEN_NOT_PRESENT error. >> > >> > When I try to check the logs, the state of the smart card become ABSENT , I can see this during the C_InitToken, when sc_detect_card_presence is called. >> > >> > When I try to run application A, and call C_InitToken without the application B running, I do not encounter this issue, and the smart card does not become ABSENT but instead I can see from the >> logs >> > that its state become CHANGED. >> > >> > I am not sure if this is the expected behavior or where or how I should handle it. I am not sure if this is also an issue on the OpenSC PKCS# 11 DLL or the smart card. I tried to look at the >> available >> > documentation but couldn't find an answer to this, >> > >> > Your expert opinion is greatly appreciated. >> > >> > >> > Thanks, >> > >> > fightingsibuyas >> > >> > >> > _______________________________________________ >> > Opensc-devel mailing list >> > Ope...@li... <mailto:Ope...@li...> >> > https://lists.sourceforge.net/lists/listinfo/opensc-devel >> > >> >> -- >> Douglas E. Engert <DEE...@gm... <mailto:DEE...@gm...>> >> >> >> >> _______________________________________________ >> Opensc-devel mailing list >> Ope...@li... <mailto:Ope...@li...> >> https://lists.sourceforge.net/lists/listinfo/opensc-devel >> >> >> >> _______________________________________________ >> Opensc-devel mailing list >> Ope...@li... >> https://lists.sourceforge.net/lists/listinfo/opensc-devel >> > -- Douglas E. Engert <DEE...@gm...> |
From: Douglas E E. <dee...@gm...> - 2018-12-29 12:59:07
|
I went back and read your other emails, and have some questions below. On 12/18/2018 9:06 PM, Bob Backlund wrote: > Hi, > > Just some question about how the OpenSC PKCS# 11 (DLL) handles the multiple applications using it. > > The scenario is I have two applications, application A and application B loading the same DLL. > > Application B loops continuously, calling C_WaitForSlotEvent and C_GetTokenInfo, basically it just checks for the insert and remove events from the smart card. > > Application A can call C_InitPIN and C_InitToken. You say you have logs, so I assume you have a driver. You also said you where trying to write your own driver and you were simulation a token. Are you trying tying to simulate the token within OpenSC, without using PCSC? If you are NOT using PCSC to coordinate access from 2 applications you are one your own. OpenSC is expecting PCSC or one of the older reader drivers to do the coordination between applications. > > The conflict happens when, while the application B is checking for smart card events, application A then calls C_InitToken, which deletes the smart card contents, and formats it to be a new card, (and > possibly deleting the PKCS# 15 objects) and the next call to C_OpenSession fails returning CKR_TOKEN_NOT_PRESENT error. Is the failing "next call to C_OpenSession" done by A or B? Or by both? OpenSC will assume the card has not changed much from one session to another and may have cached some info about objects and files on the token in memory. But if it receives a PCSC event that says the card was reset or other error from SCardBeginTransaction (which is done when the sc_lock goes from 0 to > 0) OpenSC will discard any cached data and try to reconnect to the card and reread what is needed from the card, and set not logged_in. These are possible return codes for SCard* routines: https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/authentication-return-values > > When I try to check the logs, the state of the smart card become ABSENT , I can see this during the C_InitToken, when sc_detect_card_presence is called. Lower level logs would show where sc_detect_card_presence got the error. > > When I try to run application A, and call C_InitToken without the application B running, I do not encounter this issue, and the smart card does not become ABSENT but instead I can see from the logs > that its state become CHANGED. What are "ABSENT" and "CHANGED" Are they at the PKCS\#11 level or something internal to to your driver, PCSC or OpenSC? > > I am not sure if this is the expected behavior or where or how I should handle it. I am not sure if this is also an issue on the OpenSC PKCS# 11 DLL or the smart card. I tried to look at the available > documentation but couldn't find an answer to this, Very little OpenSC internal documentation, mostly the code. Have you get your driver to run on Linux? It would eliminate possible issues with DLL "Critical Section" If you think you have found bugs in OpenSC, (and not just your driver) you can open a issue on https://github.com/OpenSC/OpenSC/issues Are you willing to share any logs? Doing this via an open issue would be preferred. If you think the DLL "Critical Section" is incorrect, open an issue. > > Your expert opinion is greatly appreciated. > > > Thanks, > > fightingsibuyas > > > _______________________________________________ > Opensc-devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/opensc-devel > -- Douglas E. Engert <DEE...@gm...> |
From: Frank M. <fra...@gm...> - 2018-12-30 00:35:48
|
We don't need to share a mutex across processes, because we don't share contexts across the process boundaries. Consequently, when initializing the card in process A with a PIN, that PIN doesn't show up in the sc_pkcs15_card_t object of process B if the card was already visible for B. You should never be able to use the newly initialized card in B (without calling C_Finalize()/C_Initialize()). However, calling C_WaitForSlotEvent() and C_GetTokenInfo() from B should not interfere with A initializing the card. This may be a bug within OpenSC. You should check in the logs which APDUs B actually sends while A is initializing. In general, locking in PC/SC should be done based on the command that's issued to avoid interference (sc_lock()/sc_unlock()), which is why A should not be interrupted during pkcs15_initialize() or pkcs15_init_pin(). Whether or not unpowering the card is useful or harming, depends on the card. If you want to get more details, send the logs and show your code. -- Frank Morgner Virtual Smart Card Architecture http://vsmartcard.sourceforge.net OpenPACE http://openpace.sourceforge.net IFD Handler for libnfc Devices http://sourceforge.net/projects/ifdnfc |
From: Douglas E E. <dee...@gm...> - 2018-12-30 13:04:30
|
My interpretation was A initialized the card, but B did not realize that happened. so A needs to force a reset when the initializing is complete. As you point out B could have interfered with the initialization if A did not hold the lock while doing all the initialization steps to keep B from interfering. With out some logs (and it sounds like he is writing a new diver) it is hard to say. On 12/29/2018 6:35 PM, Frank Morgner wrote: > We don't need to share a mutex across processes, because we don't share > contexts across the process boundaries. Consequently, when initializing > the card in process A with a PIN, that PIN doesn't show up in the > sc_pkcs15_card_t object of process B if the card was already visible for > B. You should never be able to use the newly initialized card in B > (without calling C_Finalize()/C_Initialize()). > > However, calling C_WaitForSlotEvent() and C_GetTokenInfo() from B should > not interfere with A initializing the card. This may be a bug within > OpenSC. You should check in the logs which APDUs B actually sends while > A is initializing. > > In general, locking in PC/SC should be done based on the command that's > issued to avoid interference (sc_lock()/sc_unlock()), which is why A > should not be interrupted during pkcs15_initialize() or > pkcs15_init_pin(). Whether or not unpowering the card is useful or > harming, depends on the card. > > If you want to get more details, send the logs and show your code. > -- Douglas E. Engert <DEE...@gm...> |
From: Bob B. <fig...@gm...> - 2019-01-14 09:38:28
|
Hi Douglas and Frank, Thank you for your answer. To answer your questions: 1. Yes, I have my own driver I implemented it based on the existing driver implementation (EnterSafe, ePass2003 and others), it also supports PKCS# 15. 2. I am using PCSC, I used the implementation in version 0.18.0, I did not change anything. 3. Application A is the one that called the C_OpenSession, B just keeps on looping. I see the error on C_OpenSession, CKR_TOKEN_NOT_PRESENT is the error. 4. The PRESENT and ABSENT (sorry for not being clear) is based on the refresh_attributes (reader-pcsc.c), when the SC_READER_CARD_PRESENT is checked. 5. I haven't tried on Linux, I do my test mainly in Windows 8.1. 5. Sorry I cannot share my codes or logs, as of the moment it is pretty messed-up. Most of my changes are only on the driver implementation, (card-*.c, pkcs15-*.c) but I added a lot of logs and commented-out code everywhere. Here's what I tried, because I wanted to isolate the problem. - Application B starts - Application B calls C_Initialize - Application B starts loop with sleep (without calling C_WaitForSlotEvent) - Application A starts - Application A calls C_Initialize - Application A calls C_InitToken - Application A calls C_OpenSession (FAILS, CKR_TOKEN_NOT_PRESENT) - Application A calls C_Finalize - Application A stops - Application B stops loop - Application B calls C_Finalize - Application B stops As you can see it is still the same issue, I tried to debug why the C_OpenSession is returning the CKR_TOKEN_NOT_PRESENT. >From C_OpenSession, the error was returned by slot_get_token (slot.c), from slot_get_token, error was returned by card_detect (slot.c), card_detect is the one the returned the CKR_TOKEN_NOT_PRESENT error, after it get 0 from sc_detect_card_presence (sc.c). The sc_detect_card_presence called pcsc_detect_card_presence (reader-pcsc.c), pcsc_detect_card_presence called the refresh_attributes (reader-pcsc.c) which returned the 0, 0 is actually SC_SUCCESS. It was returned after calling SCardGetStatusChange and it returned SCARD_E_TIMEOUT. When SCARD_E_TIMEOUT is returned, it will remove the SC_READER_CARD_CHANGE from the reader flag and will return SC_SUCCESS. Not also sure, what happened but when I trace the reader state in refresh_attributes, I notice that on Application A the SCARD_STATE_INUSE is always present my guess is it is because of the Application B running in parallel. If I run Application A alone without Application B, the SCARD_STATE_INUSE is sometimes present, and SCARD_STATE_CHANGED is also present. If it doesn't go in line 336 of the refresh_attributes it will be okay. So to fix, modified line 335 to be; if ((rv != SCARD_S_SUCCESS) && (rv != (LONG) SCARD_E_TIMEOUT)) { So that it will always be forced to run the code after the condition in line 335 and check for the SCARD_STATE_PRESENT reader state (line 361). So far the hack is working for my scenario, but I am not sure if it is the correct way to handle it or why it was built that way. I base the line number on the original code here. https://github.com/OpenSC/OpenSC/blob/0.18.0/src/libopensc/reader-pcsc.c I have some additional question still related to multiple application support of OpenSC. Frank mentioned that; * Consequently, when initializing the card in process A with a PIN, that PIN doesn't show up in the sc_pkcs15_card_t object of process B if the card was already visible for B. You should never be able to use the newly initialized card in B (without calling C_Finalize()/C_Initialize()). * Does this mean that on the current implementation of OpenSC, each process that uses the PKCS# 11 module has it's own memory space and does not "share resources"? The reason I ask is because PKCS# 11 standard section 13.2 mentioned that; *Whenever possible, changing the value of an object attribute should impact the behavior of active operations in other applications or threads.* It was also mentioned in section 2 that one of it's goal is the *resource sharing (multiple applications accessing multiple devices), presenting to applications a common, logical view of the device called a “cryptographic token”.* If I wanted to support this, what will be the best way to approach it, create a shared memory or create a dedicated service to sync the sc_pkcs15_card_t object across all applications/processes? Source: https://www.cryptsoft.com/pkcs11doc/STANDARD/pkcs-11v2-11r1.pdf I greatly appreciate your time and patience and I want you to know that I am learning a lot from you. Thanks, Jared On Sun, Dec 30, 2018 at 9:04 PM Douglas E Engert <dee...@gm...> wrote: > My interpretation was A initialized the card, but B did not realize that > happened. > so A needs to force a reset when the initializing is complete. > > As you point out B could have interfered with the initialization if A did > not hold > the lock while doing all the initialization steps to keep B from > interfering. > > With out some logs (and it sounds like he is writing a new diver) it is > hard to say. > > > On 12/29/2018 6:35 PM, Frank Morgner wrote: > > We don't need to share a mutex across processes, because we don't share > > contexts across the process boundaries. Consequently, when initializing > > the card in process A with a PIN, that PIN doesn't show up in the > > sc_pkcs15_card_t object of process B if the card was already visible for > > B. You should never be able to use the newly initialized card in B > > (without calling C_Finalize()/C_Initialize()). > > > > However, calling C_WaitForSlotEvent() and C_GetTokenInfo() from B should > > not interfere with A initializing the card. This may be a bug within > > OpenSC. You should check in the logs which APDUs B actually sends while > > A is initializing. > > > > In general, locking in PC/SC should be done based on the command that's > > issued to avoid interference (sc_lock()/sc_unlock()), which is why A > > should not be interrupted during pkcs15_initialize() or > > pkcs15_init_pin(). Whether or not unpowering the card is useful or > > harming, depends on the card. > > > > If you want to get more details, send the logs and show your code. > > > > -- > > Douglas E. Engert <DEE...@gm...> > > > > _______________________________________________ > Opensc-devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/opensc-devel > |