Sharing PKCS#11 modules: p11-kit

# Sharing PKCS#11 modules

## Multiple consumers of PKCS#11 in a process

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 initialize) 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 `CKR_CRYPTOKI_ALREADY_INITIALIZED` is correctly returned. This is normal PKCS#11 specification defined behavior for when a module is initialized 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.