Closed Bug 244907 Opened 21 years ago Closed 21 years ago

NSS needs to handle unprotected keys in tokens.

Categories

(NSS :: Libraries, enhancement, P2)

3.9.1
enhancement

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: rrelyea, Assigned: rrelyea)

References

Details

Attachments

(1 file, 2 obsolete files)

Currently NSS believes all private keys in all tokens are protected if the token itself has a password. It is possible, however, for tokens to contain 'public' private keys, where the private key is not access controlled. NSS needs to be able to find and use these keys without require the user (or application) to provide a pin. These keys are already marked in PKCS #11 with the CKA_PRIVATE attribute set to FALSE.
Patch information: There are 2 different types of changes in this patch. 1) Changes to authentication before looking up Private keys. These changes are those made in pk11cert.c. They delay the PK11Authenticate call if the token is 'Friendly' even when looking for private keys. Most tokens hide private objects until the token is authenticated, therefore if we do not find any private keys, we need to authenticate and try again. NOTE: if there is no private key on the token, this code takes now takes 2 tries to determine this, even in the case were the token was authenticated before hand. It might be worth adding the extra complexity to read the current authentication state and not do the second find if the token was already authenticated. 2) Check the CKA_PRIVATE flag before forcing Authentication operations when doing private key operations. These changes are in pk11skey.c Just before we do some operation on the private key, we make a call 'PK11_HandlePasswordCheck'. This function differs from PK11_Authenticate in that it handles the application configured password options. The application can configure NSS to require the password/pin be reentered every time the key is used, or reentered after a certain timeout time. PK11_Authenticate() only caused a authentication on a token that needs authentication, but has not been authenticated yet. PK11_HandlePasswordCheck() also enforces the application's password requirements. These changes make will make the applications configured options a no-op for keys that are considered public. bob
I'm submitting these for review now. One issue to consider is the way CKA_PRIVATE is checked. If CKA_PRIVATE is not available (the PKCS #11 module is non-standard), then the code currently treats this as 'FALSE'. In this case the "ask every" or "timeout" options will erroneously not be active for this key. If the key is also visible without a password, NSS may not automatically authenticate before using the key. This could be fixed by adding a new function "PK11_HasAttributeClear()" which returns TRUE if the Boolean is false, and false if the Boolean is true or does not exist. The calls PK11_HasAttributeSet() tests would become ! PK11_HasAttributeClear().
Target Milestone: --- → 3.9.2
Attachment #149448 - Flags: superreview?(wchang0222)
Attachment #149448 - Flags: review?(MisterSSL)
Comment on attachment 149448 [details] [diff] [review] Allow use of "Public" private keys Several comments, but no r+ or r- yet. More comments forthcoming. Please answer my questions below (see comments 4 and later) Re: pk11cert.c: 1. Lots of new duplicated code that should be a new function instead. There are about 5 places where a single function call is replaced with a new larger block of code, which is duplicated in each of the places. The 5 places are in PK11_findPrivKeyFromCert PK11_FindCertAndKeyByRecipientList PK11_FindCertAndKeyByRecipientListNew PK11_FindCertInSlot PK11_GetLowLevelKeyIDForCert Example: >- rv = PK11_Authenticate(slot, PR_TRUE, wincx); >- if (rv != SECSuccess) { >- return NULL; >+ if (!PK11_IsFriendly(slot)) { >+ rv = PK11_Authenticate(slot, PR_TRUE, wincx); >+ if (rv != SECSuccess) { >+ return NULL; >+ } It would be MUCH better, IMO, to create a new function named PK11_AuthenticateIfNotFriendly which takes the same arguemnts as PK11_Authenticate, and which does the logic duplicated in all 5 places. Then in those 5 places, you can simply replace one function name with the other. This avoids source code bloat, and, in the event that you later decide to further tweak this logic, you only have to tweak it in one place, not in 5. 2. This patch adds 4 places where an operation is attempted, and if that operation fails FOR ANY REASON, the code then attempts to (re)authenticate and try again. Those 4 places are in PK11_FindPrivKeyFromCert PK11_KeyForCertExists PK11_FindKeyByAnyCert PK11_FindKeyObjectByDERCert At the very least, those places should check the ERROR CODE returned by the previous failed call to see if it indicates an authentication failure (e.g. token not logged in, etc). We shouldn't be retrying with authentication for errors that clearly have nothing to do with authentication. We shouldn't do an expensive test to see if the failure was authentication related. The answer should be handed to us. We shouldn't have to go dig it up. This may mean that functions pk11_FindPrivateKeyFromCertID and PK11_MatchItem need to be changed to return meaningful error codes. 3. I'm wondering why we have both PK11_FindPrivKeyFromCert AND PK11_FindKeyByAnyCert. I need to look at those functions more carefully. Maybe one should call the other. (This is not really a comment about this patch) 4. It appears to me that the changes to functions PK11_FindCertInSlot and PK11_GetLowLevelKeyIDForCert are solving a DIFFERENT problem than the one being solved elsewhere in this patch. This bug is about access to private keys without authenticating. But those two functions provide access to certs, not priv keys. So, it looks like these two changes are intended to eliminate unnecessary authentication for cert access, which is a separate issue. (But I agree with these changes.) Re pk11skey.c: 5. Question: In PK11_MakePrivKey, a new call is added to PK11_Authenticate. Should this be calling PK11_HandlePasswordCheck instead? The rest of the changes to pk11skey.c look fine.
Comment on attachment 149448 [details] [diff] [review] Allow use of "Public" private keys Of my 5 comments above, the only one that is serious enough to warrant an r- is number 2. I'd like to see #1 changed also, but if that was my only comment, I wouldn't hold up r+ for it. But I think comment 2 warrants a change.
Attachment #149448 - Flags: review?(MisterSSL) → review-
Thanks Nelson, I'll look into all the comments and definately will change 2) and probably 1). bob
This patch replaces the pk11cert.c portion of the previous patch. It also addes changes to slot.cpp and secmodi.h. Differences between this patch and the previous patch: 1) new pk11_AuthenticateUnfriendly() function only authenticates new tokens. Note: this patch changes everywhere PK11_Authenticate is called conditional on the friendly flag, not just the 5 new places. This should address area 1. 2)The conditional retry case now happens checks 3 conditions: 1) was the search unsuccessful (key was INVALID). -- if we found it we're done. 2) was it invalid be cause it wasn't found (PORT_Error() set to SSL_NO_CERTICATE). -- if token is private an we aren't logged in, the object will appear to be missing. This short cuts other reasons like problems with the cert object on the token, device problems, memory allocation, etc. 3) does the token need to be logged in (because the token is one that requires loggin and it is not already logged in) pk11_LoginStillRequired(). This test is somewhat common within pk11wrap, so I've lumpped it into a single call and replaced the other occurances with this new call. -- this tells us whether or not we are already logged in. If we are, then there is no point in Authenticating and trying again (we have already determined that the object is not present, even when authenticated). Note that this 3rd check is necessary. There is no way to tell from PKCS #11 if a private object is present if the token is not logged in. This is true because many tokens hide the private objects at the token level (they aren't even visible) until the token is authenticated. These changes (proportedly) address nelson's primary concern (#2). Addressing area 3.. PK11_FindPrivKeyFromCert is a short cut if the application already knows which token it is dealing with. It only searches the specified token. PK11_FindKeyByAnyCert "searches" for the Cert in all the tokens. It then uses the token it found the cert on to look for the key. Addressing area 4. Yes, these locations are searching for certs. They are missing the traditional "isFriendly" check. Addressing area 5. This code is really paranoia. With a standard compliant PKCS #11 module, we should never trip here. Basically private keys, be default, are authenticated before the get to this point. If a PKCS #11 module had 'private' private keys that were still 'visible' without authenticating, it would be possible to get here unauthenticated. The paranoia part is if some code were expecting these keys to be authenticated (because they always are), that could would break. Anyway I wouldn't have a problem removing it (though this current patch does not do so).
Comment on attachment 150985 [details] [diff] [review] Incremental patch on top of the previous patch. Wan-Teh, please also review pk11skey.c from the previous patch. Thanks, bob
Attachment #150985 - Flags: superreview?(wchang0222)
Attachment #150985 - Flags: review?(MisterSSL)
Bob, please provide a new patch showing diffs against the trunk. I'd prefer that to the incremental patch. Thanks. I will make reviewing that my top priority. One tiny bit of review feedback: There are several errors in the block comment preceeding the new function pk11_LoginStillRequired in pk11slot.c
Here is the whole patch. By Incremental in the previous comment I meant "here are the files that had changes", not "here are the diffs relative to the previous patch". My word choice was poor. Anyway it's simple enough to give you the combined patch. This patch does vary from he previous 2 patches in that I adjusted the comment in pk11slot.c nelson meantioned.
Attachment #149448 - Attachment is obsolete: true
Attachment #150985 - Attachment is obsolete: true
Comment on attachment 151129 [details] [diff] [review] This is the same as the previous patch plus pk11skey.c from the first patch (plus a comment fix) I'm going to mark this patch r+, with the proviso that the following things be changed. >@@ -2345,7 +2371,7 @@ > return NULL; > } > >- rv = PK11_Authenticate(*slotPtr,PR_TRUE,wincx); >+ rv = pk11_AuthenticateUnfriendly(*slotPtr, PR_TRUE, wincx); > if (rv != SECSuccess) { > goto loser; > } This call to pk11_Authenticate seems to be unnecessary, since the function called immediately thereafter, pk11_FinKeyByAnyCert, seems to do the authentication and retry logic. >@@ -2418,10 +2444,10 @@ > /* at this point, rl->slot is set */ > > /* authenticate to the token */ >- if (PK11_Authenticate(rl->slot, PR_TRUE, wincx) != SECSuccess) { >- goto loser; >+ rv = pk11_AuthenticateUnfriendly(rl->slot, PR_TRUE, wincx); >+ if (rv != SECSuccess) { >+ goto loser; > } >- > rl->privkey = PK11_FindKeyByAnyCert(cert, wincx); > if (rl->privkey == NULL) { > goto loser; Same comment here. This call to pk11_authenticate seems to be unnecessary. >Index: pk11slot.c >=================================================================== >RCS file: /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11slot.c,v >retrieving revision 1.78 >diff -u -r1.78 pk11slot.c >--- pk11slot.c 25 Apr 2004 15:03:12 -0000 1.78 >+++ pk11slot.c 18 Jun 2004 16:17:34 -0000 >@@ -906,11 +906,23 @@ > } > > /* >+ * Returns true if the token is needs login and isn't logged in. I think that wants to say "token needs login", or "token is needLogin".
Attachment #151129 - Flags: review+
Checking Log for NSS 3.9 Branch.. Checking in lib/pk11wrap/pk11cert.c; /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11cert.c,v <-- pk11cert.c new revision: 1.128.4.2; previous revision: 1.128.4.1 done Checking in lib/pk11wrap/pk11skey.c; /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11skey.c,v <-- pk11skey.c new revision: 1.84.2.3; previous revision: 1.84.2.2 done Checking in lib/pk11wrap/pk11slot.c; /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11slot.c,v <-- pk11slot.c new revision: 1.77.4.1; previous revision: 1.77 done Checking in lib/pk11wrap/secmodi.h; /cvsroot/mozilla/security/nss/lib/pk11wrap/secmodi.h,v <-- secmodi.h new revision: 1.14.16.1; previous revision: 1.14 done
Check-in log for tip: Checking in pk11wrap/pk11cert.c; /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11cert.c,v <-- pk11cert.c new revision: 1.132; previous revision: 1.131 done Checking in pk11wrap/pk11skey.c; /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11skey.c,v <-- pk11skey.c new revision: 1.88; previous revision: 1.87 done Checking in pk11wrap/pk11slot.c; /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11slot.c,v <-- pk11slot.c new revision: 1.79; previous revision: 1.78 done Checking in pk11wrap/secmodi.h; /cvsroot/mozilla/security/nss/lib/pk11wrap/secmodi.h,v <-- secmodi.h new revision: 1.16; previous revision: 1.15 done
Checkin log for Tip: Checking in nss/nss.def; /cvsroot/mozilla/security/nss/lib/nss/nss.def,v <-- nss.def new revision: 1.132; previous revision: 1.131 done Checking in nss/nssinit.c; /cvsroot/mozilla/security/nss/lib/nss/nssinit.c,v <-- nssinit.c new revision: 1.67; previous revision: 1.66 done Checking in pk11wrap/debug_module.c; /cvsroot/mozilla/security/nss/lib/pk11wrap/debug_module.c,v <-- debug_module.c new revision: 1.10; previous revision: 1.9 done Checking in pk11wrap/pk11func.h; /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11func.h,v <-- pk11func.h new revision: 1.53; previous revision: 1.52 done Checking in pk11wrap/pk11skey.c; /cvsroot/mozilla/security/nss/lib/pk11wrap/pk11skey.c,v <-- pk11skey.c new revision: 1.88; previous revision: 1.87 done Checking in pk11wrap/secmodt.h; /cvsroot/mozilla/security/nss/lib/pk11wrap/secmodt.h,v <-- secmodt.h new revision: 1.22; previous revision: 1.21 done Checking in pk11wrap/secmodti.h; /cvsroot/mozilla/security/nss/lib/pk11wrap/secmodti.h,v <-- secmodti.h new revision: 1.18; previous revision: 1.17 done Checking in util/secerr.h; /cvsroot/mozilla/security/nss/lib/util/secerr.h,v <-- secerr.h new revision: 1.15; previous revision: 1.14 done
checkin log from comment 13 applies to bug 244914 Comments 12 and 11 are correct for this bug.
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Sun is also using the NSS 3.9 branch, so anything we check in on the NSS 3.9 branch must be approved by a Sun representative. Let's continue this discussion in email.
Comment on attachment 149448 [details] [diff] [review] Allow use of "Public" private keys cancelling review requests on obsolete patches
Attachment #149448 - Flags: review-
Comment on attachment 149448 [details] [diff] [review] Allow use of "Public" private keys cancelling review requests on obsolete patches (really this time)
Attachment #149448 - Flags: superreview?(wchang0222) → review-
Comment on attachment 150985 [details] [diff] [review] Incremental patch on top of the previous patch. cancelling review requests on obsolete patches.
Attachment #150985 - Flags: superreview?(wchang0222)
Attachment #150985 - Flags: review?(nelson)
Blocks: 211523
Priority: -- → P2
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: