As more and more applications and libraries use PKCS#11 we run into a very basic problem. The PKCS#11 modules cannot be initialized and finalized properly without coordination between the various consumers.
An example: An application might use GnuTLS for TLS connections, and use libgcr for display of certificates. Both of these want to load (and initialze) the same PKCS#11 modules. There are many places where this situation occurs, including large applications like Evolution which due to their dependencies end up using both NSS and GnuTLS.
Consumer A loads a PKCS#11 module and uses the module's
C_Initialize function to initialize it, which works as expected.
When consumer B initializes the module (also using C_Initialize),
the error code
is correctly returned. This is normal PKCS#11 specification
defined behavior for when a module is initalized twice in the
same process. If consumer B is aware of this situation they may
choose to ignore this error code.
However when the consumer A is done with its use of the PKCS#11 module it finalizes the module using the module's C_Finalize function. This is expected of a well behaved PKCS#11 consumer. This then causes errors and/or crashes for consumer B, which cannot know that the module has now been finalized out from underneath it.
It is necessary for the two consumers to coordinate their
initialization and finalization in some fashion. In
p11-kit we provide this coordination in a
loosely coupled, backwards compatible, and flexible way.