Issue with current PKCS#11 support

Thomas Calderon calderon.thomas at
Mon Apr 13 12:06:39 UTC 2015


Thank you for describing the impersonation mechanism.
However, stating "find a better PKCS#11 provider" is not the way to go.
It seems you are making wrong assumptions related to the PKCS#11 standard,
"fork" related behaviour (section 6.6.1) is described as follows:
"In general, on most platforms, the previous paragraph means that an
application consists of a single process. Consider a UNIX process P
which becomes a Cryptoki application by calling C_Initialize,
and then uses the fork() system call to create a child process C.
Since P and C have separate address spaces (or will when one of them
performs a write operation, if the operating system follows the
paradigm), they are not part of the same application. Therefore, if C needs
to use Cryptoki, it needs to perform its own C_Initialize call. Furthermore,
if C needs to be logged into the token(s) that it will access via Cryptoki,
it needs to log into them even if P already logged in, since P and C are
completely separate applications. In this particular case (when C is the
child of a process which is a Cryptoki application), the behavior of
Cryptoki is undefined if C tries to use it without its own C_Initialize
Ideally, such an attempt would return the value
however, because of the way fork() works, insisting on this return value
might have a
bad impact on the performance of libraries.
Therefore, the behavior of Cryptoki in this situation is left undefined.
Applications should definitely not attempt to take advantage of any
"shortcuts" which might (or might not!) be available because of this.
In the scenario specified above, C should actually call C_Initialize whether
or not it needs to use Cryptoki; if it has no need to use Cryptoki, it
then call C_Finalize immediately thereafter.
This (having the child immediately call C_Initialize and then
C_Finalize if the parent is using Cryptoki) is considered to be good
Cryptoki programming practice, since it can prevent the existence of
duplicate resources that were created at the time of the fork() call;
it is not required by Cryptoki."

Now, assuming a PKCS#11 provider provides a shortcut to re-initialize
resources across a fork is a wrong assumption since the behaviour is left
undefined. Furthermore, in most cases and given my experience with PKCS#11,
you have to re-initialize the whole library (i.e., login again, find
objects, etc).

Is there no better way to handle this case in nginx ?


Thomas Calderon

On Fri, Apr 10, 2015 at 12:30 PM, Dmitrii Pichulin <pdn at> wrote:

> This is a common behavior for security providers that do not have own
> service running, which can handle objects globally.
> nginx loads private keys once then forks then impersonates to user in
> config (if set).
> In your case, it seems that your PKCS#11 library does not support a fork
> or a user change.
> You can try to run nginx and its worker processes by the same user (
> Or you can try to find a better PKCS#11 provider.
> On 10.04.2015 13:00, Thomas Calderon wrote:
>> Hi,
>> I just tried nginx PKCS#11 support that was introduced in 1.7.9.
>> In a Debug/Test environment I have a working setup. Namely, using
>> "daemon off" and the instructions provided on the mailing list, I manage
>> to establish a TLS connection using my token.
>> However, when using "daemon on", a client connection spawn the
>> worker_process, the PKCS#11 library gets reloaded. However, the PKCS#11
>> context is lost, hence the TLS connection cannot be established (further
>> function fails since the library is not initilized, objects handles are
>> not valid anymore, etc).
>> Given the stack used to leverage PKCS#11 support
>> (OpenSSL->engine_pkcs11->...), I am not sure how to fix this.
>> Did you observe the same behavior ?
>> Cheers,
>> Thomas Calderon
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the nginx-devel mailing list