OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

pkcs11-comment message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Re: [pkcs11-comment] PKCS#11 Usage Guide vs. POSIX issue


On 10 May 2015 at 11:55, Woodhouse, David <david.woodhouse@intel.com> wrote:
> It has come to my attention that the PKCS#11 Usage Guide is making a
> recommendation which triggers POSIX-undefined behaviour.
>
> The recommendation in question is §2.5.2 of the Usage Guide:
> http://docs.oasis-open.org/pkcs11/pkcs11-ug/v2.40/cn02/pkcs11-ug-v2.40-cn02.html#_Toc406759987
>
> It says that it is good Cryptoki programming practice to call
> C_Initialize() again "immediately" in the child process after fork().
>
> This has been implemented in some cases by using a pthread_atfork()
> child handler and directly calling C_Initialize() from it, for any
> PKCS#11 providers which were loaded in the parent.

The context that I've come across this problem is when using an intermediate
library in between the application layer and the PKCS#11 implementation.

Consider, for example, a forking webserver which uses PKCS#11 only through
OpenSSL having been configured to use engine_pkcs11, or a similar situation.

The application calls fork(), and the author of the application knows nothing of
PKCS#11, so the application doesn't call C_Initialize. So the library that calls
C_Initialize in the first place has to call it again after fork, but doesn't have any
control over when fork is called.

So either the OpenSSL layer has to have every API call that might use the engine
check to see whether getpid() still returns the same value it did before, presumably
exactly what the authors of the bit of PKCS#11 that says "Ideally, such an attempt
would return the value CKR_CRYPTOKI_NOT_INITIALIZED; however, because of
the way fork() works, insisting on this return value might have a bad impact on the
performance of libraries" were trying to avoid, or it needs to be notified whenever a
fork happens - which pthread_atfork does.

However, it isn't necessary for the pthread_atfork handler to call
C_Initialize, it can simply set a flag which is cheap to check later
(or can just be ignored in the "immediate exec()" case).


> My personal preference might be to add a short paragraph warning that
> POSIX effectively forbids the child process from calling *any* functions
> of a PKCS#11 provider after fork() from a multi-threaded program, and
> also to recommend that C_Initialize() should *only* be called if the
> child process is going to be long-lived rather than immediately exiting
> or executing something else.

I'd support that. As far as I can tell, the only really safe way to combine
threads and fork is to use only one or the other; the main thread which is
going to fork should ensure that all other threads have been ended before
forking, and restart any needed threads afterwards.
(It may be possible to use pthread_atfork to help with that, but it's not easy.)

Note that the example usage above is single threaded; other pthread functions
aren't used.

I would add a recommendation that applications that fork, or libraries which
call C_Initialize that may be used by forking applications, should set
CKF_LIBRARY_CANT_CREATE_OS_THREADS.

--
alan.braggins@gmail.com
http://www.chiark.greenend.org.uk/~armb/


[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]