Closed
Bug 103752
Opened 23 years ago
Closed 22 years ago
add support for multiple hostnames in an SSL server certificate
Categories
(NSS :: Libraries, enhancement, P1)
Tracking
(Not tracked)
RESOLVED
FIXED
3.5.1
People
(Reporter: Bill.Burns, Assigned: nelson)
References
()
Details
(Whiteboard: [rfc2818] [cert])
Attachments
(3 files, 2 obsolete files)
Stephane - it's called SubjectAltName, and CMS does support the extension [;-)] However, NSS doesn't support using this extension as an alternative for the common name check, it only supports either one common name, or the magic, proprietry extension SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME (which is no longer n common usage). There are several models we could follow to represent the common name: - use a single CN with regular expression (does not work in IE) - use multiple instances of CN's (NSS will only read the first - use a combination of 1 & 2 (I haven't tested this) - use multiple subjectaltnames (doesn't work with NSS) See section 4.2.1.7 in RFC 2459 for more info on RFC 2459 http://www.ietf.org/rfc/rfc2459.txt?number=2459 My recommendation is to add code to NSS to support: - reading multiple instances of CN - reading dnsName from subjectaltname The code is here: http://lxr.mozilla.org/mozilla/source/security/nss/lib/certdb/certdb.c#1293
Comment 1•23 years ago
|
||
Bob, could you take a look at this request? Thanks.
Assignee: wtc → relyea
Severity: normal → enhancement
Comment 2•23 years ago
|
||
add myself and stevep/thomask to the cc list.
Updated•23 years ago
|
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment 4•22 years ago
|
||
Changed the QA contact to Bishakha.
QA Contact: sonja.mirtitsch → bishakhabanerjee
Comment 5•22 years ago
|
||
RFC 2818 also discusses using SubjectAltName for DNS (host) names.
Whiteboard: [rfc2818]
Comment 6•22 years ago
|
||
RFC 2818 describes the way how to interpret a servercertificate too (RFC describes HTTP over TLS). Mozilla is not compliant to this standard but Microsofts IE is it but there is a solution for this problem. 1. Microsoft is standard compliant so it checks the subject alternative name first. 2. Mozilla (and Netscape too) checks only the (first) common name. So what to do? Set the servernames in the common name like a regular expression. Set the subject alternative name like described in RFC 2818 and don't forget the IPs. IE will check the subject alternative name first and ignores the ugly common name in the distinguished name. Mozilla will check only your common name and ignores the subject alternative name. This way work but please take in mind that this is a hack and Mozilla is not standard comliant to RFC 2818.
Assignee | ||
Comment 7•22 years ago
|
||
This is a deficiency in the NSS library function CERT_VerifyCertName(). It just hasn't kept up to date with the standards. If that function is brought up to date (so that it also considers SubjectAltName in addition to the Subject CommonName, then this problem will be fixed without any changes to the SSL library being needed.
Assignee | ||
Comment 8•22 years ago
|
||
*** Bug 138792 has been marked as a duplicate of this bug. ***
Assignee | ||
Comment 9•22 years ago
|
||
I disagree with the target fix milestone of NSS 4.0. I believe this deficiency in CERT_VerifyCertName can be fixed without depending on any of the other "stan" changes. This is becoming a hotter issue daily. CERT_VerifyCertName needs to catch up with the times, changing from 5 year old code to only 1-2 year old code :)
Updated•22 years ago
|
Whiteboard: [rfc2818] → [rfc2818] [cert]
Target Milestone: 4.0 → 3.6
Comment 10•22 years ago
|
||
*** Bug 142897 has been marked as a duplicate of this bug. ***
Assignee | ||
Comment 12•22 years ago
|
||
This patch should work for Subject Alternative Names that are either DNSNames or IPAddresses. I've tested it with DNSNames, but haven't yet found any server certs with IPAddresses in the Subject Alt Name extension.
Assignee | ||
Comment 13•22 years ago
|
||
I have checked in the above patch on the trunk. The ability to match on IP addresses in the subjectAltName extension is not yet tested because I have not found a cert that contains an IPAddress in the subjectAltName extension.
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 14•22 years ago
|
||
This patch is now checked in.
Attachment #93214 -
Attachment is obsolete: true
Comment 15•22 years ago
|
||
We have a server which uses an IP address in the subjectAltName. https://www.hu-berlin.de
Assignee | ||
Comment 16•22 years ago
|
||
Thanks for the URL of the server. I see that my code for handling IP addresses is wrong, so I'm reopening this bug.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Assignee | ||
Comment 17•22 years ago
|
||
Comment on attachment 93406 [details]
cert of server with IP address in subjectAltName
Changed MIME type of the above attachment.
Attachment #93406 -
Attachment mime type: application/x-X509-user-cert → text/plain
Comment 18•22 years ago
|
||
Comment on attachment 93347 [details] revised patch, works when subjectAltName extension is absent These are the review comments on the second patch. 1. I didn't find any errors. 2. Nit: declare cert_TestHostName and cert_VerifySubjectAltName as static. 3. Nit: in cert_TestHostName, the type of nameLen should be ptrdiff_t. >+ if ((cndomain = PORT_Strchr(cn, '.')) != NULL && >+ (nameLen = cndomain - cn) < sizeof cnbuf && >+ nameLen > 0) { The comparison nameLen > 0 must be true (unless PORT_Strchr is broken) and can be deleted. >+ cn = (const char *)cnbuf; The (const char *) cast in front of cnbuf is not necessary. 4. In cert_TestHostName, you can declare the cn argument as char *, without the const. Then, you can chop off the domain in the cn string by *cndomain = '\0'; like the original code does. This avoids the copy. 5. In cert_VerifySubjectAltName, the comment "so much copy it" should be "so must copy it". Delete the comment "Then downshift it." 6. If we are more likely to have a match with the common name, we should compare the hn string with it first. If they compare equal, we skip the cert_VerifySujectAltName call altogether. 7. It's kind of strange to see certdb set an SSL error code (SSL_ERROR_BAD_CERT_DOMAIN).
Attachment #93347 -
Flags: review+
Assignee | ||
Comment 19•22 years ago
|
||
reponses to above review comments, by number: 2. The lower case cert_ prefix is intended to signify that the function is only for NSS internal use. I didn't make these functions static because I thought some other part of NSS might want to use them sometime. 3. if the first character of cn is '.', then namelen == 0, right? 4-5. Good suggestions. I did them. 6. RFC 2818 says that if a subjectAltName with a DNSNmae is present, it must be used as the cert's identity, otherwise the subject common name may be used. So, I have changed this test so that it only examines the Common Name if the subjectAltName call returns SEC_ERROR_EXTENSION_NOT_FOUND. 7. True. Perhaps these functions actually belong in libSSL. But changing that would be an ABI change, not backwards binary compatible.
Status: REOPENED → ASSIGNED
Comment 20•22 years ago
|
||
Nelson wrote:
> 3. if the first character of cn is '.', then namelen == 0,
> right?
Ah, you are right. I thought the intent was to detect a
negative nameLen, which is impossible. I didn't realize
the intent was to detect a zero nameLen.
Assignee | ||
Comment 21•22 years ago
|
||
Review invited.
Comment 22•22 years ago
|
||
Comment on attachment 93497 [details] [diff] [review] incremental patch, addresses issues listed above Comments on the incremental patch. 1. When verifying an IP address, you handle three cases. Seems like for completeness, the fourth case ( current->name.other.len == 4 && netAddr.ipv6.family == PR_AF_INET6 ) should also be handled. 2. I suggest using replacing PRStatus prs; ... prs = PR_StringToNetAddr(hn, &netAddr); by something like PRBool hnIsIPAddr; ... hnIsIPAddr = (PR_StringToNetAddr(hn, &netAddr) == PR_SUCCESS); It'll be easier to read and make the comments unnecessary.
Attachment #93497 -
Flags: needs-work+
Comment 24•22 years ago
|
||
Comment on attachment 93617 [details] [diff] [review] incremental patch, addresses review comments above >+ PRUint32 ipv4 = (current->name.other.data[0] << 24) | >+ (current->name.other.data[1] << 16) | >+ (current->name.other.data[2] << 8) | >+ current->name.other.data[3]; >+ /* ipv4 must be in Network Byte Order on input. */ >+ PR_ConvertIPv4AddrToIPv6(PR_htonl(ipv4), &v6Addr); >+ match = !memcmp(&netAddr.ipv6.ip, &v6Addr, 16); You can also just say: PRUint32 ipv4; memcpy(&ipv4, current->name.other.data, 4); PR_ConvertIPv4AddrToIPv6(ipv4, &v6addr); match = !memcmp(&netAddr.ipv6.ip, &v6Addr, 16); or alternatively: if (PR_IsNetAddrType(&netAddr, PR_IpAddrV4Mapped) { match = !memcmp(&netAddr.ipv6.ip.pr_s6_addr[12], current->name.other.data, 4); } >- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); >+ if ((!isIPaddr && !DNSextCount) || (isIPaddr && !IPextCount)) { >+ /* no relevant value in the extension was found. */ >+ PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); >+ } else { >+ PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); >+ } The (isIPaddr && !IPextCount) test makes your name verification more lenient than what RFC 2818 reads to me. That is, if the server cert has the subject alt name extension but the extension contains no IP addresses (IPextCount is 0), RFC 2818 suggests that the name verification should fail, but your patch will go on to test the common name. The relevant paragraph in RFC 2818 is quoted here: In some cases, the URI is specified as an IP address rather than a hostname. In this case, the iPAddress subjectAltName must be present in the certificate and must exactly match the IP in the URI. It is fine by me to be more lenient.
Assignee | ||
Comment 25•22 years ago
|
||
Elsewhere in RFC 2818, it says If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. Notice that this section is not conditioned upon the URI being a hostname and not an IP address. So this statement conflicts with the one cited above. I implemented this policy: if the URI contains a host name if the subject alt name is present and has one or more DNS names use the DNS names in that extension as the server identity else use the subject common name as the server identity else if the URI contains an IP address if the subject alt name is present and has one or more IP addresses use the IP addresses in that extension as the server identity else compare the URI IP address string with the subject common name. Perhaps there is another issue here. NSS always gets and examines the first Common Name attribute. It is apparently possible for the subject name to cotnain more than one Common Name attribute. We make no attempt to find the "most specific" one. I don't know how that's defined. The above patch is checked in. I'm marking this resolved.
Status: ASSIGNED → RESOLVED
Closed: 22 years ago → 22 years ago
Resolution: --- → FIXED
Comment 26•22 years ago
|
||
My understanding of the phrase "most specific" is that the last attribute in the RDN sequence that matches the tag (CN) should be used. As you point out, NSS does not do this. However, since the use of CN for host name is supported only for compatibility, and we haven't had any problems to this point, there is no need to fix this.
Comment 27•22 years ago
|
||
Comment on attachment 93617 [details] [diff] [review] incremental patch, addresses review comments above r=wtc.
Attachment #93617 -
Flags: review+
Comment 28•22 years ago
|
||
a=asa (on behalf of drivers) for checkin to 1.1
Comment 29•22 years ago
|
||
I checked in Nelson's patches into the NSS_3_5_BRANCH and NSS_CLIENT_TAG. This fix will be in Mozilla 1.1 and NSS 3.5.1.
Target Milestone: 3.6 → 3.5.1
Comment 30•22 years ago
|
||
This broke the Mac build: Error : illegal implicit conversion from 'const char *' to 'char *' certdb.c line 1266 int match = PORT_RegExpCaseSearch(hn, cn); We may need to do what the original code did: duplicate hn hostname = PORT_Strdup(hn); and pass the copy (hostname) to PORT_RegExpCaseSearch. I backed out the patch from NSS_CLIENT_TAG.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Comment 31•22 years ago
|
||
I found that Nelson already fixed this problem the right way on the tip. PORT_RegExpCaseSearch and the other functions declared in portreg.h should take const char * arguments. I merged Nelson's changes to portreg.{h,c} into the NSS_3_5_BRANCH and NSS_CLIENT_TAG and put the fix for this bug back in NSS_CLIENT_TAG.
Status: REOPENED → RESOLVED
Closed: 22 years ago → 22 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 32•22 years ago
|
||
*** Bug 183732 has been marked as a duplicate of this bug. ***
Comment 33•22 years ago
|
||
If you look at https://uzivatel.vsb.cz/ , the browser will not display a spoofing warning, but on the other hand it will display "Bad Padlock". The certificate has 4 different SubjectAltName DNS records. Should Mozilla either display warning or don't display the "Bad Padlock" at all... it looks inconsistent. Not really sure if this is a bug or a feature, so I am not reopening this bug. Personally I am not really sure if the presented kind of certificate complies RFC 2818 and I will be grateful for your opinion. I am using Mozilla 1.2.1 release on Win98 with its version of NSS. The CA Certificate can be downloaded at http://www.vsb.cz/cgi-bin/CA/CAload.pl/001/cacert.crt .
Comment 34•22 years ago
|
||
I think the bad padlock means the secure page contains. references to non-secure (http, not https) URLs. If you replace all the href="http://..." by href="https://..." in that page, the bad padlock should be gone.
Comment 35•22 years ago
|
||
The four different subjectAltNames are correct. This is not spoofing. The different alternative names are for virtual hosts like ISPs. We have servers with up to six or seven different names and they have only one certificate. I checked the page and only some http://... avoid Mozilla from running without warnings.
Comment 36•22 years ago
|
||
Thank you guys for your effort and the lesson. I didn't make the webpage itself and somehow did a silent implication that the experienced author knew what he was doing. Sorry for your time and thank you once again.
You need to log in
before you can comment on or make changes to this bug.
Description
•