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.
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.
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.
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"
Addition to bug description: After the import, the CA cert appears in section "web site certificates" of certificate manager.
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.