Re: Question about multiple applications
Bob Backlund <[email protected]> Mon, 14 Jan 2019 17:35:10 +0800
| Newsgroups | gmane.comp.encryption.opensc.devel |
|---|---|
| Message-ID | <CAC+xjZrkedsXKovGd0LWX409tUMDFiWiP5g+_qRp7zSvnrt3-g@mail.gmail.com> |
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 <[email protected]> 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 <[email protected]>
>
>
>
> _______________________________________________
> Opensc-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/opensc-devel
>
_______________________________________________
Opensc-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensc-devel