<?xml version="1.0"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ ]> <chapter xml:id="sharing"> <title>Sharing PKCS#11 modules</title> <section xml:id="sharing-problem"> <title>Multiple consumers of PKCS#11 in a process</title> <para>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. </para> <para>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.</para> <para>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 <literal>CKR_CRYPTOKI_ALREADY_INITIALIZED</literal> 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.</para> <para>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.</para> <para>It is necessary for the two consumers to coordinate their initialization and finalization in some fashion. In <literal>p11-kit</literal> we provide this coordination in a loosely coupled, backwards compatible, and flexible way.</para> </section> <section xml:id="sharing-initialize"> <title>Solution: p11-kit</title> <para><literal>p11-kit</literal> provides functions to coordinate initialization and finalization of any PKCS#11 module. A module may be initialized any number of times using the p11_kit_initialize_module() function. The first time that p11_kit_initialize_module() is called for a module, that module's C_Initialize function is used. Later invocations for the same module cause p11-kit to increment an internal initialization count, rather than calling C_Initialize again.</para> <para>The p11_kit_finalize_module() is used to finalize a module. Each time it is called it decrements the internal initialization count for that module. When the internal initialization count reaches zero, the module's C_Finalize function is called.</para> <para>This is done in a thread-safe manner. These functions can be used on modules that the consumer loads themselves.</para> </section> <section xml:id="sharing-module"> <title>Solution: proxy module</title> <para>When an application is aware of the fact that coordination is necessary between multiple consumers of a PKCS#11 module, it can link to p11-kit and use the functions there to provide this coordination.</para> <para>However most current consumers of PKCS#11 are ignorant of this problem, and do not link to p11-kit. In order to solve this multiple initialization problem for all applications, <literal>p11-kit</literal> provides a proxy compatibility module.</para> <para>This proxy module acts like a normal PKCS#11 module, but internally loads a preconfigured set of PKCS#11 modules and coordinates their initialization and finalization. Each slot in the configured modules is exposed as a slot of the <literal>p11-kit</literal> proxy module. The proxy module is then used as a normal PKCS#11 module would be. It can be loaded by crypto libraries like NSS and behaves as expected.</para> <para>The proxy module bends the PKCS#11 rules slightly. It does not return the <literal>CKR_CRYPTOKI_ALREADY_INITIALIZED</literal> error code as specified in PKCS#11. However this is a small price to pay for this compatibility.</para> </section> </chapter>