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

 


Help: OASIS Mailing Lists Help | MarkMail Help

pkcs11 message

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


Subject: Re: [pkcs11] Proposal: Supporting multiple callers in process




On 04/18/13 16:11, Stef Walter wrote:
On 16.04.2013 16:23, Darren J Moffat wrote:


On 04/15/13 14:00, Stef Walter wrote:
There are several issues related to having multiple callers of a PKCS#11
module in a process. I propose we either:

There is also a semi-related set of issues to do with what happens on
fork() that we should also discuss - the fork saftey issues have caused
us more problems on the Solaris/Java boundary than thread safety issues.

Yes, that's certainly a rough area. Do you have any proposals here?
Reconciling threads/fork seems extremely hard to get right in a general
sense. Is there something specific PKCS#11 can do to make this easier?

The current PKCS#11 requirements that everything is invalid on a fork() has been very very painful for us because we have PKCS#11 plugged in underneath the Java JCE and under OpenSSL.

What we currently do in Solaris is use pthread_at_fork() handlers in all our PKCS#11 implementation libraries. Those handlers attempt to clean up all our locks and closed down all the sessions in the fork'ed child. The reason we use pthread_at_fork() is because we don't want to be calling getpid() on the entry to every PKCS#11 API, even where getpid() is a fasttrap rather than a full syscall it is still expensive.

We also have a init/fini calls to set those up and take them down in case the shared library gets loaded/unloaded without proper C_Initalize/C_Finalize calls.

Personally I wish PKCS#11 had said nothing about fork(), UNIX creds don't generally change as a result of doing the fork() but as a result of doing an exec(). It is really exec() that PKCS#11 should have been worried about not fork().

For example most other crypto APIs (say OpenSSL) assume that you can have context structs (a session handle in PKCS#11) on the stack and they are still usable over a fork.

... besides a test suite... :)

We have that for Solaris - quite a big one. Most of the issues we have seen in this area have been very complex deployments. Say some high level java application which ends up doing something that results in a JNI call in another thread that does a fork/exec.

   a) Clarify these issues in the spec so that multiple callers can use
      a token within certain expectations.

I'd rather we do this and where necessary update the spec to allow
things as you have detailed below.

Does making C_Initialize and C_Finalize thread safe seems to require
mutexes that are initialized either statically or on module load.
Obviously the major platforms have no problem with that, but is this
something we can require of everyone?

In Solaris we just chose to not allow the application to supply the locking primitives. Since all processes in Solaris are multi threaded all the time applications just have to deal with the fact that OS level locks are used in system provided libraries.

We do however respect CKF_LIBRARY_CANT_CREATE_OS_THREADS, though in hindsight we shouldn't have respected that either because other system libraries in Solaris that our PKCS#11 libs can call may now create OS threads and there is nothing we can do about it.


Trying to get a sense here if there would be implementation issues.

Proposing that C_Initialize may be called multiple times within a
process without returning CKR_CRYPTOKI_ALREADY_INITIALIZED.

In the Solaris provided libraries and applications that call
C_Initalize() we check for CKR_OK and CKR_CRYPTOKI_ALREADY_INITIALIZED
and treat both as success.

Do you wrap C_Initialize somehow to make it thread safe? We do in
p11-kit as a work around for the current deficiencies.

We just a statically initalised global mutex that we acquire on entry to C_Initalize. There are other lower level locks at the object and session level.

C_Finalize must be called the same number of times before actually
finalizing the token.

Corollary is that C_Initialize and C_Finalize implementations must be
thread safe.

We actually had that implemented for our Solaris libpkcs11 many years
ago, but we removed it before we integrated into Solaris 10 and shipped.
  The reason we removed it is that it wasn't compliant with the spec.

I'd like to see this formalised as being the correct thing to do.

Yes. This would require module implementations to maintain the
initialization count. Not that big a deal, but we need to decide if this
is 2.40 material.

I think at least the reference counting could be 2.40 material.

--
Darren J Moffat


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