Open
Bug 210941
Opened 21 years ago
Updated 2 years ago
Redefine NSS nicknames to identify certs unambiguously
Categories
(NSS :: Libraries, enhancement, P2)
Tracking
(Not tracked)
NEW
People
(Reporter: nelson, Assigned: rrelyea)
Details
This RFE is filed on behalf of thomask@netscape.com, and the CMS team. Today, NSS nicknames identify a subject name, not an individual cert. If a user has multiple certs with the same subject name, there is only one nickname that identifies all those certs. The nickname does not unambiguously identify any one of the certs that share that subject name. When an NSS application calls functions such as CERT_FindCertByNickname or CERT_FindUserCertByUsage to obtain a cert (say, to be used as an SSL server cert or SSL client auth cert) NSS picks the most recently issued cert (that is currently within its validity period) with that nickname. The cert chosen this way is ALWAYS a valid cert for use at the present time. The cert returned by CERT_FindUserCertByUsage is always value for the specified use at the present time. But nonetheless, the user may wish to use a different specific cert than the one chosen by the NSS functions named above. So, Thomas proposes to change the operation of functions like those named above to make is possible to unambiguously identify a cert through those APIs. The idea is to effect this change without needing to change the products that use NSS. A new NSS shared library could allow users of existing server and client products to simply change the strings they use, and be able to identify specific particular certs. The proposal is to have these functions first behave exactly as they do now, so as to maximize backward compatibility. Then if the cert search fails to find a nickname match, parse the nickname according to an alternative syntax, and look for a cert according to that information. There have been several proposals for alternative nickname syntax, including Proposal 1) An RFC 2253 ASCII-encoded issuer name followed by an ASCII encoded serial number. Proposal 2) An NSS nickname (as today) followed by " serial#" and a serial number in ASCII encoded decimal. Proposal 3) An NSS nickname (as today) followed by an expiration date expressed as an ASCII encoded generalTime.
Reporter | ||
Comment 1•21 years ago
|
||
See bug 210709 and the bugs on which it depends to see why I think Proposal 1 is not a good idea.
Hmm, just looked at NES's code, look like they do their own version of find certificate by nickname. I will work with to NES to solve this problem CERTCertificate* SSLSocketConfiguration :: FindServerCertFromNickname(const char* name) const { CERTCertList* clist; clist = PK11_ListCerts(PK11CertListUser, NULL); CERTCertListNode *cln; for (cln = CERT_LIST_HEAD(clist); !CERT_LIST_END(cln,clist); cln = CERT_LIST_NEXT(cln)) { CERTCertificate* cert = cln->cert; const char* nickname = (const char*) cln->appData; if (!nickname) { nickname = cert->nickname; }; if (0==strcmp(name, nickname)) { // we found our cert return cert; }; }; return NULL; }; void SSLSocketConfiguration :: set_cert_and_key() { SECStatus secstatus = SECFailure; // check the certificate SECCertTimeValidity certtimestatus; // Get own certificate and private key // later, we may need to do do a PK11_FindCertsFromNickname (note the plural) // because there may be several certs under the same nickname, // * for example in the case of certs signed by distinct CA // * there can also be certs with different expiration dates, but the singular // PK11_FindCertFromNickname always returns the most recent cert so we are OK // for that case, except if a cert that isn't yet valid has been installed ... // * DH support : if both RSA and DSA certs need to be installed on the same // server, we'll actually need to set both types certs on the socket ... servercert = FindServerCertFromNickname((char*)servercertnickname.data()) ...
For reference, here is the NES bug filed https://blackflag.mcom.com/show_bug.cgi?id=623094
Independently, I suggest we put the change into NSS: certutil is currently using PK11_FindCertsFromNickname() In mozilla/security/nss/lib/pk11wrap/pk11cert.c static long pk11_getSerialNumberFromNickname(char *nickname) { /* Alternative Nickname Format: <nickname> <serial># */ int len = 0; int i; char *nicknameDup = NULL; long rv = -1; int isNum = 0; nicknameDup = PORT_Strdup(nickname); len = PORT_Strlen(nicknameDup); if (len <= 0) { goto done; } if (nicknameDup[len-1] == '#') { nicknameDup[len-1] = '\0'; for (i=len-2; i >= 0; i--) { if (nicknameDup[i] == ' ') { if (isNum) { rv = atol(nicknameDup+i+1); } goto done; } if (nicknameDup[i] < '0' || nicknameDup[i] > '9') { goto done; } else { isNum = 1; } } } done: if (nicknameDup) PORT_Free(nicknameDup); return rv; } static CERTCertificate * pk11_FindCertFromNicknameWithSN(char *nickname, void *wincx) { char *nicknameDup = NULL; int i; long sn = -1; long certSN = -1; CERTCertificate *rvCert = NULL; CERTCertList *certList = NULL; CERTCertListNode *node = NULL; sn = pk11_getSerialNumberFromNickname(nickname); if (sn == -1) goto done; /* error */ nicknameDup = PORT_Strdup(nickname); for (i = PORT_Strlen(nicknameDup); i >= 0; i--) { if (nicknameDup[i] == ' ') { nicknameDup[i] = '\0'; goto next; } } next: certList = PK11_FindCertsFromNickname(nicknameDup, wincx); if (certList == NULL) { goto done; /* error */ } for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) { CERTCertificate *cert = node->cert; certSN = DER_GetInteger(&cert->serialNumber); if (certSN == sn) { rvCert = CERT_DupCertificate(cert); goto done; /* success */ } } done: if (nicknameDup) PORT_Free(nicknameDup); if (certList) CERT_DestroyCertList(certList); return rvCert; } CERTCertificate * PK11_FindCertFromNickname(char *nickname, void *wincx) { ... } /* Test if we are using the new serial number format */ if (rvCert == NULL && pk11_getSerialNumberFromNickname(nickname) != -1) { rvCert = pk11_FindCertFromNicknameWithSN(nickname, wincx); } if (slot) { PK11_FreeSlot(slot); } if (nickCopy) PORT_Free(nickCopy); return rvCert; loser: if (slot) { PK11_FreeSlot(slot); } if (nickCopy) PORT_Free(nickCopy); return NULL; #endif }
Comment 5•21 years ago
|
||
Thomas, Before you "fix" NES, let me explain why I had to implement my own version of findcertbynickname. The problem was that an identical cert could exist in multiple tokens, along with multiple private keys. Even though the NSS cert nickname specified the slot (token:nickname), the NSS APIs could return the cert structure with an undetermined slot, if there were multiple copies of the cert. Only NSS 4.0 could solve this problem with the API. Of course, this would be a major change for all NSS applications, and not just a simple recompile. If we change the definition of an NSS nickname to map to a unique cert rather than any cert matching a subject, we will still have to deal with the token issue. This isn't just a corner case for servers. Currently for instance, I have my email certs and private keys living both on a smartcard and in the softoken. Also, I think it is likely that some applications that are aware of the NSS indexing by subject, eg. PSM and possibly parts of the NES admin, will break if we make this change. Note that I'm not at all saying we shouldn't change it, but that this is a major change that is probably best dealt with in NSS 4.0 . Since we are now working on NSS 3.9, it seems like an appropriate time to start seriously scheduling NSS 4.0 work.
Updated•21 years ago
|
Priority: -- → P2
Target Milestone: --- → 3.9
Comment 6•21 years ago
|
||
Bob, please work with Steve and Thomas to resolve this RFE.
Assignee: wchang0222 → rrelyea0264
Assignee | ||
Comment 7•21 years ago
|
||
We should not change the semantics of the current find cert by nickname call. Adding a new function with a new name may be reasonable. Applications can get this current functionality without changes to NSS by creating their own FindCertByNicknameWithSerial(). Call CERT_CreateNicknameCertList() for the nickname part. walk the CertList looking for a cert with the requested serial number. NOTE: This API is *not* guarrenteed to identify a unique cert. nickname the nickname of the subject, not the issuer. Two certs may have the same subject and same serial number with different issuers. bob
Reporter | ||
Comment 8•21 years ago
|
||
Bob, the purpose of this RFE is to avoid having to build new binaries of certain old NSS-based server products. The argument is that if the syntax accepted by NSS functions that use nicknames is extended to facilitate unique cert selection, then those old servers can be used with new NSS libs, without rebuilding the servers.
Assignee | ||
Comment 9•21 years ago
|
||
The problem is the only way to get that is to also change PK11_ListCerts to return these kinds of nicknames. That would break existing apps as well. Since it already requires a rebuild of those servers, then the problem should be fixed correctly.
Comment 10•21 years ago
|
||
I agree with Bob. There is no "fix" for this that can be done only in NSS. Some changes will have to be made to the server applications.
Comment 11•21 years ago
|
||
Can we not localize the change to PK11_FindCertFromNickname? I understand that DS server team uses this function to retrieve the server certificate for SSL certificate. If we worry about consistent issue, then maybe we should introduce a new function PK11_FindCertFromSuperNickname() as suggested. Then, in the long run, all server should use this PK11_FindCertFromSuperNickname(). For server certificate selection in SSL configuration, we should provide automatic and manual configuration. Maybe by default and normal circumstances, we will use the automatic certificate selection provided in PK11_FindCertFromNickname(). But in some scenario, administrators do want to be able to pick one particular certificate for whatever reason. Currently, we do not provide that functionality in NSS. I agree that the application that implement this feature. But if this is useful to all server product, why dont we put this feature in NSS? Providing a brand new infrastructure to support manual selection could be a lot of work. That is why I proposed to have a way to leverage the existing API.
Comment 12•21 years ago
|
||
Thomas, Even if we localize the change to PK11_FindCertFromNickname, the web server still won't work with that sole change, because it uses PK11_ListCerts to locate certs, not PK11_FindCertFromNickname. PK11_ListCerts returns a list of certs with their nickname. If we change it to return a nickname + SN, existing applications, including NES, will be broken by that change. So we would have to change the web server anyway. It can't work with just an NSS patch to PK11_FindCertFromNickname. DS may be different. I don't know about other products. I suspect there is no one single rule here as far as the certificate search goes. There are lots of different ways to find certificates in NSS. nickname is only one of them. Other applications have moved away from using nicknames completely. It is not accurate to say that we don't provide the function you want in NSS. We don't provide a one-line function call to do what you want. However, you can can certainly already perform the search you want by getting a subject list of all the certs under the given nickname, and then looking at their serial number and filter to the specific one that you need. There is nothing in NSS that stops you from implementing what you need today. However, what you really want is to add functionality to a number of different NSS-based applications, and you believe that a change to NSS will automatically do that. My take on this, is that it will not. I have been trying to tell you that in our previous meeting on the issue, as Bob is telling you now. I have no problem with adding a one-line function that does the search that you want, so that you can modify all the applications that need the new behavior to call this new cert search function. In standard NSS terminology, we would probably not modify the format of the nickname string, but instead have a function called "PK11_FindCertByNicknameAndSN" which would take 2 arguments - one for the nickname and SN. If we add this new function to do the search, it would be my preference to use that sort of prototype. However, I don't have a problem with putting the 2 arguments in a single string together as long as that argument is not called a nickname. I don't particularly like "SuperNickname", but we can probably find something less confusing.
Comment 13•21 years ago
|
||
No, I don't think we never asked for any change to PK11_ListCerts. That function should continue to return the plain nickname. At least if we extend CERT_FindCertByNickname, users can override the nickname in their applications config file to add the serial number.
Comment 14•21 years ago
|
||
By the way - if we were able to make more extensive changes to the servers handling of certificate configuration, it would be to remove support for nicknames completely. They seem to cause far more confusion than is necessary.
Comment 15•21 years ago
|
||
Steve, Once more ... NES uses PK11_ListCerts to locate certs, not PK11_FindCertFromNickname. It works by enumerating the certs into a list, then matching the nickname string in the list against the string in the config file. This is why changes to CERT_FindCertFromNickname, or PK11_FindCertByNickname, won't help this particular application. There may be other cases. If we make the change, I don't think you will get all the results you expect. IMO we should not be lazy about this problem, because it will not work as you expect. We should look at each application that needs this new functionality, see exactly which functions they call, and modify them to call the new search function where needed. If we keep the 2 arguments in one string, the application changes should not be expensive - essentially renaming a couple of function calls. However the applications code does need to be reviewed.
Assignee | ||
Comment 16•21 years ago
|
||
My issue is PK11_FindCertByNickname() has a semantic and a meaning. You want a new function with a different semantic. This new function needs to be distinct. Where it goes is 6 of one half a dozen of another. There is definately server specific code in NSS that clients never use. There is also shared code servercore that implements functions unique to the way servers use NSS. This can be implemented in either place. -------------------- So here's one proposal: We provide two new functions: char *PK11_GetStringForUniqueCert(CERTCertificate *); CERTCertificate *PK11_FindUniqueCertByString(const char *string); under the covers the string is the nickname and one of: Issue date serial number certificate hash I personally prefer certificate hash, since it's the only one guarrenteed to be unique, but we can discuss which it is. It is even possible that PK11_FindUniqueCertByString() will accept any of the three properly identified. Example: "ServerCert serial:05:06:7d:54:45:80:12" (assuming a verisign cert) bob
Assignee | ||
Comment 17•21 years ago
|
||
RE: Steve and removing nicknames: That is certainly doable, and probably desirable. It doesn't require any changes to NSS. Other apps have done this already. bob
Comment 18•21 years ago
|
||
Is certificate hash being displayed by certutil? If it is not currently displayed by our utility, people may have a hard time coming up the hash to do the listing.
Comment 19•21 years ago
|
||
Yes, certificate hash can be displayed in certutil, but certutil in all NSS releases <= 3.8.2 displays the wrong hash (bug 220016). This bug was recently fixed by Nelson in the upcoming NSS 3.9 release.
Comment 20•21 years ago
|
||
Moved to NSS 3.10. Should we resolve this bug WONTFIX or implement Bob's alternate proposal in comment 16?
Target Milestone: 3.9 → 3.10
Reporter | ||
Updated•19 years ago
|
QA Contact: bishakhabanerjee → jason.m.reid
Updated•19 years ago
|
Target Milestone: 3.10 → 3.12
Reporter | ||
Updated•18 years ago
|
QA Contact: jason.m.reid → libraries
Assignee | ||
Updated•17 years ago
|
Target Milestone: 3.12 → 3.12.2
Reporter | ||
Comment 21•15 years ago
|
||
Unsetting target milestone in unresolved bugs whose targets have passed.
Target Milestone: 3.12.2 → ---
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•