Open Bug 271290 Opened 20 years ago Updated 2 years ago

NSS should load an ABI compatible nssckbi

Categories

(NSS :: Libraries, enhancement, P3)

enhancement

Tracking

(Not tracked)

People

(Reporter: david, Unassigned)

Details

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113

If you build an application that contains a mixture of 32-bit and 64-bit binaries,
that all aim to share a single certificate database, the libnssckbi library
mechanism causes a problem:

There is only one pathname used for this library. However, because it must match
the word-size of the host application, it turns out that two libraries are
required: a 32-bit version and a 64-bit version. This is because NSS wants to
find the library in the same directory as the certificate database files.

Suggest that NSS be modified to load the library with a different filename,
for example libnssckbi64.sl in the 64-bit case. This would allow the two
sizes of library to be packaged in the same directory. Alternatively, allow
NSS to load this library from the same directory as the NSS libraries themselves
were loaded (which are by definition the correct type for the host application).






Reproducible: Always
Steps to Reproduce:
1. Install a copy of Netscape Directory Server 7.0 built for 64-bit HP-UX or
Solaris.
2. Fire up the console application.
3. Select the manage certificates task.
4. Observe that there are no CA certs listed. This is because the CGI invoked
underneath this UI is 32-bit, but the Directory server is 64-bit. The 64-bit
copy of libnssckbi is packaged and hence the 32-bit UI fails to load it.
David,
This is by design . The problem is that you are sharing the secmod database,
which contains a list of PKCS#11 modules, of which libnssckbi is only one .
There could be smartcard or accelerator drivers as well.
But there is no rule for finding the name of a PKCS#11 library appropriate for
the word size of the application, so NSS cannot do anything about this.

You will run into the same problem when trying to share secmod databases in a
mozilla profile between different operating systems, and again there is nothing
mozilla or NSS can do to fix it.

I'd like to mark "works as designed", but this option doesn't exist, so marking
WONTFIX.

Status: UNCONFIRMED → RESOLVED
Closed: 20 years ago
Resolution: --- → WONTFIX
I understand that this is 'as designed' I'm saying that the design is broken.

The purpose of this bug is to get the design changed.

Status: RESOLVED → UNCONFIRMED
Resolution: WONTFIX → ---
Status: UNCONFIRMED → NEW
Ever confirmed: true
David,

There is no rule in the PKCS#11 specification for finding a library of a
particular word size. That's what's missing to fix this problem in the general
sense. You could come up with your design and present it to the PKCS#11
committee on the cryptoki list, and if this design is approved, we would
implement it in NSS.

