Closed Bug 1782980 Opened 2 years ago Closed 1 year ago

RFE: fall back to internal token when changing trust (certutil)

Categories

(NSS :: Tools, enhancement)

3.81
enhancement

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: rcritten, Assigned: rrelyea)

Details

Attachments

(1 file)

The general algorithm of AddCert is:

  • load the cert
  • validate the incoming trust string
  • PK11_ImportCert()
  • If above fails with SEC_ERROR_TOKEN_NOT_LOGGED_IN call PK11_Authenticate() on the slot and try again
  • CERT_ChangeCertTrust()
  • If above fails with SEC_ERROR_TOKEN_NOT_LOGGED_IN call PK11_Authenticate() on the slot and try again

I'm primarily interested in the trust change. Because trust is stored directly in the NSS database and not on PKCS#11 token we don't need to authenticate to the PKCS#11 token, but to the NSS database. The issue is that when SEC_ERROR_TOKEN_NOT_LOGGED_IN is raised certutil tries to log into the same slot again (for perhaps the third time).

I think it should instead authenticate to the softokn where the write will actually take place.

This is what I'm proposing:

diff --git a/nss/cmd/certutil/certutil.c b/nss/cmd/certutil/certutil.c
index 16a9bf1..6b1499e 100644
--- a/nss/cmd/certutil/certutil.c
+++ b/nss/cmd/certutil/certutil.c
@@ -153,13 +153,16 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
rv = CERT_ChangeCertTrust(handle, cert, trust);
if (rv != SECSuccess) {
if (PORT_GetError() == SEC_ERROR_TOKEN_NOT_LOGGED_IN) {

  •            rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
    
  •            PK11SlotInfo *internalslot;
    
  •            internalslot = PK11_GetInternalKeySlot();
    
  •            rv = PK11_Authenticate(internalslot, PR_TRUE, pwdata);
               if (rv != SECSuccess) {
                   SECU_PrintError(progName,
                                   "could not authenticate to token %s.",
    
  •                                PK11_GetTokenName(slot));
    
  •                                PK11_GetTokenName(internalslot));
                   GEN_BREAK(SECFailure);
               }
    
  •            PK11_FreeSlot(internalslot);
               rv = CERT_ChangeCertTrust(handle, cert, trust);
           }
           if (rv != SECSuccess) {
    

certutil can support multiple token passwords passed in with "-f" option via SECU_FilePasswd() which takes the slot to find the password for.

If the provided password file consists of something like this:

mypkcs11_token:SecretPassword
NSS Certificate DB:Password

Then all needed credentials are available to certutil so the cert can be added to the PKCS#11 token and trust can be added to the softokn.

The softokn name is configurable by the application via PK11_ConfigurePKCS11() and may also be different depending on whether FIPS is enabled so this is an exercise for the user to figure out what token to use. The output error will help in this regard.

This same pattern can be applied elsewhere in certutil in at least ChangeTrustAttributes.

The patch looks good, though I wonder if we shouldn't move this into CERT_ChangeTrust() itself. The slot should be accessible from the cert, but I don't know if the passwordArg is.

This is certainly better than the existing code, however.

bob

Attachment #9291365 - Flags: review?(rrelyea) → review+

Adding a needinfo. This patch still needs to be checked in.

Assignee: nobody → rrelyea
Status: NEW → ASSIGNED
Flags: needinfo?(rrelyea)

Firefox also implements this https://searchfox.org/mozilla-central/source/security/manager/ssl/nsNSSCertificateDB.cpp#165-193. So I agree with Bob that we should probably expose this as a (new) library function.

Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Flags: needinfo?(rrelyea)
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: