Open mihaicristiantanase opened 1 year ago
If I remove the first PKCS11_login call , I get a successful key pair generation.
From what I found, the second call to PKCS11_login finds the user already logged in, even though a new session was created for read-write operations (PKCS11_open_session) in the mean time.
If I remove the first PKCS11_login call , I get a successful key pair generation.
And if I were to insert a PKCS11_logout just before the second PKCS11_login, the operation is also successful.
With pure PKCS11 an application can have multiple session to the same slot. C_login takes a session parameter, and changes the session state CK_STATE from CK_RO_xxx to CK_R_xxx. There are 5 possible session states. When used with a smartcard which in , C_Login is also used to change the state on the smart card and which may have a user pin and an SO pin.
(If I am reading the code correctly) https://github.com/OpenSC/libp11/blob/master/src/p11_slot.c#L220
libp11_login will create a session if one is not found for CKU_USER or CKU_SO. In your case PKCS11_login(slot, 0, passwd);
will create a CK_RO_USER at line 320 and the C_Login at line 324 will convert it to a RW session.
So somehow it is getting confused because you first ask it to login and create a session, then create a new session and then do the login.
If you really want to see what PKCS11 calls are being made see OpenSC SPY: https://github.com/OpenSC/OpenSC/wiki/Using-OpenSC
I've just finished a step by step debugging with LLDB and it shows that the problem is in the second call to PKCS11_login which finds the client already logged in and it skips everything else: https://github.com/OpenSC/libp11/blob/dd0a8c63c0311674cabfd781753e8374ff531409/src/p11_slot.c#L227
To me, this looks to be like a bug in PKCS11_open_session
which invokes
https://github.com/OpenSC/libp11/blob/dd0a8c63c0311674cabfd781753e8374ff531409/src/p11_slot.c#L110
Shouldn't this function reset the login state?
Or maybe there should be a more complex mechanism that handles login state per session (not a session independent flag like it is at the moment: slot->logged_in
). This might be the cause of confusion that you mentioned in the previous comment...
(lldb) r
Process 8269 launched: 'open-session-and-login' (x86_64)
Process 8269 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003bfb open-session-and-login`runSimplifiedTest(lib="/usr/local/lib/libeToken.dylib", passwd="00000000") at open-session-and-login.c:103:15
100 PKCS11_login(slot, 0, passwd);
101
102 PKCS11_open_session(slot, 1);
-> 103 PKCS11_login(slot, 0, passwd);
104 PKCS11_generate_key(slot->token, 0, 2048, "test_label", (unsigned char*)"testid", 6);
105 if (ERR_peek_last_error()) {
106 fprintf(stderr, "Generated errors:\n");
Target 0: (open-session-and-login) stopped.
(lldb) s
libp11.3.dylib was compiled with optimization - stepping may behave oddly; variables may not be available.
Process 8269 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
frame #0: 0x0000000100131cf0 libp11.3.dylib`PKCS11_login(pslot=0x000000010060a8d0, so=0, pin="00000000") at p11_front.c:171:30 [opt]
168
169 int PKCS11_login(PKCS11_SLOT *pslot, int so, const char *pin)
170 {
-> 171 PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
172 if (check_slot_fork(slot) < 0)
173 return -1;
174 return pkcs11_login(slot, so, pin);
Target 0: (open-session-and-login) stopped.
(lldb) n
Process 8269 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x0000000100131cf4 libp11.3.dylib`PKCS11_login(pslot=0x000000010060a8d0, so=0, pin="00000000") at p11_front.c:172:6 [opt]
169 int PKCS11_login(PKCS11_SLOT *pslot, int so, const char *pin)
170 {
171 PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
-> 172 if (check_slot_fork(slot) < 0)
173 return -1;
174 return pkcs11_login(slot, so, pin);
175 }
Target 0: (open-session-and-login) stopped.
(lldb)
Process 8269 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x0000000100131d00 libp11.3.dylib`PKCS11_login(pslot=<unavailable>, so=0, pin="00000000") at p11_front.c:174:9 [opt]
171 PKCS11_SLOT_private *slot = PRIVSLOT(pslot);
172 if (check_slot_fork(slot) < 0)
173 return -1;
-> 174 return pkcs11_login(slot, so, pin);
175 }
176
177 int PKCS11_logout(PKCS11_SLOT *pslot)
Target 0: (open-session-and-login) stopped.
(lldb) s
Process 8269 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
frame #0: 0x0000000100130e50 libp11.3.dylib`pkcs11_login(slot=0x000000010060a550, so=0, pin="00000000") at p11_slot.c:221 [opt]
218 * Authenticate with the card.
219 */
220 int pkcs11_login(PKCS11_SLOT_private *slot, int so, const char *pin)
-> 221 {
222 PKCS11_CTX_private *ctx = slot->ctx;
223 CK_SESSION_HANDLE session;
224 int rv;
Target 0: (open-session-and-login) stopped.
(lldb) n
Process 8269 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x0000000100130e64 libp11.3.dylib`pkcs11_login(slot=0x000000010060a550, so=0, pin="00000000") at p11_slot.c:226:22 [opt]
223 CK_SESSION_HANDLE session;
224 int rv;
225
-> 226 if (slot->logged_in >= 0)
227 return 0; /* Nothing to do */
228
229 /* SO needs a r/w session, user can be checked with a r/o session. */
Target 0: (open-session-and-login) stopped.
(lldb) p slot->logged_in
(int8_t) $0 = '\0'
(lldb) c
Process 8269 resuming
Generated errors:
4295917056:error:81082101:PKCS#11 module:func(130):User not logged in:p11_key.c:322:
Process 8269 exited with status = 0 (0x00000000)
You can submit a PR if you think this is important.
Sure, I can do that. A workaround (without fully understanding the interaction between a session and the login status) I was thinking about is to simply reset the login state whenever a new session is opened. But, before doing any changes, can you clarify the following?
@mtrojnar any comments on this?
I have an issue with key pair generation. This simplified code:
shows the following error: 4407954944:error:81082101:PKCS#11 module:func(130):User not logged in:p11_key.c:322: