On 2009-09-27 07:10 PDT, Guenter wrote:

> very interesting since exactly NSS_INIT_COOPERATE was the reason in first  
> place why I've posted here ...

The PKCS#11 API standard defines two functions, C_Initialize & C_Finalize
in such a way that makes it difficult for two independent libraries running
in the same process to both use a common PKCS#11 module.  If both try to
initialize a module, the second will get an error.  When the first of
them finalizes the module, it finalizes the module for both.  Essentially,
the only way for multiple libraries (or bodies of code) running in a
process to share a PKCS#11 module is for them to cooperate, and have one
of them be responsible for initialization and finalization, and the others
just "go along for the ride".

NSS_INIT_COOPERATE tells NSS to just "go along for the ride".  It tells
NSS_Init to try to initialize any PKCS#11 modules, but if that fails with
the "already initialized" error, just ignore that error.  NSS remembers
that flag, and later, when NSS_Shutdown is called, it does NOT call
C_Finalize.  The idea is that NSS_INIT_COOPERATE tells NSS that some other
library is going to control the initialization and finalization of a
PKCS#11 module, so NSS should not forcefully finalize it.

To use this correctly, the application must ensure that some other code
initializes the PKCS#11 module, then NSS is initialized, and at shutdown
time, first NSS is shut down, then the other code is shutdown, and that
other code finalizes the PKCS#11 module.  There are some (few) circum-
stances where this is feasible, but there are many more where it is not.

> can you perhaps explain a bit more about why its deprecated, 

When this flag is set, there is NO WAY to get NSS to call C_Finalize on the
PKCS#11 modules it is using.  But it is essential that C_Finalize get
called on PKCS#11 modules at various times for various purposes.
C_Finalize is what causes any buffers to be flushed and files to be closed.

But more importantly, on Unix/Linux systems, the PKCS#11 standard forbids
children from using modules that were inherited in an initialized state
from their parent via fork.  That effectively means that prior to every
fork, every PKCS#11 module must be finalized, and after every fork, if
the parent needs to continue to use the module, the parent must
re-initialize it, and any new children who need it must initialize it.

It is possible to do this and get it right in some circumstances, but
unfortunately, we've seen numerous cases of application programmers who
used it incorrectly.

Perhaps it is fair to say that it is deprecated because few application
programs have ever used it correctly, and those who do not tend to blame
NSS for their problems.  We're discouraging all but the best from using
it.  But it's still supported, and I don't think it will go away soon.

> and what to use now?

Another related issue is when two libraries inside a process want to use NSS
independently of each other.  It's the same problem as the PKCS#11
API has.  They both want to initialize NSS.  They both want to shut down
NSS.  The first one to shut down pulls NSS out from under the other.

We're working on new variants of NSS_Initialize and NSS_Shutdown to
solve this problem.  They may be in the next release of NSS.  See
https://bugzilla.mozilla.org/show_bug.cgi?id=453495
-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to