Otherwise, we could only fix this problem for nssckbi itself, which would be a
hack, and it wouldn't work for any of the other PKCS#11 modules. Eg. you would
have a smartcard driver or accelerator driver loaded in 32 bit, but not in 64
bit. I don't think it makes much sense to fix it just for this case. And
renaming the libnssckbi library creates other problems anyway, for the old
applications, so you would have to upgrade both your 32 bit and 64 bit programs
at the same time to the same version of NSS for it to work.
David,  When NSS loads the PKCS11 modules, it first loads the modules 
named in the secmod.db file in the profile directory (the directory that
contains the cert, key, and secmod DBs).  The secmod DB can name the 
PKCS11 modules with 
  - absolute path names
  - relative path names
  - simple file names (in which case, the behaviro is OS dependent, but 
    generally searches for the shared lib in LD_LIBRARY_PATH (or PATH on Win32).
After NSS has loaded (or at least attempted to load) all the modules named
in secmod.db, if it finds that no trust module (module of trusted root CAs)
has been loaded, then it goes and looks in several more places for the 
module, including in the profile directory.  

Note that the content of the escmod.db file is a joint responsibility of
NSS and of the "admin" application.  In many cases, when an application
is not happy with the contents of secmod.db, the solution is for the 
(admin) application to put the contents in that it wants.  

I'd suggest that you try this:  using the modutil tool, modify secmod.db
to contain the simple file name for the nssckbi shared library.  Then 
ensure that your LD_LIBRARY_PATH environment variable (or whatever your 
OS uses) includes the directory that contains the proper platform+size 
shared lib.  That will probably solve the problem.  
Nelson, thanks, this sounds promising. I'd attempted to reverse-engineer
the library loading behavior from the source code, but hadn't appreciated
the full semantics available via secmod.db (I started looking at the place
where we see NSS fail to load the library, and worked backwards, which
in hindsight probably wasn't the right way to approach this).

I'll try futzing with secmod.db and see if it's possible to get the
behavior we're looking for.

Thanks again.

QA Contact: bishakhabanerjee → jason.m.reid
What is the role of this library, and why is NSS looking for it explicitly 
in ./ instead of letting dlopen() find automatically (in LD_LIBRARY_PATH plus 
the OS' standard directories)? 
 
In my Purify tests, I'm seeing failed attempts to dlopen("./libnssckbi.so", 1) 
by all NSS programs. Should not that be dlopen("libnssckbi.so", 1)? 
 
Thanks! 
This library is the one the stores all the root certs.

NSS is looking for it in ./ because that's where the application told it to
look;). If the application does not explicitly load it.

The mixed mode application can solve this problem by with 2 nssckbi's. One is
loaded from the 32-bit directory and one is loaded from the 64 bit directory. As
long as the platform dl_load recognized the difference, then NSS will load the
appropriate version.

I've used the method myself when I had several different *platforms* sharing the
same .db files. Only those modules associated with the existing platform is
loaded and the rest are ignored.

bob
Yes, I think this bug can in fact me marked as invalid because
we were able (eventually) to make the mixed 64-bit/32-bit Directory Server
work properly (by specifying the library path explicitly).

Status: NEW → RESOLVED
Closed: 20 years ago19 years ago
Resolution: --- → INVALID
Target Milestone: --- → 3.11
I'm reopening this, and turning it into an RFE.  It's true that an 
application can (with enough effort) load the right version of nssckbi.
But today, NSS places the burden of getting this right on the application
programmer, and that has resulted in problems for many applications whose
programmers did not fully understand the issues.  Also, relying on 
LD_LIBRARY_PATH doesn't work for programs running as root on some boxes.

We know how to find the nssckbi shared library that is in the same directory
has the rest of the NSS shared libs, and IMO we should use that knowledge to
load nssckbi.  There is already another bug about the same issue for freebl.

So, I'm going to turn this into an RFE, to load nssckbi from the same 
directory as the rest of the currently running NSS shared libs.
Severity: normal → enhancement
Status: RESOLVED → REOPENED
Priority: -- → P2
Resolution: INVALID → ---
Summary: NSS should load a copy of libnssckbi appropriate to its own word-size (32 or 64-bit) → NSS should load an ABI compatible nssckbi
Version: unspecified → 3.10
Assignee: wtchang → saul.edwards.bugs
Status: REOPENED → NEW
Version: 3.10 → 3.3
Implementation should be easier than design.
One tool available now is NSPR now has the ability to fetch the directory that a
given shared library resides in.

The question issue is when does NSS get involved.
Currently NSS only gets involved when there is already no previously specified
builtin root certs in the secmod.db. This allows applications (or actually
*users* to control what builtins are used). Do we really want NSS to load
another nssckbi file if one is already loaded?

There are call setup to detect whether or not a slot is a root cert slot, so
it's fairly easy to detect this case.

Currently if no root cert slot is loaded, NSS looks in the .db directory for a
root cert slot. If one exists, it loads that slot and adds it to secmod.db.

A resonable proposal might be if the root cert slot is not loaded, NSS looks for
a root cert module in the "bin" directory (the same directory that nss3.dll
lives in) and loads that without adding it to secmod.db.

This proposal means that applications which share secmod.db do not get automatic
root cert upgrades when installing newer versions of the app in a different
directory (some will argue this is a 'misfeature' anyway).

It also means applications with existing secmod.db's which have root certs
loaded in them will continue to use the loaded root certs unless the application
intervenes (by deleting the root cert, or upgrading the root cert itself).
Currently this is already the case.

Another proposal could be to ignore any root cert entries in the secmod.db and
always load from the local path. This would break users who have explicitly set
up their own root certs in secmod.db.

bob
Bob: nobody will miss that "misfeature", but I remember
that is implemented in the applications.
If NSS always tries to load libnssckbi from the same location as libnss3, then
how will an application specify that it does *not* want to load libnssckbi ? I
believe this is common in corporate environments, and we must preserve that
behavior for existing applications, which did that by not putting a
libnssckbi.so in the secmod.db directory.
In proposal 1, NSS wouldn't load nssckbi if a root certs slot was already loaded
out of secmod.db.

In proposal 2, that feature would not work (I don't particularly like proposal
2, but I suspect there may be some proponents out there -- julien's observation
is the particularly nasty part of proposal 2).

bob
Bob,

Actually, we already have an NSS_INIT_NOROOTINIT flag for NSS_Initialize, so
perhaps we can just reuse that. But not all NSS initialization APIs can take
flags currently ...
> A resonable proposal might be if the root cert slot is not loaded, NSS 
> looks for a root cert module in the "bin" directory (the same directory 
> that nss3.dll lives in) 

That is the very essence of this bug/rfe.

> and loads that without adding it to secmod.db.

That could also be part of the solution.

The full problem that needs to be solved is to enable multiple applications
that have differen ABIs to share the DB files in a common "config" directory.  

Today, that is difficult because NSS looks for ABI-dependent information in 
the config directory.  It looks for the ABI-dependent nssckbi shared lib there.
There is one secmod.db there, which contains pathnames of ABI-dependent PKCS11
module shared libs.  The only way to make this work today is to place only 
simple file names for shared libs in nssckbi (no path names), and then rely
on each application to have an LD_LIBRARY_PATH appropriate to its own ABI.

The LD_LIBRARY_PATH-dependent scheme would be complete solution, except for 
the fact that some unixes disable LD_LIBRARY_PATH for root (or setuid root) 
processes.  

I'm nto yet sure of the complete solution for ABI-dependent secmod.db files,
but I'm pretty sure that looking for the nssckbi shared lib in the CODE 
directory (where the rest of the NSS libs live) rather than in the DATA
directory is part of the solution.
Bob, your "reasonable proposal" (is that proposal #1 or #2?) suggests that 
we would load the root cert module "without adding it to secmod.db."  
I agree that that is a necessary part of the solution (at least for mozilla 
clients).

Question: how is that done?  How does one load/init a module without adding
it to the secmod.db?

I think we're talking about the following stack:
  nss_Init ->
   nss_FindExternalRoot ->
    SECMOD_AddNewModule -> SECMOD_AddNewModuleEx ->
     SECMOD_AddModule ->
      SECMOD_AddPermDB ...

I don't see any option to any of those functions that says "load it but 
don't add it to the secmod.db".  
Saul and I are considering implementing the first part of the proposal Bob
called the "reasonable proposal", using logic very similar to that used in
NSS 3.10.2 to load the freebl shared lib, but using it in function 
nss_FindExternalRootPaths (in lib/nss/nssinit.c) to find nssckbi.<whatever>.  

Saul if you have a patch for that function, please attach it to this bug.  

But we still need to solve the issue of not adding the found path to the 
secmod.db, as discussed in the previous comment.  

Nelson, I believe the functions you are looking for are
SECMOD_LoadUserModule and SECMOD_UnloadUserModule.
re: Comment #16

nssFindExternaRoot is an internal NSS call. Proposal #1 would change the call
from calling SECMOD_AddNewModule to SECMOD_LoadUserModule or
SECMOD_LoadModule(). The former is callable by external NSS users, the latter
takes a module structure (like SECMOD_AddModule) and is callable inside NSS.
QA Contact: jason.m.reid → libraries
Assignee: saul.edwards.bugs → nobody
Priority: P2 → P3
Target Milestone: 3.11 → ---
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.