libp11 requires successful logout before successful login

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

libp11 requires successful logout before successful login

Anthony Foiani

I found an interesting buglet in my particular combination of raw
libp11 + openssl / engine_pkcs11 / libp11, all on top of opensc /

First, a bit of background: I'm implementing a data recorder which
uses a USB crypto token to sign log files as they are acquired.  The
user interface allows for a "stored PIN" (which is persistent across
reboots and removal/insert cycles) or "one-time PIN" (which, as the
name applied, is used only the one time it is submitted, and not

In the process of experimenting with different one-time PINs, and
seeing how it reacted when an invalid PIN was entered followed by a
valid PIN, I discovered that I only ever got one successful login per
insertion cycle.

After a bit of debugging, it turns out that my patches to reduce
memory leakage when using keys through engine_pkcs11 [1] had a rather
nasty side-effect: when one frees the key, it invalidates all sessions
on that token.  (The list of sessions is kept in a static variable in
the shared library, so if a single application uses
the library through two different paths, it still shares that list of
sessions -- at least on Linux.)

Then, when I go to log in through "raw" libp11 again, it complains
because my session is invalid.  To make a long story short(er), the
critical code is in PKCS11_login:

Which calls PKCS11_logout.  The actual error I encountered is from line 181:

But the final failure is due to the fact that
doesn't know that the underlying session got clobbered (through engine_pkcs11).

After that point, my session is invalid, and the call at

Fails, as does my entire login attempt.

I can work around this in client code by mucking with the private
per-slot state like so:

        pkcs11_slot_private * priv =
          static_cast< pkcs11_slot_private * >( m_pUsedSlot->_private );

        if ( priv->haveSession )
            priv->loggedIn = 0;
            priv->haveSession = 0;

But that's *horrible*.

I suspect the correct answer is to update libp11 to make the logout
failure non-fatal, or to otherwise uncouple the login attempt from a
(possibly stale) state.

engine_pkcs11 already acknowledges a related problem; its comments on
logged-in state and PINs is:

/* Login successful, PIN retained in case further logins are
  required. This will occur on subsequent calls to the
  pkcs11_load_key function. Subsequent login calls should be
  relatively fast (the token should maintain its own login
  state), although there may still be a slight performance
  penalty. We could maintain state noting that successful
  login has been performed, but this state may not be updated
  if the token is removed and reinserted between calls. It
  seems safer to retain the PIN and peform a login on each
  call to pkcs11_load_key, even if this may not be strictly
  necessary. */

If I get a chance to make a patch, I'll try to do so.  If I don't,
however, I wanted to post this report so that we have a record of the

(An alternate approach would be to remove the need for raw libp11
access; in my case, that would require some way of obtaining a list of
certificates and keys on the device through the engine_pkcs11
interface.  The engine_pkcs11 code traverses all the certificates, but
there is no method published for getting that list through the openssl
engine interface.)

Best regards,
Anthony Foiani


See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
Opensc-devel mailing list
[hidden email]