Closed Bug 101616 Opened 23 years ago Closed 23 years ago

root CA lost and untrusted after importing personal cert

Categories

(Core Graveyard :: Security: UI, defect, P1)

1.0 Branch
x86
Windows NT

Tracking

(Not tracked)

VERIFIED FIXED
psm2.2

People

(Reporter: nelson, Assigned: KaiE)

Details

Using 6.1 Build ID 2001091703,
1. setup a new profile
2. setup a password for the software security device
3. imported a PKCS#12 user cert (AOL employee cert, previously exported from
Communicator
Looked at cert in cert manager.  The "verified" column says false.
As I understand it, this means the cert chain verification failed, 
probably due to trust issues.
This will be a major issue for users who routinely import their certs.

By opening the Cert Viewer, I can see my user cert, the intermediate CA cert
that issued my cert, and the root CA cert.
But in the "Cert manager" Autherities tab, the root CA is not shown.  
The intermediate CA cert appears, but not the root CA cert.
This is related to bug 100386, which also provides a workaround.
If you fist import the intranet CA chain before restoring your personal cert
you're in better shape.  What you then have to do (because of 100386) is to go
and manually edit the root trust setting, and then the personal cert does validate.

This bug is much nastier in that after following Nelson's instructions, there is
no obvious way to get the personal cert to validate.

I'm going to try to see whether deleting the personal cert, the CA cert, and
following the procedure to reproduce 100386 allows one to get the personal cert
to validate.
Assignee: ssaux → javi
Priority: -- → P1
Target Milestone: --- → Future
deleting the personal cert and the CA cert and importing the CA cert first then
the personal cert allows one to go and edit the edit of the root.

Another workaround is to edit the trust of the non-root CA.
Adding relnote keyword.
Keywords: relnote
Playing with the cert manager window shows, that before the cert is imported,
the root CA is already present and trusted, stored in the builtin object token.

Importing the p12, and switching to the authorities tab immediately (without
closing cert manager first), the root CA is still there, but it is now stored in
the software security device and the trust has gone.

When you close cert manager and reopen it, the root CA is no longer present.

I assume importing the p12 file (including some CA certs), hides or overwrites
the build root CA cert. The new (identical) one get's placed in the temp cert db
only. During the import process, while the cert manager is open, the imported
CAs are still referenced by the cert manager. Once this window closes the last
reference count is decremented and the cert discarded from memory.

If is correct what I assume, we have a bug in the cert import code. For each
cert found, the code should check whether this newly seen cert is already
present somewhere, and not try to store it, but ignore it.

The application code that does the import is in nsPKCS12Blob::ImportFromFile,
which can currently be found at
http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsPKCS12Blob.cpp#118
The file reading code is in nsPKCS12Blob::inputToDecoder, currently at
http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsPKCS12Blob.cpp#462

While the above code mostly just calls some NSS functions to decode the PKCS#12
file, there is an application callback function given that influences the
"nickname collision" case, which might the location of our problem.
This function is nsPKCS12Blob::nickname_collision, at
http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsPKCS12Blob.cpp#577
As I think this could have to do with the NSS internal code that does the
PKCS#12 import, I'm CC'ing relyea.
target->2.2
Target Milestone: Future → 2.2
Keywords: relnote
This appears to be a bug in the NSS implementation of PKCS#12.

PSM simply calls SEC_PKCS12DecoderImportBags to import all of the data in the
PKCS #12 blob.  One or more of those bags will contain the chain of certs.  NSS
imports them into cert db with no trust info.  So when it goes to verify the
chain later, it finds the root in the cert db and verification fails.  NSS needs
to give us an API where we can tell it what PK11 slot to use for root
certificates or check itself that a certificate in a bag isn't already in the
default root modules slot.

This bug could be changed to "PSM doesn't show a root certificate from the Built
ins module if it is marked untrusted in the cert7.db" 
nsbeta1
Keywords: nsbeta1
kai
Assignee: javi → kaie
Addition to bug description: After the import, the CA cert appears in section
"web site certificates" of certificate manager.
Status: NEW → ASSIGNED
that's right. How lovely, isn't it.
I think this is a NSS bug, as Javi said already.

I traced the import. The pkcs#12 decoder creates safebags. I think the problem
is caused by those safebags not having the correct flags set.

We are importing a pkcs#12 file that has a user key/cert and the CA cert(s).

From the user's perspective, it seems the root CA cert contained in the p12 file
is already known. It is contained in the builtin object token.

The importing code calls sec_pkcs12_install_bags. This function checks for an
attribute "installed" of the decoded safebags. For the CA certs (coming from p12
file), this flag is not set. And this results in sec_pkcs12_add_cert being
called. This function calls CERT_ImportCerts (at least for those where no key is
imported from the p12 file).

Function CERT_ImportCerts is called with flags "keepCerts" (to store them in the
perm db I think), and "not caOnly", i.e. the code requests certs from the p12
file, which are not CA certs, and don't have a private key, should be stored, too.

The call chain continues to arrive CERT_SaveImportedCert, with a usage set to
certUsageUserCertImport.

For the tested p12 file, I see the following certs contained in safebags, which
are being processed:

First, a cert with nickname "Intranet Certificate Authority - GTE Corporation"
is processed.
This is a new cert. It get's imported, which is fine.

Next, a cert with nickname "GTE CyberTrust Root CA" is processed. This is the
cert that later shows the mad behaviour. This is the one that is already stored
in the NSS builtin object token.

When this cert arrives at CERT_SaveImportedCert, it is tested for the
CERT_IsCACert property. But the result says "this is not a CA certificate".

As a result, the function imports the certificate using the "not a CA" codepath,
and adds the CERTDB_VALID_PEER attribute to trust.sslFlags.

I think we have two problems here.

First, why is this cert shown as not being a CA?

Second, how comes NSS tries to import this CA cert at all? For my understanding,
the p12 import code should iterate over the builtin object token and detect that
is in the builtin object token, and no attempt should be made to import it.

Two functions that seem to be involved, and might lack iterating over the
builtin object token, are:
- sec_pkcs12_get_existing_nick_for_dn
- sec_pkcs12_certs_for_nickname_exist

NSS team, can you help us?
cc'ing wtc, suggesting move of this bug to NSS
The export feature may incorrectly create the cert  in the p12 file.  The p12
file I have that causes this behavior was created using moz.

Shouldn't NSS always check to see if the cert is not already somewhere? This
should include temp and perm soft db, builtins, and any hardware token already
installed.
There's a similiar bug with S/MIME as well. The problem is the certificates read
out from the built-in module are temporary certs. If the certs in the cert DB
already has trust bits set, then the built-in suggested trust values are not
used (the certDB overrides). What was supposed to happen was that when you
imported the cert, it would pick up the trust bits that the build-in module
presents. What actually happens is the import code ignores the cert's own trust
values since the cert is a temp cert, and stores it into the database with trust
values that are '0' (which means the cert is not explicitly trusted). This is
yet another example of what we are trying to fix in 3.4. Hopefully I'll get the
landing done this week and we can start integrating PSM. I'm sure we'll have a
bunch of new weird problems and I'd like to be able to look at those as soon as
possible.

bob
ok. I think that means we'll delay working on this bug until NSS 3.4 has landed.
Now that NSS 3.4 has landed, we should retest this bug.

Marking fixed with the 2/12 Win2000 trunk build.
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Verified.
Status: RESOLVED → VERIFIED
Product: PSM → Core
Version: psm2.1 → 1.0 Branch
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.